diff --git a/src/detailedgraphicaloverview.cpp b/src/detailedgraphicaloverview.cpp index 1fea5809..8aff0f6a 100644 --- a/src/detailedgraphicaloverview.cpp +++ b/src/detailedgraphicaloverview.cpp @@ -1,171 +1,171 @@ /*************************************************************************** copyright : (C) 2004, 2005, 2006, 2007 by Carsten Niehaus email : 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. * * * ***************************************************************************/ #include "detailedgraphicaloverview.h" #include "kalziumdataobject.h" #include "kalziumutils.h" #include #include #include #include #include #include #include #include #include #include #include "prefs.h" DetailedGraphicalOverview::DetailedGraphicalOverview(QWidget *parent) : QWidget(parent), m_element(nullptr) { setAttribute(Qt::WA_NoBackground, true); setMinimumSize(300, 200); // Set Hydrogen as initial element. setElement(1); } void DetailedGraphicalOverview::setElement(int el) { m_element = KalziumDataObject::instance()->element(el); setBackgroundColor(KalziumElementProperty::instance()->getElementColor(el)); update(); } void DetailedGraphicalOverview::setBackgroundColor(QColor bgColor) { if (bgColor == Qt::transparent) { bgColor = palette().window().color(); } // add a gradient QLinearGradient grad(QPointF(0, 0), QPointF(0, height())); grad.setColorAt(0,bgColor); qreal h, s, v, a; bgColor.getHsvF(&h, &s, &v, &a); bgColor.setHsvF(h, s, v*0.6, a); grad.setColorAt(1,bgColor); m_backgroundBrush = QBrush(grad); } void DetailedGraphicalOverview::paintEvent(QPaintEvent*) { QRect rect(0, 0, width(), height()); QPixmap pm(width(), height()); QPainter p; p.begin(&pm); p.setBrush(Qt::SolidPattern); if (!m_element) { pm.fill(palette().window().color()); p.drawText(0, 0, width(), height(), Qt::AlignCenter | Qt::TextWordWrap, i18n("No element selected")); } else if (Prefs::colorschemebox() == 2) { //The iconic view is the 3rd view (0,1,2,...) pm.fill(palette().window().color()); QString pathname = QStandardPaths::locate(QStandardPaths::DataLocation, QStringLiteral("data/iconsets/"), QStandardPaths::LocateDirectory); int enumii = m_element->dataAsVariant(ChemicalDataObject::atomicNumber).toInt(); QString filename = pathname + "school" + '/' + QString::number(enumii) + ".svg"; QSvgRenderer svgrenderer; if (QFile::exists(filename) && svgrenderer.load(filename)) { QSize size = svgrenderer.defaultSize(); size.scale(width(), height(), Qt::KeepAspectRatio); QRect bounds(QPoint(0, 0), size); bounds.moveCenter(QPoint(width()/2, height()/2)); svgrenderer.render(&p, bounds); } else { p.drawText(rect, Qt::AlignCenter | Qt::TextWordWrap, i18n("No graphic found")); } } else { const int h_t = 20; //height of the texts p.setBrush(m_backgroundBrush); p.drawRect(rect); p.setBrush(Qt::black); p.setBrush(Qt::NoBrush); QFont fA = QFontDatabase::systemFont(QFontDatabase::GeneralFont); QFont fB = QFontDatabase::systemFont(QFontDatabase::GeneralFont); QFont fC = QFontDatabase::systemFont(QFontDatabase::GeneralFont); fA.setPointSize(fA.pointSize() + 20); //Huge font fA.setBold(true); fB.setPointSize(fB.pointSize() + 6); //Big font fC.setPointSize(fC.pointSize() + 4); //Big font fC.setBold(true); QFontMetrics fmA = QFontMetrics(fA); QFontMetrics fmB = QFontMetrics(fB); //coordinates for element symbol: near the center int xA = 4 * width() / 10; int yA = height() / 2; //coordinates for the atomic number: offset from element symbol to the upper left - int xB = xA - fmB.width(m_element->dataAsString(ChemicalDataObject::atomicNumber)); + int xB = xA - fmB.boundingRect(m_element->dataAsString(ChemicalDataObject::atomicNumber)).width(); int yB = yA + fmB.height()/2; //Element Symbol p.setFont(fA); p.drawText(xA, yA, m_element->dataAsString(ChemicalDataObject::symbol)); //Atomic number p.setFont(fB); p.drawText(xB, yB, m_element->dataAsString(ChemicalDataObject::atomicNumber)); //Name and other data fC.setPointSize(h_t); p.setFont(fC); //Name p.drawText(1, 0, width(), height(), Qt::AlignLeft, m_element->dataAsString(ChemicalDataObject::name)); //TODO Oxidationstates -> not there yet //Mass QString massString = i18nc("For example '1.0079u', the mass of an element in units", "%1 u", m_element->dataAsString(ChemicalDataObject::mass)); int size3 = KalziumUtils::maxSize(massString, rect, fC, &p); fC.setPointSize(size3); p.setFont(fC); int offset = KalziumUtils::StringHeight(massString, fC, &p); p.drawText(0, height() - offset, width(), offset, Qt::AlignRight, massString ); } p.end(); p.begin(this); p.drawPixmap(0, 0, pm); p.end(); } diff --git a/src/kalzium.cpp b/src/kalzium.cpp index 0a96cdf3..fb63d256 100644 --- a/src/kalzium.cpp +++ b/src/kalzium.cpp @@ -1,648 +1,648 @@ /*************************************************************************** copyright : (C) 2003-2007 by Carsten Niehaus email : 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. * * * ***************************************************************************/ #include "kalzium.h" #include #include #include "prefs.h" #include "ui_settings_colors.h" #include "ui_settings_gradients.h" #include "ui_settings_calc.h" #include "detailinfodlg.h" #include "detailedgraphicaloverview.h" #include "gradientwidget_impl.h" #include "kalziumdataobject.h" #include "kalziumnumerationtype.h" #include "kalziumschemetype.h" #include "kalziumgradienttype.h" #include "legendwidget.h" #include "exportdialog.h" #include "search.h" #include "searchwidget.h" #include "tableinfowidget.h" #include "psetables.h" #include #ifdef HAVE_FACILE #include "eqchemview.h" #endif #ifdef HAVE_OPENBABEL2 #if defined(HAVE_EIGEN) && defined(HAVE_AVOGADRO) #include "tools/moleculeview.h" #include #endif #include "tools/obconverter.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define IDS_ELEMENTINFO 7 Kalzium::Kalzium() : KXmlGuiWindow(nullptr) { setObjectName(QStringLiteral("KalziumMainWindow")); // Init pointers with null m_infoDialog = nullptr; m_isotopeDialog = nullptr; m_elementDataPlotter = nullptr; m_tablesDialog = nullptr; m_rsDialog = nullptr; m_calculator = nullptr; m_exportDialog = nullptr; m_glossarydlg = nullptr; m_elementInfo = nullptr; // reading the elements from file KalziumDataObject::instance(); Search *newsearch = new Search(); KalziumDataObject::instance()->setSearch(newsearch); // Main pse-Table Tablewidget QWidget *pseTempWidget = new QWidget(this); QVBoxLayout *layout = new QVBoxLayout(pseTempWidget); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(2); SearchWidget *searchWidget = new SearchWidget(pseTempWidget); searchWidget->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Maximum)); // Creating the periodic table m_periodicTable = new PeriodicTableView(pseTempWidget); // Connecting the search to the periodic table connect(newsearch, &Search::searchChanged, KalziumElementProperty::instance(), &KalziumElementProperty::propertyChanged); connect(newsearch, &Search::searchReset, KalziumElementProperty::instance(), &KalziumElementProperty::propertyChanged); layout->addWidget(searchWidget); layout->addWidget(m_periodicTable); setCentralWidget(pseTempWidget); connect(m_periodicTable->pseScene(), &PeriodicTableScene::elementChanged, this, &Kalzium::openInformationDialog); connect(m_periodicTable->pseScene(), &PeriodicTableScene::elementHovered, this, &Kalzium::elementHover); connect(this, &Kalzium::numerationChanged, m_periodicTable, &PeriodicTableView::numerationChange); // layouting setupSidebars(); setupActions(); setupStatusBar(); } void Kalzium::setupActions() { export_action = actionCollection()->add(QStringLiteral("file_exporter")); export_action->setText(i18n("&Export Data...")); connect(export_action, &QAction::triggered, this, &Kalzium::slotShowExportDialog); // the action for switching look: color schemes and gradients QStringList schemes = KalziumElementProperty::instance()->schemeList(); /*KalziumSchemeTypeFactory::instance()->schemes();*/ QStringList gradients = KalziumElementProperty::instance()->gradientList(); // the action for switching look: schemes look_action_schemes = actionCollection()->add(QStringLiteral("view_look_onlyschemes")); look_action_schemes->setText(i18n("&Scheme")); look_action_schemes->setItems(schemes); look_action_schemes->setToolBarMode(KSelectAction::MenuMode); look_action_schemes->setToolButtonPopupMode(QToolButton::InstantPopup); connect(look_action_schemes, SIGNAL(triggered(int)), this, SLOT(slotSwitchtoLookScheme(int))); // the action for switching look: gradients look_action_gradients = actionCollection()->add(QStringLiteral("view_look_onlygradients")); look_action_gradients->setText(i18n("&Gradients")); look_action_gradients->setItems(gradients); look_action_gradients->setToolBarMode(KSelectAction::MenuMode); look_action_gradients->setToolButtonPopupMode(QToolButton::InstantPopup); connect(look_action_gradients, SIGNAL(triggered(int)), this, SLOT(slotSwitchtoLookGradient(int))); // the action for switching tables QStringList table_schemes = pseTables::instance()->tables(); table_action = actionCollection()->add(QStringLiteral("view_table")); table_action->setText(i18n("&Tables")); table_action->setItems(table_schemes); table_action->setCurrentItem(Prefs::table()); connect(table_action, SIGNAL(triggered(int)), this, SLOT(slotSwitchtoTable(int))); // the actions for switching numeration numeration_action = actionCollection()->add(QStringLiteral("view_numerationtype")); numeration_action->setText(i18n("&Numeration")); numeration_action->setItems(KalziumNumerationTypeFactory::instance()->numerations()); numeration_action->setCurrentItem(Prefs::numeration()); connect(numeration_action, SIGNAL(triggered(int)), this, SLOT(slotSwitchtoNumeration(int))); // tools actions m_pPlotAction = actionCollection()->addAction(QStringLiteral("tools_plotdata")); m_pPlotAction->setText(i18n("&Plot Data...")); m_pPlotAction->setIcon(QIcon::fromTheme(QStringLiteral("plot"))); connect(m_pPlotAction, &QAction::triggered, this, &Kalzium::slotPlotData); // calculator actions m_pcalculator = actionCollection()->addAction(QStringLiteral("tools_calculate")); m_pcalculator->setText(i18n("Perform &Calculations...")); m_pcalculator->setIcon(QIcon::fromTheme(QStringLiteral("calculate"))); m_pcalculator->setWhatsThis(i18nc("WhatsThis Help", "This is the calculator, it performs basic chemical calculations.")); connect(m_pcalculator, &QAction::triggered, this, &Kalzium::showCalculator); m_pIsotopeTableAction= actionCollection()->addAction(QStringLiteral("tools_isotopetable")); m_pIsotopeTableAction->setText(i18n("&Isotope Table...")); m_pIsotopeTableAction->setIcon(QIcon::fromTheme(QStringLiteral("isotopemap"))); m_pIsotopeTableAction->setWhatsThis(i18nc("WhatsThis Help", "This table shows all of the known isotopes of the chemical elements.")); connect(m_pIsotopeTableAction, &QAction::triggered, this, &Kalzium::slotIsotopeTable); m_pGlossaryAction = actionCollection()->addAction(QStringLiteral("tools_glossary")); m_pGlossaryAction->setText(i18n("&Glossary...")); m_pGlossaryAction->setIcon(QIcon::fromTheme(QStringLiteral("glossary"))); connect(m_pGlossaryAction, &QAction::triggered, this, &Kalzium::slotGlossary); m_pRSAction = actionCollection()->addAction(QStringLiteral("tools_rs")); m_pRSAction->setText(i18n("&R/S Phrases...")); m_pRSAction->setIcon(QIcon::fromTheme(QStringLiteral("kalzium_rs"))); connect(m_pRSAction, &QAction::triggered, this, &Kalzium::slotRS); m_pOBConverterAction = actionCollection()->addAction(QStringLiteral("tools_obconverter")); m_pOBConverterAction->setText(i18n("Convert chemical files...")); m_pOBConverterAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy"))); m_pOBConverterAction->setWhatsThis(i18nc("WhatsThis Help", "With this tool, you can convert files containing chemical data between various file formats.")); connect(m_pOBConverterAction, &QAction::triggered, this, &Kalzium::slotOBConverter); #ifndef HAVE_OPENBABEL2 m_pOBConverterAction->setEnabled(false); #endif m_pMoleculesviewer = actionCollection()->addAction(QStringLiteral("tools_moleculeviewer")); m_pMoleculesviewer->setText(i18n("Molecular Editor...")); m_pMoleculesviewer->setIcon(QIcon::fromTheme(QStringLiteral("kalzium_molviewer"))); m_pMoleculesviewer->setWhatsThis(i18nc("WhatsThis Help", "This tool allows you to view and edit 3D molecular structures.")); connect(m_pMoleculesviewer, &QAction::triggered, this, &Kalzium::slotMoleculeviewer); #if !defined(HAVE_OPENBABEL2) || !defined(HAVE_EIGEN) || !defined(HAVE_AVOGADRO) m_pMoleculesviewer->setEnabled(false); #endif m_pTables = actionCollection()->addAction(QStringLiteral("tools_tables")); m_pTables->setText(i18n("&Tables...")); m_pTables->setIcon(QIcon::fromTheme(QStringLiteral("kalzium_tables"))); m_pTables->setWhatsThis(i18nc("WhatsThis Help", "This will open a dialog with listings of symbols and numbers related to chemistry.")); connect(m_pTables, &QAction::triggered, this, &Kalzium::slotTables); // other period view options m_pLegendAction = m_legendDock->toggleViewAction(); actionCollection()->addAction(QStringLiteral("view_legend"), m_pLegendAction); m_pLegendAction->setIcon(QIcon::fromTheme(QStringLiteral("legend"))); m_pLegendAction->setWhatsThis(i18nc("WhatsThis Help", "This will show or hide the legend for the periodic table.")); m_SidebarAction = m_dockWin->toggleViewAction(); actionCollection()->addAction(QStringLiteral("view_sidebar"), m_SidebarAction); m_SidebarAction->setIcon(QIcon::fromTheme(QStringLiteral("sidebar"))); m_SidebarAction->setWhatsThis(i18nc("WhatsThis Help", "This will show or hide a sidebar with additional information and a set of tools.")); m_SidebarAction = m_tableDock->toggleViewAction(); actionCollection()->addAction(QStringLiteral("view_tablebar"), m_SidebarAction); m_SidebarAction->setIcon(QIcon::fromTheme(QStringLiteral("kalzium_tables"))); m_SidebarAction->setWhatsThis(i18nc("WhatsThis Help", "This will show or hide a sidebar with additional information about the table.")); // the standard actions actionCollection()->addAction(QStringLiteral("saveAs"), KStandardAction::saveAs(this, SLOT(slotExportTable()), actionCollection())); KStandardAction::preferences(this, SLOT(showSettingsDialog()), actionCollection()); actionCollection()->addAction(QStringLiteral("quit"), KStandardAction::quit(qApp, SLOT(quit()), actionCollection())); m_legendWidget->LockWidget(); slotSwitchtoLookGradient(KalziumElementProperty::instance()->gradientId()); slotSwitchtoLookScheme(KalziumElementProperty::instance()->schemeId()); slotSwitchtoNumeration(Prefs::numeration()); slotSwitchtoTable(Prefs::table()); m_legendWidget->UnLockWidget(); m_legendWidget->updateContent(); // set the shell's ui resource file setXMLFile(QStringLiteral("kalziumui.rc")); setupGUI(); } void Kalzium::setupSidebars() { setDockNestingEnabled(true); m_legendWidget = new LegendWidget(this); m_legendDock = new QDockWidget(i18n("Legend"), this); m_legendDock->setObjectName(QStringLiteral("kalzium-legend")); m_legendDock->setFeatures(QDockWidget::AllDockWidgetFeatures); m_legendDock->setWidget(m_legendWidget); connect(m_legendDock, &QDockWidget::dockLocationChanged, m_legendWidget, &LegendWidget::setDockArea); connect(m_legendWidget, &LegendWidget::elementMatched, m_periodicTable, &PeriodicTableView::slotSelectAdditionalElement); connect(m_legendWidget, &LegendWidget::resetElementMatch, m_periodicTable, &PeriodicTableView::slotUnSelectElements); m_TableInfoWidget = new TableInfoWidget(this); m_tableDock = new QDockWidget(i18n("Table Information"), this); m_tableDock->setWidget(m_TableInfoWidget); m_tableDock->setObjectName(QStringLiteral("kalzium-tableinfo")); m_tableDock->setFeatures(QDockWidget::AllDockWidgetFeatures); m_dockWin = new QDockWidget(i18n("Information"), this); m_dockWin->setObjectName(QStringLiteral("kalzium-sidebar")); m_dockWin->setFeatures(QDockWidget::AllDockWidgetFeatures); m_dockWin->setMinimumWidth(250); m_toolbox = new QToolBox(m_dockWin); m_dockWin->setWidget(m_toolbox); m_detailWidget = new DetailedGraphicalOverview(m_toolbox); m_detailWidget->setObjectName(QStringLiteral("DetailedGraphicalOverview")); m_detailWidget->setMinimumSize(200, m_detailWidget->minimumSize().height()); m_toolbox->addItem(m_detailWidget, QIcon::fromTheme(QStringLiteral("overview")), i18n("Overview")); m_gradientWidget = new GradientWidgetImpl(m_toolbox); m_gradientWidget->setObjectName(QStringLiteral("viewtWidget")); connect(m_gradientWidget, &GradientWidgetImpl::gradientValueChanged, KalziumElementProperty::instance(), &KalziumElementProperty::setSliderValue); connect(m_gradientWidget->scheme_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSwitchtoLookScheme(int))); connect(m_gradientWidget->gradient_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSwitchtoLookGradient(int))); m_toolbox->addItem(m_gradientWidget, QIcon::fromTheme(QStringLiteral("statematter")), i18n("View")); addDockWidget(Qt::LeftDockWidgetArea, m_dockWin); addDockWidget(Qt::BottomDockWidgetArea, m_tableDock, Qt::Horizontal); addDockWidget(Qt::BottomDockWidgetArea, m_legendDock, Qt::Horizontal); m_tableDock->setVisible(false); } void Kalzium::slotExportTable() { QString fileName = QFileDialog::getSaveFileName(this, i18n("Save Kalzium's Table In"), QString(), i18n("Image files (*.png *.xpm *.jpg *.svg)")); if (fileName.endsWith(QLatin1String(".svg"))) { m_periodicTable->generateSvg(fileName); } else { - QPixmap pix = QPixmap::grabWidget(m_periodicTable); + QPixmap pix = m_periodicTable->grab(); pix.save(fileName); } } void Kalzium::slotGlossary() { if (!m_glossarydlg) { // creating the glossary dialog and loading the glossaries we have m_glossarydlg = new GlossaryDialog(this); m_glossarydlg->setObjectName(QStringLiteral("glossary")); QString dir = QStandardPaths::locate(QStandardPaths::DataLocation, QStringLiteral("data/"), QStandardPaths::LocateDirectory); dir = QFileInfo(dir).absolutePath(); QString picturepath = dir + "/bg.jpg"; QUrl u = QUrl::fromLocalFile(dir + "/knowledge.xml"); Glossary *g = new Glossary(u); g->setName(i18n("Knowledge")); g->setBackgroundPicture(picturepath); m_glossarydlg->addGlossary(g, true); u = QUrl::fromLocalFile(dir + "/tools.xml"); g = new Glossary(u, dir + "/toolpics/"); g->setName(i18n("Tools")); g->setBackgroundPicture(picturepath); m_glossarydlg->addGlossary(g, true); } m_glossarydlg->show(); } void Kalzium::slotRS() { if (!m_rsDialog) { m_rsDialog = new RSDialog(this); } m_rsDialog->show(); } void Kalzium::slotOBConverter() { #ifdef HAVE_OPENBABEL2 KOpenBabel * d = new KOpenBabel(this); d->setAttribute(Qt::WA_DeleteOnClose); d->show(); #endif } MoleculeDialog *Kalzium::slotMoleculeviewer() { #if defined(HAVE_OPENBABEL2) && defined(HAVE_EIGEN) && defined(HAVE_AVOGADRO) if (!QGLFormat::hasOpenGL()) { QMessageBox::critical(Q_NULLPTR, i18n("Kalzium Error"), i18n("This system does not support OpenGL.")); return nullptr; } MoleculeDialog * d = new MoleculeDialog(this); d->show(); return d; #if 0 KPluginLoader loader("libkalziumglpart"); KPluginFactory* factory = loader.factory(); if (factory) { KParts::ReadOnlyPart *part = 0; part = static_cast(factory->create(this, "KalziumGLPart")); part->widget()->show(); } #endif #endif return nullptr; } void Kalzium::slotTables() { if (!m_tablesDialog) { m_tablesDialog = new TablesDialog(this); } m_tablesDialog->show(); } void Kalzium::slotIsotopeTable() { if (!m_isotopeDialog) { m_isotopeDialog = new IsotopeTableDialog(this); } m_isotopeDialog->show(); } void Kalzium::slotPlotData() { if (!m_elementDataPlotter) { m_elementDataPlotter = new ElementDataViewer(this); } m_elementDataPlotter->show(); } void Kalzium::showCalculator() { if (!m_calculator) { m_calculator = new calculator(this); } m_calculator -> show(); } void Kalzium::slotSwitchtoTable(int index) { m_periodicTable->slotChangeTable(index); m_TableInfoWidget->setTableType(index); if (m_infoDialog) { m_infoDialog->setTableType(m_periodicTable->table()); } Prefs::setTable(index); Prefs::self()->save(); } void Kalzium::slotSwitchtoNumeration(int index) { emit numerationChanged(index); Prefs::setNumeration(index); Prefs::self()->save(); } void Kalzium::slotSwitchtoLookGradient(int which) { qDebug() << "slotSwitchtoLookGradient Kalzium"; KalziumElementProperty::instance()->setGradient(which); look_action_gradients->blockSignals(true); m_gradientWidget->gradient_combo->blockSignals(true); look_action_gradients->setCurrentItem(which); m_gradientWidget->gradient_combo->setCurrentIndex(which); look_action_gradients->blockSignals(false); m_gradientWidget->gradient_combo->blockSignals(false); m_gradientWidget->slotGradientChanged(); m_legendWidget->updateContent(); } void Kalzium::slotSwitchtoLookScheme(int which) { qDebug() << "slotSwitchtoLookScheme Kalzium"; KalziumElementProperty::instance()->setScheme(which); m_gradientWidget->scheme_combo->blockSignals(true); look_action_schemes->blockSignals(true); look_action_schemes->setCurrentItem(which); m_gradientWidget->scheme_combo->setCurrentIndex(which); look_action_schemes->blockSignals(false); m_gradientWidget->scheme_combo->blockSignals(false); m_legendWidget->updateContent(); } void Kalzium::showSettingsDialog() { if (KConfigDialog::showDialog(QStringLiteral("settings"))) { return; } //KConfigDialog didn't find an instance of this dialog, so lets create it : KConfigDialog *dialog = new KConfigDialog(this,QStringLiteral("settings"), Prefs::self()); // colors page Ui_setupColors ui_colors; QWidget *w_colors = new QWidget(this); w_colors->setObjectName(QStringLiteral("colors_page")); ui_colors.setupUi(w_colors); dialog->addPage(w_colors, i18n("Schemes"), QStringLiteral("preferences-desktop-color")); // gradients page Ui_setupGradients ui_gradients; QWidget *w_gradients = new QWidget(this); w_gradients->setObjectName(QStringLiteral("gradients_page")); ui_gradients.setupUi(w_gradients); dialog->addPage(w_gradients, i18n("Gradients"), QStringLiteral("preferences-desktop-color")); // units page m_unitsDialog = new UnitSettingsDialog(this); m_unitsDialog->setObjectName(QStringLiteral("units_page")); dialog->addPage(m_unitsDialog, i18n("Units"), QStringLiteral("system-run")); Ui_setupCalc ui_calc; QWidget *w_calc = new QWidget(this); ui_calc.setupUi(w_calc); dialog->addPage(w_calc, i18n("Calculator"), QStringLiteral("accessories-calculator")); connect(dialog, &KConfigDialog::settingsChanged, this, &Kalzium::slotUpdateSettings); connect(dialog, &KConfigDialog::settingsChanged, m_gradientWidget, &GradientWidgetImpl::slotGradientChanged); dialog->show(); } void Kalzium::slotUpdateSettings() { Prefs::setLengthUnit(m_unitsDialog->getLenghtUnitId()); Prefs::setEnergiesUnit(m_unitsDialog->getEnergyUnitId()); Prefs::setTemperatureUnit(m_unitsDialog->getTemperatureUnitId()); Prefs::self()->save(); /*This slot function calls change the color of pse elements immediately after prefs change*/ slotSwitchtoLookGradient(Prefs::colorgradientbox()); slotSwitchtoLookScheme(Prefs::colorschemebox()); } void Kalzium::slotShowExportDialog() { if (!m_exportDialog) { m_exportDialog = new ExportDialog(this); } m_exportDialog->show(); } void Kalzium::setupStatusBar() { QStatusBar *statusBar = new QStatusBar(this); setStatusBar(statusBar); m_elementInfo = new QLabel(QLatin1String("")); m_elementInfo->setAlignment(Qt::AlignRight); statusBar->addWidget(m_elementInfo, 1); statusBar->show(); } void Kalzium::elementHover(int num) { // extractIconicInformationAboutElement(num); Element *e = KalziumDataObject::instance()->element(num); m_elementInfo->setText(i18nc("For example: \"Carbon (6), Mass: 12.0107 u\"", "%1 (%2), Mass: %3 u", e->dataAsString(ChemicalDataObject::name), e->dataAsString(ChemicalDataObject::atomicNumber), e->dataAsString(ChemicalDataObject::mass))); qDebug() << "change item in status bar"; m_detailWidget->setElement(num); } // FIXME What is that function for? Does not seem to do anything useful... yet? void Kalzium::extractIconicInformationAboutElement(int elementNumber) { QString setname = QStringLiteral("school"); QString pathname = QStandardPaths::locate(QStandardPaths::DataLocation, QStringLiteral("data/iconsets/"), QStandardPaths::LocateDirectory); pathname = QFileInfo(pathname).absolutePath(); QString filename = pathname + setname + '/' + "iconinformation.txt"; QFile file(filename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return; } QString infoline; QTextStream in(&file); while (!in.atEnd()) { QString tmp = in.readLine(); if (tmp.startsWith(QString::number(elementNumber))) { infoline = tmp; } } QString realText = QStringLiteral("Moin dies ist ein test!"); //X QString realText = infoline.remove(QRegExp("\\d+ ")); } void Kalzium::openInformationDialog(int number) { if (m_infoDialog) { m_infoDialog->setElement(number); } else { m_infoDialog = new DetailedInfoDlg(number, this); // Remove the selection when this dialog finishes or hides. connect(m_infoDialog, &DetailedInfoDlg::elementChanged, m_periodicTable, &PeriodicTableView::slotSelectOneElement); connect(m_infoDialog, &DetailedInfoDlg::elementChanged, this, &Kalzium::elementHover); } m_infoDialog->setTableType(m_periodicTable->table()); m_infoDialog->show(); } Kalzium::~Kalzium() { delete m_periodicTable; delete m_infoDialog; delete m_TableInfoWidget; delete m_legendWidget; delete m_gradientWidget; delete m_dockWin; delete m_legendDock; delete m_tableDock; } void Kalzium::loadMolecule(const QString &moleculeFile) { #if defined(HAVE_OPENBABEL2) && defined(HAVE_EIGEN) && defined(HAVE_AVOGADRO) MoleculeDialog *d = slotMoleculeviewer(); if (d) { d->loadMolecule(moleculeFile); } #endif } QSize Kalzium::sizeHint() const { return QSize(700, 500); } diff --git a/src/psetable/periodictablescene.cpp b/src/psetable/periodictablescene.cpp index 76cedbda..5c3b76ec 100644 --- a/src/psetable/periodictablescene.cpp +++ b/src/psetable/periodictablescene.cpp @@ -1,141 +1,141 @@ /********************************************************************** PeriodicTableScene - Periodic Table Graphics Scene for Kalzium Copyright (C) 2005-2006 by Pino Toscano, toscano.pino@tiscali.it Copyright (C) 2003-2006 by Carsten Niehaus, cniehaus@kde.org Copyright (C) 2007-2009 by Marcus D. Hanwell, marcus@cryos.org Copyright (C) 2010 by Etienne Rebetez, etienne.rebetez@oberwallis.ch This file is part of the Kalzium molecular editor project. Kalzium is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. Kalzium 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 "periodictablescene.h" #include #include #include #include #include #include #include #include PeriodicTableScene::PeriodicTableScene(QObject *parent) : QGraphicsScene(parent), m_prevHoverElement(-1) { QPalette widgetPalette = palette(); setBackgroundBrush(QBrush(widgetPalette.window())); setItemIndexMethod(QGraphicsScene::NoIndex); m_hoverTimer.setSingleShot(true); connect(&m_hoverTimer, &QTimer::timeout, this, &PeriodicTableScene::slotMouseover); } PeriodicTableScene::~PeriodicTableScene() {} bool PeriodicTableScene::event(QEvent *e) { return QGraphicsScene::event(e); } void PeriodicTableScene::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (event->button() != Qt::LeftButton) { return; } QGraphicsItem *item = QGraphicsScene::itemAt(event->scenePos(), QTransform()); if (item->data(0).toInt() > 0 && item->data(0).toInt() < 119) { m_eventPos = event->scenePos(); } else { emit freeSpaceClick(); } QGraphicsScene::mousePressEvent(event); } void PeriodicTableScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { QGraphicsItem *item = QGraphicsScene::itemAt(m_eventPos, QTransform()); if ((QApplication::mouseButtons() & Qt::LeftButton) && (event->pos() - m_eventPos).manhattanLength() > QApplication::startDragDistance() && item->data(0).toInt() > 0) { Element* pointedElement = KalziumDataObject::instance()->element(item->data(0).toInt()); QDrag *drag = new QDrag(event->widget()); QMimeData *mimeData = new QMimeData; mimeData->setText(pointedElement->dataAsString(ChemicalDataObject::name)); drag->setMimeData(mimeData); QPixmap pix(item->boundingRect().width() + 1, item->boundingRect().height() + 1); pix.fill(palette().color(QPalette::Window)); QPainter painter(&pix); item->paint(&painter, new QStyleOptionGraphicsItem()); drag->setPixmap(pix); - drag->start(Qt::CopyAction | Qt::MoveAction); + drag->exec(Qt::CopyAction | Qt::MoveAction); m_eventPos = QPoint(); } else { m_eventPos = event->scenePos(); if (m_hoverTimer.isActive()) { m_hoverTimer.stop(); } m_hoverTimer.start(100); } QGraphicsScene::mouseMoveEvent(event); } void PeriodicTableScene::slotMouseover() { QGraphicsItem *item = QGraphicsScene::itemAt(m_eventPos, QTransform()); if (item->data(0).toInt() > 0 && item->data(0).toInt() < 119) { int num = item->data(0).toInt(); if ((num > 0) && (num != m_prevHoverElement)) { emit elementHovered(num); } m_prevHoverElement = num; } } void PeriodicTableScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() != Qt::LeftButton) { return; } QGraphicsItem *item = QGraphicsScene::itemAt(event->scenePos(), QTransform()); if (item->data(0).toInt() > 0 && item->data(0).toInt() < 119) { emit(elementChanged(item->data(0).toInt())); } QGraphicsScene::mouseReleaseEvent(event); } diff --git a/src/spectrumwidget.cpp b/src/spectrumwidget.cpp index 95b6b89a..88d4a1ca 100644 --- a/src/spectrumwidget.cpp +++ b/src/spectrumwidget.cpp @@ -1,394 +1,394 @@ /*************************************************************************** * Copyright (C) 2005, 2006 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 "spectrumwidget.h" #include "spectrum.h" #include "kalziumutils.h" #include #include #include #include #include #include #include #include #include #include #if defined(HAVE_IEEEFP_H) #include #endif SpectrumWidget::SpectrumWidget(QWidget *parent) : QWidget(parent) { m_startValue = 0; m_endValue = 0; m_LMBPointCurrent.setX(-1); m_LMBPointPress.setX(-1); m_realHeight = 200; m_gamma = 0.8; m_intensityMax = 255; setType(Prefs::spectrumType()); setMinimumSize(400, 230); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setAttribute(Qt::WA_OpaquePaintEvent, true); setContextMenuPolicy(Qt::PreventContextMenu); } void SpectrumWidget::paintEvent(QPaintEvent * /*e*/) { if (!m_spectrum) { return; } m_pixmap = QPixmap(width(), height()); - m_pixmap.fill(this, width(), height()); + m_pixmap.fill(); QPainter p; p.begin(&m_pixmap); p.fillRect(0, 0, width(), m_realHeight, Qt::black); paintBands(&p); drawTickmarks(&p); if (m_LMBPointPress.x() != -1 && m_LMBPointCurrent.x() != -1) { drawZoomLine(&p); } p.end(); QPainter p2(this); p2.drawPixmap(0, 0, m_pixmap); } void SpectrumWidget::drawZoomLine(QPainter* p) { p->setPen(Qt::white); p->drawLine(m_LMBPointPress.x(), m_LMBPointPress.y(), m_LMBPointCurrent.x(), m_LMBPointPress.y()); p->drawLine(m_LMBPointCurrent.x(), m_LMBPointPress.y() + 10, m_LMBPointCurrent.x(), m_LMBPointPress.y() - 10); p->drawLine(m_LMBPointPress.x(), m_LMBPointPress.y() + 10, m_LMBPointPress.x(), m_LMBPointPress.y() - 10); } void SpectrumWidget::paintBands(QPainter* p) { if (m_type == AbsorptionSpectrum) { for (double va = m_startValue; va <= m_endValue; va += 0.1) { int x = xPos(va); p->setPen(wavelengthToRGB(va)); p->drawLine(x, 0, x, m_realHeight); } p->setPen(Qt::black); } int i = 0; int x = 0; double currentWavelength; foreach (Spectrum::peak *peak, m_spectrum->peaklist()) { currentWavelength = peak->wavelengthToUnit(Prefs::spectrumWavelengthUnit()); if (currentWavelength < m_startValue || currentWavelength > m_endValue) { continue; } x = xPos(currentWavelength); switch (m_type) { case EmissionSpectrum: p->setPen(wavelengthToRGB(currentWavelength)); p->drawLine(x, 0, x, m_realHeight - 1); p->setPen(Qt::black); p->drawLine(x, m_realHeight, x, m_realHeight); break; case AbsorptionSpectrum: p->setPen(Qt::black); p->drawLine(x, 0, x, m_realHeight - 1); break; } ++i; } } QColor SpectrumWidget::wavelengthToRGB(double wavelength) { double blue = 0.0, green = 0.0, red = 0.0, factor = 0.0; // wavelengthTo RGB function works with nanometers. wavelength = KUnitConversion::Value(wavelength,KUnitConversion::UnitId(Prefs::spectrumWavelengthUnit())) .convertTo(KUnitConversion::Nanometer).number(); int wavelength_ = (int)floor(wavelength); if (wavelength_ < 380 || wavelength_ > 780) { return QColor(Qt::white); } else if (wavelength_ >= 380 && wavelength_ < 440) { red = -(wavelength - 440) / (440 - 380); green = 0.0; blue = 1.0; } else if (wavelength_ >= 440 && wavelength_ < 490) { red = 0.0; green = (wavelength - 440) / (490 - 440); blue = 1.0; } else if (wavelength_ >= 490 && wavelength_ < 510) { red = 0.0; green = 1.0; blue = -(wavelength - 510) / (510 - 490); } else if (wavelength_ >= 510 && wavelength_ < 580) { red = (wavelength - 510) / (580 - 510); green = 1.0; blue = 0.0; } else if (wavelength_ >= 580 && wavelength_ < 645) { red = 1.0; green = -(wavelength - 645) / (645 - 580); blue = 0.0; } else if (wavelength_ >= 645 && wavelength_ < 780) { red = 1.0; green = 0.0; blue = 0.0; } if (wavelength_ > 380 && wavelength_ <= 420) { factor = 0.3 + 0.7 * (wavelength - 380) / (420 - 380); } else if (wavelength_ > 420 && wavelength_ <= 701) { factor = 1.0; } else if (wavelength_ > 701 && wavelength_ <= 780) { factor = 0.3 + 0.7 * (780 - wavelength) / (780 - 700); } else { factor = 0.0; } return QColor(Adjust(red, factor), Adjust(green, factor), Adjust(blue, factor)); } int SpectrumWidget::Adjust(double color, double /*factor*/) { if (color == 0.0) { return 0; } else { // return qRound(m_intensityMax * pow(color*factor, m_gamma)); FIXME return m_intensityMax * color; } } void SpectrumWidget::drawTickmarks(QPainter* p) { //the size of the text on the tickmarks const int space = 20; //the distance between the tickmarks in pixel const int d = 10; //the total number of tickmarks to draw (small and long) const int numberOfTickmarks = (int)floor((double)(width() / d)); double pos = 0.0; for (int i = 0; i < numberOfTickmarks; ++i) { if (i % 5 == 0) { //long tickmarks plus text p->drawLine(i * d, m_realHeight, i * d, m_realHeight + 10); if (i % 10 == 0 && i * d > space && i * d < width() - space) { pos = (double)(i * d) / width(); p->fillRect(i * d - space, m_realHeight + 12, 2 * space, 15, Qt::white); p->drawText(i * d - space, m_realHeight + 12, 2 * space, 15, Qt::AlignCenter, QString::number(KalziumUtils::strippedValue(Wavelength(pos)))); } } else { //small tickmarks p->drawLine(i * d, m_realHeight, i * d, m_realHeight + 5); } } } void SpectrumWidget::keyPressEvent(QKeyEvent *e) { switch (e->key()) { case Qt::Key_Plus: slotZoomIn(); break; case Qt::Key_Minus: slotZoomOut(); break; } } void SpectrumWidget::slotZoomOut() { qDebug() << "SpectrumWidget::slotZoomOut() " << m_startValue << ":: " << m_endValue; double diff = m_endValue - m_startValue; double offset = diff * 0.05; m_endValue = m_endValue + offset; m_startValue = m_startValue - offset; //check for invalid values if (m_startValue < 0.0) { m_startValue = 0.0; } if (m_endValue > 10000.0) { // FIXME: Magic numbers... m_endValue = 40000.0; } setBorders(m_startValue, m_endValue); } void SpectrumWidget::setBorders(double left, double right) { qDebug() << "setBorders " << left << ".." << right; m_startValue = left; m_endValue = right; //round the startValue down and the endValue up emit bordersChanged(int(m_startValue + 0.5), int(m_endValue + 0.5)); update(); } void SpectrumWidget::slotZoomIn() { qDebug() << "SpectrumWidget::slotZoomIn() " << m_startValue << ":: " << m_endValue; double diff = m_endValue - m_startValue; double offset = diff * 0.05; m_endValue = m_endValue - offset; m_startValue = m_startValue + offset; setBorders(m_startValue, m_endValue); } void SpectrumWidget::mouseMoveEvent(QMouseEvent *e) { m_LMBPointCurrent = e->pos(); update(); } void SpectrumWidget::mousePressEvent(QMouseEvent *e) { if (e->button() == Qt::LeftButton) { m_LMBPointPress = e->pos(); } if (e->button() == Qt::RightButton) { resetSpectrum(); } findPeakFromMouseposition(Wavelength((double)e->pos().x() / width())); } void SpectrumWidget::findPeakFromMouseposition(double wavelength) { qDebug() << "SpectrumWidget::findPeakFromMouseposition()"; Spectrum::peak *peak = nullptr; //find the difference in percent (1.0 is 100%, 0.1 is 10%) double dif = 0.0; bool foundWavelength = false; //find the highest intensity foreach (Spectrum::peak *currentPeak, m_spectrum->peaklist()) { double currentWavelength = currentPeak->wavelengthToUnit(Prefs::spectrumWavelengthUnit()); double thisdif = currentWavelength / wavelength; if (thisdif < 0.9 || thisdif > 1.1) { continue; } if (thisdif > 1.0) { //convert for example 1.3 to 0.7 thisdif = thisdif - 1; thisdif = 1 - thisdif; } if (thisdif > dif) { dif = thisdif; peak = currentPeak; foundWavelength = true; } } if (foundWavelength) { emit peakSelected(peak); } } void SpectrumWidget::mouseReleaseEvent(QMouseEvent *e) { if (e->button() == Qt::LeftButton) { int left = (int)Wavelength((double)m_LMBPointPress.x() / width()); int right = (int)Wavelength((double)e->pos().x() / width()); if (left == right) { return; } if (left > right) { setBorders(right, left); } else { setBorders(left, right); } } m_LMBPointPress.setX(-1); m_LMBPointCurrent.setX(-1); } void SpectrumWidget::setSpectrum(Spectrum* spec) { m_spectrum = spec; resetSpectrum(); } void SpectrumWidget::resetSpectrum() { //set the minimum and maximum peak to the min/max wavelength //plus/minus ten. This makes then always visible double minimumPeak = m_spectrum->minPeak(Prefs::spectrumWavelengthUnit()) - 20.0; double maximumPeak = m_spectrum->maxPeak(Prefs::spectrumWavelengthUnit()) + 20.0; setBorders(minimumPeak, maximumPeak); }