1 /***************************************************************************
2 * *
3 * copyright : (C) 2007 The University of Toronto *
4 * netterfield@astro.utoronto.ca *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 ***************************************************************************/
12
13 #include "mainwindow.h"
14 #include "boxitem.h"
15 #include "datamanager.h"
16 #include "debugdialog.h"
17 #include "debugnotifier.h"
18 #include "document.h"
19 #include "ellipseitem.h"
20 #include "exportgraphicsdialog.h"
21 #include "exportvectorsdialog.h"
22 #include "logdialog.h"
23 #include "application.h"
24 #include "debug.h"
25 #include "labelitem.h"
26 #include "lineitem.h"
27 #include "circleitem.h"
28 #include "arrowitem.h"
29 #include "memorywidget.h"
30 #include "objectstore.h"
31 #include "pictureitem.h"
32 #include "plotitem.h"
33 #include "plotitemmanager.h"
34 #include "svgitem.h"
35 #include "tabwidget.h"
36 #include "sharedaxisboxitem.h"
37 #include "ui_aboutdialog.h"
38 #include "viewvectordialog.h"
39 #include "viewmatrixdialog.h"
40 #include "viewprimitivedialog.h"
41 #include "view.h"
42 #include "applicationsettings.h"
43 #include "updatemanager.h"
44 #include "datasourcepluginmanager.h"
45 #include "pluginmenuitemaction.h"
46
47 #include "applicationsettingsdialog.h"
48 #include "themedialog.h"
49 #include "differentiatecurvesdialog.h"
50 #include "filtermultipledialog.h"
51 #include "choosecolordialog.h"
52 #include "changedatasampledialog.h"
53 #include "changefiledialog.h"
54 #include "bugreportwizard.h"
55 #include "datawizard.h"
56 #include "aboutdialog.h"
57 #include "shortcutdialog.h"
58 #include "datavector.h"
59 #include "commandlineparser.h"
60 #include "dialogdefaults.h"
61 #include "settings.h"
62
63 #include "dialoglauncher.h"
64 #include "scriptserver.h"
65
66 #include "geticon.h"
67
68 #ifndef KST_NO_SVG
69 #include <QSvgGenerator>
70 #endif
71
72 #include <QUndoGroup>
73 #ifndef KST_NO_PRINTER
74 #include <QPrintDialog>
75 #endif
76 #include <QMenuBar>
77 #include <QStatusBar>
78 #include <QProgressBar>
79 #include <QMessageBox>
80 #include <QImageWriter>
81 #include <QToolBar>
82 #include <QDebug>
83 #include <QDesktopServices>
84 #include <QSignalMapper>
85 #include <QClipboard>
86
87 namespace Kst {
88
MainWindow()89 MainWindow::MainWindow() :
90 _settings(createSettings("application")),
91 _dataManager(0),
92 _exportGraphics(0),
93 _exportVectors(0),
94 _logDialog(0),
95 _differentiateCurvesDialog(0),
96 _filterMultipleDialog(0),
97 _chooseColorDialog(0),
98 _changeDataSampleDialog(0),
99 _changeFileDialog(0),
100 _bugReportWizard(0),
101 _applicationSettingsDialog(0),
102 _themeDialog(0),
103 _aboutDialog(0),
104 _shortcutDialog(0),
105 _viewVectorDialog(0),
106 _highlightPoint(false),
107 _statusBarTimeout(0),
108 #if defined(__QNX__)
109 qnxToolbarsVisible(true),
110 #endif
111 _ae_width(1280),
112 _ae_height(1024),
113 _ae_display(2),
114 _ae_export_all(false),
115 _ae_autosave_period(0),
116 _ae_Timer(0),
117 _sessionFileName(QString())
118 {
119 _doc = new Document(this);
120 _scriptServer = new ScriptServer(_doc->objectStore());
121 _videoMapper = new QSignalMapper(this);
122
123 _tabWidget = new TabWidget(this);
124 _undoGroup = new QUndoGroup(this);
125 _debugDialog = new DebugDialog(this);
126
127 Debug::self()->setHandler(_debugDialog);
128
129 setKstWindowTitle();
130
131 createActions();
132 createMenus();
133 createToolBars();
134 createStatusBar();
135
136 _tabWidget->createView();
137
138 setCentralWidget(_tabWidget);
139 _tabWidget->setAcceptDrops(false); // Force drops to be passed to parent
140 connect(_tabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentViewChanged()));
141 connect(_tabWidget, SIGNAL(currentViewModeChanged()), this, SLOT(currentViewModeChanged()));
142 connect(PlotItemManager::self(), SIGNAL(tiedZoomRemoved()), this, SLOT(tiedZoomRemoved()));
143 connect(PlotItemManager::self(), SIGNAL(allPlotsTiedZoom()), this, SLOT(allPlotsTiedZoom()));
144
145 readSettings();
146 connect(UpdateManager::self(), SIGNAL(objectsUpdated(qint64)), this, SLOT(updateViewItems(qint64)));
147
148 QTimer::singleShot(0, this, SLOT(performHeavyStartupActions()));
149
150 updateRecentKstFiles();
151 setAcceptDrops(true);
152
153 #if defined(__QNX__)
154 // We want to be able to intercept bezel gestures, which show up in Qt as menu button keyPressEvents.
155 qApp->installEventFilter(this);
156 qnxToggleToolbarVisibility();
157 #endif
158
159 }
160
161
~MainWindow()162 MainWindow::~MainWindow() {
163 delete _dataManager;
164 _dataManager = 0;
165 delete _doc;
166 _doc = 0;
167 delete _viewVectorDialog;
168 _viewVectorDialog = 0;
169 delete _scriptServer;
170 _scriptServer = 0;
171 }
172
173
performHeavyStartupActions()174 void MainWindow::performHeavyStartupActions() {
175 // Set the timer for the UpdateManager.
176 UpdateManager::self()->setMinimumUpdatePeriod(ApplicationSettings::self()->minimumUpdatePeriod());
177 DataObject::init();
178 DataSourcePluginManager::init();
179 }
180
cleanup()181 void MainWindow::cleanup() {
182 if (document() && document()->objectStore()) {
183 document()->objectStore()->clear();
184 }
185 }
186
187
setLayoutMode(bool layoutMode)188 void MainWindow::setLayoutMode(bool layoutMode) {
189 foreach (View *v, tabWidget()->views() ) {
190
191 Q_ASSERT(v);
192
193 if (layoutMode) {
194 v->setViewMode(View::Layout);
195 _highlightPointAct->setEnabled(false);
196 _tiedZoomAct->setEnabled(false);
197 } else {
198 v->setViewMode(View::Data);
199 _highlightPointAct->setEnabled(true);
200 _tiedZoomAct->setEnabled(true);
201 }
202 }
203 }
204
setHighlightPoint(bool highlight)205 void MainWindow::setHighlightPoint(bool highlight) {
206 _highlightPoint = highlight;
207 }
208
changeZoomOnlyMode(QAction * act)209 void MainWindow::changeZoomOnlyMode(QAction* act) {
210 if (act == _layoutModeAct && act->isChecked()) {
211 setLayoutMode(true);
212 } else {
213 setLayoutMode(false);
214 }
215 foreach (View *view, tabWidget()->views() ) {
216 view->setZoomOnly((View::ZoomOnlyMode)act->data().toInt());
217 }
218
219 }
220
toggleTiedZoom()221 void MainWindow::toggleTiedZoom() {
222 if (isTiedTabs()) {
223 PlotItemManager::self()->toggleAllTiedZoom(0);
224 /*
225 QList<View*> views = tabWidget()->views();
226 foreach (View* view, views) {
227 PlotItemManager::self()->toggleAllTiedZoom(view);
228 }
229 */
230 } else {
231 PlotItemManager::self()->toggleAllTiedZoom(tabWidget()->currentView());
232 }
233 }
234
tiedZoomRemoved()235 void MainWindow::tiedZoomRemoved() {
236 _tiedZoomAct->setChecked(false);
237 }
238
239
allPlotsTiedZoom()240 void MainWindow::allPlotsTiedZoom() {
241 _tiedZoomAct->setChecked(true);
242 }
243
244
promptSaveDone()245 bool MainWindow::promptSaveDone() {
246 if (! _doc->isChanged()) {
247 return true; // No need to ask if there is no unsaved change -> we're done
248 }
249 else { // Changes registered: ask the user
250 int rc = QMessageBox::warning(this, tr("Kst: Save Prompt"), tr("Your document has been modified.\nSave changes?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save);
251 if (rc == QMessageBox::Save) {
252 save();
253 } else if (rc == QMessageBox::Cancel) {
254 return false;
255 }
256 return true;
257 }
258 }
259
260
closeEvent(QCloseEvent * e)261 void MainWindow::closeEvent(QCloseEvent *e) {
262 if (!promptSaveDone()) {
263 e->ignore();
264 return;
265 }
266 //cleanup();
267 QMainWindow::closeEvent(e);
268 kstApp->closeAllWindows();
269 }
270
271
document() const272 Document *MainWindow::document() const {
273 return _doc;
274 }
275
276
undoGroup() const277 QUndoGroup *MainWindow::undoGroup() const {
278 return _undoGroup;
279 }
280
281
tabWidget() const282 TabWidget *MainWindow::tabWidget() const {
283 return _tabWidget;
284 }
285
286
save()287 void MainWindow::save() {
288 if (_doc->isOpen()) {
289 _doc->save();
290 } else {
291 saveAs();
292 }
293 }
294
295
saveAs()296 void MainWindow::saveAs() {
297 QString fn = QFileDialog::getSaveFileName(this, tr("Kst: Save File"), _doc->fileName(), tr("Kst Sessions (*.kst)"));
298 if (fn.isEmpty()) {
299 return;
300 }
301 QString restorePath = QDir::currentPath();
302 QString kstfiledir = fn.left(fn.lastIndexOf('/')) + '/';
303 QDir::setCurrent(kstfiledir);
304 //QString currentP = QDir::currentPath();
305 _doc->save(fn);
306 QDir::setCurrent(restorePath);
307 _sessionFileName = fn;
308 setKstWindowTitle();
309 updateRecentKstFiles(fn);
310 }
311
newDoc(bool force)312 void MainWindow::newDoc(bool force) {
313 bool clearApproved = false;
314 if (force) {
315 clearApproved = true;
316 } else {
317 clearApproved = promptSaveDone();
318 }
319
320 if (clearApproved) {
321 cleanup();
322 delete _dataManager;
323 _dataManager = 0;
324 delete _doc;
325 resetNameIndexes();
326 _doc = new Document(this);
327 _scriptServer->setStore(_doc->objectStore());
328 tabWidget()->clear();
329 tabWidget()->createView();
330 return;
331 } else {
332 return;
333 }
334
335 }
336
open()337 void MainWindow::open() {
338 if (!promptSaveDone()) {
339 return;
340 }
341 const QString key = "lastOpenedKstFile";
342 QString fn = _settings.value(key).toString();
343 if (fn.isEmpty()) {
344 fn = _doc->fileName();
345 }
346 fn = QFileDialog::getOpenFileName(this, tr("Kst: Open File"), fn, tr("Kst Sessions (*.kst)"));
347 if (fn.isEmpty()) {
348 return;
349 }
350 _settings.setValue(key, fn);
351 openFile(fn);
352 }
353
354
355
createRecentFileAction(const QString & filename,int idx,const QString & name,const char * openslot)356 QAction* MainWindow::createRecentFileAction(const QString& filename, int idx, const QString& name, const char* openslot)
357 {
358 QAction* action = new QAction(this);
359 QString text = tr("&%1 %2", "Part of a list. %1 is an index. %2 is a file name").arg(idx).arg(name);
360 action->setText(text);
361 action->setData(filename);
362 action->setStatusTip(filename);
363 action->setVisible(true);
364 connect(action, SIGNAL(triggered()), this, openslot);
365 return action;
366 }
367
368
updateRecentKstFiles(const QString & filename)369 void MainWindow::updateRecentKstFiles(const QString& filename)
370 {
371 updateRecentFiles("recentKstFileList", _fileMenu, _bottomRecentKstActions, _recentKstFilesMenu, filename, SLOT(openRecentKstFile()));
372 }
373
setKstWindowTitle()374 void MainWindow::setKstWindowTitle()
375 {
376 QString title = "Kst";
377 QString server_name = _scriptServer->serverName;
378 QString user_name = "--"+kstApp->userName();
379
380 if (server_name.endsWith(user_name)) {
381 server_name.remove(server_name.lastIndexOf(user_name),10000);
382 }
383
384 if (!_sessionFileName.isEmpty()) {
385 title += " - " + _sessionFileName;
386 }
387 if (scriptServerNameSet()) {
388 title += " -- " + server_name;
389 }
390 setWindowTitle(title);
391 }
392
scriptServerName()393 QString MainWindow::scriptServerName()
394 {
395 return _scriptServer->serverName;
396 }
397
scriptServerNameSet()398 bool MainWindow::scriptServerNameSet()
399 {
400 return _scriptServer->serverNameSet;
401 }
402
setScriptServerName(QString server_name)403 void MainWindow::setScriptServerName(QString server_name)
404 {
405 _scriptServer->setScriptServerName(server_name);
406 setKstWindowTitle();
407 }
408
copyTab()409 void MainWindow::copyTab()
410 {
411 View *view = _tabWidget->currentView();
412 QClipboard *clipboard = QApplication::clipboard();
413 QMimeData *mimedata = new QMimeData();
414
415 QPainter painter;
416 QPixmap pixmap(view->size());
417
418 painter.begin(&pixmap);
419
420 view->setPrinting(true);
421 view->render(&painter);
422 view->setPrinting(false);
423
424 painter.end();
425
426 //mimedata->setText("Some text from kst, just for you!");
427 mimedata->setImageData(pixmap.toImage());
428
429 clipboard->setMimeData(mimedata);
430 }
431
432
updateRecentDataFiles(const QString & filename)433 void MainWindow::updateRecentDataFiles(const QString& filename)
434 {
435 updateRecentFiles("recentDataFileList", _toolsMenu, _bottomRecentDataActions, _recentDataFilesMenu, filename, SLOT(openRecentDataFile()));
436 if (!filename.isEmpty()) {
437 dialogDefaults().setValue("vector/datasource", filename);
438 }
439 }
440
441
recentDataFiles()442 QStringList MainWindow::recentDataFiles() {
443 QStringList recentFiles = _settings.value("recentDataFileList").toStringList();
444 if (recentFiles.removeDuplicates() > 0) {
445 _settings.setValue("recentDataFileList", recentFiles);
446 }
447 return recentFiles;
448 }
449
cleanupRecentDataFilesList()450 void MainWindow::cleanupRecentDataFilesList() {
451 QStringList recentFiles = _settings.value("recentDataFileList").toStringList();
452 recentFiles.removeDuplicates();
453 foreach(const QString& it, recentFiles) {
454 if (!QFileInfo(it).exists()) {
455 recentFiles.removeOne(it);
456 }
457 }
458 _settings.setValue("recentDataFileList", recentFiles);
459 updateRecentKstFiles();
460 updateRecentDataFiles();
461 }
462
463
updateRecentFiles(const QString & key,QMenu * menu,QList<QAction * > & actions,QMenu * submenu,const QString & newfilename,const char * openslot)464 void MainWindow::updateRecentFiles(const QString& key ,QMenu* menu, QList<QAction*>& actions, QMenu* submenu, const QString& newfilename, const char* openslot)
465 {
466 // Always add absolute paths to the recent file lists, otherwise they are not very reusable
467 QString absoluteFilePath = DataSource::cleanPath(newfilename);
468 if (!newfilename.isEmpty() && !QDir::isAbsolutePath(newfilename)) { // If it's not empty and not absolute either, add the dir
469 absoluteFilePath = DataSource::cleanPath(QDir::currentPath() + '/' + newfilename);
470 }
471 foreach(QAction* it, actions) {
472 menu->removeAction(it);
473 delete it;
474 }
475 actions.clear();
476 QStringList recentFiles = _settings.value(key).toStringList();
477 if (recentFiles.removeDuplicates() > 0) {
478 _settings.setValue(key, recentFiles);
479 }
480 if (!absoluteFilePath.isEmpty()) {
481 recentFiles.removeOne(absoluteFilePath);
482 recentFiles.push_front(absoluteFilePath);
483 recentFiles = recentFiles.mid(0, 30);
484 _settings.setValue(key, recentFiles);
485 }
486
487 submenu->clear();
488 QAction* check = new QAction(this);
489 check->setText(tr("&Cleanup Non-Existent Files"));
490 check->setData(key);
491 check->setVisible(true);
492 connect(check, SIGNAL(triggered()), this, SLOT(checkRecentFilesOnExistence()));
493 submenu->addAction(check);
494 submenu->addSeparator();
495 int i = 0;
496 foreach(const QString& it, recentFiles) {
497 i++;
498 if (i <= 5) {
499 // don't make file menu too wide, show complete path in statusbar
500 QAction* action = createRecentFileAction(it, i, QFileInfo(it).fileName(), openslot);
501 actions << action;
502 menu->addAction(action);
503 }
504 submenu->addAction(createRecentFileAction(it, i, it, openslot));
505 }
506 }
507
508
openRecentKstFile()509 void MainWindow::openRecentKstFile()
510 {
511 QAction *action = qobject_cast<QAction *>(sender());
512 if (action) {
513 openFile(action->data().toString());
514 }
515 }
516
517
checkRecentFilesOnExistence()518 void MainWindow::checkRecentFilesOnExistence()
519 {
520 QAction *action = qobject_cast<QAction *>(sender());
521 if (action) {
522 QStringList recentFiles = _settings.value(action->data().toString()).toStringList();
523 recentFiles.removeDuplicates();
524 foreach(const QString& it, recentFiles) {
525 if (!QFileInfo(it).exists()) {
526 recentFiles.removeOne(it);
527 }
528 }
529 _settings.setValue(action->data().toString(), recentFiles);
530 updateRecentKstFiles();
531 updateRecentDataFiles();
532 }
533 }
534
autoExportImage()535 void MainWindow::autoExportImage() {
536 exportGraphicsFile(_ae_filename, _ae_format, _ae_width, _ae_height, _ae_display, _ae_export_all, _ae_autosave_period);
537 }
538
539
540
initFromCommandLine()541 bool MainWindow::initFromCommandLine() {
542 delete _doc;
543 _doc = new Document(this);
544 _scriptServer->setStore(_doc->objectStore());
545
546 CommandLineParser P(_doc, this);
547
548 bool ok = _doc->initFromCommandLine(&P);
549 if (!P.pngFile().isEmpty()) {
550 int w = 1280;
551 int h = 1024;
552
553 if (P.pngWidth()>1) {
554 w = P.pngWidth();
555 }
556 if (P.pngHeight()>1) {
557 h = P.pngHeight();
558 }
559 exportGraphicsFile(P.pngFile(), "png", w, h, 2, true, 0);
560 ok = false;
561 }
562 if (!P.printFile().isEmpty()) {
563 #ifndef KST_NO_PRINTER
564 printFromCommandLine(P.printFile());
565 #endif
566 ok = false;
567 }
568 if (!P.kstFileName().isEmpty()) {
569 _sessionFileName = P.kstFileName();
570 setKstWindowTitle();
571 }
572 _doc->setChanged(false);
573 return ok;
574 }
575
openFile(const QString & file)576 void MainWindow::openFile(const QString &file) {
577 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
578 cleanup();
579 newDoc(true); // Does all the init stuff, but does not ask for override as it's supposed to be done elsewhere
580 bool ok = _doc->open(file);
581 updateProgress(100, "");
582 QApplication::restoreOverrideCursor();
583
584 if (!ok) {
585 QString lastError = _doc->lastError();
586 if (lastError.isEmpty())
587 lastError = tr("For details see Help->Debug Dialog->Log.");
588 QMessageBox::critical(this, tr("Kst"),tr("Error opening document:\n '%1'\n%2\n").arg(file, lastError));
589 }
590
591 _sessionFileName = file;
592 setKstWindowTitle();
593 updateRecentKstFiles(file);
594 }
595
596
exportGraphicsFile(const QString & filename,const QString & format,int width,int height,int display,bool export_all,int autosave_period)597 void MainWindow::exportGraphicsFile(const QString &filename, const QString &format, int width, int height, int display, bool export_all, int autosave_period) {
598 int viewCount = 0;
599 int n_views = _tabWidget->views().size();
600 int i_startview, i_endview;
601
602 _ae_filename = filename;
603 _ae_format = format;
604 _ae_width = width;
605 _ae_height = height;
606 _ae_display = display;
607 _ae_export_all = export_all;
608 _ae_autosave_period = autosave_period;
609
610 dialogDefaults().setValue("export/filename", filename);
611 dialogDefaults().setValue("export/format", format);
612 dialogDefaults().setValue("export/xsize", width);
613 dialogDefaults().setValue("export/ysize", height);
614 dialogDefaults().setValue("export/sizeOption", display);
615
616 if (export_all) {
617 i_startview = 0;
618 i_endview = n_views-1;
619 } else {
620 i_startview = i_endview = _tabWidget->currentIndex();
621 }
622
623 for (int i_view = i_startview; i_view<=i_endview; i_view++) {
624 View *view = _tabWidget->views().at(i_view);
625 QSize size;
626 if (display == 0) { // Width set by user, maintain aspect ratio
627 QSize sizeWindow(view->geometry().size());
628 size.setWidth(width);
629 size.setHeight((int)((qreal)width * (qreal)sizeWindow.height() / (qreal)sizeWindow.width()));
630 } else if (display == 1) { // Height set by user, maintain aspect ratio
631 QSize sizeWindow(view->geometry().size());
632 size.setHeight(height);
633 size.setWidth((int)((qreal)height * (qreal)sizeWindow.width() / (qreal)sizeWindow.height()));
634 } else if (display == 2) { // Width and height set by user
635 size.setWidth(width);
636 size.setHeight(height);
637 } else { //if (display == 3) { // Square (width x width)
638 size.setWidth(width);
639 size.setHeight(width);
640 }
641
642 QString file = filename;
643 if (i_startview - i_endview != 0) {
644 QFileInfo QFI(filename);
645 file = QFI.dir().path() + '/' + QFI.completeBaseName() +
646 '_' +
647 _tabWidget->tabBar()->tabText(viewCount).replace(QString("&"),QString()) + '.' +
648 QFI.suffix();
649 }
650 if (format == QString("svg")) {
651 #ifndef KST_NO_SVG
652 QPainter painter;
653 QSvgGenerator generator;
654
655 QSize currentSize(view->size());
656 view->resize(size);
657 view->processResize(size);
658 view->setPrinting(true);
659
660 generator.setFileName(file);
661 generator.setResolution(300);
662 generator.setSize(view->size());
663 generator.setViewBox(view->rect());
664
665 painter.begin(&generator);
666 view->render(&painter);
667 painter.end();
668
669 view->setPrinting(false);
670 view->resize(currentSize);
671 view->processResize(currentSize);
672 #endif
673 } else if (format == QString("eps")) {
674 #ifndef KST_NO_PRINTER
675 QPrinter printer(QPrinter::ScreenResolution);
676 #ifdef QT5
677 printer.setOutputFormat(QPrinter::PdfFormat);
678 #else
679 printer.setOutputFormat(QPrinter::PostScriptFormat);
680 #endif
681 printer.setOutputFileName(file);
682 printer.setOrientation(QPrinter::Portrait);
683
684 printer.setPrintRange(QPrinter::PageRange);
685 printer.setFromTo(i_view+1, i_view+1);
686
687 printer.setPaperSize(size, QPrinter::DevicePixel);
688 printToPrinter(&printer);
689
690 } else if (format == QString("pdf")) {
691 QPrinter printer(QPrinter::ScreenResolution);
692 printer.setOutputFormat(QPrinter::PdfFormat);
693 printer.setOutputFileName(file);
694 //setPrinterDefaults(&printer);
695 printer.setOrientation(QPrinter::Portrait);
696
697 printer.setPrintRange(QPrinter::PageRange);
698 printer.setFromTo(i_view+1, i_view+1);
699
700 printer.setPaperSize(size, QPrinter::DevicePixel);
701 printToPrinter(&printer);
702 #endif
703 } else {
704 QPainter painter;
705 QImage image(size, QImage::Format_ARGB32);
706
707 painter.begin(&image);
708
709 QSize currentSize(view->size());
710 view->resize(size);
711 view->processResize(size);
712 view->setPrinting(true);
713 view->render(&painter);
714 view->setPrinting(false);
715 view->resize(currentSize);
716 view->processResize(currentSize);
717
718 painter.end();
719
720 QImageWriter imageWriter(file, format.toLatin1());
721 imageWriter.write(image);
722 }
723 viewCount++;
724 }
725
726 if (_ae_autosave_period > 0) {
727 if (_ae_Timer == 0) { // create timer (only once)
728 _ae_Timer = new QTimer(this);
729 _ae_Timer->setSingleShot(true);
730 connect(_ae_Timer, SIGNAL(timeout()), this, SLOT(autoExportImage()));
731 }
732 _ae_Timer->start(_ae_autosave_period); // one shot timer...
733 }
734 }
735
exportLog(const QString & imagename,QString & msgfilename,const QString & format,int x_size,int y_size,int size_option_index,const QString & message)736 void MainWindow::exportLog(const QString &imagename, QString &msgfilename, const QString &format, int x_size, int y_size,
737 int size_option_index, const QString &message) {
738 View *view = _tabWidget->currentView();
739
740 QSize size;
741 if (size_option_index == 0) {
742 size.setWidth(x_size);
743 size.setHeight(y_size);
744 } else if (size_option_index == 1) {
745 size.setWidth(x_size);
746 size.setHeight(y_size);
747 } else if (size_option_index == 2) {
748 QSize sizeWindow(view->geometry().size());
749
750 size.setWidth(x_size);
751 size.setHeight((int)((qreal)x_size * (qreal)sizeWindow.height() / (qreal)sizeWindow.width()));
752 } else {
753 QSize sizeWindow(view->geometry().size());
754
755 size.setHeight(y_size);
756 size.setWidth((int)((qreal)y_size * (qreal)sizeWindow.width() / (qreal)sizeWindow.height()));
757 }
758
759 QImage image(size, QImage::Format_ARGB32);
760
761 QPainter painter(&image);
762 QSize currentSize(view->size());
763 view->resize(size);
764 view->processResize(size);
765 view->setPrinting(true);
766 view->render(&painter);
767 view->setPrinting(false);
768 view->resize(currentSize);
769 view->processResize(currentSize);
770
771 QImageWriter imageWriter(imagename, format.toLatin1());
772 imageWriter.write(image);
773
774 QFile file(msgfilename);
775
776 if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
777 QTextStream out(&file);
778 out << message;
779 file.close();
780 }
781
782 }
783
784 #ifndef KST_NO_PRINTER
printToPrinter(QPrinter * printer)785 void MainWindow::printToPrinter(QPrinter *printer) {
786 QPainter painter(printer);
787 QList<View*> pages;
788
789 switch (printer->printRange()) {
790 case QPrinter::PageRange:
791 if (printer->fromPage()>0) {
792 for (int i_page = printer->fromPage(); i_page<=printer->toPage(); i_page++) {
793 pages.append(_tabWidget->views().at(i_page-1));
794 }
795 }
796 break;
797 case QPrinter::AllPages:
798 foreach (View *view, _tabWidget->views()) {
799 pages.append(view);
800 }
801 break;
802 case QPrinter::Selection:
803 default:
804 pages.append(_tabWidget->currentView());
805 break;
806 }
807
808 QSize printerPageSize = printer->pageRect().size();
809 for (int i = 0; i < printer->numCopies(); ++i) {
810 for (int i_page = 0; i_page<pages.count(); i_page++) {
811 View *view = pages.at(i_page);
812 QSize currentSize(view->size());
813 view->resize(printerPageSize);
814 view->processResize(printerPageSize);
815 view->setPrinting(true);
816 view->render(&painter);
817 view->setPrinting(false);
818 view->resize(currentSize);
819 view->processResize(currentSize);
820 if (i_page<pages.count()-1)
821 printer->newPage();
822
823 }
824 }
825 }
826
printFromCommandLine(const QString & printFileName)827 void MainWindow::printFromCommandLine(const QString &printFileName) {
828 QPrinter printer(QPrinter::ScreenResolution);
829 printer.setResolution(300);
830 printer.setOutputFileName(printFileName);
831 setPrinterDefaults(&printer);
832
833 printer.setPrintRange(QPrinter::AllPages);
834 printToPrinter(&printer);
835 }
836
setPrinterDefaults(QPrinter * printer)837 void MainWindow::setPrinterDefaults(QPrinter *printer) {
838 if (dialogDefaults().value("print/landscape",true).toBool()) {
839 printer->setOrientation(QPrinter::Landscape);
840 } else {
841 printer->setOrientation(QPrinter::Portrait);
842 }
843
844 printer->setPaperSize(QPrinter::PaperSize(dialogDefaults().value("print/paperSize", QPrinter::Letter).toInt()));
845
846 QPointF topLeft =dialogDefaults().value("print/topLeftMargin", QPointF(15.0,15.0)).toPointF();
847 QPointF bottomRight =dialogDefaults().value("print/bottomRightMargin", QPointF(15.0,15.0)).toPointF();
848
849 printer->setPageMargins(topLeft.x(), topLeft.y(), bottomRight.x(), bottomRight.y(), QPrinter::Millimeter);
850 // Apparent Qt bug: setting the page margins here doesn't set the correspoding values in the print
851 // dialog->printer-options sub-dialog under linux. If you don't open the printer-options sub-dialog,
852 // the values here are honored.
853 }
854
savePrinterDefaults(QPrinter * printer)855 void MainWindow::savePrinterDefaults(QPrinter *printer) {
856 dialogDefaults().setValue("print/landscape", printer->orientation() == QPrinter::Landscape);
857 dialogDefaults().setValue("print/paperSize", int(printer->paperSize()));
858
859 qreal left, top, right, bottom;
860 printer->getPageMargins(&left, &top, &right, &bottom, QPrinter::Millimeter);
861 dialogDefaults().setValue("print/topLeftMargin", QPointF(left, top));
862 dialogDefaults().setValue("print/bottomRightMargin", QPointF(right, bottom));
863
864 }
865
print()866 void MainWindow::print() {
867 QPrinter printer(QPrinter::ScreenResolution);
868 printer.setResolution(300);
869
870 setPrinterDefaults(&printer);
871
872 #ifndef Q_OS_WIN
873 // QPrintDialog: Cannot be used on non-native printers
874 printer.setOutputFileName(dialogDefaults().value("print/path", "./print.pdf").toString());
875 #endif
876 QPointer<QPrintDialog> pd = new QPrintDialog(&printer, this);
877 #if QT_VERSION >= 0x040500
878 pd->setOption(QPrintDialog::PrintToFile);
879 pd->setOption(QPrintDialog::PrintPageRange, true);
880 pd->setOption(QAbstractPrintDialog::PrintShowPageSize,true);
881 #endif
882
883 if (pd->exec() == QDialog::Accepted) {
884 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
885 printToPrinter(&printer);
886 QApplication::restoreOverrideCursor();
887 savePrinterDefaults(&printer);
888 }
889 dialogDefaults().setValue("print/path", printer.outputFileName());
890 delete pd;
891 }
892 #endif
893
currentViewChanged()894 void MainWindow::currentViewChanged() {
895 if(!_tabWidget->currentView())
896 return;
897 _undoGroup->setActiveStack(_tabWidget->currentView()->undoStack());
898 currentViewModeChanged();
899 }
900
901
currentViewModeChanged()902 void MainWindow::currentViewModeChanged() {
903 if(!_tabWidget->currentView())
904 return;
905 _layoutModeAct->setChecked(_tabWidget->currentView()->viewMode() == View::Layout);
906 }
907
aboutToQuit()908 void MainWindow::aboutToQuit() {
909 writeSettings();
910 }
911
912
about()913 void MainWindow::about() {
914 if (!_aboutDialog) {
915 _aboutDialog = new AboutDialog(this);
916 }
917 if (_aboutDialog->isVisible()) {
918 _aboutDialog->raise();
919 _aboutDialog->activateWindow();
920 }
921 _aboutDialog->show();
922 }
923
924
showShortcutDialog()925 void MainWindow::showShortcutDialog() {
926 if (!_shortcutDialog) {
927 _shortcutDialog = new ShortcutDialog(this);
928 } else if (_shortcutDialog->isVisible()) {
929 _shortcutDialog->raise();
930 _shortcutDialog->activateWindow();
931 }
932 _shortcutDialog->show();
933
934 _shortcutDialog->resetWidth();
935
936 }
937
938
clearDrawingMarker()939 void MainWindow::clearDrawingMarker() {
940 _createBoxAct->setChecked(false);
941 _createSharedAxisBoxAct->setChecked(false);
942 _createCircleAct->setChecked(false);
943 _createEllipseAct->setChecked(false);
944 _createLabelAct->setChecked(false);
945 _createLineAct->setChecked(false);
946 _createArrowAct->setChecked(false);
947 _createPictureAct->setChecked(false);
948 _createPlotAct->setChecked(false);
949 #ifndef KST_NO_SVG
950 _createSvgAct->setChecked(false);
951 #endif
952 _tabWidget->currentView()->setMouseMode(View::Default);
953 }
954
955
createBox()956 void MainWindow::createBox() {
957 if (_createBoxAct->isChecked()) {
958 clearDrawingMarker();
959 _createBoxAct->setChecked(true);
960 CreateBoxCommand *cmd = new CreateBoxCommand;
961 cmd->createItem();
962 } else {
963 _tabWidget->currentView()->setMouseMode(View::Default);
964 }
965 }
966
967
968
createSharedAxisBox()969 void MainWindow::createSharedAxisBox() {
970 if (_createSharedAxisBoxAct->isChecked()) {
971 clearDrawingMarker();
972 _createSharedAxisBoxAct->setChecked(true);
973 CreateSharedAxisBoxCommand *cmd = new CreateSharedAxisBoxCommand;
974 cmd->createItem();
975 } else {
976 _tabWidget->currentView()->setMouseMode(View::Default);
977 }
978 }
979
createVector()980 void MainWindow::createVector() {
981 QString tmp;
982 DialogLauncher::self()->showVectorDialog(tmp);
983 }
984
985
createMatrix()986 void MainWindow::createMatrix() {
987 QString tmp;
988 DialogLauncher::self()->showMatrixDialog(tmp);
989 }
990
991
createScalar()992 void MainWindow::createScalar() {
993 QString scalarName;
994 DialogLauncher::self()->showScalarDialog(scalarName);
995 }
996
997
createString()998 void MainWindow::createString() {
999 QString stringName;
1000 DialogLauncher::self()->showStringDialog(stringName);
1001 }
1002
1003
createCircle()1004 void MainWindow::createCircle() {
1005 if (_createCircleAct->isChecked()) {
1006 clearDrawingMarker();
1007 _createCircleAct->setChecked(true);
1008 CreateCircleCommand *cmd = new CreateCircleCommand;
1009 cmd->createItem();
1010 } else {
1011 _tabWidget->currentView()->setMouseMode(View::Default);
1012 }
1013 }
1014
1015
createEllipse()1016 void MainWindow::createEllipse() {
1017 if (_createEllipseAct->isChecked()) {
1018 clearDrawingMarker();
1019 _createEllipseAct->setChecked(true);
1020 CreateEllipseCommand *cmd = new CreateEllipseCommand;
1021 cmd->createItem();
1022 } else {
1023 _tabWidget->currentView()->setMouseMode(View::Default);
1024 }
1025 }
1026
1027
createLabel()1028 void MainWindow::createLabel() {
1029 if (_createLabelAct->isChecked()) {
1030 clearDrawingMarker();
1031 _createLabelAct->setChecked(true);
1032 CreateLabelCommand *cmd = new CreateLabelCommand;
1033 cmd->createItem();
1034 } else {
1035 _tabWidget->currentView()->setMouseMode(View::Default);
1036 }
1037 }
1038
1039
createLine()1040 void MainWindow::createLine() {
1041 if (_createLineAct->isChecked()) {
1042 clearDrawingMarker();
1043 _createLineAct->setChecked(true);
1044 CreateLineCommand *cmd = new CreateLineCommand;
1045 cmd->createItem();
1046 } else {
1047 _tabWidget->currentView()->setMouseMode(View::Default);
1048 }
1049 }
1050
1051
createArrow()1052 void MainWindow::createArrow() {
1053 if (_createArrowAct->isChecked()) {
1054 clearDrawingMarker();
1055 _createArrowAct->setChecked(true);
1056 CreateArrowCommand *cmd = new CreateArrowCommand;
1057 cmd->createItem();
1058 } else {
1059 _tabWidget->currentView()->setMouseMode(View::Default);
1060 }
1061 }
1062
1063
createPicture()1064 void MainWindow::createPicture() {
1065 if (_createPictureAct->isChecked()) {
1066 clearDrawingMarker();
1067 _createPictureAct->setChecked(true);
1068 CreatePictureCommand *cmd = new CreatePictureCommand;
1069 cmd->createItem();
1070 } else {
1071 _tabWidget->currentView()->setMouseMode(View::Default);
1072 }
1073 }
1074
1075
createPlot()1076 void MainWindow::createPlot() {
1077 if (_createPlotAct->isChecked()) {
1078 clearDrawingMarker();
1079 _createPlotAct->setChecked(true);
1080 CreatePlotCommand *cmd = new CreatePlotCommand;
1081 cmd->createItem();
1082 } else {
1083 _tabWidget->currentView()->setMouseMode(View::Default);
1084 }
1085 }
1086
insertPlot()1087 void MainWindow::insertPlot() {
1088 CreatePlotForCurve *cmd = new CreatePlotForCurve();
1089 cmd->createItem();
1090
1091 PlotItem *plotItem = static_cast<PlotItem*>(cmd->item());
1092 plotItem->view()->resetPlotFontSizes(plotItem);
1093 plotItem->view()->configurePlotFontDefaults(plotItem); // copy plots already in window
1094 plotItem->view()->appendToLayout(CurvePlacement::Auto, plotItem, 0);
1095
1096 }
1097
1098 #ifndef KST_NO_SVG
createSvg()1099 void MainWindow::createSvg() {
1100 if (_createSvgAct->isChecked()) {
1101 clearDrawingMarker();
1102 _createSvgAct->setChecked(true);
1103 CreateSvgCommand *cmd = new CreateSvgCommand;
1104 cmd->createItem();
1105 } else {
1106 _tabWidget->currentView()->setMouseMode(View::Default);
1107 }
1108 }
1109 #endif
1110
createCurve()1111 void MainWindow::createCurve() {
1112 DialogLauncher::self()->showCurveDialog();
1113 }
1114
createPSD()1115 void MainWindow::createPSD() {
1116 DialogLauncher::self()->showPowerSpectrumDialog();
1117 }
1118
createEquation()1119 void MainWindow::createEquation() {
1120 DialogLauncher::self()->showEquationDialog();
1121 }
1122
createHistogram()1123 void MainWindow::createHistogram() {
1124 DialogLauncher::self()->showHistogramDialog();
1125 }
1126
createImage()1127 void MainWindow::createImage() {
1128 DialogLauncher::self()->showImageDialog();
1129 }
1130
createSpectogram()1131 void MainWindow::createSpectogram() {
1132 DialogLauncher::self()->showCSDDialog();
1133 }
1134
createEventMonitor()1135 void MainWindow::createEventMonitor() {
1136 DialogLauncher::self()->showEventMonitorDialog();
1137 }
1138
createActions()1139 void MainWindow::createActions() {
1140 // ***************************** File actions ******************************** //
1141 _openAct = new QAction(tr("&Open..."), this);
1142 _openAct->setStatusTip(tr("Open a new session"));
1143 _openAct->setShortcuts(QKeySequence::Open);
1144 _openAct->setIcon(KstGetIcon("document-open"));
1145 connect(_openAct, SIGNAL(triggered()), this, SLOT(open()));
1146
1147 _saveAct = new QAction(tr("&Save"), this);
1148 _saveAct->setStatusTip(tr("Save the current session"));
1149 _saveAct->setShortcuts(QKeySequence::Save);
1150 _saveAct->setIcon(KstGetIcon("document-save"));
1151 connect(_saveAct, SIGNAL(triggered()), this, SLOT(save()));
1152
1153 _saveAsAct = new QAction(tr("Save &as..."), this);
1154 _saveAsAct->setStatusTip(tr("Save the current session"));
1155 _saveAsAct->setIcon(KstGetIcon("document-save-as"));
1156 _saveAsAct->setShortcuts(QKeySequence::SaveAs);
1157 connect(_saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));
1158
1159 _closeAct = new QAction(tr("Ne&w Session"), this);
1160 _closeAct->setStatusTip(tr("Close current session and start a new, empty one"));
1161 _closeAct->setIcon(KstGetIcon("document-close"));
1162 _closeAct->setShortcuts(QKeySequence::Close);
1163 connect(_closeAct, SIGNAL(triggered()), this, SLOT(newDoc()));
1164
1165 _reloadAct = new QAction(tr("Reload All &Data Sources"), this);
1166 _reloadAct->setStatusTip(tr("Reload all data sources"));
1167 _reloadAct->setIcon(KstGetIcon("kst_reload"));
1168 connect(_reloadAct, SIGNAL(triggered()), this, SLOT(reload()));
1169
1170 _printAct = new QAction(tr("&Print..."), this);
1171 _printAct->setStatusTip(tr("Print the current view"));
1172 _printAct->setIcon(KstGetIcon("document-print"));
1173 _printAct->setShortcuts(QKeySequence::Print);
1174 connect(_printAct, SIGNAL(triggered()), this, SLOT(print()));
1175 #ifdef KST_NO_PRINTER
1176 _printAct->setEnabled(false);
1177 #endif
1178
1179 _exportGraphicsAct = new QAction(tr("&Export as Image(s)..."), this);
1180 _exportGraphicsAct->setStatusTip(tr("Export graphics to disk"));
1181 _exportGraphicsAct->setIcon(KstGetIcon("insert-image"));
1182 connect(_exportGraphicsAct, SIGNAL(triggered()), this, SLOT(showExportGraphicsDialog()));
1183
1184 _exportVectorsAct = new QAction(tr("Save &Vectors to Disk..."), this);
1185 _exportVectorsAct->setStatusTip(tr("Export vectors to ascii file"));
1186 _exportVectorsAct->setIcon(KstGetIcon("save-vectors"));
1187 connect(_exportVectorsAct, SIGNAL(triggered()), this, SLOT(showExportVectorsDialog()));
1188
1189 _logAct = new QAction(tr("&Log Entry..."), this);
1190 _logAct->setStatusTip(tr("Commit a log entry"));
1191 _logAct->setIcon(KstGetIcon("new-log-event"));
1192 connect(_logAct, SIGNAL(triggered()), this, SLOT(showLogDialog()));
1193
1194 _newTabAct = new QAction(tr("&New Tab"), this);
1195 _newTabAct->setStatusTip(tr("Create a new tab"));
1196 _newTabAct->setIcon(KstGetIcon("tab-new"));
1197
1198 connect(_newTabAct, SIGNAL(triggered()), tabWidget(), SLOT(createView()));
1199
1200 _closeTabAct = new QAction(tr("&Close Tab"), this);
1201 _closeTabAct->setStatusTip(tr("Close the current tab"));
1202 _closeTabAct->setIcon(KstGetIcon("tab-close"));
1203 connect(_closeTabAct, SIGNAL(triggered()), tabWidget(), SLOT(closeCurrentView()));
1204
1205 _exitAct = new QAction(tr("E&xit"), this);
1206 _exitAct->setShortcuts(QKeySequence::Quit);
1207 _exitAct->setStatusTip(tr("Exit the application"));
1208 _exitAct->setIcon(KstGetIcon("application-exit"));
1209 connect(_exitAct, SIGNAL(triggered()), this, SLOT(close()));
1210
1211 // ************************** Edit Actions ******************************* //
1212 _undoAct = _undoGroup->createUndoAction(this);
1213 _undoAct->setShortcuts(QKeySequence::Undo);
1214 _undoAct->setIcon(KstGetIcon("edit-undo"));
1215
1216 _redoAct = _undoGroup->createRedoAction(this);
1217 _redoAct->setShortcuts(QKeySequence::Redo);
1218 _redoAct->setIcon(KstGetIcon("edit-redo"));
1219
1220 _copyTabAct = new QAction(tr("Copy Tab Image"), this);
1221 _copyTabAct->setStatusTip("Copy image of the current tab to the desktop clipboard");
1222 _copyTabAct->setIcon(KstGetIcon("edit-copy"));
1223 connect(_copyTabAct, SIGNAL(triggered()), this, SLOT(copyTab()));
1224
1225 // ********************* View Actions ********************************** //
1226 _vectorEditorAct = new QAction(tr("&Vectors"), this);
1227 _vectorEditorAct->setStatusTip(tr("Show all vectors in a spreadsheet"));
1228 connect(_vectorEditorAct, SIGNAL(triggered()), this, SLOT(showVectorEditor()));
1229
1230 _scalarEditorAct = new QAction(tr("&Scalars"), this);
1231 _scalarEditorAct->setStatusTip(tr("Show all scalars in a spreadsheet"));
1232 connect(_scalarEditorAct, SIGNAL(triggered()), this, SLOT(showScalarEditor()));
1233
1234 _matrixEditorAct = new QAction(tr("&Matrices"), this);
1235 _matrixEditorAct->setStatusTip(tr("Show all matrices in a spreadsheet"));
1236 connect(_matrixEditorAct, SIGNAL(triggered()), this, SLOT(showMatrixEditor()));
1237
1238 _stringEditorAct = new QAction(tr("S&trings"), this);
1239 _stringEditorAct->setStatusTip(tr("Show all strings in a spreadsheet"));
1240 connect(_stringEditorAct, SIGNAL(triggered()), this, SLOT(showStringEditor()));
1241
1242 // ************************ Data Range 1 click Actions ************************** //
1243 _backAct = new QAction(tr("&Back One Screen"), this);
1244 _backAct->setStatusTip(tr("Back one screen (Page Up)"));
1245 _backAct->setToolTip(tr("Back one screen (Page Up)"));
1246 _backAct->setIcon(KstGetIcon("page-previous"));
1247 _backAct->setShortcut(Qt::Key_PageUp);
1248 connect(_backAct, SIGNAL(triggered()), this, SLOT(back()));
1249
1250 _forwardAct = new QAction(tr("&Forward One Screen"), this);
1251 _forwardAct->setStatusTip(tr("Forward one screen (Page Down)"));
1252 _forwardAct->setToolTip(tr("Forward one screen (Page Down)"));
1253 _forwardAct->setIcon(KstGetIcon("page-next"));
1254 _forwardAct->setShortcut(Qt::Key_PageDown);
1255 connect(_forwardAct, SIGNAL(triggered()), this, SLOT(forward()));
1256
1257 _backSmallAct = new QAction(tr("&Back 1/5th Screen"), this);
1258 _backSmallAct->setStatusTip(tr("Back 1/5th screen (Shift + Page Up)"));
1259 _backSmallAct->setToolTip(tr("Back 1/5th screen (Shift + Page Up)"));
1260 _backSmallAct->setIcon(KstGetIcon("page-previous"));
1261 _backSmallAct->setShortcut(Qt::SHIFT + Qt::Key_PageDown);
1262 connect(_backSmallAct, SIGNAL(triggered()), this, SLOT(backSmall()));
1263
1264 _forwardSmallAct = new QAction(tr("&Forward 1/5th Screen"), this);
1265 _forwardSmallAct->setStatusTip(tr("Forward 1/5th screen (Page Down)"));
1266 _forwardSmallAct->setToolTip(tr("Forward 1/5th screen (Page Down)"));
1267 _forwardSmallAct->setIcon(KstGetIcon("page-next"));
1268 _forwardSmallAct->setShortcut(Qt::SHIFT + Qt::Key_PageUp);
1269 connect(_forwardSmallAct, SIGNAL(triggered()), this, SLOT(forwardSmall()));
1270
1271 _readFromEndAct = new QAction(tr("&Count from End"), this);
1272 _readFromEndAct->setStatusTip(tr("Count from end mode (End)"));
1273 _readFromEndAct->setToolTip(tr("Count from end mode (End)"));
1274 _readFromEndAct->setIcon(KstGetIcon("count-from-end"));
1275 _readFromEndAct->setShortcut(Qt::Key_End);
1276 connect(_readFromEndAct, SIGNAL(triggered()), this, SLOT(readFromEnd()));
1277
1278 _readToEndAct = new QAction(tr("&Read to End"), this);
1279 _readToEndAct->setStatusTip(tr("Read to end mode"));
1280 _readToEndAct->setToolTip(tr("Read to end mode (shift+end)"));
1281 _readToEndAct->setIcon(KstGetIcon("read-to-end"));
1282 _readToEndAct->setShortcut(Qt::ShiftModifier+Qt::Key_End);
1283 connect(_readToEndAct, SIGNAL(triggered()), this, SLOT(readToEnd()));
1284
1285 _pauseAct = new QAction(tr("&Pause"), this);
1286 _pauseAct->setIcon(KstGetIcon("pause"));
1287 _pauseAct->setCheckable(true);
1288 _pauseAct->setShortcut(tr("p", "shortcut for pause"));
1289 _pauseAct->setStatusTip(tr("Toggle pause updates of data sources (%1)").arg(_pauseAct->shortcut().toString()));
1290 _pauseAct->setToolTip(tr("Toggle \"Pause Data Sources\" (%1)").arg(_pauseAct->shortcut().toString()));
1291 connect(_pauseAct, SIGNAL(toggled(bool)), this, SLOT(pause(bool)));
1292
1293 _changeDataSampleDialogAct = new QAction(tr("Change Data &Sample Range..."), this);
1294 _changeDataSampleDialogAct->setShortcut(tr("J", "shortcut change data sample dialog"));
1295 _changeDataSampleDialogAct->setStatusTip(tr("Show Kst's Change Data Sample Range Dialog (%1)").arg(_changeDataSampleDialogAct->shortcut().toString()));
1296 _changeDataSampleDialogAct->setToolTip(tr("Change Data Sample Range (%1)").arg(_changeDataSampleDialogAct->shortcut().toString()));
1297 _changeDataSampleDialogAct->setIcon(KstGetIcon("kst_changenpts"));
1298 connect(_changeDataSampleDialogAct, SIGNAL(triggered()), this, SLOT(showChangeDataSampleDialog()));
1299
1300 // ************************ Create Actions ************************** //
1301 _insertPlotAct = new QAction(tr("&Plot"), this);
1302 _insertPlotAct->setIcon(KstGetIcon("kst_newplot"));
1303 _insertPlotAct->setShortcut(QString("F11"));
1304 _insertPlotAct->setStatusTip(tr("Insert a plot in the current view (%1)").arg(_insertPlotAct->shortcut().toString()));
1305 _insertPlotAct->setToolTip(tr("New plot (%1)").arg(_insertPlotAct->shortcut().toString()));
1306 _insertPlotAct->setCheckable(false);
1307 connect(_insertPlotAct, SIGNAL(triggered()), this, SLOT(insertPlot()));
1308
1309 _createPlotAct = new QAction(tr("&Plot"), this);
1310 _createPlotAct->setIcon(KstGetIcon("kst_newplot"));
1311 //_createPlotAct->setShortcut(QString("F11"));
1312 _createPlotAct->setStatusTip(tr("Create a plot for the current view"));
1313 _createPlotAct->setCheckable(true);
1314 connect(_createPlotAct, SIGNAL(triggered()), this, SLOT(createPlot()));
1315
1316 _newScalarAct = new QAction(tr("&Scalar"), this);
1317 connect(_newScalarAct, SIGNAL(triggered()), this, SLOT(createScalar()));
1318
1319 _newVectorAct = new QAction(tr("&Vector"), this);
1320 connect(_newVectorAct, SIGNAL(triggered()), this, SLOT(createVector()));
1321
1322 _newMatrixAct = new QAction(tr("&Matrix"), this);
1323 connect(_newMatrixAct, SIGNAL(triggered()), this, SLOT(createMatrix()));
1324
1325 _newStringAct = new QAction(tr("Strin&g"), this);
1326 connect(_newStringAct, SIGNAL(triggered()), this, SLOT(createString()));
1327
1328 _newCurveAct = new QAction(tr("&Curve"), this);
1329 connect(_newCurveAct, SIGNAL(triggered()), this, SLOT(createCurve()));
1330
1331 _newEquationAct = new QAction(tr("&Equation"), this);
1332 connect(_newEquationAct, SIGNAL(triggered()), this, SLOT(createEquation()));
1333
1334 _newPSDAct = new QAction(tr("Po&wer Spectrum"), this);
1335 connect(_newPSDAct, SIGNAL(triggered()), this, SLOT(createPSD()));
1336
1337 _newHistogramAct = new QAction(tr("&Histogram"), this);
1338 connect(_newHistogramAct, SIGNAL(triggered()), this, SLOT(createHistogram()));
1339
1340 _newImageAct = new QAction(tr("&Image"), this);
1341 connect(_newImageAct, SIGNAL(triggered()), this, SLOT(createImage()));
1342
1343 _newSpectrogramAct = new QAction(tr("Spectr&ogram"), this);
1344 connect(_newSpectrogramAct, SIGNAL(triggered()), this, SLOT(createSpectogram()));
1345
1346 _newEventMonitorAct = new QAction(tr("Eve&nt Monitor"), this);
1347 connect(_newEventMonitorAct, SIGNAL(triggered()), this, SLOT(createEventMonitor()));
1348
1349 // Advanced layout
1350 _createLabelAct = new QAction(tr("&Label"), this);
1351 _createLabelAct->setIcon(KstGetIcon("kst_gfx_label"));
1352 _createLabelAct->setShortcut(QString("F3"));
1353 _createLabelAct->setStatusTip(tr("Create a label for the current view (%1)").arg(_createLabelAct->shortcut().toString()));
1354 _createLabelAct->setToolTip(tr("Create label (%1)").arg(_createLabelAct->shortcut().toString()));
1355 _createLabelAct->setCheckable(true);
1356 connect(_createLabelAct, SIGNAL(triggered()), this, SLOT(createLabel()));
1357
1358 _createBoxAct = new QAction(tr("&Box"), this);
1359 _createBoxAct->setIcon(KstGetIcon("kst_gfx_rectangle"));
1360 _createBoxAct->setShortcut(QString("F4"));
1361 _createBoxAct->setStatusTip(tr("Create a box for the current view (%1)").arg(_createBoxAct->shortcut().toString()));
1362 _createBoxAct->setToolTip(tr("Create box (%1)").arg(_createBoxAct->shortcut().toString()));
1363 _createBoxAct->setCheckable(true);
1364 connect(_createBoxAct, SIGNAL(triggered()), this, SLOT(createBox()));
1365
1366 _createCircleAct = new QAction(tr("&Circle"), this);
1367 _createCircleAct->setIcon(KstGetIcon("kst_gfx_circle"));
1368 _createCircleAct->setShortcut(QString("F5"));
1369 _createCircleAct->setStatusTip(tr("Create a circle for the current view (%1)").arg(_createCircleAct->shortcut().toString()));
1370 _createCircleAct->setToolTip(tr("Create circle (%1)").arg(_createCircleAct->shortcut().toString()));
1371 _createCircleAct->setCheckable(true);
1372 connect(_createCircleAct, SIGNAL(triggered()), this, SLOT(createCircle()));
1373
1374 _createEllipseAct = new QAction(tr("&Ellipse"), this);
1375 _createEllipseAct->setIcon(KstGetIcon("kst_gfx_ellipse"));
1376 _createEllipseAct->setShortcut(QString("F6"));
1377 _createEllipseAct->setStatusTip(tr("Create an ellipse for the current view (%1)").arg(_createEllipseAct->shortcut().toString()));
1378 _createEllipseAct->setToolTip(tr("Create ellipse (%1)").arg(_createEllipseAct->shortcut().toString()));
1379 _createEllipseAct->setCheckable(true);
1380 connect(_createEllipseAct, SIGNAL(triggered()), this, SLOT(createEllipse()));
1381
1382 _createLineAct = new QAction(tr("&Line"), this);
1383 _createLineAct->setIcon(KstGetIcon("kst_gfx_line"));
1384 _createLineAct->setShortcut(QString("F7"));
1385 _createLineAct->setStatusTip(tr("Create a line for the current view (%1)").arg(_createLineAct->shortcut().toString()));
1386 _createLineAct->setToolTip(tr("Create line (%1)").arg(_createLineAct->shortcut().toString()));
1387 _createLineAct->setCheckable(true);
1388 connect(_createLineAct, SIGNAL(triggered()), this, SLOT(createLine()));
1389
1390 _createArrowAct = new QAction(tr("&Arrow"), this);
1391 _createArrowAct->setIcon(KstGetIcon("kst_gfx_arrow"));
1392 _createArrowAct->setShortcut(QString("F8"));
1393 _createArrowAct->setStatusTip(tr("Create a arrow for the current view (%1)").arg(_createArrowAct->shortcut().toString()));
1394 _createArrowAct->setToolTip(tr("Create arrow (%1)").arg(_createArrowAct->shortcut().toString()));
1395 _createArrowAct->setCheckable(true);
1396 connect(_createArrowAct, SIGNAL(triggered()), this, SLOT(createArrow()));
1397
1398 _createPictureAct = new QAction(tr("&Picture"), this);
1399 _createPictureAct->setIcon(KstGetIcon("insert-image"));
1400 _createPictureAct->setShortcut(QString("F9"));
1401 _createPictureAct->setStatusTip(tr("Create a picture for the current view (%1)").arg(_createPictureAct->shortcut().toString()));
1402 _createPictureAct->setToolTip(tr("Create picture (%1)").arg(_createPictureAct->shortcut().toString()));
1403 _createPictureAct->setCheckable(true);
1404 connect(_createPictureAct, SIGNAL(triggered()), this, SLOT(createPicture()));
1405
1406 #ifndef KST_NO_SVG
1407 _createSvgAct = new QAction(tr("&Svg"), this);
1408 _createSvgAct->setIcon(KstGetIcon("draw-bezier-curves"));
1409 _createSvgAct->setShortcut(QString("F10"));
1410 _createSvgAct->setStatusTip(tr("Create a svg for the current view (%1)").arg(_createSvgAct->shortcut().toString()));
1411 _createSvgAct->setToolTip(tr("Create embedded svg image (%1)").arg(_createSvgAct->shortcut().toString()));
1412 _createSvgAct->setCheckable(true);
1413 connect(_createSvgAct, SIGNAL(triggered()), this, SLOT(createSvg()));
1414 #endif
1415
1416 _createSharedAxisBoxAct = new QAction(tr("Shared Axis &Box"), this);
1417 _createSharedAxisBoxAct->setStatusTip(tr("Create a shared axis box for the current item"));
1418 _createSharedAxisBoxAct->setIcon(KstGetIcon("kst_gfx_sharedaxisbox"));
1419 _createSharedAxisBoxAct->setCheckable(true);
1420 connect(_createSharedAxisBoxAct, SIGNAL(triggered()), this, SLOT(createSharedAxisBox()));
1421
1422 // ************************** Mode Actions ******************************* //
1423 // First, general options
1424 _tiedZoomAct = new QAction(tr("&Toggle Tied Zoom"), this);
1425 _tiedZoomAct->setIcon(KstGetIcon("tied-zoom"));
1426 _tiedZoomAct->setCheckable(false);
1427 _tiedZoomAct->setShortcut(Qt::Key_O);
1428 _tiedZoomAct->setStatusTip(tr("Toggle the current view's tied zoom (%1)").arg(_tiedZoomAct->shortcut().toString()));
1429 _tiedZoomAct->setToolTip(tr("Toggle tied zoom (%1)").arg(_tiedZoomAct->shortcut().toString()));
1430 connect(_tiedZoomAct, SIGNAL(triggered()), this, SLOT(toggleTiedZoom()));
1431
1432 _tabTiedAct = new QAction(tr("Tie &Across All Tabs"), this);
1433 _tabTiedAct->setStatusTip(tr("Tied zoom applies between tabs"));
1434 //_tiedZoomAct->setIcon(KstGetIcon("tied-zoom"));
1435 _tabTiedAct->setCheckable(true);
1436 //connect(_tiedZoomAct, SIGNAL(triggered()), this, SLOT(toggleTiedZoom()));
1437
1438
1439 _highlightPointAct = new QAction(tr("&Highlight Data Points"), this);
1440 _highlightPointAct->setShortcut(QString("h"));
1441 _highlightPointAct->setStatusTip(tr("Highlight closest data point (%1)").arg(_highlightPointAct->shortcut().toString()));
1442 _highlightPointAct->setToolTip(tr("Highlight closest data point (%1)").arg(_highlightPointAct->shortcut().toString()));
1443 _highlightPointAct->setIcon(KstGetIcon("kst_datamode"));
1444 _highlightPointAct->setCheckable(true);
1445 connect(_highlightPointAct, SIGNAL(toggled(bool)), this, SLOT(setHighlightPoint(bool)));
1446
1447
1448 // Then, exclusive interaction modes
1449 QActionGroup* _interactionModeGroup = new QActionGroup(this);
1450
1451 _standardZoomAct = _interactionModeGroup->addAction(tr("X-Y Zoom/Scroll"));
1452 _standardZoomAct->setStatusTip(tr("Zoom arbitrarily in X- or Y-direction"));
1453 _standardZoomAct->setShortcut(Qt::Key_K);
1454 _standardZoomAct->setToolTip(tr("X-Y Zoom mode (%1)").arg(_standardZoomAct->shortcut().toString()));
1455 _standardZoomAct->setCheckable(true);
1456 _standardZoomAct->setData(View::ZoomOnlyDisabled);
1457 _standardZoomAct->setIcon(KstGetIcon("xy-zoom"));
1458
1459 _xOnlyZoomAct = _interactionModeGroup->addAction(tr("&X-only Zoom"));
1460 _xOnlyZoomAct->setStatusTip(tr("Zoom only in X direction"));
1461 _xOnlyZoomAct->setShortcut(Qt::CTRL + Qt::Key_K);
1462 _xOnlyZoomAct->setToolTip(tr("X Zoom mode (%1)").arg(_xOnlyZoomAct->shortcut().toString()));
1463 _xOnlyZoomAct->setCheckable(true);
1464 _xOnlyZoomAct->setData(View::ZoomOnlyX);
1465 _xOnlyZoomAct->setIcon(KstGetIcon("x-zoom"));
1466
1467 _yOnlyZoomAct = _interactionModeGroup->addAction(tr("&Y-only Zoom"));
1468 _yOnlyZoomAct->setStatusTip(tr("Zoom only in Y direction"));
1469 _yOnlyZoomAct->setShortcut(Qt::SHIFT + Qt::Key_K);
1470 _yOnlyZoomAct->setToolTip(tr("Y Zoom mode (%1)").arg(_yOnlyZoomAct->shortcut().toString()));
1471 _yOnlyZoomAct->setData(View::ZoomOnlyY);
1472 _yOnlyZoomAct->setCheckable(true);
1473 _yOnlyZoomAct->setIcon(KstGetIcon("y-zoom"));
1474
1475 _layoutModeAct = _interactionModeGroup->addAction(tr("&Layout Mode"));
1476 _layoutModeAct->setIcon(KstGetIcon("transform-move"));
1477 _layoutModeAct->setCheckable(true);
1478 _layoutModeAct->setShortcut(QString("F2"));
1479 _layoutModeAct->setStatusTip(tr("Toggle the current view's layout mode (%1)").arg(_layoutModeAct->shortcut().toString()));
1480 _layoutModeAct->setToolTip(tr("Layout mode (%1)").arg(_layoutModeAct->shortcut().toString()));
1481 connect(_layoutModeAct, SIGNAL(toggled(bool)), this, SLOT(setLayoutMode(bool)));
1482
1483 _interactionModeGroup->setExclusive(true);
1484 connect(_interactionModeGroup, SIGNAL(triggered(QAction*)), this, SLOT(changeZoomOnlyMode(QAction*)));
1485
1486 // *********************** Tools actions ************************************** //
1487 _dataManagerAct = new QAction(tr("Data Manager"), this);
1488 _dataManagerAct->setIcon(KstGetIcon("data-manager"));
1489 _dataManagerAct->setShortcut(QString("d"));
1490 _dataManagerAct->setStatusTip(tr("Show Kst's data manager window (%1)").arg(_dataManagerAct->shortcut().toString()));
1491 _dataManagerAct->setToolTip(tr("Show Data Manager (%1)").arg(_dataManagerAct->shortcut().toString()));
1492 connect(_dataManagerAct, SIGNAL(triggered()), this, SLOT(showDataManager()));
1493
1494 _dataWizardAct = new QAction(tr("&Data Wizard"), this);
1495 _dataWizardAct->setIcon(KstGetIcon("tools-wizard"));
1496 _dataWizardAct->setShortcut(QString("w"));
1497 _dataWizardAct->setStatusTip(tr("Show Kst's Data Wizard (%1)").arg(_dataWizardAct->shortcut().toString()));
1498 _dataWizardAct->setToolTip(tr("Show Data Wizard (%1)").arg(_dataWizardAct->shortcut().toString()));
1499 connect(_dataWizardAct, SIGNAL(triggered()), this, SLOT(showDataWizard()));
1500
1501 _changeFileDialogAct = new QAction(tr("Change Data &File"), this);
1502 _changeFileDialogAct->setIcon(KstGetIcon("change-data-file"));
1503 _changeFileDialogAct->setStatusTip(tr("Show Kst's Change Data File Dialog (%1)").arg(_changeFileDialogAct->shortcut().toString()));
1504 _changeFileDialogAct->setShortcut(QString("f"));
1505 _changeFileDialogAct->setToolTip(tr("Show Change Data File Dialog (%1)").arg(_changeFileDialogAct->shortcut().toString()));
1506 connect(_changeFileDialogAct, SIGNAL(triggered()), this, SLOT(showChangeFileDialog()));
1507
1508 _chooseColorDialogAct = new QAction(tr("Assign Curve &Color per File"), this);
1509 _chooseColorDialogAct->setStatusTip(tr("Show Kst's Choose Color Dialog"));
1510 _chooseColorDialogAct->setIcon(KstGetIcon("code-class"));
1511 connect(_chooseColorDialogAct, SIGNAL(triggered()), this, SLOT(showChooseColorDialog()));
1512
1513 _differentiateCurvesDialogAct = new QAction(tr("D&ifferentiate Curves"), this);
1514 _differentiateCurvesDialogAct->setStatusTip(tr("Show Kst's Differentiate Curves Dialog"));
1515 _differentiateCurvesDialogAct->setIcon(KstGetIcon("kst_differentiatecurves"));
1516 connect(_differentiateCurvesDialogAct, SIGNAL(triggered()), this, SLOT(showDifferentiateCurvesDialog()));
1517
1518 _filterMultipleDialogAct = new QAction(tr("&Filter Vectors"), this);
1519 _filterMultipleDialogAct->setStatusTip(tr("Filter multiple vectors"));
1520 _filterMultipleDialogAct->setIcon(KstGetIcon("kst_filter_vectors"));
1521 connect(_filterMultipleDialogAct, SIGNAL(triggered()), this, SLOT(filterMultipleDialog()));
1522
1523 // *********************** Settings actions ************************************** //
1524 _settingsDialogAct = new QAction(tr("&Configure Kst"), this);
1525 _settingsDialogAct->setStatusTip(tr("Show Kst's Configuration Dialog"));
1526 _settingsDialogAct->setIcon(KstGetIcon("configure"));
1527 connect(_settingsDialogAct, SIGNAL(triggered()), this, SLOT(showSettingsDialog()));
1528
1529 _themeDialogAct = new QAction(tr("&Theme"), this);
1530 _themeDialogAct->setStatusTip(tr("Show Kst's Theme Dialog"));
1531 _themeDialogAct->setIcon(KstGetIcon("themes"));
1532 connect(_themeDialogAct, SIGNAL(triggered()), this, SLOT(showThemeDialog()));
1533
1534 _clearUISettings = new QAction(tr("Clear settings and defaults"), this);
1535 _clearUISettings->setStatusTip(tr("Clear sticky defaults and all settings in all dialogs."));
1536 //_clearUISettings->setIcon(KstGetIcon("configure")); // FIXME: pick an icon (broom?)
1537 connect(_clearUISettings, SIGNAL(triggered()), this, SLOT(clearDefaults()));
1538
1539 _clearDataSourceSettings = new QAction(tr("Clear datasource settings"), this);
1540 _clearDataSourceSettings->setStatusTip(tr("Clear datasource settings"));
1541 //_clearDataSourceSettings->setIcon(KstGetIcon("configure")); // FIXME: pick an icon (broom?)
1542 connect(_clearDataSourceSettings, SIGNAL(triggered()), this, SLOT(clearDataSourceSettings()));
1543
1544 // *********************** Help actions ************************************** //
1545 _debugDialogAct = new QAction(tr("&Debug Dialog"), this);
1546 _debugDialogAct->setStatusTip(tr("Show the Kst debugging dialog"));
1547 _debugDialogAct->setIcon(KstGetIcon("text-x-log"));
1548 connect(_debugDialogAct, SIGNAL(triggered()), this, SLOT(showDebugDialog()));
1549
1550 _bugReportWizardAct = new QAction(tr("&Bug Report Wizard"), this);
1551 _bugReportWizardAct->setStatusTip(tr("Show Kst's Bug Report Wizard"));
1552 _bugReportWizardAct->setIcon(KstGetIcon("kbugbuster"));
1553 connect(_bugReportWizardAct, SIGNAL(triggered()), this, SLOT(showBugReportWizard()));
1554
1555 _aboutAct = new QAction(tr("&About"), this);
1556 _aboutAct->setStatusTip(tr("Show Kst's About box"));
1557 _aboutAct->setIcon(KstGetIcon("dialog-information"));
1558 connect(_aboutAct, SIGNAL(triggered()), this, SLOT(about()));
1559
1560 _showShortcutAct = new QAction(tr("Keyboard Shortcuts"), this);
1561 _showShortcutAct->setStatusTip(tr("Show a list of keyboard shortcuts"));
1562 connect(_showShortcutAct, SIGNAL(triggered()), this, SLOT(showShortcutDialog()));
1563
1564 _video1Act = new QAction(tr("#&1: Quick Start"), this);
1565 _video1Act->setStatusTip(tr("Kst presentation #1: The shortest tutorial to the fastest plotting tool"));
1566 connect(_video1Act, SIGNAL(triggered()), _videoMapper, SLOT(map()));
1567 _videoMapper->setMapping(_video1Act, 1);
1568 _video2Act = new QAction(tr("#&2: General UI Presentation"), this);
1569 _video2Act->setStatusTip(tr("Kst presentation #2: General presentation of the user interface and most important concepts"));
1570 connect(_video2Act, SIGNAL(triggered()), _videoMapper, SLOT(map()));
1571 _videoMapper->setMapping(_video2Act, 2);
1572 _video3Act = new QAction(tr("#&3: Live Data / Range Tools"), this);
1573 _video3Act->setStatusTip(tr("Kst presentation #3: Range tools and live plots with streaming data"));
1574 connect(_video3Act, SIGNAL(triggered()), _videoMapper, SLOT(map()));
1575 _videoMapper->setMapping(_video3Act, 3);
1576 _video4Act = new QAction(tr("#&4: FFT, Equations, Fits, Filters"), this);
1577 _video4Act->setStatusTip(tr("Kst presentation #4: FFTs, equations, filters, fits, plugins"));
1578 connect(_video4Act, SIGNAL(triggered()), _videoMapper, SLOT(map()));
1579 _videoMapper->setMapping(_video4Act, 4);
1580 _video5Act = new QAction(tr("#&5: Productivity Features"), this);
1581 _video5Act->setStatusTip(tr("Kst presentation #5: Unique productivity features like edit multiple mode and change data file tool"));
1582 connect(_video5Act, SIGNAL(triggered()), _videoMapper, SLOT(map()));
1583 _videoMapper->setMapping(_video5Act, 5);
1584 _video6Act = new QAction(tr("#&6: Advanced Layout / Export"), this);
1585 _video6Act->setStatusTip(tr("Kst presentation #6: Advanced layout and export options"));
1586 connect(_video6Act, SIGNAL(triggered()), _videoMapper, SLOT(map()));
1587 _videoMapper->setMapping(_video6Act, 6);
1588 _video7Act = new QAction(tr("#&7: Matrices / Images / Metadata"), this);
1589 _video7Act->setStatusTip(tr("Kst presentation #7: Matrices, images and metadata"));
1590 connect(_video7Act, SIGNAL(triggered()), _videoMapper, SLOT(map()));
1591 _videoMapper->setMapping(_video7Act, 7);
1592 connect(_videoMapper, SIGNAL(mapped(int)), this, SLOT(videoTutorial(int)));
1593 }
1594
1595
createMenus()1596 void MainWindow::createMenus() {
1597 _fileMenu = menuBar()->addMenu(tr("&File"));
1598 // Session operations
1599 _fileMenu->addAction(_openAct);
1600 _fileMenu->addAction(_saveAct);
1601 _fileMenu->addAction(_saveAsAct);
1602 _fileMenu->addAction(_closeAct);
1603 _fileMenu->addSeparator();
1604 _recentKstFilesMenu = _fileMenu->addMenu(tr("&Recent Sessions"));
1605 _recentDataFilesMenu = _fileMenu->addMenu(tr("Recent Data &Files"));
1606 _fileMenu->addSeparator();
1607 // Reload, isolate it a bit from the other entries to avoid inadvertent triggering
1608 _fileMenu->addAction(_reloadAct);
1609 _fileMenu->addSeparator();
1610 // Print/export
1611 _fileMenu->addAction(_printAct);
1612 _fileMenu->addAction(_exportGraphicsAct);
1613 _fileMenu->addAction(_exportVectorsAct);
1614 _fileMenu->addAction(_logAct);
1615 _fileMenu->addSeparator();
1616 // Tabs
1617 _fileMenu->addAction(_newTabAct);
1618 _fileMenu->addAction(_closeTabAct);
1619 _fileMenu->addSeparator();
1620 // exit
1621 _fileMenu->addAction(_exitAct);
1622 // recent files
1623 _fileMenu->addSeparator();
1624 updateRecentKstFiles();
1625
1626
1627 _editMenu = menuBar()->addMenu(tr("&Edit"));
1628 _editMenu->addAction(_undoAct);
1629 _editMenu->addAction(_redoAct);
1630 _editMenu->addAction(_copyTabAct);
1631 // Cut/Copy/Paste will come here
1632
1633 _viewMenu = menuBar()->addMenu(tr("&View"));
1634 _viewMenu->addAction(_vectorEditorAct);
1635 _viewMenu->addAction(_scalarEditorAct);
1636 _viewMenu->addAction(_matrixEditorAct);
1637 _viewMenu->addAction(_stringEditorAct);
1638
1639 _rangeMenu = menuBar()->addMenu(tr("&Range"));
1640 _rangeMenu->addAction(_backAct);
1641 _rangeMenu->addAction(_backSmallAct);
1642 _rangeMenu->addAction(_forwardAct);
1643 _rangeMenu->addAction(_forwardSmallAct);
1644 _rangeMenu->addSeparator();
1645 _rangeMenu->addAction(_readFromEndAct);
1646 _rangeMenu->addAction(_readToEndAct);
1647 _rangeMenu->addAction(_pauseAct);
1648 _rangeMenu->addSeparator();
1649 _rangeMenu->addAction(_changeDataSampleDialogAct);
1650
1651 _createMenu = menuBar()->addMenu(tr("&Create"));
1652 // Containers
1653 _createMenu->addAction(_insertPlotAct);
1654 //_createMenu->addAction(_createPlotAct);
1655 _createMenu->addAction(_createSharedAxisBoxAct);
1656 _createMenu->addSeparator();
1657 // Primitives
1658 _createMenu->addAction(_newScalarAct);
1659 _createMenu->addAction(_newVectorAct);
1660 _createMenu->addAction(_newMatrixAct);
1661 _createMenu->addAction(_newStringAct);
1662 _createMenu->addSeparator();
1663 // Data objects
1664 _createMenu->addAction(_newEquationAct);
1665 _createMenu->addAction(_newHistogramAct);
1666 _createMenu->addAction(_newPSDAct);
1667 _createMenu->addAction(_newSpectrogramAct);
1668 _createMenu->addAction(_newEventMonitorAct);
1669 _createMenu->addSeparator();
1670
1671 // Now, create the dynamic plugin menus
1672 QMenu* _pluginsMenu = _createMenu->addMenu(tr("Standard P&lugin"));
1673 QMenu* _fitPluginsMenu = _createMenu->addMenu(tr("Fit Pl&ugin"));
1674 QMenu* _filterPluginsMenu = _createMenu->addMenu(tr("Fil&ter Plugin"));
1675 PluginMenuItemAction* action;
1676 foreach (const QString &pluginName, DataObject::dataObjectPluginList()) {
1677 action = new PluginMenuItemAction(pluginName, this);
1678 connect(action, SIGNAL(triggered(QString&)), this, SLOT(showPluginDialog(QString&)));
1679 _pluginsMenu->addAction(action);
1680 }
1681 foreach (const QString &pluginName, DataObject::fitsPluginList()) {
1682 action = new PluginMenuItemAction(pluginName, this);
1683 connect(action, SIGNAL(triggered(QString&)), this, SLOT(showPluginDialog(QString&)));
1684 _fitPluginsMenu->addAction(action);
1685 }
1686 foreach (const QString &pluginName, DataObject::filterPluginList()) {
1687 action = new PluginMenuItemAction(pluginName, this);
1688 connect(action, SIGNAL(triggered(QString&)), this, SLOT(showPluginDialog(QString&)));
1689 _filterPluginsMenu->addAction(action);
1690 }
1691 _createMenu->addSeparator();
1692 // Relations
1693 _createMenu->addAction(_newCurveAct);
1694 _createMenu->addAction(_newImageAct);
1695 _createMenu->addSeparator();
1696 // Annotation objects
1697 QMenu* annotations = _createMenu->addMenu(tr("&Annotation"));
1698 annotations->addAction(_createLabelAct);
1699 annotations->addAction(_createBoxAct);
1700 annotations->addAction(_createCircleAct);
1701 annotations->addAction(_createEllipseAct);
1702 annotations->addAction(_createLineAct);
1703 annotations->addAction(_createArrowAct);
1704 annotations->addAction(_createPictureAct);
1705 #ifndef KST_NO_SVG
1706 annotations->addAction(_createSvgAct);
1707 #endif
1708
1709 _modeMenu = menuBar()->addMenu(tr("&Mode"));
1710 // Interaction mode
1711 _modeMenu->addSeparator()->setText(tr("Interaction mode"));
1712 _modeMenu->addAction(_standardZoomAct);
1713 _modeMenu->addAction(_xOnlyZoomAct);
1714 _modeMenu->addAction(_yOnlyZoomAct);
1715 _modeMenu->addAction(_layoutModeAct);
1716 _standardZoomAct->setChecked(true);
1717 _modeMenu->addSeparator();
1718 // Tied zoom options
1719 _modeMenu->addAction(_tiedZoomAct);
1720 _modeMenu->addAction(_tabTiedAct);
1721 _modeMenu->addSeparator();
1722 // Data mode
1723 _modeMenu->addAction(_highlightPointAct);
1724
1725 _toolsMenu = menuBar()->addMenu(tr("&Tools"));
1726 _toolsMenu->addAction(_dataManagerAct);
1727 _toolsMenu->addAction(_dataWizardAct);
1728 _toolsMenu->addAction(_changeFileDialogAct);
1729 _toolsMenu->addAction(_chooseColorDialogAct);
1730 _toolsMenu->addAction(_differentiateCurvesDialogAct);
1731 _toolsMenu->addAction(_filterMultipleDialogAct);
1732 _toolsMenu->addSeparator();
1733 updateRecentDataFiles();
1734
1735 _settingsMenu = menuBar()->addMenu(tr("&Settings"));
1736 _settingsMenu->addAction(_settingsDialogAct);
1737 _settingsMenu->addAction(_themeDialogAct);
1738 _settingsMenu->addAction(_clearUISettings);
1739 _settingsMenu->addAction(_clearDataSourceSettings);
1740
1741 menuBar()->addSeparator();
1742
1743 _helpMenu = menuBar()->addMenu(tr("&Help"));
1744 QMenu* _videoTutorialsMenu = _helpMenu->addMenu(tr("&Video tutorials"));
1745 _videoTutorialsMenu->addAction(_video1Act);
1746 _videoTutorialsMenu->addAction(_video2Act);
1747 _videoTutorialsMenu->addAction(_video3Act);
1748 _videoTutorialsMenu->addAction(_video4Act);
1749 _videoTutorialsMenu->addAction(_video5Act);
1750 _videoTutorialsMenu->addAction(_video6Act);
1751 _videoTutorialsMenu->addAction(_video7Act);
1752 _helpMenu->addSeparator();
1753 _helpMenu->addAction(_debugDialogAct);
1754 _helpMenu->addAction(_bugReportWizardAct);
1755 _helpMenu->addSeparator();
1756 _helpMenu->addAction(_showShortcutAct);
1757 _helpMenu->addAction(_aboutAct);
1758
1759 }
1760
1761
createToolBars()1762 void MainWindow::createToolBars() {
1763 setToolButtonStyle(Qt::ToolButtonIconOnly);
1764
1765 _fileToolBar = addToolBar(tr("File"));
1766 _fileToolBar->setObjectName("File Toolbar");
1767 _fileToolBar->addAction(_openAct);
1768 _fileToolBar->addAction(_saveAct);
1769 _fileToolBar->addAction(_reloadAct);
1770 _fileToolBar->addAction(_printAct);
1771 _fileToolBar->addAction(_logAct);
1772
1773 _editToolBar = addToolBar(tr("Edit"));
1774 _editToolBar->setObjectName("Edit Toolbar");
1775 _editToolBar->addAction(_undoAct);
1776 _editToolBar->addAction(_redoAct);
1777 _editToolBar->addAction(_copyTabAct);
1778
1779 _toolsToolBar = addToolBar(tr("Tools"));
1780 _toolsToolBar->setObjectName("Tools Toolbar");
1781 _toolsToolBar->addAction(_dataManagerAct);
1782 _toolsToolBar->addAction(_dataWizardAct);
1783 _toolsToolBar->addAction(_changeDataSampleDialogAct);
1784 _toolsToolBar->addAction(_changeFileDialogAct);
1785
1786 _rangeToolBar = addToolBar(tr("Data Range"));
1787 _rangeToolBar->setObjectName("Data Range Toolbar");
1788 _rangeToolBar->addAction(_backAct);
1789 _rangeToolBar->addAction(_forwardAct);
1790 _rangeToolBar->addAction(_readFromEndAct);
1791 _rangeToolBar->addAction(_readToEndAct);
1792 _rangeToolBar->addAction(_pauseAct);
1793
1794 _modeToolBar = addToolBar(tr("Mode"));
1795 _modeToolBar->setObjectName("Mode Toolbar");
1796 _modeToolBar->addAction(_tiedZoomAct);
1797 _modeToolBar->addAction(_highlightPointAct);
1798 _modeToolBar->addSeparator();
1799 _modeToolBar->addAction(_standardZoomAct);
1800 _modeToolBar->addAction(_xOnlyZoomAct);
1801 _modeToolBar->addAction(_yOnlyZoomAct);
1802 _modeToolBar->addAction(_layoutModeAct);
1803
1804 _plotLayoutToolBar = addToolBar(tr("Plot Layout"));
1805 _plotLayoutToolBar->setObjectName("Plot Layout Toolbar");
1806 _plotLayoutToolBar->addAction(_createSharedAxisBoxAct);
1807 _plotLayoutToolBar->addAction(_insertPlotAct);
1808 //_plotLayoutToolBar->addAction(_createPlotAct);
1809
1810 _annotationToolBar = addToolBar(tr("Advanced Layout"));
1811 _annotationToolBar->setObjectName("Advanced Layout Toolbar");
1812 _annotationToolBar->addAction(_createLabelAct);
1813 _annotationToolBar->addAction(_createBoxAct);
1814 _annotationToolBar->addAction(_createCircleAct);
1815 _annotationToolBar->addAction(_createEllipseAct);
1816 _annotationToolBar->addAction(_createLineAct);
1817 _annotationToolBar->addAction(_createArrowAct);
1818 _annotationToolBar->addAction(_createPictureAct);
1819 #ifndef KST_NO_SVG
1820 _annotationToolBar->addAction(_createSvgAct);
1821 #endif
1822 }
1823
1824
createStatusBar()1825 void MainWindow::createStatusBar() {
1826 _messageLabel = new QLabel(statusBar());
1827 setStatusMessage(tr("Ready"), 3000);
1828
1829 _progressBar = new QProgressBar(statusBar());
1830 _progressBar->setFixedWidth(200);
1831 _progressBar->hide();
1832 statusBar()->addPermanentWidget(_progressBar);
1833 MemoryWidget *mw = new MemoryWidget(statusBar());
1834 statusBar()->addPermanentWidget(mw);
1835 DebugNotifier *dn = new DebugNotifier(statusBar());
1836 connect(dn, SIGNAL(showDebugLog()), this, SLOT(showDebugDialog()));
1837 connect(_debugDialog, SIGNAL(notifyOfError()), dn, SLOT(reanimate()));
1838 connect(_debugDialog, SIGNAL(notifyAllClear()), dn, SLOT(close()));
1839 statusBar()->addPermanentWidget(dn);
1840 }
1841
1842 /** set the status bar message. If you are doing this inside a view
1843 * object paint() call, then set delayed to true, and call ::updateStatusMessage()
1844 * later (after leaving paint). This is currently done for you in updateViewItems */
setStatusMessage(QString message,int timeout,bool delayed)1845 void MainWindow::setStatusMessage(QString message, int timeout, bool delayed) {
1846 _statusBarMessage = message;
1847 _statusBarTimeout = timeout;
1848 if (!delayed) {
1849 statusBar()->showMessage(message, timeout);
1850 }
1851 }
1852
videoTutorial(int i)1853 void MainWindow::videoTutorial(int i) {
1854 switch (i) {
1855 case 1:
1856 QDesktopServices::openUrl(QUrl("http://www.youtube.com/watch?v=d1uz5g_cWh4")); break;
1857 case 2:
1858 QDesktopServices::openUrl(QUrl("http://www.youtube.com/watch?v=6z2bGNrgwL0")); break;
1859 case 3:
1860 QDesktopServices::openUrl(QUrl("http://www.youtube.com/watch?v=dstOQpmfY1U")); break;
1861 case 4:
1862 QDesktopServices::openUrl(QUrl("http://www.youtube.com/watch?v=YJ54X0nKnmk")); break;
1863 case 5:
1864 QDesktopServices::openUrl(QUrl("http://www.youtube.com/watch?v=3YZVC-GiS_4")); break;
1865 case 6:
1866 QDesktopServices::openUrl(QUrl("http://www.youtube.com/watch?v=rI7nYHlz6rs")); break;
1867 case 7:
1868 QDesktopServices::openUrl(QUrl("http://www.youtube.com/watch?v=mgP24MryyKw")); break;
1869 default:
1870 break;
1871 }
1872 }
1873
statusMessage()1874 QString MainWindow::statusMessage() {
1875 return statusBar()->currentMessage();
1876 }
1877
updateStatusMessage()1878 void MainWindow::updateStatusMessage() {
1879 statusBar()->showMessage(_statusBarMessage, _statusBarTimeout);
1880 }
1881
progressBar() const1882 QProgressBar *MainWindow::progressBar() const {
1883 return _progressBar;
1884 }
1885
updateProgress(int percent,const QString & message)1886 void MainWindow::updateProgress(int percent, const QString& message)
1887 {
1888 if (percent == -1) {
1889 _progressBar->setMaximum(0);
1890 _progressBar->setMinimum(0);
1891 _progressBar->show();
1892 return;
1893 }
1894
1895 if (percent > 0 && percent < 100) {
1896 _progressBar->setMaximum(100);
1897 _progressBar->setValue(percent);
1898 _progressBar->show();
1899 } else {
1900 _progressBar->hide();
1901 }
1902 setStatusMessage(message);
1903 }
1904
readFromEnd()1905 void MainWindow::readFromEnd() {
1906 int nf = 0;
1907 int skip;
1908 bool do_skip;
1909 bool do_filter;
1910
1911 DataVectorList dataVectors = document()->objectStore()->getObjects<DataVector>();
1912
1913 foreach (DataVectorPtr v, dataVectors) {
1914 v->readLock();
1915 nf = v->reqNumFrames();
1916 if (nf <=0 ) {
1917 nf = v->numFrames();
1918 }
1919 skip = v->skip();
1920 do_skip = v->doSkip();
1921 do_filter = v->doAve();
1922 v->unlock();
1923
1924 v->writeLock();
1925 v->changeFrames(-1, nf, skip, do_skip, do_filter);
1926 v->registerChange();
1927 v->unlock();
1928 }
1929
1930 VScalarList vScalars = document()->objectStore()->getObjects<VScalar>();
1931 foreach (VScalarPtr s, vScalars) {
1932 s->readLock();
1933 s->changeFrame(-1);
1934 s->registerChange();
1935 s->unlock();
1936 }
1937
1938 DataStringList dataStrings = document()->objectStore()->getObjects<DataString>();
1939 foreach (DataStringPtr s, dataStrings) {
1940 if (s->isStream()) {
1941 s->readLock();
1942 s->setFrame(-1);
1943 s->registerChange();
1944 s->unlock();
1945 }
1946 }
1947
1948 DataMatrixList dataMatrices = document()->objectStore()->getObjects<DataMatrix>();
1949 foreach (DataMatrixPtr m, dataMatrices) {
1950 m->readLock();
1951 m->setFrame(-1);
1952 m->registerChange();
1953 m->unlock();
1954 }
1955
1956 UpdateManager::self()->doUpdates(true);
1957 dialogDefaults().setValue("vector/range", nf);
1958 dialogDefaults().setValue("vector/countFromEnd", true);
1959 dialogDefaults().setValue("vector/readToEnd", false);
1960 }
1961
readToEnd()1962 void MainWindow::readToEnd() {
1963 int f0 = 0;
1964 int skip;
1965 bool do_skip;
1966 bool do_filter;
1967
1968 DataVectorList dataVectors = document()->objectStore()->getObjects<DataVector>();
1969
1970 foreach (DataVectorPtr v, dataVectors) {
1971 v->readLock();
1972 f0 = v->startFrame();
1973 skip = v->skip();
1974 do_skip = v->doSkip();
1975 do_filter = v->doAve();
1976 v->unlock();
1977
1978 v->writeLock();
1979 v->changeFrames(f0, -1, skip, do_skip, do_filter);
1980 v->registerChange();
1981 v->unlock();
1982 }
1983
1984 VScalarList vScalars = document()->objectStore()->getObjects<VScalar>();
1985 foreach (VScalarPtr s, vScalars) {
1986 s->readLock();
1987 s->changeFrame(-1);
1988 s->registerChange();
1989 s->unlock();
1990 }
1991
1992 DataStringList dataStrings = document()->objectStore()->getObjects<DataString>();
1993 foreach (DataStringPtr s, dataStrings) {
1994 if (s->isStream()) {
1995 s->readLock();
1996 s->setFrame(-1);
1997 s->registerChange();
1998 s->unlock();
1999 }
2000 }
2001
2002 DataMatrixList dataMatrices = document()->objectStore()->getObjects<DataMatrix>();
2003 foreach (DataMatrixPtr m, dataMatrices) {
2004 m->readLock();
2005 m->setFrame(-1);
2006 m->registerChange();
2007 m->unlock();
2008 }
2009
2010 dialogDefaults().setValue("vector/start", f0);
2011 dialogDefaults().setValue("vector/countFromEnd", false);
2012 dialogDefaults().setValue("vector/readToEnd", true);
2013 UpdateManager::self()->doUpdates(true);
2014 }
2015
pause(bool pause)2016 void MainWindow::pause(bool pause) {
2017 UpdateManager::self()->setPaused(pause);
2018
2019 //if (!pause) {
2020 //foreach (DataSourcePtr s, document()->objectStore()->dataSourceList()) {
2021 //s->checkUpdate();
2022 //}
2023 //}
2024 }
2025
forward(double scale)2026 void MainWindow::forward(double scale) {
2027 int f0 = 0;
2028 int nf = 0;
2029 int lastF = -1;
2030 int skip;
2031 int filelength;
2032 bool count_from_end;
2033 bool read_to_end;
2034 bool do_skip;
2035 bool do_filter;
2036
2037 DataVectorList dataVectors = document()->objectStore()->getObjects<DataVector>();
2038 DataMatrixList dataMatrices = document()->objectStore()->getObjects<DataMatrix>();
2039 VScalarList vScalars = document()->objectStore()->getObjects<VScalar>();
2040 DataStringList dataStrings = document()->objectStore()->getObjects<DataString>();
2041 QHash<int,int> lastframehash;
2042
2043 foreach (DataVectorPtr v, dataVectors) {
2044 v->readLock();
2045 f0 = v->startFrame();
2046 nf = v->numFrames();
2047 count_from_end = v->countFromEOF();
2048 read_to_end = v->readToEOF();
2049 filelength = v->fileLength();
2050
2051 skip = v->skip();
2052 do_skip = v->doSkip();
2053 do_filter = v->doAve();
2054 v->unlock();
2055
2056 if ((!count_from_end) && (!read_to_end)) {
2057 f0 += ceil(scale*nf);
2058 if (f0+nf>=filelength) {
2059 f0 = filelength - nf;
2060 }
2061 lastF = f0 + nf - 1;
2062 ++lastframehash[lastF];
2063
2064 v->writeLock();
2065 v->changeFrames(f0, nf, skip, do_skip, do_filter);
2066 v->registerChange();
2067 v->unlock();
2068 }
2069 }
2070
2071 int most_popular_lastF = -1;
2072 int n_most_popular_lastF = -1;
2073 foreach (int key, lastframehash.keys()) {
2074 int n = lastframehash[key] ;
2075 if (n > n_most_popular_lastF) {
2076 n_most_popular_lastF = n;
2077 most_popular_lastF = key;
2078 }
2079 }
2080
2081 foreach (VScalarPtr vs, vScalars) {
2082 int new_frame;
2083 int filelength = vs->fileLength();
2084 if (most_popular_lastF>=0) {
2085 if (most_popular_lastF < filelength) {
2086 new_frame = most_popular_lastF;
2087 } else {
2088 new_frame = filelength-1;
2089 }
2090 } else {
2091 if (vs->F0() < 0) {
2092 new_frame = -1;
2093 } else if (vs->F0()+1 <= filelength) {
2094 new_frame = vs->F0()+1;
2095 } else {
2096 new_frame = filelength-1;
2097 }
2098 }
2099 vs->writeLock();
2100 vs->changeFrame(new_frame);
2101 vs->registerChange();
2102 vs->unlock();
2103 }
2104
2105 foreach (DataStringPtr s, dataStrings) {
2106 if (s->isStream()) {
2107 int new_frame;
2108 int filelength = s->fileLength();
2109 if (most_popular_lastF>=0) {
2110 if (most_popular_lastF < filelength) {
2111 new_frame = most_popular_lastF;
2112 } else {
2113 new_frame = filelength-1;
2114 }
2115 } else {
2116 if (s->frame() < 0) {
2117 new_frame = -1;
2118 } else if (s->frame()+1 < filelength) {
2119 new_frame = s->frame()+1;
2120 } else {
2121 new_frame = filelength-1;
2122 }
2123 }
2124 s->writeLock();
2125 s->setFrame(new_frame);
2126 s->registerChange();
2127 s->unlock();
2128 }
2129 }
2130
2131
2132 foreach (DataMatrixPtr m, dataMatrices) {
2133 if (m->isStream()) {
2134 int new_frame;
2135 int filelength = m->fileLength();
2136 if (most_popular_lastF>=0) {
2137 if (most_popular_lastF < filelength) {
2138 new_frame = most_popular_lastF;
2139 } else {
2140 new_frame = filelength-1;
2141 }
2142 } else {
2143 if (m->frame() < 0) {
2144 new_frame = -1;
2145 } else if (m->frame()+1 < filelength) {
2146 new_frame = m->frame()+1;
2147 } else {
2148 new_frame = filelength-1;
2149 }
2150 }
2151 m->writeLock();
2152 m->setFrame(new_frame);
2153 m->registerChange();
2154 m->unlock();
2155 }
2156 }
2157
2158 dialogDefaults().setValue("vector/range", nf);
2159 dialogDefaults().setValue("vector/start", f0);
2160 dialogDefaults().setValue("vector/countFromEnd", false);
2161 dialogDefaults().setValue("vector/readToEnd", false);
2162
2163 UpdateManager::self()->doUpdates(true);
2164 }
2165
back(double scale)2166 void MainWindow::back(double scale) {
2167 int f0 = 0;
2168 int nf = 0;
2169 int skip;
2170 int filelength;
2171 bool count_from_end;
2172 bool read_to_end;
2173 bool do_skip;
2174 bool do_filter;
2175 int lastF = -1;
2176
2177 DataVectorList dataVectors = document()->objectStore()->getObjects<DataVector>();
2178 DataMatrixList dataMatrices = document()->objectStore()->getObjects<DataMatrix>();
2179 VScalarList vScalars = document()->objectStore()->getObjects<VScalar>();
2180 DataStringList dataStrings = document()->objectStore()->getObjects<DataString>();
2181
2182 QHash<int,int> lastframehash;
2183
2184 foreach (DataVectorPtr v, dataVectors) {
2185 v->readLock();
2186 f0 = v->startFrame();
2187 nf = v->numFrames();
2188 count_from_end = v->countFromEOF();
2189 read_to_end = v->readToEOF();
2190 filelength = v->fileLength();
2191
2192 skip = v->skip();
2193 do_skip = v->doSkip();
2194 do_filter = v->doAve();
2195 v->unlock();
2196
2197 if (f0 != 0) {
2198 if (count_from_end) {
2199 f0 = filelength - nf;
2200 }
2201 if (read_to_end) {
2202 nf = filelength - f0;
2203 }
2204
2205 f0 -= ceil(scale*nf);
2206 if (f0<0) {
2207 f0 = 0;
2208 }
2209 lastF = f0 + nf - 1;
2210 ++lastframehash[lastF];
2211
2212 v->writeLock();
2213 v->changeFrames(f0, nf, skip, do_skip, do_filter);
2214 v->registerChange();
2215 v->unlock();
2216 }
2217 }
2218
2219 int most_popular_lastF = -1;
2220 int n_most_popular_lastF = -1;
2221 foreach (int key, lastframehash.keys()) {
2222 int n = lastframehash[key] ;
2223 if (n > n_most_popular_lastF) {
2224 n_most_popular_lastF = n;
2225 most_popular_lastF = key;
2226 }
2227 }
2228
2229 foreach (VScalarPtr vs, vScalars) {
2230 int new_frame;
2231 int filelength = vs->fileLength();
2232 if (most_popular_lastF>=0) {
2233 if (most_popular_lastF < filelength) {
2234 new_frame = most_popular_lastF;
2235 } else {
2236 new_frame = filelength-1;
2237 }
2238 } else {
2239 if (vs->F0() < 0) {
2240 new_frame = filelength-1;
2241 } else if (vs->F0()-1 >= 0) {
2242 new_frame = vs->F0()-1;
2243 } else {
2244 new_frame = 0;
2245 }
2246 }
2247 vs->writeLock();
2248 vs->changeFrame(new_frame);
2249 vs->registerChange();
2250 vs->unlock();
2251 }
2252
2253 foreach (DataStringPtr s, dataStrings) {
2254 if (s->isStream()) {
2255 int new_frame;
2256 int filelength = s->fileLength();
2257 if (most_popular_lastF>=0) {
2258 if (most_popular_lastF < filelength) {
2259 new_frame = most_popular_lastF;
2260 } else {
2261 new_frame = filelength-1;
2262 }
2263 } else {
2264 if (s->frame() < 0) {
2265 new_frame = filelength-1;
2266 } else if (s->frame()-1 >= 0) {
2267 new_frame = s->frame()-1;
2268 } else {
2269 new_frame = 0;
2270 }
2271 }
2272 s->writeLock();
2273 s->setFrame(new_frame);
2274 s->registerChange();
2275 s->unlock();
2276 }
2277 }
2278
2279 foreach (DataMatrixPtr m, dataMatrices) {
2280 if (m->isStream()) {
2281 int new_frame;
2282 int filelength = m->fileLength();
2283 if (most_popular_lastF>=0) {
2284 if (most_popular_lastF < filelength) {
2285 new_frame = most_popular_lastF;
2286 } else {
2287 new_frame = filelength-1;
2288 }
2289 } else {
2290 if (m->frame() < 0) {
2291 new_frame = filelength-1;
2292 } else if (m->frame()-1 >= 0) {
2293 new_frame = m->frame()-1;
2294 } else {
2295 new_frame = filelength-2;
2296 }
2297 }
2298 m->writeLock();
2299 m->setFrame(new_frame);
2300 m->registerChange();
2301 m->unlock();
2302 }
2303 }
2304
2305 dialogDefaults().setValue("vector/range", nf);
2306 dialogDefaults().setValue("vector/start", f0);
2307 dialogDefaults().setValue("vector/countFromEnd", false);
2308 dialogDefaults().setValue("vector/readToEnd", false);
2309 UpdateManager::self()->doUpdates(true);
2310 }
2311
reload()2312 void MainWindow::reload() {
2313 document()->objectStore()->rebuildDataSourceList();
2314 UpdateManager::self()->doUpdates(true);
2315 //document()->setChanged(true);
2316 }
2317
showDataManager()2318 void MainWindow::showDataManager() {
2319 if (!_dataManager) {
2320 _dataManager = new DataManager(this, _doc);
2321 }
2322 if (_dataManager->isVisible()) {
2323 _dataManager->raise();
2324 _dataManager->activateWindow();
2325 }
2326 _dataManager->show();
2327 }
2328
2329
updateViewItems(qint64 serial)2330 void Kst::MainWindow::updateViewItems(qint64 serial)
2331 {
2332
2333 QList<PlotItem *> plots = ViewItem::getItems<PlotItem>();
2334
2335 bool changed = false;
2336 foreach (PlotItem *plot, plots) {
2337 changed |= plot->handleChangedInputs(serial);
2338 }
2339
2340 QList<LabelItem*> labels = ViewItem::getItems<LabelItem>();
2341 foreach (LabelItem * label, labels) {
2342 if (label->_labelRc) {
2343 label->inputsChanged(serial);
2344 }
2345 }
2346
2347
2348 if (changed) {
2349 _tabWidget->currentView()->update();
2350 if (_viewVectorDialog) {
2351 _viewVectorDialog->update();
2352 }
2353 kstApp->mainWindow()->updateStatusMessage();
2354 }
2355
2356 QTimer::singleShot(20, UpdateManager::self(), SLOT(viewItemUpdateFinished())); // why 20ms ???
2357 }
2358
showVectorEditor()2359 void MainWindow::showVectorEditor() {
2360 if (!_viewVectorDialog) {
2361 _viewVectorDialog = new ViewVectorDialog(this, _doc);
2362 }
2363 if (_viewVectorDialog->isVisible()) {
2364 _viewVectorDialog->raise();
2365 _viewVectorDialog->activateWindow();
2366 }
2367 _viewVectorDialog->show();
2368 }
2369
2370
showScalarEditor()2371 void MainWindow::showScalarEditor() {
2372 ViewPrimitiveDialog *viewScalarDialog = new ViewScalarDialog(this, _doc);
2373 viewScalarDialog->show();
2374 }
2375
2376
showStringEditor()2377 void MainWindow::showStringEditor() {
2378 ViewPrimitiveDialog *viewStringDialog = new ViewStringDialog(this, _doc);
2379 viewStringDialog->show();
2380 }
2381
showMatrixEditor()2382 void MainWindow::showMatrixEditor() {
2383 ViewMatrixDialog *viewMatrixDialog = new ViewMatrixDialog(this, _doc);
2384 viewMatrixDialog->show();
2385 }
2386
2387
showDebugDialog()2388 void MainWindow::showDebugDialog() {
2389 if (!_debugDialog) {
2390 _debugDialog = new DebugDialog(this);
2391 }
2392 _debugDialog->setObjectStore(document()->objectStore());
2393 if (_debugDialog->isVisible()) {
2394 _debugDialog->raise();
2395 _debugDialog->activateWindow();
2396 }
2397 _debugDialog->show();
2398 }
2399
2400
showExportGraphicsDialog()2401 void MainWindow::showExportGraphicsDialog() {
2402 if (!_exportGraphics) {
2403 _exportGraphics = new ExportGraphicsDialog(this);
2404 connect(_exportGraphics, SIGNAL(exportGraphics(QString,QString,int,int,int,bool,int)),
2405 this, SLOT(exportGraphicsFile(QString,QString,int,int,int,bool,int)));
2406 }
2407 if (_exportGraphics->isVisible()) {
2408 _exportGraphics->raise();
2409 _exportGraphics->activateWindow();
2410 }
2411 _exportGraphics->show();
2412 }
2413
2414
showExportVectorsDialog()2415 void MainWindow::showExportVectorsDialog() {
2416 if (!_exportVectors) {
2417 _exportVectors = new ExportVectorsDialog(this);
2418 }
2419 if (_exportVectors->isVisible()) {
2420 _exportVectors->raise();
2421 _exportVectors->activateWindow();
2422 }
2423 _exportVectors->show();
2424 }
2425
2426
showLogDialog()2427 void MainWindow::showLogDialog() {
2428 if (!_logDialog) {
2429 _logDialog = new LogDialog(this);
2430 //connect(_logDialog, SIGNAL(exportLog(const QString &, time_t, const QString &, int, int, int, const QString &)),
2431 // this, SLOT(exportLog(const QString &, time_t, const QString &, int, int, int, const QString &)));
2432 }
2433 if (_logDialog->isVisible()) {
2434 _logDialog->raise();
2435 _logDialog->activateWindow();
2436 }
2437 _logDialog->show();
2438 }
2439
2440
showSettingsDialog()2441 void MainWindow::showSettingsDialog() {
2442 if (!_applicationSettingsDialog) {
2443 _applicationSettingsDialog = new ApplicationSettingsDialog(this);
2444 }
2445 if (_applicationSettingsDialog->isVisible()) {
2446 _applicationSettingsDialog->raise();
2447 _applicationSettingsDialog->activateWindow();
2448 }
2449 _applicationSettingsDialog->show();
2450 }
2451
2452
showThemeDialog()2453 void MainWindow::showThemeDialog() {
2454 if (!_themeDialog) {
2455 _themeDialog = new ThemeDialog(this);
2456 }
2457 if (_themeDialog->isVisible()) {
2458 _themeDialog->raise();
2459 _themeDialog->activateWindow();
2460 }
2461
2462 _themeDialog->reset();
2463 _themeDialog->show();
2464 }
2465
2466
clearDefaults()2467 void MainWindow::clearDefaults() {
2468
2469 QMessageBox confirmationBox;
2470 confirmationBox.setText(tr("Clear all settings and defaults?"));
2471 confirmationBox.setInformativeText(tr("You are about to clear all settings defaults in all dialogs in kst.\nThis can not be undone."));
2472 confirmationBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
2473 confirmationBox.setDefaultButton(QMessageBox::Ok);
2474 int confirmed = confirmationBox.exec();
2475
2476 switch (confirmed) {
2477 case QMessageBox::Ok:
2478 dialogDefaults().clear();
2479 ApplicationSettings::self()->clear();
2480 DataSourcePluginManager::settingsObject().clear();
2481 break;
2482 case QMessageBox::Cancel:
2483 default:
2484 // cancel: do nothing at all.
2485 break;
2486 }
2487 }
2488
clearDataSourceSettings()2489 void MainWindow::clearDataSourceSettings() {
2490
2491 QMessageBox confirmationBox;
2492 confirmationBox.setText(tr("Clear datasource settings?"));
2493 confirmationBox.setInformativeText(tr("You are about to clear all\nconfiguration settings for\nall datasources/file types."));
2494 confirmationBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
2495 confirmationBox.setDefaultButton(QMessageBox::Ok);
2496 int confirmed = confirmationBox.exec();
2497
2498 switch (confirmed) {
2499 case QMessageBox::Ok:
2500 DataSourcePluginManager::settingsObject().clear();
2501 break;
2502 case QMessageBox::Cancel:
2503 default:
2504 // cancel: do nothing at all.
2505 break;
2506 }
2507
2508 }
2509
2510
showDifferentiateCurvesDialog()2511 void MainWindow::showDifferentiateCurvesDialog() {
2512 if (!_differentiateCurvesDialog) {
2513 _differentiateCurvesDialog = new DifferentiateCurvesDialog(this);
2514 }
2515 if (_differentiateCurvesDialog->isVisible()) {
2516 _differentiateCurvesDialog->raise();
2517 _differentiateCurvesDialog->activateWindow();
2518 }
2519 _differentiateCurvesDialog->show();
2520 }
2521
2522
filterMultipleDialog()2523 void MainWindow::filterMultipleDialog() {
2524 if (!_filterMultipleDialog) {
2525 _filterMultipleDialog = new FilterMultipleDialog(this);
2526 }
2527 if (_filterMultipleDialog->isVisible()) {
2528 _filterMultipleDialog->raise();
2529 _filterMultipleDialog->activateWindow();
2530 }
2531 _filterMultipleDialog->show();
2532 }
2533
2534
2535
showChooseColorDialog()2536 void MainWindow::showChooseColorDialog() {
2537 if (!_chooseColorDialog) {
2538 _chooseColorDialog = new ChooseColorDialog(this);
2539 }
2540 if (_chooseColorDialog->isVisible()) {
2541 _chooseColorDialog->raise();
2542 _chooseColorDialog->activateWindow();
2543 }
2544 _chooseColorDialog->show();
2545 }
2546
2547
showChangeDataSampleDialog()2548 void MainWindow::showChangeDataSampleDialog() {
2549 if (!_changeDataSampleDialog) {
2550 _changeDataSampleDialog = new ChangeDataSampleDialog(this);
2551 }
2552 if (_changeDataSampleDialog->isVisible()) {
2553 _changeDataSampleDialog->raise();
2554 _changeDataSampleDialog->activateWindow();
2555 }
2556 _changeDataSampleDialog->show();
2557 }
2558
2559
showDataWizard()2560 void MainWindow::showDataWizard() {
2561 DataWizard *dataWizard = new DataWizard(this);
2562 connect(dataWizard, SIGNAL(dataSourceLoaded(QString)), this, SLOT(updateRecentDataFiles(QString)));
2563 dataWizard->show();
2564 }
2565
showDataWizard(const QString & dataFile)2566 void MainWindow::showDataWizard(const QString &dataFile) {
2567 DataWizard *dataWizard = new DataWizard(this, dataFile);
2568 dataWizard->show();
2569 }
2570
2571
openRecentDataFile()2572 void MainWindow::openRecentDataFile()
2573 {
2574 QAction *action = qobject_cast<QAction *>(sender());
2575 if (action) {
2576 DataWizard *dataWizard = new DataWizard(this, action->data().toString());
2577 connect(dataWizard, SIGNAL(dataSourceLoaded(QString)), this, SLOT(updateRecentDataFiles(QString)));
2578 dataWizard->show();
2579 }
2580 }
2581
2582
showBugReportWizard()2583 void MainWindow::showBugReportWizard() {
2584 if (!_bugReportWizard) {
2585 _bugReportWizard = new BugReportWizard(this);
2586 }
2587 if (_bugReportWizard->isVisible()) {
2588 _bugReportWizard->raise();
2589 _bugReportWizard->activateWindow();
2590 }
2591 _bugReportWizard->show();
2592 }
2593
showChangeFileDialog()2594 void MainWindow::showChangeFileDialog() {
2595 if (!_changeFileDialog) {
2596 _changeFileDialog = new ChangeFileDialog(this);
2597 }
2598 if (_changeFileDialog->isVisible()) {
2599 _changeFileDialog->raise();
2600 _changeFileDialog->activateWindow();
2601 }
2602 _changeFileDialog->show();
2603 }
2604
showPluginDialog(QString & pluginName)2605 void MainWindow::showPluginDialog(QString &pluginName) {
2606 DialogLauncher::self()->showBasicPluginDialog(pluginName);
2607 }
2608
isTiedTabs()2609 bool MainWindow::isTiedTabs() {
2610 return _tabTiedAct->isChecked();
2611 }
2612
readSettings()2613 void MainWindow::readSettings() {
2614 #if defined(__QNX__) || defined(__ANDROID__)
2615 // There is only one size we want on mobile platforms - full screen!
2616 setWindowState(Qt::WindowFullScreen);
2617 #else
2618 QByteArray geo = _settings.value("geometry").toByteArray();
2619 if (!geo.isEmpty()) {
2620 restoreGeometry(geo);
2621 } else {
2622 setGeometry(50, 50, 800, 600);
2623 }
2624 #endif // defined(__QNX__) || defined(__ANDROID__)
2625
2626 restoreState(_settings.value("toolbarState").toByteArray());
2627 _tabTiedAct->setChecked(_settings.value("tieTabs").toBool());
2628 }
2629
2630
writeSettings()2631 void MainWindow::writeSettings() {
2632 _settings.setValue("geometry", saveGeometry());
2633 _settings.setValue("toolbarState", saveState());
2634 _settings.setValue("tieTabs", _tabTiedAct->isChecked());
2635 }
2636
setWidgetFlags(QWidget * widget)2637 void MainWindow::setWidgetFlags(QWidget* widget)
2638 {
2639 if (widget) {
2640 // Make sure the dialog gets maximize and minimize buttons under Windows
2641 widget->QWidget::setWindowFlags((Qt::WindowFlags) Qt::Dialog | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint
2642 #if QT_VERSION >= 0x040500
2643 | Qt::WindowCloseButtonHint
2644 #endif
2645 );
2646 }
2647 }
2648
dragEnterEvent(QDragEnterEvent * event)2649 void MainWindow::dragEnterEvent(QDragEnterEvent *event)
2650 {
2651 if (event->mimeData()->hasUrls()) {
2652 event->acceptProposedAction();
2653 }
2654 }
2655
2656
dropEvent(QDropEvent * event)2657 void MainWindow::dropEvent(QDropEvent *event)
2658 {
2659 QString path = event->mimeData()->urls().first().toLocalFile();
2660 if (path.endsWith(QString(".kst"))) {
2661 if (!promptSaveDone()) { // There are things to save => cancel
2662 event->ignore();
2663 return;
2664 }
2665 openFile(path);
2666 }
2667 else {
2668 showDataWizard(path); // This is not destructive: it only add data, no need to ask for confirmation
2669 }
2670 event->accept();
2671 }
2672
cleanUpDataSourceList()2673 void MainWindow::cleanUpDataSourceList() {
2674 _doc->objectStore()->cleanUpDataSourceList();
2675 }
2676
2677 #if defined(__QNX__)
eventFilter(QObject * obj,QEvent * event)2678 bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
2679 if (!qApp->activeWindow()) {
2680 activateWindow();
2681 }
2682 if (event->type() == QEvent::KeyPress) {
2683 QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
2684 if (keyEvent->key()==Qt::Key_Menu) { // i.e., bezel swipe gesture...
2685 qnxToggleToolbarVisibility();
2686 }
2687 return false;
2688 } else if (event->type() == QEvent::MouseButtonPress && obj != menuBar()) {
2689 if (_qnxToolbarsVisible) qnxToggleToolbarVisibility();
2690 update();
2691 return false;
2692 } else if (event->type() == QEvent::WindowActivate) {
2693 update();
2694 return false;
2695 } else {
2696 return QObject::eventFilter(obj, event);
2697 }
2698 }
2699
keyPressEvent(QKeyEvent * event)2700 void MainWindow::keyPressEvent(QKeyEvent *event) {
2701 if ((event->type() == QEvent::KeyPress && static_cast<QKeyEvent*>(event)->key() == Qt::Key_Menu)) {
2702 qnxToggleToolbarVisibility();
2703 }
2704 }
2705
qnxToggleToolbarVisibility()2706 void MainWindow::qnxToggleToolbarVisibility() {
2707 if (_qnxLastToolbarEvent.msecsTo(QDateTime::currentDateTime()) < 100) {
2708 return; // HACK
2709 }
2710 _qnxLastToolbarEvent = QDateTime::currentDateTime();
2711 menuBar()->setVisible(!_qnxToolbarsVisible);
2712 statusBar()->setVisible(!_qnxToolbarsVisible);
2713 _fileToolBar->setVisible(!_qnxToolbarsVisible);
2714 _editToolBar->setVisible(!_qnxToolbarsVisible);
2715 _toolsToolBar->setVisible(!_qnxToolbarsVisible);
2716 _rangeToolBar->setVisible(!_qnxToolbarsVisible);
2717 _modeToolBar->setVisible(!_qnxToolbarsVisible);
2718 _plotLayoutToolBar->setVisible(!_qnxToolbarsVisible);
2719 _annotationToolBar->setVisible(!_qnxToolbarsVisible);
2720 _qnxToolbarsVisible = !_qnxToolbarsVisible;
2721 }
2722 #endif
2723
2724 }
2725
2726 // vim: ts=2 sw=2 et
2727