Warning, file /education/khipu/src/mainwindow.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /************************************************************************************* 0002 * Copyright (C) 2010-2012 by Percy Camilo T. Aucahuasi <percy.camilo.ta@gmail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or * 0005 * modify it under the terms of the GNU General Public License * 0006 * as published by the Free Software Foundation; either version 2 * 0007 * of the License, or (at your option) any later version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, * 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0012 * GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License * 0015 * along with this program; if not, write to the Free Software * 0016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 0017 *************************************************************************************/ 0018 0019 #include "mainwindow.h" 0020 0021 //Analitza includes 0022 #include <analitza/expression.h> 0023 #include <analitzagui/plotsview2d.h> 0024 #include <analitzagui/plotsview3d_es.h> 0025 #include <analitzaplot/plotsdictionarymodel.h> 0026 #include <analitzaplot/planecurve.h> 0027 #include <analitzaplot/functiongraph.h> 0028 #include <analitzaplot/plotter3d_es.h> 0029 #include <analitzaplot/plotsmodel.h> 0030 #include <analitzaplot/plotsfactory.h> 0031 0032 //Qt includes 0033 #include <QBuffer> 0034 #include <QDockWidget> 0035 #include <QLayout> 0036 #include <QLineEdit> 0037 #include <QPushButton> 0038 #include <QToolButton> 0039 #include <QDebug> 0040 #include <QFileDialog> 0041 #include <QClipboard> 0042 #include <QSettings> 0043 #include <QJsonDocument> 0044 #include <QApplication> 0045 0046 //KDE includes 0047 #include <KLocalizedString> 0048 #include <KStandardDirs> 0049 #include <KActionCollection> 0050 #include <KStandardAction> 0051 #include <KStatusBar> 0052 #include <KMessageBox> 0053 #include <KIO/NetAccess> 0054 #include <KTemporaryFile> 0055 #include <KToolBar> 0056 #include <KMenuBar> 0057 #include <KConfigGroup> 0058 #include <KIO/CommandLauncherJob> 0059 #include <KIO/ApplicationLauncherJob> 0060 0061 //local includes 0062 #include "spaceitem.h" 0063 #include "spacesmodel.h" 0064 #include "dashboard.h" 0065 #include "plotseditor.h" 0066 #include "datastore.h" 0067 #include "plotsbuilder.h" 0068 #include "spaceinformation.h" 0069 #include "spaceoptions.h" 0070 #include "filter.h" 0071 #include "dictionarycollection.h" 0072 0073 using namespace Analitza; 0074 0075 MainWindow::MainWindow(QWidget *parent) 0076 : KXmlGuiWindow(parent) 0077 { 0078 m_document = new DataStore(this); 0079 0080 m_dashboard = new Dashboard(this); 0081 m_dashboard->setDocument(m_document); 0082 0083 //From Main Dashboard to the activated space UI 0084 connect(m_dashboard, SIGNAL(spaceActivated(int)), SLOT(activateSpace(int))); 0085 0086 connect(m_dashboard, SIGNAL(spaceActivated(int)), m_document , SIGNAL(spaceActivated(int))); 0087 0088 setupDocks(); 0089 setupActions(); 0090 setupGUI(Keys | StatusBar | Save | Create, "khipu.rc"); 0091 0092 m_filter = new Filter(this); 0093 m_filter->setFilterDashboard(m_dashboard); 0094 0095 connect(m_filter, SIGNAL(filterByText(QString)), m_dashboard, SLOT(filterByText(QString))); 0096 connect(m_dashboard, SIGNAL(plotRequested(QModelIndex)), this, SLOT(createPlot(QModelIndex))); 0097 connect(m_dashboard, SIGNAL(showFilter(bool)), m_filter, SLOT(setFilterVisible(bool))); 0098 connect(m_dashboard, SIGNAL(restoreDictionaryData(Analitza::Dimension)), m_dictionaryDock, SLOT(setSpaceDimension(Analitza::Dimension))); 0099 0100 //Main tool bar for Khipu 0101 toolBar("mainToolBar")->addWidget(m_filter); 0102 setCentralWidget(m_dashboard); 0103 activateDashboardUi(); 0104 0105 //Used to update the recent file list 0106 updateRecentFileList(); 0107 } 0108 0109 void MainWindow::closeEvent(QCloseEvent * event) 0110 { 0111 // Do not want to close then just ignore the event 0112 if (!closeClicked()) 0113 event->ignore(); 0114 } 0115 0116 MainWindow::~MainWindow() 0117 { 0118 } 0119 0120 QAction* MainWindow::createAction(const char* name, const QString& text, const QString& iconName, const QKeySequence& shortcut, const QObject* recvr, const char* slot, bool isCheckable, bool checked) 0121 { 0122 auto act = new QAction(this); 0123 act->setText(text); 0124 act->setIcon(QIcon::fromTheme(iconName)); 0125 act->setShortcut(shortcut); 0126 act->setCheckable(isCheckable); 0127 0128 if (isCheckable) 0129 { 0130 act->setChecked(checked); 0131 QObject::connect(act, SIGNAL(toggled(bool)), recvr, slot); 0132 } else 0133 QObject::connect(act, SIGNAL(triggered()), recvr, slot); 0134 0135 actionCollection()->addAction(name, act); 0136 return act; 0137 } 0138 0139 void MainWindow::setupDocks() 0140 { 0141 PlotsBuilder *plotsBuilder = new PlotsBuilder(this); 0142 m_plotsBuilderDock = new QDockWidget(i18n("&Shortcuts"), this); 0143 m_plotsBuilderDock->setWidget(plotsBuilder); // plotsbuilder debe ser miembro 0144 m_plotsBuilderDock->setObjectName("dsfs"); 0145 m_plotsBuilderDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); 0146 m_plotsBuilderDock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable); 0147 m_plotsBuilderDock->hide(); 0148 0149 //Connecting the buttons to create a specific plot 0150 plotsBuilder->mapConnection(PlotsBuilder::CartesianGraphCurve, this, SLOT(buildCartesianGraphCurve())); 0151 plotsBuilder->mapConnection(PlotsBuilder::CartesianImplicitCurve, this, SLOT(buildCartesianImplicitCurve())); 0152 plotsBuilder->mapConnection(PlotsBuilder::CartesianParametricCurve2D, this, SLOT(buildCartesianParametricCurve2D())); 0153 plotsBuilder->mapConnection(PlotsBuilder::PolarGraphCurve, this, SLOT(buildPolarGraphCurve())); 0154 plotsBuilder->mapConnection(PlotsBuilder::CartesianParametricCurve3D, this, SLOT(buildCartesianParametricCurve3D())); 0155 plotsBuilder->mapConnection(PlotsBuilder::CartesianGraphSurface, this, SLOT(buildCartesianGraphSurface())); 0156 plotsBuilder->mapConnection(PlotsBuilder::CartesianImplicitSurface, this, SLOT(buildCartesianImplicitSurface())); 0157 plotsBuilder->mapConnection(PlotsBuilder::CartesianParametricSurface, this, SLOT(buildCartesianParametricSurface())); 0158 plotsBuilder->mapConnection(PlotsBuilder::CylindricalGraphSurface, this, SLOT(buildCylindricalGraphSurface())); 0159 plotsBuilder->mapConnection(PlotsBuilder::SphericalGraphSurface, this, SLOT(buildSphericalGraphSurface())); 0160 0161 //Plot-Editing dock 0162 m_spacePlotsDock = new PlotsEditor(this); 0163 m_spacePlotsDock->setDocument(m_document); 0164 m_spacePlotsDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); 0165 m_spacePlotsDock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable); 0166 0167 connect(m_spacePlotsDock, SIGNAL(goHome()), SLOT(goHome())); 0168 connect(m_spacePlotsDock, SIGNAL(sendStatus(QString, int)), statusBar(), SLOT(showMessage(QString, int))); 0169 connect(m_spacePlotsDock, SIGNAL(updateGridcolor(QColor)), m_dashboard, SLOT(setGridColor(QColor))); 0170 connect(m_dashboard, SIGNAL(spaceActivated(int)), m_spacePlotsDock, SLOT(setCurrentSpace(int))); 0171 connect(m_spacePlotsDock, SIGNAL(mapDataChanged()), this, SLOT(autoSaveFile())); 0172 connect(m_document, SIGNAL(mapDataChanged()), this, SLOT(autoSaveFile())); 0173 0174 //Space information dock 0175 m_spaceInfoDock = new SpaceInformation(this); 0176 m_spaceOptionsDock = new SpaceOptions(this); 0177 0178 //Plot-Dictionary Dock 0179 m_dictionaryDock = new DictionaryCollection(this); 0180 m_dictionaryDock->setDashboardWidget(m_dashboard); 0181 m_dictionaryDock->setDocument(m_document); 0182 m_dictionaryDock->setDictionaryDataMap(); 0183 m_dictionaryDock->setDefaultDictionaries(); 0184 0185 connect(this, SIGNAL(Spaceinserted(Analitza::Dimension)), m_dictionaryDock, SLOT(setSpaceDimension(Analitza::Dimension))); 0186 connect(m_dictionaryDock, SIGNAL(mapDataChanged()), this, SLOT(autoSaveFile())); 0187 connect(m_document, SIGNAL(gridStyleChanged(int)), m_spaceOptionsDock, SLOT(setGridStyleIndex(int))); 0188 0189 //Signal/slots for 2d Space 0190 connect(m_spaceOptionsDock, SIGNAL(updateGridStyle(int)), m_dashboard, SLOT(setGridStyle(int))); 0191 connect(m_spaceOptionsDock, SIGNAL(updateGridColor(QColor)), m_dashboard, SLOT(setPlotsViewGridColor(QColor))); 0192 connect(m_spaceOptionsDock, SIGNAL(setXAxisLabel(QString)), m_dashboard->view2d(), SLOT(setXAxisLabel(QString))); 0193 connect(m_spaceOptionsDock, SIGNAL(setYAxisLabel(QString)), m_dashboard->view2d(), SLOT(setYAxisLabel(QString))); 0194 connect(m_spaceOptionsDock, SIGNAL(ticksFormatChanged(Analitza::TicksFormat)), m_dashboard->view2d(), SLOT(setTicksFormat(Analitza::TicksFormat))); 0195 connect(m_spaceOptionsDock, SIGNAL(ticksShown(QFlags<Qt::Orientation>)), m_dashboard->view2d(), SLOT(setTicksShown(QFlags<Qt::Orientation>))); 0196 connect(m_spaceOptionsDock, SIGNAL(axesShown(QFlags<Qt::Orientation>)), m_dashboard->view2d(), SLOT(setAxesShown(QFlags<Qt::Orientation>))); 0197 0198 //Signal/slots for 3d Space 0199 // connect(m_spaceOptionsDock, SIGNAL(axisIsDrawn(bool)), m_dashboard->view3d(), SLOT(setAxisIsDrawn(bool))); 0200 // connect(m_spaceOptionsDock, SIGNAL(gridIsDrawn(bool)), m_dashboard->view3d(), SLOT(setGridIsDrawn(bool))); 0201 // connect(m_spaceOptionsDock, SIGNAL(sceneResized(int)), m_dashboard->view3d(), SLOT(resizeScene(int))); 0202 0203 addDockWidget(Qt::LeftDockWidgetArea, m_plotsBuilderDock); 0204 addDockWidget(Qt::LeftDockWidgetArea, m_spacePlotsDock); 0205 addDockWidget(Qt::LeftDockWidgetArea, m_spaceOptionsDock); 0206 addDockWidget(Qt::LeftDockWidgetArea, m_spaceInfoDock); 0207 addDockWidget(Qt::LeftDockWidgetArea, m_dictionaryDock); 0208 0209 tabifyDockWidget(m_plotsBuilderDock, m_spacePlotsDock); 0210 tabifyDockWidget(m_spacePlotsDock, m_spaceOptionsDock); 0211 tabifyDockWidget(m_spaceOptionsDock, m_spaceInfoDock); 0212 tabifyDockWidget(m_spaceInfoDock, m_dictionaryDock); 0213 } 0214 0215 void MainWindow::setupActions() 0216 { 0217 //file 0218 KStandardAction::openNew(this, SLOT(newFile()), actionCollection()); 0219 KStandardAction::open(this, SLOT(openFileClicked()), actionCollection()); 0220 m_openrecent=KStandardAction::openRecent(this, SLOT(openRecentClicked(const QUrl& )), actionCollection()); 0221 connect(m_openrecent, SIGNAL(recentListCleared()), this, SLOT(clearRecentFileList())); 0222 0223 KStandardAction::save(this, SLOT(saveClicked()), actionCollection()); 0224 KStandardAction::saveAs(this, SLOT(saveAsClicked()), actionCollection()); 0225 KStandardAction::quit(this, SLOT(close()), actionCollection()); 0226 createAction("save_plotImage", i18n("&Save Plot as PNG"), QString(), Qt::CTRL + Qt::Key_P, this, SLOT(savePlot())); 0227 0228 //edit - dashboard 0229 createAction("add_space2d", i18n("Add Space &2D"), "add-space2d", Qt::CTRL + Qt::Key_2, this, SLOT(addSpace2D())); 0230 createAction("add_space3d", i18n("Add Space &3D"), "add-space3d", Qt::CTRL + Qt::Key_3, this, SLOT(addSpace3D())); 0231 0232 //view - dashboard 0233 m_plotsBuilderDock->toggleViewAction()->setIcon(QIcon::fromTheme("formula")); 0234 m_plotsBuilderDock->toggleViewAction()->setShortcut(Qt::Key_S); 0235 m_plotsBuilderDock->toggleViewAction()->setToolTip(i18n("Create a plot in a new space")); 0236 actionCollection()->addAction("show_plotsbuilder", m_plotsBuilderDock->toggleViewAction()); 0237 0238 createAction("show_plotsdictionary", i18n("Plot &Dictionaries"), "functionhelp", Qt::CTRL + Qt::Key_D, this, 0239 SLOT(setVisibleDictionary())); 0240 0241 //view - space 0242 // createAction("show_plots_editor", i18n("S&how Space Plots"), "address-book-new", Qt::CTRL + Qt::Key_W, this, SLOT(fooSlot()), true); 0243 m_spacePlotsDock->toggleViewAction()->setIcon(QIcon::fromTheme("editplots")); 0244 m_spacePlotsDock->toggleViewAction()->setShortcut(Qt::CTRL + Qt::Key_A); 0245 actionCollection()->addAction("show_plots_editor", m_spacePlotsDock->toggleViewAction()); 0246 0247 // createAction("show_space_info", i18n("&Show Space Information"), "document-properties", Qt::CTRL + Qt::Key_W, this, SLOT(fooSlot()), true); 0248 m_spaceInfoDock->toggleViewAction()->setIcon(QIcon::fromTheme("dialog-information")); 0249 m_spaceInfoDock->toggleViewAction()->setShortcut(Qt::CTRL + Qt::Key_I); 0250 actionCollection()->addAction("show_space_info", m_spaceInfoDock->toggleViewAction()); 0251 0252 // createAction("show_plotter_options", i18n("&Show Space Options"), "configure", Qt::CTRL + Qt::Key_W, this, SLOT(fooSlot()), true); 0253 m_spaceOptionsDock->toggleViewAction()->setIcon(QIcon::fromTheme("diagram-options")); 0254 m_spaceOptionsDock->toggleViewAction()->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_O); 0255 actionCollection()->addAction("show_plotter_options", m_spaceOptionsDock->toggleViewAction()); 0256 0257 m_dictionaryDock->toggleViewAction()->setIcon(QIcon::fromTheme("list-add")); 0258 m_dictionaryDock->toggleViewAction()->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_D); 0259 actionCollection()->addAction("show_dictionary_collection", m_dictionaryDock->toggleViewAction()); 0260 0261 //go 0262 QAction *firstPageAct = KStandardAction::firstPage(this, SLOT(firstPageActClicked()), actionCollection()); 0263 firstPageAct->setText(i18n("&Go First Space")); 0264 firstPageAct->setIcon(QIcon::fromTheme("go-first-view")); 0265 firstPageAct->setEnabled(true); 0266 0267 m_priorAct = KStandardAction::prior(this, SLOT(priorActClicked()), actionCollection()); 0268 m_priorAct->setText(i18n("&Go Previous Space")); 0269 m_priorAct->setIcon(QIcon::fromTheme("go-previous-view")); 0270 m_priorAct->setEnabled(true); 0271 0272 m_nextAct = KStandardAction::next(this, SLOT(nextActClicked()), actionCollection()); 0273 m_nextAct->setText(i18n("&Go Next Space")); 0274 m_nextAct->setIcon(QIcon::fromTheme("go-next-view")); 0275 m_nextAct->setEnabled(true); 0276 0277 QAction *lastPageAct = KStandardAction::lastPage(this, SLOT(lastPageActClicked()), actionCollection()); 0278 lastPageAct->setText(i18n("&Go Last Space")); 0279 lastPageAct->setIcon(QIcon::fromTheme("go-last-view")); 0280 lastPageAct->setEnabled(true); 0281 0282 KStandardAction::home(this, SLOT(goHome()), actionCollection()); 0283 //tools dashboard 0284 createAction("delete_currentspace", i18n("&Remove Current Space"), "list-remove", Qt::CTRL + Qt::Key_W, this, SLOT(removeCurrentSpace()))->setVisible(false);; 0285 //tools space 0286 createAction("copy_snapshot", i18n("&Take Snapshot"), "take-snapshot", Qt::CTRL + Qt::SHIFT + Qt::Key_C, this, SLOT(copySnapshot())); 0287 m_getdictionaryAct=createAction("get_dictionary", i18n("&Get Plot-Dictionary files"), "get-hot-new-stuff", Qt::CTRL + Qt::SHIFT + Qt::Key_G, m_dashboard, SLOT(getDictionaryClicked())); 0288 m_importdictionaryAct=createAction("import_dictionary", i18n("&Import Plot-Dictionary file"), "document-import", Qt::CTRL + Qt::SHIFT + Qt::Key_I, m_dashboard, SLOT(importDictionaryClicked())); 0289 0290 // createAction("export_snapshot", i18n("&Export Space Snapshot"), "view-preview", Qt::CTRL + Qt::Key_W, this, SLOT(fooSlot())); 0291 //settings 0292 KStandardAction::showMenubar(this, SLOT(setMenuBarVisibility(bool)), actionCollection()); 0293 KStandardAction::fullScreen(this, SLOT(fullScreenView(bool)), this , actionCollection()); 0294 } 0295 0296 //Saving a space title 0297 void MainWindow::setCurrentSpaceTitle(const QString& str) 0298 { 0299 m_document->spacesModel()->space(m_document->currentSpace())->setName(str); 0300 } 0301 0302 //Saving a space description 0303 void MainWindow::setCurrentSpaceDesc(const QString& desc) 0304 { 0305 m_document->spacesModel()->space(m_document->currentSpace())->setDescription(desc); 0306 } 0307 0308 void MainWindow::fullScreenView (bool isFull) 0309 { 0310 if (isFull) { 0311 showFullScreen(); 0312 statusBar()->hide(); 0313 m_spaceOptionsDock->hide(); 0314 m_spaceInfoDock->hide(); 0315 m_spacePlotsDock->hide(); 0316 m_plotsBuilderDock->hide(); 0317 m_dictionaryDock->hide(); 0318 } else { 0319 showNormal(); 0320 statusBar()->show(); 0321 } 0322 toolBar("mainToolBar")->setVisible(!isFull); 0323 } 0324 0325 void MainWindow::firstPageActClicked() 0326 { 0327 m_getdictionaryAct->setVisible(false); 0328 m_importdictionaryAct->setVisible(false); 0329 0330 int currentSpaceRow=m_document->currentSpace(); 0331 0332 if (m_document->spacesModel()->rowCount()==0) { //For empty space model 0333 statusBar()->showMessage(i18n("There is not any space available to show!"), MessageDuration); 0334 } else if (currentSpaceRow==0) { //Already on the first space 0335 QModelIndex firstInd=m_document->spacesModel()->index(0); 0336 m_dashboard->setCurrentSpace(firstInd); 0337 statusBar()->showMessage(i18n("Currently you are on the first space!"), MessageDuration); 0338 } else if (m_document->spacesModel()->rowCount()>0) { 0339 QModelIndex firstInd=m_document->spacesModel()->index(0); 0340 m_dashboard->setCurrentSpace(firstInd); 0341 } 0342 } 0343 0344 void MainWindow::priorActClicked() 0345 { 0346 int currentSpaceRow=m_document->currentSpace(); 0347 if (currentSpaceRow==0) { 0348 statusBar()->showMessage(i18n("You are already on the first space!"), MessageDuration); 0349 } else if (currentSpaceRow>0) { 0350 QModelIndex prevInd=m_document->spacesModel()->index(currentSpaceRow-1); 0351 m_dashboard->setCurrentSpace(prevInd); 0352 } 0353 } 0354 0355 void MainWindow::nextActClicked() 0356 { 0357 int currentSpaceRow=m_document->currentSpace(); 0358 int size=m_document->spacesModel()->rowCount(); 0359 if (currentSpaceRow==size-1) { 0360 statusBar()->showMessage(i18n("You are already on the last space!"), MessageDuration); 0361 } else if (currentSpaceRow<size-1) { 0362 QModelIndex nextInd=m_document->spacesModel()->index(currentSpaceRow+1); 0363 m_dashboard->setCurrentSpace(nextInd); 0364 } 0365 } 0366 0367 void MainWindow::lastPageActClicked() 0368 { 0369 m_getdictionaryAct->setVisible(false); 0370 m_importdictionaryAct->setVisible(false); 0371 0372 int currentSpaceRow=m_document->currentSpace(); 0373 int size=m_document->spacesModel()->rowCount(); 0374 0375 if (m_document->spacesModel()->rowCount()==0) { //For empty space model 0376 statusBar()->showMessage(i18n("There is not any space available to show!"), MessageDuration); 0377 } else if (currentSpaceRow==size-1) { //Already on the last space 0378 QModelIndex lastInd=m_document->spacesModel()->index(size-1); 0379 m_dashboard->setCurrentSpace(lastInd); 0380 statusBar()->showMessage(i18n("Currently you are on the last space!"), MessageDuration); 0381 } else if (m_document->spacesModel()->rowCount() >0) { 0382 int size=m_document->spacesModel()->rowCount(); 0383 QModelIndex lastInd=m_document->spacesModel()->index(size-1); 0384 m_dashboard->setCurrentSpace(lastInd); 0385 } 0386 } 0387 0388 void MainWindow::clearRecentFileList() 0389 { 0390 KConfig config; 0391 KConfigGroup recentFiles(&config, "file_Recent"); 0392 recentFiles.deleteEntry("recentFileList"); 0393 } 0394 0395 void MainWindow::setMenuBarVisibility(bool isShow) 0396 { 0397 if (isShow) { 0398 menuBar()->show(); 0399 } else { 0400 KMessageBox::information(this, i18n("Press Ctrl + M to make menubar visible again"), i18n("Menubar Visibility")); 0401 menuBar()->hide(); 0402 } 0403 } 0404 0405 void MainWindow::autoSaveFile() 0406 { 0407 updateThumbnail(); 0408 0409 //no filename available, need to save it as temporary , filename used here is ".khipu.autosave" 0410 if (m_fileLocation.isEmpty()) { 0411 saveFile(getDefaultAutoSavepath()); 0412 } else { 0413 QString path=QFileInfo(m_fileLocation).dir().path().append("/.").append(QFileInfo(m_fileLocation).baseName().append(".khipu.autosave")); 0414 saveFile(QUrl::fromLocalFile(path)); 0415 } 0416 } 0417 0418 //Update thumbnail whenever the plots are changed. 0419 void MainWindow::updateThumbnail() 0420 { 0421 0422 if (m_document->spacesModel()->rowCount()==0) 0423 return; 0424 0425 SpaceItem *space = m_document->spacesModel()->space(m_document->currentSpace()); 0426 0427 if (space==nullptr) 0428 return; 0429 0430 if (space->dimension()!=Analitza::Dim2D && space->dimension()!=Analitza::Dim3D) 0431 return; 0432 0433 const QPixmap thumbnail = m_dashboard->thumbnail(space->dimension()).scaled(QSize(PreviewWidth, PreviewHeight), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); 0434 space->setThumbnail(thumbnail); 0435 } 0436 0437 void MainWindow::checkforAutoSavedFile() 0438 { 0439 openFile(getDefaultAutoSavepath()); 0440 } 0441 0442 void MainWindow::newFile() 0443 { 0444 // if there are not any plots added (i.e. file is completely clean) 0445 if (m_document->plotsModel()->rowCount()==0) { 0446 QMessageBox::information(this, i18n("No need to create New Window"), i18n("There are not any plots available. So, you do not need to create a new Plot Window")); 0447 return; 0448 } 0449 0450 // creates a new proccess. 0451 // The commandline arguments is used to create a completely new instance of Khipu(i.e. it does not reload the autosaved file) 0452 auto *job = new KIO::CommandLauncherJob(QStringLiteral("khipu"), {QStringLiteral("--ignoreautosavedfile")}); 0453 job->setDesktopName(QStringLiteral("org.kde.khipu")); 0454 job->start(); 0455 } 0456 0457 void MainWindow::openRecentClicked(const QUrl& name) 0458 { 0459 // no plots are available , can open in the same proccess. 0460 if (m_document->plotsModel()->rowCount()==0) { 0461 openFile(name); 0462 return; 0463 } 0464 auto *job = new KIO::ApplicationLauncherJob(KService::serviceByDesktopName(QStringLiteral("org.kde.khipu"))); 0465 job->setUrls({name}); 0466 job->start(); 0467 } 0468 0469 void MainWindow::setCurrentFile(const QString &fileName) 0470 { 0471 if (fileName.isEmpty()) 0472 return; 0473 0474 KConfig config; 0475 KConfigGroup recentFiles(&config, "file_Recent"); 0476 0477 QStringList files =recentFiles.readPathEntry("recentFileList", QStringList()); 0478 files.removeAll(fileName); 0479 files.prepend(fileName); 0480 0481 while (files.size() > MaxRecentFiles) 0482 files.removeLast(); 0483 0484 recentFiles.deleteEntry("recentFileList"); 0485 recentFiles.writePathEntry("recentFileList", files); 0486 recentFiles.sync(); 0487 updateRecentFileList(); 0488 } 0489 0490 void MainWindow::updateRecentFileList() 0491 { 0492 KConfig config; 0493 KConfigGroup recentFiles(&config, "file_Recent"); 0494 QStringList files = recentFiles.readPathEntry("recentFileList", QStringList()); 0495 int numRecentFiles = qMin(files.size(), (int)MaxRecentFiles); 0496 0497 // Traversing in reverse manner will lead to the correct Recently opened file-list 0498 for (int i = numRecentFiles-1; i >=0 ; i--) { 0499 QString text=files[i]; 0500 m_openrecent->addUrl(QUrl::fromLocalFile(text), QFileInfo(text).fileName()); 0501 } 0502 } 0503 0504 bool MainWindow::openFileClicked() 0505 { 0506 const auto url = QFileDialog::getOpenFileUrl(this, i18n("Open"), {}, 0507 i18n("Khipu Files (*.khipu);;All Files (*)")); 0508 0509 if (url.path().isEmpty() || m_currentFileUrl == url) 0510 return false; 0511 0512 openFile(url); 0513 0514 return true; 0515 } 0516 0517 bool MainWindow::openFile(const QUrl &url) 0518 { 0519 if (url.path().isEmpty()) 0520 return false; 0521 0522 QFile file; 0523 0524 if (!url.isLocalFile()) 0525 { 0526 if (!KIO::NetAccess::exists(url, KIO::NetAccess::SourceSide, this)) 0527 { 0528 KMessageBox::error(this, i18n("The file does not exist.")); 0529 return false; 0530 } 0531 0532 QString tmpfile; 0533 0534 if (!KIO::NetAccess::download(url, tmpfile, this)) 0535 { 0536 KMessageBox::error(this, i18n("An error appeared when opening this file (%1)", KIO::NetAccess::lastErrorString())); 0537 return false; 0538 } 0539 file.setFileName(tmpfile); 0540 } 0541 else 0542 file.setFileName(url.toLocalFile()); 0543 0544 // for the default autosaved file (.khipu.autosave) 0545 if (url == getDefaultAutoSavepath()) 0546 { 0547 // ask for reloading the autosave file 0548 if (!file.exists()) 0549 return false; 0550 int answer=KMessageBox::questionYesNo(this, i18n("Do you want to recover the file you have not saved last time?"), i18n("Autosaved .khipu file")); 0551 0552 if (answer!=KMessageBox::Yes) 0553 { 0554 QFile file(url.toLocalFile()); 0555 if (file.remove()) 0556 return false; 0557 } 0558 } 0559 else 0560 { 0561 QString path=url.toLocalFile(); 0562 0563 // not , current autosave ! 0564 if (!path.contains(".khipu.autosave")) 0565 setCurrentFile(path); 0566 0567 m_fileLocation = path; // this allows user to save the other work in the file which he/she has just opened. 0568 0569 changeTitleBar(path); 0570 0571 //check for available autosave file 0572 QString currentautosavepath=getCurrentAutoSavepath(path); 0573 0574 if (QFile::exists(currentautosavepath)) 0575 { 0576 0577 // ask for reloading the autosave file 0578 int answer=KMessageBox::questionYesNo(this, i18n("There are some unsaved changes in the file %1. Do you want to recover them?", QFileInfo(path).baseName()), i18n("Autosaved .khipu file")); 0579 0580 if (answer==KMessageBox::Yes) 0581 { 0582 // user wants to open the autosave file. 0583 file.setFileName(currentautosavepath); 0584 } 0585 } 0586 } 0587 if (!file.open(QFile::ReadOnly)) 0588 { 0589 KMessageBox::error(this, i18n("Error while reading file, maybe path is not found."), i18n("Error while reading")); 0590 0591 if (file.fileName() != getDefaultAutoSavepath().toLocalFile()) 0592 KMessageBox::error(this, i18n("%1 could not be opened", file.fileName())); 0593 0594 return false; 0595 } 0596 0597 m_parsedSpaceDetails = QJsonDocument::fromJson(file.readAll()).toVariant().toList(); 0598 file.close(); 0599 0600 if (!url.isLocalFile()) 0601 KIO::NetAccess::removeTempFile( file.fileName() ); 0602 0603 // if a wrong file is hit 0604 if (m_parsedSpaceDetails.isEmpty()) 0605 { 0606 KMessageBox::error(this, i18n("Problem in parsing the contents of the file, maybe a wrong khipu file."), i18n("Error while reading")); 0607 0608 return false; 0609 } 0610 0611 m_dashboard->m_openclicked = true; 0612 0613 //NOTE we need to remove all current data before load new data from file 0614 bool reloadviews = false; 0615 0616 if (m_document->spacesModel()->rowCount() > 0) 0617 { 0618 m_document->clearAllData(); 0619 reloadviews = true; 0620 } 0621 0622 foreach (QVariant record, m_parsedSpaceDetails) 0623 { 0624 QVariantMap map = record.toMap(); 0625 0626 QString spacename=map.value("name").toString(); 0627 QString spaceDescription=map.value("description").toString(); 0628 QByteArray image= map.value("image").toByteArray(); 0629 0630 Analitza::Dimension dim=static_cast<Analitza::Dimension> (map.value("dimension").toInt()); 0631 QPixmap thumbnail= toPixmap(image); 0632 0633 m_document->spacesModel()->addSpace(dim, spacename, spaceDescription, thumbnail); 0634 } 0635 0636 //NOTE we need to realod views after load a new file data (see datastore::clearalldata) 0637 if (reloadviews) 0638 { 0639 m_dashboard->setDocument(m_document); 0640 m_spacePlotsDock->setDocument(m_document); 0641 m_dictionaryDock->setDocument(m_document); 0642 } 0643 0644 m_dashboard->goHome(); 0645 activateDashboardUi(); 0646 0647 m_currentFileUrl = url; 0648 0649 return true; 0650 } 0651 0652 QPixmap MainWindow::toPixmap(const QByteArray &bytearray) 0653 { 0654 QByteArray imageArray(QByteArray::fromBase64(bytearray)); 0655 QBuffer imagebuffer(&imageArray); 0656 imagebuffer.open(QIODevice::ReadOnly); 0657 QImage img; 0658 img.loadFromData(imagebuffer.data(), "PNG"); 0659 return QPixmap::fromImage(img); 0660 } 0661 0662 void MainWindow::saveClicked() 0663 { 0664 // Intially when the data is not saved. We would not have the actual file path. 0665 if (m_fileLocation.isEmpty()) 0666 { 0667 QUrl url = QFileDialog::getSaveFileUrl(this, i18n("Save As"), {}, i18n("Khipu Files (*.khipu);;All Files (*)") ); 0668 if (url.isEmpty()) 0669 return; 0670 0671 //overwriting warning 0672 if (QFileInfo::exists(url.toLocalFile())) 0673 { 0674 int answer=KMessageBox::questionYesNo(this, 0675 i18n("The file which you want to save, already exists. Do you want to overwrite this file?"), 0676 i18n("Warning: File already exists")); 0677 if (answer==KMessageBox::No) 0678 return; 0679 } 0680 m_fileLocation =url.toLocalFile(); 0681 } 0682 saveFile(QUrl::fromLocalFile(m_fileLocation)); 0683 } 0684 0685 bool MainWindow::closeClicked() 0686 { 0687 QFile autosaveFile(getDefaultAutoSavepath().toLocalFile()); 0688 0689 const QFileInfo fi(m_fileLocation); 0690 QString path = fi.dir().path().append("/.").append(fi.baseName().append(".khipu.autosave")); 0691 QFile currentautosaveFile(path); 0692 0693 if (autosaveFile.exists() || currentautosaveFile.exists()) { 0694 int answer=KMessageBox::questionYesNoCancel(this, 0695 i18n("The current file contains some unsaved work. Do you want to save it?"), 0696 i18n("Warning: Unsaved changes")); 0697 if (answer==KMessageBox::Yes) { 0698 saveClicked(); 0699 return true; 0700 } else if (answer==KMessageBox::Cancel) { 0701 return false; 0702 } else if (answer==KMessageBox::No) { 0703 // if user selects No , then he/she can restore the work using autosaving feature. But this can be removed ! 0704 return true; 0705 } 0706 } 0707 return true; // just close the application. 0708 } 0709 0710 bool MainWindow::saveAsClicked() 0711 { 0712 const auto path = QFileDialog::getSaveFileUrl( this, i18n("Save As"), {}, i18n("Khipu Files (*.khipu);;All Files (*)")); 0713 0714 if (path.isEmpty()) 0715 return false; 0716 0717 if (saveFile(path)) 0718 { 0719 m_fileLocation = path.toLocalFile(); 0720 0721 return true; 0722 } 0723 0724 return false; 0725 } 0726 0727 bool MainWindow::saveFile(const QUrl &url) 0728 { 0729 QMap<SpaceItem*, Analitza::PlotItem*> map=m_document->currentDataMap(); 0730 0731 // just starting, no plots and no spaces are available, so no need to save 0732 if (map.empty() && m_document->spacesModel()->items().isEmpty()) 0733 { 0734 // no plots are there. so, we dont need autosave file 0735 QFile tempautosaveFile(getDefaultAutoSavepath().toLocalFile()); 0736 tempautosaveFile.remove(); 0737 0738 QString path=QFileInfo(m_fileLocation).dir().path().append("/.").append(QFileInfo(m_fileLocation).baseName().append(".khipu.autosave")); 0739 QFile currentautosaveFile(path); 0740 currentautosaveFile.remove(); 0741 0742 return false; 0743 } 0744 0745 //NOTE We need to read all space items, not just only the mapped ones (see bug: 328252) 0746 QList<SpaceItem*> spaceList=m_document->spacesModel()->items(); 0747 0748 if (spaceList.empty()) 0749 { 0750 KMessageBox::error(this, i18n("Error while reading file, file may be empty"), i18n("Error while reading")); 0751 0752 return false; 0753 } 0754 0755 QVariantList plotspace_list; 0756 0757 foreach(SpaceItem* space, spaceList) { 0758 QString spaceName = space->name(); 0759 QString spaceDescription = space->description(); 0760 QPixmap thumbnail = space->thumbnail(); 0761 int dim = space->dimension(); 0762 0763 QVariantList subplot_list; 0764 subplot_list.clear(); 0765 0766 QVariantMap plotspace; 0767 plotspace.insert("name", spaceName); 0768 plotspace.insert("description", spaceDescription); 0769 plotspace.insert("dimension", dim); 0770 plotspace.insert("image", thumbnailtoByteArray(thumbnail)); 0771 0772 QList<Analitza::PlotItem*> plotList=map.values(space); 0773 0774 foreach(Analitza::PlotItem* plotitem, plotList) { 0775 QString plotName = plotitem->name(); 0776 QString plotExpression = plotitem->expression().toString(); 0777 QColor plotcolor = plotitem->color(); 0778 0779 QVariantMap plot; 0780 plot.insert("name", plotName); 0781 plot.insert("expression", plotExpression); 0782 plot.insert("color", plotcolor); 0783 0784 if (dim==2) { 0785 Analitza::FunctionGraph* functiongraph = static_cast<Analitza::FunctionGraph*>(plotitem); 0786 0787 if (functiongraph->hasIntervals()) 0788 { 0789 QString arg1min = functiongraph->interval(functiongraph->parameters().at(0), false).first.toString(); 0790 QString arg1max = functiongraph->interval(functiongraph->parameters().at(0), false).second.toString(); 0791 0792 plot.insert("arg1min", arg1min); 0793 plot.insert("arg1max", arg1max); 0794 } 0795 } 0796 0797 //writehere 0798 subplot_list << plot; 0799 0800 } 0801 0802 QByteArray subjson = QJsonDocument::fromVariant(subplot_list).toJson(); 0803 plotspace.insert("plots", subjson); 0804 plotspace_list << plotspace; 0805 } 0806 0807 QByteArray json = QJsonDocument::fromVariant(plotspace_list).toJson(); 0808 0809 if (!url.isLocalFile()) 0810 { 0811 KTemporaryFile tmpfile; 0812 0813 if (!tmpfile.open()) 0814 { 0815 KMessageBox::error(this, i18n("Could not open %1 for writing", QUrl(tmpfile.fileName()).toLocalFile()), i18n("Error while writing")); 0816 0817 return false; 0818 } 0819 0820 QTextStream out(&tmpfile); 0821 out << json; 0822 out.flush(); 0823 0824 if (!KIO::NetAccess::upload(tmpfile.fileName(), url, this)) 0825 { 0826 KMessageBox::error(this, i18n("Could not open %1 for writing %2", url.toDisplayString(), KIO::NetAccess::lastErrorString()), i18n("Error while writing")); 0827 0828 return false; 0829 } 0830 } 0831 else 0832 { 0833 if (!url.isLocalFile()) 0834 { 0835 KMessageBox::error(this, i18n("Error while saving file. Maybe path is not found"), i18n("Error while saving")); 0836 0837 return false; 0838 } 0839 0840 QFile file(url.toLocalFile()); 0841 0842 // saved action clicked by the user , this is not the autosave case 0843 QString currentautosavepath = getCurrentAutoSavepath(m_fileLocation); 0844 0845 if (url != getDefaultAutoSavepath() && url.toLocalFile()!=currentautosavepath) 0846 { 0847 if (!file.open(QFile::WriteOnly | QFile::Text)) 0848 return false; 0849 0850 // remove the auto save file (can be improved later) -> better to use function (TODO) 0851 QFile tempautosaveFile(getDefaultAutoSavepath().toLocalFile()); 0852 tempautosaveFile.remove(); 0853 QFile currentautosaveFile(currentautosavepath); 0854 currentautosaveFile.remove(); 0855 0856 setCurrentFile(url.toLocalFile()); 0857 statusBar()->showMessage(i18n("File %1 [%2] is saved successfully", 0858 QFileInfo(url.toLocalFile()).fileName(), url.toLocalFile()), MessageDuration); 0859 changeTitleBar(url.toLocalFile()); 0860 } 0861 else // autosave case 0862 { 0863 if (!file.open(QFile::WriteOnly | QFile::Text)) 0864 return false; 0865 } 0866 0867 QTextStream out(&file); 0868 out << json; 0869 file.close(); 0870 } 0871 0872 m_currentFileUrl = url; 0873 0874 return true; 0875 } 0876 0877 void MainWindow::changeTitleBar(const QString& path) 0878 { 0879 window()->setWindowTitle(QFileInfo(path).fileName().append(" - Khipu")); 0880 } 0881 0882 QString MainWindow::getCurrentAutoSavepath(const QString &path) 0883 { 0884 if (!path.isEmpty()) 0885 return QFileInfo(path).dir().path().append("/.").append(QFileInfo(path).baseName().append(".autosave")); 0886 0887 return QString(); 0888 } 0889 0890 QUrl MainWindow::getDefaultAutoSavepath() const 0891 { 0892 return QUrl::fromLocalFile(QDir::homePath().append("/.khipu.autosave")); 0893 } 0894 0895 void MainWindow::savePlot() 0896 { 0897 if (m_document->currentSpace()==-1) 0898 return; 0899 Dimension dim = m_document->spacesModel()->space(m_document->currentSpace())->dimension(); 0900 m_dashboard->exportSpaceSnapshot(dim); 0901 } 0902 0903 void MainWindow::activateSpace(int spaceidx) 0904 { 0905 activateSpaceUi(); 0906 0907 m_spacePlotsDock->reset(true); 0908 0909 SpaceItem *space = m_document->spacesModel()->space(spaceidx); 0910 m_spaceInfoDock->setInformation(space->name(), space->description()); 0911 0912 m_spaceOptionsDock->setDimension(space->dimension()); 0913 } 0914 0915 void MainWindow::activateDashboardUi() 0916 { 0917 //menubar 0918 //edit 0919 action("add_space2d")->setVisible(true); 0920 action("add_space3d")->setVisible(true); 0921 0922 if (m_document->spacesModel()->rowCount()>0) 0923 action("delete_currentspace")->setVisible(true); 0924 0925 //view 0926 action("show_plotsbuilder")->setVisible(true); 0927 action("show_plotsdictionary")->setVisible(true); 0928 action("show_plots_editor")->setVisible(false); 0929 action("show_space_info")->setVisible(false); 0930 action("show_plotter_options")->setVisible(false); 0931 action("show_dictionary_collection")->setVisible(false); 0932 0933 //go 0934 action("go_home")->setVisible(false); 0935 //tools 0936 action("copy_snapshot")->setVisible(false); 0937 action("save_plotImage")->setVisible(false); 0938 0939 //docks 0940 // primero oculto los widgets sino el size de los que voy a ocultar interfieren y la mainwnd se muestra muy grande 0941 m_spacePlotsDock->hide(); 0942 m_spaceInfoDock->hide(); 0943 m_spaceOptionsDock->hide(); 0944 m_plotsBuilderDock->hide(); 0945 m_dictionaryDock->hide(); 0946 m_priorAct->setVisible(false); 0947 m_nextAct->setVisible(false); 0948 //actions should be invisible 0949 m_getdictionaryAct->setVisible(false); 0950 m_importdictionaryAct->setVisible(false); 0951 } 0952 0953 void MainWindow::activateSpaceUi() 0954 { 0955 m_dashboard->setCurrentIndex(1); 0956 0957 //menu 0958 0959 //tools 0960 m_filter->setFilterVisible(false); 0961 0962 //edit 0963 action("add_space2d")->setVisible(false); 0964 action("add_space3d")->setVisible(false); 0965 action("delete_currentspace")->setVisible(false); 0966 //view 0967 action("show_plotsbuilder")->setVisible(false); 0968 action("show_plotsdictionary")->setVisible(false); 0969 action("show_plots_editor")->setVisible(true); 0970 action("show_space_info")->setVisible(true); 0971 action("show_plotter_options")->setVisible(true); 0972 action("show_dictionary_collection")->setVisible(true); 0973 0974 //go 0975 action("go_home")->setVisible(true); 0976 //tools 0977 action("copy_snapshot")->setVisible(true); 0978 action("save_plotImage")->setVisible(true); 0979 0980 //docks 0981 //lo mismo ... primero hides luego show 0982 m_plotsBuilderDock->hide(); 0983 m_spacePlotsDock->show(); 0984 m_spaceInfoDock->show(); 0985 m_spaceOptionsDock->show(); 0986 m_dictionaryDock->show(); 0987 m_priorAct->setVisible(true); 0988 m_nextAct->setVisible(true); 0989 } 0990 0991 void MainWindow::copySnapshot() 0992 { 0993 SpaceItem *space = m_document->spacesModel()->space(m_document->currentSpace()); 0994 switch (space->dimension()) 0995 { 0996 case Analitza::Dim2D: 0997 m_dashboard->copySpace2DSnapshotToClipboard(); 0998 break; 0999 case Analitza::Dim3D: 1000 m_dashboard->copySpace3DSnapshotToClipboard(); 1001 break; 1002 default: 1003 break; 1004 } 1005 statusBar()->showMessage(i18n("The diagram was copied to clipboard"), MessageDuration); 1006 } 1007 1008 void MainWindow::setVisibleDictionary() 1009 { 1010 1011 //menu 1012 //edit 1013 action("add_space2d")->setVisible(false); 1014 action("add_space3d")->setVisible(false); 1015 action("delete_currentspace")->setVisible(false); 1016 //view 1017 action("show_plotsbuilder")->setVisible(false); 1018 action("show_plots_editor")->setVisible(false); 1019 action("show_space_info")->setVisible(false); 1020 action("show_plotter_options")->setVisible(false); 1021 action("show_dictionary_collection")->setVisible(false); 1022 //go 1023 action("show_plotsdictionary")->setVisible(false); 1024 action("go_home")->setVisible(true); 1025 1026 //tools 1027 action("copy_snapshot")->setVisible(false); 1028 action("save_plotImage")->setVisible(false); 1029 1030 //docks on the dashboard 1031 m_plotsBuilderDock->hide(); 1032 m_spacePlotsDock->hide(); 1033 m_spaceInfoDock->hide(); 1034 m_spaceOptionsDock->hide(); 1035 m_dictionaryDock->hide(); 1036 m_dashboard->showDictionary(); 1037 m_priorAct->setVisible(false); 1038 m_nextAct->setVisible(false); 1039 1040 //actions should be visible 1041 m_getdictionaryAct->setVisible(true); 1042 m_importdictionaryAct->setVisible(true); 1043 m_dashboard->activateDictionaryData(); 1044 } 1045 1046 void MainWindow::addSpace2D() 1047 { 1048 activateSpaceUi(); 1049 1050 m_dashboard->showPlotsView2D(); 1051 int rows=m_document->spacesModel()->rowCount(); 1052 m_document->spacesModel()->addSpace(Analitza::Dim2D, i18n("Untitled %1", rows+1)); 1053 1054 emit Spaceinserted(Dim2D); 1055 } 1056 1057 void MainWindow::addSpace3D() 1058 { 1059 activateSpaceUi(); 1060 1061 m_dashboard->showPlotsView3D(); 1062 int rows=m_document->spacesModel()->rowCount(); 1063 m_document->spacesModel()->addSpace(Analitza::Dim3D, i18n("Untitled %1", rows+1)); 1064 1065 emit Spaceinserted(Dim3D); 1066 } 1067 1068 void MainWindow::removeCurrentSpace() 1069 { 1070 m_document->removeCurrentSpace(); 1071 1072 if (m_document->spacesModel()->rowCount() == 0) 1073 action("delete_currentspace")->setVisible(false); 1074 } 1075 1076 // Allows the user to go Home which will save the current space and take the user to the main view 1077 void MainWindow::goHome() 1078 { 1079 if (m_dashboard->currentIndex() != 0) 1080 { 1081 //Current Space from where go home is pressed 1082 SpaceItem *space = m_document->spacesModel()->space(m_document->currentSpace()); 1083 1084 space->stamp(); // marcamos la fecha y hora de ingreso al space 1085 space->setName(m_spaceInfoDock->title()); 1086 space->setDescription(m_spaceInfoDock->description()); 1087 1088 // Thumbnail of the current space which is used to identify the space 1089 const QPixmap thumbnail = m_dashboard->thumbnail(space->dimension()).scaled(QSize(PreviewWidth, PreviewHeight), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); 1090 space->setThumbnail(thumbnail); 1091 } 1092 m_dashboard->goHome(); 1093 activateDashboardUi(); 1094 } 1095 1096 QByteArray MainWindow::thumbnailtoByteArray(const QPixmap &thumbnail) 1097 { 1098 QImage image = thumbnail.toImage(); 1099 QByteArray imageArray; 1100 QBuffer buffer(&imageArray); 1101 buffer.open(QIODevice::WriteOnly); 1102 image.save(&buffer, "PNG"); 1103 QByteArray encodedImage=buffer.data().toBase64(); 1104 return encodedImage; 1105 } 1106 1107 void MainWindow::buildCartesianGraphCurve() 1108 { 1109 addSpace2D(); 1110 m_spacePlotsDock->buildCartesianGraphCurve(true); 1111 } 1112 1113 void MainWindow::buildCartesianImplicitCurve() 1114 { 1115 addSpace2D(); 1116 m_spacePlotsDock->buildCartesianImplicitCurve(true); 1117 } 1118 1119 void MainWindow::buildCartesianParametricCurve2D() 1120 { 1121 addSpace2D(); 1122 m_spacePlotsDock->buildCartesianParametricCurve2D(true); 1123 } 1124 1125 void MainWindow::buildPolarGraphCurve() 1126 { 1127 addSpace2D(); 1128 m_spacePlotsDock->buildPolarGraphCurve(true); 1129 } 1130 1131 void MainWindow::buildCartesianParametricCurve3D() 1132 { 1133 addSpace3D(); 1134 m_spacePlotsDock->buildCartesianParametricCurve3D(true); 1135 } 1136 1137 void MainWindow::buildCartesianGraphSurface() 1138 { 1139 addSpace3D(); 1140 m_spacePlotsDock->buildCartesianGraphSurface(true); 1141 } 1142 1143 void MainWindow::buildCartesianImplicitSurface() 1144 { 1145 addSpace3D(); 1146 m_spacePlotsDock->buildCartesianImplicitSurface(true); 1147 } 1148 1149 void MainWindow::buildCartesianParametricSurface() 1150 { 1151 addSpace3D(); 1152 m_spacePlotsDock->buildCartesianParametricSurface(true); 1153 } 1154 1155 void MainWindow::buildCylindricalGraphSurface() 1156 { 1157 addSpace3D(); 1158 m_spacePlotsDock->buildCylindricalGraphSurface(true); 1159 } 1160 1161 void MainWindow::buildSphericalGraphSurface() 1162 { 1163 addSpace3D(); 1164 m_spacePlotsDock->buildSphericalGraphSurface(true); 1165 } 1166 1167 void MainWindow::createPlot(const QModelIndex &ind) 1168 { 1169 if (ind.row() < 0) 1170 return; 1171 1172 //Parsing the data from the qjson file 1173 QVariantMap map = m_parsedSpaceDetails.at(ind.row()).toMap(); // corresponding space entry 1174 1175 Analitza::Dimension dim=static_cast<Analitza::Dimension> (map.value("dimension").toInt()); 1176 QVariantList plotList= QJsonDocument::fromJson(map.value("plots").toByteArray()).toVariant().toList(); 1177 1178 foreach(QVariant plot, plotList) { 1179 1180 QVariantMap plotmap = plot.toMap(); 1181 QString plotname=plotmap.value("name").toString(); 1182 QString ploteqn=plotmap.value("expression").toString(); 1183 QColor plotcolor=plotmap.value("color").toString(); 1184 1185 double arg1min=plotmap.value("arg1min").toDouble(); 1186 double arg1max=plotmap.value("arg1max").toDouble(); 1187 1188 QStringList errors; 1189 1190 PlotBuilder req = PlotsFactory::self()->requestPlot(Analitza::Expression(QString(ploteqn)), dim); 1191 1192 if (req.canDraw()) 1193 { 1194 1195 FunctionGraph *item = nullptr; 1196 item = req.create(plotcolor, plotname); 1197 1198 if (dim==Dim2D) 1199 { 1200 //Used to deal with infinite intervals. 1201 if (arg1min!=0 || arg1max!=0) 1202 item->setInterval(item->parameters().first(), arg1min, arg1max); 1203 } 1204 1205 m_document->plotsModel()->addPlot(item); 1206 } 1207 else 1208 errors = req.errors(); 1209 } 1210 }