Test change - can I push OK?
[kdeedu-porting.git] / kalzium / src / detailinfodlg.cpp
blob55d8d57d6d08dccf8cc6f93e153fb6d5dcaca1f1
1 /***************************************************************************
2 begin : Tue Apr 8 2003
3 copyright : (C) 2003, 2004, 2005, 2006 by Carsten Niehaus
4 email : cniehaus@kde.org
5 ***************************************************************************/
7 /***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
16 #include "detailinfodlg.h"
17 #include "isotope.h"
18 #include "kalziumdataobject.h"
20 #include <klocale.h>
21 #include <khtml_part.h>
22 #include <dom/html_base.h>
23 #include <dom/html_document.h>
24 #include <khtmlview.h>
25 #include <kstandarddirs.h>
26 #include <kactioncollection.h>
27 #include <kpagewidgetmodel.h>
28 #include <ktoolinvocation.h>
31 #include <QFile>
32 #include <QLabel>
33 #include <QImage>
34 #include <QLayout>
35 #include <QPushButton>
36 #include <QStackedWidget>
37 #include <QDebug>
39 #include "element.h"
40 #include "orbitswidget.h"
41 #include "detailedgraphicaloverview.h"
42 #include "spectrumviewimpl.h"
43 #include "kalziumutils.h"
44 #include "kalziumtabletype.h"
46 DetailedInfoDlg::DetailedInfoDlg( int el , QWidget *parent )
47 : KPageDialog( parent ), m_ktt( 0 )
49 setFaceType( List );
50 setButtons( Help | User1 | User2 | Close );
51 setDefaultButton( Close );
52 setButtonGuiItem( User1, KGuiItem( i18nc( "Next element", "Next" ),
53 ( layoutDirection() == Qt::LeftToRight ) ? "arrow-right" : "arrow-left", i18n( "Goes to the next element" ) ) );
54 setButtonGuiItem( User2, KGuiItem( i18nc( "Previous element", "Previous" ),
55 ( layoutDirection() == Qt::LeftToRight ) ? "arrow-left" : "arrow-right", i18n( "Goes to the previous element" ) ) );
57 m_baseHtml = KGlobal::dirs()->findResourceDir( "appdata", "data/" ) + "data/htmlview/";
58 m_baseHtml2 = KGlobal::dirs()->findResourceDir( "appdata", "data/" ) + "data/hazardsymbols/";
60 //X m_picsdir = KGlobal::dirs()->findResourceDir( "appdata", "elempics/" ) + "elempics/";
62 // creating the tabs but not the contents, as that will be done when setting the element
63 createContent();
65 m_actionCollection = new KActionCollection(this);
66 KStandardAction::quit(this, SLOT(close()), m_actionCollection);
68 connect( this, SIGNAL( user1Clicked() ), this, SLOT( slotUser1() ) );
69 connect( this, SIGNAL( user2Clicked() ), this, SLOT( slotUser2() ) );
70 connect( this, SIGNAL( helpClicked() ), this, SLOT( slotHelp() ) );
72 // setting the element and updating the whole dialog
73 setElement( el );
76 void DetailedInfoDlg::setElement( int el )
78 Element *element = KalziumDataObject::instance()->element( el );
79 if ( !element ) return;
81 m_element = element;
82 m_elementNumber = el;
84 emit elementChanged( m_elementNumber );
86 reloadContent();
88 enableButton( User1, true );
89 enableButton( User2, true );
90 if ( m_elementNumber == 1 )
91 enableButton( User2, false );
92 else if ( m_elementNumber == KalziumDataObject::instance()->numberOfElements() )
93 enableButton( User1, false );
96 void DetailedInfoDlg::setOverviewBackgroundColor( const QColor &bgColor )
98 dTab->setBackgroundColor( bgColor );
101 void DetailedInfoDlg::setTableType( KalziumTableType* ktt )
103 m_ktt = ktt;
106 KHTMLPart* DetailedInfoDlg::addHTMLTab( const QString& title, const QString& icontext, const QString& iconname )
108 QWidget* frame = new QWidget();
109 KPageWidgetItem *item = addPage( frame, title );
110 item->setHeader( icontext );
111 item->setIcon( KIcon( iconname ) );
112 QVBoxLayout *layout = new QVBoxLayout( frame );
113 layout->setMargin( 0 );
114 KHTMLPart *w = new KHTMLPart( frame, frame );
115 layout->addWidget( w->view() );
117 return w;
120 void DetailedInfoDlg::fillHTMLTab( KHTMLPart* htmlpart, const QString& htmlcode )
122 if ( !htmlpart ) return;
124 htmlpart->begin();
125 htmlpart->write( htmlcode );
127 // set the background color of the document to match that of the dialog
128 DOM::HTMLElement element = htmlpart->htmlDocument().body();
129 if ( element.tagName() == "body" )
131 const QColor backgroundColor = palette().background().color();
132 ((DOM::HTMLBodyElement)element).setBgColor( backgroundColor.name() );
135 htmlpart->end();
138 QString DetailedInfoDlg::getHtml( DATATYPE type )
141 QString html =
142 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">"
143 "<html><head><title>Chemical data</title>"
144 "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + m_baseHtml + "style.css\" />"
145 "<base href=\"" + m_baseHtml + "\"/></head><body>"
146 "<div class=\"chemdata\"><div><table summary=\"header\">"
147 "<tr><td>" + m_element->dataAsString( ChemicalDataObject::symbol ) + "<td><td>"
148 + i18n( "Block: %1", m_element->dataAsString( ChemicalDataObject::periodTableBlock ) ) +
149 "</td></tr></table></div>"
150 "<table summary=\"characteristics\" class=\"characterstics\">";
152 switch ( type )
154 case MISC:
156 // discovery date and discoverers
157 html.append( "<tr><td><img src=\"discovery.png\" alt=\"icon\"/></td><td>" );
158 html += KalziumUtils::prettyUnit( m_element, ChemicalDataObject::date );
159 QString discoverers = m_element->dataAsString( ChemicalDataObject::discoverers );
160 if ( !discoverers.isEmpty() )
162 discoverers = discoverers.replace( ";", ", " );
163 html += "<br />" + i18n( "It was discovered by %1.", discoverers );
165 html.append( "</td></tr>" );
166 // origin of the name
167 QString nameorigin = m_element->dataAsString( ChemicalDataObject::nameOrigin );
168 if ( !nameorigin.isEmpty() )
170 html.append( "<tr><td><img src=\"book.png\" alt=\"icon\"/></td><td>" );
171 html.append( i18n( "Origin of the name:<br/>%1", nameorigin ) );
172 html.append( "</td></tr>" );
174 //X if ( m_element->artificial() || m_element->radioactive() )
175 //X {
176 //X html.append( "<tr><td><img src=\"structure.png\" alt=\"icon\"/></td><td>" );
177 //X if ( !m_element->radioactive() )
178 //X html.append( i18n( "This element is artificial" ));
179 //X else if ( !m_element->artificial() )
180 //X html.append( i18n( "This element is radioactive" ));
181 //X else
182 //X html.append( i18n( "This element is radioactive and artificial" ));
183 //X html.append( "</td></tr>" );
184 //X }
185 break;
187 case ISOTOPES:
189 html.append( "<tr><td>" );
190 html.append( isotopeTable() );
191 html.append( "</td></tr>" );
192 break;
194 case DATA:
196 // melting point
197 html.append( "<tr><td><img src=\"meltingpoint.png\" alt=\"icon\"/></td><td>" );
198 html.append( i18n( "Melting Point: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::meltingpoint ) ) );
199 html.append( "</td></tr>" );
201 // boiling point
202 html.append( "<tr><td><img src=\"boilingpoint.png\" alt=\"icon\"/></td><td>" );
203 html.append( i18n( "Boiling Point: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::boilingpoint ) ) );
204 html.append( "</td></tr>" );
206 html.append( "</table>" );
207 html.append( "<table summary=\"characteristics\" class=\"characterstics\">" );
209 // electro affinity
210 html.append( "<tr><td><img src=\"electronaffinity.png\" alt=\"icon\"/></td><td>" );
211 html.append( i18n( "Electron Affinity: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::electronAffinity ) ) );
212 html.append( "</td></tr>" );
214 //Electronic configuration
215 html.append( "<tr><td><img src=\"structure.png\" alt=\"icon\"/></td><td>" );
216 //Probably beautify here...
217 QString config = beautifyOrbitalString(m_element->dataAsString( ChemicalDataObject::electronicConfiguration ) );
218 html.append( i18n( "Electronic configuration: %1", config ) );
219 html.append( "</td></tr>" );
221 // covalent radius
222 html.append( "<tr><td><img src=\"radius.png\" alt=\"icon\"/></td><td>" );
223 html.append( i18n( "Covalent Radius: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::radiusCovalent ) ) );
224 html.append( "</td></tr>" );
226 // van der Waals radius
227 html.append( "<tr><td><img src=\"radius.png\" alt=\"icon\"/></td><td>" );
228 html.append( i18n( "van der Waals Radius: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::radiusVDW ) ) );
229 html.append( "</td></tr>" );
231 // mass
232 html.append( "<tr><td stype=\"text-align:center\"><img src=\"mass.png\" alt=\"icon\"/></td><td>" );
233 html.append( i18n( "Mass: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::mass ) ) );
234 html.append( "</td></tr>" );
236 // 1st ionization energy
237 html.append( "<tr><td><img src=\"ionisation.png\" alt=\"icon\"/></td><td>" );
238 html.append( i18n( "First Ionization energy: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::ionization ) ) );
239 html.append( "</td></tr>" );
241 // electro negativity
242 html.append( "<tr><td><img src=\"structure.png\" alt=\"icon\"/></td><td>" );
243 html.append( i18n( "Electronegativity: %1", KalziumUtils::prettyUnit( m_element, ChemicalDataObject::electronegativityPauling ) ) );
244 html.append( "</td></tr>" );
248 html += "</table></div></body></html>";
250 return html;
253 QString DetailedInfoDlg::isotopeTable() const
255 QList<Isotope*> list = KalziumDataObject::instance()->isotopes( m_elementNumber );
257 QString html;
259 html = "<table class=\"isotopes\" cellspacing=\"0\"><tr><td colspan=\"7\">";
260 html += i18n( "Isotope-Table" );
261 html += "</tr></td><tr><td><b>";
262 html += i18n( "Mass" );
263 html += "</b></td><td><b>";
264 html += i18n( "Neutrons" );
265 html += "</b></td><td><b>";
266 html += i18n( "Percentage" );
267 html += "</b></td><td><b>";
268 html += i18n( "Half-life period" );
269 html += "</b></td><td><b>";
270 html += i18n( "Energy and Mode of Decay" );
271 html += "</b></td><td><b>";
272 html += i18n( "Spin and Parity" );
273 html += "</b></td><td><b>";
274 html += i18n( "Magnetic Moment" );
275 html += "</b></td></tr>";
277 foreach( Isotope * isotope , list )
279 html.append( "<tr><td align=\"right\">" );
280 if ( isotope->mass() > 0.0 )
281 html.append( i18n( "%1 u", isotope->mass() ) );
282 html.append( "</td><td>" );
283 html.append( QString::number( (( isotope )->nucleons()-( isotope )->parentElementNumber()) ) );
284 html.append( "</td><td>" );
285 if ( !( isotope )->abundance().isEmpty() )
286 html.append( i18nc( "this can for example be '24%'", "%1%", ( isotope )->abundance() ) );
287 html.append( "</td><td>" );
288 if ( ( isotope )->halflife() > 0.0 )
289 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( ) ) );
290 html.append( "</td><td>" );
291 if ( ( isotope )->alphalikeliness() > 0.0){
292 if ( ( isotope )->alphadecay() > 0.0 )
293 html.append( i18n( "%1 MeV", ( isotope )->alphadecay() ));
294 html.append( i18n( " %1", QChar( 945 ) ));
295 if ( ( isotope )->alphalikeliness() < 100.0)
296 html.append( i18n( "(%1%)", ( isotope )->alphalikeliness()));
297 if ( ( isotope )->betaminuslikeliness() > 0.0 || ( isotope )->betapluslikeliness() > 0.0 || ( isotope )->eclikeliness() > 0.0)
298 html.append( i18n( ", " ) );
300 if ( ( isotope )->betaminuslikeliness() > 0.0){
301 if ( ( isotope )->betaminusdecay() > 0.0 )
302 html.append( i18n( "%1 MeV", ( isotope )->betaminusdecay() ));
303 html.append( i18n( " %1<sup>-</sup>", QChar( 946 ) ));
304 if ( ( isotope )->betaminuslikeliness() < 100.0)
305 html.append( i18n( "(%1%)", ( isotope )->betaminuslikeliness() ));
307 if ( ( isotope )->betapluslikeliness() > 0.0 || ( isotope )->eclikeliness() > 0.0 )
308 html.append( i18n( ", " ) );
310 if ( ( isotope )->betapluslikeliness() > 0.0) {
311 if ( ( isotope )->betaplusdecay() > 0.0 )
312 html.append( i18n( "%1 MeV", ( isotope )->betaplusdecay() ));
313 html.append( i18n( " %1<sup>+</sup>", QChar( 946 ) ));
314 if ( ( isotope )->betapluslikeliness() == ( isotope )->eclikeliness() ) {
315 if ( ( isotope )->ecdecay() > 0.0 ) {
316 html.append( i18n( "%1 MeV", ( isotope )->ecdecay() )); }
317 html.append( i18nc( "Acronym of Electron Capture"," EC" ) );
319 if ( ( isotope )->betapluslikeliness() < 100.0)
320 html.append( i18n( "(%1%)", ( isotope )->betapluslikeliness() ));
321 html += ' ';
323 if ( ( isotope )->eclikeliness() > 0.0 ){
324 if ( ( isotope )->ecdecay() > 0.0 )
325 html.append( i18n( "%1 MeV", ( isotope )->ecdecay() ));
326 html.append( i18nc( "Acronym of Electron Capture"," EC" ) );
327 if ( ( isotope )->eclikeliness() < 100.0 )
328 html.append( i18n( "(%1%)", ( isotope )->eclikeliness() ));
330 html.append( "</td><td>" );
331 html.append( ( isotope )->spin() );
332 html.append( "</td><td>" );
333 if ( !( isotope )->magmoment().isEmpty() )
334 html.append( i18n( "%1 %2<sub>n</sub>", ( isotope )->magmoment(), QChar( 956 ) ) );
335 html.append( "</td></tr>" );
339 html += "</table>";
341 return html;
344 void DetailedInfoDlg::createContent()
346 KPageWidgetItem *item = 0;
348 // overview tab
349 QWidget *m_pOverviewTab = new QWidget();
350 item = addPage( m_pOverviewTab, i18n( "Overview" ) );
351 item->setHeader( i18n( "Overview" ) );
352 item->setIcon( KIcon( "overview" ) );
353 QVBoxLayout *overviewLayout = new QVBoxLayout( m_pOverviewTab );
354 overviewLayout->setMargin( 0 );
355 dTab = new DetailedGraphicalOverview( m_pOverviewTab );
356 dTab->setObjectName( "DetailedGraphicalOverview" );
357 overviewLayout->addWidget( dTab );
359 //X // picture tab
360 //X QWidget *m_pPictureTab = new QWidget();
361 //X item = addPage( m_pPictureTab, i18n( "Picture" ) );
362 //X item->setHeader( i18n( "What does this element look like?" ) );
363 //X item->setIcon( KIcon( "elempic" ) );
364 //X QVBoxLayout *mainLayout = new QVBoxLayout( m_pPictureTab );
365 //X mainLayout->setMargin( 0 );
366 //X piclabel = new QLabel( m_pPictureTab );
367 //X piclabel->setMinimumSize( 400, 350 );
368 //X mainLayout->addWidget( piclabel );
370 // atomic model tab
371 QWidget *m_pModelTab = new QWidget();
372 item = addPage( m_pModelTab, i18n( "Atom Model" ) );
373 item->setHeader( i18n( "Atom Model" ) );
374 item->setIcon( KIcon( "orbits" ) );
375 QVBoxLayout *modelLayout = new QVBoxLayout( m_pModelTab );
376 modelLayout->setMargin( 0 );
377 wOrbits = new OrbitsWidget( m_pModelTab );
378 modelLayout->addWidget( wOrbits );
380 // html tabs
381 m_htmlpages["misc"] = addHTMLTab( i18n( "Miscellaneous" ), i18n( "Miscellaneous" ), "misc" );
382 m_htmlpages["isotopes"] = addHTMLTab( i18n( "Isotopes" ), i18n( "Isotopes" ), "isotopes" );
383 m_htmlpages["new"] = addHTMLTab( i18n( "Data Overview" ), i18n( "Data Overview" ), "data" );
385 // spectrum widget tab
386 QWidget *m_pSpectrumTab = new QWidget();
387 item = addPage( m_pSpectrumTab, i18n( "Spectrum" ) );
388 item->setHeader( i18n( "Spectrum" ) );
389 item->setIcon( KIcon( "spectrum" ) );
390 QVBoxLayout *spectrumLayout = new QVBoxLayout( m_pSpectrumTab );
391 spectrumLayout->setMargin( 0 );
392 m_spectrumStack = new QStackedWidget( m_pSpectrumTab );
393 spectrumLayout->addWidget( m_spectrumStack );
394 m_spectrumview = new SpectrumViewImpl( m_spectrumStack );
395 m_spectrumview->setObjectName( "spectrumwidget" );
396 m_spectrumStack->addWidget( m_spectrumview );
397 m_spectrumLabel = new QLabel( m_spectrumStack );
398 m_spectrumStack->addWidget( m_spectrumLabel );
401 void DetailedInfoDlg::reloadContent()
403 // reading the most common data
404 const QString element_name = m_element->dataAsString( ChemicalDataObject::name );
405 const QString element_symbol = m_element->dataAsString( ChemicalDataObject::symbol );
407 // updating caption
408 setCaption( i18nc( "For example Carbon (6)" , "%1 (%2)", element_name, m_elementNumber ) );
410 // updating overview tab
411 dTab->setElement( m_elementNumber );
413 //X // updating picture tab
414 //X QString picpath = m_picsdir + element_symbol + ".jpg";
415 //X if ( QFile::exists( picpath ) )
416 //X {
417 //X QImage img( picpath, "JPEG" );
418 //X img = img.scaled( 400, 400, Qt::KeepAspectRatio );
419 //X piclabel->setPixmap( QPixmap::fromImage( img ) );
420 //X }
421 //X else
422 //X piclabel->setText( i18n( "No picture of %1 found.", element_name ) );
424 // updating atomic model tab
425 wOrbits->setElementNumber( m_elementNumber );
427 wOrbits->setWhatsThis(
428 i18n( "Here you can see the atomic hull of %1. %2 has the configuration %3." )
429 .arg( m_element->dataAsString( ChemicalDataObject::name ) )
430 .arg( m_element->dataAsString( ChemicalDataObject::name ) )
431 .arg( "" ));//m_element->parsedOrbits() ) );
434 // updating html tabs
435 fillHTMLTab( m_htmlpages["new"], getHtml( DATA ) );
436 fillHTMLTab( m_htmlpages["misc"], getHtml( MISC ) );
437 fillHTMLTab( m_htmlpages["isotopes"], getHtml( ISOTOPES ) );
439 Spectrum * spec = KalziumDataObject::instance()->spectrum( m_elementNumber );
441 // updating spectrum widget
442 if ( spec )
444 m_spectrumview->setSpectrum( spec );
446 else
448 m_spectrumLabel->setText( i18n( "No spectrum of %1 found.", element_name ) );
449 m_spectrumStack->setCurrentWidget( m_spectrumLabel );
453 void DetailedInfoDlg::slotHelp()
455 //TODO fix this stuff...
456 #if 0
457 QString chapter = "infodialog_overview";
458 switch ( activePageIndex() )
460 case 0:
461 chapter = "infodialog_overview";
462 break;
463 case 1:
464 chapter = "infodialog_orbits";
465 break;
466 case 2:
467 chapter = "infodialog_chemical";
468 break;
469 case 3:
470 chapter = "infodialog_energies";
471 break;
472 case 4:
473 chapter = "infodialog_misc";
474 break;
475 case 5:
476 chapter = "infodialog_spectrum";
477 break;
478 case 6:
479 chapter = "infodialog_warnings";
480 break;
482 #endif
483 KToolInvocation::invokeHelp( "infodialog_spectrum", QLatin1String( "kalzium" ) );
486 void DetailedInfoDlg::slotUser1()
488 setElement( m_ktt->nextOf( m_elementNumber ) );
491 QString DetailedInfoDlg::beautifyOrbitalString(const QString& orbits)
493 QString newOrbit = orbits;
495 QRegExp reg( "(.*)(f|s|d|p)(\\d+)(.?)" );
497 bool superindexesLeft = newOrbit.contains( reg );
498 while (superindexesLeft) {
499 newOrbit = newOrbit.replace( reg, "\\1\\2<sup>\\3</sup>\\4" );
501 superindexesLeft = newOrbit.contains( reg );
504 return newOrbit;
507 void DetailedInfoDlg::slotUser2()
509 setElement( m_ktt->previousOf( m_elementNumber ) );
512 #include "detailinfodlg.moc"