]> Git trees. - libqmvoc.git/commitdiff
I hope this commit doesn't break compilation... This is the "brackport"
authorCarsten Niehaus <cniehaus@gmx.de>
Tue, 8 Mar 2005 14:46:55 +0000 (14:46 +0000)
committerCarsten Niehaus <cniehaus@gmx.de>
Tue, 8 Mar 2005 14:46:55 +0000 (14:46 +0000)
of kalziumkde4 branch. It compiled here, but you never know.

svn path=/trunk/kdeedu/kalzium/src/element.h; revision=395803

kalzium/src/element.cpp
kalzium/src/element.h

index ace21f17b81afbc80c64506e11347779431308d2..8a55b3e0230219b41060660681de8db097c6fe4d 100644 (file)
 #include "element.h"
 #include "prefs.h"
 #include <qregexp.h>
+#include <qmap.h>
 #include <kdebug.h>
 #include <klocale.h>
 
+#include <math.h>
+
+#include <qpainter.h>
+
+#define ELEMENTSIZE 45
+
 Element::Element( int num )
 {
        m_number = num;
@@ -39,10 +46,11 @@ Element::Element( int num )
        m_name=config.readEntry( "Name", "Unknown" );
        m_symbol=config.readEntry( "Symbol", "Unknown" );
        m_weight=config.readDoubleNumEntry( "Weight",0.0 );
-       m_isotopes=config.readEntry(  "Isotopes", "0" );
 
        m_oxstage=config.readEntry( "Ox","0" );
        m_acidbeh=config.readEntry( "acidbeh","0" );
+       m_isotopes=config.readEntry( "Isotopes", "0" );
+
        m_block=config.readEntry( "Block","s" );
        m_EN=config.readDoubleNumEntry( "EN", -1 );
        m_MP=config.readDoubleNumEntry( "MP", -1 );
@@ -52,6 +60,7 @@ Element::Element( int num )
        m_BP=config.readDoubleNumEntry( "BP", -1 );
        m_Density=config.readDoubleNumEntry( "Density", -1 );
        m_group=config.readEntry( "Group","1" );
+       m_family=config.readEntry( "Family","1" );
        m_orbits=config.readEntry( "Orbits","0" );
        m_biological=config.readNumEntry(  "biological" , -1 );
        m_az=config.readNumEntry( "az",-1 );
@@ -71,11 +80,29 @@ QString Element::parsedOrbits()
 }
 
 
+double Element::strippedWeight( double num )
+{
+       if ( !finite( num ) )
+               return num;
+
+       double power;
+       power = 1e-6;
+       while ( power < num )
+               power *= 10;
+
+       num = num / power * 10000;
+       num = round( num );
+
+       return num * power / 10000;
+}
+
 
 Element::~Element()
 {
 }
 
+
+
 double Element::meanweight()
 {
        return m_weight/m_number;
@@ -98,14 +125,16 @@ const QString Element::adjustUnits( const int type )
                        v = i18n( "Value unknown" );
                else 
                {
-                       if ( Prefs::units() == 0 )
+                       if ( Prefs::energies() == 0 )
                        {
                                val*=96.6;
-                               v = i18n( "%1 kj/mol" ).arg( QString::number( val ) );
+                               v = QString::number( val );
+                               v.append( "kj/mol" );
                        }
                        else // use electronvolt
                        {
-                               v = i18n( "%1 eV" ).arg( QString::number( val ) );
+                               v = QString::number( val );
+                               v.append( "eV" );
                        }
                }
        }
@@ -116,43 +145,98 @@ const QString Element::adjustUnits( const int type )
                else
                        val = melting();
 
