1 /***************************************************************************
2 * Copyright (C) 2005, 2006 by Pino Toscano, toscano.pino@tiscali.it*
3 * Copyright (C) 2006, 2007 by Carsten Niehaus, cniehaus@kde.org *
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. *
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. *
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"
33 #include <QApplication>
44 #include <QPainterPath>
48 #include <kglobalsettings.h>
51 KalziumPainter::KalziumPainter( KalziumTableType
*ktt
)
65 void KalziumPainter::begin( QPaintDevice
*pd
)
68 m_painter
= new QPainter( pd
);
71 void KalziumPainter::end()
75 if ( m_painter
->isActive() )
82 KalziumTableType
* KalziumPainter::currentTableType() const
87 void KalziumPainter::drawAll()
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();
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
);
129 if ( selectedElement
)
130 c
= QBrush( Qt::yellow
, Qt::CrossPattern
);
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() )
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
);
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
);
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();
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();
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
);
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();
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
);
241 QBrush c
= brushForElement( element
);
243 m_painter
->fillRect( rect
, c
);
244 m_painter
->drawRect( rect
);
246 m_painter
->drawText( rect
, Qt::AlignCenter
, symbol
);
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
);
272 m_painter
->setRenderHint(QPainter::Antialiasing
, true);
274 pen
.setStyle( Qt::DotLine
);
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);
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
)
293 void KalziumPainter::setScheme( int s
)
295 KalziumSchemeType
*tmp
= KalziumSchemeTypeFactory::instance()->build( s
);
302 void KalziumPainter::setScheme( const QByteArray
& s
)
304 KalziumSchemeType
*tmp
= KalziumSchemeTypeFactory::instance()->build( s
);
311 KalziumSchemeType
* KalziumPainter::scheme() const
316 void KalziumPainter::setGradient( int g
)
318 KalziumGradientType
*tmp
= KalziumGradientTypeFactory::instance()->build( g
);
325 void KalziumPainter::setGradient( const QByteArray
& g
)
327 KalziumGradientType
*tmp
= KalziumGradientTypeFactory::instance()->build( g
);
334 KalziumGradientType
* KalziumPainter::gradient() const
339 void KalziumPainter::setNumeration( int n
)
341 KalziumNumerationType
*tmp
= KalziumNumerationTypeFactory::instance()->build( n
);
348 void KalziumPainter::setNumeration( const QByteArray
& n
)
350 KalziumNumerationType
*tmp
= KalziumNumerationTypeFactory::instance()->build( n
);
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
);
373 return m_scheme
->elementBrush( element
, rect
);
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();
399 color
= Qt::lightGray
;
401 return QBrush( color
);
406 double coeff
= m_gradient
->elementCoeff( element
);
407 return QBrush( m_gradient
->calculateColor( coeff
) );
412 const int date
= el
->dataAsVariant( ChemicalDataObject::date
).toInt();
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
);
422 return QBrush( Qt::lightGray
);