00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "detailinfodlg.h"
00017 #include "isotope.h"
00018 #include "kalziumdataobject.h"
00019
00020 #include <kdebug.h>
00021 #include <klocale.h>
00022 #include <kicon.h>
00023 #include <khtml_part.h>
00024 #include <dom/html_base.h>
00025 #include <dom/html_document.h>
00026 #include <khtmlview.h>
00027 #include <kstandarddirs.h>
00028 #include <kactioncollection.h>
00029 #include <kcombobox.h>
00030 #include <kstandardaction.h>
00031 #include <kpagewidgetmodel.h>
00032 #include <ktoolinvocation.h>
00033
00034 #include <QFile>
00035 #include <QLabel>
00036 #include <QImage>
00037 #include <QLayout>
00038 #include <QPushButton>
00039 #include <QStackedWidget>
00040
00041 #include "element.h"
00042 #include "orbitswidget.h"
00043 #include "detailedgraphicaloverview.h"
00044
00045
00046 #include "kalziumutils.h"
00047 #include "kalziumtabletype.h"
00048
00049 DetailedInfoDlg::DetailedInfoDlg( int el , QWidget *parent )
00050 : KPageDialog( parent ), m_ktt( 0 )
00051 {
00052 setFaceType( List );
00053 setButtons( Help | User1 | User2 | Close );
00054 setDefaultButton( Close );
00055 setButtonGuiItem( User1, KGuiItem( i18nc( "Next element", "Next" ),
00056 ( layoutDirection() == Qt::LeftToRight ) ? "arrow-right" : "arrow-left", i18n( "Goes to the next element" ) ) );
00057 setButtonGuiItem( User2, KGuiItem( i18nc( "Previous element", "Previous" ),
00058 ( layoutDirection() == Qt::LeftToRight ) ? "arrow-left" : "arrow-right", i18n( "Goes to the previous element" ) ) );
00059
00060 m_baseHtml = KGlobal::dirs()->findResourceDir( "appdata", "data/" ) + "data/htmlview/";
00061 m_baseHtml2 = KGlobal::dirs()->findResourceDir( "appdata", "data/" ) + "data/hazardsymbols/";
00062
00063
00064
00065
00066
00067
00068
00069 createContent();
00070
00071 m_actionCollection = new KActionCollection(this);
00072 KStandardAction::quit(this, SLOT(close()), m_actionCollection);
00073
00074 connect( this, SIGNAL( user1Clicked() ), this, SLOT( slotUser1() ) );
00075 connect( this, SIGNAL( user2Clicked() ), this, SLOT( slotUser2() ) );
00076 connect( this, SIGNAL( helpClicked() ), this, SLOT( slotHelp() ) );
00077
00078
00079 setElement( el );
00080 }
00081
00082 void DetailedInfoDlg::setElement( int el )
00083 {
00084 Element *element = KalziumDataObject::instance()->element( el );
00085 if ( !element ) return;
00086
00087 m_element = element;
00088 m_elementNumber = el;
00089
00090 emit elementChanged( m_elementNumber );
00091
00092 reloadContent();
00093
00094 enableButton( User1, true );
00095 enableButton( User2, true );
00096 if ( m_elementNumber == 1 )
00097 enableButton( User2, false );
00098 else if ( m_elementNumber == KalziumDataObject::instance()->numberOfElements() )
00099 enableButton( User1, false );
00100 }
00101
00102 void DetailedInfoDlg::setOverviewBackgroundColor( const QColor &bgColor )
00103 {
00104 dTab->setBackgroundColor( bgColor );
00105 }
00106
00107 void DetailedInfoDlg::setTableType( KalziumTableType* ktt )
00108 {
00109 m_ktt = ktt;
00110 }
00111
00112 KHTMLPart* DetailedInfoDlg::addHTMLTab( const QString& title, const QString& icontext, const QString& iconname )
00113 {
00114 QWidget* frame = new QWidget();
00115 KPageWidgetItem *item = addPage( frame, title );
00116 item->setHeader( icontext );
00117 item->setIcon( KIcon( iconname ) );
00118 QVBoxLayout *layout = new QVBoxLayout( frame );
00119 layout->setMargin( 0 );
00120 KHTMLPart *w = new KHTMLPart( frame, frame );
00121 layout->addWidget( w->view() );
00122
00123 return w;
00124 }
00125
00126 void DetailedInfoDlg::fillHTMLTab( KHTMLPart* htmlpart, const QString& htmlcode )
00127 {
00128 if ( !htmlpart ) return;
00129
00130 htmlpart->begin();
00131 htmlpart->write( htmlcode );
00132
00133
00134 DOM::HTMLElement element = htmlpart->htmlDocument().body();
00135 if ( element.tagName() == "body" )
00136 {
00137 const QColor backgroundColor = palette().background().color();
00138 ((DOM::HTMLBodyElement)element).setBgColor( backgroundColor.name() );
00139 }
00140
00141 htmlpart->end();
00142 }
00143
00144 QString DetailedInfoDlg::getHtml( DATATYPE type ) const
00145 {
00146 QString html =
00147 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">"
00148 "<html><head><title>Chemical data</title>"
00149 "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + m_baseHtml + "style.css\" />"
00150 "<base href=\"" + m_baseHtml + "\"/></head><body>"
00151 "<div class=\"chemdata\"><div><table summary=\"header\">"
00152 "<tr><td>" + m_element->dataAsString( ChemicalDataObject::symbol ) + "<td><td>"
00153 + i18n( "Block: %1", m_element->dataAsString( ChemicalDataObject::periodTableBlock ) ) +
00154 "</td></tr></table></div>"
00155 "<table summary=\"characteristics\" class=\"characterstics\">";
00156
00157 switch ( type )
00158 {
00159 case CHEMICAL:
00160 {
00161
00162 html.append( "<tr><td><img src=\"structure.png\" alt=\"icon\"/></td><td>" );
00163
00164 QString config = m_element->dataAsString( ChemicalDataObject::electronicConfiguration );
00165 html.append( i18n( "Electronic configuration: %1", config ) );
00166 html.append( "</td></tr>" );
00167
00168
00169 html.append( "<tr><td><img src=\"density.png\" alt=\"icon\"/></td><td>" );
00170 html.append( i18n( "Density: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::density ) ) );
00171 html.append( "</td></tr>" );
00172
00173 html.append( "<tr><td><img src=\"radius.png\" alt=\"icon\"/></td><td>" );
00174 html.append( i18n( "Covalent Radius: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::radiusCovalent ) ) );
00175 html.append( "</td></tr>" );
00176
00177 html.append( "<tr><td><img src=\"radius.png\" alt=\"icon\"/></td><td>" );
00178 html.append( i18n( "van der Waals Radius: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::radiusVDW ) ) );
00179 html.append( "</td></tr>" );
00180 html.append( "<tr><td stype=\"text-align:center\"><img src=\"mass.png\" alt=\"icon\"/></td><td>" );
00181 html.append( i18n( "Mass: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::mass ) ) );
00182 html.append( "</td></tr>" );
00183 break;
00184 }
00185 case MISC:
00186 {
00187
00188 html.append( "<tr><td><img src=\"discovery.png\" alt=\"icon\"/></td><td>" );
00189 html += KalziumUtils::prettyUnit( m_element, ChemicalDataObject::date );
00190 QString discoverers = m_element->dataAsString( ChemicalDataObject::discoverers );
00191 if ( !discoverers.isEmpty() )
00192 {
00193 discoverers = discoverers.replace( ";", ", " );
00194 html += "<br />" + i18n( "It was discovered by %1.", discoverers );
00195 }
00196 html.append( "</td></tr>" );
00197 html.append( "<tr><td><img src=\"mass.png\" alt=\"icon\"/></td><td>" );
00198 double mass = m_element->dataAsVariant( ChemicalDataObject::mass ).toDouble();
00199 double neutrons = m_element->dataAsVariant( ChemicalDataObject::atomicNumber ).toInt();
00200 html.append( i18n( "Mean mass: %1 u", mass/neutrons) );
00201 html.append( "</td></tr>" );
00202
00203 QString nameorigin = m_element->dataAsString( ChemicalDataObject::nameOrigin );
00204 if ( !nameorigin.isEmpty() )
00205 {
00206 html.append( "<tr><td><img src=\"book.png\" alt=\"icon\"/></td><td>" );
00207 html.append( i18n( "Origin of the name:<br/>%1", nameorigin ) );
00208 html.append( "</td></tr>" );
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 break;
00222 }
00223 case ENERGY:
00224 {
00225
00226 html.append( "<tr><td><img src=\"meltingpoint.png\" alt=\"icon\"/></td><td>" );
00227 html.append( i18n( "Melting Point: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::meltingpoint ) ) );
00228 html.append( "</td></tr>" );
00229
00230 html.append( "<tr><td><img src=\"boilingpoint.png\" alt=\"icon\"/></td><td>" );
00231 html.append( i18n( "Boiling Point: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::boilingpoint ) ) );
00232 html.append( "</td></tr>" );
00233
00234 html.append( "<tr><td><img src=\"structure.png\" alt=\"icon\"/></td><td>" );
00235 html.append( i18n( "Electronegativity: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::electronegativityPauling ) ) );
00236 html.append( "</td></tr>" );
00237
00238 html.append( "<tr><td><img src=\"electronaffinity.png\" alt=\"icon\"/></td><td>" );
00239 html.append( i18n( "Electron Affinity: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::electronAffinity ) ) );
00240 html.append( "</td></tr>" );
00241
00242 html.append( "<tr><td><img src=\"ionisation.png\" alt=\"icon\"/></td><td>" );
00243 html.append( i18n( "First Ionization energy: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::ionization ) ) );
00244 html.append( "</td></tr>" );
00245 break;
00246 }
00247 case ISOTOPES:
00248 {
00249 html.append( "<tr><td>" );
00250 html.append( isotopeTable() );
00251 html.append( "</td></tr>" );
00252 break;
00253 }
00254 case DATA:
00255 {
00256 html.append( i18n( "<tr><th colspan=\"2\" align=\"left\">Compound properties</th></tr>" ) );
00257
00258
00259 html.append( "<tr><td><img src=\"meltingpoint.png\" alt=\"icon\"/></td><td>" );
00260 html.append( i18n( "Melting Point: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::meltingpoint ) ) );
00261 html.append( "</td></tr>" );
00262
00263
00264 html.append( "<tr><td><img src=\"boilingpoint.png\" alt=\"icon\"/></td><td>" );
00265 html.append( i18n( "Boiling Point: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::boilingpoint ) ) );
00266 html.append( "</td></tr>" );
00267
00268 html.append( "</table>" );
00269 html.append( "<table summary=\"characteristics\" class=\"characterstics\">" );
00270
00271
00272 html.append( i18n( "<tr><th colspan=\"2\" align=\"left\">Atomic properties</th></tr>" ) );
00273
00274 html.append( "<tr><td><img src=\"electronaffinity.png\" alt=\"icon\"/></td><td>" );
00275 html.append( i18n( "Electron Affinity: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::electronAffinity ) ) );
00276 html.append( "</td></tr>" );
00277
00278
00279 html.append( "<tr><td><img src=\"density.png\" alt=\"icon\"/></td><td>" );
00280 html.append( i18n( "Density: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::density ) ) );
00281 html.append( "</td></tr>" );
00282
00283
00284 html.append( "<tr><td><img src=\"structure.png\" alt=\"icon\"/></td><td>" );
00285
00286 QString config = m_element->dataAsString( ChemicalDataObject::electronicConfiguration );
00287 html.append( i18n( "Electronic configuration: %1", config ) );
00288 html.append( "</td></tr>" );
00289
00290
00291 html.append( "<tr><td><img src=\"radius.png\" alt=\"icon\"/></td><td>" );
00292 html.append( i18n( "Covalent Radius: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::radiusCovalent ) ) );
00293 html.append( "</td></tr>" );
00294
00295
00296 html.append( "<tr><td><img src=\"radius.png\" alt=\"icon\"/></td><td>" );
00297 html.append( i18n( "van der Waals Radius: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::radiusVDW ) ) );
00298 html.append( "</td></tr>" );
00299 html.append( "<tr><td stype=\"text-align:center\"><img src=\"mass.png\" alt=\"icon\"/></td><td>" );
00300 html.append( i18n( "Mass: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::mass ) ) );
00301 html.append( "</td></tr>" );
00302 }
00303 }
00304
00305 html += "</table></div></body></html>";
00306
00307 return html;
00308 }
00309
00310 QString DetailedInfoDlg::isotopeTable() const
00311 {
00312 QList<Isotope*> list = KalziumDataObject::instance()->isotopes( m_elementNumber );
00313
00314 QString html;
00315
00316 html = "<table class=\"isotopes\" cellspacing=\"0\"><tr><td colspan=\"7\">";
00317 html += i18n( "Isotope-Table" );
00318 html += "</tr></td><tr><td><b>";
00319 html += i18n( "Mass" );
00320 html += "</b></td><td><b>";
00321 html += i18n( "Neutrons" );
00322 html += "</b></td><td><b>";
00323 html += i18n( "Percentage" );
00324 html += "</b></td><td><b>";
00325 html += i18n( "Half-life period" );
00326 html += "</b></td><td><b>";
00327 html += i18n( "Energy and Mode of Decay" );
00328 html += "</b></td><td><b>";
00329 html += i18n( "Spin and Parity" );
00330 html += "</b></td><td><b>";
00331 html += i18n( "Magnetic Moment" );
00332 html += "</b></td></tr>";
00333
00334 foreach( Isotope * isotope , list )
00335 {
00336 html.append( "<tr><td align=\"right\">" );
00337 if ( isotope->mass() > 0.0 )
00338 html.append( i18n( "%1 u", isotope->mass() ) );
00339 html.append( "</td><td>" );
00340 html.append( QString::number( (( isotope )->nucleons()-( isotope )->parentElementNumber()) ) );
00341 html.append( "</td><td>" );
00342
00343 if ( !( isotope )->abundance().isEmpty() )
00344 html.append( i18nc( "this can for example be '24%'", "%1%", ( isotope )->abundance() ) );
00345 html.append( "</td><td>" );
00346
00347
00348
00349 html.append( "</td><td>" );
00350 if ( ( isotope )->alphalikeliness() > 0.0){
00351 if ( ( isotope )->alphadecay() > 0.0 )
00352 html.append( i18n( "%1 MeV", ( isotope )->alphadecay() ));
00353 html.append( i18n( " %1", QChar( 945 ) ));
00354 if ( ( isotope )->alphalikeliness() < 100.0)
00355 html.append( i18n( "(%1%)", ( isotope )->alphalikeliness()));
00356 if ( ( isotope )->betaminuslikeliness() > 0.0 || ( isotope )->betapluslikeliness() > 0.0 || ( isotope )->eclikeliness() > 0.0)
00357 html.append( i18n( ", " ) );
00358 }
00359 if ( ( isotope )->betaminuslikeliness() > 0.0){
00360 if ( ( isotope )->betaminusdecay() > 0.0 )
00361 html.append( i18n( "%1 MeV", ( isotope )->betaminusdecay() ));
00362 html.append( i18n( " %1<sup>-</sup>", QChar( 946 ) ));
00363 if ( ( isotope )->betaminuslikeliness() < 100.0)
00364 html.append( i18n( "(%1%)", ( isotope )->betaminuslikeliness() ));
00365
00366 if ( ( isotope )->betapluslikeliness() > 0.0 || ( isotope )->eclikeliness() > 0.0 )
00367 html.append( i18n( ", " ) );
00368 }
00369 if ( ( isotope )->betapluslikeliness() > 0.0) {
00370 if ( ( isotope )->betaplusdecay() > 0.0 )
00371 html.append( i18n( "%1 MeV", ( isotope )->betaplusdecay() ));
00372 html.append( i18n( " %1<sup>+</sup>", QChar( 946 ) ));
00373 if ( ( isotope )->betapluslikeliness() == ( isotope )->eclikeliness() ) {
00374 if ( ( isotope )->ecdecay() > 0.0 ) {
00375 html.append( i18n( "%1 MeV", ( isotope )->ecdecay() )); }
00376 html.append( i18nc( "Acronym of Electron Capture"," EC" ) );
00377 }
00378 if ( ( isotope )->betapluslikeliness() < 100.0)
00379 html.append( i18n( "(%1%)", ( isotope )->betapluslikeliness() ));
00380 html += ' ';
00381 }
00382 if ( ( isotope )->eclikeliness() > 0.0 ){
00383 if ( ( isotope )->ecdecay() > 0.0 )
00384 html.append( i18n( "%1 MeV", ( isotope )->ecdecay() ));
00385 html.append( i18nc( "Acronym of Electron Capture"," EC" ) );
00386 if ( ( isotope )->eclikeliness() < 100.0 )
00387 html.append( i18n( "(%1%)", ( isotope )->eclikeliness() ));
00388 }
00389 html.append( "</td><td>" );
00390 html.append( ( isotope )->spin() );
00391 html.append( "</td><td>" );
00392 if ( !( isotope )->magmoment().isEmpty() )
00393 html.append( i18n( "%1 %2<sub>n</sub>", ( isotope )->magmoment(), QChar( 956 ) ) );
00394 html.append( "</td></tr>" );
00395
00396 }
00397
00398 html += "</table>";
00399
00400 return html;
00401 }
00402
00403 void DetailedInfoDlg::createContent()
00404 {
00405 KPageWidgetItem *item = 0;
00406
00407
00408 QWidget *m_pOverviewTab = new QWidget();
00409 item = addPage( m_pOverviewTab, i18n( "Overview" ) );
00410 item->setHeader( i18n( "Overview" ) );
00411 item->setIcon( KIcon( "overview" ) );
00412 QVBoxLayout *overviewLayout = new QVBoxLayout( m_pOverviewTab );
00413 overviewLayout->setMargin( 0 );
00414 dTab = new DetailedGraphicalOverview( m_pOverviewTab );
00415 dTab->setObjectName( "DetailedGraphicalOverview" );
00416 overviewLayout->addWidget( dTab );
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 QWidget *m_pModelTab = new QWidget();
00431 item = addPage( m_pModelTab, i18n( "Atom Model" ) );
00432 item->setHeader( i18n( "Atom Model" ) );
00433 item->setIcon( KIcon( "orbits" ) );
00434 QVBoxLayout *modelLayout = new QVBoxLayout( m_pModelTab );
00435 modelLayout->setMargin( 0 );
00436 wOrbits = new OrbitsWidget( m_pModelTab );
00437 modelLayout->addWidget( wOrbits );
00438
00439
00440
00441
00442 m_htmlpages["misc"] = addHTMLTab( i18n( "Miscellaneous" ), i18n( "Miscellaneous" ), "misc" );
00443 m_htmlpages["isotopes"] = addHTMLTab( i18n( "Isotopes" ), i18n( "Isotopes" ), "isotopes" );
00444
00445 m_htmlpages["new"] = addHTMLTab( i18n( "Data Overview" ), i18n( "Data Overview" ), "data" );
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 }
00462
00463 void DetailedInfoDlg::reloadContent()
00464 {
00465
00466 const QString element_name = m_element->dataAsString( ChemicalDataObject::name );
00467 const QString element_symbol = m_element->dataAsString( ChemicalDataObject::symbol );
00468
00469
00470 setCaption( i18nc( "For example Carbon (6)" , "%1 (%2)", element_name, m_elementNumber ) );
00471
00472
00473 dTab->setElement( m_elementNumber );
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 wOrbits->setElementNumber( m_elementNumber );
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 fillHTMLTab( m_htmlpages["new"], getHtml( DATA ) );
00500 fillHTMLTab( m_htmlpages["misc"], getHtml( MISC ) );
00501 fillHTMLTab( m_htmlpages["isotopes"], getHtml( ISOTOPES ) );
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 }
00526
00527 void DetailedInfoDlg::slotHelp()
00528 {
00529
00530 #if 0
00531 QString chapter = "infodialog_overview";
00532 switch ( activePageIndex() )
00533 {
00534 case 0:
00535 chapter = "infodialog_overview";
00536 break;
00537 case 1:
00538 chapter = "infodialog_orbits";
00539 break;
00540 case 2:
00541 chapter = "infodialog_chemical";
00542 break;
00543 case 3:
00544 chapter = "infodialog_energies";
00545 break;
00546 case 4:
00547 chapter = "infodialog_misc";
00548 break;
00549 case 5:
00550 chapter = "infodialog_spectrum";
00551 break;
00552 case 6:
00553 chapter = "infodialog_warnings";
00554 break;
00555 }
00556 #endif
00557 KToolInvocation::invokeHelp( "infodialog_spectrum", QLatin1String( "kalzium" ) );
00558 }
00559
00560 void DetailedInfoDlg::slotUser1()
00561 {
00562 setElement( m_ktt->nextOf( m_elementNumber ) );
00563 }
00564
00565 void DetailedInfoDlg::slotUser2()
00566 {
00567 setElement( m_ktt->previousOf( m_elementNumber ) );
00568 }
00569
00570 #include "detailinfodlg.moc"