-               switch (Prefs::temperature()) {
-                       case 0: //kelvin
-                               v = i18n( "%1 K" ).arg( QString::number( val ) );
-                               break;
-                       case 1://kelvin to Celsius
-                               val-=273.15;
-                               v = i18n( "%1 C" ).arg( QString::number( val ) );
-                               break;
-                       case 2: // kelvin to Fahrenheit
-                               val = val * 1.8 - 459.67;
-                               v = i18n( "%1 F" ).arg( QString::number( val ) );
-                               break;
+               if ( val == -1 )
+                       v = i18n( "Value unknown" );
+               else
+               {
+                       switch (Prefs::temperature()) {
+                               case 0: //Kelvin
+                                       v = QString::number( val );
+                                       v.append( "K" );
+                                       break;
+                               case 1://Kelvin to Celsius
+                                       val-=273.15;
+                                       v = QString::number( val );
+                                       v.append( "C" );
+                                       break;
+                               case 2: // Kelvin to Fahrenheit
+                                       val = val * 1.8 - 459.67;
+                                       v = QString::number( val );
+                                       v.append( "F" );
+                                       break;
+                       }
                }
        }
        else if ( type == RADIUS ) // its a length
        {
                val = radius();
 
-               v = i18n( "%1 pm" ).arg( QString::number( val ) );
+               if ( val == -1 )
+                       v = i18n( "Value unknown" );
+               else
+               {
+                       switch ( Prefs::units() )
+                       {
+                               case 0://use SI-values (meter for length)
+                                       v = QString::number( val );
+
+                                       v.append( " 10<sup>-12</sup>m" );
+                                       break;
+                               case 1://use picometer, the most common unit for radii
+                                       v = QString::number( val );
+
+                                       v.append( i18n( " pm" ) );
+                                       break;
+                       }
+               }
        }
        else if ( type == WEIGHT ) // its a weight
        {
                val = weight();
-
-               v = i18n( "%1 u" ).arg( QString::number( val ) );
+               if ( val == -1 )
+                       v = i18n( "Value unknown" );
+               else
+               {
+                       v = QString::number( val );
+                       switch ( Prefs::units() )
+                       {
+                               case 0:
+                                       v.append( i18n( "g/mol" ) );
+                                       break;
+                               case 1:
+                                       v.append( i18n( " u" ) );
+                                       break;
+                       }
+               }
        }
        else if ( type == DENSITY ) // its a density
        {
                val = density();
 
-               if ( az() == 2 )//gasoline
-               {
-                       v = i18n( "%1 g/L" ).arg( QString::number( val ) );
-               }
-               else//liquid or solid
+               if ( val == -1 )
+                       v = i18n( "Value unknown" );
+               else
                {
-                       v = i18n( "%1 g/cm<sup>2</sup>" ).arg( QString::number( val ) );
+                       switch ( Prefs::units() )
+                       {
+                               case 0://use SI (kg per cubic-meter)
+                                       val *= 1000;
+                                       v = QString::number( val );
+                                       v.append( " kg/m<sup>3</sup>" );
+                                       break;
+                               case 1://use more common units
+                                       if ( az() == 2 )//gasoline
+                                       {
+                                               v = QString::number( val );
+                                               v.append( " g/L" );
+                                       }
+                                       else//liquid or solid
+                                       {
+                                               v = QString::number( val );
+                                               v.append( " g/cm<sup>3</sup>" );
+                                       }
+                                       break;
+                       }
                }
        }
        else if ( type == DATE ) //its a date
@@ -171,15 +255,172 @@ const QString Element::adjustUnits( const int type )
        return v;
 }
 
