summaryrefslogtreecommitdiffstats
path: root/kalzium/src/periodictableview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kalzium/src/periodictableview.cpp')
-rw-r--r--kalzium/src/periodictableview.cpp1382
1 files changed, 1382 insertions, 0 deletions
diff --git a/kalzium/src/periodictableview.cpp b/kalzium/src/periodictableview.cpp
new file mode 100644
index 00000000..b466cffa
--- /dev/null
+++ b/kalzium/src/periodictableview.cpp
@@ -0,0 +1,1382 @@
+/***************************************************************************
+ * Copyright (C) 2003-2005 by Carsten Niehaus *
+ * cniehaus@kde.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "periodictableview.h"
+#include "prefs.h"
+#include "element.h"
+#include "kalziumtip.h"
+#include "kalziumutils.h"
+#include "kalziumdataobject.h"
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kpixmapeffect.h>
+#include <kimageeffect.h>
+
+#include <qimage.h>
+#include <qstring.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qlabel.h>
+#include <qpixmap.h>
+#include <qpoint.h>
+#include <qcursor.h>
+#include <qpainter.h>
+#include <qcolor.h>
+#include <qrect.h>
+
+PerodicTableView::PerodicTableView(QWidget *parent, const char *name)
+ : QWidget(parent, name), m_kalziumTip(0), table(0), table2(0)
+{
+ d = KalziumDataObject::instance();
+
+
+ // No selection
+ unSelect();
+
+#if 0
+ connect( this, SIGNAL( tableClicked( QPoint ) ),
+ this, SLOT( selectPoint( QPoint ) ) );
+#endif
+ connect( this, SIGNAL( ToolTip( int ) ),
+ this, SLOT( slotToolTip( int ) ) );
+
+ connect( &HoverTimer, SIGNAL( timeout() ),
+ this, SLOT( slotTransientLabel() ) );
+
+ connect( &MouseoverTimer, SIGNAL( timeout() ),
+ this, SLOT( slotMouseover() ) );
+
+ setMouseTracking( true );
+
+ //JH: eliminates flicker on redraw
+ setBackgroundMode( QWidget::NoBackground );
+
+ m_molcalcIsActive = false;
+ m_showTooltip = true;
+ m_showLegend = Prefs::showlegend();
+ m_showLegendTooltip = Prefs::tooltip();
+ m_timeline = false;
+ m_showSOM = false;
+ m_showGradient = false;
+ m_tooltipsEnabled = Prefs::tooltip();
+
+ reloadColours();
+
+ //IUPAC
+ m_IUPAClist.append( "IA");
+ m_IUPAClist.append( "IIA");
+ m_IUPAClist.append( "IIIB");
+ m_IUPAClist.append( "IVB");
+ m_IUPAClist.append( "VB");
+ m_IUPAClist.append( "VIB");
+ m_IUPAClist.append( "VIIB");
+ m_IUPAClist.append( "VIII");
+ m_IUPAClist.append( "VIII");
+ m_IUPAClist.append( "VIII");
+ m_IUPAClist.append( "IB");
+ m_IUPAClist.append( "IIB");
+ m_IUPAClist.append( "IIIA");
+ m_IUPAClist.append( "IVA");
+ m_IUPAClist.append( "VA");
+ m_IUPAClist.append( "VIA");
+ m_IUPAClist.append( "VIIA");
+ m_IUPAClist.append( "VIIIA");
+
+ //oldIUPAC
+ m_IUPACOLDlist.append( "1A");
+ m_IUPACOLDlist.append( "2A");
+ m_IUPACOLDlist.append( "3A");
+ m_IUPACOLDlist.append( "4A");
+ m_IUPACOLDlist.append( "5A");
+ m_IUPACOLDlist.append( "6A");
+ m_IUPACOLDlist.append( "7A");
+ m_IUPACOLDlist.append( "8");
+ m_IUPACOLDlist.append( "8");
+ m_IUPACOLDlist.append( "8");
+ m_IUPACOLDlist.append( "1B");
+ m_IUPACOLDlist.append( "2B");
+ m_IUPACOLDlist.append( "3B");
+ m_IUPACOLDlist.append( "4B");
+ m_IUPACOLDlist.append( "5B");
+ m_IUPACOLDlist.append( "6B");
+ m_IUPACOLDlist.append( "7B");
+ m_IUPACOLDlist.append( "0");
+
+ table = new QPixmap();
+ table2 = new QPixmap();
+
+ m_kalziumTip = new KalziumTip( this );
+
+ //JH: Start with a full draw
+ doFullDraw = true;
+
+ // according to carsten :)
+ setMinimumSize(ELEMENTSIZE*18+1, ELEMENTSIZE*10+30);
+}
+
+void PerodicTableView::reloadColours()
+{
+ color_s = Prefs::block_s();
+ color_p = Prefs::block_p();
+ color_d = Prefs::block_d();
+ color_f = Prefs::block_f();
+ color_1 = Prefs::group_1();
+ color_2 = Prefs::group_2();
+ color_3 = Prefs::group_3();
+ color_4 = Prefs::group_4();
+ color_5 = Prefs::group_5();
+ color_6 = Prefs::group_6();
+ color_7 = Prefs::group_7();
+ color_8 = Prefs::group_8();
+ color_ba = Prefs::beh_basic();
+ color_ac = Prefs::beh_acidic();
+ color_neu = Prefs::beh_neutral();
+ color_amp = Prefs::beh_amphoteric();
+ c_alkalie = Prefs::alkalie();
+ c_rare = Prefs::rare();
+ c_nonmetal = Prefs::nonmetal();
+ c_alkaline = Prefs::alkaline();
+ c_other_metal = Prefs::other_metal();
+ c_halogene = Prefs::halogene();
+ c_transition = Prefs::transition();
+ c_noble_gas = Prefs::noble_gas();
+ c_metalloid = Prefs::metalloid();
+ c_solid = Prefs::color_solid();
+ c_vapor = Prefs::color_vapor();
+ c_liquid = Prefs::color_liquid();
+}
+
+void PerodicTableView::slotToolTip( int number )
+{
+ if ( !m_showTooltip || !m_tooltipsEnabled )
+ return; //don't update if the table is locked
+
+ m_tooltipElementNumber = number;
+
+ QWidget *p = 0;
+ if ( dynamic_cast<QWidget*>( parent() ) )
+ p = static_cast<QWidget*>( parent() );
+
+ if( p )
+ m_kalziumTip->showTip( mapFromGlobal(QCursor::pos()),
+ d->element(number),
+ p->width(),
+ p->height() );
+}
+
+PerodicTableView::~PerodicTableView(){}
+
+void PerodicTableView::activateColorScheme( const int nr )
+{
+ m_currentScheme = nr;
+
+ EList::ConstIterator it = d->ElementList.begin();
+ const EList::ConstIterator itEnd = d->ElementList.end();
+
+ if ( m_currentScheme == PerodicTableView::NOCOLOUR ) //normal view, no colors
+ {
+ const QColor color = Prefs::noscheme();
+ while ( it != itEnd )
+ {
+ ( *it )->setElementColor( color );
+ ++it;
+ }
+ }
+ else if ( m_currentScheme == PerodicTableView::GROUPS ) //groups view
+ {
+
+ static QString group;
+
+ while ( it != itEnd )
+ {
+ group = ( *it )->group();
+
+ if (group == QString("1")) {
+ ( *it )->setElementColor( color_1 );
+ }
+ if (group == QString("2")){
+ ( *it )->setElementColor( color_2 );
+ }
+ if (group == QString("3")){
+ ( *it )->setElementColor( color_3 );
+ }
+ if (group == QString("4")){
+ ( *it )->setElementColor( color_4 );
+ }
+ if (group == QString("5")){
+ ( *it )->setElementColor( color_5 );
+ }
+ if (group == QString("6")){
+ ( *it )->setElementColor( color_6 );
+ }
+ if (group == QString("7")){
+ ( *it )->setElementColor( color_7 );
+ }
+ if (group == QString("8")){
+ ( *it )->setElementColor( color_8 );
+ }
+
+ ++it;
+ }
+ }
+ else if ( m_currentScheme == PerodicTableView::BLOCK ) //block view
+ {
+ static QString block;
+ while ( it != itEnd )
+ {
+ block = (*it)->block();
+
+ if (block == QString("s")) {
+ (*it)->setElementColor( color_s );
+ }
+ if (block == QString("p")) {
+ (*it)->setElementColor( color_p );
+ }
+ if (block == QString("d")) {
+ (*it)->setElementColor( color_d );
+ }
+ if (block == QString("f")) {
+ (*it)->setElementColor( color_f );
+ }
+ ++it;
+ }
+ }
+ else if ( m_currentScheme == PerodicTableView::ACIDIC ) //acidic beh
+ {
+ static QString acidicbeh;
+
+ while ( it != itEnd )
+ {
+ acidicbeh = ( *it )->acidicbeh();
+
+ if (acidicbeh == QString("0")) {
+ (*it)->setElementColor( color_ac );
+ }
+ if (acidicbeh == QString("1")){
+ (*it)->setElementColor( color_ba );
+ }
+ if (acidicbeh == QString("2")){
+ (*it)->setElementColor( color_neu );
+ }
+ if (acidicbeh == QString("3")){
+ (*it)->setElementColor( color_amp );
+ }
+ ++it;
+ }
+ }
+ else if ( m_currentScheme == PerodicTableView::FAMILY ) //familiy of the element
+ {
+ static QString family;
+
+ while ( it != itEnd )
+ {
+ family = ( *it )->family();
+
+ if ( family == "Noblegas" ){
+ (*it)->setElementColor( c_noble_gas );
+ }
+ if ( family == "Non-Metal" ){
+ (*it)->setElementColor( c_nonmetal );
+ }
+ if ( family == "Rare_Earth" ){
+ (*it)->setElementColor( c_rare );
+ }
+ if ( family == "Alkaline_Earth" ){
+ (*it)->setElementColor( c_alkaline );
+ }
+ if ( family == "Alkali_Earth" ){
+ (*it)->setElementColor( c_alkalie );
+ }
+ if ( family == "Transition" ){
+ (*it)->setElementColor( c_transition );
+ }
+ if ( family == "Other_Metal" ){
+ (*it)->setElementColor( c_other_metal );
+ }
+ if ( family == "Metalloids" ){
+ (*it)->setElementColor( c_metalloid );
+ }
+ if ( family == "Halogene" ){
+ (*it)->setElementColor( c_halogene );
+ }
+
+ ++it;
+ }
+ }
+
+}
+
+void PerodicTableView::resizeEvent( QResizeEvent * /*e*/ )
+{
+ table->resize( width(), height() );
+ table2->resize( width(), height() );
+ // XXX: I know it isn't the best way, but otherwise the table won't be redrawn
+ // on repaint... Feel *free* to remove these two lines if you foind a better
+ // solution...
+ doFullDraw = true;
+ update();
+}
+
+void PerodicTableView::paintEvent( QPaintEvent * /*e*/ )
+{
+ QPainter p;
+
+ //JH: I have split the drawing into two pixmaps: table and table2.
+ //table contains the "static" PerodicTableView table, and does not change very often.
+ //table2 contains the tooltips and any other dynamic overlays.
+ //Usually, we can skip the code which renders the table, and just use the
+ //image stored in table...when doFullDraw==false, the rendering code is skipped.
+ if ( doFullDraw )
+ {
+ //DEBUG
+ kdDebug() << "Drawing full table" << endl;
+
+ p.begin( table );
+ p.fillRect( 0, 0, width(), height(), paletteBackgroundColor() );
+
+ // Draw the numbers above the table.
+ drawNumeration( &p );
+
+ drawLegend( &p );
+
+ if ( m_timeline )
+ { //use timeline
+ drawTimeLine(& p );
+ p.end();
+
+ *table2 = *table;
+ bitBlt( this, 0, 0, table2 );
+ return;
+ }
+ if ( som() )
+ {//use state of matter
+ drawSOMPerodicTableView(& p );
+ p.end();
+
+ *table2 = *table;
+ bitBlt( this, 0, 0, table2 );
+ return;
+ }
+ if ( gradient() )
+ {//show a gradient
+ calculateGradient(& p );
+ p.end();
+
+ *table2 = *table;
+ bitBlt( this, 0, 0, table2 );
+ return;
+ }
+
+ drawPerodicTableView( &p, m_currentScheme == CRYSTAL );
+
+ paintCurrentSelection();
+
+ p.end();
+
+ doFullDraw = false;
+ }
+
+ //JH: Ok, now table contains the static PerodicTableView table, and we may need to draw
+ //a tooltip on it. However, we don't want to ruin the stored table pixmap,
+ //so let's copy it to table2 and add the tooltip there.
+ *table2 = *table;
+
+ //JH: Finally, bitBlt the table2 pixmap to the widget
+ bitBlt( this, 0, 0, table2 );
+}
+
+void PerodicTableView::paintCurrentSelection()
+{
+ if (m_currentPoint.x() == -1)
+ return;
+
+ int x = (m_currentPoint.x()-1)*ELEMENTSIZE;
+ int y = m_currentPoint.y()*ELEMENTSIZE;
+
+ // make a small gap (ELEMENTSIZE/3) over the rare earths
+ if (m_currentPoint.y() > 7) y += ELEMENTSIZE/3;
+
+ QPainter p;
+ p.begin(table);
+
+ QPen pen;
+ pen.setStyle( DotLine );
+ pen.setWidth( 4 );
+ pen.setColor( Qt::blue );
+ p.setPen( pen );
+
+ p.drawEllipse( x-10,y-10,ELEMENTSIZE+20,ELEMENTSIZE+20 );
+ pen.setWidth( 3 );
+ pen.setColor( Qt::red );
+ p.setPen( pen );
+ p.drawEllipse( x-5,y-5,ELEMENTSIZE+10,ELEMENTSIZE+10 );
+
+ p.end();
+}
+
+void PerodicTableView::drawLegendToolTip( QPainter* p )
+{
+ kdDebug() << "PerodicTableView::drawLegendToolTip()" << endl;
+ if(!m_showLegendTooltip || !m_showLegend) return;
+
+ QString text;
+
+ switch ( m_currentScheme ) {
+ //No Legend drawn as only one colour is used
+ case PerodicTableView::NOCOLOUR:
+ break;
+ case PerodicTableView::BLOCK:
+ text = i18n( "The periodic table can be split up into four areas:\n the s-, p-, d- and f-Block. The name indicates which orbit\n is being filled last. For example, all elements in the s-block\n fill up the s-orbits." );
+ break;
+ case PerodicTableView::GROUPS:
+ text = i18n( "The periodic table can be split up into groups:\n All elements in a group show similar behaviour");
+ break;
+ case PerodicTableView::ACIDIC:
+ text = i18n( "The periodic table can be split up in groups of \nelements with different acidic behaviour.");
+ break;
+ case PerodicTableView::FAMILY:
+ text = i18n( "The periodic table can be split up into several families.");
+ break;
+ }
+
+ const int x1 = mapFromGlobal( QCursor::pos() ).x();
+ const int y1 = mapFromGlobal( QCursor::pos() ).y();
+
+ static const int padding = 3;
+
+ QFont fB = KGlobalSettings::generalFont();
+ fB.setPointSize( fB.pointSize() + 4 );
+ p->setFont( fB );
+
+ QRect bRect( 0, 0, 1000, 1000 );
+ bRect = p->boundingRect( bRect, AlignLeft|AlignTop, text );
+ bRect.moveBy( x1, y1 );
+ QRect bRectExt = bRect;
+ bRect.moveBy( padding, padding );
+ bRectExt.setWidth( bRectExt.width() + 2 * padding );
+ bRectExt.setHeight( bRectExt.height() + 2 * padding );
+
+ bool vertflipped = false;
+ if ( bRectExt.bottom() > height() )
+ {
+ bRectExt.moveBy( 0, - bRectExt.height() );
+ bRect.moveBy( 0, - bRect.height() - 2 * padding );
+ vertflipped = true;
+ }
+ if ( bRectExt.right() > width() )
+ {
+ bRectExt.moveBy( - bRectExt.width(), 0 );
+ bRect.moveBy( - bRect.width() - 2 * padding, 0 );
+ }
+ else if ( !vertflipped )
+ {
+ bRectExt.moveBy( 15, 0 );
+ bRect.moveBy( 15, 0 );
+ }
+
+ p->setBrush(Qt::SolidPattern);
+ p->setBrush( QColor( 255, 255, 220 ) );
+ p->drawRect( bRectExt );
+
+ p->setBrush( Qt::black );
+ p->setBrush(Qt::NoBrush);
+
+ p->drawText( bRect, AlignLeft|AlignTop, text );
+}
+
+void PerodicTableView::drawTimeLine( QPainter* p )
+{
+ if ( !p ) return;
+ kdDebug() << "PerodicTableView::drawTimeLine: " << m_date << endl;
+
+ if ( gradient() )
+ activateColorScheme( PerodicTableView::NOCOLOUR );
+
+ EList::ConstIterator it = d->ElementList.begin();
+ const EList::ConstIterator itEnd = d->ElementList.end();
+
+ bool simple = Prefs::pselook();
+
+ /**
+ * this loop iterates through all elements. The Elements
+ * draw themselfs, the PerodicTableView only tells them to do so
+ */
+ while ( it != itEnd )
+ {
+ if ( ( *it )->date() <= m_date )
+ ( *it )->drawSelf( p, simple );
+ else
+ ( *it )->drawGrayedOut( p );
+ ++it;
+ }
+}
+
+void PerodicTableView::drawLegend( QPainter* p )
+{
+ if ( !p ) return;
+
+ if ( !m_showLegend ) return;
+
+ /*
+ * The legend is drawn in the big gap of the table. The gap has
+ * this size:
+ *
+ * width: ELEMENTSIZE * 10
+ * height: ELEMENTSIZE * 3
+ *
+ * We need to spare a few pixels on every side so that the legend
+ * does not collide with the elements
+ */
+
+ QFont legendFont = KGlobalSettings::generalFont();
+ legendFont.setPointSize( legendFont.pointSize() + 1 );
+ p->setFont( legendFont );
+
+ int legendLeft = ELEMENTSIZE * 5 / 2;
+ int legendTop = ELEMENTSIZE * 3 / 4;
+ int legendWidth = ELEMENTSIZE * 9;
+ int legendHeight = ELEMENTSIZE * 3;
+
+ int x1 = legendLeft + ELEMENTSIZE / 2;
+ int x2 = legendLeft + ELEMENTSIZE * 5;
+
+ /*
+ * one field is allowed to be half the gap minus 10 pixel
+ */
+ int fieldsize = ELEMENTSIZE*5-10;
+
+ /*
+ * one field is a maximum of half the size of an element
+ */
+ int fieldheight = ELEMENTSIZE/2;
+
+
+ const int square_w = 18;
+ const int square_h = 18;
+ const int textOffset = square_w + 10;
+
+ if ( !m_currentScheme == PerodicTableView::NOCOLOUR )
+ p->fillRect(legendLeft, legendTop, legendWidth, legendHeight,
+ QColor(200, 200, 200));
+
+ if ( som() )
+ {
+ p->fillRect(x1, fieldheight*2, square_w, square_h, c_solid );
+ p->fillRect(x1, fieldheight*3, square_w, square_h, c_liquid );
+ p->fillRect(x1, fieldheight*4, square_w, square_h, c_vapor );
+
+ p->drawText(x1 + textOffset, fieldheight*2, fieldsize, fieldheight, Qt::AlignLeft, i18n("Solid") );
+ p->drawText(x1 + textOffset, fieldheight*3, fieldsize, fieldheight, Qt::AlignLeft, i18n("Liquid") );
+ p->drawText(x1 + textOffset, fieldheight*4, fieldsize, fieldheight, Qt::AlignLeft, i18n("Vaporous") );
+ return;
+ }
+ switch ( m_currentScheme ){
+ //No Legend to be drawn as only one colour is used
+ case PerodicTableView::NOCOLOUR:
+ break;
+ case PerodicTableView::GROUPS:
+ p->fillRect( x1, fieldheight*2, square_w, square_h, color_1);
+ p->fillRect( x1, fieldheight*3, square_w, square_h, color_2);
+ p->fillRect( x1, fieldheight*4, square_w, square_h, color_3);
+ p->fillRect( x1, fieldheight*5, square_w, square_h, color_4);
+ p->fillRect( x2, fieldheight*2, square_w, square_h, color_5);
+ p->fillRect( x2, fieldheight*3, square_w, square_h, color_6);
+ p->fillRect( x2, fieldheight*4, square_w, square_h, color_7);
+ p->fillRect( x2, fieldheight*5, square_w, square_h, color_8 );
+
+ p->drawText( x1 + textOffset , fieldheight*2, fieldsize, fieldheight, Qt::AlignLeft, i18n("Group 1") );
+ p->drawText( x1 + textOffset , fieldheight*3, fieldsize, fieldheight, Qt::AlignLeft, i18n("Group 2"));
+ p->drawText( x1 + textOffset , fieldheight*4, fieldsize, fieldheight, Qt::AlignLeft, i18n("Group 3"));
+ p->drawText( x1 + textOffset , fieldheight*5, fieldsize, fieldheight, Qt::AlignLeft, i18n("Group 4"));
+ p->drawText( x2 + textOffset , fieldheight*2, fieldsize, fieldheight, Qt::AlignLeft, i18n("Group 5"));
+ p->drawText( x2 + textOffset , fieldheight*3, fieldsize, fieldheight, Qt::AlignLeft, i18n("Group 6"));
+ p->drawText( x2 + textOffset , fieldheight*4, fieldsize, fieldheight, Qt::AlignLeft, i18n("Group 7"));
+ p->drawText( x2 + textOffset , fieldheight*5, fieldsize, fieldheight, Qt::AlignLeft, i18n("Group 8"));
+ break;
+ case PerodicTableView::BLOCK:
+ p->fillRect(x1, fieldheight*2, square_w, square_h, color_s );
+ p->fillRect(x1, fieldheight*3, square_w, square_h, color_p );
+ p->fillRect(x1, fieldheight*4, square_w, square_h, color_d );
+ p->fillRect(x1, fieldheight*5, square_w, square_h, color_f );
+
+ p->drawText(x1 + textOffset, fieldheight*2, fieldsize, fieldheight, Qt::AlignLeft, i18n("s-Block") );
+ p->drawText(x1 + textOffset, fieldheight*3, fieldsize, fieldheight, Qt::AlignLeft, i18n("p-Block") );
+ p->drawText(x1 + textOffset, fieldheight*4, fieldsize, fieldheight, Qt::AlignLeft, i18n("d-Block") );
+ p->drawText(x1 + textOffset, fieldheight*5, fieldsize, fieldheight, Qt::AlignLeft, i18n("f-Block") );
+ break;
+ case PerodicTableView::ACIDIC:
+ p->fillRect(x1, fieldheight*2, square_w, square_h, color_ba );
+ p->fillRect(x1, fieldheight*3, square_w, square_h, color_neu );
+ p->fillRect(x1, fieldheight*4, square_w, square_h, color_ac );
+ p->fillRect(x1, fieldheight*5, square_w, square_h, color_amp );
+
+ p->drawText(x1 + textOffset, fieldheight*2, fieldsize, fieldheight, Qt::AlignLeft, i18n("Basic") );
+ p->drawText(x1 + textOffset, fieldheight*3, fieldsize, fieldheight, Qt::AlignLeft, i18n("Neutral") );
+ p->drawText(x1 + textOffset, fieldheight*4, fieldsize, fieldheight, Qt::AlignLeft, i18n("Acidic") );
+ p->drawText(x1 + textOffset, fieldheight*5, fieldsize, fieldheight, Qt::AlignLeft, i18n("both acidic and basic behaviour","Amphoteric") );
+ break;
+ case PerodicTableView::FAMILY:
+ p->fillRect( x1, fieldheight*2, square_w, square_h, c_alkaline );
+ p->fillRect( x2, fieldheight*2, square_w, square_h, c_rare );
+ p->fillRect( x1, fieldheight*3, square_w, square_h, c_nonmetal );
+ p->fillRect( x2, fieldheight*3, square_w, square_h, c_alkalie );
+ p->fillRect( x1, fieldheight*4, square_w, square_h, c_other_metal );
+ p->fillRect( x2, fieldheight*4, square_w, square_h, c_halogene );
+ p->fillRect( x1, fieldheight*5, square_w, square_h, c_transition );
+ p->fillRect( x2, fieldheight*5, square_w, square_h, c_noble_gas );
+ p->fillRect( x1, fieldheight*6, square_w, square_h, c_metalloid );
+
+ p->drawText( x1 + textOffset , fieldheight*2, fieldsize, fieldheight, Qt::AlignLeft, i18n("Alkaline") );
+ p->drawText( x2 + textOffset , fieldheight*2, fieldsize, fieldheight, Qt::AlignLeft, i18n("Rare Earth"));
+ p->drawText( x1 + textOffset , fieldheight*3, fieldsize, fieldheight, Qt::AlignLeft, i18n("Non-Metals"));
+ p->drawText( x2 + textOffset , fieldheight*3, fieldsize, fieldheight, Qt::AlignLeft, i18n("Alkalie-Metals"));
+ p->drawText( x1 + textOffset , fieldheight*4, fieldsize, fieldheight, Qt::AlignLeft, i18n("Other Metal"));
+ p->drawText( x2 + textOffset , fieldheight*4, fieldsize, fieldheight, Qt::AlignLeft, i18n("Halogene"));
+ p->drawText( x1 + textOffset , fieldheight*5, fieldsize, fieldheight, Qt::AlignLeft, i18n("Transition Metal"));
+ p->drawText( x2 + textOffset , fieldheight*5, fieldsize, fieldheight, Qt::AlignLeft, i18n("Noble Gas"));
+ p->drawText( x1 + textOffset , fieldheight*6, fieldsize, fieldheight, Qt::AlignLeft, i18n("Metalloid"));
+ break;
+ case PerodicTableView::CRYSTAL:
+ p->fillRect(x1, fieldheight*2, square_w, square_h, Qt::cyan );
+ p->fillRect(x1, fieldheight*3, square_w, square_h, Qt::red );
+ p->fillRect(x1, fieldheight*4, square_w, square_h, Qt::yellow );
+ p->fillRect(x1, fieldheight*5, square_w, square_h, Qt::green );
+ p->fillRect(x1, fieldheight*6, square_w, square_h, Qt::white );
+
+ p->drawText(x1 + textOffset, fieldheight*2, fieldsize, fieldheight, Qt::AlignLeft, i18n("Own") );
+ p->drawText(x1 + textOffset, fieldheight*3, fieldsize, fieldheight, Qt::AlignLeft, i18n("bcc, body centered cubic") );
+ p->drawText(x1 + textOffset, fieldheight*4, fieldsize, fieldheight, Qt::AlignLeft, i18n("hdp, hexagonal") );
+ p->drawText(x1 + textOffset, fieldheight*5, fieldsize, fieldheight, Qt::AlignLeft, i18n("ccp, cubic close packed") );
+ p->drawText(x1 + textOffset, fieldheight*6, fieldsize, fieldheight, Qt::AlignLeft, i18n("Unknown") );
+ break;
+ }
+}
+
+void PerodicTableView::drawNumeration( QPainter* p )
+{
+ if ( !p ) return;
+
+ switch(m_num){
+ case PerodicTableView::NO:
+ return;
+ case PerodicTableView::CAS:
+ for(int i = 0; i < 18 ; ++i )
+ {
+ p->drawText( i*ELEMENTSIZE,0 ,ELEMENTSIZE,ELEMENTSIZE, Qt::AlignCenter, QString::number(i+1));
+ }
+ break;
+ case PerodicTableView::IUPAC:
+ for(int i = 0; i < 18 ; ++i )
+ {
+ p->drawText( i*ELEMENTSIZE,0 ,ELEMENTSIZE,ELEMENTSIZE, Qt::AlignCenter, m_IUPAClist[i]);
+ }
+ break;
+ case PerodicTableView::IUPACOLD:
+ for(int i = 0; i < 18 ; ++i )
+ {
+ p->drawText( i*ELEMENTSIZE,0 ,ELEMENTSIZE,ELEMENTSIZE, Qt::AlignCenter, m_IUPACOLDlist[i]);
+ }
+ break;
+ }
+}
+
+
+void PerodicTableView::drawSOMPerodicTableView( QPainter* p )
+{
+ EList::ConstIterator it = d->ElementList.begin();
+ const EList::ConstIterator itEnd = d->ElementList.end();
+
+ while ( it != itEnd )
+ {
+ ( *it )->drawStateOfMatter( p, m_temperature );
+ ++it;
+ }
+
+}
+
+void PerodicTableView::slotTransientLabel()
+{
+ QPoint point = ElementUnderMouse();
+
+ int X = point.x();
+ int Y = point.y();
+
+ const int num = ElementNumber( X, Y );
+ if ( num )
+ emit ToolTip( num );
+ else if ( pointerOnLegend( X, Y ) ) //show the tooltip for the lengend
+ {
+ m_showLegendTooltip = true;
+ update();
+ }
+ else
+ m_showLegendTooltip = false;
+}
+
+void PerodicTableView::mousePressEvent( QMouseEvent *)
+{
+ if( m_kalziumTip->isVisible() )
+ m_kalziumTip->hide();
+}
+
+void PerodicTableView::mouseMoveEvent( QMouseEvent * /*mouse*/ )
+{
+ //JH: only update() if we were showing a tooltip
+ if ( m_tooltipElementNumber || m_showLegendTooltip )
+ {
+ //this invalidates the number. If the mouse
+ //is moved, the number is invalid.
+ m_tooltipElementNumber = 0;
+ m_showLegendTooltip = false;
+ update();
+ }
+
+ if( m_kalziumTip->isVisible() )
+ {
+// kdDebug()<< "visible" << endl;
+ QPoint point = ElementUnderMouse();
+
+ int X = point.x();
+ int Y = point.y();
+
+ const int num = ElementNumber( X, Y );
+
+ if ( num != 0 )
+ emit ToolTip( num );
+ else
+ m_kalziumTip->hide();
+ }
+
+ HoverTimer.start( 500, true ); //JH: true = run timer once, not continuously
+ MouseoverTimer.start( 200, true ); //JH: true = run timer once, not continuously
+}
+
+bool PerodicTableView::pointerOnLegend(int X, int Y)
+{
+ if ( X > 2 && X < 13 )
+ {
+ if ( Y < 4 && Y > 0 )
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void PerodicTableView::mouseReleaseEvent( QMouseEvent *mouse )
+{
+ ///first: find out the position
+ int X = mouse->x()/ELEMENTSIZE;
+
+ //for the y-position I need to substract ELEMENTSIZE pixel because
+ //the whole table doesn't start at (0,0) but at (0,ELEMENTSIZE)
+ int Y = mouse->y()-ELEMENTSIZE;
+
+ // ignore clicks on the small gap over rare earth
+ if (Y >= (ELEMENTSIZE*7) && Y < (ELEMENTSIZE*7+ELEMENTSIZE/3+1)) return;
+
+ // mind the gap!
+ if (Y > (ELEMENTSIZE*7)) Y -= ELEMENTSIZE/3;
+ Y /= ELEMENTSIZE;
+
+ X += 1;
+ Y += 1;
+
+ QPoint point( X,Y );
+ emit tableClicked( point );
+
+ const int num = ElementNumber( X, Y );
+
+ //kdDebug() << "Element clicked: " << num << endl;
+
+ //If no element was clicked ElementNumber() will return 0
+ if ( num ) {
+ emit ElementClicked( num );
+ selectPoint( point );
+ }
+}
+
+int PerodicTableView::ElementNumber( int X, int Y )
+{
+ //from this on I can use X and Y. Both contain the position of an element in the
+ //complete PerodicTableView. Eg, He is 1,18 and Na is 2,1
+
+ CList::ConstIterator it = d->CoordinateList.begin();
+ const CList::ConstIterator itEnd = d->CoordinateList.end();
+
+ int counter = 1;
+ while ( it != itEnd )
+ {//iterate through the list of coordinates and compare the x/y values.
+ //finally, if the 20'es iterator has the same coordinates Element 20
+ //has been clicked.
+
+ coordinate c = *it;
+ if ( c.x == X )
+ {
+ if ( c.y == Y )
+ {//coordinates match. Return the number of the element.
+ return counter;
+ }
+ }
+ ++it;
+ ++counter;
+ }
+
+ return 0;
+}
+
+
+void PerodicTableView::unSelect()
+{
+ m_currentPoint = QPoint(-1, -1);
+
+ // Full draw needed to redraw the select mark.
+ setFullDraw();
+ update();
+}
+
+void PerodicTableView::selectPoint( const QPoint& point )
+{
+ kdDebug() << "PerodicTableView::selectPoint " << point << endl;
+
+ m_currentPoint = point;
+
+ // Full draw needed to redraw the select mark.
+ setFullDraw();
+ update();
+}
+
+void PerodicTableView::selectElement( int num )
+{
+ kdDebug() << "PerodicTableView::selectElement " << num << endl;
+
+ selectPoint( d->element( num )->coords() );
+}
+
+void PerodicTableView::drawPerodicTableView( QPainter* p, bool isCrystal )
+{
+ EList::ConstIterator it = d->ElementList.begin();
+ const EList::ConstIterator itEnd = d->ElementList.end();
+
+ bool simple = Prefs::pselook();
+ /**
+ * this loop iterates through all elements. The Elements
+ * draw themselfs, the PerodicTableView only tells them to do so
+ */
+ while ( it != itEnd )
+ {
+ ( *it )->drawSelf( p, simple, isCrystal );
+ ++it;
+ }
+}
+
+//CN This is called for *every* drawing of the table. This means
+//a lot overload... I would be better to chache the values in
+//member variables an only check if they need an update.
+void PerodicTableView::calculateGradient( QPainter *p )
+{
+ EList::ConstIterator it = d->ElementList.begin();
+ const EList::ConstIterator itEnd = d->ElementList.end();
+
+ QValueList<double> tmpList;
+ switch ( m_gradientType )
+ {
+ case Element::ATOMICRADIUS:
+ for (; it != itEnd; ++it )
+ {
+ tmpList.append( ( *it )->radius(Element::ATOMIC) );
+ }
+ break;
+ case Element::COVALENTRADIUS:
+ for (; it != itEnd; ++it )
+ {
+ tmpList.append( ( *it )->radius(Element::COVALENT) );
+ }
+ break;
+ case Element::VDWRADIUS:
+ for (; it != itEnd; ++it )
+ {
+ tmpList.append( ( *it )->radius(Element::VDW) );
+ }
+ break;
+ case Element::MASS:
+ for (; it != itEnd; ++it )
+ {
+ tmpList.append( ( *it )->mass() );
+ }
+ break;
+ case Element::DENSITY:
+ for (; it != itEnd; ++it )
+ {
+ tmpList.append( ( *it )->density() );
+ }
+ break;
+ case Element::BOILINGPOINT:
+ for (; it != itEnd; ++it )
+ {
+ tmpList.append( ( *it )->boiling() );
+ }
+ break;
+ case Element::MELTINGPOINT:
+ for (; it != itEnd; ++it )
+ {
+ tmpList.append( ( *it )->melting() );
+ }
+ break;
+ case Element::EN:
+ for (; it != itEnd; ++it )
+ {
+ tmpList.append( ( *it )->electroneg() );
+ }
+ break;
+ case Element::EA:
+ for (; it != itEnd; ++it )
+ {
+ tmpList.append( ( *it )->electroaf() );
+ }
+ break;
+ }
+
+ QValueList<double>::iterator dit = tmpList.begin();
+ const QValueList<double>::iterator ditEnd = tmpList.end();
+
+ double tmpMin = *dit;
+ double tmpMax = *dit;
+ for ( ; dit != ditEnd; ++dit )
+ {
+ if (( *dit ) == 0 ) continue;
+ if ( ( *dit ) < tmpMin )
+ tmpMin = *dit;
+ if ( ( *dit ) > tmpMax )
+ tmpMax = *dit;
+ }
+
+ //now draw the gradient-table
+ drawGradientPerodicTableView( p, tmpMin, tmpMax );
+}
+
+
+
+void PerodicTableView::drawGradientPerodicTableView( QPainter *p, const double min, const double max )
+{
+ QString title = QString::null;
+
+ const double var = max-min;
+ EList::ConstIterator it = d->ElementList.begin();
+ const EList::ConstIterator itEnd = d->ElementList.end();
+
+
+ /**
+ * this loop iterates through all elements. The Elements
+ * draw themselves, the PerodicTableView only tells them to do so
+ */
+ it = d->ElementList.begin();
+ switch ( m_gradientType )
+ {
+ case Element::ATOMICRADIUS:
+ title = i18n( "Gradient: Atomic Radius" );
+ while ( it != d->ElementList.end() )
+ {
+ double value = ( *it )->radius( Element::ATOMIC );
+ double coeff = ( value - min )/var;
+
+ drawGradientButton( p, *it, coeff, value, min );
+
+ ++it;
+ }
+ break;
+ case Element::VDWRADIUS:
+ title = i18n( "Gradient: van der Waals Radius" );
+ while ( it != d->ElementList.end() )
+ {
+ double value = ( *it )->radius( Element::VDW );
+ double coeff = ( value - min )/var;
+
+ drawGradientButton( p, *it, coeff, value, min );
+
+ ++it;
+ }
+ break;
+ case Element::COVALENTRADIUS:
+ title = i18n( "Gradient: Covalent Radius" );
+ while ( it != d->ElementList.end() )
+ {
+ double value = ( *it )->radius( Element::COVALENT );
+ double coeff = ( (*it)->radius(Element::COVALENT) - min )/var;
+
+ drawGradientButton( p, *it, coeff, value, min );
+
+ ++it;
+ }
+ break;
+ case Element::MASS:
+ title = i18n( "Gradient: Atomic Mass" );
+ while ( it != d->ElementList.end() )
+ {
+ double coeff = ( (*it)->mass() - min )/var;
+ drawGradientButton( p, *it, coeff, ( *it )->mass(), min );
+
+ ++it;
+ }
+ break;
+ case Element::DENSITY:
+ title = i18n( "Gradient: Atomic Density" );
+ while ( it != d->ElementList.end() )
+ {
+ double coeff = ( (*it)->density() - min )/var;
+
+ drawGradientButton( p, *it, coeff, ( *it )->density(), min );
+ ++it;
+ }
+ break;
+ case Element::BOILINGPOINT:
+ title = i18n( "Gradient: Boiling point" );
+ while ( it != d->ElementList.end() )
+ {
+ double coeff = ( (*it)->boiling() - min )/var;
+ drawGradientButton( p, *it, coeff, ( *it )->boiling(), min );
+
+ ++it;
+ }
+ break;
+ case Element::MELTINGPOINT:
+ title = i18n( "Gradient: Melting point" );
+ while ( it != d->ElementList.end() )
+ {
+ double coeff = ( (*it)->melting() - min )/var;
+ drawGradientButton( p, *it, coeff, ( *it )->melting(), min );
+
+ ++it;
+ }
+ break;
+ case Element::EN:
+ title = i18n( "Gradient: Electronegativity" );
+ while ( it != d->ElementList.end() )
+ {
+ double coeff = ( (*it)->electroneg() - min )/var;
+ drawGradientButton( p, *it, coeff, ( *it )->electroneg(), min );
+
+ ++it;
+ }
+ break;
+ case Element::EA:
+ title = i18n( "Gradient: Electron affinity" );
+ double tmpVar = -1*(min - max);
+ while ( it != d->ElementList.end() )
+ {
+ if( (*it)->electroaf() == 0.0)
+ drawGradientButton( p, *it,-1.0, (*it )->electroaf(), min );
+ else
+ {
+ double coeff = ( max - (*it)->electroaf() )/tmpVar;
+ drawGradientButton( p, *it, coeff, (*it )->electroaf(), min );
+ }
+
+ ++it;
+ }
+ break;
+ }
+
+ // Now draw the legend.
+ int x = ELEMENTSIZE*2+5;
+ int y = 5;
+ //int w = ELEMENTSIZE*10-5;
+ //int h = ELEMENTSIZE*4-5;
+
+ // Create the gradient image.
+ QSize s( ELEMENTSIZE*7+20, 20 );
+ QImage img = KImageEffect::gradient ( s, Qt::white, Qt::red,
+ KImageEffect::HorizontalGradient );
+ QPixmap pm( img );
+
+ /**
+ * now find the optimum stringsize for the caption
+ * i18n( "Gradient: van der Waals Radius" ); is at least
+ * for english the longest possible string. As "van der Waals"
+ * is a name it should be the same in all languages and be
+ * probably always the longest string
+ */
+ QString tmp = i18n( "Gradient: van der Waals Radius" );
+ QRect rect(x+5, y+50, ELEMENTSIZE*10,20);
+ QFont font = p->font();
+ int maxSize = KalziumUtils::maxSize( tmp, rect, p->font(), p, 8, 24 );
+ kdDebug() << "maxSize: " << maxSize << endl;
+ font.setPointSize(maxSize);
+ p->setFont(font);
+
+ p->drawText( x+5, y+50, ELEMENTSIZE*10,20, Qt::AlignCenter, title );
+ p->drawPixmap( x+50, y+80, pm );
+
+ if ( m_gradientType == Element::EA )
+ {
+ // FIXME: In the lines below, "30" is the max allowed text
+ // height. This should be calculated from the font
+ // metrics, not hard coded.
+ p->drawText( x+50,y+100,ELEMENTSIZE*7+20,30, Qt::AlignRight, QString::number( min ) );
+ p->drawText( x+50,y+100,ELEMENTSIZE*7+20,30, Qt::AlignLeft, QString::number( max ) );
+ }
+ else
+ {
+ p->drawText( x+50,y+100,ELEMENTSIZE*7+20,30, Qt::AlignRight, QString::number( max ) );
+ p->drawText( x+50,y+100,ELEMENTSIZE*7+20,30, Qt::AlignLeft, QString::number( min ) );
+
+ }
+}
+
+QPoint PerodicTableView::ElementUnderMouse()
+{
+ int X = mapFromGlobal( QCursor::pos() ).x()/ELEMENTSIZE;
+ int Y = mapFromGlobal( QCursor::pos() ).y( )-ELEMENTSIZE;
+
+ // mind the gap over rare earth!
+ if (Y >= (ELEMENTSIZE*7) && Y < (ELEMENTSIZE*7+ELEMENTSIZE/3+1)) return QPoint( 0, 0 );
+
+ if (Y > (ELEMENTSIZE*7)) Y -= ELEMENTSIZE/3;
+
+ Y /= ELEMENTSIZE;
+
+ X += 1;
+ Y += 1;
+
+ return QPoint( X,Y );
+}
+
+
+void PerodicTableView::slotMouseover()
+{
+ QPoint point = ElementUnderMouse();
+
+ int num = ElementNumber( point.x(), point.y() );
+ if ( num )
+ emit MouseOver( num );
+}
+
+void PerodicTableView::drawGradientButton( QPainter *p, Element* e, double coeff, double value, double minValue )
+{
+ if ( value >= minValue && coeff != -1.0)
+ {
+ QColor c = calculateColor( coeff );
+ QString v = KalziumUtils::localizedValue( KalziumUtils::strippedValue( value ), 6 );
+ e->drawGradient( p, v, c );
+ }
+ else
+ e->drawGradient( p, i18n("It means: Not Available. Translators: keep it as short as you can!", "N/A"), Qt::lightGray );
+}
+
+QColor PerodicTableView::calculateColor( const double coeff )
+{
+ const QColor color2 = Qt::white;
+ const QColor color1 = Qt::red;
+
+ int red = (int)( (color1.red() - color2.red()) * coeff + color2.red() );
+ int green = (int)( (color1.green() - color2.green()) * coeff + color2.green() );
+ int blue = (int)( (color1.blue() - color2.blue()) * coeff + color2.blue() );
+
+ return QColor( red, green, blue );
+}
+
+void PerodicTableView::setLook( PerodicTableView::SCHEMETYPE type, int which )
+{
+ m_currentScheme = type;
+
+ EList::ConstIterator it = d->ElementList.begin();
+ const EList::ConstIterator itEnd = d->ElementList.end();
+
+ switch ( type )
+ {
+ case NOCOLOUR:
+ {
+ const QColor color = Prefs::noscheme();
+ while ( it != itEnd )
+ {
+ ( *it )->setElementColor( color );
+ ++it;
+ }
+ setGradient( false );
+ break;
+ }
+ case PerodicTableView::GROUPS: // group view
+ {
+ QString group;
+
+ while ( it != itEnd )
+ {
+ group = ( *it )->group();
+
+ if (group == QString("1")) {
+ ( *it )->setElementColor( color_1 );
+ }
+ if (group == QString("2")){
+ ( *it )->setElementColor( color_2 );
+ }
+ if (group == QString("3")){
+ ( *it )->setElementColor( color_3 );
+ }
+ if (group == QString("4")){
+ ( *it )->setElementColor( color_4 );
+ }
+ if (group == QString("5")){
+ ( *it )->setElementColor( color_5 );
+ }
+ if (group == QString("6")){
+ ( *it )->setElementColor( color_6 );
+ }
+ if (group == QString("7")){
+ ( *it )->setElementColor( color_7 );
+ }
+ if (group == QString("8")){
+ ( *it )->setElementColor( color_8 );
+ }
+
+ ++it;
+ }
+ setGradient( false );
+ break;
+ }
+ case PerodicTableView::BLOCK: //block view
+ {
+ static QString block;
+ while ( it != itEnd )
+ {
+ block = (*it)->block();
+
+ if (block == QString("s")) {
+ (*it)->setElementColor( color_s );
+ }
+ if (block == QString("p")) {
+ (*it)->setElementColor( color_p );
+ }
+ if (block == QString("d")) {
+ (*it)->setElementColor( color_d );
+ }
+ if (block == QString("f")) {
+ (*it)->setElementColor( color_f );
+ }
+ ++it;
+ }
+ setGradient( false );
+ break;
+ }
+ case PerodicTableView::ACIDIC: //acidic beh
+ {
+ static QString acidicbeh;
+ while ( it != itEnd )
+ {
+ acidicbeh = ( *it )->acidicbeh();
+
+ if (acidicbeh == QString("0")) {
+ (*it)->setElementColor( color_ac );
+ }
+ if (acidicbeh == QString("1")){
+ (*it)->setElementColor( color_ba );
+ }
+ if (acidicbeh == QString("2")){
+ (*it)->setElementColor( color_neu );
+ }
+ if (acidicbeh == QString("3")){
+ (*it)->setElementColor( color_amp );
+ }
+ ++it;
+ }
+ setGradient( false );
+ break;
+ }
+ case PerodicTableView::FAMILY: //familiy of the element
+ {
+ static QString family;
+
+ while ( it != itEnd )
+ {
+ family = ( *it )->family();
+
+ if ( family == "Noblegas" ){
+ (*it)->setElementColor( c_noble_gas );
+ }
+ if ( family == "Non-Metal" ){
+ (*it)->setElementColor( c_nonmetal );
+ }
+ if ( family == "Rare_Earth" ){
+ (*it)->setElementColor( c_rare );
+ }
+ if ( family == "Alkaline_Earth" ){
+ (*it)->setElementColor( c_alkaline );
+ }
+ if ( family == "Alkali_Earth" ){
+ (*it)->setElementColor( c_alkalie );
+ }
+ if ( family == "Transition" ){
+ (*it)->setElementColor( c_transition );
+ }
+ if ( family == "Other_Metal" ){
+ (*it)->setElementColor( c_other_metal );
+ }
+ if ( family == "Metalloids" ){
+ (*it)->setElementColor( c_metalloid );
+ }
+ if ( family == "Halogene" ){
+ (*it)->setElementColor( c_halogene );
+ }
+
+ ++it;
+ }
+ setGradient( false );
+ break;
+ }
+ case CRYSTAL:
+ {
+ QString structure;
+ while ( it != itEnd )
+ {
+ structure = ( *it )->crystalstructure();
+ if ( structure == "own")
+ (*it)->setElementColor( Qt::cyan );
+ else if ( structure == "bcc" )
+ (*it)->setElementColor( Qt::red );
+ else if ( structure == "hdp" )
+ (*it)->setElementColor( Qt::yellow );
+ else if ( structure == "ccp" )
+ (*it)->setElementColor( Qt::green );
+ else
+ (*it)->setElementColor( Qt::white );
+ ++it;
+ }
+ setGradient( false );
+ break;
+ }
+ case GRADIENT:
+ {
+ setGradient( true );
+ setGradientType( which );
+ break;
+ }
+ default:
+ ;
+ }
+
+ Prefs::setColorschemebox( type );
+ Prefs::writeConfig();
+
+ //JH: redraw the full table next time
+ setFullDraw();
+ update();
+}
+
+#include "periodictableview.moc"