diff options
Diffstat (limited to 'src/pmchart/tab.cpp')
-rw-r--r-- | src/pmchart/tab.cpp | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/src/pmchart/tab.cpp b/src/pmchart/tab.cpp new file mode 100644 index 0000000..3d5ef2c --- /dev/null +++ b/src/pmchart/tab.cpp @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2007-2008, 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 "main.h" +#include <QtGui/QMessageBox> +#include "openviewdialog.h" +#include "recorddialog.h" + +Tab::Tab(): QWidget(NULL) +{ + my.currentGadget = -1; + my.recording = false; + my.splitter = NULL; + my.group = NULL; +} + +void Tab::init(QTabWidget *tab, GroupControl *group, QString label) +{ + my.splitter = new QSplitter(tab); + my.splitter->setOrientation(Qt::Vertical); + my.splitter->setSizePolicy(QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding); + tab->blockSignals(true); + tab->addTab(my.splitter, label); + tab->blockSignals(false); + my.group = group; +} + +void Tab::addGadget(Gadget *gadget) +{ + if (gadgetCount()) + pmchart->updateHeight(PmChart::minimumChartHeight()); + my.gadgetsList.append(gadget); + if (my.currentGadget == -1) + setCurrentGadget(gadgetCount() - 1); + gadget->showWidget(); + console->post("Tab::addChart: [%d]->Chart %p", my.currentGadget, gadget); +} + +int Tab::deleteCurrent(void) +{ + return deleteGadget(my.currentGadget); +} + +int Tab::deleteGadget(Gadget *gadget) +{ + for (int i = 0; i < gadgetCount(); i++) + if (my.gadgetsList.at(i) == gadget) + return deleteGadget(i); + return 0; +} + +int Tab::deleteGadget(int index) +{ + Gadget *gadget = my.gadgetsList.at(index); + int newCurrent = my.currentGadget; + int oldCurrent = my.currentGadget; + int oldCount = gadgetCount(); + int height = gadget->height(); + + if (index < oldCurrent || index == oldCount - 1) + newCurrent--; + if (newCurrent < 0) + my.currentGadget = -1; + else + setCurrent(my.gadgetsList.at(newCurrent)); + + my.group->deleteGadget(gadget); + my.gadgetsList.removeAt(index); + delete gadget; + + if (gadgetCount() > 0) + pmchart->updateHeight(-height); + + return my.currentGadget; +} + +int Tab::gadgetCount(void) +{ + return my.gadgetsList.size(); +} + +int Tab::currentGadgetIndex(void) +{ + return my.currentGadget; +} + +Gadget *Tab::gadget(int index) +{ + if (index >= gadgetCount()) + return NULL; + return my.gadgetsList.at(index); +} + +Gadget *Tab::currentGadget(void) +{ + if (my.currentGadget == -1) + return NULL; + return my.gadgetsList.at(my.currentGadget); +} + +void Tab::setCurrent(Gadget *gadget) +{ + int index; + + for (index = 0; index < gadgetCount(); index++) + if (my.gadgetsList.at(index) == gadget) + break; + if (index == gadgetCount()) + abort(); // bad, bad, bad - attempted setCurrent on invalid gadget + setCurrentGadget(index); +} + +void Tab::setCurrentGadget(int index) +{ + if (index >= gadgetCount() || index == my.currentGadget) + return; + if (my.currentGadget >= 0) + my.gadgetsList.at(my.currentGadget)->setCurrent(false); + my.currentGadget = index; + if (my.currentGadget >= 0) + my.gadgetsList.at(my.currentGadget)->setCurrent(true); +} + +void Tab::showGadgets() +{ + for (int index = 0; index < gadgetCount() - 1; index++) + my.gadgetsList.at(index)->showWidget(); +} + +bool Tab::isArchiveSource(void) +{ + return my.group->isArchiveSource(); +} + +bool Tab::isRecording(void) +{ + return my.recording; +} + +void Tab::addFolio(QString folio, QString view) +{ + my.view = view; + my.folio = folio; +} + +void Tab::addLogger(PmLogger *pmlogger, QString archive) +{ + my.loggerList.append(pmlogger); + my.archiveList.append(archive); +} + +bool Tab::startRecording(void) +{ + RecordDialog record(this); + + console->post("Tab::startRecording"); + record.init(this); + if (record.exec() != QDialog::Accepted) + my.recording = false; + else { // write pmlogger/pmchart/pmafm configs and start up loggers. + console->post("Tab::startRecording starting loggers"); + record.startLoggers(); + my.recording = true; + } + return my.recording; +} + +void Tab::stopRecording(void) +{ + QString msg = "Q\n", errmsg; + int count = my.loggerList.size(); + int i, sts, error = 0; + + console->post("Tab::stopRecording stopping %d logger(s)", count); + for (int i = 0; i < count; i++) { + if (my.loggerList.at(i)->state() == QProcess::NotRunning) { + errmsg.append(tr("Record process (pmlogger) failed for host: ")); + errmsg.append(my.loggerList.at(i)->host()); + errmsg.append("\n"); + error++; + } + else { + my.loggerList.at(i)->write(msg.toAscii()); + my.loggerList.at(i)->terminate(); + } + } + + for (i = 0; i < my.archiveList.size(); i++) { + QString archive = my.archiveList.at(i); + + console->post("Tab::stopRecording opening archive %s", + (const char *)archive.toAscii()); + if ((sts = archiveGroup->use(PM_CONTEXT_ARCHIVE, archive)) < 0) { + errmsg.append(tr("Cannot open PCP archive: ")); + errmsg.append(archive); + errmsg.append("\n"); + errmsg.append(tr(pmErrStr(sts))); + errmsg.append("\n"); + error++; + } + 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" Tab. + // 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. pmchart->enableUi()). + + if (error) { + cleanupRecording(); + pmchart->setRecordState(false); + QMessageBox::warning(this, pmProgname, errmsg, + QMessageBox::Ok|QMessageBox::Default|QMessageBox::Escape, + QMessageBox::NoButton, QMessageBox::NoButton); + } + else { + // Make the current Tab stop recording before changing Tabs + pmchart->setRecordState(false); + + Tab *tab = new Tab; + console->post("Tab::stopRecording creating tab: delta=%.2f pos=%.2f", + tosec(*pmtime->archiveInterval()), + tosec(*pmtime->archivePosition())); + // TODO: may need to update archive samples/visible? + tab->init(pmchart->tabWidget(), archiveGroup, "Record"); + pmchart->addActiveTab(tab); + OpenViewDialog::openView((const char *)my.view.toAscii()); + cleanupRecording(); + } +} + +void Tab::cleanupRecording(void) +{ + my.recording = false; + my.loggerList.clear(); + my.archiveList.clear(); + my.view = QString::null; + my.folio = QString::null; +} + +void Tab::queryRecording(void) +{ + QString msg = "?\n", errmsg; + int i, error = 0, count = my.loggerList.size(); + + console->post("Tab::stopRecording querying %d logger(s)", count); + for (i = 0; i < count; i++) { + if (my.loggerList.at(i)->state() == QProcess::NotRunning) { + errmsg.append(tr("Record process (pmlogger) failed for host: ")); + errmsg.append(my.loggerList.at(i)->host()); + errmsg.append("\n"); + error++; + } + else { + my.loggerList.at(i)->write(msg.toAscii()); + } + } + + if (error) { + msg = "Q\n"; // if one fails, we shut down all loggers + for (i = 0; i < count; i++) + my.loggerList.at(i)->write(msg.toAscii()); + cleanupRecording(); + pmchart->setRecordState(false); + QMessageBox::warning(this, pmProgname, errmsg, + QMessageBox::Ok|QMessageBox::Default|QMessageBox::Escape, + QMessageBox::NoButton, QMessageBox::NoButton); + } +} + +void Tab::detachLoggers(void) +{ + QString msg = "D\n", errmsg; + int error = 0, count = my.loggerList.size(); + + console->post("Tab::detachLoggers detaching %d logger(s)", count); + for (int i = 0; i < count; i++) { + if (my.loggerList.at(i)->state() == QProcess::NotRunning) { + errmsg.append(tr("Record process (pmlogger) failed for host: ")); + errmsg.append(my.loggerList.at(i)->host()); + errmsg.append("\n"); + error++; + } + else { + my.loggerList.at(i)->write(msg.toAscii()); + } + } + + if (error) { + cleanupRecording(); + pmchart->setRecordState(false); + QMessageBox::warning(this, pmProgname, errmsg, + QMessageBox::Ok|QMessageBox::Default|QMessageBox::Escape, + QMessageBox::NoButton, QMessageBox::NoButton); + } + else { + pmchart->setRecordState(false); + cleanupRecording(); + } +} |