+void Element::drawStateOfMatter( QPainter* p, double temp )
+{
+       //the height of a "line" inside an element
+       int h_small = 15; //the size for the small units like elementnumber
+
+       //The X-coordiante
+       int X = ( x-1 )*ELEMENTSIZE;
+
+       //The Y-coordinate
+       int Y = ( y-1 )*ELEMENTSIZE;
+       
+       QColor color = currentColor( temp );
+       
+       p->setPen( color );
+       p->fillRect( X+3, Y+3,ELEMENTSIZE-6,ELEMENTSIZE-6, color );
+       p->drawRoundRect( X+2, Y+2,ELEMENTSIZE-4,ELEMENTSIZE-4 );
+       
+       QString text;
+       QFont symbol_font = p->font();
+       symbol_font.setPointSize( 18 );
+       QFont f = p->font();
+       f.setPointSize( 9 );
+               
+       p->setFont( f );
+
+       //top left
+       p->setPen( Qt::black );
+       text = QString::number( strippedWeight( weight( ) ) );
+       p->drawText( X+5,Y+2 ,ELEMENTSIZE-2,h_small,Qt::AlignLeft, text );
+
+       text = QString::number( number() );
+       p->drawText( X+5,( y )*ELEMENTSIZE - h_small, ELEMENTSIZE-2, h_small,Qt::AlignLeft, text );
+
+       p->setFont( symbol_font );
+       p->drawText( X+5,Y+2, ELEMENTSIZE,ELEMENTSIZE,Qt::AlignCenter, symbol() );
+       
+       //border
+       p->setPen( Qt::black );
+       p->drawRoundRect( X+1, Y+1,ELEMENTSIZE-2,ELEMENTSIZE-2);
+}
+       
+QColor Element::currentColor( double temp )
+{
+       QColor color;
+       //take the colours for the given temperature
+       const int _az = az();
+       if ( _az == 3 || _az == 4 )
+       { //check if the element is radioactive or artificial
+               if ( _az == 3 ) color=Prefs::color_radioactive();
+               if ( _az == 4 ) color=Prefs::color_artificial();
+       }
+
+       double iButton_melting = melting();
+       double iButton_boiling = boiling();
+
+       if ( temp < iButton_melting )
+       { //the element is solid
+               color= Prefs::color_solid();
+       }
+       if ( temp > iButton_melting &&
+                       temp < iButton_boiling )
+       { //the element is liquid
+               color= Prefs::color_liquid();
+       }
+       if ( temp > iButton_boiling )
+       { //the element is vaporous
+               color= Prefs::color_vapor();
+       }
+       return color;
+
+}
+
+void Element::drawHighlight( QPainter* p, int coordinate, bool horizontal )
+{
+       //first: test if the element is in the selected period of group
+       if ( horizontal )
+       {
+               if ( x != coordinate )
+                       return;
+               //else the element is in the selected row
+       }
+       else if ( !horizontal )
+       {
+               if ( y != coordinate )
+                       return;
+               //else the element is in the selected group
+       }
+
+       //the element matches. Now highlight it.
+       //The X-coordiante
+       int X = ( x-1 )*ELEMENTSIZE;
+
+       //The Y-coordinate
+       int Y = ( y-1 )*ELEMENTSIZE;
+
+       p->fillRect( X, Y,ELEMENTSIZE,ELEMENTSIZE, Qt::darkRed );
+
+       //now draw the elements over the red area
+       drawSelf( p, false );
+}
+       
+void Element::drawSelf( QPainter* p, bool useSimpleView )
+{
+       //the height of a "line" inside an element
+       int h_small = 15; //the size for the small units like elementnumber
+
+       //The X-coordiante
+       int X;
+       
+       if ( useSimpleView )
+       {//use the small periodic table without the d- and f-Block
+               if ( block() == "f" )
+                       return;
+               if ( block() == "d" )
+                       return;
+               if ( block() == "p" )
+               {
+                       X = ( x-1 )*ELEMENTSIZE;
+                       X -= 10*ELEMENTSIZE;
+               }
+               if ( block() == "s" )
+               {
+                       X = ( x-1 )*ELEMENTSIZE;
+               }
+       }
+       else //use the full table
+               X = ( x-1 )*ELEMENTSIZE;
+
+       //The Y-coordinate
+       int Y = ( y-1 )*ELEMENTSIZE;
+
+       p->setPen( elementColor() );
+       p->fillRect( X+3, Y+3,ELEMENTSIZE-6,ELEMENTSIZE-6, elementColor() );
+       p->drawRoundRect( X+2, Y+2,ELEMENTSIZE-4,ELEMENTSIZE-4 );
+       
+       QString text;
+       QFont symbol_font = p->font();
+       symbol_font.setPointSize( 18 );
+       QFont f = p->font();
+       f.setPointSize( 9 );
+               
+       p->setFont( f );
+
+       //top left
+       p->setPen( Qt::black );
+       text = QString::number( strippedWeight( weight( ) ) );
+       p->drawText( X+5,Y+2 ,ELEMENTSIZE+4,h_small,Qt::AlignLeft, text );
+
+       text = QString::number( number() );
+       p->drawText( X+5,( y )*ELEMENTSIZE - h_small, ELEMENTSIZE-2, h_small,Qt::AlignLeft, text );
+
+       p->setFont( symbol_font );
+       p->drawText( X+5,Y+2, ELEMENTSIZE,ELEMENTSIZE,Qt::AlignCenter, symbol() );
+       
+       //border
+       p->setPen( Qt::black );
+       p->drawRoundRect( X+1, Y+1,ELEMENTSIZE-2,ELEMENTSIZE-2);
+}
+
 /*!
-    \fn Element::setupXY()
     This looks pretty evil and it is. The problem is that a PSE is pretty
-    irregular and you cannot "calculate" the position. This means that 
-    every type of PSE need such a complicated list of x/y-pairs...
+    irregular and you cannot "calculate" the position. 
  */
 void Element::setupXY()
 {
- static const int posXRegular[110] = {1,18,
+ static const int posXRegular[111] = {1,18,
                                                                        1,2,13,14,15,16,17,18,
                                                                        1,2,13,14,15,16,17,18,
                                                                        1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
@@ -187,8 +428,8 @@ void Element::setupXY()
                                                                        1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,     //Element 71 (Lu)
                                                                              4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
                                                                        1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,     //Element 71 (Lr)
-                                                                             4,5,6,7,8,9,10};
- static const int posYRegular[110] = {1,1,
+                                                                             4,5,6,7,8,9,10,11};
+ static const int posYRegular[111] = {1,1,
                                                                        2,2, 2, 2, 2, 2, 2, 2,
                                                                        3,3, 3, 3, 3, 3, 3, 3,
                                                                        4,4,4,4,4,4,4,4,4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
@@ -196,61 +437,21 @@ void Element::setupXY()
                                                                6,6,6,8,8,8,8,8,8, 8, 8, 8, 8, 8, 8, 8, 8,     //Element 71 (Lr)
                                                                              6,6,6,6,6,6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
                                                                        7,7,7,9,9,9,9,9,9, 9, 9, 9, 9, 9, 9, 9, 9,
-                                                                             7,7,7,7,7,7,7};
-                                                                                 
-                                                               
-static const int posXSimplified[110] = {
-       1,8,
-       1,2,3,4,5,6,7,8,
-       1,2,
-       3,4,5,6,7,8,
-       1,2,
-       0,0,0,0,0,0,0,0,0,0, //dummy
-       
-       3,4,5,6,7,8,//36
-       1,2,
-       0,0,0,0,0,0,0,0,0,0, //dummy
-       3,4,5,6,7,8,
-       1,2,//56
-       0,0,0,0,0,0,0,0,0,0, //dummy 66
-       0,0,0,0,0,0,0,0,0,0, //dummy 76
-       0,0,0,0, //dummy 80
-       3,4,5,6,7,8,
-       1,2};
+                                                                             7,7,7,7,7,7,7,7};
 
-       
-static const int posYSimplified[110] = {
-       1,1,
-       2,2,2,2,2,2,2,2,
-       3,3,
-       3,3,3,3,3,3,
-       4,4,
-       0,0,0,0,0,0,0,0,0,0, //dummy
-       
-       4,4,4,4,4,4,//36
-       5,5,
-       0,0,0,0,0,0,0,0,0,0, //dummy
-       5,5,5,5,5,5,
-       6,6,
-       0,0,0,0,0,0,0,0,0,0, //dummy
-       0,0,0,0,0,0,0,0,0,0, //dummy
-       0,0,0,0, //dummy 80
-       6,6,6,6,6,6,
-       7,7};
  x = posXRegular[m_number-1];
  y = posYRegular[m_number-1];
-
- s_y = posYSimplified[m_number-1];
- s_x = posXSimplified[m_number-1];
 }
 
 KalziumDataObject::KalziumDataObject()
 {
-       for( int i = 1 ; i < 111 ; ++i )
+       for( int i = 1 ; i < 112 ; ++i )
        {
-               ElementList.append( new Element( i ) );
+               Element *e = new Element( i );
+               coordinate point; point.x =  e->x; point.y = e->y;
+
+               CoordinateList.append( point );
+               ElementList.append( e );
        }
 }
 
