scidavis  2.3.0
About: SciDAVis is a free application for Scientific Data Analysis and Visualization (a fork off of QtiPlot).
  Fossies Dox: scidavis-2.3.0.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

ApplicationWindow.cpp
Go to the documentation of this file.
1 
13 
32 #define HOMEPAGE_URI "http://scidavis.sourceforge.net"
33 #define MANUAL_URI "http://sourceforge.net/projects/scidavis/files/SciDAVis%20Documentation/0.1/"
34 #define FORUM_URI "http://sourceforge.net/forum/?group_id=199120"
35 #define BUGREPORT_URI "http://sourceforge.net/tracker/?group_id=199120&atid=968214"
36 #define DOWNLOAD_URI "http://sourceforge.net/projects/scidavis/files/SciDAVis/"
37 
38 #include "globals.h"
39 #include "ApplicationWindow.h"
40 #include "CurvesDialog.h"
41 #include "PlotDialog.h"
42 #include "AxesDialog.h"
43 #include "LineDialog.h"
44 #include "TextDialog.h"
45 #include "ExportDialog.h"
46 #include "ErrDialog.h"
47 #include "Legend.h"
48 #include "ArrowMarker.h"
49 #include "ImageMarker.h"
50 #include "Graph.h"
51 #include "Plot.h"
52 #include "Grid.h"
53 #include "PlotWizard.h"
54 #include "PolynomFitDialog.h"
55 #include "ExpDecayDialog.h"
56 #include "FunctionDialog.h"
57 #include "FitDialog.h"
58 #include "SurfaceDialog.h"
59 #include "Graph3D.h"
60 #include "Plot3DDialog.h"
61 #include "ImageDialog.h"
62 #include "MultiLayer.h"
63 #include "LayerDialog.h"
64 #include "DataSetDialog.h"
65 #include "IntDialog.h"
66 #include "ConfigDialog.h"
67 #ifdef ORIGIN_IMPORT
68 #include "importOPJ.h"
69 #endif
70 #include "AssociationsDialog.h"
71 #include "RenameWindowDialog.h"
72 #include "QwtErrorPlotCurve.h"
73 #include "InterpolationDialog.h"
74 #include "ImportASCIIDialog.h"
75 #include "ImageExportDialog.h"
76 #include "SmoothCurveDialog.h"
77 #include "FilterDialog.h"
78 #include "FFTDialog.h"
79 #include "Note.h"
80 #include "Folder.h"
81 #include "FindDialog.h"
82 #include "ScaleDraw.h"
83 #include "ScriptingLangDialog.h"
84 #include "TableStatistics.h"
85 #include "Fit.h"
86 #include "MultiPeakFit.h"
87 #include "PolynomialFit.h"
88 #include "SigmoidalFit.h"
89 #include "FunctionCurve.h"
90 #include "QwtPieCurve.h"
91 #include "Spectrogram.h"
92 #include "Differentiation.h"
93 #include "SmoothFilter.h"
94 #include "FFTFilter.h"
95 #include "Convolution.h"
96 #include "Correlation.h"
97 #include "CurveRangeDialog.h"
98 #include "ColorButton.h"
99 #include "QwtHistogram.h"
100 #include "OpenProjectDialog.h"
101 #include "IconLoader.h"
102 #include "core/Project.h"
103 #include "core/column/Column.h"
104 #include "lib/XmlStreamReader.h"
105 #include "table/future_Table.h"
106 
107 // TODO: move tool-specific code to an extension manager
108 #include "ScreenPickerTool.h"
109 #include "DataPickerTool.h"
110 #include "TranslateCurveTool.h"
111 #include "MultiPeakFitTool.h"
112 #include "LineProfileTool.h"
113 
114 #include <stdio.h>
115 #include <stdlib.h>
116 
117 #include <QFileDialog>
118 #include <QInputDialog>
119 #include <QProgressDialog>
120 #include <QPrintDialog>
121 #include <QPixmapCache>
122 #include <QMenuBar>
123 #include <QClipboard>
124 #include <QMdiArea>
125 #include <QMdiSubWindow>
126 #include <QTranslator>
127 #include <QSplitter>
128 #include <QSettings>
129 #include <QApplication>
130 #include <QMessageBox>
131 #include <QPrinter>
132 #include <QActionGroup>
133 #include <QAction>
134 #include <QToolBar>
135 #include <QKeySequence>
136 #include <QImageReader>
137 #include <QImageWriter>
138 #include <QDateTime>
139 #include <QShortcut>
140 #include <QDockWidget>
141 #include <QTextStream>
142 #include <QVarLengthArray>
143 #include <QList>
144 #include <QUrl>
145 #include <QDesktopServices>
146 #include <QStatusBar>
147 #include <QToolButton>
148 #include <QSignalMapper>
149 #include <QUndoStack>
150 #include <QtDebug>
151 #include <QDialogButtonBox>
152 #include <QUndoView>
153 #include <QUndoStack>
154 #include <QTemporaryFile>
155 #include <QDebug>
156 #include <QTextCodec>
157 #include <QScrollBar>
158 #include <QMimeData>
159 
160 #include <zlib.h>
161 
162 #include <iostream>
163 #include <memory>
164 using namespace std;
165 
166 #ifdef Q_OS_WIN
167 #include <io.h> // for _commit()
168 #else
169 #include <unistd.h> // for fsync()
170 #endif
171 
172 using namespace Qwt3D;
173 
174 extern "C"
175 {
176 void file_compress(const char *file, const char *mode);
177 }
178 
180  : scripted(ScriptingLangManager::newEnv(this)),
181 // logWindow(new QDockWidget(this)),
182 // explorerWindow(new QDockWidget(this)),
183 // results(new QTextEdit(logWindow)),
184 //#ifdef SCRIPTING_CONSOLE
185 // consoleWindow(new QDockWidget(this)),
186 // console(new QTextEdit(consoleWindow)),
187 //#endif
188 // d_workspace(new QMdiArea(this)),
189 // lv(new FolderListView()),
190 // folders(new FolderListView()),
191 
192 // hiddenWindows(new QList<MyWidget*>()),
193 // outWindows(new QList<MyWidget*>()),
194  lastModified(0),
195  current_folder(new Folder(tr("UNTITLED"))),
196  show_windows_policy(ActiveFolder),
197  appStyle(qApp->style()->objectName()),
198  appFont(QFont()),
199  projectname("untitled"),
200  logInfo(QString()),
201  savingTimerId(0),
202  copiedLayer(false),
203  renamedTables(QStringList()),
204  copiedMarkerType(Graph::None),
205 #ifdef SEARCH_FOR_UPDATES
206  autoSearchUpdatesRequest(false),
207 #endif
208  lastCopiedLayer(0),
209  explorerSplitter(new QSplitter(Qt::Horizontal, &explorerWindow)),
210  actionNextWindow(new QAction(QIcon(QPixmap(":/next.xpm")),
211  tr("&Next","next window"), this)),
212  actionPrevWindow(new QAction(QIcon(QPixmap(":/prev.xpm")),
213  tr("&Previous","previous window"), this))
214 
215 {
216  setAttribute(Qt::WA_DeleteOnClose);
217  QCoreApplication::setAttribute(Qt::AA_DontShowIconsInMenus, false);
218 
219  setWindowTitle(tr("SciDAVis - untitled"));
220 
221  // Icons
223  IconLoader::lumen_ = IconLoader::isLight(palette().color(QPalette::Window));
224 
225  initFonts();
226  QPixmapCache::setCacheLimit(20*QPixmapCache::cacheLimit ());
227 
228  d_project = new Project();
229  connect(d_project, SIGNAL(aspectAdded(const AbstractAspect *, int)),
230  this, SLOT(handleAspectAdded(const AbstractAspect *, int)));
231  connect(d_project, SIGNAL(aspectAboutToBeRemoved(const AbstractAspect *, int)),
232  this, SLOT(handleAspectAboutToBeRemoved(const AbstractAspect *, int)));
233 
234  explorerWindow.setWindowTitle(tr("Project Explorer"));
235  explorerWindow.setObjectName("explorerWindow"); // this is needed for QMainWindow::restoreState()
236  explorerWindow.setMinimumHeight(150);
237  addDockWidget( Qt::BottomDockWidgetArea, &explorerWindow );
238 
239  folders.setObjectName("folders");
240  folders.setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
241  folders.setContextMenuPolicy(Qt::CustomContextMenu);
242 
243  folders.setHeaderLabels(QStringList() << tr("Folder") << QString() );
244  folders.setRootIsDecorated( true );
245  folders.setColumnWidth(1,0); // helps autoScroll
246  folders.hideColumn(1); // helps autoScroll
247 #if QT_VERSION >= 0x050000
248  folders.header()->setSectionsClickable( false );
249  folders.header()->setSectionResizeMode(QHeaderView::ResizeToContents);
250 #else
251  folders.header()->setClickable( false );
252  folders.header()->setResizeMode(QHeaderView::ResizeToContents);
253 #endif
254  folders.header()->hide();
255  folders.setSelectionMode(QTreeWidget::SingleSelection);
256 
257  connect(&folders, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
258  this, SLOT(folderItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
259  connect(&folders, SIGNAL(itemRenamed(QTreeWidgetItem *, int, const QString &)),
260  this, SLOT(renameFolder(QTreeWidgetItem *, int, const QString &)));
261  connect(&folders, SIGNAL(customContextMenuRequested(const QPoint &)),
262  this, SLOT(showFolderPopupMenu(const QPoint &)));
263  connect(&folders, SIGNAL(dragItems(QList<QTreeWidgetItem *>)),
264  this, SLOT(dragFolderItems(QList<QTreeWidgetItem *>)));
265  connect(&folders, SIGNAL(dropItems(QTreeWidgetItem *)),
266  this, SLOT(dropFolderItems(QTreeWidgetItem *)));
267  connect(&folders, SIGNAL(renameItem(QTreeWidgetItem *, int)),
268  this, SLOT(startRenameFolder(QTreeWidgetItem *, int)));
269  connect(&folders, SIGNAL(addFolderItem()), this, SLOT(addFolder()));
270  connect(&folders, SIGNAL(deleteSelection()), this, SLOT(deleteSelectedItems()));
271 
274  folders.setCurrentItem(fli);
275  fli->setExpanded( true );
276 
277  lv.setObjectName("lv");
278  lv.setRootIsDecorated(false);
279  lv.setContextMenuPolicy(Qt::CustomContextMenu);
280  lv.setHeaderLabels(QStringList() << tr("Name") << tr("Type") << tr("View") << tr("Created") << tr("Label"));
281  lv.header()->setStretchLastSection(true);
282  lv.setMinimumHeight(80);
283  lv.setSelectionMode(QTreeWidget::ExtendedSelection);
284 
285  explorerSplitter->addWidget(&folders);
286  explorerSplitter->addWidget(&lv);
287  explorerWindow.setWidget(explorerSplitter);
288  explorerSplitter->setSizes( QList<int>() << 50 << 50);
289  explorerWindow.hide();
290 
291  logWindow.setObjectName("logWindow"); // this is needed for QMainWindow::restoreState()
292  logWindow.setWindowTitle(tr("Results Log"));
293  addDockWidget( Qt::TopDockWidgetArea, &logWindow );
294 
295  results->setReadOnly (true);
296 
297  logWindow.setWidget(results);
298  logWindow.hide();
299 
300 #ifdef SCRIPTING_CONSOLE
301  consoleWindow.setObjectName("consoleWindow"); // this is needed for QMainWindow::restoreState()
302  consoleWindow.setWindowTitle(tr("Scripting Console"));
303  addDockWidget( Qt::TopDockWidgetArea, &consoleWindow );
304  console.setReadOnly(true);
305  consoleWindow.setWidget(&console);
306  consoleWindow.hide();
307 #endif
308 
309  // Needs to be done after initialization of dock windows,
310  // because we now use QDockWidget::toggleViewAction()
311  createActions();
312  initToolBars();
314  initMainMenu();
315 
316  d_workspace.setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
317  d_workspace.setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
318  d_workspace.setActivationOrder(QMdiArea::ActivationHistoryOrder);
319  setCentralWidget(&d_workspace);
320  setAcceptDrops(true);
321 
322  readSettings();
325 
326  actionNextWindow->setShortcut( tr("F5","next window shortcut") );
327  connect(actionNextWindow, SIGNAL(triggered()), &d_workspace, SLOT(activateNextSubWindow()));
328 
329  actionPrevWindow->setShortcut( tr("F6","previous window shortcut") );
330  connect(actionPrevWindow, SIGNAL(triggered()), &d_workspace, SLOT(activatePreviousSubWindow()));
331 
332  connect(this, SIGNAL(modified()),this, SLOT(modifiedProject()));
333  connect(&d_workspace, SIGNAL(subWindowActivated (QMdiSubWindow*)),this, SLOT(windowActivated(QMdiSubWindow*)));
334  connect(&lv, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
335  this, SLOT(folderItemDoubleClicked(QTreeWidgetItem *, int)));
336  connect(&lv, SIGNAL(customContextMenuRequested(const QPoint &)),
337  this, SLOT(showWindowPopupMenu(const QPoint &)));
338  connect(&lv, SIGNAL(dragItems(QList<QTreeWidgetItem *>)),
339  this, SLOT(dragFolderItems(QList<QTreeWidgetItem *>)));
340  connect(&lv, SIGNAL(dropItems(QTreeWidgetItem *)),
341  this, SLOT(dropFolderItems(QTreeWidgetItem *)));
342  connect(&lv, SIGNAL(renameItem(QTreeWidgetItem *, int)),
343  this, SLOT(startRenameFolder(QTreeWidgetItem *, int)));
344  connect(&lv, SIGNAL(addFolderItem()), this, SLOT(addFolder()));
345  connect(&lv, SIGNAL(deleteSelection()), this, SLOT(deleteSelectedItems()));
346  connect(&lv, SIGNAL(itemRenamed(QTreeWidgetItem *, int, const QString &)),
347  this, SLOT(renameWindow(QTreeWidgetItem *, int, const QString &)));
348  connect(scriptEnv, SIGNAL(error(const QString&,const QString&,int)),
349  this, SLOT(scriptError(const QString&,const QString&,int)));
350  connect(scriptEnv, SIGNAL(print(const QString&)), this, SLOT(scriptPrint(const QString&)));
351 
352 #ifdef SEARCH_FOR_UPDATES
353  connect(&http, SIGNAL(finished(QNetworkReply*)), this, SLOT(receivedVersionFile(QNetworkReply*)));
354 #endif
355 
356  // this has to be done after connecting scriptEnv
358 
359  lv.setDragEnabled(true);
360  lv.setAcceptDrops(true);
361  lv.setDefaultDropAction(Qt::MoveAction);
362  folders.setDragEnabled(true);
363  folders.setAcceptDrops(true);
364  folders.setDefaultDropAction(Qt::MoveAction);
365 
366  connect(d_project->undoStack(), SIGNAL(canUndoChanged(bool)), actionUndo, SLOT(setEnabled(bool)));
367  connect(d_project->undoStack(), SIGNAL(canRedoChanged(bool)), actionRedo, SLOT(setEnabled(bool)));
368 }
369 
371 {
372  QString family = appFont.family();
373  int pointSize = appFont.pointSize();
376  plotAxesFont = QFont(family, pointSize, QFont::Bold, false);
377  plotNumbersFont = QFont(family, pointSize );
379  plotTitleFont = QFont(family, pointSize + 2, QFont::Bold,false);
380 
381  plot3DAxesFont = QFont(family, pointSize, QFont::Bold, false );
382  plot3DNumbersFont = QFont(family, pointSize);
383  plot3DTitleFont = QFont(family, pointSize + 2, QFont::Bold,false);
384 }
385 
387 {
388  updateAppFonts();
390 
391  d_workspace.setBackground (workspaceColor);
392 
393  QPalette cg;
394  cg.setColor(QPalette::Base, QColor(panelsColor));
395  qApp->setPalette(cg);
396 
397  cg.setColor(QPalette::Text, QColor(panelsTextColor) );
398  cg.setColor(QPalette::WindowText, QColor(panelsTextColor) );
399  cg.setColor(QPalette::HighlightedText, QColor(panelsTextColor) );
400  lv.setPalette(cg);
401  results->setPalette(cg);
402 
403  cg.setColor(QPalette::Text, QColor(Qt::green) );
404  cg.setColor(QPalette::HighlightedText, QColor(Qt::darkGreen) );
405  cg.setColor(QPalette::Base, QColor(Qt::black) );
406 }
407 
409 {
410  setWindowIcon(QIcon(":/appicon"));
411  QPixmap openIcon, saveIcon;
412 
413  file_tools = new QToolBar( tr( "File" ), this );
414  file_tools->setObjectName("file_tools"); // this is needed for QMainWindow::restoreState()
415  file_tools->setIconSize( QSize(22,22) );
416  addToolBar( Qt::TopToolBarArea, file_tools );
417 
418  file_tools->addAction(actionNewProject);
419 
420  QMenu *menu_new_aspect = new QMenu(this);
421  menu_new_aspect->addAction(actionNewTable);
422  menu_new_aspect->addAction(actionNewMatrix);
423  menu_new_aspect->addAction(actionNewNote);
424  menu_new_aspect->addAction(actionNewGraph);
425  menu_new_aspect->addAction(actionNewFunctionPlot);
426  menu_new_aspect->addAction(actionNewSurfacePlot);
427  QToolButton *btn_new_aspect = new QToolButton(this);
428  btn_new_aspect->setMenu(menu_new_aspect);
429  btn_new_aspect->setPopupMode(QToolButton::InstantPopup);
430  btn_new_aspect->setIcon(QPixmap(":/new_aspect.xpm"));
431  btn_new_aspect->setToolTip(tr("New Aspect"));
432  file_tools->addWidget(btn_new_aspect);
433 
434  file_tools->addAction(actionOpen);
435  file_tools->addAction(actionOpenTemplate);
436  file_tools->addAction(actionLoad);
437  file_tools->addAction(actionSaveProject);
438  file_tools->addAction(actionSaveTemplate);
439 
440  file_tools->addSeparator ();
441 
442  file_tools->addAction(actionPrint);
443  file_tools->addAction(actionExportPDF);
444 
445  file_tools->addSeparator();
446 
447  file_tools->addAction(actionShowExplorer);
448  file_tools->addAction(actionShowLog);
449  file_tools->addAction(locktoolbar);
450 
451  edit_tools = new QToolBar( tr("Edit"), this);
452  edit_tools->setObjectName("edit_tools"); // this is needed for QMainWindow::restoreState()
453  edit_tools->setIconSize( QSize(22,22) );
454  addToolBar( edit_tools );
455 
456  edit_tools->addAction(actionUndo);
457  edit_tools->addAction(actionRedo);
458  edit_tools->addAction(actionCutSelection);
459  edit_tools->addAction(actionCopySelection);
460  edit_tools->addAction(actionPasteSelection);
461  edit_tools->addAction(actionClearSelection);
462 
463  graph_tools = new QToolBar( tr("Graph"), this );
464  graph_tools->setObjectName("graph_tools"); // this is needed for QMainWindow::restoreState()
465  graph_tools->setIconSize( QSize(22,22) );
466  addToolBar( graph_tools );
467 
468  dataTools = new QActionGroup( this );
469  dataTools->setExclusive( true );
470 
471  btnPointer = new QAction(tr("Disable &Tools"), this);
472  btnPointer->setActionGroup(dataTools);
473  btnPointer->setCheckable( true );
474  btnPointer->setIcon(QIcon(QPixmap(":/pointer.xpm")) );
475  btnPointer->setChecked(true);
476  graph_tools->addAction(btnPointer);
477 
478  graph_tools->addSeparator();
479 
480  QMenu *menu_layers = new QMenu(this);
481  QToolButton *btn_layers = new QToolButton(this);
482  btn_layers->setMenu(menu_layers);
483  btn_layers->setPopupMode(QToolButton::InstantPopup);
484  btn_layers->setIcon(QPixmap(":/arrangeLayers.xpm"));
485  btn_layers->setToolTip(tr("Manage layers"));
486  graph_tools->addWidget(btn_layers);
487 
488  menu_layers->addAction(actionAutomaticLayout);
489  menu_layers->addAction(actionAddLayer);
490  menu_layers->addAction(actionDeleteLayer);
491  menu_layers->addAction(actionShowLayerDialog);
492 
493  QMenu *menu_curves = new QMenu(this);
494  QToolButton *btn_curves = new QToolButton(this);
495  btn_curves->setMenu(menu_curves);
496  btn_curves->setPopupMode(QToolButton::InstantPopup);
497  btn_curves->setIcon(QPixmap(":/curves.xpm"));
498  btn_curves->setToolTip(tr("Add curves / error bars"));
499  graph_tools->addWidget(btn_curves);
500 
501  menu_curves->addAction(actionShowCurvesDialog);
502  menu_curves->addAction(actionAddErrorBars);
503  menu_curves->addAction(actionAddFunctionCurve);
504 
505  QMenu *menu_plot_enrichments = new QMenu(this);
506  QToolButton *btn_plot_enrichments = new QToolButton(this);
507  btn_plot_enrichments->setMenu(menu_plot_enrichments);
508  btn_plot_enrichments->setPopupMode(QToolButton::InstantPopup);
509  btn_plot_enrichments->setIcon(QPixmap(":/text.xpm"));
510  btn_plot_enrichments->setToolTip(tr("Enrichments"));
511  graph_tools->addWidget(btn_plot_enrichments);
512 
513  actionAddText = new QAction(tr("Add &Text"), this);
514  actionAddText->setShortcut( tr("ALT+T") );
515  actionAddText->setIcon(QIcon(QPixmap(":/text.xpm")));
516  actionAddText->setCheckable(true);
517  connect(actionAddText, SIGNAL(triggered()), this, SLOT(addText()));
518  menu_plot_enrichments->addAction(actionAddText);
519 
520  btnArrow = new QAction(tr("Draw &Arrow"), this);
521  btnArrow->setShortcut( tr("CTRL+ALT+A") );
522  btnArrow->setActionGroup(dataTools);
523  btnArrow->setCheckable( true );
524  btnArrow->setIcon(QIcon(QPixmap(":/arrow.xpm")) );
525  menu_plot_enrichments->addAction(btnArrow);
526 
527  btnLine = new QAction(tr("Draw &Line"), this);
528  btnLine->setShortcut( tr("CTRL+ALT+L") );
529  btnLine->setActionGroup(dataTools);
530  btnLine->setCheckable( true );
531  btnLine->setIcon(QIcon(QPixmap(":/lPlot.xpm")) );
532  menu_plot_enrichments->addAction(btnLine);
533 
534  menu_plot_enrichments->addAction(actionTimeStamp);
535  menu_plot_enrichments->addAction(actionAddImage);
536  menu_plot_enrichments->addAction(actionNewLegend);
537 
538  graph_tools->addSeparator ();
539 
540  btnZoomIn = new QAction(tr("&Zoom In"), this);
541  btnZoomIn->setShortcut( tr("Ctrl++") );
542  btnZoomIn->setActionGroup(dataTools);
543  btnZoomIn->setCheckable( true );
544  btnZoomIn->setIcon(QIcon(QPixmap(":/zoom.xpm")) );
545  graph_tools->addAction(btnZoomIn);
546 
547  btnZoomOut = new QAction(tr("&Zoom Out"), this);
548  btnZoomOut->setShortcut( tr("Ctrl+-") );
549  btnZoomOut->setActionGroup(dataTools);
550  btnZoomOut->setCheckable( true );
551  btnZoomOut->setIcon(QIcon(QPixmap(":/zoomOut.xpm")) );
552  graph_tools->addAction(btnZoomOut);
553 
554  graph_tools->addAction(actionUnzoom);
555 
556  graph_tools->addSeparator();
557 
558  btnPicker = new QAction(tr("S&creen Reader"), this);
559  btnPicker->setActionGroup(dataTools);
560  btnPicker->setCheckable( true );
561  btnPicker->setIcon(QIcon(QPixmap(":/cursor_16.xpm")) );
562  graph_tools->addAction(btnPicker);
563 
564  btnCursor = new QAction(tr("&Data Reader"), this);
565  btnCursor->setShortcut( tr("CTRL+D") );
566  btnCursor->setActionGroup(dataTools);
567  btnCursor->setCheckable( true );
568  btnCursor->setIcon(QIcon(QPixmap(":/select.xpm")) );
569  graph_tools->addAction(btnCursor);
570 
571  btnSelect = new QAction(tr("&Select Data Range"), this);
572  btnSelect->setShortcut( tr("ALT+S") );
573  btnSelect->setActionGroup(dataTools);
574  btnSelect->setCheckable( true );
575  btnSelect->setIcon(QIcon(QPixmap(":/cursors.xpm")) );
576  graph_tools->addAction(btnSelect);
577 
578  btnMovePoints = new QAction(tr("&Move Data Points..."), this);
579  btnMovePoints->setShortcut( tr("Ctrl+ALT+M") );
580  btnMovePoints->setActionGroup(dataTools);
581  btnMovePoints->setCheckable( true );
582  btnMovePoints->setIcon(QIcon(QPixmap(":/hand.xpm")) );
583 
584  btnRemovePoints = new QAction(tr("Remove &Bad Data Points..."), this);
585  btnRemovePoints->setShortcut( tr("Alt+B") );
586  btnRemovePoints->setActionGroup(dataTools);
587  btnRemovePoints->setCheckable( true );
588  btnRemovePoints->setIcon(QIcon(QPixmap(":/gomme.xpm")));
589 
590  connect( dataTools, SIGNAL( triggered( QAction* ) ), this, SLOT( pickDataTool( QAction* ) ) );
591 
592  plot_tools = new QToolBar(tr("Plot"), this);
593  plot_tools->setObjectName("plot_tools"); // this is needed for QMainWindow::restoreState()
594  plot_tools->setIconSize( QSize(22,22) );
595  addToolBar( Qt::TopToolBarArea, plot_tools );
596 
597  QMenu *menu_plot_linespoints = new QMenu(this);
598  QToolButton *btn_plot_linespoints = new QToolButton(this);
599  btn_plot_linespoints->setMenu(menu_plot_linespoints);
600  btn_plot_linespoints->setPopupMode(QToolButton::InstantPopup);
601  btn_plot_linespoints->setIcon(QPixmap(":/lpPlot.xpm"));
602  btn_plot_linespoints->setToolTip(tr("Lines and/or symbols"));
603  plot_tools->addWidget(btn_plot_linespoints);
604  menu_plot_linespoints->addAction(actionPlotL);
605  menu_plot_linespoints->addAction(actionPlotP);
606  menu_plot_linespoints->addAction(actionPlotLP);
607  menu_plot_linespoints->addAction(actionPlotSpline);
608  menu_plot_linespoints->addAction(actionPlotVerticalDropLines);
609  menu_plot_linespoints->addAction(actionPlotHorSteps);
610  menu_plot_linespoints->addAction(actionPlotVertSteps);
611 
612  QMenu *menu_plot_bars = new QMenu(this);
613  QToolButton *btn_plot_bars = new QToolButton(this);
614  btn_plot_bars->setMenu(menu_plot_bars);
615  btn_plot_bars->setPopupMode(QToolButton::InstantPopup);
616  btn_plot_bars->setIcon(QPixmap(":/vertBars.xpm"));
617  plot_tools->addWidget(btn_plot_bars);
618  menu_plot_bars->addAction(actionPlotVerticalBars);
619  menu_plot_bars->addAction(actionPlotHorizontalBars);
620 
621  plot_tools->addAction(actionPlotArea);
622  plot_tools->addAction(actionPlotPie);
623  plot_tools->addAction(actionPlotHistogram);
624  plot_tools->addAction(actionBoxPlot);
625 
626  QMenu *menu_plot_vect = new QMenu(this);
627  QToolButton *btn_plot_vect = new QToolButton(this);
628  btn_plot_vect->setMenu(menu_plot_vect);
629  btn_plot_vect->setPopupMode(QToolButton::InstantPopup);
630  btn_plot_vect->setIcon(QPixmap(":/vectXYXY.xpm"));
631  plot_tools->addWidget(btn_plot_vect);
632  menu_plot_vect->addAction(actionPlotVectXYXY);
633  menu_plot_vect->addAction(actionPlotVectXYAM);
634 
635  plot_tools->addSeparator ();
636 
637  plot_tools->addAction(actionPlot3DRibbon);
638  plot_tools->addAction(actionPlot3DBars);
639  plot_tools->addAction(actionPlot3DScatter);
641 
642 
643  table_tools = new QToolBar( tr( "Table" ), this );
644  table_tools->setObjectName("table_tools"); // this is needed for QMainWindow::restoreState()
645  table_tools->setIconSize( QSize(22,22) );
646  addToolBar( Qt::TopToolBarArea, table_tools );
647 
648  graph_tools->setEnabled(false);
649  table_tools->setEnabled(false);
650  plot_tools->setEnabled(false);
651 
652  d_status_info = new QLabel( this );
653  d_status_info->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel );
654  d_status_info->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
655  d_status_info->setContextMenuPolicy( Qt::CustomContextMenu );
656  connect(d_status_info, SIGNAL(customContextMenuRequested(const QPoint &)),
657  this, SLOT(showStatusBarContextMenu(const QPoint &)) );
658 
659  statusBar()->addWidget( d_status_info, 1 );
660 
661  matrix_plot_tools = new QToolBar( tr( "Matrix Plot" ), this);
662  matrix_plot_tools->setObjectName("matrix_plot_tools");
663  addToolBar(Qt::BottomToolBarArea, matrix_plot_tools);
664 
667 
670 
671  matrix_plot_tools->addSeparator();
672 
675 
676  matrix_plot_tools->addSeparator();
677  matrix_plot_tools->addAction(actionColorMap);
679  matrix_plot_tools->addAction(actionGrayMap);
680 
681  matrix_plot_tools->setEnabled(false);
682 }
683 
684 void ApplicationWindow::lockToolbar(const bool status)
685 {
686  if (status)
687  {
688  file_tools->setMovable(false);
689  edit_tools->setMovable(false);
690  graph_tools->setMovable(false);
691  graph_3D_tools->setMovable(false);
692  plot_tools->setMovable(false);
693  table_tools->setMovable(false);
694  matrix_plot_tools->setMovable(false);
695  locktoolbar->setIcon(QIcon(QPixmap(":/lock.xpm")));
696  } else {
697  file_tools->setMovable(true);
698  edit_tools->setMovable(true);
699  graph_tools->setMovable(true);
700  graph_3D_tools->setMovable(true);
701  plot_tools->setMovable(true);
702  table_tools->setMovable(true);
703  matrix_plot_tools->setMovable(true);
704  locktoolbar->setIcon(QIcon(QPixmap(":/unlock.xpm")));
705  }
706 }
707 
709 {
710  if (projectname == "untitled")
711  setWindowTitle(tr("SciDAVis - untitled"));
712 
713  lv.headerItem()->setText (0, tr("Name"));
714  lv.headerItem()->setText (1, tr("Type"));
715  lv.headerItem()->setText (2, tr("View"));
716  lv.headerItem()->setText (3, tr("Created"));
717  lv.headerItem()->setText (4, tr("Label"));
718 
719  explorerWindow.setWindowTitle(tr("Project Explorer"));
720  logWindow.setWindowTitle(tr("Results Log"));
721 #ifdef SCRIPTING_CONSOLE
722  consoleWindow.setWindowTitle(tr("Scripting Console"));
723 #endif
724  table_tools->setWindowTitle(tr("Table"));
725  plot_tools->setWindowTitle(tr("Plot"));
726  graph_tools->setWindowTitle(tr("Graph"));
727  file_tools->setWindowTitle(tr("File"));
728  edit_tools->setWindowTitle(tr("Edit"));
729  matrix_plot_tools->setWindowTitle(tr("Matrix Plot"));
730  graph_3D_tools->setWindowTitle(tr("3D Surface"));
731 
732  file->setTitle(tr("&File"));
733  edit->setTitle(tr("&Edit"));
734  view->setTitle(tr("&View"));
735  scriptingMenu->setTitle(tr("Scripting"));
736  graph->setTitle(tr("&Graph"));
737  plot3DMenu->setTitle(tr("3D &Plot"));
738  matrixMenu->setTitle(tr("&Matrix"));
739  tableMenu->setTitle(tr("&Table"));
740  plot2D->setTitle(tr("&Plot"));
741  dataMenu->setTitle(tr("&Analysis"));
742  plotDataMenu->setTitle(tr("&Tools"));
743  calcul->setTitle(tr("&Analysis"));
744  d_quick_fit_menu->setTitle(tr("&Quick Fit"));
745  format->setTitle(tr("For&mat"));
746  windowsMenu->setTitle(tr("&Windows"));
747  help->setTitle(tr("&Help"));
748 
749  type->setTitle(tr("&New"));
750  recent->setTitle(tr("&Recent Projects"));
751  exportPlot->setTitle(tr("&Export Graph"));
752 
753  specialPlot->setTitle(tr("Special Line/Symb&ol"));
754  stat->setTitle(tr("Statistical &Graphs"));
755  panels->setTitle(tr("Pa&nel"));
756  plot3D->setTitle(tr("3&D Plot"));
757 
758  translateMenu->setTitle(tr("&Translate"));
759  smooth->setTitle(tr("&Smooth"));
760  filter->setTitle(tr("&FFT Filter"));
761  decay->setTitle(tr("Fit E&xponential Decay"));
762  multiPeakMenu->setTitle(tr("Fit &Multi-Peak"));
763 
765  for (auto w: windowsList())
766  customMenu(w);
767 }
768 
770 {
771  file = new QMenu( this );
772  file->setTitle(tr("&File"));
773  file->setFont(appFont);
774 
775  type = file->addMenu(tr("&New"));
776  type->setFont(appFont);
777  type->addAction(actionNewProject);
778  type->addAction(actionNewTable);
779  type->addAction(actionNewMatrix);
780  type->addAction(actionNewNote);
781  type->addAction(actionNewGraph);
782  type->addAction(actionNewFunctionPlot);
783  type->addAction(actionNewSurfacePlot);
784 
785  file->addAction(actionOpen);
786 
787  recent = file->addMenu(tr("&Recent Projects"));
788  recent->setFont(appFont);
789 
790  file->addSeparator();
791 
792  file->addAction(actionLoadImage);
793  file->addAction(actionImportImage);
794 
795  file->addSeparator();
796 
797  file->addAction(actionSaveProject);
798  file->addAction(actionSaveProjectAs);
799 
800  file->addSeparator();
801  file->addAction(actionOpenTemplate);
802  file->addAction(actionSaveTemplate);
803  file->addSeparator();
804 
805  exportPlot = file->addMenu(tr("&Export Graph"));
806  exportPlot->addAction(actionExportGraph);
807  exportPlot->addAction(actionExportAllGraphs);
808 
809  file->addAction(actionPrint);
810  file->addAction(actionPrintAllPlots);
811 
812  file->addSeparator();
813 
814  file->addAction(actionShowExportASCIIDialog);
815  file->addAction(actionLoad);
816 
817  file->addSeparator();
818 
819  file->addAction(actionCloseAllWindows);
820 
821  edit = new QMenu(this);
822  edit->setFont(appFont);
823  edit->setTitle(tr("&Edit"));
824  edit->addAction(actionUndo);
825  edit->addAction(actionRedo);
826 
827  edit->addSeparator();
828 
829  edit->addAction(actionCutSelection);
830  edit->addAction(actionCopySelection);
831  edit->addAction(actionPasteSelection);
832  edit->addAction(actionClearSelection);
833 
834  edit->addSeparator();
835 
836  edit->addAction(actionDeleteFitTables);
837  edit->addAction(actionClearLogInfo);
838 
839  edit->addSeparator();
840 
841  edit->addAction(actionShowConfigureDialog);
842 
843  view = new QMenu(this);
844  view->setFont(appFont);
845  view->setTitle(tr("&View"));
847  if(!toolbarsMenu) toolbarsMenu = new QMenu(this);
848  toolbarsMenu->setTitle(tr("Toolbars"));
849 
850  view->addMenu(toolbarsMenu);
851  view->addAction(locktoolbar);
852  view->addSeparator();
853  view->addAction(actionShowPlotWizard);
854  view->addAction(actionShowExplorer);
855  view->addAction(actionShowLog);
856  view->addAction(actionShowHistory);
857 #ifdef SCRIPTING_CONSOLE
858  view->addAction(actionShowConsole);
859 #endif
860 
861  graph = new QMenu(this);
862  graph->setFont(appFont);
863  graph->setTitle(tr("&Graph"));
864  graph->addAction(actionShowCurvesDialog);
865  graph->addAction(actionAddErrorBars);
866  graph->addAction(actionAddFunctionCurve);
867 
868  graph->addSeparator();
869 
870  graph->addAction(actionAddText);
871  graph->addAction(btnArrow);
872  graph->addAction(btnLine);
873  graph->addAction(actionTimeStamp);
874  graph->addAction(actionAddImage);
875  graph->addAction(actionNewLegend);
876 
877  graph->addSeparator();//layers section
878  graph->addAction(actionAutomaticLayout);
879  graph->addAction(actionAddLayer);
880  graph->addAction(actionDeleteLayer);
881  graph->addAction(actionShowLayerDialog);
882 
883  plot3DMenu = new QMenu(this);
884  plot3DMenu->setFont(appFont);
885  plot3DMenu->setTitle(tr("3D &Plot"));
886 
887  plot3DMenu->addAction(actionPlot3DWireFrame);
889 
890  plot3DMenu->addAction(actionPlot3DPolygons);
892 
893  plot3DMenu->addSeparator();
894 
895  plot3DMenu->addAction(actionPlot3DBars);
896  plot3DMenu->addAction(actionPlot3DScatter);
897 
898  plot3DMenu->addSeparator();
899  plot3DMenu->addAction(actionColorMap);
900  plot3DMenu->addAction(actionContourMap);
901  plot3DMenu->addAction(actionGrayMap);
902 
903  matrixMenu = new QMenu(this);
904  matrixMenu->setFont(appFont);
905  matrixMenu->setTitle(tr("&Matrix"));
906 
907  tableMenu = new QMenu(this);
908  tableMenu->setFont(appFont);
909  tableMenu->setTitle(tr("&Table"));
910 
911  initPlotMenu();
914 
915  calcul = new QMenu( this );
916  calcul->setFont(appFont);
917  calcul->setTitle(tr("&Analysis"));
918 
919  translateMenu = calcul->addMenu(tr("&Translate"));
920  translateMenu->setFont(appFont);
922  translateMenu->addAction(actionTranslateHor);
923  calcul->addSeparator();
924 
925  calcul->addAction(actionDifferentiate);
926  calcul->addAction(actionShowIntDialog);
927 
928  calcul->addSeparator();
929 
930  smooth = calcul->addMenu(tr("&Smooth"));
931  smooth->setFont(appFont);
932  smooth->addAction(actionSmoothSavGol);
933  smooth->addAction(actionSmoothAverage);
934  smooth->addAction(actionSmoothFFT);
935 
936  filter = calcul->addMenu(tr("&FFT Filter"));
937  filter->setFont(appFont);
938  filter->addAction(actionLowPassFilter);
939  filter->addAction(actionHighPassFilter);
940  filter->addAction(actionBandPassFilter);
941  filter->addAction(actionBandBlockFilter);
942 
943  calcul->addSeparator();
944  calcul->addAction(actionInterpolate);
945  calcul->addAction(actionFFT);
946  calcul->addSeparator();
947 
948  d_quick_fit_menu = new QMenu(this);
949  d_quick_fit_menu->setTitle(tr("&Quick Fit"));
950 
951  d_quick_fit_menu->addAction(actionFitLinear);
953 
954  d_quick_fit_menu->addSeparator();
955 
956  decay = d_quick_fit_menu->addMenu(tr("Fit E&xponential Decay"));
957  decay->setFont(appFont);
958  decay->addAction(actionShowExpDecayDialog);
960  decay->addAction(actionShowExpDecay3Dialog);
961 
964  d_quick_fit_menu->addAction(actionFitGauss);
966 
967  multiPeakMenu = d_quick_fit_menu->addMenu(tr("Fit &Multi-peak"));
968  multiPeakMenu->setFont(appFont);
971 
972  d_quick_fit_menu->addSeparator();
973 
974  calcul->addMenu(d_quick_fit_menu);
975  calcul->addAction(actionShowFitDialog);
976 
977  format = new QMenu(this);
978  format->setFont(appFont);
979  format->setTitle(tr("For&mat"));
980 
981  scriptingMenu = new QMenu(this);
982  scriptingMenu->setFont(appFont);
983  scriptingMenu->setTitle(tr("Scripting"));
984 
985  windowsMenu = new QMenu( this );
986  windowsMenu->setFont(appFont);
987  windowsMenu->setTitle(tr("&Windows"));
988  connect( windowsMenu, SIGNAL( aboutToShow() ),
989  this, SLOT( windowsMenuAboutToShow() ) );
990 
991  help = new QMenu( this );
992  help->setFont(appFont);
993  help->setTitle(tr("&Help"));
994 
995  help->addAction(actionShowHelp);
996 #ifdef DYNAMIC_MANUAL_PATH
997  help->addAction(actionChooseHelpFolder);
998 #endif
999  help->addSeparator();
1000  help->addAction(actionHomePage);
1001 #ifdef SEARCH_FOR_UPDATES
1002  help->addAction(actionCheckUpdates);
1003 #endif
1004 #ifdef DOWNLOAD_LINKS
1005  help->addAction(actionDownloadManual);
1006 #endif
1007  help->addSeparator();
1008  help->addAction(actionHelpForums);
1009  help->addAction(actionHelpBugReports);
1010  help->addSeparator();
1011  help->addAction(actionAbout);
1012 
1013  disableActions();
1014 }
1015 
1017 {
1018  plotDataMenu = new QMenu(this);
1019  plotDataMenu->setFont(appFont);
1020  plotDataMenu->setTitle(tr("&Tools"));
1021 
1022  plotDataMenu->addAction(btnPointer);
1023  plotDataMenu->addAction(btnZoomIn);
1024  plotDataMenu->addAction(btnZoomOut);
1025  plotDataMenu->addAction(actionUnzoom);
1026  plotDataMenu->addSeparator();
1027 
1028  plotDataMenu->addAction(btnPicker);
1029  plotDataMenu->addAction(btnCursor);
1030  plotDataMenu->addAction(btnSelect);
1031 
1032  plotDataMenu->addSeparator();
1033 
1034  plotDataMenu->addAction(btnMovePoints);
1035  plotDataMenu->addAction(btnRemovePoints);
1036 }
1037 
1039 {
1040  plot2D = new QMenu(this);
1041  plot2D->setFont(appFont);
1042  plot2D->setTitle(tr("&Plot"));
1043 
1044  plot2D->addAction(actionPlotL);
1045  plot2D->addAction(actionPlotP);
1046  plot2D->addAction(actionPlotLP);
1047 
1048  specialPlot = plot2D->addMenu(tr("Special Line/Symb&ol"));
1049  specialPlot->setFont(appFont);
1051  specialPlot->addAction(actionPlotSpline);
1052  specialPlot->addAction(actionPlotVertSteps);
1053  specialPlot->addAction(actionPlotHorSteps);
1054 
1055  plot2D->addSeparator();
1056 
1057  plot2D->addAction(actionPlotVerticalBars);
1058  plot2D->addAction(actionPlotHorizontalBars);
1059  plot2D->addAction(actionPlotArea);
1060  plot2D->addAction(actionPlotPie);
1061  plot2D->addAction(actionPlotVectXYXY);
1062  plot2D->addAction(actionPlotVectXYAM);
1063 
1064  plot2D->addSeparator();
1065 
1066  stat = plot2D->addMenu(tr("Statistical &Graphs"));
1067  stat->setFont(appFont);
1068  stat->addAction(actionBoxPlot);
1069  stat->addAction(actionPlotHistogram);
1070  stat->addAction(actionPlotStackedHistograms);
1071 
1072  panels = plot2D->addMenu(tr("Pa&nel"));
1073  panels->setFont(appFont);
1074  panels->addAction(actionPlot2VerticalLayers);
1075  panels->addAction(actionPlot2HorizontalLayers);
1076  panels->addAction(actionPlot4Layers);
1077  panels->addAction(actionPlotStackedLayers);
1078 
1079  plot2D->addSeparator();
1080 
1081  plot3D = plot2D->addMenu(tr("3&D Plot"));
1082  plot3D->setFont(appFont);
1083  plot3D->addAction(actionPlot3DRibbon);
1084  plot3D->addAction(actionPlot3DBars);
1085  plot3D->addAction(actionPlot3DScatter);
1086  plot3D->addAction(actionPlot3DTrajectory);
1087 
1088 }
1089 
1091 {
1092  dataMenu = new QMenu(this);
1093  dataMenu->setFont(appFont);
1094  dataMenu->setTitle(tr("&Analysis"));
1095 
1096  dataMenu->addAction(actionShowColStatistics);
1097  dataMenu->addAction(actionShowRowStatistics);
1098 
1099  dataMenu->addSeparator();
1100  dataMenu->addAction(actionFFT);
1101  dataMenu->addSeparator();
1102  dataMenu->addAction(actionCorrelate);
1103  dataMenu->addAction(actionAutoCorrelate);
1104  dataMenu->addSeparator();
1105  dataMenu->addAction(actionConvolute);
1106  dataMenu->addAction(actionDeconvolute);
1107 
1108  dataMenu->addSeparator();
1109  dataMenu->addAction(actionShowFitDialog);
1110 }
1111 
1113 {
1114  menuBar()->clear();
1115  menuBar()->addMenu(file);
1116  menuBar()->addMenu(edit);
1117  menuBar()->addMenu(view);
1118  menuBar()->addMenu(scriptingMenu);
1119 
1120  scriptingMenu->clear();
1121 #ifdef SCRIPTING_DIALOG
1122  scriptingMenu->addAction(actionScriptingLang);
1123 #endif
1125 
1126  // these use the same keyboard shortcut (Ctrl+Return) and should not be enabled at the same time
1127  actionNoteEvaluate->setEnabled(false);
1128 
1129  if(w)
1130  {
1131  actionPrintAllPlots->setEnabled(projectHas2DPlots());
1132  actionPrint->setEnabled(true);
1133  actionCutSelection->setEnabled(true);
1134  actionCopySelection->setEnabled(true);
1135  actionPasteSelection->setEnabled(true);
1136  actionClearSelection->setEnabled(true);
1137  actionSaveTemplate->setEnabled(true);
1138 
1139  if (w->inherits("MultiLayer"))
1140  {
1141  menuBar()->addMenu(graph);
1142  menuBar()->addMenu(plotDataMenu);
1143  menuBar()->addMenu(calcul);
1144  menuBar()->addMenu(format);
1145 
1146  exportPlot->setEnabled (true);
1147  actionShowExportASCIIDialog->setEnabled(false);
1148  // file->setItemEnabled (closeID,true);
1149 
1150  format->clear();
1151  format->addAction(actionShowPlotDialog);
1152  format->addSeparator();
1153  format->addAction(actionShowScaleDialog);
1154  format->addAction(actionShowAxisDialog);
1155  actionShowAxisDialog->setEnabled(true);
1156  format->addSeparator();
1157  format->addAction(actionShowGridDialog);
1158  format->addAction(actionShowTitleDialog);
1159  }
1160  else if (w->inherits("Graph3D"))
1161  {
1162  disableActions();
1163 
1164  menuBar()->addMenu(format);
1165 
1166  actionPrint->setEnabled(true);
1167  actionSaveTemplate->setEnabled(true);
1168  exportPlot->setEnabled (true);
1169  // file->setItemEnabled (closeID,true);
1170 
1171  format->clear();
1172  format->addAction(actionShowPlotDialog);
1173  format->addAction(actionShowScaleDialog);
1174  format->addAction(actionShowAxisDialog);
1175  format->addAction(actionShowTitleDialog);
1176  if (((Graph3D*)w)->coordStyle() == Qwt3D::NOCOORD)
1177  actionShowAxisDialog->setEnabled(false);
1178  }
1179  else if (w->inherits("Table"))
1180  {
1181  menuBar()->addMenu(plot2D);
1182  menuBar()->addMenu(dataMenu);
1183 
1184  actionShowExportASCIIDialog->setEnabled(true);
1185  exportPlot->setEnabled (false);
1186  // file->setItemEnabled (closeID,true);
1187 
1188  tableMenu->clear();
1189  static_cast<Table *>(w)->d_future_table->fillProjectMenu(tableMenu);
1190  tableMenu->addSeparator();
1192  tableMenu->addSeparator();
1193  tableMenu->addAction(actionConvertTable);
1194  menuBar()->addMenu(tableMenu);
1195  }
1196  else if (w->inherits("Matrix"))
1197  {
1198  menuBar()->addMenu(plot3DMenu);
1199 
1200  matrixMenu->clear();
1201  static_cast<Matrix *>(w)->d_future_matrix->fillProjectMenu(matrixMenu);
1202  matrixMenu->addSeparator();
1203  matrixMenu->addAction(actionInvertMatrix);
1204  matrixMenu->addAction(actionMatrixDeterminant);
1205  matrixMenu->addSeparator();
1206  matrixMenu->addAction(actionConvertMatrix);
1207  menuBar()->addMenu(matrixMenu);
1208  }
1209  else if (w->inherits("Note"))
1210  {
1211  actionSaveTemplate->setEnabled(false);
1212  actionNoteEvaluate->setEnabled(true);
1213  scriptingMenu->addSeparator();
1214  scriptingMenu->addAction(actionNoteExecute);
1215  scriptingMenu->addAction(actionNoteExecuteAll);
1216  scriptingMenu->addAction(actionNoteEvaluate);
1217 
1218  actionNoteExecute->disconnect(SIGNAL(triggered()));
1219  actionNoteExecuteAll->disconnect(SIGNAL(triggered()));
1220  actionNoteEvaluate->disconnect(SIGNAL(triggered()));
1221  connect(actionNoteExecute, SIGNAL(triggered()), w, SLOT(execute()));
1222  connect(actionNoteExecuteAll, SIGNAL(triggered()), w, SLOT(executeAll()));
1223  connect(actionNoteEvaluate, SIGNAL(triggered()), w, SLOT(evaluate()));
1224  }
1225  else
1226  disableActions();
1227 
1228  menuBar()->addMenu(windowsMenu );
1229  }
1230  else
1231  disableActions();
1232 
1233  menuBar()->addMenu(help);
1234 }
1235 
1237 {
1238  actionSaveTemplate->setEnabled(false);
1239  actionPrintAllPlots->setEnabled(false);
1240  actionPrint->setEnabled(false);
1241  actionShowExportASCIIDialog->setEnabled(false);
1242  exportPlot->setEnabled (false);
1243  // file->setItemEnabled (closeID,false);
1244 
1245  actionUndo->setEnabled(false);
1246  actionRedo->setEnabled(false);
1247 
1248  actionCutSelection->setEnabled(false);
1249  actionCopySelection->setEnabled(false);
1250  actionPasteSelection->setEnabled(false);
1251  actionClearSelection->setEnabled(false);
1252 }
1253 
1255 {
1256  if (w)
1257  {
1258  if (!projectHas3DPlots())
1259  graph_3D_tools->setEnabled(false);
1260  if (!projectHas2DPlots())
1261  graph_tools->setEnabled(false);
1262  if (!projectHasMatrices())
1263  matrix_plot_tools->setEnabled(false);
1264  if (tableWindows().count()<=0) {
1265  table_tools->setEnabled(false);
1266  plot_tools->setEnabled(false);
1267  }
1268 
1269  if (w->inherits("MultiLayer"))
1270  {
1271  graph_tools->setEnabled (true);
1272  graph_3D_tools->setEnabled (false);
1273  table_tools->setEnabled(false);
1274  matrix_plot_tools->setEnabled (false);
1275 
1276  Graph *g = static_cast<MultiLayer*>(w)->activeGraph();
1277  if (g) {
1278  dataTools->blockSignals(true);
1279  if (g->rangeSelectorsEnabled())
1280  btnSelect->setChecked(true);
1281  else if (g->zoomOn())
1282  btnZoomIn->setChecked(true);
1283  else if (g->drawArrow())
1284  btnArrow->setChecked(true);
1285  else if (g->drawLineActive())
1286  btnLine->setChecked(true);
1287  else if (g->activeTool() == 0)
1288  btnPointer->setChecked(true);
1289  else switch (g->activeTool()->rtti()) {
1291  switch (static_cast<DataPickerTool*>(g->activeTool())->mode()) {
1293  btnCursor->setChecked(true);
1294  break;
1295  case DataPickerTool::Move:
1296  btnMovePoints->setChecked(true);
1297  break;
1299  btnRemovePoints->setChecked(true);
1300  break;
1301  }
1302  break;
1304  btnPicker->setChecked(true);
1305  break;
1306  default:
1307  btnPointer->setChecked(true);
1308  break;
1309  }
1310  dataTools->blockSignals(false);
1311  }
1312  if (g && g->curves() > 0) {
1313  plot_tools->setEnabled(true);
1314  QwtPlotCurve *c = g->curve(g->curves()-1);
1315  // plot tools managed by d_plot_mapper
1316  for (int i=0; i<=(int)Graph::VerticalSteps; i++) {
1317  QAction *a = static_cast<QAction*>(d_plot_mapper->mapping(i));
1318  if (a)
1319  a->setEnabled(Graph::canConvertTo(c, (Graph::CurveType)i));
1320  }
1321  // others
1322  actionPlotPie->setEnabled(Graph::canConvertTo(c, Graph::Pie));
1325  actionBoxPlot->setEnabled(Graph::canConvertTo(c, Graph::Box));
1326  // 3D plots
1327  actionPlot3DRibbon->setEnabled(false);
1328  actionPlot3DScatter->setEnabled(false);
1329  actionPlot3DTrajectory->setEnabled(false);
1330  actionPlot3DBars->setEnabled(false);
1331  } else
1332  plot_tools->setEnabled(false);
1333  }
1334  else if (w->inherits("Table"))
1335  {
1336  table_tools->clear();
1337  static_cast<Table *>(w)->d_future_table->fillProjectToolBar(table_tools);
1338  table_tools->setEnabled (true);
1339 
1340  graph_tools->setEnabled (false);
1341  graph_3D_tools->setEnabled (false);
1342  matrix_plot_tools->setEnabled (false);
1343 
1344  plot_tools->setEnabled(true);
1345  // plot tools managed by d_plot_mapper
1346  for (int i=0; i<=(int)Graph::VerticalSteps; i++) {
1347  QAction *a = static_cast<QAction*>(d_plot_mapper->mapping(i));
1348  if (a)
1349  a->setEnabled(true);
1350  }
1351  // others
1352  actionPlotPie->setEnabled(true);
1353  actionPlotVectXYAM->setEnabled(true);
1354  actionPlotVectXYXY->setEnabled(true);
1355  actionBoxPlot->setEnabled(true);
1356  // 3D plots
1357  actionPlot3DRibbon->setEnabled(true);
1358  actionPlot3DScatter->setEnabled(true);
1359  actionPlot3DTrajectory->setEnabled(true);
1360  actionPlot3DBars->setEnabled(true);
1361  }
1362  else if (w->inherits("Matrix"))
1363  {
1364  graph_tools->setEnabled (false);
1365  graph_3D_tools->setEnabled (false);
1366  table_tools->setEnabled (false);
1367  plot_tools->setEnabled(false);
1368  matrix_plot_tools->setEnabled (true);
1369  }
1370  else if (w->inherits("Graph3D"))
1371  {
1372  graph_tools->setEnabled (false);
1373  table_tools->setEnabled (false);
1374  plot_tools->setEnabled(false);
1375  matrix_plot_tools->setEnabled (false);
1376 
1377  Graph3D* plot= (Graph3D*)w;
1378  if (plot->plotStyle() == Qwt3D::NOPLOT)
1379  graph_3D_tools->setEnabled (false);
1380  else
1381  graph_3D_tools->setEnabled (true);
1382 
1383  custom3DActions(w);
1384  }
1385  else if (w->inherits("Note"))
1386  {
1387  graph_tools->setEnabled (false);
1388  graph_3D_tools->setEnabled (false);
1389  table_tools->setEnabled (false);
1390  plot_tools->setEnabled(false);
1391  matrix_plot_tools->setEnabled (false);
1392  }
1393 
1394  }
1395  else
1396  {
1397  graph_tools->setEnabled (false);
1398  table_tools->setEnabled (false);
1399  plot_tools->setEnabled(false);
1400  graph_3D_tools->setEnabled (false);
1401  matrix_plot_tools->setEnabled (false);
1402  }
1403 }
1404 
1406 {
1407  if (!d_workspace.activeSubWindow() || !d_workspace.activeSubWindow()->inherits("Table"))
1408  return;
1409 
1410  Table* table = static_cast<Table*>(d_workspace.activeSubWindow());
1411  if(table->selectedColumns().count() == 1)
1412  {
1413  if (!validFor3DPlot(table))
1414  return;
1416  }
1417  else
1418  QMessageBox::warning(this,tr("Plot error"),tr("You must select exactly one column for plotting!"));
1419 }
1420 
1422 {
1423  plot3DMatrix (Qwt3D::WIREFRAME);
1424 }
1425 
1427 {
1428  plot3DMatrix (Qwt3D::HIDDENLINE);
1429 }
1430 
1432 {
1433  plot3DMatrix (Qwt3D::FILLED);
1434 }
1435 
1437 {
1438  plot3DMatrix (Qwt3D::FILLEDMESH);
1439 }
1440 
1442 {
1443  MyWidget* w = (MyWidget*)d_workspace.activeSubWindow();
1444  if (!w)
1445  return;
1446 
1447  if (w->inherits("Table"))
1448  {
1449  Table *table = static_cast<Table *>(w);
1450 
1451  if(table->selectedColumns().count() == 1)
1452  {
1453  if (!validFor3DPlot(table))
1454  return;
1456  }
1457  else
1458  QMessageBox::warning(this, tr("Plot error"),tr("You must select exactly one column for plotting!"));
1459  }
1460  else if(w->inherits("Matrix"))
1461  plot3DMatrix(Qwt3D::USER);
1462 }
1463 
1465 {
1466  MyWidget* w = (MyWidget*)d_workspace.activeSubWindow();
1467  if (!w)
1468  return;
1469 
1470  if (w->inherits("Table"))
1471  {
1472  Table *table = static_cast<Table *>(w);
1473 
1474  if(table->selectedColumns().count() == 1)
1475  {
1476  if (!validFor3DPlot(table))
1477  return;
1479  }
1480  else
1481  QMessageBox::warning(this, tr("Plot error"),tr("You must select exactly one column for plotting!"));
1482  }
1483  else if(w->inherits("Matrix"))
1484  plot3DMatrix (Qwt3D::POINTS);
1485 }
1486 
1488 {
1489  MyWidget* w = (MyWidget*)d_workspace.activeSubWindow();
1490  if (!w)
1491  return;
1492 
1493  if (w->inherits("Table"))
1494  {
1495  Table *table = static_cast<Table *>(w);
1496 
1497  if(table->selectedColumns().count() == 1)
1498  {
1499  if (!validFor3DPlot(table))
1500  return;
1502  }
1503  else
1504  QMessageBox::warning(this, tr("Plot error"),tr("You must select exactly one column for plotting!"));
1505  }
1506 }
1507 
1509 {
1510  if (!d_workspace.activeSubWindow() || !d_workspace.activeSubWindow()->inherits("Table"))
1511  return;
1512 
1513  Table * table = static_cast<Table *>(d_workspace.activeSubWindow());
1514 
1515  if(table->selectedColumns().count() != 1)
1516  {
1517  QMessageBox::warning(this, tr("Plot error"),
1518  tr("You must select exactly one column for plotting!"));
1519  return;
1520  }
1521  if (table->noXColumn())
1522  {
1523  QMessageBox::critical(0,tr("Error"), tr("Please set a default X column for this table, first!"));
1524  return;
1525  }
1526 
1527  QStringList s = table->selectedColumns();
1528  if (s.count()>0)
1529  {
1531  }
1532  else
1533  QMessageBox::warning(this, tr("Error"), tr("Please select a column to plot!"));
1534 }
1535 
1537 {
1538  if (!d_workspace.activeSubWindow() || !d_workspace.activeSubWindow()->inherits("Table"))
1539  return;
1540 
1541  Table * table = static_cast<Table *>(d_workspace.activeSubWindow());
1542 
1544  return;
1545 
1546  QStringList s = table->selectedColumns();
1547  if (s.count() == 4)
1548  {
1550  }
1551  else
1552  QMessageBox::warning(this, tr("Error"), tr("Please select four columns for this operation!"));
1553 }
1554 
1556 {
1557  if (!d_workspace.activeSubWindow() || !d_workspace.activeSubWindow()->inherits("Table"))
1558  return;
1559 
1560  Table * table = static_cast<Table *>(d_workspace.activeSubWindow());
1561 
1563  return;
1564 
1565  QStringList s = table->selectedColumns();
1566  if (s.count() == 4)
1567  {
1569  }
1570  else
1571  QMessageBox::warning(this, tr("Error"), tr("Please select four columns for this operation!"));
1572 }
1573 
1574 void ApplicationWindow::renameListViewItem(const QString& oldName,const QString& newName)
1575 {
1576  QTreeWidgetItem *it=lv.findItems (oldName, Qt::MatchExactly | Qt::MatchCaseSensitive ).value(0);
1577  if (it)
1578  it->setText(0,newName);
1579 }
1580 
1581 void ApplicationWindow::setListViewLabel(const QString& caption,const QString& label)
1582 {
1583  QTreeWidgetItem *it=lv.findItems ( caption, Qt::MatchExactly | Qt::MatchCaseSensitive ).value(0);
1584  if (it)
1585  it->setText(4,label);
1586 }
1587 
1588 void ApplicationWindow::setListViewDate(const QString& caption,const QString& date)
1589 {
1590  QTreeWidgetItem *it=lv.findItems ( caption, Qt::MatchExactly | Qt::MatchCaseSensitive ).value(0);
1591  if (it)
1592  it->setText(3,date);
1593 }
1594 
1595 void ApplicationWindow::setListView(const QString& caption,const QString& view)
1596 {
1597  QTreeWidgetItem *it=lv.findItems ( caption, Qt::MatchExactly | Qt::MatchCaseSensitive ).value(0);
1598  if (it)
1599  it->setText(2,view);
1600 }
1601 
1602 void ApplicationWindow::updateTableNames(const QString& oldName, const QString& newName)
1603 {
1604  QList<MyWidget*> windows = windowsList();
1605  foreach (MyWidget *w, windows)
1606  {
1607  if (w->inherits("MultiLayer"))
1608  {
1609  QWidgetList gr_lst = ((MultiLayer*)w)->graphPtrs();
1610  foreach(QWidget *widget, gr_lst)
1611  ((Graph *)widget)->updateCurveNames(oldName, newName);
1612  }
1613  else if (w->inherits("Graph3D"))
1614  {
1615  QString name = ((Graph3D*)w)->formula();
1616  if (name.contains(oldName,Qt::CaseSensitive))
1617  {
1618  name.replace(oldName,newName);
1619  ((Graph3D*)w)->setPlotAssociation(name);
1620  }
1621  }
1622  }
1623 }
1624 
1625 void ApplicationWindow::updateColNames(const QString& oldName, const QString& newName)
1626 {
1627  QList<MyWidget*> windows = windowsList();
1628  foreach (MyWidget *w, windows)
1629  {
1630  if (w->inherits("MultiLayer"))
1631  {
1632  QWidgetList gr_lst = ((MultiLayer*)w)->graphPtrs();
1633  foreach (QWidget *widget, gr_lst)
1634  ((Graph *)widget)->updateCurveNames(oldName, newName, false);
1635  }
1636  else if (w->inherits("Graph3D"))
1637  {
1638  QString name = ((Graph3D*)w)->formula();
1639  if (name.contains(oldName))
1640  {
1641  name.replace(oldName,newName);
1642  ((Graph3D*)w)->setPlotAssociation(name);
1643  }
1644  }
1645  }
1646 }
1647 
1648 void ApplicationWindow::changeMatrixName(const QString& oldName, const QString& newName)
1649 {
1650  QList<MyWidget*> lst = windowsList();
1651  foreach(MyWidget *w, lst)
1652  {
1653  if (w->inherits("Graph3D"))
1654  {
1655  QString s = ((Graph3D*)w)->formula();
1656  if (s.contains(oldName))
1657  {
1658  s.replace(oldName, newName);
1659  ((Graph3D*)w)->setPlotAssociation(s);
1660  }
1661  }
1662  else if (w->inherits("MultiLayer"))
1663  {
1664  QWidgetList graphsList = ((MultiLayer*)w)->graphPtrs();
1665  foreach (QWidget *gr_widget, graphsList)
1666  {
1667  Graph* g = (Graph*)gr_widget;
1668  for (int i=0; i<g->curves(); i++)
1669  {
1670  QwtPlotItem *sp = (QwtPlotItem *)g->plotItem(i);
1671  if (sp && sp->rtti() == QwtPlotItem::Rtti_PlotSpectrogram && sp->title().text() == oldName)
1672  sp->setTitle(newName);
1673  }
1674  }
1675  }
1676  }
1677 }
1678 
1680 {
1681  if (!m)
1682  return;
1683 
1684  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1685 
1686  QList<MyWidget*> windows = windowsList();
1687  foreach(MyWidget *w, windows)
1688  {
1689  if (w->inherits("Graph3D") && ((Graph3D*)w)->matrix() == m)
1690  ((Graph3D*)w)->clearData();
1691  else if (w->inherits("MultiLayer"))
1692  {
1693  QWidgetList graphsList = ((MultiLayer*)w)->graphPtrs();
1694  for (int j=0; j<(int)graphsList.count(); j++)
1695  {
1696  Graph* g = (Graph*)graphsList.at(j);
1697  for (int i=0; i<g->curves(); i++)
1698  {
1699  Spectrogram *sp = (Spectrogram *)g->plotItem(i);
1700  if (sp && sp->rtti() == QwtPlotItem::Rtti_PlotSpectrogram && sp->matrix() == m)
1701  g->removeCurve(i);
1702  }
1703  }
1704  }
1705  }
1706  QApplication::restoreOverrideCursor();
1707 }
1708 
1710 {
1711  Matrix *m = (Matrix *)window;
1712  if (!m)
1713  return;
1714 
1715  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1716 
1717  QList<MyWidget*> windows = windowsList();
1718  foreach(MyWidget *w, windows){
1719  if (w->inherits("Graph3D") && ((Graph3D*)w)->matrix() == m)
1720  ((Graph3D*)w)->updateMatrixData(m);
1721  else if (w->inherits("MultiLayer")){
1722  QWidgetList graphsList = ((MultiLayer*)w)->graphPtrs();
1723  for (int j=0; j<(int)graphsList.count(); j++){
1724  Graph* g = (Graph*)graphsList.at(j);
1725  for (int i=0; i<g->curves(); i++){
1726  Spectrogram *sp = (Spectrogram *)g->plotItem(i);
1727  if (sp && sp->rtti() == QwtPlotItem::Rtti_PlotSpectrogram && sp->matrix() == m)
1728  sp->updateData(m);
1729  }
1730  }
1731  }
1732  }
1733 
1734  QApplication::restoreOverrideCursor();
1735 }
1736 
1738 {
1739  if (tableWindows().count() <= 0)
1740  {
1741  QMessageBox::warning(this,tr("Warning"),
1742  tr("<h4>There are no tables available in this project.</h4>"
1743  "<p><h4>Please create a table and try again!</h4>"));
1744  return;
1745  }
1746 
1747  // TODO: string list -> Column * list
1748  QStringList zColumns = columnsList(SciDAVis::Z);
1749  if ((int)zColumns.count() <= 0)
1750  {
1751  QMessageBox::critical(this,tr("Warning"),
1752  tr("There are no available columns with plot designation set to Z!"));
1753  return;
1754  }
1755 
1756  DataSetDialog *ad = new DataSetDialog(tr("Column") + " : ", this);
1757  ad->setAttribute(Qt::WA_DeleteOnClose);
1758  connect (ad,SIGNAL(options(const QString&)), this, SLOT(insertNew3DData(const QString&)));
1759  ad->setWindowTitle(tr("Choose data set"));
1760  ad->setCurveNames(zColumns);
1761  ad->exec();
1762 }
1763 
1765 {
1766  DataSetDialog *ad = new DataSetDialog(tr("Column") + " : ", this);
1767  ad->setAttribute(Qt::WA_DeleteOnClose);
1768  connect (ad,SIGNAL(options(const QString&)), this, SLOT(change3DData(const QString&)));
1769 
1770  ad->setWindowTitle(tr("Choose data set"));
1771  // TODO: string list -> Column * list
1773  ad->exec();
1774 }
1775 
1777 {
1778  DataSetDialog *ad = new DataSetDialog(tr("Matrix") + " : ", this);
1779  ad->setAttribute(Qt::WA_DeleteOnClose);
1780  connect (ad, SIGNAL(options(const QString&)), this, SLOT(change3DMatrix(const QString&)));
1781 
1782  ad->setWindowTitle(tr("Choose matrix to plot"));
1783  ad->setCurveNames(matrixNames());
1784 
1785  Graph3D* g = (Graph3D*)d_workspace.activeSubWindow();
1786  if (g && g->matrix())
1787  ad->setCurentDataSet(g->matrix()->name());
1788  ad->exec();
1789 }
1790 
1791 void ApplicationWindow::change3DMatrix(const QString& matrix_name)
1792 {
1793  if ( d_workspace.activeSubWindow() && d_workspace.activeSubWindow()->inherits("Graph3D"))
1794  {
1795  Graph3D* g = (Graph3D*)d_workspace.activeSubWindow();
1796  Matrix *m = matrix(matrix_name);
1797  if (m && g)
1798  g->changeMatrix(m);
1799 
1800  emit modified();
1801  }
1802 }
1803 
1805 {
1806  QStringList matrices = matrixNames();
1807  if ((int)matrices.count() <= 0)
1808  {
1809  QMessageBox::warning(this, tr("Warning"),
1810  tr("<h4>There are no matrices available in this project.</h4>"
1811  "<p><h4>Please create a matrix and try again!</h4>"));
1812  return;
1813  }
1814 
1815  DataSetDialog *ad = new DataSetDialog(tr("Matrix") + " :", this);
1816  ad->setAttribute(Qt::WA_DeleteOnClose);
1817  connect (ad,SIGNAL(options(const QString&)), this, SLOT(insert3DMatrixPlot(const QString&)));
1818 
1819  ad->setWindowTitle(tr("Choose matrix to plot"));
1820  ad->setCurveNames(matrices);
1821  ad->exec();
1822 }
1823 
1824 void ApplicationWindow::insert3DMatrixPlot(const QString& matrix_name)
1825 {
1826  if ( d_workspace.activeSubWindow() && d_workspace.activeSubWindow()->inherits("Graph3D"))
1827  {
1828  ((Graph3D*)d_workspace.activeSubWindow())->addMatrixData(matrix(matrix_name));
1829  emit modified();
1830  }
1831 }
1832 
1833 void ApplicationWindow::insertNew3DData(const QString& colName)
1834 {
1835  if ( d_workspace.activeSubWindow() && d_workspace.activeSubWindow()->inherits("Graph3D"))
1836  {
1837  ((Graph3D*)d_workspace.activeSubWindow())->insertNewData(table(colName),colName);
1838  emit modified();
1839  }
1840 }
1841 
1842 void ApplicationWindow::change3DData(const QString& colName)
1843 {
1844  if ( d_workspace.activeSubWindow() && d_workspace.activeSubWindow()->inherits("Graph3D"))
1845  {
1846  ((Graph3D*)d_workspace.activeSubWindow())->changeDataColumn(table(colName),colName);
1847  emit modified();
1848  }
1849 }
1850 
1852 {
1853  if ( d_workspace.activeSubWindow() && d_workspace.activeSubWindow()->inherits("Graph3D"))
1854  {
1855  Graph3D* g = (Graph3D*)d_workspace.activeSubWindow();
1856 
1857  SurfaceDialog* sd= new SurfaceDialog(this);
1858  sd->setAttribute(Qt::WA_DeleteOnClose);
1859  connect (sd,SIGNAL(options(const QString&,double,double,double,double,double,double)),
1860  g,SLOT(insertFunction(const QString&,double,double,double,double,double,double)));
1861  connect (sd,SIGNAL(clearFunctionsList()),this,SLOT(clearSurfaceFunctionsList()));
1862 
1864  if (g->hasData())
1865  {
1866  sd->setFunction(g->formula());
1867  sd->setLimits(g->xStart(), g->xStop(), g->yStart(),
1868  g->yStop(), g->zStart(), g->zStop());
1869  }
1870  sd->exec();
1871  }
1872 }
1873 
1875 {
1876  SurfaceDialog* sd= new SurfaceDialog(this);
1877  sd->setAttribute(Qt::WA_DeleteOnClose);
1878  connect (sd,SIGNAL(options(const QString&,double,double,double,double,double,double)),
1879  this,SLOT(newPlot3D(const QString&,double,double,double,double,double,double)));
1880  connect (sd,SIGNAL(clearFunctionsList()),this,SLOT(clearSurfaceFunctionsList()));
1881 
1883  sd->exec();
1884 }
1885 
1886 Graph3D* ApplicationWindow::newPlot3D(const QString& formula, double xl, double xr,
1887  double yl, double yr, double zl, double zr)
1888 {
1889  QString label = generateUniqueName(tr("Graph"));
1890 
1891  Graph3D *plot = new Graph3D("",&d_workspace,0);
1892  plot->setAttribute(Qt::WA_DeleteOnClose);
1893  plot->addFunction(formula, xl, xr, yl, yr, zl, zr);
1894  plot->resize(500,400);
1895  plot->setWindowTitle(label);
1896  plot->setName(label);
1897  customPlot3D(plot);
1898  plot->update();
1899 
1900  initPlot3D(plot);
1901 
1902  emit modified();
1903  return plot;
1904 }
1905 
1907 {
1908  surfaceFunc.removeAll(s);
1909  surfaceFunc.push_front(s);
1910  while ((int)surfaceFunc.size() > 10)
1911  surfaceFunc.pop_back();
1912 }
1913 
1914 Graph3D* ApplicationWindow::newPlot3D(const QString& caption,const QString& formula,
1915  double xl, double xr,double yl, double yr,
1916  double zl, double zr)
1917 {
1918  Graph3D *plot = new Graph3D("",&d_workspace,0);
1919  plot->setAttribute(Qt::WA_DeleteOnClose);
1920  plot->addFunction(formula, xl, xr, yl, yr, zl, zr);
1921  plot->update();
1922 
1923  QString label = caption;
1924  while(alreadyUsedName(label))
1925  label = generateUniqueName(tr("Graph"));
1926 
1927  plot->setWindowTitle(label);
1928  plot->setName(label);
1929  initPlot3D(plot);
1930  return plot;
1931 }
1932 
1933 Graph3D* ApplicationWindow::dataPlot3D(Table* table, const QString& colName)
1934 {
1935  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1936 
1937  QString label = generateUniqueName(tr("Graph"));
1938  Graph3D *plot = new Graph3D("", &d_workspace, 0);
1939  plot->setAttribute(Qt::WA_DeleteOnClose);
1940  plot->addData(table, colName);
1941  plot->resize(500,400);
1942  plot->setWindowTitle(label);
1943  plot->setName(label);
1944 
1945  customPlot3D(plot);
1946  plot->update();
1947  initPlot3D(plot);
1948 
1949  emit modified();
1950  QApplication::restoreOverrideCursor();
1951  return plot;
1952 }
1953 
1954 Graph3D* ApplicationWindow::dataPlot3D(const QString& caption,const QString& formula,
1955  double xl, double xr, double yl, double yr, double zl, double zr)
1956 {
1957  int pos=formula.indexOf("_",0);
1958  QString wCaption=formula.left(pos);
1959 
1960  Table* w=table(wCaption);
1961  if (!w)
1962  return 0;
1963 
1964  int posX=formula.indexOf("(",pos);
1965  QString xCol=formula.mid(pos+1,posX-pos-1);
1966 
1967  pos=formula.indexOf(",",posX);
1968  posX=formula.indexOf("(",pos);
1969  QString yCol=formula.mid(pos+1,posX-pos-1);
1970 
1971  Graph3D *plot = new Graph3D("", &d_workspace, 0);
1972  plot->setAttribute(Qt::WA_DeleteOnClose);
1973  plot->addData(w, xCol, yCol, xl, xr, yl, yr, zl, zr);
1974  plot->update();
1975 
1976  QString label=caption;
1977  while(alreadyUsedName(label))
1978  label = generateUniqueName(tr("Graph"));
1979 
1980  plot->setWindowTitle(label);
1981  plot->setName(label);
1982  initPlot3D(plot);
1983 
1984  return plot;
1985 }
1986 
1988 {
1989  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1990 
1991  QString label = generateUniqueName(tr("Graph"));
1992 
1993  Graph3D *plot = new Graph3D("", &d_workspace, 0);
1994  plot->setAttribute(Qt::WA_DeleteOnClose);
1995  plot->resize(500, 400);
1996  plot->setWindowTitle(label);
1997  plot->setName(label);
1998 
1999  customPlot3D(plot);
2000  initPlot3D(plot);
2001 
2002  emit modified();
2003  QApplication::restoreOverrideCursor();
2004  return plot;
2005 }
2006 
2007 Graph3D* ApplicationWindow::dataPlotXYZ(Table* table, const QString& zColName, int type)
2008 {
2009  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2010 
2011  QString label = generateUniqueName(tr("Graph"));
2012  int zCol=table->colIndex(zColName);
2013  int yCol=table->colY(zCol);
2014  int xCol=table->colX(zCol);
2015 
2016  Graph3D *plot=new Graph3D("", &d_workspace,0);
2017  plot->setAttribute(Qt::WA_DeleteOnClose);
2018  plot->addData(table, xCol, yCol, zCol, type);
2019  plot->resize(500,400);
2020  plot->setWindowTitle(label);
2021  plot->setName(label);
2022 
2023  customPlot3D(plot);
2024  plot->update();
2025  initPlot3D(plot);
2026 
2027  emit modified();
2028  QApplication::restoreOverrideCursor();
2029  return plot;
2030 }
2031 
2032 Graph3D* ApplicationWindow::dataPlotXYZ(const QString& caption,const QString& formula,
2033  double xl, double xr, double yl, double yr, double zl, double zr)
2034 {
2035  int pos=formula.indexOf("_",0);
2036  QString wCaption=formula.left(pos);
2037 
2038  Table* w=table(wCaption);
2039  if (!w)
2040  return 0;
2041 
2042  int posX=formula.indexOf("(X)",pos);
2043  QString xColName=formula.mid(pos+1,posX-pos-1);
2044 
2045  pos=formula.indexOf(",",posX);
2046 
2047  posX=formula.indexOf("(Y)",pos);
2048  QString yColName=formula.mid(pos+1,posX-pos-1);
2049 
2050  pos=formula.indexOf(",",posX);
2051  posX=formula.indexOf("(Z)",pos);
2052  QString zColName=formula.mid(pos+1,posX-pos-1);
2053 
2054  int xCol=w->colIndex(xColName);
2055  int yCol=w->colIndex(yColName);
2056  int zCol=w->colIndex(zColName);
2057 
2058  Graph3D *plot=new Graph3D("", &d_workspace, 0);
2059  plot->setAttribute(Qt::WA_DeleteOnClose);
2060  plot->addData(w, xCol, yCol, zCol, xl, xr, yl, yr, zl, zr);
2061  plot->update();
2062 
2063  QString label = caption;
2064  if(alreadyUsedName(label))
2065  label = generateUniqueName(tr("Graph"));
2066 
2067  plot->setWindowTitle(label);
2068  plot->setName(label);
2069  initPlot3D(plot);
2070  return plot;
2071 }
2072 
2074 {
2075  plot->setDataColors(QColor(COLORVALUE(plot3DColors[4])), QColor(COLORVALUE(plot3DColors[0])));
2076  plot->updateColors(QColor(COLORVALUE(plot3DColors[2])), QColor(COLORVALUE(plot3DColors[6])),
2077  QColor(COLORVALUE(plot3DColors[5])), QColor(COLORVALUE(plot3DColors[1])),
2078  QColor(COLORVALUE(plot3DColors[7])), QColor(COLORVALUE(plot3DColors[3])));
2079 
2082  plot->setSmoothMesh(smooth3DMesh);
2083  plot->setOrtho(orthogonal3DPlots);
2085  plot->setFloorData();
2086 
2092 }
2093 
2095 {
2096  d_workspace.addSubWindow(plot);
2097  current_folder->addWindow(plot);
2098  plot->setFolder(current_folder);
2099  connectSurfacePlot(plot);
2100 
2101  plot->setWindowIcon(QPixmap(":/trajectory.xpm"));
2102  plot->show();
2103  plot->setFocus();
2104 
2105  addListViewItem(plot);
2106 
2107  if (!graph_3D_tools->isEnabled())
2108  graph_3D_tools->setEnabled(true);
2109 
2110  customMenu(plot);
2111  customToolBars(plot);
2112 }
2113 
2115 {
2116  QList<QByteArray> list = QImageReader::supportedImageFormats();
2117  QString filter = tr("Images") + " (", aux1, aux2;
2118  for (int i=0; i<(int)list.count(); i++){
2119  aux1 = " *."+list[i]+" ";
2120  aux2 += " *."+list[i]+";;";
2121  filter += aux1;
2122  }
2123  filter+=");;" + aux2;
2124 
2125  QString fn = QFileDialog::getOpenFileName(this, tr("Import image from file"), imagesDirPath, filter);
2126  if ( !fn.isEmpty() ){
2127  QFileInfo fi(fn);
2128  imagesDirPath = fi.absolutePath();
2129  return importImage(fn);
2130  }
2131  else return 0;
2132 }
2133 
2135 {
2136  QList<QByteArray> list = QImageReader::supportedImageFormats();
2137  QString filter = tr("Images") + " (", aux1, aux2;
2138  for (int i=0; i<(int)list.count(); i++){
2139  aux1 = " *."+list[i]+" ";
2140  aux2 += " *."+list[i]+";;";
2141  filter += aux1;
2142  }
2143  filter+=");;" + aux2;
2144 
2145  QString fn = QFileDialog::getOpenFileName(this, tr("Load image from file"), imagesDirPath, filter);
2146  if ( !fn.isEmpty() ){
2147  loadImage(fn);
2148  QFileInfo fi(fn);
2149  imagesDirPath = fi.absolutePath();
2150  }
2151 }
2152 
2153 void ApplicationWindow::loadImage(const QString& fn)
2154 {
2155  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2156 
2157  MultiLayer *plot = multilayerPlot(generateUniqueName(tr("Graph")));
2158  plot->setWindowLabel(fn);
2160  setListViewLabel(plot->name(), fn);
2161 
2162  plot->showNormal();
2163  Graph *g = plot->addLayer(0, 0, plot->width(), plot->height());
2164 
2165  g->setTitle("");
2166  QVector<bool> axesOn(4);
2167  for (int j=0;j<4;j++)
2168  axesOn[j]=false;
2169  g->enableAxes(axesOn);
2170  g->removeLegend();
2171  g->setIgnoreResizeEvents(false);
2172  g->addImage(fn);
2173  QApplication::restoreOverrideCursor();
2174 }
2175 
2177 {
2178  if (style == Graph::VerticalBars || style == Graph::HorizontalBars ||style == Graph::Histogram)
2179  {
2180  QList<int> ticksList;
2181  int ticksStyle = ScaleDraw::Out;
2182  ticksList<<ticksStyle<<ticksStyle<<ticksStyle<<ticksStyle;
2183  g->setMajorTicksType(ticksList);
2184  g->setMinorTicksType(ticksList);
2185  }
2186  if (style == Graph::HorizontalBars)
2187  {
2188  g->setAxisTitle(0, tr("Y Axis Title"));
2189  g->setAxisTitle(1, tr("X Axis Title"));
2190  }
2191 }
2192 
2194 {
2195  MultiLayer* ml = new MultiLayer("", &d_workspace, 0);
2196  ml->setAttribute(Qt::WA_DeleteOnClose);
2197  QString label = caption;
2198  initMultilayerPlot(ml, label.replace(QRegExp("_"),"-"));
2199  return ml;
2200 }
2201 
2202 MultiLayer* ApplicationWindow::newGraph(const QString& caption)
2203 {
2205  if (ml)
2206  {
2207  Graph *g = ml->addLayer();
2208  setPreferences(g);
2209  g->newLegend();
2210  g->setAutoscaleFonts(false);
2211  g->setIgnoreResizeEvents(false);
2212  ml->arrangeLayers(false, false);
2213  g->setAutoscaleFonts(autoScaleFonts);//restore user defined fonts behaviour
2215  customMenu(ml);
2216  }
2217  return ml;
2218 }
2219 
2220 MultiLayer* ApplicationWindow::multilayerPlot(Table* w, const QStringList& colList, int style, int startRow, int endRow)
2221 {//used when plotting selected columns
2222  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2223 
2224  MultiLayer* g = new MultiLayer("", &d_workspace, 0);
2225  g->setAttribute(Qt::WA_DeleteOnClose);
2226 
2227  initMultilayerPlot(g, generateUniqueName(tr("Graph")));
2228 
2229  Graph *ag = g->addLayer();
2230  if (!ag)
2231  return 0;
2232 
2233  setPreferences(ag);
2234  ag->insertCurvesList(w, colList, style, defaultCurveLineWidth, defaultSymbolSize, startRow, endRow);
2235 
2236  polishGraph(ag, style);
2237  ag->newLegend();
2238  g->arrangeLayers(false, false);
2239  customMenu(g);
2240 
2241  emit modified();
2242  QApplication::restoreOverrideCursor();
2243  return g;
2244 }
2245 
2247 {//used when plotting from the panel menu
2248  if (!d_workspace.activeSubWindow() || !d_workspace.activeSubWindow()->inherits("Table"))
2249  return 0;
2250 
2251  Table* w = (Table*)d_workspace.activeSubWindow();
2252  if (!validFor2DPlot(w, style))
2253  return 0;
2254 
2255  QStringList list;
2256  switch (style) {
2257  case Graph::Histogram:
2258  case Graph::Pie:
2259  case Graph::Box:
2260  list = w->selectedColumns();
2261  break;
2262  default:
2263  list = w->selectedYColumns();
2264  break;
2265  }
2266 
2267  int curves = (int)list.count();
2268  if (r<0)
2269  r = curves;
2270 
2271  MultiLayer* g = new MultiLayer("", &d_workspace, 0);
2272  g->setAttribute(Qt::WA_DeleteOnClose);
2273 
2274  initMultilayerPlot(g, generateUniqueName(tr("Graph")));
2275 
2276  int layers = c*r;
2277  if (curves<layers)
2278  {
2279  for (int i=0; i<curves; i++)
2280  {
2281  Graph *ag = g->addLayer();
2282  if (ag)
2283  {
2284  setPreferences(ag);
2285  ag->insertCurvesList(w, QStringList(list[i]), style, defaultCurveLineWidth, defaultSymbolSize);
2286  ag->newLegend();
2287  ag->setAutoscaleFonts(false);//in order to avoid to small fonts
2288  ag->setIgnoreResizeEvents(false);
2289  polishGraph(ag, style);
2290  }
2291  }
2292  }
2293  else
2294  {
2295  for (int i=0; i<layers; i++)
2296  {
2297  Graph *ag = g->addLayer();
2298  if (ag)
2299  {
2300  QStringList lst;
2301  lst << list[i];
2302  setPreferences(ag);
2304  ag->newLegend();
2305  ag->setAutoscaleFonts(false);//in order to avoid to small fonts
2306  ag->setIgnoreResizeEvents(false);
2307  polishGraph(ag, style);
2308  }
2309  }
2310  }
2311  g->setRows(r);
2312  g->setCols(c);
2313  g->arrangeLayers(false, false);
2314  QWidgetList lst = g->graphPtrs();
2315  foreach(QWidget *widget, lst)
2316  {
2317  Graph *ag = (Graph *)widget;
2318  ag->setAutoscaleFonts(autoScaleFonts);//restore user defined fonts behaviour
2320  }
2321  customMenu(g);
2322  emit modified();
2323  return g;
2324 }
2325 
2326 MultiLayer* ApplicationWindow::multilayerPlot(const QStringList& colList)
2327 {//used when plotting from wizard
2328  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2329  MultiLayer* g = new MultiLayer("", &d_workspace, 0);
2330  g->setAttribute(Qt::WA_DeleteOnClose);
2331 
2332  initMultilayerPlot(g, generateUniqueName(tr("Graph")));
2333 
2334  Graph *ag = g->addLayer();
2335  setPreferences(ag);
2337  int curves = (int)colList.count();
2338  int errorBars = 0;
2339  for (int i=0; i<curves; i++)
2340  {
2341  if (colList[i].contains("(yErr)") || colList[i].contains("(xErr)"))
2342  errorBars++;
2343  }
2344 
2345  for (int i=0; i<curves; i++)
2346  {
2347  QString s = colList[i];
2348  int pos = s.indexOf(":", 0);
2349  QString caption = s.left(pos) + "_";
2350  Table *w = (Table *)table(caption);
2351 
2352  int posX = s.indexOf("(X)", pos);
2353  QString xColName = caption+s.mid(pos+2, posX-pos-2);
2354  int xCol=w->colIndex(xColName);
2355 
2356  posX = s.indexOf(",", posX);
2357  int posY = s.indexOf("(Y)", posX);
2358  QString yColName = caption+s.mid(posX+2, posY-posX-2);
2359 
2360  if (s.contains("(yErr)") || s.contains("(xErr)"))
2361  {
2362  posY = s.indexOf(",", posY);
2363  int posErr, errType;
2364  if (s.contains("(yErr)"))
2365  {
2366  errType = QwtErrorPlotCurve::Vertical;
2367  posErr = s.indexOf("(yErr)", posY);
2368  }
2369  else
2370  {
2372  posErr = s.indexOf("(xErr)",posY);
2373  }
2374 
2375  QString errColName = caption+s.mid(posY+2, posErr-posY-2);
2376  ag->addErrorBars(xColName, yColName, w, errColName, errType);
2377  }
2378  else
2379  ag->insertCurve(w, xCol, yColName, defaultCurveStyle);
2380 
2381  CurveLayout cl = ag->initCurveLayout(defaultCurveStyle, curves - errorBars);
2383  cl.sSize = defaultSymbolSize;
2384  ag->updateCurveLayout(i, &cl);
2385  }
2386  ag->newLegend();
2387  ag->updatePlot();
2388  g->arrangeLayers(true, false);
2389  customMenu(g);
2390  emit modified();
2391  QApplication::restoreOverrideCursor();
2392  return g;
2393 }
2394 
2396 { // FIXME: workaround, init without unnecessary g->show()
2397  QString label = name;
2398  while(alreadyUsedName(label))
2399  label = generateUniqueName(tr("Graph"));
2400 
2402 
2403  g->setWindowTitle(label);
2404  g->setName(label);
2405  g->setWindowIcon(QPixmap(":/graph.xpm"));
2408 
2409  d_workspace.addSubWindow(g);
2412  addListViewItem(g);
2413 }
2414 
2416 {
2418  g->show(); // FIXME: bad idea do it here
2419  g->setFocus();
2420 }
2421 
2422 void ApplicationWindow::customizeTables(const QColor& bgColor,const QColor& textColor,
2423  const QColor& headerColor,const QFont& textFont, const QFont& headerFont, bool showComments)
2424 {
2425  tableBkgdColor = bgColor;
2426  tableTextColor = textColor;
2427  tableHeaderColor = headerColor;
2428  tableTextFont = textFont;
2429  tableHeaderFont = headerFont;
2430  d_show_table_comments = showComments;
2431 
2432  QList<MyWidget*> windows = windowsList();
2433  foreach(MyWidget *w, windows)
2434  {
2435  if (w->inherits("Table"))
2436  customTable((Table*)w);
2437  }
2438 }
2439 
2441 {
2442  QPalette cg;
2443  cg.setColor(QPalette::Base, QColor(tableBkgdColor));
2444  cg.setColor(QPalette::Text, QColor(tableTextColor));
2445  w->setPalette(cg);
2446 
2451 }
2452 
2454 {
2455  if (!g->isPiePlot()){
2456  if (allAxesOn){
2457  QVector<bool> axesOn(QwtPlot::axisCnt);
2458  axesOn.fill(true);
2459  g->enableAxes(axesOn);
2460  g->updateSecondaryAxis(QwtPlot::xTop);
2461  g->updateSecondaryAxis(QwtPlot::yRight);
2462  }
2463 
2464  QList<int> ticksList;
2466  g->setMajorTicksType(ticksList);
2467  ticksList.clear();
2469  g->setMinorTicksType(ticksList);
2470 
2474  }
2475 
2482  g->plotWidget()->setMargin(defaultPlotMargin);
2487 }
2488 
2489 void ApplicationWindow::newWrksheetPlot(const QString& name,const QString& label, QList<Column *> columns)
2490 {
2491  Table* w = newTable(name, label, columns);
2492  MultiLayer* plot=multilayerPlot(w, QStringList(QString(w->name())+"_intensity"), 0);
2493  Graph *g=(Graph*)plot->activeGraph();
2494  if (g)
2495  {
2496  g->setTitle("");
2497  g->setXAxisTitle(tr("pixels"));
2498  g->setYAxisTitle(tr("pixel intensity (a.u.)"));
2499  }
2500 }
2501 
2502 /*
2503  *used when importing an ASCII file
2504  */
2505 Table* ApplicationWindow::newTable(const QString& fname, const QString &sep,
2506  int lines, bool renameCols, bool stripSpaces,
2507  bool simplifySpaces, bool convertToNumeric, QLocale numericLocale)
2508 {
2509  Table* w = new Table(scriptEnv, fname, sep, lines, renameCols, stripSpaces,
2510  simplifySpaces, convertToNumeric, numericLocale, fname, &d_workspace, 0, 0);
2511  if (w)
2512  {
2513  w->setName(generateUniqueName(tr("Table")));
2515  }
2516  return w;
2517 }
2518 
2519 /*
2520  *creates a new empty table
2521  */
2523 {
2524  Table* w = new Table(scriptEnv, 30, 2, "", &d_workspace, 0);
2525  w->setName(generateUniqueName(tr("Table")));
2527  return w;
2528 }
2529 
2530 /*
2531  *used when opening a project file
2532  */
2533 Table* ApplicationWindow::newTable(const QString& caption, int r, int c)
2534 {
2535  Table* w = new Table(scriptEnv, r, c, "", &d_workspace, 0);
2536  w->setName(caption);
2538  if (w->name() != caption)//the table was renamed
2539  {
2540  renamedTables << caption << w->name();
2541 
2542  QMessageBox:: warning(this, tr("Renamed Window"),
2543  tr("The table '%1' already exists. It has been renamed '%2'.").arg(caption).arg(w->name()));
2544  }
2545  return w;
2546 }
2547 
2548 Table* ApplicationWindow::newTable(int r, int c, const QString& name, const QString& legend)
2549 {
2550  Table* w = new Table(scriptEnv, r, c, legend, &d_workspace, 0);
2551  w->setName(name);
2553  return w;
2554 }
2555 
2556 Table* ApplicationWindow::newTable(const QString& name, const QString& legend, QList<Column *> columns)
2557 {
2558  Table* w = new Table(scriptEnv, 0, 0, legend, &d_workspace, 0);
2559  w->d_future_table->appendColumns(columns);
2560  w->setName(name);
2562  return w;
2563 }
2564 
2565 Table* ApplicationWindow::newHiddenTable(const QString& name, const QString& label, QList<Column *> columns)
2566 {
2567  auto w=newTable(name,label,columns);
2568  hideWindow(w);
2569  return w;
2570 }
2571 
2573 {
2574  d_workspace.addSubWindow(w);
2575  w->setWindowIcon( QPixmap(":/worksheet.xpm") );
2578  addListViewItem(w);
2579  w->showNormal();
2580 
2581  connectTable(w);
2582  customTable(w);
2583 
2584  w->d_future_table->setPlotMenu(plot2D);
2585 
2586  emit modified();
2587 }
2588 
2589 /*
2590  * !creates a new table with type statistics on target columns/rows of table base
2591  */
2592 TableStatistics *ApplicationWindow::newTableStatistics(Table *base, int type, QList<int> target, const QString &caption)
2593 {
2595  if (!caption.isEmpty())
2596  s->setName(caption);
2597 
2599  connect(base, SIGNAL(modifiedData(Table*,const QString&)), s, SLOT(update(Table*,const QString&)));
2600  connect(base, SIGNAL(changedColHeader(const QString&, const QString&)), s, SLOT(renameCol(const QString&, const QString&)));
2601  connect(base, SIGNAL(removedCol(const QString&)), s, SLOT(removeCol(const QString&)));
2602  connect(base->d_future_table, SIGNAL(aspectAboutToBeRemoved(const AbstractAspect *)),
2603  this, SLOT(removeDependentTableStatistics(const AbstractAspect *)));
2604  return s;
2605 }
2606 
2608 {
2609  ::future::Table *future_table = qobject_cast<::future::Table *>(const_cast<AbstractAspect *>(aspect));
2610  if (!future_table) return;
2611  QList<MyWidget*> windows = windowsList();
2612  foreach(MyWidget *win, windows)
2613  {
2614  TableStatistics *table_stat = qobject_cast<TableStatistics *>(win);
2615  if (!table_stat) continue;
2616  Table *table = qobject_cast<Table *>(future_table->view());
2617  if (!table) continue;
2618  if (table_stat->base() == table)
2619  d_project->removeChild(table_stat->d_future_table);
2620  }
2621 }
2622 
2623 /*
2624  *creates a new empty note window
2625  */
2626 Note* ApplicationWindow::newNote(const QString& caption)
2627 {
2628  Note* m = new Note(scriptEnv, "", &d_workspace);
2629  if (caption.isEmpty())
2630  initNote(m, generateUniqueName(tr("Notes")));
2631  else
2632  initNote(m, caption);
2633  m->showNormal();
2634  return m;
2635 }
2636 
2637 void ApplicationWindow::initNote(Note* m, const QString& caption)
2638 {
2639  QString name=caption;
2640  while(name.isEmpty() || alreadyUsedName(name))
2641  name = generateUniqueName(tr("Notes"));
2642 
2643  d_workspace.addSubWindow(m);
2644  m->setWindowTitle(name);
2645  m->setName(name);
2646  m->setWindowIcon( QPixmap(":/note.xpm") );
2649 
2651  addListViewItem(m);
2652 
2653  connect(m, SIGNAL(modifiedWindow(MyWidget*)), this, SLOT(modifiedProject(MyWidget*)));
2654  connect(m, SIGNAL(closedWindow(MyWidget*)), this, SLOT(closeWindow(MyWidget*)));
2655  connect(m, SIGNAL(hiddenWindow(MyWidget*)), this, SLOT(hideWindow(MyWidget*)));
2656  connect(m, SIGNAL(statusChanged(MyWidget*)), this, SLOT(updateWindowStatus(MyWidget*)));
2657  connect(m, SIGNAL(showTitleBarMenu()), this, SLOT(showWindowTitleBarMenu()));
2658 
2659  emit modified();
2660 }
2661 
2662 Matrix* ApplicationWindow::newMatrix(int rows, int columns)
2663 {
2664  Matrix* m = new Matrix(scriptEnv, rows, columns, "", 0, 0);
2665  QString caption = generateUniqueName(tr("Matrix"));
2666  while(alreadyUsedName(caption)) { caption = generateUniqueName(tr("Matrix")); }
2667  m->setName(caption);
2669  return m;
2670 }
2671 
2672 Matrix* ApplicationWindow::newMatrix(const QString& caption, int r, int c)
2673 {
2674  Matrix* w = new Matrix(scriptEnv, r, c, "", 0 ,0);
2675  QString name = caption;
2676  while(alreadyUsedName(name)) {name = generateUniqueName(caption); }
2677  w->setName(name);
2679  if (w->name() != caption)//the matrix was renamed
2680  renamedTables << caption << w->name();
2681 
2682  return w;
2683 }
2684 
2686 {
2687  Matrix* m = (Matrix*)d_workspace.activeSubWindow();
2688  if (!m)
2689  return;
2690 
2691  QDateTime dt = QDateTime::currentDateTime ();
2692  QString info=dt.toString(Qt::LocalDate);
2693  info+= "\n" + tr("Determinant of ") + QString(m->name()) + ":\t";
2694  info+= "det = " + QString::number(m->determinant()) + "\n";
2695  info+="-------------------------------------------------------------\n";
2696 
2697  logInfo+=info;
2698 
2699  showResults(true);
2700 }
2701 
2703 {
2704  Matrix* m = (Matrix*)d_workspace.activeSubWindow();
2705  if (!m)
2706  return;
2707 
2708  m->invert();
2709 }
2710 
2712 {
2713  Matrix* m = (Matrix*)d_workspace.activeSubWindow();
2714  if (!m)
2715  return 0;
2716 
2717  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2718 
2719  int rows = m->numRows();
2720  int cols = m->numCols();
2721 
2722  Table* w = new Table(scriptEnv, rows, cols, "", &d_workspace, 0);
2723  for (int i = 0; i<rows; i++)
2724  {
2725  for (int j = 0; j<cols; j++)
2726  w->setCell(i, j, m->cell(i,j));
2727  }
2728 
2729  w->setName(generateUniqueName(tr("Table")));
2731  w->setWindowLabel(m->windowLabel());
2733  w->resize(m->size());
2734  w->showNormal();
2735 
2736  QApplication::restoreOverrideCursor();
2737 
2738  return w;
2739 }
2740 
2742 {
2743  d_workspace.addSubWindow(m);
2744  m->setWindowIcon( QPixmap(":/matrix.xpm") );
2748 
2751  addListViewItem(m);
2752  m->showNormal();
2753 
2754  connect(m, SIGNAL(showTitleBarMenu()),this,SLOT(showWindowTitleBarMenu()));
2755  connect(m, SIGNAL(modifiedWindow(MyWidget*)), this, SLOT(modifiedProject(MyWidget*)));
2756  connect(m, SIGNAL(modifiedWindow(MyWidget*)), this, SLOT(updateMatrixPlots(MyWidget *)));
2757  connect(m, SIGNAL(hiddenWindow(MyWidget*)), this, SLOT(hideWindow(MyWidget*)));
2758  connect(m, SIGNAL(statusChanged(MyWidget*)),this, SLOT(updateWindowStatus(MyWidget*)));
2759  connect(m, SIGNAL(showContextMenu()), this, SLOT(showWindowContextMenu()));
2760  emit modified();
2761 }
2762 
2764 {
2765  Table* m = (Table*)d_workspace.activeSubWindow();
2766  if (!m)
2767  return 0;
2768 
2769  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2770 
2771  int rows = m->numRows();
2772  int cols = m->numCols();
2773 
2774  Matrix* w = new Matrix(scriptEnv, rows, cols, "", 0, 0);
2775  for (int i = 0; i<rows; i++)
2776  {
2777  for (int j = 0; j<cols; j++)
2778  w->setText(i, j, m->text(i,j));
2779  }
2780 
2781  QString caption = generateUniqueName(m->name());
2782  w->setName(caption);
2784 
2786  w->resize(m->size());
2787  w->showNormal();
2788 
2789  QApplication::restoreOverrideCursor();
2790  return w;
2791 }
2792 
2794 {
2795  MyWidget* widget = 0;
2796  QList<MyWidget*> windows = windowsList();
2797  for (int i = 0; i < windows.count();i++ )
2798  {
2799  widget = windows.at(i);
2800  if (widget && widget->name() == name)
2801  return widget;
2802  }
2803  return widget;
2804 }
2805 
2807 {
2808  int pos = name.indexOf("_", 0);
2809  QString caption = name.left(pos);
2810 
2811  QList<MyWidget*> lst = windowsList();
2812  foreach(MyWidget *w, lst)
2813  {
2814  if (w->inherits("Table") && static_cast<Table *>(w)->name() == caption)
2815  {
2816  return (Table*)w;
2817  }
2818  }
2819  return 0;
2820 }
2821 
2823 {
2824  QString caption = name;
2825  if (!renamedTables.isEmpty() && renamedTables.contains(caption))
2826  {
2827  int index = renamedTables.indexOf(caption);
2828  caption = renamedTables[index+1];
2829  }
2830 
2831  QList<MyWidget*> lst = windowsList();
2832  foreach(MyWidget *w, lst)
2833  {
2834  if (w->inherits("Matrix") && static_cast<Matrix *>(w)->name() == caption)
2835  {
2836  return (Matrix*)w;
2837  }
2838  }
2839  return 0;
2840 }
2841 
2843 {
2844  if (!w || !w->inherits("MyWidget"))
2845  return;
2846 
2847  customToolBars((MyWidget*)w);
2848  customMenu((MyWidget*)w);
2849 
2850  Folder *f = ((MyWidget *)w)->folder();
2851  if (f)
2852  f->setActiveWindow((MyWidget *)w);
2853 }
2854 
2856 {
2857  if (!d_workspace.activeSubWindow() || !d_workspace.activeSubWindow()->inherits("MultiLayer"))
2858  return;
2859 
2860  MultiLayer* plot = (MultiLayer*)d_workspace.activeSubWindow();
2861  if (plot->isEmpty())
2862  {
2863  QMessageBox::warning(this,tr("Warning"),
2864  tr("<h4>There are no plot layers available in this window.</h4>"
2865  "<p><h4>Please add a layer and try again!</h4>"));
2866  return;
2867  }
2868 
2869  Graph* g = (Graph*)plot->activeGraph();
2870  if (!g)
2871  return;
2872 
2873  if (!g->curves())
2874  {
2875  QMessageBox::warning(this, tr("Warning"), tr("There are no curves available on this plot!"));
2876  return;
2877  }
2878 
2879  if (g->isPiePlot())
2880  {
2881  QMessageBox::warning(this, tr("Warning"), tr("This functionality is not available for pie plots!"));
2882  return;
2883  }
2884 
2885  ErrDialog* ed = new ErrDialog(this);
2886  ed->setAttribute(Qt::WA_DeleteOnClose);
2887  connect (ed,SIGNAL(options(const QString&,int,const QString&,int)),this,SLOT(defineErrorBars(const QString&,int,const QString&,int)));
2888  connect (ed,SIGNAL(options(const QString&,const QString&,int)),this,SLOT(defineErrorBars(const QString&,const QString&,int)));
2889 
2891  ed->setSrcTables(tableList());
2892  ed->exec();
2893 }
2894 
2895 void ApplicationWindow::defineErrorBars(const QString& name, int type, const QString& percent, int direction)
2896 {
2897  if (!d_workspace.activeSubWindow() || !d_workspace.activeSubWindow()->inherits("MultiLayer"))
2898  return;
2899 
2900  Graph* g = ((MultiLayer*)d_workspace.activeSubWindow())->activeGraph();
2901  if (!g)
2902  return;
2903 
2904  Table *w = table(name);
2905  if (!w)
2906  { //user defined function
2907  QMessageBox::critical(this,tr("Error bars error"),
2908  tr("This feature is not available for user defined function curves!"));
2909  return;
2910  }
2911 
2912  DataCurve *master_curve = (DataCurve *)g->curve(name);
2913  QString xColName = master_curve->xColumnName();
2914  if (xColName.isEmpty())
2915  return;
2916 
2917  Column * errors = new Column("1", SciDAVis::Numeric);
2918  Column * data;
2919  if (direction == QwtErrorPlotCurve::Horizontal) {
2921  data = w->d_future_table->column(xColName);
2922  } else {
2924  data = w->d_future_table->column(name);
2925  }
2926  if (!data) return;
2927 
2928  int rows = data->rowCount();
2929  if (type==0) {
2930  double fraction = percent.toDouble()/100.0;
2931  for (int i=0; i<rows; i++)
2932  errors->setValueAt(i, data->valueAt(i)*fraction);
2933  } else if (type==1) {
2934  double average=0.0;
2935  double dev=0.0;
2936  for (int i=0; i<rows; i++)
2937  average += data->valueAt(i);
2938  average /= rows;
2939  for (int i=0; i<rows; i++)
2940  dev += pow(data->valueAt(i)-average, 2);
2941  dev = sqrt(dev/rows);
2942  for (int i=0; i<rows; i++)
2943  errors->setValueAt(i, dev);
2944  }
2945  w->d_future_table->addChild(errors);
2946  g->addErrorBars(xColName, name, w, errors->name(), direction);
2947 }
2948 
2949 void ApplicationWindow::defineErrorBars(const QString& curveName, const QString& errColumnName, int direction)
2950 {
2951  Table *w=table(curveName);
2952  if (!w)
2953  {//user defined function --> no worksheet available
2954  QMessageBox::critical(this,tr("Error"),
2955  tr("This feature is not available for user defined function curves!"));
2956  return;
2957  }
2958 
2959  Table *errTable=table(errColumnName);
2960  if (w->numRows() != errTable->numRows())
2961  {
2962  QMessageBox::critical(this,tr("Error"),
2963  tr("The selected columns have different numbers of rows!"));
2964 
2965  addErrorBars();
2966  return;
2967  }
2968 
2969  int errCol=errTable->colIndex(errColumnName);
2970  if (errTable->d_future_table->column(errCol)->dataType() != SciDAVis::TypeDouble)
2971  {
2972  QMessageBox::critical(this,tr("Error"),
2973  tr("You can only define error bars for numeric columns."));
2974  addErrorBars();
2975  return;
2976  }
2977 
2978  if (!d_workspace.activeSubWindow() || !d_workspace.activeSubWindow()->inherits("MultiLayer"))
2979  return;
2980 
2981  Graph* g = ((MultiLayer*)d_workspace.activeSubWindow())->activeGraph();
2982  if (!g)
2983  return;
2984 
2985  g->addErrorBars(curveName, errTable, errColumnName, direction);
2986  emit modified();
2987 }
2988 
2990 {
2991  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2992 
2993  QList<MyWidget*> windows = windowsList();
2994  foreach(MyWidget *w, windows)
2995  {
2996  if (w->inherits("MultiLayer"))
2997  {
2998  QWidgetList lst= ((MultiLayer*)w)->graphPtrs();
2999  foreach(QWidget *widget, lst)
3000  ((Graph *)widget)->removeCurves(name);
3001  }
3002  else if (w->inherits("Graph3D"))
3003  {
3004  if ( (((Graph3D*)w)->formula()).contains(name) )
3005  ((Graph3D*)w)->clearData();
3006  }
3007  }
3008  QApplication::restoreOverrideCursor();
3009 }
3010 
3012 {
3013  QList<MyWidget*> windows = windowsList();
3014  foreach(MyWidget *w, windows)
3015  {
3016  if (w->inherits("MultiLayer"))
3017  {
3018  QWidgetList graphsList = ((MultiLayer*)w)->graphPtrs();
3019  for (int k=0; k<(int)graphsList.count(); k++)
3020  {
3021  Graph* g=(Graph*)graphsList.at(k);
3022  if (g)
3023  g->updateCurvesData(t, name);
3024  }
3025  }
3026  else if (w->inherits("Graph3D"))
3027  {
3028  Graph3D* g = (Graph3D*)w;
3029  if ((g->formula()).contains(name))
3030  g->updateData(t);
3031  }
3032  }
3033 }
3034 
3036 {
3037  ConfigDialog* cd= new ConfigDialog(this);
3038  cd->setAttribute(Qt::WA_DeleteOnClose);
3040  cd->exec();
3041 }
3042 
3043 void ApplicationWindow::setSaveSettings(bool autoSaving, int min)
3044 {
3045  if (autoSave==autoSaving && autoSaveTime==min)
3046  return;
3047 
3048  autoSave=autoSaving;
3049  autoSaveTime=min;
3050 
3051  killTimer(savingTimerId);
3052 
3053  if (autoSave)
3054  savingTimerId=startTimer(autoSaveTime*60000);
3055  else
3056  savingTimerId=0;
3057 }
3058 
3060 {
3061  // style keys are case insensitive
3062  if (appStyle.toLower() == s.toLower())
3063  return;
3064 
3065  qApp->setStyle(s);
3066  appStyle = qApp->style()->objectName();
3067 
3068  QPalette pal = qApp->palette();
3069  pal.setColor (QPalette::Active, QPalette::Base, QColor(panelsColor));
3070  qApp->setPalette(pal);
3071 
3072 }
3073 
3075 {
3076  if (appFont == f)
3077  return;
3078 
3079  appFont=f;
3080  updateAppFonts();
3081 }
3082 
3084 {
3085  qApp->setFont (appFont);
3086  this->setFont(appFont);
3087  scriptingMenu->setFont(appFont);
3088  windowsMenu->setFont(appFont);
3089  view->setFont(appFont);
3090  graph->setFont(appFont);
3091  file->setFont(appFont);
3092  format->setFont(appFont);
3093  calcul->setFont(appFont);
3094  edit->setFont(appFont);
3095  dataMenu->setFont(appFont);
3096  recent->setFont(appFont);
3097  help->setFont(appFont);
3098  type->setFont(appFont);
3099  plot2D->setFont(appFont);
3100  plot3D->setFont(appFont);
3101  plot3DMenu->setFont(appFont);
3102  matrixMenu->setFont(appFont);
3103  specialPlot->setFont(appFont);
3104  panels->setFont(appFont);
3105  stat->setFont(appFont);
3106  smooth->setFont(appFont);
3107  filter->setFont(appFont);
3108  decay->setFont(appFont);
3109  plotDataMenu->setFont(appFont);
3110  tableMenu->setFont(appFont);
3111  exportPlot->setFont(appFont);
3112  translateMenu->setFont(appFont);
3113  multiPeakMenu->setFont(appFont);
3114 }
3115 
3116 void ApplicationWindow::updateConfirmOptions(bool askTables, bool askMatrices, bool askPlots2D,
3117  bool askPlots3D, bool askNotes)
3118 {
3119  QList<MyWidget*> windows = windowsList();
3120  if (confirmCloseTable != askTables)
3121  {
3122  confirmCloseTable=askTables;
3123  for (int i = 0; i < int(windows.count());i++ )
3124  {
3125  if (windows.at(i)->inherits("Table"))
3126  ((MyWidget*)windows.at(i))->askOnCloseEvent(confirmCloseTable);
3127  }
3128  }
3129 
3130  if (confirmCloseMatrix != askMatrices)
3131  {
3132  confirmCloseMatrix = askMatrices;
3133  for (int i = 0; i < int(windows.count());i++ )
3134  {
3135  if (windows.at(i)->inherits("Matrix"))
3136  ((MyWidget*)windows.at(i))->askOnCloseEvent(confirmCloseMatrix);
3137  }
3138  }
3139 
3140  if (confirmClosePlot2D != askPlots2D)
3141  {
3142  confirmClosePlot2D=askPlots2D;
3143  for (int i = 0; i < int(windows.count());i++ )
3144  {
3145  if (windows.at(i)->inherits("MultiLayer"))
3146  ((MyWidget*)windows.at(i))->askOnCloseEvent(confirmClosePlot2D);
3147  }
3148  }
3149 
3150  if (confirmClosePlot3D != askPlots3D)
3151  {
3152  confirmClosePlot3D=askPlots3D;
3153  for (int i = 0; i < int(windows.count());i++ )
3154  {
3155  if (windows.at(i)->inherits("Graph3D"))
3156  ((MyWidget*)windows.at(i))->askOnCloseEvent(confirmClosePlot3D);
3157  }
3158  }
3159 
3160  if (confirmCloseNotes != askNotes)
3161  {
3162  confirmCloseNotes = askNotes;
3163  for (int i = 0; i < int(windows.count());i++ )
3164  {
3165  if (windows.at(i)->inherits("Note"))
3166  ((MyWidget*)windows.at(i))->askOnCloseEvent(confirmCloseNotes);
3167  }
3168  }
3169 
3170 }
3171 
3172 void ApplicationWindow::setGraphDefaultSettings(bool autoscale, bool scaleFonts,
3173  bool resizeLayers, bool antialiasing)
3174 {
3175  if (autoscale2DPlots == autoscale &&
3176  autoScaleFonts == scaleFonts &&
3177  autoResizeLayers != resizeLayers &&
3178  antialiasing2DPlots == antialiasing)
3179  return;
3180 
3181  autoscale2DPlots = autoscale;
3182  autoScaleFonts = scaleFonts;
3183  autoResizeLayers = !resizeLayers;
3184  antialiasing2DPlots = antialiasing;
3185 
3186  QList<MyWidget*> windows = windowsList();
3187  foreach(MyWidget *w, windows)
3188  {
3189  if (w->inherits("MultiLayer"))
3190  {
3191  QWidgetList lst = ((MultiLayer*)w)->graphPtrs();
3192  Graph *g;
3193  foreach(QWidget *widget, lst)
3194  {
3195  g = (Graph *)widget;
3197  g->updateScale();
3201  }
3202  }
3203  }
3204 }
3205 
3206 void ApplicationWindow::setLegendDefaultSettings(int frame, const QFont& font,
3207  const QColor& textCol, const QColor& backgroundCol)
3208 {
3209  if (legendFrameStyle == frame &&
3210  legendTextColor == textCol &&
3211  legendBackground == backgroundCol &&
3212  plotLegendFont == font)
3213  return;
3214 
3215  legendFrameStyle = frame;
3216  legendTextColor = textCol;
3217  legendBackground = backgroundCol;
3218  plotLegendFont = font;
3219 
3220  QList<MyWidget*> windows = windowsList();
3221  foreach(MyWidget *w, windows)
3222  {
3223  if (w->inherits("MultiLayer"))
3224  {
3225  QWidgetList graphsList = ((MultiLayer*)w)->graphPtrs();
3226  foreach(QWidget *widget, graphsList)
3227  ((Graph *)widget)->setTextMarkerDefaults(frame, font, textCol, backgroundCol);
3228  }
3229  }
3230  saveSettings();
3231 }
3232 
3234  int headLength, int headAngle, bool fillHead)
3235 {
3236  if (defaultArrowLineWidth == pen.width() &&
3237  defaultArrowColor == pen.color() &&
3238  defaultArrowLineStyle == pen.style() &&
3239  defaultArrowHeadLength == headLength &&
3240  defaultArrowHeadAngle == headAngle &&
3241  defaultArrowHeadFill == fillHead)
3242  return;
3243 
3244  defaultArrowLineWidth = pen.width();
3245  defaultArrowColor = pen.color();
3246  defaultArrowLineStyle = pen.style();
3247  defaultArrowHeadLength = headLength;
3248  defaultArrowHeadAngle = headAngle;
3249  defaultArrowHeadFill = fillHead;
3250 
3251  QList<MyWidget*> windows = windowsList();
3252  foreach(MyWidget *w, windows)
3253  {
3254  if (w->inherits("MultiLayer"))
3255  {
3256  QWidgetList graphsList = ((MultiLayer*)w)->graphPtrs();
3257  foreach(QWidget *widget, graphsList)
3258  ((Graph *)widget)->setArrowDefaults(defaultArrowLineWidth, defaultArrowColor,
3259 
3262  }
3263  }
3264  saveSettings();
3265 }
3266 
3268 {
3269  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
3271  app->applyUserSettings();
3272  app->showMaximized();
3273 
3274  Table* t = app->newTable(fn, app->columnSeparator, 0, true, app->strip_spaces,
3278  QApplication::restoreOverrideCursor();
3279  return 0;
3280 }
3281 
3283 {
3284  ImportASCIIDialog *import_dialog = new ImportASCIIDialog(d_workspace.currentSubWindow() && d_workspace.currentSubWindow()->inherits("Table"), this, d_extended_import_ASCII_dialog);
3285  import_dialog->setDirectory(asciiDirPath);
3286  import_dialog->selectNameFilter(d_ASCII_file_filter);
3287  if (import_dialog->exec() != QDialog::Accepted)
3288  return;
3289 
3290  asciiDirPath = import_dialog->directory().path();
3291  if (import_dialog->rememberOptions()) {
3292  columnSeparator = import_dialog->columnSeparator();
3293  ignoredLines = import_dialog->ignoredLines();
3294  renameColumns = import_dialog->renameColumns();
3295  strip_spaces = import_dialog->stripSpaces();
3296  simplify_spaces = import_dialog->simplifySpaces();
3297  d_ASCII_import_locale = import_dialog->decimalSeparators();
3298  d_convert_to_numeric = import_dialog->convertToNumeric();
3299  saveSettings();
3300  }
3301 
3302  QLocale save_locale = QLocale();
3303  QLocale::setDefault(import_dialog->decimalSeparators());
3304  importASCII(import_dialog->selectedFiles(),
3305  import_dialog->importMode(),
3306  import_dialog->columnSeparator(),
3307  import_dialog->ignoredLines(),
3308  import_dialog->renameColumns(),
3309  import_dialog->stripSpaces(),
3310  import_dialog->simplifySpaces(),
3311  import_dialog->convertToNumeric(),
3312  import_dialog->decimalSeparators());
3313  QLocale::setDefault(save_locale);
3314 }
3315 
3316 void ApplicationWindow::importASCII(const QStringList& files, int import_mode, const QString& local_column_separator, int local_ignored_lines,
3317  bool local_rename_columns, bool local_strip_spaces, bool local_simplify_spaces, bool local_convert_to_numeric, QLocale local_numeric_locale)
3318 {
3319  if (files.isEmpty())
3320  return;
3321 
3322  // this is very much a special case, and thus is handled completely in its own block
3323  if (import_mode == ImportASCIIDialog::NewTables) {
3324  int dx=0, dy=0;
3325  QStringList sorted_files = files;
3326  sorted_files.sort();
3327  for (int i=0; i<sorted_files.size(); i++)
3328  {
3329  Table *w = newTable(sorted_files[i], local_column_separator, local_ignored_lines,
3330  local_rename_columns, local_strip_spaces, local_simplify_spaces, local_convert_to_numeric, local_numeric_locale);
3331  if (!w) continue;
3333  setListViewLabel(w->name(), sorted_files[i]);
3334  if (i==0)
3335  {
3336  dx = w->verticalHeaderWidth();
3337  dy = w->frameGeometry().height() - w->height();
3338  w->move(QPoint(0,0));
3339  }
3340  else
3341  w->move(QPoint(i*dx,i*dy));
3342 
3343  }
3344  modifiedProject();
3345  return;
3346  }
3347 
3348  Table *table = qobject_cast<Table *>(d_workspace.currentSubWindow());
3349  if (!table) return;
3350 
3351  foreach(QString file, files) {
3352  Table *temp = new Table(scriptEnv, file, local_column_separator, local_ignored_lines,
3353  local_rename_columns, local_strip_spaces, local_simplify_spaces, local_convert_to_numeric,
3354  local_numeric_locale, "temp", 0, 0, 0);
3355  if (!temp) continue;
3356 
3357  // need to check data types of columns for append/overwrite
3358  if (import_mode == ImportASCIIDialog::NewRows || import_mode == ImportASCIIDialog::Overwrite)
3359  {
3360  if (local_convert_to_numeric) {
3361  for (int col=0; col < qMin(temp->columnCount(), table->columnCount()); col++)
3362  if (table->column(col)->columnMode() != SciDAVis::Numeric) {
3363  QMessageBox::critical(this, tr("ASCII Import Failed"),
3364  tr("Numeric data cannot be imported into non-numeric column \"%1\".").arg(table->column(col)->name()));
3365  delete temp;
3366  return;
3367  }
3368  } else {
3369  for (int col=0; col < qMin(temp->columnCount(), table->columnCount()); col++)
3370  if (table->column(col)->columnMode() != SciDAVis::Text) {
3371  QMessageBox::critical(this, tr("ASCII Import Failed"),
3372  tr("Non-numeric data cannot be imported into non-text column \"%1\".").arg(table->column(col)->name()));
3373  delete temp;
3374  return;
3375  }
3376  }
3377  }
3378 
3379  // copy or move data from temp to table
3380  switch(import_mode) {
3382  while (temp->d_future_table->childCount() > 0)
3383  temp->d_future_table->reparentChild(table->d_future_table, temp->d_future_table->child(0));
3384  break;
3386  {
3387  int missing_columns = temp->columnCount() - table->columnCount();
3388  for (int col=0; col<missing_columns; col++) {
3389  Column * new_col = new Column(tr("new_by_import") + QString::number(col+1),
3390  local_convert_to_numeric ? SciDAVis::Numeric : SciDAVis::Text);
3391  new_col->setPlotDesignation(SciDAVis::Y);
3392  table->d_future_table->addChild(new_col);
3393  }
3394  Q_ASSERT(table->columnCount() >= temp->columnCount());
3395  int start_row = table->rowCount();
3396  table->d_future_table->setRowCount(table->rowCount() + temp->rowCount());
3397  for (int col=0; col<temp->columnCount(); col++)
3398  {
3399  Column * src_col = temp->column(col);
3400  Column * dst_col = table->column(col);
3401  Q_ASSERT(src_col->dataType() == dst_col->dataType());
3402  dst_col->copy(src_col, 0, start_row, src_col->rowCount());
3403  if (local_rename_columns) dst_col->setName(src_col->name());
3404  }
3405  break;
3406  }
3408  {
3409  if (table->rowCount() < temp->rowCount())
3410  table->d_future_table->setRowCount(temp->rowCount());
3411  for (int col=0; col<table->columnCount() && col<temp->columnCount(); col++)
3412  {
3413  Column * src_col = temp->column(col);
3414  Column * dst_col = table->column(col);
3415  Q_ASSERT(src_col->dataType() == dst_col->dataType());
3416  dst_col->copy(src_col, 0, 0, temp->rowCount());
3417  if (local_rename_columns) dst_col->setName(src_col->name());
3418  }
3419  if (temp->columnCount() > table->columnCount())
3420  {
3421  temp->d_future_table->removeColumns(0, table->columnCount());
3422  while (temp->d_future_table->childCount() > 0)
3423  temp->d_future_table->reparentChild(table->d_future_table, temp->d_future_table->child(0));
3424  }
3425  break;
3426  }
3427  }
3428  delete temp;
3429  }
3430 
3431  table->setWindowLabel(files.join("; "));
3432  table->notifyChanges();
3434  modifiedProject();
3435 }
3436 
3438 {
3440  open_dialog->setDirectory(workingDir);
3441  if (open_dialog->exec() != QDialog::Accepted || open_dialog->selectedFiles().isEmpty())
3442  return;
3443  workingDir = open_dialog->directory().path();
3444 
3445  switch(open_dialog->openMode()) {
3447  {
3448  QString fn = open_dialog->selectedFiles()[0];
3449  QFileInfo fi(fn);
3450 
3451  if (projectname != "untitled"){
3452  QFileInfo fi(projectname);
3453  QString pn = fi.absolutePath();
3454  if (fn == pn){
3455  QMessageBox::warning(this, tr("File opening error"),
3456  tr("The file: <b>%1</b> is the current file!").arg(fn));
3457  return;
3458  }
3459  }
3460 
3461  if (fn.endsWith(".sciprj",Qt::CaseInsensitive) || fn.endsWith(".sciprj~",Qt::CaseInsensitive) ||
3462  fn.endsWith(".qti",Qt::CaseInsensitive) || fn.endsWith(".qti~",Qt::CaseInsensitive) ||
3463  fn.endsWith(".sciprj.gz",Qt::CaseInsensitive) || fn.endsWith(".qti.gz",Qt::CaseInsensitive) ||
3464  fn.endsWith(".opj",Qt::CaseInsensitive) || fn.endsWith(".ogm",Qt::CaseInsensitive) ||
3465  fn.endsWith(".ogw",Qt::CaseInsensitive) || fn.endsWith(".ogg",Qt::CaseInsensitive) ||
3466  fn.endsWith(".org",Qt::CaseInsensitive))
3467  {
3468  if (!fi.exists ()){
3469  QMessageBox::critical(this, tr("File opening error"),
3470  tr("The file: <b>%1</b> doesn't exist!").arg(fn));
3471  return;
3472  }
3473 
3474  saveSettings();//the recent projects must be saved
3475 
3476  ApplicationWindow *a = open (fn);
3477  if (a){
3478  a->workingDir = workingDir;
3479  if (fn.endsWith(".sciprj",Qt::CaseInsensitive) || fn.endsWith(".sciprj~",Qt::CaseInsensitive) ||
3480  fn.endsWith(".sciprj.gz",Qt::CaseInsensitive) || fn.endsWith(".qti.gz",Qt::CaseInsensitive) ||
3481  fn.endsWith(".qti",Qt::CaseInsensitive) || fn.endsWith(".qti~",Qt::CaseInsensitive) ||
3482  fn.endsWith(".opj",Qt::CaseInsensitive) || fn.endsWith(".ogg", Qt::CaseInsensitive) ||
3483  fn.endsWith(".org",Qt::CaseInsensitive))
3484  this->close();
3485  }
3486  } else {
3487  QMessageBox::critical(this,tr("File opening error"),
3488  tr("The file <b>%1</b> is not a valid project file.").arg(fn));
3489  return;
3490  }
3491  break;
3492  }
3494  appendProject(open_dialog->selectedFiles()[0]);
3495  break;
3496  }
3497 }
3498 
3499 ApplicationWindow* ApplicationWindow::open(const QString& fn, const QStringList& scriptArgs)
3500 {
3501  if (
3502  fn.endsWith(".opj", Qt::CaseInsensitive) ||
3503  fn.endsWith(".ogm", Qt::CaseInsensitive) ||
3504  fn.endsWith(".ogw", Qt::CaseInsensitive) ||
3505  fn.endsWith(".ogg", Qt::CaseInsensitive) ||
3506  fn.endsWith(".org", Qt::CaseInsensitive)
3507  )
3508 #ifdef ORIGIN_IMPORT
3509  return importOPJ(fn);
3510 #else
3511  {
3512  QMessageBox::critical(this, tr("File opening error"), tr("SciDAVis currently does not support Origin import. If you are interested in reviving and maintaining an Origin import filter, contact the developers.").arg(fn));
3513  return 0;
3514  }
3515 #endif
3516  else if (fn.endsWith(".py", Qt::CaseInsensitive))
3517  return loadScript(fn, scriptArgs);
3518  else if (
3519  fn.endsWith(".sciprj",Qt::CaseInsensitive) ||
3520  fn.endsWith(".sciprj.gz",Qt::CaseInsensitive) ||
3521  fn.endsWith(".qti",Qt::CaseInsensitive) ||
3522  fn.endsWith(".qti.gz",Qt::CaseInsensitive) ||
3523  fn.endsWith(".sciprj~",Qt::CaseInsensitive) ||
3524  fn.endsWith(".sciprj.gz~",Qt::CaseInsensitive) ||
3525  fn.endsWith(".qti~",Qt::CaseInsensitive) ||
3526  fn.endsWith(".qti.gz~",Qt::CaseInsensitive)
3527  )
3528  return openProject(fn);
3529  else
3530  return plotFile(fn);
3531 }
3532 
3534 {
3535  QAction *trigger = qobject_cast<QAction*>(sender());
3536  if (!trigger) return;
3537  QString fn = trigger->text();
3538  int pos = fn.indexOf(" ",0);
3539  fn = fn.right(fn.length()-pos-1);
3540 
3541  QFile f(fn);
3542  if (!f.exists())
3543  {
3544  QMessageBox::critical(this,tr("File Open Error"),
3545  tr("The file: <b> %1 </b> <p>does not exist anymore!"
3546  "<p>It will be removed from the list.").arg(fn));
3547 
3548  recentProjects.removeAll(fn);
3550  return;
3551  }
3552 
3553  if (projectname != "untitled")
3554  {
3555  QFileInfo fi(projectname);
3556  QString pn = fi.absolutePath();
3557  if (fn == pn)
3558  {
3559  QMessageBox::warning(this, tr("File opening error"),
3560  tr("The file: <p><b> %1 </b><p> is the current file!").arg(fn));
3561  return;
3562  }
3563  }
3564 
3565  if (!fn.isEmpty())
3566  {
3567  saveSettings();//the recent projects must be saved
3568  ApplicationWindow * a = open (fn);
3569  if (a && (fn.endsWith(".sciprj",Qt::CaseInsensitive) || fn.endsWith(".sciprj~",Qt::CaseInsensitive) ||
3570  fn.endsWith(".sciprj.gz",Qt::CaseInsensitive) || fn.endsWith(".qti.gz",Qt::CaseInsensitive) ||
3571  fn.endsWith(".qti",Qt::CaseInsensitive) || fn.endsWith(".qti~",Qt::CaseInsensitive) ||
3572  fn.endsWith(".opj",Qt::CaseInsensitive) || fn.endsWith(".ogg", Qt::CaseInsensitive) ||
3573  fn.endsWith(".org",Qt::CaseInsensitive)))
3574  this->close();
3575  }
3576 }
3577 
3578 QFile * ApplicationWindow::openCompressedFile(const QString& fn)
3579 {
3580  QTemporaryFile * file;
3581  char buf[16384];
3582  int len, err;
3583 
3584  gzFile in = gzopen(QFile::encodeName(fn).constData(), "rb");
3585  if (!in) {
3586  QMessageBox::critical(this, tr("File opening error"), tr("zlib can't open %1.").arg(fn));
3587  return 0;
3588  }
3589  file = new QTemporaryFile();
3590  if (!file || !file->open()) {
3591  gzclose(in);
3592  QMessageBox::critical(this, tr("File opening error"), tr("Can't create temporary file for writing uncompressed copy of %1.").arg(fn));
3593  return 0;
3594  }
3595 
3596  forever {
3597  len = gzread(in, buf, sizeof(buf));
3598  if (len == 0) break;
3599  if (len < 0) {
3600  QMessageBox::critical(this, tr("File opening error"), gzerror(in, &err));
3601  gzclose(in);
3602  file->close(); delete file;
3603  return 0;
3604  }
3605  if (file->write(buf, len) != len) {
3606  QMessageBox::critical(this, tr("File opening error"), tr("Error writing to temporary file: %1").arg(file->errorString()));
3607  gzclose(in);
3608  file->close(); delete file;
3609  return 0;
3610  }
3611  }
3612 
3613  gzclose(in);
3614  file->reset();
3615  return file;
3616 }
3617 
3618 bool ApplicationWindow::loadProject(const QString& fn)
3619 {
3620  unique_ptr<QFile> file;
3621 
3622  if (fn.endsWith(".gz", Qt::CaseInsensitive) || fn.endsWith(".gz~", Qt::CaseInsensitive)) {
3623  file.reset(openCompressedFile(fn));
3624  if (!file) return false;
3625  } else {
3626  file.reset(new QFile(fn));
3627  if (!file->open(QIODevice::ReadOnly))
3628  {
3629  QMessageBox::critical(this, tr("File opening error"), file->errorString());
3630  return false;
3631  }
3632  }
3633 
3634  QTextStream t(file.get());
3635  t.setCodec(QTextCodec::codecForName("UTF-8"));
3636  QString s;
3637  QStringList list;
3638 
3639  s = t.readLine();
3640  list = s.split(QRegExp("\\s"), QString::SkipEmptyParts);
3641  if (list.count() < 2 || (list[0] != "SciDAVis" && list[0] != "QtiPlot")) {
3642  if (QFile::exists(fn + "~")) {
3643  int choice = QMessageBox::question(this, tr("File opening error"),
3644  tr("The file <b>%1</b> is corrupted, but there exists a backup copy.<br>Do you want to open the backup instead?").arg(fn),
3645  QMessageBox::Yes|QMessageBox::Default, QMessageBox::No|QMessageBox::Escape);
3646  if (choice == QMessageBox::Yes) {
3647  QMessageBox::information(this, tr("Opening backup copy"),
3648  tr("The original (corrupt) file is being left untouched, in case you want to "\
3649  "try rescuing data manually. If you want to continue working with the "\
3650  "automatically restored backup copy, you have to explicitly overwrite the "\
3651  "original file."));
3652  return loadProject(fn + "~");
3653  }
3654  }
3655  QMessageBox::critical(this, tr("File opening error"), tr("The file <b>%1</b> is not a valid project file.").arg(fn));
3656  return false;
3657  }
3658 
3659  QStringList vl = list[1].split(".", QString::SkipEmptyParts);
3660  if(
3661  fn.endsWith(".qti",Qt::CaseInsensitive) ||
3662  fn.endsWith(".qti.gz",Qt::CaseInsensitive) ||
3663  fn.endsWith(".qti~",Qt::CaseInsensitive) ||
3664  fn.endsWith(".qti.gz~",Qt::CaseInsensitive)
3665  ) {
3666  d_file_version = 100*(vl[0]).toInt()+10*(vl[1]).toInt()+(vl[2]).toInt();
3667  if(d_file_version > 90) {
3668  QMessageBox::critical(this, tr("File opening error"),
3669  tr("SciDAVis does not support QtiPlot project files from versions later than 0.9.0.").arg(fn));
3670  return false;
3671  }
3672  } else
3673  d_file_version = ((vl[0]).toInt() << 16) + ((vl[1]).toInt() << 8) + (vl[2]).toInt();
3674 
3675  projectname = fn;
3676  setWindowTitle(tr("SciDAVis") + " - " + fn);
3677 
3678  QFileInfo fi(fn);
3679  QString baseName = fi.fileName();
3680 
3681  if (d_file_version < 73)
3682  t.readLine();
3683 
3684  s = t.readLine();
3685  list=s.split("\t", QString::SkipEmptyParts);
3686  if (list[0] == "<scripting-lang>")
3687  {
3688  if (!setScriptingLang(list[1], true))
3689  QMessageBox::warning(this, tr("File opening error"),
3690  tr("The file \"%1\" was created using \"%2\" as scripting language.\n\n"\
3691  "Initializing support for this language FAILED; I'm using \"%3\" instead.\n"\
3692  "Various parts of this file may not be displayed as expected.")\
3693  .arg(fn).arg(list[1]).arg(scriptEnv->objectName()));
3694 
3695  s = t.readLine();
3696  list=s.split("\t", QString::SkipEmptyParts);
3697  }
3698  int aux=0,widgets=list[1].toInt();
3699 
3700  QString titleBase = tr("Window") + ": ";
3701  QString title = titleBase + "1/"+QString::number(widgets)+" ";
3702 
3703  QProgressDialog progress;/*(this);*/
3704  progress.setWindowModality(Qt::WindowModal);
3705  progress.setRange(0, widgets);
3706  progress.setMinimumWidth(width()/2);
3707  progress.setWindowTitle(tr("Opening file") + ": " + baseName);
3708  progress.setLabelText(title);
3709  progress.activateWindow();
3710 
3711  Folder *cf = projectFolder();
3712  folders.blockSignals (true);
3713  blockSignals (true);
3714  //rename project folder item
3715  FolderListItem *item = (FolderListItem *)folders.topLevelItem(0);
3716  item->setText(0, fi.baseName());
3717  item->folder()->setName(fi.baseName());
3718 
3719  //process tables and matrix information
3720  while ( !t.atEnd() && !progress.wasCanceled())
3721  {
3722  s = t.readLine(4096); // workaround for safely reading very big lines
3723  list.clear();
3724  if (s.left(8) == "<folder>")
3725  {
3726  list = s.split("\t");
3727  Folder& f = current_folder->addChild<Folder>(list[1]);
3728  f.setBirthDate(list[2]);
3729  f.setModificationDate(list[3]);
3730  if(list.count() > 4)
3731  if (list[4] == "current")
3732  cf = &f;
3733 
3735  fli->setText(0, list[1]);
3736  f.setFolderListItem(fli);
3737 
3738  current_folder = &f;
3739  }
3740  else if (s == "<table>")
3741  {
3742  title = titleBase + QString::number(++aux)+"/"+QString::number(widgets);
3743  progress.setLabelText(title);
3744 
3745  openTable(this, t);
3746  progress.setValue(aux);
3747  }
3748  else if (s.left(17)=="<TableStatistics>")
3749  {
3750  QStringList lst;
3751  while ( s!="</TableStatistics>" )
3752  {
3753  s=t.readLine();
3754  lst<<s;
3755  }
3756  lst.pop_back();
3757  openTableStatistics(lst);
3758  }
3759  else if (s == "<matrix>")
3760  {
3761  title= titleBase + QString::number(++aux)+"/"+QString::number(widgets);
3762  progress.setLabelText(title);
3763  QStringList lst;
3764  while ( s != "</matrix>" )
3765  {
3766  s=t.readLine();
3767  lst<<s;
3768  }
3769  lst.pop_back();
3770  openMatrix(this, lst);
3771  progress.setValue(aux);
3772  }
3773  else if (s == "<note>")
3774  {
3775  title= titleBase + QString::number(++aux)+"/"+QString::number(widgets);
3776  progress.setLabelText(title);
3777  for (int i=0; i<3; i++)
3778  {
3779  s = t.readLine();
3780  list << s;
3781  }
3782  Note* m = openNote(this,list);
3783  QStringList cont;
3784  while ( s != "</note>" )
3785  {
3786  s=t.readLine();
3787  cont << s;
3788  }
3789  cont.pop_back();
3790  m->restore(cont);
3791  progress.setValue(aux);
3792  }
3793  else if (s == "</folder>")
3794  {
3795  Folder *parent = (Folder *)current_folder->parent();
3796  if (!parent)
3798  else
3799  current_folder = parent;
3800  }
3801  }
3802 
3803 
3804  if (progress.wasCanceled())
3805  {
3806  saved = true;
3807  close();
3808  return false;
3809  }
3810 
3811  //process the rest
3812  t.seek(0);
3813 
3814  MultiLayer *plot=0;
3815  while ( !t.atEnd() && !progress.wasCanceled())
3816  {
3817  s = t.readLine(4096); // workaround for safely reading very big lines
3818  if (s.left(8) == "<folder>")
3819  {
3820  list = s.split("\t");
3822  }
3823  else if (s == "<multiLayer>")
3824  {//process multilayers information
3825  title = titleBase + QString::number(++aux)+"/"+QString::number(widgets);
3826  progress.setLabelText(title);
3827 
3828  s=t.readLine();
3829  QStringList graph=s.split("\t");
3830  QString caption=graph[0];
3831  plot = multilayerPlot(caption);
3832  plot->setCols(graph[1].toInt());
3833  plot->setRows(graph[2].toInt());
3834 
3835  setListViewDate(caption, graph[3]);
3836  plot->setBirthDate(graph[3]);
3837 
3838  restoreWindowGeometry(this, plot, t.readLine());
3839  plot->blockSignals(true);
3840 
3841  if (d_file_version > 71)
3842  {
3843  QStringList lst=t.readLine().split("\t");
3844  plot->setWindowLabel(lst[1]);
3845  setListViewLabel(plot->name(),lst[1]);
3846  plot->setCaptionPolicy((MyWidget::CaptionPolicy)lst[2].toInt());
3847  }
3848  if (d_file_version > 83)
3849  {
3850  QStringList lst=t.readLine().split("\t", QString::SkipEmptyParts);
3851  plot->setMargins(lst[1].toInt(),lst[2].toInt(),lst[3].toInt(),lst[4].toInt());
3852  lst=t.readLine().split("\t", QString::SkipEmptyParts);
3853  plot->setSpacing(lst[1].toInt(),lst[2].toInt());
3854  lst=t.readLine().split("\t", QString::SkipEmptyParts);
3855  plot->setLayerCanvasSize(lst[1].toInt(),lst[2].toInt());
3856  lst=t.readLine().split("\t", QString::SkipEmptyParts);
3857  plot->setAlignement(lst[1].toInt(),lst[2].toInt());
3858  }
3859 
3860  while ( s!="</multiLayer>" )
3861  {//open layers
3862  s = t.readLine();
3863  if (s.left(7)=="<graph>")
3864  {
3865  list.clear();
3866  while ( s!="</graph>" )
3867  {
3868  s=t.readLine();
3869  list<<s;
3870  }
3871  openGraph(this, plot, list);
3872  }
3873  }
3874  plot->blockSignals(false);
3875  activateSubWindow(plot);
3876  progress.setValue(aux);
3877  }
3878  else if (s == "<SurfacePlot>")
3879  {//process 3D plots information
3880  list.clear();
3881  title = titleBase + QString::number(++aux)+"/"+QString::number(widgets);
3882  progress.setLabelText(title);
3883  while ( s!="</SurfacePlot>" )
3884  {
3885  s=t.readLine();
3886  list<<s;
3887  }
3888  openSurfacePlot(this,list);
3889  progress.setValue(aux);
3890  }
3891  else if (s == "</folder>")
3892  {
3893  Folder *parent = (Folder *)current_folder->parent();
3894  if (!parent)
3896  else
3897  current_folder = parent;
3898  }
3899  else if (s.left(5)=="<log>")
3900  {//process analysis information
3901  s = t.readLine();
3902  while ( s != "</log>" )
3903  {
3904  logInfo+= s+"\n";
3905  s = t.readLine();
3906  }
3907  results->setText(logInfo);
3908  }
3909  }
3910 
3911  if (progress.wasCanceled())
3912  {
3913  saved = true;
3914  close();
3915  return false;
3916  }
3917 
3918  logInfo=logInfo.remove ("</log>\n", Qt::CaseInsensitive);
3919 
3920  folders.setCurrentItem(cf->folderListItem());
3921  folders.blockSignals (false);
3922  //change folder to user defined current folder
3923  changeFolder(cf, true);
3924 
3925  blockSignals (false);
3926  renamedTables.clear();
3927 
3928  show();
3929  executeNotes();
3930  savedProject();
3931 
3932  recentProjects.removeAll(fn);
3933  recentProjects.push_front(fn);
3935 
3936  return true;
3937 }
3938 
3939 
3941 {
3942  unique_ptr<ApplicationWindow> app(new ApplicationWindow);
3943  app->applyUserSettings();
3944  return app->loadProject(fn)? app.release(): nullptr;
3945 }
3946 
3948 {
3949  QList<MyWidget *> lst = projectFolder()->windowsList();
3950  foreach(MyWidget *widget, lst)
3951  if (widget->inherits("Note") && ((Note*)widget)->autoexec())
3952  ((Note*)widget)->executeAll();
3953 }
3954 
3955 void ApplicationWindow::scriptError(const QString &message, const QString &scriptName, int lineNumber)
3956 {
3957  Q_UNUSED(scriptName)
3958  Q_UNUSED(lineNumber)
3959  QMessageBox::critical(this, tr("SciDAVis") + " - "+ tr("Script Error"), message);
3960 }
3961 
3962 void ApplicationWindow::scriptPrint(const QString &text)
3963 {
3964 #ifdef SCRIPTING_CONSOLE
3965  if(!text.isEmpty()) console.insertPlainText(text);
3966 #else
3967  printf(text.toUtf8().constData());
3968 #endif
3969 }
3970 
3971 bool ApplicationWindow::setScriptingLang(const QString &lang, bool force, bool batch)
3972 {
3973  if (!force && lang == scriptEnv->objectName()) return true;
3974  if (lang.isEmpty()) return false;
3975 
3976  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
3977 
3978  ScriptingEnv *newEnv = ScriptingLangManager::newEnv(lang.toStdString(), this, batch);
3979  if (!newEnv) {
3980  QApplication::restoreOverrideCursor();
3981  return false;
3982  }
3983 
3984  connect(newEnv, SIGNAL(error(const QString&,const QString&,int)),
3985  this, SLOT(scriptError(const QString&,const QString&,int)));
3986  connect(newEnv, SIGNAL(print(const QString&)), this, SLOT(scriptPrint(const QString&)));
3987  if (!newEnv->initialize())
3988  {
3989  QApplication::restoreOverrideCursor();
3990  return false;
3991  }
3992 
3993  // notify everyone who might be interested
3994  ScriptingChangeEvent sce(newEnv);
3995  QApplication::sendEvent(this, &sce);
3996 
3997  foreach(QObject *i, findChildren<QWidget*>())
3998  QApplication::postEvent(i, new ScriptingChangeEvent(newEnv));
3999 
4000  QApplication::restoreOverrideCursor();
4001 
4002  return true;
4003 }
4004 
4006 {
4008  d->showNormal();
4009  d->activateWindow();
4010 }
4011 
4013 {
4014  if (setScriptingLang(scriptEnv->objectName(), true))
4015  executeNotes();
4016  else
4017  QMessageBox::critical(this, tr("Scripting Error"),
4018  tr("Scripting language \"%1\" failed to initialize.").arg(scriptEnv->objectName()));
4019 }
4020 
4021 //TODO: rewrite the template system
4023 {
4024  QString filter = "SciDAVis/QtiPlot 2D Graph Template (*.qpt);;";
4025  filter += "SciDAVis/QtiPlot 3D Surface Template (*.qst);;";
4026  filter += "SciDAVis/QtiPlot Table Template (*.qtt);;";
4027  filter += "SciDAVis/QtiPlot Matrix Template (*.qmt)";
4028 
4029  QString fn = QFileDialog::getOpenFileName(this, tr("Open Template File"), templatesDir, filter);
4030  if (!fn.isEmpty())
4031  {
4032  QFileInfo fi(fn);
4033  templatesDir = fi.absolutePath();
4034  if (fn.contains(".qmt",Qt::CaseSensitive) || fn.contains(".qpt",Qt::CaseSensitive) ||
4035  fn.contains(".qtt",Qt::CaseSensitive) || fn.contains(".qst",Qt::CaseSensitive))
4036  {
4037  if (!fi.exists())
4038  {
4039  QMessageBox::critical(this, tr("File opening error"),
4040  tr("The file: <b>%1</b> doesn't exist!").arg(fn));
4041  return;
4042  }
4043  QFile f(fn);
4044  QTextStream t(&f);
4045  t.setCodec(QTextCodec::codecForName("UTF-8"));
4046  f.open(QIODevice::ReadOnly);
4047  QStringList l=t.readLine().split(QRegExp("\\s"), QString::SkipEmptyParts);
4048  QString fileType=l[0];
4049  if( (fileType != "SciDAVis") && (fileType != "QtiPlot") )
4050  {
4051  QMessageBox::critical(this,tr("File opening error"),
4052  tr("The file: <b> %1 </b> was not created using SciDAVis!").arg(fn));
4053  return;
4054  }
4055  QStringList vl = l[1].split(".", QString::SkipEmptyParts);
4056  if( fileType == "QtiPlot" )
4057  {
4058  d_file_version = 100*(vl[0]).toInt()+10*(vl[1]).toInt()+(vl[2]).toInt();
4059  if(d_file_version > 90)
4060  {
4061  QMessageBox::critical(this, tr("File opening error"), tr("SciDAVis does not support QtiPlot template files from versions later than 0.9.0.").arg(fn));
4062  return;
4063  }
4064  }
4065  else
4066  d_file_version = ((vl[0]).toInt() << 16) + ((vl[1]).toInt() << 8) + (vl[2]).toInt();
4067 
4068  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
4069 
4070  MyWidget *w = 0;
4071  QString templateType;
4072  t>>templateType;
4073 
4074  if (templateType == "<SurfacePlot>")
4075  {
4076  t.skipWhiteSpace();
4077  QStringList lst;
4078  while (!t.atEnd())
4079  lst << t.readLine();
4080  w = openSurfacePlot(this,lst);
4081  if (w)
4082  ((Graph3D *)w)->clearData();
4083  }
4084  else
4085  {
4086  int rows, cols;
4087  t>>rows; t>>cols;
4088  t.skipWhiteSpace();
4089  QString geometry = t.readLine();
4090 
4091  if (templateType == "<multiLayer>")
4092  { // FIXME: workarounds for template
4093  w = new MultiLayer("", &d_workspace, 0);
4094  w->setAttribute(Qt::WA_DeleteOnClose);
4095  QString label = generateUniqueName(tr("Graph"));
4096  initBareMultilayerPlot((MultiLayer*)w, label.replace(QRegExp("_"),"-"));
4097  if (w)
4098  {
4099  ((MultiLayer*)w)->setCols(cols);
4100  ((MultiLayer*)w)->setRows(rows);
4101  restoreWindowGeometry(this, w, geometry);
4102  if (d_file_version > 83)
4103  {
4104  QStringList lst=t.readLine().split("\t", QString::SkipEmptyParts);
4105  ((MultiLayer*)w)->setMargins(lst[1].toInt(),lst[2].toInt(),lst[3].toInt(),lst[4].toInt());
4106  lst=t.readLine().split("\t", QString::SkipEmptyParts);
4107  ((MultiLayer*)w)->setSpacing(lst[1].toInt(),lst[2].toInt());
4108  lst=t.readLine().split("\t", QString::SkipEmptyParts);
4109  ((MultiLayer*)w)->setLayerCanvasSize(lst[1].toInt(),lst[2].toInt());
4110  lst=t.readLine().split("\t", QString::SkipEmptyParts);
4111  ((MultiLayer*)w)->setAlignement(lst[1].toInt(),lst[2].toInt());
4112  }
4113  while (!t.atEnd())
4114  {//open layers
4115  QString s=t.readLine();
4116  if (s.left(7)=="<graph>")
4117  {
4118  QStringList lst;
4119  while ( s!="</graph>" )
4120  {
4121  s = t.readLine();
4122  lst << s;
4123  }
4124  openGraph(this, (MultiLayer*)w, lst);
4125  }
4126  }
4127  }
4128  }
4129  else
4130  {
4131  if (templateType == "<table>")
4132  w = newTable(tr("Table1"), rows, cols);
4133  else if (templateType == "<matrix>")
4134  w = newMatrix(rows, cols);
4135  if (w)
4136  {
4137  QStringList lst;
4138  while (!t.atEnd())
4139  lst << t.readLine();
4140  w->restore(lst);
4141  restoreWindowGeometry(this, w, geometry);
4142  }
4143  }
4144  }
4145 
4146  f.close();
4147  if (w)
4148  {
4149  switch (w->status())
4150  {
4151  case MyWidget::Maximized :
4152  w->setMaximized();
4153  break;
4154  case MyWidget::Minimized :
4155  w->setMinimized();
4156  break;
4157  case MyWidget::Hidden :
4158  w->setHidden();
4159  break;
4160  case MyWidget::Normal :
4161  w->setNormal();
4162  break;
4163  }
4164  customMenu((MyWidget*)w);
4165  customToolBars((MyWidget*)w);
4166  }
4167  QApplication::restoreOverrideCursor();
4168  }
4169  else
4170  {
4171  QMessageBox::critical(this,tr("File opening error"),
4172  tr("The file: <b>%1</b> is not a SciDAVis template file!").arg(fn));
4173  return;
4174  }
4175  }
4176 }
4177 
4179 {
4180  QSettings settings;
4181 
4182  /* ---------------- group General --------------- */
4183  settings.beginGroup("/General");
4184 #ifdef SEARCH_FOR_UPDATES
4185  autoSearchUpdates = settings.value("/AutoSearchUpdates", false).toBool();
4186 #endif
4187  appLanguage = settings.value("/Language", QLocale::system().name().section('_',0,0)).toString();
4188  show_windows_policy = (ShowWindowsPolicy)settings.value("/ShowWindowsPolicy", ApplicationWindow::ActiveFolder).toInt();
4189 
4190  recentProjects = settings.value("/RecentProjects").toStringList();
4191  //Follows an ugly hack added by Ion in order to fix Qt4 porting issues
4192  //(only needed on Windows due to a Qt bug?)
4193 #ifdef Q_OS_WIN
4194  if (!recentProjects.isEmpty() && recentProjects[0].contains("^e"))
4195  recentProjects = recentProjects[0].split("^e", QString::SkipEmptyParts);
4196  else if (recentProjects.count() == 1)
4197  {
4198  QString s = recentProjects[0];
4199  if (s.remove(QRegExp("\\s")).isEmpty())
4200  recentProjects = QStringList();
4201  }
4202 #endif
4203 
4205 
4206  changeAppStyle(settings.value("/Style", appStyle).toString());
4207  undoLimit = settings.value("/UndoLimit",10).toInt();
4208  d_project->undoStack()->setUndoLimit(undoLimit);
4209  autoSave = settings.value("/AutoSave",true).toBool();
4210  autoSaveTime = settings.value("/AutoSaveTime",15).toInt();
4211  defaultScriptingLang = settings.value("/ScriptingLang","muParser").toString();
4212 
4213  QLocale temp_locale = QLocale( settings.value("/Locale", QLocale::system().name()).toString() );
4214  bool usegl = settings.value("/LocaleUseGroupSeparator", true).toBool();
4215  if(usegl)
4216  temp_locale.setNumberOptions(temp_locale.numberOptions() & ~QLocale::OmitGroupSeparator);
4217  else
4218  temp_locale.setNumberOptions(temp_locale.numberOptions() | QLocale::OmitGroupSeparator);
4219  QLocale::setDefault(temp_locale);
4220 
4221  d_decimal_digits = settings.value("/DecimalDigits", 6).toInt();
4222  d_default_numeric_format = settings.value("/DefaultNumericFormat", 'g').toChar().toLatin1();
4223 
4224  //restore geometry of main window
4225  restoreGeometry(settings.value("/ProjectWindow/Geometry").toByteArray());
4226 
4227  //restore dock windows and tool bars
4228  restoreState(settings.value("/DockWindows").toByteArray());
4229  explorerSplitter->restoreState(settings.value("/ExplorerSplitter").toByteArray());
4230 
4231  QStringList applicationFont = settings.value("/Font").toStringList();
4232  if (applicationFont.size() == 4)
4233  appFont=QFont (applicationFont[0],applicationFont[1].toInt(),applicationFont[2].toInt(),applicationFont[3].toInt());
4234 
4235  settings.beginGroup("/Dialogs");
4236  d_extended_open_dialog = settings.value("/ExtendedOpenDialog", true).toBool();
4237  d_extended_export_dialog = settings.value("/ExtendedExportDialog", true).toBool();
4238  d_extended_import_ASCII_dialog = settings.value("/ExtendedImportAsciiDialog", true).toBool();
4239  d_extended_plot_dialog = settings.value("/ExtendedPlotDialog", true).toBool();//used by PlotDialog
4240 
4241  settings.beginGroup("/AddRemoveCurves");
4242  d_add_curves_dialog_size = QSize(settings.value("/Width", 700).toInt(),
4243  settings.value("/Height", 400).toInt());
4244  d_show_current_folder = settings.value("/ShowCurrentFolder", false).toBool();
4245  settings.endGroup(); // AddRemoveCurves Dialog
4246  settings.endGroup(); // Dialogs
4247 
4248  settings.beginGroup("/Colors");
4249  workspaceColor = QColor(COLORVALUE(settings.value("/Workspace","darkGray").toString()));
4250  // see http://doc.trolltech.com/4.2/qvariant.html for instructions on qcolor <-> qvariant conversion
4251  panelsColor = QColor(COLORVALUE(settings.value("/Panels","#ffffffff").toString()));
4252  panelsTextColor = QColor(COLORVALUE(settings.value("/PanelsText","#ff000000").toString()));
4253  settings.endGroup(); // Colors
4254 
4255  settings.beginGroup("/Paths");
4256  workingDir = settings.value("/WorkingDir", qApp->applicationDirPath()).toString();
4257  helpFilePath = settings.value("/HelpFile", "").toString();
4258 #ifdef PLUGIN_PATH
4259  QString defaultFitPluginsPath = PLUGIN_PATH;
4260 #else // defined PLUGIN_PATH
4261 #ifdef Q_OS_WIN
4262  QString defaultFitPluginsPath = "fitPlugins";
4263 #else
4264  QString defaultFitPluginsPath = "/usr/lib/scidavis/plugins";
4265 #endif
4266 #endif // defined PLUGIN_PATH
4267 #ifdef DYNAMIC_PLUGIN_PATH
4268  fitPluginsPath = settings.value("/FitPlugins", defaultFitPluginsPath).toString();
4269 #else // defined PLUGIN_PATH
4270  fitPluginsPath = defaultFitPluginsPath;
4271 #endif
4272 
4273 #ifdef Q_OS_WIN
4274  templatesDir = settings.value("/TemplatesDir", qApp->applicationDirPath()).toString();
4275  asciiDirPath = settings.value("/ASCII", qApp->applicationDirPath()).toString();
4276  imagesDirPath = settings.value("/Images", qApp->applicationDirPath()).toString();
4277 #else
4278  templatesDir = settings.value("/TemplatesDir", QDir::homePath()).toString();
4279  asciiDirPath = settings.value("/ASCII", QDir::homePath()).toString();
4280  imagesDirPath = settings.value("/Images", QDir::homePath()).toString();
4281 #endif
4282  locktoolbar->setChecked(settings.value("LockToolbars", false).toBool());
4283  settings.endGroup(); // Paths
4284  settings.endGroup();
4285  /* ------------- end group General ------------------- */
4286 
4287 
4288  settings.beginGroup("/UserFunctions");
4289  fitFunctions = settings.value("/FitFunctions").toStringList();
4290  surfaceFunc = settings.value("/SurfaceFunctions").toStringList();
4291  xFunctions = settings.value("/xFunctions").toStringList();
4292  yFunctions = settings.value("/yFunctions").toStringList();
4293  rFunctions = settings.value("/rFunctions").toStringList();
4294  thetaFunctions = settings.value("/thetaFunctions").toStringList();
4295  settings.endGroup(); // UserFunctions
4296 
4297 
4298  settings.beginGroup("/Confirmations");
4299  confirmCloseFolder = settings.value("/Folder", true).toBool();
4300  confirmCloseTable = settings.value("/Table", true).toBool();
4301  confirmCloseMatrix = settings.value("/Matrix", true).toBool();
4302  confirmClosePlot2D = settings.value("/Plot2D", true).toBool();
4303  confirmClosePlot3D = settings.value("/Plot3D", true).toBool();
4304  confirmCloseNotes = settings.value("/Note", true).toBool();
4305  settings.endGroup(); // Confirmations
4306 
4307 
4308  /* ---------------- group Tables --------------- */
4309  settings.beginGroup("/Tables");
4310  d_show_table_comments = settings.value("/DisplayComments", false).toBool();
4311  QStringList tableFonts = settings.value("/Fonts").toStringList();
4312  if (tableFonts.size() == 8)
4313  {
4314  tableTextFont=QFont (tableFonts[0],tableFonts[1].toInt(),tableFonts[2].toInt(),tableFonts[3].toInt());
4315  tableHeaderFont=QFont (tableFonts[4],tableFonts[5].toInt(),tableFonts[6].toInt(),tableFonts[7].toInt());
4316  }
4317 
4318  settings.beginGroup("/Colors");
4319  tableBkgdColor = QColor(COLORVALUE(settings.value("/Background","#ffffffff").toString()));
4320  tableTextColor = QColor(COLORVALUE(settings.value("/Text","#ff000000").toString()));
4321  tableHeaderColor = QColor(COLORVALUE(settings.value("/Header","#ff000000").toString()));
4322  settings.endGroup(); // Colors
4323  settings.endGroup();
4324  /* --------------- end group Tables ------------------------ */
4325 
4326  /* --------------- group 2D Plots ----------------------------- */
4327  settings.beginGroup("/2DPlots");
4328  settings.beginGroup("/General");
4329  titleOn = settings.value("/Title", true).toBool();
4330  allAxesOn = settings.value("/AllAxes", false).toBool();
4331  canvasFrameOn = settings.value("/CanvasFrame", false).toBool();
4332  canvasFrameWidth = settings.value("/CanvasFrameWidth", 0).toInt();
4333  defaultPlotMargin = settings.value("/Margin", 0).toInt();
4334  drawBackbones = settings.value("/AxesBackbones", true).toBool();
4335  axesLineWidth = settings.value("/AxesLineWidth", 1).toInt();
4336  autoscale2DPlots = settings.value("/Autoscale", true).toBool();
4337  autoScaleFonts = settings.value("/AutoScaleFonts", true).toBool();
4338  autoResizeLayers = settings.value("/AutoResizeLayers", true).toBool();
4339  antialiasing2DPlots = settings.value("/Antialiasing", true).toBool();
4340  d_scale_plots_on_print = settings.value("/ScaleLayersOnPrint", false).toBool();
4341  d_print_cropmarks = settings.value("/PrintCropmarks", false).toBool();
4342 
4343  QStringList graphFonts = settings.value("/Fonts").toStringList();
4344  if (graphFonts.size() == 16)
4345  {
4346  plotAxesFont=QFont (graphFonts[0],graphFonts[1].toInt(),graphFonts[2].toInt(),graphFonts[3].toInt());
4347  plotNumbersFont=QFont (graphFonts[4],graphFonts[5].toInt(),graphFonts[6].toInt(),graphFonts[7].toInt());
4348  plotLegendFont=QFont (graphFonts[8],graphFonts[9].toInt(),graphFonts[10].toInt(),graphFonts[11].toInt());
4349  plotTitleFont=QFont (graphFonts[12],graphFonts[13].toInt(),graphFonts[14].toInt(),graphFonts[15].toInt());
4350  }
4351  settings.endGroup(); // General
4352 
4353  settings.beginGroup("/Curves");
4354  defaultCurveStyle = settings.value("/Style", Graph::LineSymbols).toInt();
4355  defaultCurveLineWidth = settings.value("/LineWidth", 1).toInt();
4356  defaultSymbolSize = settings.value("/SymbolSize", 7).toInt();
4357  settings.endGroup(); // Curves
4358 
4359  settings.beginGroup("/Ticks");
4360  majTicksStyle = settings.value("/MajTicksStyle", ScaleDraw::Out).toInt();
4361  minTicksStyle = settings.value("/MinTicksStyle", ScaleDraw::Out).toInt();
4362  minTicksLength = settings.value("/MinTicksLength", 5).toInt();
4363  majTicksLength = settings.value("/MajTicksLength", 9).toInt();
4364  settings.endGroup(); // Ticks
4365 
4366  settings.beginGroup("/Legend");
4367  legendFrameStyle = settings.value("/FrameStyle", Legend::Line).toInt();
4368  legendTextColor = QColor(COLORVALUE(settings.value("/TextColor", "#ff000000").toString())); //default color Qt::black
4369  legendBackground = QColor(COLORVALUE(settings.value("/BackgroundColor", "#ffffffff").toString())); //default color Qt::white
4370  legendBackground.setAlpha(settings.value("/Transparency", 0).toInt()); // transparent by default;
4371  settings.endGroup(); // Legend
4372 
4373  settings.beginGroup("/Arrows");
4374  defaultArrowLineWidth = settings.value("/Width", 1).toInt();
4375  defaultArrowColor = QColor(COLORVALUE(settings.value("/Color", "#ff000000").toString()));//default color Qt::black
4376  defaultArrowHeadLength = settings.value("/HeadLength", 4).toInt();
4377  defaultArrowHeadAngle = settings.value("/HeadAngle", 45).toInt();
4378  defaultArrowHeadFill = settings.value("/HeadFill", true).toBool();
4379  defaultArrowLineStyle = Graph::getPenStyle(settings.value("/LineStyle", "SolidLine").toString());
4380  settings.endGroup(); // Arrows
4381  settings.endGroup();
4382  /* ----------------- end group 2D Plots --------------------------- */
4383 
4384  /* ----------------- group 3D Plots --------------------------- */
4385  settings.beginGroup("/3DPlots");
4386  showPlot3DLegend = settings.value("/Legend",true).toBool();
4387  showPlot3DProjection = settings.value("/Projection", false).toBool();
4388  smooth3DMesh = settings.value("/Antialiasing", true).toBool();
4389  plot3DResolution = settings.value ("/Resolution", 1).toInt();
4390  orthogonal3DPlots = settings.value("/Orthogonal", false).toBool();
4391  autoscale3DPlots = settings.value ("/Autoscale", true).toBool();
4392 
4393  QStringList plot3DFonts = settings.value("/Fonts").toStringList();
4394  if (plot3DFonts.size() == 12)
4395  {
4396  plot3DTitleFont=QFont (plot3DFonts[0],plot3DFonts[1].toInt(),plot3DFonts[2].toInt(),plot3DFonts[3].toInt());
4397  plot3DNumbersFont=QFont (plot3DFonts[4],plot3DFonts[5].toInt(),plot3DFonts[6].toInt(),plot3DFonts[7].toInt());
4398  plot3DAxesFont=QFont (plot3DFonts[8],plot3DFonts[9].toInt(),plot3DFonts[10].toInt(),plot3DFonts[11].toInt());
4399  }
4400 
4401  settings.beginGroup("/Colors");
4402  plot3DColors << settings.value("/MaxData", "blue").toString();
4403  plot3DColors << settings.value("/Labels", "#000000").toString();
4404  plot3DColors << settings.value("/Mesh", "#000000").toString();
4405  plot3DColors << settings.value("/Grid", "#000000").toString();
4406  plot3DColors << settings.value("/MinData", "red").toString();
4407  plot3DColors << settings.value("/Numbers", "#000000").toString();
4408  plot3DColors << settings.value("/Axes", "#000000").toString();
4409  plot3DColors << settings.value("/Background", "#ffffff").toString();
4410  settings.endGroup(); // Colors
4411  settings.endGroup();
4412  /* ----------------- end group 3D Plots --------------------------- */
4413 
4414 
4415  settings.beginGroup("/Fitting");
4416  fit_output_precision = settings.value("/OutputPrecision", 15).toInt();
4417  pasteFitResultsToPlot = settings.value("/PasteResultsToPlot", false).toBool();
4418  writeFitResultsToLog = settings.value("/WriteResultsToLog", true).toBool();
4419  generateUniformFitPoints = settings.value("/GenerateFunction", true).toBool();
4420  fitPoints = settings.value("/Points", 100).toInt();
4421  generatePeakCurves = settings.value("/GeneratePeakCurves", true).toBool();
4422  peakCurvesColor = QColor(COLORVALUE(settings.value("/PeaksColor", "#ff00ff00").toString()));//green color
4423  fit_scale_errors = settings.value("/ScaleErrors", false).toBool();
4424  d_2_linear_fit_points = settings.value("/TwoPointsLinearFit", true).toBool();
4425  settings.endGroup(); // Fitting
4426 
4427  settings.beginGroup("/ImportASCII");
4428  columnSeparator = settings.value("/ColumnSeparator", "\\t").toString();
4429  columnSeparator.replace("\\t", "\t").replace("\\s", " ");
4430  ignoredLines = settings.value("/IgnoreLines", 0).toInt();
4431  renameColumns = settings.value("/RenameColumns", true).toBool();
4432  strip_spaces = settings.value("/StripSpaces", false).toBool();
4433  simplify_spaces = settings.value("/SimplifySpaces", false).toBool();
4434  d_ASCII_file_filter = settings.value("/AsciiFileTypeFilter", "*").toString();
4435  d_ASCII_import_locale = settings.value("/AsciiImportLocale", "C").toString();
4436  d_convert_to_numeric = settings.value("/ConvertToNumeric", true).toBool();
4437  settings.endGroup(); // Import ASCII
4438 
4439  settings.beginGroup("/ExportImage");
4440  d_image_export_filter = settings.value("/ImageFileTypeFilter", ".png").toString();
4441  d_export_transparency = settings.value("/ExportTransparency", false).toBool();
4442  d_export_quality = settings.value("/ImageQuality", 100).toInt();
4443  d_export_resolution = settings.value("/Resolution", 72).toInt();
4444  d_export_color = settings.value("/ExportColor", true).toBool();
4445  d_export_vector_size = settings.value("/ExportPageSize", QPrinter::Custom).toInt();
4446  d_keep_plot_aspect = settings.value("/KeepAspect", true).toBool();
4447  d_export_orientation = settings.value("/Orientation", QPrinter::Landscape).toInt();
4448  settings.endGroup(); // ExportImage
4449 }
4450 
4452 {
4453 
4454 #ifdef Q_OS_MAC // Mac
4455  QSettings settings(QSettings::IniFormat,QSettings::UserScope, "SciDAVis", "SciDAVis");
4456 #else
4457  QSettings settings(QSettings::NativeFormat,QSettings::UserScope, "SciDAVis", "SciDAVis");
4458 #endif
4459 
4460  /* ---------------- group General --------------- */
4461  settings.beginGroup("/General");
4462 #ifdef SEARCH_FOR_UPDATES
4463  settings.setValue("/AutoSearchUpdates", autoSearchUpdates);
4464 #endif
4465  settings.setValue("/Language", appLanguage);
4466  settings.setValue("/ShowWindowsPolicy", show_windows_policy);
4467  settings.setValue("/RecentProjects", recentProjects);
4468  settings.setValue("/Style", appStyle);
4469  settings.setValue("/AutoSave", autoSave);
4470  settings.setValue("/AutoSaveTime", autoSaveTime);
4471  settings.setValue("/UndoLimit", undoLimit);
4472  settings.setValue("/ScriptingLang", defaultScriptingLang);
4473  settings.setValue("/Locale", QLocale().name());
4474  settings.setValue("/LocaleUseGroupSeparator", bool(!(QLocale().numberOptions() & QLocale::OmitGroupSeparator)));
4475  settings.setValue("/DecimalDigits", d_decimal_digits);
4476  settings.setValue("/DefaultNumericFormat", QChar(d_default_numeric_format));
4477 
4478  settings.setValue("/ProjectWindow/Geometry", saveGeometry());
4479  settings.setValue("/DockWindows", saveState());
4480  settings.setValue("/ExplorerSplitter", explorerSplitter->saveState());
4481 
4482  QStringList applicationFont;
4483  applicationFont<<appFont.family();
4484  applicationFont<<QString::number(appFont.pointSize());
4485  applicationFont<<QString::number(appFont.weight());
4486  applicationFont<<QString::number(appFont.italic());
4487  settings.setValue("/Font", applicationFont);
4488 
4489  settings.beginGroup("/Dialogs");
4490  settings.setValue("/ExtendedOpenDialog", d_extended_open_dialog);
4491  settings.setValue("/ExtendedExportDialog", d_extended_export_dialog);
4492  settings.setValue("/ExtendedImportAsciiDialog", d_extended_import_ASCII_dialog);
4493  settings.setValue("/ExtendedPlotDialog", d_extended_plot_dialog);
4494  settings.beginGroup("/AddRemoveCurves");
4495  settings.setValue("/Width", d_add_curves_dialog_size.width());
4496  settings.setValue("/Height", d_add_curves_dialog_size.height());
4497  settings.setValue("/ShowCurrentFolder", d_show_current_folder);
4498  settings.endGroup(); // AddRemoveCurves Dialog
4499  settings.endGroup(); // Dialogs
4500 
4501  settings.beginGroup("/Colors");
4502  settings.setValue("/Workspace", COLORNAME(workspaceColor));
4503  settings.setValue("/Panels", COLORNAME(panelsColor));
4504  settings.setValue("/PanelsText", COLORNAME(panelsTextColor));
4505  settings.endGroup(); // Colors
4506 
4507  settings.beginGroup("/Paths");
4508  settings.setValue("/WorkingDir", workingDir);
4509  settings.setValue("/TemplatesDir", templatesDir);
4510  settings.setValue("/HelpFile", helpFilePath);
4511  settings.setValue("/FitPlugins", fitPluginsPath);
4512  settings.setValue("/ASCII", asciiDirPath);
4513  settings.setValue("/Images", imagesDirPath);
4514 
4515  settings.setValue("LockToolbars", locktoolbar->isChecked());
4516 
4517  settings.endGroup(); // Paths
4518  settings.endGroup();
4519  /* ---------------- end group General --------------- */
4520 
4521  settings.beginGroup("/UserFunctions");
4522  settings.setValue("/FitFunctions", fitFunctions);
4523  settings.setValue("/SurfaceFunctions", surfaceFunc);
4524  settings.setValue("/xFunctions", xFunctions);
4525  settings.setValue("/yFunctions", yFunctions);
4526  settings.setValue("/rFunctions", rFunctions);
4527  settings.setValue("/thetaFunctions", thetaFunctions);
4528  settings.endGroup(); // UserFunctions
4529 
4530  settings.beginGroup("/Confirmations");
4531  settings.setValue("/Folder", confirmCloseFolder);
4532  settings.setValue("/Table", confirmCloseTable);
4533  settings.setValue("/Matrix", confirmCloseMatrix);
4534  settings.setValue("/Plot2D", confirmClosePlot2D);
4535  settings.setValue("/Plot3D", confirmClosePlot3D);
4536  settings.setValue("/Note", confirmCloseNotes);
4537  settings.endGroup(); // Confirmations
4538 
4539  /* ----------------- group Tables -------------- */
4540  settings.beginGroup("/Tables");
4541  settings.setValue("/DisplayComments", d_show_table_comments);
4542  QStringList tableFonts;
4543  tableFonts<<tableTextFont.family();
4544  tableFonts<<QString::number(tableTextFont.pointSize());
4545  tableFonts<<QString::number(tableTextFont.weight());
4546  tableFonts<<QString::number(tableTextFont.italic());
4547  tableFonts<<tableHeaderFont.family();
4548  tableFonts<<QString::number(tableHeaderFont.pointSize());
4549  tableFonts<<QString::number(tableHeaderFont.weight());
4550  tableFonts<<QString::number(tableHeaderFont.italic());
4551  settings.setValue("/Fonts", tableFonts);
4552 
4553  settings.beginGroup("/Colors");
4554  settings.setValue("/Background", COLORNAME(tableBkgdColor));
4555  settings.setValue("/Text", COLORNAME(tableTextColor));
4556  settings.setValue("/Header", COLORNAME(tableHeaderColor));
4557  settings.endGroup(); // Colors
4558  settings.endGroup();
4559  /* ----------------- end group Tables ---------- */
4560 
4561  /* ----------------- group 2D Plots ------------ */
4562  settings.beginGroup("/2DPlots");
4563  settings.beginGroup("/General");
4564  settings.setValue("/Title", titleOn);
4565  settings.setValue("/AllAxes", allAxesOn);
4566  settings.setValue("/CanvasFrame", canvasFrameOn);
4567  settings.setValue("/CanvasFrameWidth", canvasFrameWidth);
4568  settings.setValue("/Margin", defaultPlotMargin);
4569  settings.setValue("/AxesBackbones", drawBackbones);
4570  settings.setValue("/AxesLineWidth", axesLineWidth);
4571  settings.setValue("/Autoscale", autoscale2DPlots);
4572  settings.setValue("/AutoScaleFonts", autoScaleFonts);
4573  settings.setValue("/AutoResizeLayers", autoResizeLayers);
4574  settings.setValue("/Antialiasing", antialiasing2DPlots);
4575  settings.setValue("/ScaleLayersOnPrint", d_scale_plots_on_print);
4576  settings.setValue("/PrintCropmarks", d_print_cropmarks);
4577 
4578  QStringList graphFonts;
4579  graphFonts<<plotAxesFont.family();
4580  graphFonts<<QString::number(plotAxesFont.pointSize());
4581  graphFonts<<QString::number(plotAxesFont.weight());
4582  graphFonts<<QString::number(plotAxesFont.italic());
4583  graphFonts<<plotNumbersFont.family();
4584  graphFonts<<QString::number(plotNumbersFont.pointSize());
4585  graphFonts<<QString::number(plotNumbersFont.weight());
4586  graphFonts<<QString::number(plotNumbersFont.italic());
4587  graphFonts<<plotLegendFont.family();
4588  graphFonts<<QString::number(plotLegendFont.pointSize());
4589  graphFonts<<QString::number(plotLegendFont.weight());
4590  graphFonts<<QString::number(plotLegendFont.italic());
4591  graphFonts<<plotTitleFont.family();
4592  graphFonts<<QString::number(plotTitleFont.pointSize());
4593  graphFonts<<QString::number(plotTitleFont.weight());
4594  graphFonts<<QString::number(plotTitleFont.italic());
4595  settings.setValue("/Fonts", graphFonts);
4596  settings.endGroup(); // General
4597 
4598  settings.beginGroup("/Curves");
4599  settings.setValue("/Style", defaultCurveStyle);
4600  settings.setValue("/LineWidth", defaultCurveLineWidth);
4601  settings.setValue("/SymbolSize", defaultSymbolSize);
4602  settings.endGroup(); // Curves
4603 
4604  settings.beginGroup("/Ticks");
4605  settings.setValue ("/MajTicksStyle", majTicksStyle);
4606  settings.setValue ("/MinTicksStyle", minTicksStyle);
4607  settings.setValue("/MinTicksLength", minTicksLength);
4608  settings.setValue("/MajTicksLength", majTicksLength);
4609  settings.endGroup(); // Ticks
4610 
4611  settings.beginGroup("/Legend");
4612  settings.setValue("/FrameStyle", legendFrameStyle);
4613  settings.setValue("/TextColor", COLORNAME(legendTextColor));
4614  settings.setValue("/BackgroundColor", COLORNAME(legendBackground));
4615  settings.setValue("/Transparency", legendBackground.alpha());
4616  settings.endGroup(); // Legend
4617 
4618  settings.beginGroup("/Arrows");
4619  settings.setValue("/Width", defaultArrowLineWidth);
4620  settings.setValue("/Color", COLORNAME(defaultArrowColor));
4621  settings.setValue("/HeadLength", defaultArrowHeadLength);
4622  settings.setValue("/HeadAngle", defaultArrowHeadAngle);
4623  settings.setValue("/HeadFill", defaultArrowHeadFill);
4624  settings.setValue("/LineStyle", Graph::penStyleName(defaultArrowLineStyle));
4625  settings.endGroup(); // Arrows
4626  settings.endGroup();
4627  /* ----------------- end group 2D Plots -------- */
4628 
4629  /* ----------------- group 3D Plots ------------ */
4630  settings.beginGroup("/3DPlots");
4631  settings.setValue("/Legend", showPlot3DLegend);
4632  settings.setValue("/Projection", showPlot3DProjection);
4633  settings.setValue("/Antialiasing", smooth3DMesh);
4634  settings.setValue("/Resolution", plot3DResolution);
4635  settings.setValue("/Orthogonal", orthogonal3DPlots);
4636  settings.setValue("/Autoscale", autoscale3DPlots);
4637 
4638  QStringList plot3DFonts;
4639  plot3DFonts<<plot3DTitleFont.family();
4640  plot3DFonts<<QString::number(plot3DTitleFont.pointSize());
4641  plot3DFonts<<QString::number(plot3DTitleFont.weight());
4642  plot3DFonts<<QString::number(plot3DTitleFont.italic());
4643  plot3DFonts<<plot3DNumbersFont.family();
4644  plot3DFonts<<QString::number(plot3DNumbersFont.pointSize());
4645  plot3DFonts<<QString::number(plot3DNumbersFont.weight());
4646  plot3DFonts<<QString::number(plot3DNumbersFont.italic());
4647  plot3DFonts<<plot3DAxesFont.family();
4648  plot3DFonts<<QString::number(plot3DAxesFont.pointSize());
4649  plot3DFonts<<QString::number(plot3DAxesFont.weight());
4650  plot3DFonts<<QString::number(plot3DAxesFont.italic());
4651  settings.setValue("/Fonts", plot3DFonts);
4652 
4653  settings.beginGroup("/Colors");
4654  settings.setValue("/MaxData", plot3DColors[0]);
4655  settings.setValue("/Labels", plot3DColors[1]);
4656  settings.setValue("/Mesh", plot3DColors[2]);
4657  settings.setValue("/Grid", plot3DColors[3]);
4658  settings.setValue("/MinData", plot3DColors[4]);
4659  settings.setValue("/Numbers", plot3DColors[5]);
4660  settings.setValue("/Axes", plot3DColors[6]);
4661  settings.setValue("/Background", plot3DColors[7]);
4662  settings.endGroup(); // Colors
4663  settings.endGroup();
4664  /* ----------------- end group 2D Plots -------- */
4665 
4666  settings.beginGroup("/Fitting");
4667  settings.setValue("/OutputPrecision", fit_output_precision);
4668  settings.setValue("/PasteResultsToPlot", pasteFitResultsToPlot);
4669  settings.setValue("/WriteResultsToLog", writeFitResultsToLog);
4670  settings.setValue("/GenerateFunction", generateUniformFitPoints);
4671  settings.setValue("/Points", fitPoints);
4672  settings.setValue("/GeneratePeakCurves", generatePeakCurves);
4673  settings.setValue("/PeaksColor", COLORNAME(peakCurvesColor));
4674  settings.setValue("/ScaleErrors", fit_scale_errors);
4675  settings.setValue("/TwoPointsLinearFit", d_2_linear_fit_points);
4676  settings.endGroup(); // Fitting
4677 
4678  settings.beginGroup("/ImportASCII");
4679  QString sep = columnSeparator;
4680  settings.setValue("/ColumnSeparator", sep.replace("\t", "\\t").replace(" ", "\\s"));
4681  settings.setValue("/IgnoreLines", ignoredLines);
4682  settings.setValue("/RenameColumns", renameColumns);
4683  settings.setValue("/StripSpaces", strip_spaces);
4684  settings.setValue("/SimplifySpaces", simplify_spaces);
4685  settings.setValue("/AsciiFileTypeFilter", d_ASCII_file_filter);
4686  settings.setValue("/AsciiImportLocale", d_ASCII_import_locale.name());
4687  settings.setValue("/ConvertToNumeric", d_convert_to_numeric);
4688  settings.endGroup(); // ImportASCII
4689 
4690  settings.beginGroup("/ExportImage");
4691  settings.setValue("/ImageFileTypeFilter", d_image_export_filter);
4692  settings.setValue("/ExportTransparency", d_export_transparency);
4693  settings.setValue("/ImageQuality", d_export_quality);
4694  settings.setValue("/Resolution", d_export_resolution);
4695  settings.setValue("/ExportColor", d_export_color);
4696  settings.setValue("/ExportPageSize", d_export_vector_size);
4697  settings.setValue("/KeepAspect", d_keep_plot_aspect);
4698  settings.setValue("/Orientation", d_export_orientation);
4699  settings.endGroup(); // ExportImage
4700 }
4701 
4703 {
4704  QWidget *w = d_workspace.activeSubWindow();
4705  if (!w)
4706  return;
4707 
4708  MultiLayer *plot2D = 0;
4709  Graph3D *plot3D = 0;
4710  if(w->inherits("MultiLayer"))
4711  {
4712  plot2D = (MultiLayer*)w;
4713  if (plot2D->isEmpty())
4714  {
4715  QMessageBox::critical(this, tr("Export Error"),
4716  tr("<h4>There are no plot layers available in this window!</h4>"));
4717  return;
4718  }
4719  }
4720  else if (w->inherits("Graph3D"))
4721  plot3D = (Graph3D*)w;
4722  else
4723  return;
4724 
4726  ied->setDirectory(workingDir);
4728  if ( ied->exec() != QDialog::Accepted )
4729  return;
4730  workingDir = ied->directory().path();
4731  if (ied->selectedFiles().isEmpty())
4732  return;
4733 
4734  QString selected_filter = ied->selectedNameFilter();
4735  QString file_name = ied->selectedFiles()[0];
4736  QFileInfo file_info(file_name);
4737  if (!file_info.fileName().contains("."))
4738  file_name.append(selected_filter.remove("*"));
4739 
4740  QFile file(file_name);
4741  if ( !file.open( QIODevice::WriteOnly ) )
4742  {
4743  QMessageBox::critical(this, tr("Export Error"),
4744  tr("Could not write to file: <br><h4> %1 </h4><p>Please verify that you have the right to write to this location!").arg(file_name));
4745  return;
4746  }
4747 
4748  if (selected_filter.contains(".eps") || selected_filter.contains(".pdf") || selected_filter.contains(".ps")) {
4749  if (plot3D)
4750  plot3D->exportVector(file_name, selected_filter.remove("*."));
4751  else if (plot2D)
4752  plot2D->exportVector(file_name, ied->resolution(), ied->color(), ied->keepAspect(), ied->pageSize(), ied->pageOrientation());
4753  } else if (selected_filter.contains(".svg")) {
4754  if (plot2D)
4755  plot2D->exportSVG(file_name);
4756  else
4757  plot3D->exportVector(file_name,".svg");
4758  } else {
4759  QList<QByteArray> list = QImageWriter::supportedImageFormats();
4760  for (int i=0; i<(int)list.count(); i++)
4761  {
4762  if (selected_filter.contains("." + (list[i]).toLower())) {
4763  if (plot2D)
4764  plot2D->exportImage(file_name, ied->quality());
4765  else if (plot3D)
4766  plot3D->exportImage(file_name, ied->quality());
4767  }
4768  }
4769  }
4770 }
4771 
4773 {
4774  QWidget *w=d_workspace.activeSubWindow();
4775  if (!w || !w->inherits("MultiLayer"))
4776  return;
4777 
4778  Graph* g = ((MultiLayer*)w)->activeGraph();
4779  if (!g)
4780  return;
4781 
4783  ied->setDirectory(workingDir);
4785  if ( ied->exec() != QDialog::Accepted )
4786  return;
4787  workingDir = ied->directory().path();
4788  if (ied->selectedFiles().isEmpty())
4789  return;
4790 
4791  QString selected_filter = ied->selectedNameFilter();
4792  QString file_name = ied->selectedFiles()[0];
4793  QFileInfo file_info(file_name);
4794  if (!file_info.fileName().contains("."))
4795  file_name.append(selected_filter.remove("*"));
4796 
4797  QFile file(file_name);
4798  if ( !file.open( QIODevice::WriteOnly ) )
4799  {
4800  QMessageBox::critical(this, tr("Export Error"),
4801  tr("Could not write to file: <br><h4> %1 </h4><p>Please verify that you have the right to write to this location!").arg(file_name));
4802  return;
4803  }
4804 
4805  if (selected_filter.contains(".eps") || selected_filter.contains(".pdf") || selected_filter.contains(".ps"))
4806  g->exportVector(file_name, ied->resolution(), ied->color(), ied->keepAspect(), ied->pageSize(), ied->pageOrientation());
4807  else if (selected_filter.contains(".svg"))
4808  g->exportSVG(file_name);
4809  else {
4810  QList<QByteArray> list = QImageWriter::supportedImageFormats();
4811  for (int i=0; i<(int)list.count(); i++)
4812  if (selected_filter.contains("."+(list[i]).toLower()))
4813  g->exportImage(file_name, ied->quality());
4814  }
4815 }
4816 
4818 {
4820  ied->setWindowTitle(tr("Choose a directory to export the graphs to"));
4821  QStringList tmp = ied->nameFilters();
4822  ied->setFileMode(QFileDialog::Directory);
4823  ied->setNameFilters(tmp);
4824  ied->setLabelText(QFileDialog::FileType, tr("Output format:"));
4825  ied->setLabelText(QFileDialog::FileName, tr("Directory:"));
4826 
4827  ied->setDirectory(workingDir);
4829 
4830  if ( ied->exec() != QDialog::Accepted )
4831  return;
4832  workingDir = ied->directory().path();
4833  if (ied->selectedFiles().isEmpty())
4834  return;
4835 
4836  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
4837 
4838  QString output_dir = ied->selectedFiles()[0];
4839  QString file_suffix = ied->selectedNameFilter();
4840  file_suffix=file_suffix.toLower();
4841  file_suffix.remove("*");
4842 
4843  QList<MyWidget*> windows = windowsList();
4844  bool confirm_overwrite = true;
4845  MultiLayer *plot2D;
4846  Graph3D *plot3D;
4847 
4848  foreach (MyWidget *w, windows)
4849  {
4850  if (w->inherits("MultiLayer")) {
4851  plot3D = 0;
4852  plot2D = (MultiLayer *)w;
4853  if (plot2D->isEmpty()) {
4854  QApplication::restoreOverrideCursor();
4855  QMessageBox::warning(this, tr("Warning"),
4856  tr("There are no plot layers available in window <b>%1</b>.<br>"
4857  "Graph window not exported!").arg(plot2D->name()));
4858  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
4859  continue;
4860  }
4861  } else if (w->inherits("Graph3D")) {
4862  plot2D = 0;
4863  plot3D = (Graph3D *)w;
4864  } else
4865  continue;
4866 
4867  QString file_name = output_dir + "/" + w->objectName() + file_suffix;
4868  QFile f(file_name);
4869  if (f.exists() && confirm_overwrite) {
4870  QApplication::restoreOverrideCursor();
4871  switch(QMessageBox::question(this, tr("Overwrite file?"),
4872  tr("A file called: <p><b>%1</b><p>already exists. "
4873  "Do you want to overwrite it?") .arg(file_name), tr("&Yes"), tr("&All"), tr("&Cancel"), 0, 1)) {
4874  case 1:
4875  confirm_overwrite = false;
4876  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
4877  break;
4878  case 0:
4879  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
4880  break;
4881  case 2:
4882  return;
4883  }
4884  }
4885  if ( !f.open( QIODevice::WriteOnly ) ) {
4886  QApplication::restoreOverrideCursor();
4887  QMessageBox::critical(this, tr("Export Error"),
4888  tr("Could not write to file: <br><h4>%1</h4><p>"
4889  "Please verify that you have the right to write to this location!").arg(file_name));
4890  return;
4891  }
4892  if (file_suffix.contains(".eps") || file_suffix.contains(".pdf") || file_suffix.contains(".ps")) {
4893  if (plot3D)
4894  plot3D->exportVector(file_name, file_suffix.remove("."));
4895  else if (plot2D)
4896  plot2D->exportVector(file_name, ied->resolution(), ied->color());
4897  } else if (file_suffix.contains(".svg")) {
4898  if (plot2D)
4899  plot2D->exportSVG(file_name);
4900  } else {
4901  QList<QByteArray> list = QImageWriter::supportedImageFormats();
4902  for (int i=0; i<(int)list.count(); i++)
4903  {
4904  if (file_suffix.contains("." + (list[i]).toLower())) {
4905  if (plot2D)
4906  plot2D->exportImage(file_name, ied->quality());
4907  else if (plot3D)
4908  plot3D->exportImage(file_name, ied->quality());
4909  }
4910  }
4911  }
4912  }
4913 
4914  QApplication::restoreOverrideCursor();
4915 }
4916 
4918 {
4919  QString s = "geometry\t";
4920  if (w->status() == MyWidget::Maximized)
4921  {
4922  if (w == w->folder()->activeWindow())
4923  return s + "maximized\tactive\n";
4924  else
4925  return s + "maximized\n";
4926  }
4927 
4928  if (!w->parent())
4929  s+="0\t0\t500\t400\t";
4930  else
4931  {
4932  QPoint p = w->pos();// store position
4933  s+=QString::number(p.x())+"\t";
4934  s+=QString::number(p.y())+"\t";
4935  s+=QString::number(w->frameGeometry().width())+"\t";
4936  s+=QString::number(w->frameGeometry().height())+"\t";
4937  }
4938 
4939  if (w->status() == MyWidget::Minimized)
4940  s += "minimized\t";
4941 
4942  bool hide = hidden(w);
4943  if (w == w->folder()->activeWindow() && !hide)
4944  s+="active\n";
4945  else if(hide)
4946  s+="hidden\n";
4947  else
4948  s+="\n";
4949  return s;
4950 }
4951 
4953 {
4954  w->blockSignals (true);
4955  QString caption = w->name();
4956  if (s.contains ("minimized"))
4957  {
4958  QStringList lst = s.split("\t");
4959  if (lst.count() > 4)
4960  w->setGeometry(lst[1].toInt(),lst[2].toInt(),lst[3].toInt(),lst[4].toInt());
4962  app->setListView(caption, tr("Minimized"));
4963  }
4964  else if (s.contains ("maximized"))
4965  {
4967  app->setListView(caption, tr("Maximized"));
4968  }
4969  else
4970  {
4971  QStringList lst = s.split("\t");
4972  w->setGeometry(lst[1].toInt(),lst[2].toInt(),lst[3].toInt(),lst[4].toInt());
4974 
4975  if (lst.count() > 5)
4976  {
4977  if (lst[5] == "hidden")
4978  app->hideWindow(w);
4979  }
4980  }
4981 
4982  if (s.contains ("active"))
4983  {
4984  Folder *f = w->folder();
4985  if (f)
4986  f->setActiveWindow(w);
4987  }
4988 
4989  w->blockSignals (false);
4990 }
4991 
4993 {
4994  return ((FolderListItem *)folders.topLevelItem(0))->folder();
4995 }
4996 
4998 {
4999  if (projectname == "untitled" || projectname.endsWith(".opj", Qt::CaseInsensitive) ||
5000  projectname.endsWith(".ogm", Qt::CaseInsensitive) || projectname.endsWith(".ogw", Qt::CaseInsensitive)
5001  || projectname.endsWith(".ogg", Qt::CaseInsensitive) || projectname.endsWith(".org", Qt::CaseInsensitive))
5002  {
5003  saveProjectAs();
5004  return false;
5005  }
5006 
5007  bool compress = false;
5008  QString fn = projectname;
5009  if (fn.endsWith(".gz"))
5010  {
5011  fn = fn.left(fn.length() -3);
5012  compress = true;
5013  }
5014 
5015  saveFolder(projectFolder(), fn);
5016 
5017  if (compress)
5018  file_compress(QFile::encodeName(fn).constData(), "wb9");
5019 
5020  setWindowTitle("SciDAVis - " + projectname);
5021  savedProject();
5022  actionUndo->setEnabled(false);
5023  actionRedo->setEnabled(false);
5024 
5025  if (autoSave)
5026  {
5027  if (savingTimerId)
5028  killTimer(savingTimerId);
5029  savingTimerId=startTimer(autoSaveTime*60000);
5030  }
5031  else
5032  savingTimerId=0;
5033 
5034  QApplication::restoreOverrideCursor();
5035  return true;
5036 }
5037 
5039 {
5040  QString filter = tr("SciDAVis project")+" (*.sciprj);;";
5041  filter += tr("Compressed SciDAVis project")+" (*.sciprj.gz)";
5042 
5043  QString selectedFilter;
5044  QString fn = QFileDialog::getSaveFileName(this, tr("Save Project As"), workingDir, filter, &selectedFilter);
5045  if ( !fn.isEmpty() )
5046  {
5047  QFileInfo fi(fn);
5048  workingDir = fi.absolutePath();
5049  QString baseName = fi.fileName();
5050  if (!baseName.endsWith(".sciprj") && !baseName.endsWith(".sciprj.gz"))
5051  {
5052  fn.append(".sciprj");
5053  if (selectedFilter.contains(".gz"))
5054  fn.append(".gz");
5055  }
5056  projectname = fn;
5057 
5058  if (saveProject())
5059  {
5060  recentProjects.removeAll(fn);
5061  recentProjects.push_front(fn);
5063 
5064  QFileInfo fi(fn);
5065  QString baseName = fi.baseName();
5066  FolderListItem *item = (FolderListItem *)folders.topLevelItem(0);
5067  item->setText(0, baseName);
5068  item->folder()->setName(baseName);
5069  }
5070  }
5071 }
5072 
5074 {
5075  Note* w = (Note*)d_workspace.activeSubWindow();
5076  if (!w || !w->inherits("Note"))
5077  return;
5078  w->exportASCII();
5079 }
5080 
5082 {
5083  MyWidget* w = (MyWidget*)d_workspace.activeSubWindow();
5084  if (!w)
5085  return;
5086 
5087  QString filter;
5088  if (w->inherits("Matrix"))
5089  filter = tr("SciDAVis/QtiPlot Matrix Template")+" (*.qmt)";
5090  else if (w->inherits("MultiLayer"))
5091  filter = tr("SciDAVis/QtiPlot 2D Graph Template")+" (*.qpt)";
5092  else if (w->inherits("Table"))
5093  filter = tr("SciDAVis/QtiPlot Table Template")+" (*.qtt)";
5094  else if (w->inherits("Graph3D"))
5095  filter = tr("SciDAVis/QtiPlot 3D Surface Template")+" (*.qst)";
5096 
5097  QString selectedFilter;
5098  QString fn = QFileDialog::getSaveFileName(this, tr("Save Window As Template"), templatesDir + "/" + w->name(), filter, &selectedFilter);
5099  if ( !fn.isEmpty() )
5100  {
5101  QFileInfo fi(fn);
5102  workingDir = fi.absolutePath();
5103  QString baseName = fi.fileName();
5104  if (!baseName.contains("."))
5105  {
5106  selectedFilter = selectedFilter.right(5).left(4);
5107  fn.append(selectedFilter);
5108  }
5109 
5110  QFile f(fn);
5111  if ( !f.open( QIODevice::WriteOnly ) )
5112  {
5113  QMessageBox::critical(this, tr("Export Error"),
5114  tr("Could not write to file: <br><h4> %1 </h4><p>Please verify that you have the right to write to this location!").arg(fn));
5115  return;
5116  }
5117  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
5118  QString text = SciDAVis::schemaVersion() + " template file\n";
5119  text += w->saveAsTemplate(windowGeometryInfo(w));
5120  QTextStream t( &f );
5121  t.setCodec(QTextCodec::codecForName("UTF-8"));
5122  t << text;
5123  f.close();
5124  QApplication::restoreOverrideCursor();
5125  }
5126 }
5127 
5129 {
5130  MyWidget* m = (MyWidget*)d_workspace.activeSubWindow();
5131  if (!m)
5132  return;
5133 
5134  RenameWindowDialog *rwd = new RenameWindowDialog(this);
5135  rwd->setAttribute(Qt::WA_DeleteOnClose);
5136  rwd->setWidget(m);
5137  rwd->exec();
5138 }
5139 
5140 void ApplicationWindow::renameWindow(QTreeWidgetItem *item, int, const QString &text)
5141 {
5142  if (auto wli=dynamic_cast<WindowListItem*>(item))
5143  if (auto w=wli->window())
5144  if (text!=w->name())
5145  renameWindow(w, text);
5146 }
5147 
5148 bool ApplicationWindow::renameWindow(MyWidget *w, const QString &text)
5149 {
5150  if (!w)
5151  return false;
5152 
5153  QString name = w->name();
5154 
5155  QString newName = text;
5156  newName.replace("-", "_");
5157  if (newName.isEmpty()){
5158  QMessageBox::critical(this, tr("Error"), tr("Please enter a valid name!"));
5159  return false;
5160  }
5161  else if (newName.contains(QRegExp("\\W"))){
5162  QMessageBox::critical(this, tr("Error"),
5163  tr("The name you chose is not valid: only letters and digits are allowed!")+
5164  "<p>" + tr("Please choose another name!"));
5165  return false;
5166  }
5167 
5168  newName.replace("_", "-");
5169 
5170  while(alreadyUsedName(newName)){
5171  QMessageBox::critical(this, tr("Error"), tr("Name <b>%1</b> already exists!").arg(newName)+
5172  "<p>"+tr("Please choose another name!")+
5173  "<p>"+tr("Warning: for internal consistency reasons the underscore character is replaced with a minus sign."));
5174  return false;
5175  }
5176 
5177  if (w->inherits("Table")){
5178  QStringList labels=((Table *)w)->colNames();
5179  if (labels.contains(newName)>0){
5180  QMessageBox::critical(this, tr("Error"),
5181  tr("The table name must be different from the names of its columns!")+"<p>"+tr("Please choose another name!"));
5182  return false;
5183  }
5184 
5185  updateTableNames(name,newName);
5186  }
5187  else if (w->inherits("Matrix"))
5188  changeMatrixName(name, newName);
5189 
5190  w->setName(newName);
5192  renameListViewItem(name, newName);
5193  return true;
5194 }
5195 
5196  // TODO: string list -> Column * list
5198 {
5199  QList<MyWidget*> windows = windowsList();
5200  QStringList list;
5201  foreach (MyWidget *w, windows)
5202  {
5203  if (!w->inherits("Table"))
5204  continue;
5205 
5206  Table *t = (Table *)w;
5207  for (int i=0; i < t->numCols(); i++)
5208  {
5209  if (t->colPlotDesignation(i) == plotType)
5210  list << QString(t->name()) + "_" + t->colLabel(i);
5211  }
5212  }
5213 
5214  return list;
5215 }
5216 
5217  // TODO: string list -> Column * list
5219 {
5220  QList<MyWidget*> windows = windowsList();
5221  QStringList list;
5222  foreach (MyWidget *w, windows)
5223  {
5224  if (!w->inherits("Table"))
5225  continue;
5226 
5227  Table *t = (Table *)w;
5228  for (int i=0; i < t->numCols(); i++)
5229  {
5230  list << QString(t->name()) + "_" + t->colLabel(i);
5231  }
5232  }
5233 
5234  return list;
5235 }
5236 
5238 {
5239  if (!d_workspace.activeSubWindow() || !d_workspace.activeSubWindow()->inherits("MultiLayer"))
5240  return;
5241 
5242  if (((MultiLayer*)d_workspace.activeSubWindow())->isEmpty()){
5243  QMessageBox::warning(this,tr("Error"),
5244  tr("<h4>There are no plot layers available in this window.</h4>"
5245  "<p><h4>Please add a layer and try again!</h4>"));
5246  return;
5247  }
5248 
5249  Graph* g = ((MultiLayer*)d_workspace.activeSubWindow())->activeGraph();
5250  if (!g)
5251  return;
5252 
5253  if (g->isPiePlot()){
5254  QMessageBox::warning(this,tr("Error"),
5255  tr("This functionality is not available for pie plots!"