Test change - can I push OK?
[kdeedu-porting.git] / kalzium / src / kalziumpainter.cpp
blobf72e37914ca135c43dda5b83527f1118316582fe
1 /***************************************************************************
2 * Copyright (C) 2005, 2006 by Pino Toscano, toscano.pino@tiscali.it*
3 * Copyright (C) 2006, 2007 by Carsten Niehaus, cniehaus@kde.org *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #define ELEMENTSIZE 40
22 #include "kalziumpainter.h"
23 #include "kalziumdataobject.h"
24 #include "kalziumtabletype.h"
25 #include "kalziumschemetype.h"
26 #include "kalziumgradienttype.h"
27 #include "kalziumnumerationtype.h"
28 #include "kalziumutils.h"
29 #include "element.h"
30 #include "prefs.h"
31 #include "search.h"
33 #include <QApplication>
34 #include <QBrush>
35 #include <QColor>
36 #include <QFont>
37 #include <QPainter>
38 #include <QPair>
39 #include <QPalette>
40 #include <QPoint>
41 #include <QRect>
42 #include <QSize>
43 #include <QPolygon>
44 #include <QPainterPath>
45 #include <QDebug>
47 #include <kdebug.h>
48 #include <kglobalsettings.h>
49 #include <klocale.h>
51 KalziumPainter::KalziumPainter( KalziumTableType *ktt )
52 : m_painter( 0 )
54 m_ktt = ktt;
56 setScheme( 1 );
57 setGradient( 0 );
58 setNumeration( 1 );
60 m_temperature = 0;
62 m_mode = NORMAL;
65 void KalziumPainter::begin( QPaintDevice *pd )
67 end();
68 m_painter = new QPainter( pd );
71 void KalziumPainter::end()
73 if ( m_painter )
75 if ( m_painter->isActive() )
76 m_painter->end();
77 delete m_painter;
78 m_painter = 0;
82 KalziumTableType* KalziumPainter::currentTableType() const
84 return m_ktt;
87 void KalziumPainter::drawAll()
89 drawElements();
90 drawNumeration();
93 void KalziumPainter::drawElements()
95 QPaintDevice *dev = m_painter->device();
96 QRect r( 0, 0, dev->width(), dev->height() );
97 m_painter->fillRect( r, QApplication::palette().background() );
99 // now iterate over all elements the table contains
100 int num = m_ktt->firstElement();
101 while ( num != -1 )
103 drawElement( num );
104 num = m_ktt->nextOf( num );
108 void KalziumPainter::drawElement( int element, const QRect& r )
110 if ( !m_scheme || !m_ktt ) return;
112 const QRect rect = r.isNull() ? m_ktt->elementRect( element ) : r;
114 if (rect.isNull() ) {
115 return; //this element doesn't belong to the table it seems...
118 Element *el = KalziumDataObject::instance()->element( element );
119 const QString symbol = el->dataAsString( ChemicalDataObject::symbol );
121 bool selectedElement = KalziumDataObject::instance()->search()->matches( el );
123 switch ( m_mode )
125 case NORMAL:
127 QBrush c;
129 if ( selectedElement )
130 c = QBrush( Qt::yellow, Qt::CrossPattern );
131 else
132 c = m_scheme->elementBrush( element, rect );
134 //when drawing the iconic style we don't draw the text. That is
135 //why I introduced this if-condition. (C Niehaus)
136 if (m_scheme->name() == "Iconic") {
137 m_painter->fillRect( rect, c );
138 m_painter->drawRect( rect );
139 }else if ( !c.texture().isNull() )
141 QRect symbolrect;
142 QFont orig_font = m_painter->font();
143 QFont font = m_painter->font();
144 font.setPointSize( QFontInfo( font ).pointSize() - 2 );
145 m_painter->setFont( font );
146 m_painter->drawText( rect, Qt::AlignHCenter | Qt::AlignTop, symbol, &symbolrect );
147 m_painter->setFont( orig_font );
148 int symbolheight = symbolrect.height();
149 QRect rect2 = rect.translated( 0, symbolheight );
150 rect2.setHeight( rect2.height() - symbolheight - 1 );
151 QPixmap pix = c.texture().scaled( rect2.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation );
152 m_painter->drawPixmap( rect2.left() + ( rect2.width() - pix.width() ) / 2, rect2.top() + ( rect2.height() - pix.height() ) / 2, pix );
153 m_painter->drawRect( rect );
155 else
157 // the brush doesn't have any texture,
158 // so proceeding with normal colors and texts
159 QColor textc = m_scheme->textColor( element );
160 m_painter->setPen( textc );
162 m_painter->fillRect( rect, c );
163 m_painter->drawRect( rect );
165 m_painter->drawText( rect, Qt::AlignCenter, symbol );
167 break;
169 case SOM:
171 QColor color;
173 const double melting = el->dataAsVariant( ChemicalDataObject::meltingpoint ).toDouble();
174 const double boiling = el->dataAsVariant( ChemicalDataObject::boilingpoint ).toDouble();
175 const double mass = el->dataAsVariant( ChemicalDataObject::mass ).toDouble();
177 if ( m_temperature < melting )
179 //the element is solid
180 color= Prefs::color_solid();
182 else if ( ( m_temperature > melting ) && ( m_temperature < boiling ) )
184 //the element is liquid
185 color= Prefs::color_liquid();
187 else if ( ( m_temperature > boiling ) && ( boiling > 0.0 ) )
189 //the element is vaporous
190 color= Prefs::color_vapor();
192 else
193 color = Qt::lightGray;
195 m_painter->setPen( Qt::black );
197 QFont orig_font = m_painter->font();
198 QFont symbol_font = m_painter->font();
199 symbol_font.setPointSize( 10 );
200 QFont f = m_painter->font();
201 f.setPointSize( 9 );
202 m_painter->setFont( f );
204 m_painter->fillRect( rect, QBrush( color ) );
205 m_painter->drawRect( rect );
207 m_painter->drawText( rect, Qt::AlignHCenter | Qt::AlignTop, QString::number( KalziumUtils::strippedValue( mass ) ) );
209 m_painter->drawText( rect, Qt::AlignHCenter | Qt::AlignBottom, QString::number( element ) );
211 m_painter->setFont( symbol_font );
212 m_painter->drawText( rect, Qt::AlignCenter, symbol );
214 m_painter->setFont( orig_font );
215 break;
217 case GRADIENT:
219 m_painter->setPen( Qt::black );
220 double coeff = m_gradient->elementCoeff( element );
221 QBrush c = QBrush( m_gradient->calculateColor( coeff ) );
223 m_painter->fillRect( rect, c );
224 m_painter->drawRect( rect );
226 m_painter->drawText( rect, Qt::AlignCenter, symbol );
228 QFont orig_font = m_painter->font();
229 QFont f = m_painter->font();
230 f.setPointSize( 8 );
231 m_painter->setFont( f );
232 double value = m_gradient->value( element );
233 QString strval = coeff != -1 ? QString::number( KalziumUtils::strippedValue( value ) ) : i18nc( "It means: Not Available. Translators: keep it as short as you can!", "N/A" );
234 m_painter->drawText( rect, Qt::AlignHCenter | Qt::AlignBottom, strval );
236 m_painter->setFont( orig_font );
237 break;
239 case TIME:
241 QBrush c = brushForElement( element );
243 m_painter->fillRect( rect, c );
244 m_painter->drawRect( rect );
246 m_painter->drawText( rect, Qt::AlignCenter, symbol );
247 break;
252 void KalziumPainter::drawNumeration()
254 QStringList numitems = m_numeration->items();
255 for ( int i = 0; i < numitems.count(); i++ )
257 QRect itemrect = m_ktt->numerationRect( i, m_numeration );
258 if ( itemrect.isNull() ) continue;
260 m_painter->drawText( itemrect, Qt::AlignCenter, numitems.at( i ) );
264 void KalziumPainter::drawElementSelector( int element )
266 if ( !m_ktt ) return;
268 QRect elemrect = m_ktt->elementRect( element );
270 QPen pen;
272 m_painter->setRenderHint(QPainter::Antialiasing, true);
273 // outer circle
274 pen.setStyle( Qt::DotLine );
275 pen.setWidth( 4 );
276 pen.setColor( Qt::blue );
277 m_painter->setPen( pen );
278 m_painter->drawEllipse( elemrect.left() - 10, elemrect.top() - 10, elemrect.width() + 20, elemrect.height() + 20 );
279 m_painter->setRenderHint(QPainter::Antialiasing, false);
281 // inner circle
282 pen.setWidth( 3 );
283 pen.setColor( Qt::red );
284 m_painter->setPen( pen );
285 m_painter->drawEllipse( elemrect.left() - 5, elemrect.top() - 5, elemrect.width() + 10, elemrect.height() + 10 );
288 void KalziumPainter::setMode( MODE m )
290 m_mode = m;
293 void KalziumPainter::setScheme( int s )
295 KalziumSchemeType *tmp = KalziumSchemeTypeFactory::instance()->build( s );
296 if ( tmp )
298 m_scheme = tmp;
302 void KalziumPainter::setScheme( const QByteArray& s )
304 KalziumSchemeType *tmp = KalziumSchemeTypeFactory::instance()->build( s );
305 if ( tmp )
307 m_scheme = tmp;
311 KalziumSchemeType* KalziumPainter::scheme() const
313 return m_scheme;
316 void KalziumPainter::setGradient( int g )
318 KalziumGradientType *tmp = KalziumGradientTypeFactory::instance()->build( g );
319 if ( tmp )
321 m_gradient = tmp;
325 void KalziumPainter::setGradient( const QByteArray& g )
327 KalziumGradientType *tmp = KalziumGradientTypeFactory::instance()->build( g );
328 if ( tmp )
330 m_gradient = tmp;
334 KalziumGradientType* KalziumPainter::gradient() const
336 return m_gradient;
339 void KalziumPainter::setNumeration( int n )
341 KalziumNumerationType *tmp = KalziumNumerationTypeFactory::instance()->build( n );
342 if ( tmp )
344 m_numeration = tmp;
348 void KalziumPainter::setNumeration( const QByteArray& n )
350 KalziumNumerationType *tmp = KalziumNumerationTypeFactory::instance()->build( n );
351 if ( tmp )
353 m_numeration = tmp;
357 void KalziumPainter::setTemperature( int temp )
359 m_temperature = temp;
362 QBrush KalziumPainter::brushForElement( int element ) const
364 if ( !m_scheme || !m_ktt ) return QBrush();
366 QRect rect = m_ktt->elementRect( element );
367 Element *el = KalziumDataObject::instance()->element( element );
369 switch ( m_mode )
371 case NORMAL:
373 return m_scheme->elementBrush( element, rect );
374 break;
376 case SOM:
378 QColor color;
380 const double melting = el->dataAsVariant( ChemicalDataObject::meltingpoint ).toDouble();
381 const double boiling = el->dataAsVariant( ChemicalDataObject::boilingpoint ).toDouble();
383 if ( m_temperature < melting )
385 //the element is solid
386 color = Prefs::color_solid();
388 else if ( ( m_temperature > melting ) && ( m_temperature < boiling ) )
390 //the element is liquid
391 color = Prefs::color_liquid();
393 else if ( ( m_temperature > boiling ) && ( boiling > 0.0 ) )
395 //the element is vaporous
396 color = Prefs::color_vapor();
398 else
399 color = Qt::lightGray;
401 return QBrush( color );
402 break;
404 case GRADIENT:
406 double coeff = m_gradient->elementCoeff( element );
407 return QBrush( m_gradient->calculateColor( coeff ) );
408 break;
410 case TIME:
412 const int date = el->dataAsVariant( ChemicalDataObject::date ).toInt();
414 qDebug() << date;
416 if ( date == -1 ) //the element has not yet been recoqnized
417 return QBrush( Qt::blue );
419 if ( m_time >= date )
420 return m_scheme->elementBrush( element, rect );
421 else
422 return QBrush( Qt::lightGray );
423 break;
426 // fallback
427 return QBrush();