diff options
Diffstat (limited to 'src/pmchart/recorddialog.cpp')
-rw-r--r-- | src/pmchart/recorddialog.cpp | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/src/pmchart/recorddialog.cpp b/src/pmchart/recorddialog.cpp new file mode 100644 index 0000000..08415e3 --- /dev/null +++ b/src/pmchart/recorddialog.cpp @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2007-2009, Aconex. 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 "recorddialog.h" +#include <QtCore/QTextStream> +#include <QtGui/QMessageBox> +#include <QtGui/QDoubleValidator> +#include "main.h" +#include "tab.h" +#include "saveviewdialog.h" + +RecordDialog::RecordDialog(QWidget* parent) : QDialog(parent) +{ + setupUi(this); + deltaLineEdit->setValidator( + new QDoubleValidator(0.001, INT_MAX, 3, deltaLineEdit)); +} + +void RecordDialog::languageChange() +{ + retranslateUi(this); +} + +void RecordDialog::init(Tab *tab) +{ + QChar sep(__pmPathSeparator()); + QString pmlogger = QDir::toNativeSeparators(QDir::homePath()); + QString view, folio, archive; + + pmlogger.append(sep); + pmlogger.append(".pcp"); + pmlogger.append(sep); + pmlogger.append("pmlogger"); + pmlogger.append(sep); + view = folio = archive = pmlogger; + + view.append("[date].view"); + viewLineEdit->setText(view); + folio.append("[date].folio"); + folioLineEdit->setText(folio); + archive.append("[host]"); + archive.append(sep); + archive.append("[date]"); + archiveLineEdit->setText(archive); + + my.tab = tab; + my.units = QmcTime::Seconds; + deltaLineEdit->setText( + QmcTime::deltaString(globalSettings.loggerDelta, my.units)); + + selectedRadioButton->setChecked(false); + allGadgetsRadioButton->setChecked(true); +} + +void RecordDialog::selectedRadioButton_clicked() +{ + selectedRadioButton->setChecked(true); + allGadgetsRadioButton->setChecked(false); +} + +void RecordDialog::allGadgetsRadioButton_clicked() +{ + selectedRadioButton->setChecked(false); + allGadgetsRadioButton->setChecked(true); +} + +void RecordDialog::deltaUnitsComboBox_activated(int value) +{ + double delta = tosec(*(pmtime->liveInterval())); + my.units = (QmcTime::DeltaUnits)value; + deltaLineEdit->setText(QmcTime::deltaString(delta, my.units)); +} + +void RecordDialog::viewPushButton_clicked() +{ + RecordFileDialog view(this); + + QChar sep(__pmPathSeparator()); + QString pmlogger = QDir::toNativeSeparators(QDir::homePath()); + pmlogger.append(sep); + pmlogger.append(".pcp"); + pmlogger.append(sep); + pmlogger.append("pmlogger"); + pmlogger.append(sep); + + view.setDirectory(pmlogger); + if (view.exec() == QDialog::Accepted) + viewLineEdit->setText(view.selectedFiles().at(0)); +} + +void RecordDialog::folioPushButton_clicked() +{ + RecordFileDialog folio(this); + + QChar sep(__pmPathSeparator()); + QString pmlogger = QDir::toNativeSeparators(QDir::homePath()); + pmlogger.append(sep); + pmlogger.append(".pcp"); + pmlogger.append(sep); + pmlogger.append("pmlogger"); + pmlogger.append(sep); + + folio.setDirectory(pmlogger); + if (folio.exec() == QDialog::Accepted) + folioLineEdit->setText(folio.selectedFiles().at(0)); +} + +void RecordDialog::archivePushButton_clicked() +{ + RecordFileDialog archive(this); + + QChar sep(__pmPathSeparator()); + QString pmlogger = QDir::toNativeSeparators(QDir::homePath()); + pmlogger.append(sep); + pmlogger.append(".pcp"); + pmlogger.append(sep); + pmlogger.append("pmlogger"); + pmlogger.append(sep); + + archive.setDirectory(pmlogger); + if (archive.exec() == QDialog::Accepted) + archiveLineEdit->setText(archive.selectedFiles().at(0)); +} + +bool RecordDialog::saveFolio(QString folioname, QString viewname) +{ + QFile folio(folioname); + + if (!folio.open(QIODevice::WriteOnly)) { + QString msg = tr("Cannot open file: "); + msg.append(folioname); + msg.append("\n"); + msg.append(folio.errorString()); + QMessageBox::warning(this, pmProgname, msg); + return false; + } + + QTextStream stream(&folio); + QString datetime; + + datetime = QDateTime::currentDateTime().toString("ddd MMM d hh:mm:ss yyyy"); + stream << "PCPFolio\n"; + stream << "Version: 1\n"; + stream << "# use pmafm(1) to process this PCP archive folio\n" << "#\n"; + stream << "Created: on " << QmcSource::localHost; + stream << " at " << datetime << "\n"; + stream << "Creator: pmchart " << viewname << "\n"; + stream << "#\t\tHost\t\tBasename\n"; + + for (int i = 0; i < my.hosts.size(); i++) { + QString host = my.hosts.at(i); + QString archive = my.archives.at(i); + QFileInfo logFile(archive); + QDir logDir = logFile.dir(); + logDir.mkpath(logDir.absolutePath()); + stream << "Archive:\t" << my.hosts.at(i) << "\t\t" << archive << "\n"; + } + return true; +} + +bool RecordDialog::saveConfig(QString configfile, QString configdata) +{ + QFile config(configfile); + + if (!config.open(QIODevice::WriteOnly)) { + QString msg = tr("Cannot open file: "); + msg.append(configfile); + msg.append("\n"); + msg.append(config.errorString()); + QMessageBox::warning(this, pmProgname, msg); + return false; + } + + QTextStream stream(&config); + stream << configdata; + return true; +} + +PmLogger::PmLogger(QObject *parent) : QProcess(parent) +{ + connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), + this, SLOT(finished(int, QProcess::ExitStatus))); +} + +void PmLogger::init(Tab *tab, QString host, QString logfile) +{ + my.tab = tab; + my.host = host; + my.logfile = logfile; + my.terminating = false; +} + +void PmLogger::terminate() +{ + my.terminating = true; +} + +void PmLogger::finished(int, QProcess::ExitStatus) +{ + if (my.terminating == false) { + my.terminating = true; + my.tab->stopRecording(); + + QString msg = "Recording process (pmlogger) exited unexpectedly\n"; + msg.append("for host "); + msg.append(my.host); + msg.append(".\n\n"); + msg.append("Additional diagnostics may be available in the log:\n"); + msg.append(my.logfile); + QMessageBox::warning(pmchart, pmProgname, msg); + } +} + +void RecordDialog::buttonOk_clicked() +{ + if (deltaLineEdit->isModified()) { + // convert to seconds, make sure its still in range 0.001-INT_MAX + double input = QmcTime::deltaValue(deltaLineEdit->text(), my.units); + if (input < 0.001 || input > INT_MAX) { + QString msg = tr("Record Sampling Interval is invalid.\n"); + msg.append(deltaLineEdit->text()); + msg.append(" is out of range (0.001 to 0x7fffffff seconds)\n"); + QMessageBox::warning(this, pmProgname, msg); + return; + } + } + + QString today = QDateTime::currentDateTime().toString("yyyyMMdd.hh.mm.ss"); + + QString view = viewLineEdit->text().trimmed(); + view.replace(QRegExp("^~"), QDir::toNativeSeparators(QDir::homePath())); + view.replace(QRegExp("\\[date\\]"), today); + view.replace(QRegExp("\\[host\\]"), QmcSource::localHost); + QFileInfo viewFile(view); + QDir viewDir = viewFile.dir(); + if (viewDir.mkpath(viewDir.absolutePath()) == false) { + QString msg = tr("Failed to create path for view:\n"); + msg.append(view); + msg.append("\n"); + QMessageBox::warning(this, pmProgname, msg); + return; + } + + QString folio = folioLineEdit->text().trimmed(); + folio.replace(QRegExp("^~"), QDir::toNativeSeparators(QDir::homePath())); + folio.replace(QRegExp("\\[date\\]"), today); + folio.replace(QRegExp("\\[host\\]"), QmcSource::localHost); + QFileInfo folioFile(folio); + QDir folioDir = folioFile.dir(); + if (folioDir.mkpath(folioDir.absolutePath()) == false) { + QString msg = tr("Failed to create path for folio:\n"); + msg.append(folio); + msg.append("\n"); + QMessageBox::warning(this, pmProgname, msg); + return; + } + + console->post("RecordDialog verifying paths view=%s folio=%s", + (const char *)folio.toAscii(), (const char *)view.toAscii()); + + my.view = view; + my.folio = folio; + my.delta.setNum(QmcTime::deltaValue(deltaLineEdit->text(), my.units), 'f'); + + Tab *tab = pmchart->activeTab(); + for (int c = 0; c < tab->gadgetCount(); c++) { + Gadget *gadget = tab->gadget(c); + if (selectedRadioButton->isChecked() && gadget != tab->currentGadget()) + continue; + QStringList ghosts = gadget->hosts(); + for (int i = 0; i < ghosts.count(); i++) { + if (!my.hosts.contains(ghosts.at(i))) + my.hosts.append(ghosts.at(i)); + } + } + + for (int h = 0; h < my.hosts.count(); h++) { + QString archive = archiveLineEdit->text().trimmed(); + QString rehomer = QDir::toNativeSeparators(QDir::homePath()); + archive.replace(QRegExp("^~"), rehomer); + archive.replace(QRegExp("\\[host\\]"), my.hosts.at(h)); + archive.replace(QRegExp("\\[date\\]"), today); + my.archives.append(archive); + } + + if (SaveViewDialog::saveView(view, false, false, false, true) == false) + return; + if (saveFolio(folio, view) == false) + return; + QDialog::accept(); +} + +// +// write pmlogger, pmchart and pmafm configs, then start pmloggers. +// +void RecordDialog::startLoggers() +{ + QString pmlogger = pmGetConfig("PCP_BINADM_DIR"); + QChar sep(__pmPathSeparator()); + pmlogger.append(sep); + pmlogger.append("pmlogger"); + + QString regex = "^"; + regex.append(QDir::toNativeSeparators(QDir::homePath())); + my.folio.replace(QRegExp(regex), "~"); + + Tab *tab = pmchart->activeTab(); + tab->addFolio(my.folio, my.view); + + for (int i = 0; i < my.hosts.size(); i++) { + PmLogger *process = new PmLogger(pmchart); + QString archive = my.archives.at(i); + QString host = my.hosts.at(i); + QString logfile, configfile; + + configfile = archive; + configfile.append(".config"); + logfile = archive; + logfile.append(".log"); + + process->init(my.tab, host, logfile); + + QStringList arguments; + arguments << "-r" << "-c" << configfile << "-h" << host << "-x0"; + arguments << "-l" << logfile << "-t" << my.delta << archive; + + QString configdata("#pmlogger Version 1\n\n"); // header for file(1) + if (selectedRadioButton->isChecked()) + configdata.append(tab->currentGadget()->pmloggerSyntax()); + else + for (int c = 0; c < tab->gadgetCount(); c++) + configdata.append(tab->gadget(c)->pmloggerSyntax()); + saveConfig(configfile, configdata); + + process->start(pmlogger, arguments); + tab->addLogger(process, archive); + + // Send initial control messages to pmlogger + QStringList control; + control << "V0\n"; + control << "F" << my.folio << "\n"; + control << "Ppmchart\n" << "R\n"; + for (int i = 0; i < control.size(); i++) + process->write(control.at(i).toAscii()); + } +} + +// RecordFileDialog is the one which is displayed when you click +// on one of the file selection push buttons (view/logfile/folio). + +RecordFileDialog::RecordFileDialog(QWidget *parent) : QFileDialog(parent) +{ + setAcceptMode(QFileDialog::AcceptSave); + setFileMode(QFileDialog::AnyFile); + setIconProvider(fileIconProvider); + setConfirmOverwrite(true); +} + +void RecordFileDialog::setFileName(QString path) +{ + selectFile(path); +} |