moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kalzium / src / pse.cpp
blobc3af562f8506342eb7dad27745be7a8865d7386a
1 /***************************************************************************
2 * Copyright (C) 2003 by Carsten Niehaus *
3 * 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 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #include "pse.h"
21 #include "prefs.h"
22 #include "infodialog_small_impl.h"
23 #include "detailinfodlg.h"
25 #include <klocale.h>
26 #include <kdebug.h>
27 #include <qtooltip.h>
28 #include <qwhatsthis.h>
29 #include <qlayout.h>
30 #include <qlabel.h>
31 #include <qpixmap.h>
32 #include <qpoint.h>
33 #include <qradiobutton.h>
34 #include <qbuttongroup.h>
35 #include <qcursor.h>
36 #include <qpainter.h>
38 PSE::PSE(KalziumDataObject *data, QWidget *parent, const char *name)
39 : QWidget(parent, name), table(0)
41 d = data;
43 connect( this, SIGNAL( tableClicked( QPoint ) ), this, SLOT( slotUpdatePoint( QPoint ) ) );
44 connect( this, SIGNAL( ToolTip( int ) ), this, SLOT( slotToolTip( int ) ) );
45 connect( &HoverTimer, SIGNAL( timeout() ), this, SLOT( slotTransientLabel() ) );
47 setMouseTracking( true );
49 m_molcalcIsActive = false;
50 m_learningMode = false;
51 m_showTooltip = false;
52 m_timeline = false;
53 m_showSOM = false;
55 //IUPAC
56 m_IUPAClist.append( "IA");
57 m_IUPAClist.append( "IIA");
58 m_IUPAClist.append( "IIIB");
59 m_IUPAClist.append( "IVB");
60 m_IUPAClist.append( "VB");
61 m_IUPAClist.append( "VIB");
62 m_IUPAClist.append( "VIIB");
63 m_IUPAClist.append( "VIII");
64 m_IUPAClist.append( "VIII");
65 m_IUPAClist.append( "VIII");
66 m_IUPAClist.append( "IB");
67 m_IUPAClist.append( "IIB");
68 m_IUPAClist.append( "IIIA");
69 m_IUPAClist.append( "IVA");
70 m_IUPAClist.append( "VA");
71 m_IUPAClist.append( "VIA");
72 m_IUPAClist.append( "VIIA");
73 m_IUPAClist.append( "VIIIA");
75 //oldIUPAC
76 m_IUPACOLDlist.append( "1A");
77 m_IUPACOLDlist.append( "2A");
78 m_IUPACOLDlist.append( "3A");
79 m_IUPACOLDlist.append( "4A");
80 m_IUPACOLDlist.append( "5A");
81 m_IUPACOLDlist.append( "6A");
82 m_IUPACOLDlist.append( "7A");
83 m_IUPACOLDlist.append( "8");
84 m_IUPACOLDlist.append( "8");
85 m_IUPACOLDlist.append( "8");
86 m_IUPACOLDlist.append( "1B");
87 m_IUPACOLDlist.append( "2B");
88 m_IUPACOLDlist.append( "3B");
89 m_IUPACOLDlist.append( "4B");
90 m_IUPACOLDlist.append( "5B");
91 m_IUPACOLDlist.append( "6B");
92 m_IUPACOLDlist.append( "7B");
93 m_IUPACOLDlist.append( "0");
95 table = new QPixmap();
97 //JH: For now, always do a full draw
98 doFullDraw = true;
101 void PSE::slotToolTip( int number )
103 if ( m_learningMode ) return;
105 m_showTooltip = true;
106 m_tooltipElementNumber = number;
107 update();
110 PSE::~PSE(){}
112 void PSE::updateNumeration()
116 void PSE::activateColorScheme( const int nr )
118 EList::Iterator it = d->ElementList.begin();
119 const EList::Iterator itEnd = d->ElementList.end();
121 if ( nr == 0) //normal view, no colors
123 const QColor color = Prefs::noscheme();
124 while ( it != itEnd )
126 ( *it )->setElementColor( color );
127 ++it;
130 else if ( nr == 1) //groups view
132 const QColor color_1 = Prefs::group_1();
133 const QColor color_2 = Prefs::group_2();
134 const QColor color_3 = Prefs::group_3();
135 const QColor color_4 = Prefs::group_4();
136 const QColor color_5 = Prefs::group_5();
137 const QColor color_6 = Prefs::group_6();
138 const QColor color_7 = Prefs::group_7();
139 const QColor color_8 = Prefs::group_8();
141 static QString group;
143 while ( it != itEnd )
145 group = ( *it )->group();
147 if (group == QString("1")) {
148 ( *it )->setElementColor( color_1 );
150 if (group == QString("2")){
151 ( *it )->setElementColor( color_2 );
153 if (group == QString("3")){
154 ( *it )->setElementColor( color_3 );
156 if (group == QString("4")){
157 ( *it )->setElementColor( color_4 );
159 if (group == QString("5")){
160 ( *it )->setElementColor( color_5 );
162 if (group == QString("6")){
163 ( *it )->setElementColor( color_6 );
165 if (group == QString("7")){
166 ( *it )->setElementColor( color_7 );
168 if (group == QString("8")){
169 ( *it )->setElementColor( color_8 );
172 ++it;
175 else if ( nr == 2) //block view
177 const QColor color_s = Prefs::block_s();
178 const QColor color_p = Prefs::block_p();
179 const QColor color_d = Prefs::block_d();
180 const QColor color_f = Prefs::block_f();
182 static QString block;
183 while ( it != itEnd )
185 block = (*it)->block();
187 if (block == QString("s")) {
188 (*it)->setElementColor( color_s );
190 if (block == QString("p")) {
191 (*it)->setElementColor( color_p );
193 if (block == QString("d")) {
194 (*it)->setElementColor( color_d );
196 if (block == QString("f")) {
197 (*it)->setElementColor( color_f );
199 ++it;
202 else if ( nr == 3) //acidic beh
204 const QColor color_ba = Prefs::beh_basic();
205 const QColor color_ac = Prefs::beh_acidic();
206 const QColor color_neu = Prefs::beh_neutral();
207 const QColor color_amp = Prefs::beh_amphoteric();
209 static QString acidicbeh;
211 while ( it != itEnd )
213 acidicbeh = ( *it )->acidicbeh();
215 if (acidicbeh == QString("0")) {
216 (*it)->setElementColor( color_ac );
218 if (acidicbeh == QString("1")){
219 (*it)->setElementColor( color_ba );
221 if (acidicbeh == QString("2")){
222 (*it)->setElementColor( color_neu );
224 if (acidicbeh == QString("3")){
225 (*it)->setElementColor( color_amp );
227 ++it;
230 else if ( nr == 4) //familiy of the element
232 const QColor c_alkalie = Prefs::alkalie();
233 const QColor c_rare = Prefs::rare();
234 const QColor c_nonmetal = Prefs::nonmetal();
235 const QColor c_alkaline = Prefs::alkaline();
236 const QColor c_other_metal = Prefs::other_metal();
237 const QColor c_halogene = Prefs::halogene();
238 const QColor c_transition = Prefs::transition();
239 const QColor c_noble_gas = Prefs::noble_gas();
240 const QColor c_metalloid = Prefs::metalloid();
242 static QString family;
244 while ( it != itEnd )
246 family = ( *it )->family();
248 if ( family == "Noblegas" ){
249 (*it)->setElementColor( c_noble_gas );
251 if ( family == "Non-Metal" ){
252 (*it)->setElementColor( c_nonmetal );
254 if ( family == "Rare_Earth" ){
255 (*it)->setElementColor( c_rare );
257 if ( family == "Alkaline_Earth" ){
258 (*it)->setElementColor( c_alkaline );
260 if ( family == "Alkali_Earth" ){
261 (*it)->setElementColor( c_alkalie );
263 if ( family == "Transition" ){
264 (*it)->setElementColor( c_transition );
266 if ( family == "Other_Metal" ){
267 (*it)->setElementColor( c_other_metal );
269 if ( family == "Metalloids" ){
270 (*it)->setElementColor( c_metalloid );
272 if ( family == "Halogene" ){
273 (*it)->setElementColor( c_halogene );
277 ++it;
284 void PSE::resizeEvent( QResizeEvent * /*e*/ )
286 table->resize( width(), height() );
289 void PSE::paintEvent( QPaintEvent * /*e*/ )
291 QPainter p;
293 if ( doFullDraw ) {
294 p.begin( table );
295 p.fillRect( 0, 0, width(), height(), paletteBackgroundColor() ); //CN what is this line for?
296 //X if ( m_showSOM )
297 //X drawSOMPSE( &p );
298 //X else
299 drawPSE( &p, m_isSimple );
301 if ( m_showLegend )
302 drawLegend( &p );
304 if ( m_showTooltip )
306 if ( m_tooltipElementNumber < 112 && m_tooltipElementNumber > 0 )
308 Element *e = d->element( m_tooltipElementNumber );
309 drawToolTip( &p, e );
311 else
312 qWarning( "wrong number" );
315 p.end();
316 //JH: Uncomment when ready for this
317 // doFullDraw = false;
320 bitBlt( this, 0, 0, table );
323 void PSE::drawToolTip( QPainter* p, Element *e )
325 if ( !e ) return;
327 int x1 = mapFromGlobal( QCursor::pos() ).x();
328 int y1 = mapFromGlobal( QCursor::pos() ).y();
329 int w = 100;
330 int h = 100;
332 //coordinates for element symbol: near the center
333 int xA = x1 + w - ( 4 * w / 10 );
334 int yA = y1 + h - ( h / 2 );
336 p->setBrush(Qt::SolidPattern);
337 p->setBrush( Qt::yellow );
338 p->drawRect( x1 , y1 , w, h );
340 p->setBrush( Qt::black );
341 p->setBrush(Qt::NoBrush);
343 QFont fA = KGlobalSettings::generalFont();
344 QFont fB = KGlobalSettings::generalFont();
345 QFont fC = KGlobalSettings::generalFont();
347 fA.setPointSize( fA.pointSize() + 20 ); //Huge font
348 fA.setBold( true );
349 fB.setPointSize( fB.pointSize() + 6 ); //Big font
350 fC.setPointSize( fC.pointSize() + 4 ); //Big font
351 fC.setBold( true );
352 QFontMetrics fmA = QFontMetrics( fA );
353 QFontMetrics fmB = QFontMetrics( fB );
354 QFontMetrics fmC = QFontMetrics( fC );
356 //coordinates for the atomic number: offset from element symbol to the upper left
357 int xB = xA - fmB.width( QString::number( e->number() ) );
358 int yB = yA - fmA.height() + fmB.height();
360 //Atomic number
361 p->setFont( fB );
362 p->drawText( xB, yB, QString::number( e->number() ));
364 //Name and other data
365 p->setFont( fC );
366 //Name
367 p->drawText( x1, y1+15, i18n( e->elname().utf8() ));
368 //Weight
369 p->drawText( x1, y1+h-15, QString::number( e->weight() ));
373 void PSE::drawLegend( QPainter* p )
379 void PSE::drawSOMPSE( QPainter* p )
381 EList::Iterator it = d->ElementList.begin();
383 while ( it != d->ElementList.end() )
385 ( *it )->drawStateOfMatter( p, m_temperature );
386 ++it;
391 void PSE::slotTransientLabel( void )
393 int X = mapFromGlobal( QCursor::pos() ).x()/45;
394 int Y = mapFromGlobal( QCursor::pos() ).y()/45;
395 if ( m_isSimple )
397 if ( mapFromGlobal( QCursor::pos() ).x() > ( 2*45 ) )
399 X += 10;
403 X += 1;
404 Y += 1;
406 QPoint point( X,Y );
408 const int num = ElementNumber( X, Y );
409 if ( num )
410 emit ToolTip( num );
413 void PSE::mouseMoveEvent( QMouseEvent *mouse )
415 m_showTooltip = false;
416 HoverTimer.start( 2000, false );
419 void PSE::mouseReleaseEvent( QMouseEvent *mouse )
421 ///first: find out the position
423 int X = mouse->x()/45;
424 int Y = mouse->y()/45;
425 if ( m_isSimple )
427 if ( mouse->x() > ( 2*45 ) )
429 X += 10;
433 X += 1;
434 Y += 1;
436 QPoint point( X,Y );
437 emit tableClicked( point );
439 const int num = ElementNumber( X, Y );
440 if ( num )
441 emit ElementClicked( num );
444 int PSE::ElementNumber( int X, int Y )
446 //from this on I can use X and Y. Both contain the position of an element in the
447 //complete PSE. Eg, He is 1,18 and Na is 2,1
449 CList::ConstIterator it = d->CoordinateList.begin();
451 int counter = 1;
452 while ( it != d->CoordinateList.end() )
453 {//iterate through the list of coordinates and compare the x/y values.
454 //finally, if the 20'es iterator has the same cooridnates Element 20
455 //has been clicked.
457 coordinate c = *it;
458 if ( c.x == X )
460 if ( c.y == Y )
461 {//coordinates match. Get the position of the it in the list.
462 return counter;
465 ++it;
466 ++counter;
469 return 0;
472 void PSE::slotUpdatePoint( QPoint point )
474 m_currentPoint = point;
476 update();
479 void PSE::drawPSE( QPainter* p, bool useSimpleView )
481 EList::Iterator it = d->ElementList.begin();
483 int coordinate = 0;
484 m_Vertikal ? coordinate = m_currentPoint.x() : coordinate = m_currentPoint.y();
487 * this loop iterates through all elements. The Elements
488 * draw themselfs, the PSE only tells them to do so
490 while ( it != d->ElementList.end() )
492 ( *it )->drawSelf( p, useSimpleView );
493 if ( m_learningMode )
494 ( *it )->drawHighlight( p, coordinate, m_Vertikal );
495 ++it;
501 #include "pse.moc"