summaryrefslogtreecommitdiff
path: root/src/pmview/pmview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pmview/pmview.cpp')
-rw-r--r--src/pmview/pmview.cpp708
1 files changed, 708 insertions, 0 deletions
diff --git a/src/pmview/pmview.cpp b/src/pmview/pmview.cpp
new file mode 100644
index 0000000..2d4d1ff
--- /dev/null
+++ b/src/pmview/pmview.cpp
@@ -0,0 +1,708 @@
+/*
+ * Copyright (c) 2007-2009, Aconex. All Rights Reserved.
+ * Copyright (c) 2006, Ken McDonell. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#include <QtCore/QUrl>
+#include <QtCore/QTimer>
+#include <QtCore/QLibraryInfo>
+#include <QtGui/QDesktopServices>
+#include <QtGui/QApplication>
+#include <QtGui/QPrintDialog>
+#include <QtGui/QMessageBox>
+#include <QtGui/QWhatsThis>
+
+#include <Inventor/nodes/SoPerspectiveCamera.h>
+#include <Inventor/nodes/SoSeparator.h>
+#include <Inventor/nodes/SoTransform.h>
+#include <Inventor/nodes/SoBaseColor.h>
+#include <Inventor/nodes/SoCube.h>
+
+#include <iostream>
+using namespace std;
+
+#include "barobj.h"
+#include "gridobj.h"
+#include "stackobj.h"
+#include "labelobj.h"
+#include "modlist.h"
+#include "defaultobj.h"
+#include "pcpcolor.h"
+
+#include "main.h"
+#include "pmview.h"
+#include "scenegroup.h"
+#include "qed_console.h"
+#include "qed_statusbar.h"
+#include "qed_timecontrol.h"
+#include "qed_recorddialog.h"
+
+QString theConfigName;
+QString theAltConfigName;
+FILE *theConfigFile;
+FILE *theAltConfig;
+float theGlobalScale = 1.2;
+char **frontend_argv;
+int frontend_argc;
+
+PmView::PmView() : QMainWindow(NULL)
+{
+ my.dialogsSetup = false;
+
+ setIconSize(QSize(22, 22));
+ setupUi(this);
+
+ SoQt::init(widget);
+ my.viewer = new SoQtExaminerViewer(widget);
+
+ my.statusBar = new QedStatusBar;
+ setStatusBar(my.statusBar);
+
+ toolBar->setAllowedAreas(Qt::RightToolBarArea | Qt::TopToolBarArea);
+ connect(toolBar, SIGNAL(orientationChanged(Qt::Orientation)),
+ this, SLOT(updateToolbarOrientation(Qt::Orientation)));
+ updateToolbarLocation();
+ setupEnabledActionsList();
+ if (!globalSettings.initialToolbar)
+ toolBar->hide();
+
+ my.liveHidden = true;
+ my.archiveHidden = true;
+ timeControlAction->setChecked(false);
+ my.menubarHidden = false;
+ my.toolbarHidden = !globalSettings.initialToolbar;
+ toolbarAction->setChecked(globalSettings.initialToolbar);
+ my.consoleHidden = true;
+ if (!pmDebug)
+ consoleAction->setVisible(false);
+ consoleAction->setChecked(false);
+
+ // Build Scene Graph
+ my.root = new SoSeparator;
+ my.root->ref();
+
+ SoPerspectiveCamera *camera = new SoPerspectiveCamera;
+ camera->orientation.setValue(SbVec3f(1, 0, 0), -M_PI/6.0);
+ my.root->addChild(camera);
+
+ my.drawStyle = new SoDrawStyle;
+ my.drawStyle->style.setValue(SoDrawStyle::FILLED);
+ my.root->addChild(my.drawStyle);
+
+#if 0
+ // TODO is this needed?
+ if (outfile)
+ QTimer::singleShot(0, this, SLOT(exportFile()));
+ else
+#endif
+ QTimer::singleShot(PmView::defaultTimeout(), this, SLOT(timeout()));
+
+}
+
+void PmView::languageChange()
+{
+ retranslateUi(this);
+}
+
+void PmView::init(void)
+{
+ my.statusBar->init();
+}
+
+void
+PmView::selectionCB(ModList *, bool redraw)
+{
+ RenderOptions options = PmView::metricLabel;
+
+ if (redraw)
+ options = (RenderOptions)(options | PmView::inventor);
+ pmview->render(options, 0);
+}
+
+bool PmView::view(bool showAxis,
+ float xAxis, float yAxis, float zAxis, float angle, float scale)
+{
+ if (theModList->size() == 0) {
+ warningMsg(_POS_, "No modulated objects in scene");
+ }
+
+ // Setup remainder of the scene graph
+ my.root->addChild(theModList->root());
+
+ viewer()->setSceneGraph(my.root);
+ viewer()->setAutoRedraw(true);
+ viewer()->setTitle(pmProgname);
+ if (showAxis)
+ viewer()->setFeedbackVisibility(true);
+
+ SbBool smooth = TRUE;
+ int passes = 1;
+ char *sval = NULL;
+
+#if 0 // TODO: QSettings API
+ sval = VkGetResource("antiAliasSmooth", XmRString);
+ if (sval && strcmp(sval, "default") != 0 && strcasecmp(sval, "false") == 0)
+ smooth = FALSE;
+ sval = VkGetResource("antiAliasPasses", XmRString);
+ if (sval != NULL && strcmp(sval, "default"))
+ passes = atoi(sval);
+#endif
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ cerr << "PmView::view: antialiasing set to smooth = "
+ << (smooth == TRUE ? "true" : "false")
+ << ", passes = " << passes << endl;
+#endif
+
+ if (passes > 1)
+ viewer()->setAntialiasing(smooth, atoi(sval));
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ cerr << "PmView::view: displaying window" << endl;
+#endif
+
+ viewer()->viewAll();
+
+ if (angle != 0.0 || scale != 0.0) {
+ SoTransform *tran = new SoTransform();
+ if (angle != 0.0)
+ tran->rotation.setValue(SbVec3f(xAxis, yAxis, zAxis), angle);
+ if (scale != 0.0)
+ tran->scaleFactor.setValue(scale, scale, scale);
+ theModList->root()->insertChild(tran, 0);
+ }
+
+ PmView::render((RenderOptions)(PmView::inventor | PmView::metricLabel), 0);
+ viewer()->saveHomePosition();
+
+ return true;
+}
+
+void PmView::render(RenderOptions options, time_t theTime)
+{
+ viewer()->setAutoRedraw(false);
+
+ if (options & PmView::metrics)
+ theModList->refresh(true);
+
+ if (options & PmView::inventor)
+ viewer()->render();
+
+ if (options & PmView::metricLabel) {
+ theModList->infoText(my.text);
+ if (my.text != my.prevText) {
+ my.prevText = my.text;
+ if (my.text.length() == 0)
+ // TODO: clear label string
+ ;
+ else {
+ // TODO: set label string to my.text
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ cerr << "PmView::render: metricLabel text \"" <<
+ my.text() << "\"" << endl;
+#endif
+ }
+ }
+ }
+
+ if (options & PmView::timeLabel)
+ setDateLabel(theTime, QString::null); // TODO
+
+ viewer()->setAutoRedraw(true);
+}
+
+QMenu *PmView::createPopupMenu(void)
+{
+ QMenu *menu = QMainWindow::createPopupMenu();
+ menu->addAction(menubarAction);
+ return menu;
+}
+
+void PmView::quit()
+{
+ // End any processes we may have started and close any open dialogs
+ if (pmtime)
+ pmtime->quit();
+}
+
+void PmView::closeEvent(QCloseEvent *)
+{
+ quit();
+}
+
+void PmView::enableUi(void)
+{
+#if 0
+ recordStartAction->setEnabled(haveGadgets && haveLiveHosts && !haveLoggers);
+ recordQueryAction->setEnabled(haveLoggers);
+ recordStopAction->setEnabled(haveLoggers);
+ recordDetachAction->setEnabled(haveLoggers);
+#endif
+}
+
+void PmView::updateToolbarLocation()
+{
+#if QT_VERSION >= 0x040300
+ setUnifiedTitleAndToolBarOnMac(globalSettings.nativeToolbar);
+#endif
+ if (globalSettings.toolbarLocation)
+ addToolBar(Qt::RightToolBarArea, toolBar);
+ else
+ addToolBar(Qt::TopToolBarArea, toolBar);
+}
+
+void PmView::updateToolbarOrientation(Qt::Orientation orientation)
+{
+ (void)orientation;
+ // TODO
+}
+
+void PmView::setButtonState(QedTimeButton::State state)
+{
+ my.statusBar->timeButton()->setButtonState(state);
+}
+
+void PmView::step(bool live, QmcTime::Packet *packet)
+{
+ if (live)
+ liveGroup->step(packet);
+ else
+ archiveGroup->step(packet);
+}
+
+void PmView::VCRMode(bool live, QmcTime::Packet *packet, bool drag)
+{
+ if (live)
+ liveGroup->VCRMode(packet, drag);
+ else
+ archiveGroup->VCRMode(packet, drag);
+}
+
+void PmView::timeZone(bool live, QmcTime::Packet *packet, char *tzdata)
+{
+ if (live)
+ liveGroup->setTimezone(packet, tzdata);
+ else
+ archiveGroup->setTimezone(packet, tzdata);
+}
+
+void PmView::filePrint()
+{
+ QMessageBox::information(this, pmProgname, "Print, print, print... whirrr");
+}
+
+void PmView::fileQuit()
+{
+ QApplication::exit(0);
+}
+
+void PmView::helpManual()
+{
+ bool ok;
+ QString documents("file://");
+ QString separator = QString(__pmPathSeparator());
+ documents.append(pmGetConfig("PCP_HTML_DIR"));
+ documents.append(separator).append("index.html");
+ ok = QDesktopServices::openUrl(QUrl(documents, QUrl::TolerantMode));
+ if (!ok) {
+ documents.prepend("Failed to open:\n");
+ QMessageBox::warning(this, pmProgname, documents);
+ }
+}
+
+void PmView::helpTutorial()
+{
+ bool ok;
+ QString documents("file://");
+ QString separator = QString(__pmPathSeparator());
+ documents.append(pmGetConfig("PCP_HTML_DIR"));
+ documents.append(separator).append("tutorial.html");
+ ok = QDesktopServices::openUrl(QUrl(documents, QUrl::TolerantMode));
+ if (!ok) {
+ documents.prepend("Failed to open:\n");
+ QMessageBox::warning(this, pmProgname, documents);
+ }
+}
+
+void PmView::helpAbout()
+{
+#if 0
+ AboutDialog about(this);
+ about.exec();
+#endif
+}
+
+void PmView::helpSeeAlso()
+{
+#if 0
+ SeeAlsoDialog seealso(this);
+ seealso.exec();
+#endif
+}
+
+void PmView::whatsThis()
+{
+ QWhatsThis::enterWhatsThisMode();
+}
+
+void PmView::optionsTimeControl()
+{
+ if (activeView()->isArchiveSource()) {
+ if (my.archiveHidden)
+ pmtime->showArchiveTimeControl();
+ else
+ pmtime->hideArchiveTimeControl();
+ my.archiveHidden = !my.archiveHidden;
+ timeControlAction->setChecked(!my.archiveHidden);
+ }
+ else {
+ if (my.liveHidden)
+ pmtime->showLiveTimeControl();
+ else
+ pmtime->hideLiveTimeControl();
+ my.liveHidden = !my.liveHidden;
+ timeControlAction->setChecked(!my.liveHidden);
+ }
+}
+
+void PmView::optionsToolbar()
+{
+ if (my.toolbarHidden)
+ toolBar->show();
+ else
+ toolBar->hide();
+ my.toolbarHidden = !my.toolbarHidden;
+}
+
+void PmView::optionsMenubar()
+{
+ if (my.menubarHidden)
+ MenuBar->show();
+ else
+ MenuBar->hide();
+ my.menubarHidden = !my.menubarHidden;
+}
+
+void PmView::optionsConsole()
+{
+#if 0
+ if (pmDebug) {
+ if (my.consoleHidden)
+ console->show();
+ else
+ console->hide();
+ my.consoleHidden = !my.consoleHidden;
+ }
+#endif
+}
+
+void PmView::optionsNewPmchart()
+{
+ QProcess *buddy = new QProcess(this);
+ QStringList arguments;
+ QString port;
+
+ port.setNum(pmtime->port());
+ arguments << "-p" << port;
+ for (unsigned int i = 0; i < archiveGroup->numContexts(); i++) {
+ QmcSource source = archiveGroup->context(i)->source();
+ arguments << "-a" << source.source();
+ }
+ for (unsigned int i = 0; i < liveGroup->numContexts(); i++) {
+ QmcSource source = liveGroup->context(i)->source();
+ arguments << "-h" << source.source();
+ }
+ if (Lflag)
+ arguments << "-L";
+ buddy->start("pmview", arguments);
+}
+
+bool PmView::isViewRecording()
+{
+ return activeView()->isRecording();
+}
+
+bool PmView::isArchiveView()
+{
+ return activeView()->isArchiveSource();
+}
+
+void PmView::setDateLabel(time_t seconds, QString tz)
+{
+ char datestring[32];
+ QString label;
+
+ if (seconds) {
+ pmCtime(&seconds, datestring);
+ label = tr(datestring);
+ label.remove(10, 9);
+ label.replace(15, 1, " ");
+ label.append(tz);
+ }
+ else {
+ label = tr("");
+ }
+ my.statusBar->setDateText(label);
+}
+
+void PmView::setDateLabel(QString label)
+{
+ my.statusBar->setDateText(label);
+}
+
+void PmView::setRecordState(bool record)
+{
+ liveGroup->newButtonState(liveGroup->pmtimeState(),
+ QmcTime::NormalMode, record);
+ setButtonState(liveGroup->buttonState());
+ enableUi();
+}
+
+void PmView::recordStart()
+{
+ if (activeView()->startRecording())
+ setRecordState(true);
+}
+
+void PmView::recordStop()
+{
+ activeView()->stopRecording();
+}
+
+void PmView::recordQuery()
+{
+ activeView()->queryRecording();
+}
+
+void PmView::recordDetach()
+{
+ activeView()->detachLoggers();
+}
+
+QList<QAction*> PmView::toolbarActionsList()
+{
+ return my.toolbarActionsList;
+}
+
+QList<QAction*> PmView::enabledActionsList()
+{
+ return my.enabledActionsList;
+}
+
+void PmView::setupEnabledActionsList()
+{
+ // ToolbarActionsList is a list of all Actions available.
+ // The SeparatorsList contains Actions that are group "breaks", and
+ // which must be followed by a separator (if they are not the final
+ // action in the toolbar, of course).
+ // Finally the enabledActionsList lists the default enabled Actions.
+
+ my.toolbarActionsList << filePrintAction;
+ addSeparatorAction(); // end exported formats
+ my.toolbarActionsList << recordStartAction << recordStopAction;
+ addSeparatorAction(); // end recording group
+ //my.toolbarActionsList << editSettingsAction;
+ //addSeparatorAction(); // end settings group
+ my.toolbarActionsList << timeControlAction;
+ addSeparatorAction(); // end other processes
+ my.toolbarActionsList << helpManualAction << helpWhatsThisAction;
+
+ // needs to match pmview.ui
+ my.enabledActionsList << filePrintAction;
+
+ if (globalSettings.toolbarActions.size() > 0) {
+ setEnabledActionsList(globalSettings.toolbarActions, false);
+ updateToolbarContents();
+ }
+}
+
+void PmView::addSeparatorAction()
+{
+ int index = my.toolbarActionsList.size() - 1;
+ my.separatorsList << my.toolbarActionsList.at(index);
+}
+
+void PmView::updateToolbarContents()
+{
+ bool needSeparator = false;
+
+ toolBar->clear();
+ for (int i = 0; i < my.toolbarActionsList.size(); i++) {
+ QAction *action = my.toolbarActionsList.at(i);
+ if (my.enabledActionsList.contains(action)) {
+ toolBar->addAction(action);
+ if (needSeparator) {
+ toolBar->insertSeparator(action);
+ needSeparator = false;
+ }
+ }
+ if (my.separatorsList.contains(action))
+ needSeparator = true;
+ }
+}
+
+void PmView::setEnabledActionsList(QStringList tools, bool redisplay)
+{
+ my.enabledActionsList.clear();
+ for (int i = 0; i < my.toolbarActionsList.size(); i++) {
+ QAction *action = my.toolbarActionsList.at(i);
+ if (tools.contains(action->iconText()))
+ my.enabledActionsList.append(action);
+ }
+
+ if (redisplay) {
+ my.toolbarHidden = (my.enabledActionsList.size() == 0);
+ toolbarAction->setChecked(my.toolbarHidden);
+ if (my.toolbarHidden)
+ toolBar->hide();
+ else
+ toolBar->show();
+ }
+}
+
+void View::init(SceneGroup *group, QMenu *menu, QString title)
+{
+ my.group = group;
+ QedViewControl::init(group, menu, title, globalSettings.loggerDelta);
+}
+
+QStringList View::hostList(bool)
+{
+ // TODO
+ return QStringList();
+}
+
+QString View::pmloggerSyntax(bool)
+{
+// TODO
+#if 0
+ View *view = pmview->activeView();
+ QString configdata;
+
+ if (selectedOnly)
+ configdata.append(pmview->activeGadget()->pmloggerSyntax());
+ else
+ for (int c = 0; c < view->gadgetCount(); c++)
+ configdata.append(gadget(c)->pmloggerSyntax());
+ return configdata;
+#else
+ return NULL;
+#endif
+}
+
+bool View::saveConfig(QString filename, bool hostDynamic,
+ bool sizeDynamic, bool allViews, bool allCharts)
+{
+// TODO
+#if 0
+ return SaveViewDialog::saveView(filename,
+ hostDynamic, sizeDynamic, allViews, allCharts);
+#else
+ return false;
+#endif
+}
+
+bool View::stopRecording()
+{
+// TODO
+#if 0
+ QString errmsg;
+ bool error = ViewControl::stopRecording(errmsg);
+ QStringList archiveList = ViewControl::archiveList();
+
+ for (int i = 0; i < archiveList.size(); i++) {
+ QString archive = archiveList.at(i);
+ int sts;
+
+ console->post("View::stopRecording opening archive %s",
+ (const char *)archive.toAscii());
+ if ((sts = archiveGroup->use(PM_CONTEXT_ARCHIVE, archive)) < 0) {
+ errmsg.append(QApplication::tr("Cannot open PCP archive: "));
+ errmsg.append(archive);
+ errmsg.append("\n");
+ errmsg.append(pmErrStr(sts));
+ errmsg.append("\n");
+ error = true;
+ }
+ else {
+ archiveGroup->updateBounds();
+ QmcSource source = archiveGroup->context()->source();
+ pmtime->addArchive(source.start(), source.end(),
+ source.timezone(), source.host(), true);
+ }
+ }
+
+ // If all is well, we can now create the new "Record" View.
+ // Order of cleanup and changing Record mode state is different
+ // in the error case to non-error case, this is important for
+ // getting the window state correct (i.e. pmview->enableUi()).
+
+ if (error) {
+ cleanupRecording();
+ pmview->setRecordState(false);
+ QMessageBox::warning(NULL, pmProgname, errmsg,
+ QMessageBox::Ok|QMessageBox::Default|QMessageBox::Escape,
+ QMessageBox::NoButton, QMessageBox::NoButton);
+ }
+ else {
+ // Make the current View stop recording before changing Views
+ pmview->setRecordState(false);
+
+ View *view = new View;
+ console->post("View::stopRecording creating view: delta=%.2f pos=%.2f",
+ App::timevalToSeconds(*pmtime->archiveInterval()),
+ App::timevalToSeconds(*pmtime->archivePosition()));
+ // TODO: may need to update archive samples/visible?
+ view->init(archiveGroup, pmview->viewMenu(), "Record");
+ pmview->addActiveView(view);
+ OpenViewDialog::openView((const char *)ViewControl::view().toAscii());
+ cleanupRecording();
+ }
+ return error;
+#else
+ return false;
+#endif
+}
+
+bool View::queryRecording(void)
+{
+ QString errmsg;
+ bool error = QedViewControl::queryRecording(errmsg);
+
+ if (error) {
+ pmview->setRecordState(false);
+ QMessageBox::warning(NULL, pmProgname, errmsg,
+ QMessageBox::Ok|QMessageBox::Default|QMessageBox::Escape,
+ QMessageBox::NoButton, QMessageBox::NoButton);
+ }
+ return error;
+}
+
+bool View::detachLoggers(void)
+{
+ QString errmsg;
+ bool error = QedViewControl::detachLoggers(errmsg);
+
+ if (error) {
+ pmview->setRecordState(false);
+ QMessageBox::warning(NULL, pmProgname, errmsg,
+ QMessageBox::Ok|QMessageBox::Default|QMessageBox::Escape,
+ QMessageBox::NoButton, QMessageBox::NoButton);
+ }
+ else {
+ pmview->setRecordState(false);
+ cleanupRecording();
+ }
+ return error;
+}