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