index eaaac308d9eefa506a7bedac2e2171e75e013de9..43d20057b7667744f45b23fb1591f1965a8bcfdd 100644 (file)
 
 class Element;
 
+struct coordinate;
+
 typedef QValueList<Element*> EList;
+typedef QValueList<coordinate> CList;
 
 /**
  * @short this class contains all Element-objects as
@@ -41,7 +44,13 @@ class KalziumDataObject
                 * The list of element in a QValueList<Element*>
                 */
                EList ElementList;
+               
+               CList CoordinateList;
+};
 
+struct coordinate{
+       int x;
+       int y;
 };
 
 /**
@@ -54,7 +63,7 @@ class KalziumDataObject
 class Element{
        public:
                Element( int );
-               ~Element();
+               virtual ~Element();
 
                /**
                 * @return the number of the element
@@ -69,6 +78,14 @@ class Element{
                int date() const { 
                        return m_date; 
                }
+
+               ///return the correct color of the element
+               QColor currentColor( double temp );
+    
+    /**
+     * mutator for the element's color
+     */
+               void setElementColor( const QColor &c ) { m_Color = c; }
                
                /**
                 * @return the importance of the element for biological
@@ -117,6 +134,10 @@ class Element{
                QString group() const {
                        return m_group;
                }
+
+               QString family() const {
+                       return m_family;
+               }
                
                /**
                 * @return the acidic behavior of the element
@@ -148,14 +169,14 @@ class Element{
                QString parsedOrbits();
                
                /**
-                * @return the boiling point of the element in kelvin
+                * @return the boiling point of the element in Kelvin
                 */
                double boiling() const {
                        return m_BP;
                }
                
                /**
-                * @return the melting point of the element in kelvin
+                * @return the melting point of the element in Kelvin
                 */
                double melting() const {
                        return m_MP;
@@ -210,11 +231,10 @@ class Element{
                double meanweight();
 
                int x, y; //for the RegularPSE
-               int s_x, s_y; //for the SimplifiedPSE
 
                /**
                 * adjusts the units for the data. The user can
-                * eg define if Fahrenheit, kelvin or Degrees Celsius
+                * eg define if Fahrenheit, Kelvin or Degrees Celsius
                 * should be used for the temperature. This method
                 * takes care of that.
                 * @param val the value which has to be adjusted
@@ -239,12 +259,28 @@ class Element{
                };
 
 
+               /**
+                * calculate the 4-digit value of the value @p w
+                */
+               double strippedWeight( double w );
 
 
+    /**
+     * accessor for the element's color
+     */
+    QColor elementColor() const { 
+               return m_Color; 
+       }
 
        private:
                void setupXY();
                
+               /*
+                * the integer num represents the number of the element
+                */
+               int m_ElementNumber;
+       
+               QColor m_Color;
 
                double  m_weight,
                        m_MP, 
@@ -265,9 +301,27 @@ class Element{
                        m_oxstage,
                        m_block,
                        m_group,
+                       m_family,
                        m_acidbeh,
                        m_orbits,
                        m_isotopes;
+               
+       public:
+               /**
+                * draw the recatangle with the information
+                * @param showFullInformation if True more information will be shown
+                */
+               virtual void drawSelf( QPainter* p, bool showFullInformation );
+               
+               /**
+                * Highlight perdiods or groups.
+                * @param p the QPainter used for painting
+                * @p param coordinate the number of the period or group
+                * @p horizontal if true a period will be painted, otherwise a group
+                */
+               virtual void drawHighlight( QPainter* p, int coordinate, bool horizontal );
+               
+               virtual void drawStateOfMatter( QPainter* p, double temperature );
 };