From: <ibr...@us...> - 2012-10-01 14:10:28
|
Revision: 4483 http://tora.svn.sourceforge.net/tora/?rev=4483&view=rev Author: ibre5041 Date: 2012-10-01 14:10:13 +0000 (Mon, 01 Oct 2012) Log Message: ----------- Profiler tool added Modified Paths: -------------- branches/tora3/src/CMakeLists.txt Added Paths: ----------- branches/tora3/src/obsolete/tochartalarmui.ui branches/tora3/src/obsolete/tochartmanager.cpp branches/tora3/src/obsolete/tochartmanager.h branches/tora3/src/obsolete/tochartsetupui.ui branches/tora3/src/obsolete/tosmtp.h branches/tora3/src/tools/toprofiler.cpp branches/tora3/src/tools/toprofiler.h Removed Paths: ------------- branches/tora3/src/tochartalarmui.ui branches/tora3/src/tochartmanager.cpp branches/tora3/src/tochartmanager.h branches/tora3/src/tochartsetupui.ui branches/tora3/src/toprofiler.cpp branches/tora3/src/toprofiler.h branches/tora3/src/tosmtp.h Modified: branches/tora3/src/CMakeLists.txt =================================================================== --- branches/tora3/src/CMakeLists.txt 2012-10-01 13:23:58 UTC (rev 4482) +++ branches/tora3/src/CMakeLists.txt 2012-10-01 14:10:13 UTC (rev 4483) @@ -292,6 +292,8 @@ tools/toscripttreeitem.h tools/toscripttreemodel.h + tools/toprofiler.h + # toalert.h # todebug.h @@ -299,12 +301,9 @@ # toeditextensions.h - # tochartmanager.h - # tolegendchart.h - # toplsqleditor.h # toplsqltext.h - # toprofiler.h + # toproject.h # # toreport.h @@ -317,8 +316,6 @@ # # toscheduler.h # tosqledit.h - # # tosql.h - # # tosqlparse.h # # tostoragedefinition.h # totemplate.h @@ -522,6 +519,8 @@ tools/toscripttreeitem.cpp tools/toscripttreemodel.cpp + tools/toprofiler.cpp + # totemplateprovider.cpp # toalert.cpp # todebug.cpp @@ -532,7 +531,7 @@ # tolegendchart.cpp # toplsqleditor.cpp # toplsqltext.cpp - # toprofiler.cpp + # toproject.cpp # toreport.cpp # toresultlabel.cpp Copied: branches/tora3/src/obsolete/tochartalarmui.ui (from rev 4481, branches/tora3/src/tochartalarmui.ui) =================================================================== --- branches/tora3/src/obsolete/tochartalarmui.ui (rev 0) +++ branches/tora3/src/obsolete/tochartalarmui.ui 2012-10-01 14:10:13 UTC (rev 4483) @@ -0,0 +1,317 @@ +<ui version="4.0" stdsetdef="1" > + <author></author> + <comment></comment> + <exportmacro></exportmacro> + <class>toChartAlarmUI</class> + <widget class="QDialog" name="toChartAlarmUI" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>388</width> + <height>509</height> + </rect> + </property> + <property name="windowTitle" > + <string>Chart alarm</string> + </property> + <layout class="QGridLayout" > + <property name="margin" > + <number>11</number> + </property> + <property name="spacing" > + <number>6</number> + </property> + <item row="0" column="2" > + <widget class="QComboBox" name="Operation" > + <item> + <property name="text" > + <string>Any</string> + </property> + </item> + <item> + <property name="text" > + <string>All</string> + </property> + </item> + <item> + <property name="text" > + <string>Sum</string> + </property> + </item> + <item> + <property name="text" > + <string>Average</string> + </property> + </item> + <item> + <property name="text" > + <string>Max</string> + </property> + </item> + <item> + <property name="text" > + <string>Min</string> + </property> + </item> + </widget> + </item> + <item row="3" column="2" > + <widget class="QComboBox" name="Action" > + <item> + <property name="text" > + <string>Statusmessage</string> + </property> + </item> + <item> + <property name="text" > + <string>Email</string> + </property> + </item> + <item> + <property name="text" > + <string>Ignore</string> + </property> + </item> + </widget> + </item> + <item row="1" column="2" > + <widget class="QComboBox" name="Comparison" > + <item> + <property name="text" > + <string>=</string> + </property> + </item> + <item> + <property name="text" > + <string>!=</string> + </property> + </item> + <item> + <property name="text" > + <string><</string> + </property> + </item> + <item> + <property name="text" > + <string>></string> + </property> + </item> + <item> + <property name="text" > + <string><=</string> + </property> + </item> + <item> + <property name="text" > + <string>>=</string> + </property> + </item> + </widget> + </item> + <item row="2" column="2" > + <widget class="QLineEdit" name="Value" /> + </item> + <item row="0" column="1" > + <widget class="QLabel" name="TextLabel1" > + <property name="text" > + <string>Operation</string> + </property> + <property name="toolTip" > + <string>Operation to perform on the selected columns</string> + </property> + <property name="wordWrap" > + <bool>false</bool> + </property> + </widget> + </item> + <item row="2" column="1" > + <widget class="QLabel" name="TextLabel2" > + <property name="text" > + <string>Value</string> + </property> + <property name="toolTip" > + <string>Value to use in comparison.</string> + </property> + <property name="wordWrap" > + <bool>false</bool> + </property> + </widget> + </item> + <item row="1" column="1" > + <widget class="QLabel" name="TextLabel1_2" > + <property name="text" > + <string>Comparison</string> + </property> + <property name="toolTip" > + <string>What comparison to do with the result from the above operation.</string> + </property> + <property name="wordWrap" > + <bool>false</bool> + </property> + </widget> + </item> + <item row="3" column="1" > + <widget class="QLabel" name="TextLabel3" > + <property name="text" > + <string>Action</string> + </property> + <property name="toolTip" > + <string>What to do when alarm is triggered.</string> + </property> + <property name="wordWrap" > + <bool>false</bool> + </property> + </widget> + </item> + <item rowspan="1" row="7" column="0" colspan="3" > + <layout class="QHBoxLayout" > + <property name="margin" > + <number>0</number> + </property> + <property name="spacing" > + <number>6</number> + </property> + <item> + <spacer name="Spacer1" > + <property name="sizeHint" > + <size> + <width>20</width> + <height>20</height> + </size> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="PushButton1" > + <property name="text" > + <string>&Ok</string> + </property> + <property name="default" > + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="PushButton2" > + <property name="text" > + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + <item rowspan="7" row="0" column="0" colspan="1" > + <widget class="toListView" name="Charts" > + <property name="sizePolicy" > + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + </sizepolicy> + </property> + <property name="focusPolicy" > + <enum>Qt::StrongFocus</enum> + </property> + </widget> + </item> + <item row="6" column="2" > + <spacer name="Spacer2" > + <property name="sizeHint" > + <size> + <width>20</width> + <height>20</height> + </size> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="orientation" > + <enum>Qt::Vertical</enum> + </property> + </spacer> + </item> + <item rowspan="1" row="5" column="1" colspan="2" > + <widget class="QCheckBox" name="Persistent" > + <property name="text" > + <string>Persistent</string> + </property> + <property name="toolTip" > + <string>Remember this alarm when restarting.</string> + </property> + </widget> + </item> + <item row="4" column="1" > + <widget class="QLabel" name="ExtraLabel" > + <property name="text" > + <string/> + </property> + <property name="wordWrap" > + <bool>false</bool> + </property> + </widget> + </item> + <item row="4" column="2" > + <widget class="QLineEdit" name="Extra" /> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>toListView</class> + <extends>QWidget</extends> + <header location="local" >toresultview.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> + </customwidgets> + <tabstops> + <tabstop>Charts</tabstop> + <tabstop>Operation</tabstop> + <tabstop>Comparison</tabstop> + <tabstop>Value</tabstop> + <tabstop>Action</tabstop> + <tabstop>Extra</tabstop> + <tabstop>Persistent</tabstop> + <tabstop>PushButton1</tabstop> + <tabstop>PushButton2</tabstop> + </tabstops> + <images> + <image name="image0" > + <data format="XPM.GZ" length="646" >789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data> + </image> + </images> + <connections> + <connection> + <sender>PushButton1</sender> + <signal>clicked()</signal> + <receiver>toChartAlarmUI</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>PushButton2</sender> + <signal>clicked()</signal> + <receiver>toChartAlarmUI</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>Action</sender> + <signal>activated(int)</signal> + <receiver>toChartAlarmUI</receiver> + <slot>changeValue(int)</slot> + </connection> + </connections> +</ui> Copied: branches/tora3/src/obsolete/tochartmanager.cpp (from rev 4481, branches/tora3/src/tochartmanager.cpp) =================================================================== --- branches/tora3/src/obsolete/tochartmanager.cpp (rev 0) +++ branches/tora3/src/obsolete/tochartmanager.cpp 2012-10-01 14:10:13 UTC (rev 4483) @@ -0,0 +1,1118 @@ + +/* BEGIN_COMMON_COPYRIGHT_HEADER + * + * TOra - An Oracle Toolkit for DBA's and developers + * + * Shared/mixed copyright is held throughout files in this product + * + * Portions Copyright (C) 2000-2001 Underscore AB + * Portions Copyright (C) 2003-2005 Quest Software, Inc. + * Portions Copyright (C) 2004-2009 Numerous Other Contributors + * + * 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; only version 2 of + * the License is valid for this program. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * As a special exception, you have permission to link this program + * with the Oracle Client libraries and distribute executables, as long + * as you follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from Oracle client libraries. + * + * Specifically you are not permitted to link this program with the + * Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech. + * And you are not permitted to distribute binaries compiled against + * these libraries. + * + * You may link this product with any GPL'd Qt library. + * + * All trademarks belong to their respective owners. + * + * END_COMMON_COPYRIGHT_HEADER */ + +#include "tochartmanager.h" +#include "utils.h" +#include "tologger.h" + +#include "tobarchart.h" +#include "toconf.h" +#include "toconnection.h" +#include "tolinechart.h" +#include "tomain.h" +#include "toresultview.h" +#include "tosmtp.h" +#include "totool.h" + +#include <ctype.h> + +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qmenubar.h> +#include <qmessagebox.h> +#include <qtoolbar.h> +#include <qtoolbutton.h> +#include <qvalidator.h> +#include <QMdiArea> + +#include <QString> +#include <QPixmap> + +#include "icons/chart.xpm" +#include "icons/fileopen.xpm" +#include "icons/refresh.xpm" + +class toChartTool : public toTool +{ +protected: + toChartHandler *Handler; + toChartManager *Window; +public: + toChartTool() + : toTool(930, "Chart Manager") + { + Window = NULL; + } + virtual QWidget *toolWindow(QWidget *, toConnection &) + { + if (!Handler) + return NULL; + + if (Window) + { + Window->setFocus(Qt::OtherFocusReason); + // already opened, prevent creating new sub window + return 0; + } + + Window = new toChartManager(toMainWidget()->workspace()); + Window->setWindowTitle(qApp->translate("toChartTool", "Chart Manager")); + Window->setWindowIcon(QPixmap(const_cast<const char**>(chart_xpm))); + Window->refresh(); + return Window; + } + virtual void customSetup() + { + toMainWidget()->getEditMenu()->addAction( + QIcon(chart_xpm), + qApp->translate("toChartTool", "Chart Manager..."), + this, + SLOT(createWindow())); + + Handler = new toChartHandler(); + } + void closeWindow(void) + { + Window = NULL; + } + void closeHandler(void) + { + Handler = NULL; + } + + toChartHandler *handler() + { + return Handler; + } + toChartManager *manager() + { + return Window; + } + + virtual bool canHandle(toConnection &) + { + return true; + } + virtual void closeWindow(toConnection &connection) {}; +}; + +static toChartTool ChartTool; + +toChartAlarm::toChartAlarm(QWidget *parent, + const char *name, + bool modal, + Qt::WFlags fl) + : QDialog(parent) +{ + setupUi(this); +} + +void toChartAlarm::changeValue(int val) +{ + if (val == 1) + ExtraLabel->setText(qApp->translate("toChartAlarm", "Email")); + else + ExtraLabel->setText(QString::null); + + Extra->setEnabled(val == 1); +} + +toChartSetup::toChartSetup(toLineChart *chart, + QWidget* parent, + const char* name, + bool modal) + : QDialog(parent) +{ + + setupUi(this); + Chart = chart; + + connect(BrowseButton, SIGNAL(clicked()), this, SLOT(browseFile())); + connect(AddButton, SIGNAL(clicked()), this, SLOT(addAlarm())); + connect(RemoveButton, SIGNAL(clicked()), this, SLOT(removeAlarm())); + connect(ModifyButton, SIGNAL(clicked()), this, SLOT(modifyAlarm())); +} + + +void toChartSetup::browseFile() +{ + QString str = toOpenFilename(Filename->text(), QString::fromLatin1("*.csv"), this); + if (!str.isEmpty()) + Filename->setText(str); +} + + +QString toChartSetup::modifyAlarm(const QString &str, bool &persistent) +{ + toChartManager::chartAlarm alarm(str, persistent); + toChartAlarm diag(this, NULL, true); + diag.Operation->setCurrentIndex((int)alarm.Operation); + diag.Comparison->setCurrentIndex((int)alarm.Comparison); + diag.Action->setCurrentIndex((int)alarm.Action); + diag.Value->setText(QString::number(alarm.Value)); + diag.changeValue((int)alarm.Action); + diag.Value->setValidator(new QDoubleValidator(diag.Value)); + diag.Extra->setText(alarm.Extra); + std::list<int>::iterator sel = alarm.Columns.begin(); + diag.Charts->addColumn(qApp->translate("toChartSetup", "Charts")); + diag.Charts->setSelectionMode(toTreeWidget::Multi); + toTreeWidgetItem *item = NULL; + std::list<QString>::iterator lab = Chart->labels().begin(); + for (int i = 0; lab != Chart->labels().end(); i++, lab++) + { + item = new toTreeWidgetItem(diag.Charts, item, *lab); + if (sel != alarm.Columns.end() && *sel == i) + { + item->setSelected(true); + sel++; + } + } + diag.Persistent->setChecked(persistent); + if (diag.exec()) + { + persistent = diag.Persistent->isChecked(); + int i = 0; + alarm.Columns.clear(); + for (toTreeWidgetItem *item = diag.Charts->firstChild(); item; item = item->nextSibling()) + { + if (item->isSelected()) + alarm.Columns.insert(alarm.Columns.end(), i); + i++; + } + alarm.Action = (toChartManager::action)diag.Action->currentIndex(); + alarm.Operation = (toChartManager::chartAlarm::operation)diag.Operation->currentIndex(); + alarm.Comparison = (toChartManager::chartAlarm::comparison)diag.Comparison->currentIndex(); + alarm.Value = diag.Value->text().toDouble(); + alarm.Extra = diag.Extra->text(); + return alarm.toString(); + } + return QString::null; +} + +void toChartSetup::addAlarm() +{ + toChartManager::chartAlarm alarm; + QString str = modifyAlarm(alarm.toString(), alarm.Persistent); + if (!str.isEmpty()) + new toTreeWidgetItem(Alarms, str, alarm.Persistent ? qApp->translate("toChartSetup", "Persistent") : qApp->translate("toChartSetup", "Temporary")); +} + +void toChartSetup::modifyAlarm() +{ + toTreeWidgetItem *item = Alarms->selectedItem(); + if (item) + { + bool pers = item->text(1) == qApp->translate("toChartSetup", "Persistent"); + QString str = modifyAlarm(item->text(0), pers); + if (!str.isEmpty()) + { + item->setText(0, str); + item->setText(1, pers ? qApp->translate("toChartSetup", "Persistent") : qApp->translate("toChartSetup", "Temporary")); + } + } +} + +void toChartSetup::removeAlarm() +{ + delete Alarms->selectedItem(); +} + +toChartReceiver::toChartReceiver(toChartHandler *parent, toLineChart *chart) + : QObject(parent) +{ + Parent = parent; + Chart = chart; + Result = NULL; + connect(Chart, SIGNAL(valueAdded(std::list<double> &, const QString &)), + this, SLOT(valueAdded(std::list<double> &, const QString &))); +} + +toResult *toChartReceiver::result(void) +{ + if (!Result) + Result = dynamic_cast<toResult *>(Chart); + return Result; +} + +QString toChartReceiver::name(void) +{ + if (!Result || Result->sqlName().isEmpty()) + return QString::null; + try + { + LastName = Result->connection().description(false) + QString(":") + QString(Result->sqlName()); + } + catch (...) + { + TLOG(1, toDecorator, __HERE__) << " Ignored exception." << std::endl; + } + return LastName; +} + +void toChartReceiver::valueAdded(std::list<double> &value, const QString &xValues) +{ + Parent->valueAdded(Chart, name(), value, xValues); +} + +toChartManager::toChartManager(QWidget *main) + : QWidget(main), toHelpContext(QString::fromLatin1("chartmanager.html")) +{ + + QVBoxLayout *vbox = new QVBoxLayout; + + QToolBar *toolbar = toAllocBar(this, tr("Chart Manager")); + vbox->addWidget(toolbar); + + toolbar->addAction(QIcon(refresh_xpm), + tr("Refresh list"), + this, + SLOT(refresh())); + + toolbar->addSeparator(); + + toolbar->addAction(QIcon(fileopen_xpm), + tr("Open tracker file"), + this, + SLOT(openChart())); + toolbar->addAction(QIcon(chart_xpm), + tr("Setup chart"), + this, + SLOT(setupChart())); + + toolbar->addWidget(new toSpacer()); + + List = new toListView(this); + List->addColumn(tr("Connection")); + List->addColumn(tr("Title")); + List->addColumn(tr("ID")); + List->addColumn(tr("Tracking")); + List->addColumn(tr("Alarms")); + List->setSorting(2); + List->setSelectionMode(toTreeWidget::Single); + vbox->addWidget(List); + + connect(&Refresh, SIGNAL(timeout()), this, SLOT(refresh())); + + setFocusProxy(List); + + vbox->setSpacing(0); + vbox->setContentsMargins(0, 0, 0, 0); + setLayout(vbox); +} + +toChartManager::~toChartManager() +{ + ChartTool.closeWindow(); +} + +void toChartHandler::addChart(toLineChart *chart) +{ + Charts.insert(Charts.end(), new toChartReceiver(this, chart)); + toChartManager *manager = ChartTool.manager(); + if (manager) + { + manager->Refresh.setSingleShot(true); + manager->Refresh.start(1); + } +} + +void toChartHandler::removeChart(toLineChart *chart) +{ + for (std::list<toChartReceiver *>::iterator i = Charts.begin(); i != Charts.end(); i++) + { + if ((*i)->chart() == chart) + { + QString name = (*i)->name(); + if (!name.isNull()) + { + std::map<QString, std::list<toChartManager::chartAlarm> >::iterator fnda = Alarms.find(name); + if (fnda != Alarms.end()) + { + bool any = false; + for (std::list<toChartManager::chartAlarm>::iterator j = (*fnda).second.begin(); j != (*fnda).second.end();) + { + if (!(*j).Persistent) + { + (*fnda).second.erase(j); + j = (*fnda).second.begin(); + } + else + { + j++; + any = true; + } + } + if (!any) + Alarms.erase(fnda); + } + + std::map<QString, toChartManager::chartTrack>::iterator fndt = Files.find(name); + if (fndt != Files.end()) + { + if (!(*fndt).second.Persistent) + Files.erase(fndt); + } + } + + delete *i; + Charts.erase(i); + toChartManager *manager = ChartTool.manager(); + if (manager) + { + manager->Refresh.setSingleShot(true); + manager->Refresh.start(1); + } + return ; + } + } +} + +toChartManager::alarmSignal::alarmSignal(void) +{ + Action = Ignore; +} + +toChartManager::chartAlarm::chartAlarm(const QString &inp, bool pers) +{ + char oper[100]; + char cols[10000]; + char comp[100]; + char act[100]; + char extra[10000]; + Signal = false; + Persistent = pers; + + // The \01 is just one character unlikely to be in an email address + int ret = sscanf(inp.toUtf8(), "%s %s %s %lf %s %[^\01]", oper, cols, comp, &Value, act, extra); + if (ret != 5 && ret != 6) + { + Operation = Any; + Value = 0; + Comparison = Equal; + Action = Ignore; + return ; + } + + QString t = QString::fromLatin1(oper); + if (t == QString::fromLatin1("min")) + Operation = Min; + else if (t == QString::fromLatin1("all")) + Operation = All; + else if (t == QString::fromLatin1("sum")) + Operation = Sum; + else if (t == QString::fromLatin1("average")) + Operation = Average; + else if (t == QString::fromLatin1("max")) + Operation = Max; + else + Operation = Any; + + t = QString::fromUtf8(cols); + if (t.length() > 2) + { + QStringList lst = t.mid(1, t.length() - 2).split(","); + for (int i = 0; i < lst.count(); i++) + Columns.insert(Columns.end(), lst[i].toInt()); + Columns.sort(); + } + + t = QString::fromLatin1(comp); + if (t == QString::fromLatin1("=")) + { + Comparison = Equal; + } + else if (t == QString::fromLatin1("!=")) + { + Comparison = NotEqual; + } + else if (t == QString::fromLatin1("<")) + { + Comparison = Less; + } + else if (t == QString::fromLatin1(">")) + { + Comparison = Greater; + } + else if (t == QString::fromLatin1("<=")) + { + Comparison = LessEqual; + } + else if (t == QString::fromLatin1(">=")) + { + Comparison = GreaterEqual; + } + else + { + Comparison = Equal; + } + + t = QString::fromLatin1(act); + if (t == QString::fromLatin1("StatusMessage")) + Action = StatusMessage; + else if (t == QString::fromLatin1("Email")) + Action = Email; + else + Action = Ignore; + if (ret == 6) + Extra = QString::fromUtf8(extra); +} + +toChartManager::chartAlarm::chartAlarm() +{ + Signal = false; + Operation = Any; + Comparison = Equal; + Action = StatusMessage; + Value = 0; + Persistent = true; +} + +toChartManager::chartAlarm::chartAlarm(operation oper, comparison comp, action act, + double value, std::list<int> &cols, const QString &extra, + bool persistent) +{ + Signal = false; + Operation = oper; + Comparison = comp; + Action = act; + Value = value; + Columns = cols; + Persistent = persistent; + Extra = extra; +} + +QString toChartManager::chartAlarm::toString(void) +{ + QString t; + switch (Operation) + { + case Any: + t = QString::fromLatin1("any"); + break; + case All: + t = QString::fromLatin1("all"); + break; + case Sum: + t = QString::fromLatin1("sum"); + break; + case Average: + t = QString::fromLatin1("average"); + break; + case Max: + t = QString::fromLatin1("max"); + break; + case Min: + t = QString::fromLatin1("min"); + break; + } + t += QString::fromLatin1(" ("); + bool first = true; + for (std::list<int>::iterator i = Columns.begin(); i != Columns.end(); i++) + { + if (first) + first = false; + else + t += QString::fromLatin1(","); + t += QString::number(*i); + } + t += QString::fromLatin1(")"); + switch (Comparison) + { + case Equal: + t += QString::fromLatin1(" = "); + break; + case NotEqual: + t += QString::fromLatin1(" != "); + break; + case Less: + t += QString::fromLatin1(" < "); + break; + case Greater: + t += QString::fromLatin1(" > "); + break; + case LessEqual: + t += QString::fromLatin1(" <= "); + break; + case GreaterEqual: + t += QString::fromLatin1(" >= "); + break; + } + t += QString::number(Value); + switch (Action) + { + case StatusMessage: + t += QString::fromLatin1(" StatusMessage"); + break; + case Email: + t += QString::fromLatin1(" Email"); + break; + case Ignore: + t += QString::fromLatin1(" Ignore"); + break; + } + if (!Extra.isEmpty()) + { + t += QString::fromLatin1(" "); + t += Extra; + } + return t; +} + +bool toChartManager::chartAlarm::checkValue(double val) +{ + switch (Comparison) + { + case Equal: + return val == Value; + case NotEqual: + return val != Value; + case Less: + return Value < val; + case Greater: + return Value > val; + case LessEqual: + return Value <= val; + case GreaterEqual: + return Value >= val; + } + return false; +} + +void toChartManager::chartAlarm::valueAdded(toChartHandler *handler, + const QString &str, + std::list<double> &value, + const QString &xValue) +{ + std::list<double> vals; + std::list<double>::iterator i = value.begin(); + std::list<int>::iterator j = Columns.begin(); + for (int id = 0; j != Columns.end() && i != value.end(); i++, id++) + { + if (id == *j) + { + vals.insert(vals.end(), *i); + j++; + } + } + bool sig = false; + switch (Operation) + { + case Any: + { + for (std::list<double>::iterator i = vals.begin(); i != vals.end(); i++) + if (checkValue(*i)) + { + sig = true; + break; + } + } + break; + case All: + sig = true; + { + for (std::list<double>::iterator i = vals.begin(); i != vals.end(); i++) + if (!checkValue(*i)) + { + sig = false; + break; + } + } + break; + case Sum: + { + double val = 0; + for (std::list<double>::iterator i = vals.begin(); i != vals.end(); i++) + val += *i; + sig = checkValue(val); + } + break; + case Average: + { + double val = 0; + for (std::list<double>::iterator i = vals.begin(); i != vals.end(); i++) + val += *i; + sig = checkValue(val / vals.size()); + } + break; + case Max: + { + bool first = true; + double val = 0; + for (std::list<double>::iterator i = vals.begin(); i != vals.end(); i++) + { + if (first) + { + first = false; + val = *i; + } + else + val = std::max(*i, val); + } + sig = checkValue(val); + } + break; + case Min: + { + bool first = true; + double val = 0; + for (std::list<double>::iterator i = vals.begin(); i != vals.end(); i++) + { + if (first) + { + first = false; + val = *i; + } + else + val = std::min(*i, val); + } + sig = checkValue(val); + } + break; + } + if (sig) + { + if (Signal) + return ; + handler->SignalAlarms.insert(handler->SignalAlarms.end(), + alarmSignal(Action, xValue, str, toString(), Extra)); + handler->Timer.setSingleShot(true); + handler->Timer.start(1); + Signal = true; + } + else + Signal = false; +} + +void toChartHandler::saveSettings(void) +{ + { +// int num = 0; + ChartsMap c; + for (std::map<QString, toChartManager::chartTrack>::iterator i = Files.begin(); i != Files.end(); i++) + { + if ((*i).second.Persistent) + { +// num++; +// QString name = QString("Files:") + QString::number(num).toLatin1(); +// ChartTool.setConfig(name + ":Name", (*i).first); +// ChartTool.setConfig(name + ":Spec", (*i).second.File.fileName()); + c[(*i).first] = (*i).second.File.fileName(); + } + } +// ChartTool.setConfig("FilesCount", QString::number(num)); + toConfigurationSingle::Instance().setChartFiles(c); + } + { + ChartsMap c; +// int num = 0; + for (std::map<QString, std::list<toChartManager::chartAlarm> >::iterator i = Alarms.begin(); + i != Alarms.end(); i++) + { + for (std::list<toChartManager::chartAlarm>::iterator j = (*i).second.begin(); j != (*i).second.end(); j++) + { + if ((*j).Persistent) + { +// num++; +// QString name = QString("Alarms:") + QString::number(num).toLatin1(); +// ChartTool.setConfig(name + ":Name", (*i).first); +// ChartTool.setConfig(name + ":Spec", (*j).toString()); + c[(*i).first] = (*j).toString(); + } + } + } +// ChartTool.setConfig("AlarmCount", QString::number(num)); + toConfigurationSingle::Instance().setChartAlarms(c); + } + toConfigurationSingle::Instance().saveConfig(); +} + +void toChartHandler::loadSettings(void) +{ +// { +// for (int num = ChartTool.config("FilesCount", "0").toInt();num > 0;num--) +// { +// QString name = QString("Files:") + QString::number(num).toLatin1(); +// QString t = ChartTool.config(name + ":Name", ""); +// QString s = ChartTool.config(name + ":Spec", ""); +// if (!t.isEmpty() && !s.isEmpty()) +// Files[t] = toChartManager::chartTrack(s, true); +// } +// } + ChartsMapIterator i(toConfigurationSingle::Instance().chartFiles()); + while (i.hasNext()) + { + i.next(); + if (!i.key().isEmpty() && !i.value().isEmpty()) + Files[i.key()] = toChartManager::chartTrack(i.value(), true); + } +// { +// for (int num = ChartTool.config("AlarmCount", "0").toInt();num > 0;num--) +// { +// QString name = QString("Alarms:") + QString::number(num).toLatin1(); +// QString t = ChartTool.config(name + ":Name", ""); +// QString s = ChartTool.config(name + ":Spec", ""); +// if (!t.isEmpty() && !s.isEmpty()) +// Alarms[t].insert(Alarms[t].end(), toChartManager::chartAlarm(s, true)); +// } +// } + ChartsMapIterator i1(toConfigurationSingle::Instance().chartAlarms()); + while (i1.hasNext()) + { + i1.next(); + if (!i1.key().isEmpty() && !i1.value().isEmpty()) + Alarms[i1.key()].insert(Alarms[i1.key()].end(), toChartManager::chartAlarm(i1.value(), true)); + } +} + +void toChartHandler::alarm(void) +{ + while (!SignalAlarms.empty()) + { + toChartManager::alarmSignal signal = toShift(SignalAlarms); + if (signal.Action == toChartManager::StatusMessage) + Utils::toStatusMessage(tr("ALARM:") + signal.Chart + QString::fromLatin1(": ") + signal.Alarm + QString::fromLatin1(": ") + signal.xValue); + else if (signal.Action == toChartManager::Email) + new toSMTP(QString::fromLatin1(TOAPPNAME " <noreply@localhost>"), + signal.Extra, + tr("TOra alert:") + " " + signal.Chart, + tr("A defined alert value was detected:\n\n%1\n\nAt: %2").arg(signal.Alarm).arg(signal.xValue)); + } +} + +void toChartHandler::valueAdded(toLineChart *chart, + const QString &chartName, + std::list<double> &value, + const QString &xValue) +{ + std::map<QString, std::list<toChartManager::chartAlarm> >::iterator fnda = Alarms.find(chartName); + if (fnda != Alarms.end()) + { + std::list<toChartManager::chartAlarm> &alarms = (*fnda).second; + for (std::list<toChartManager::chartAlarm>::iterator i = alarms.begin(); i != alarms.end(); i++) + (*i).valueAdded(this, chartName, value, xValue); + } + + std::map<QString, toChartManager::chartTrack>::iterator fndt = Files.find(chartName); + if (fndt != Files.end()) + { + QFile &file = (*fndt).second.File; + bool header = false; + if (!file.isOpen()) + { + if (!file.exists()) + header = true; + file.open(QIODevice::Unbuffered | QIODevice::WriteOnly | QIODevice::Append); + } + if (file.isOpen()) + { + static QRegExp quote(QString::fromLatin1("\"")); + QString out = "\""; + if (header) + { + QString t = chart->title(); + t.replace(quote, QString::fromLatin1("\"\"")); + out += t.toUtf8(); + std::list<QString> labels = chart->labels(); + for (std::list<QString>::iterator i = labels.begin(); i != labels.end(); i++) + { + out += "\";\""; + QString t = (*i); + t.replace(quote, QString::fromLatin1("\"\"")); + out += t.toUtf8(); + } + out += "\"\n\""; + } + QString t = xValue; + t.replace(quote, QString::fromLatin1("\"\"")); + out += t.toUtf8(); + for (std::list<double>::iterator i = value.begin(); i != value.end(); i++) + { + out += "\";\""; + out += QString::number(*i); + } + out += "\"\n"; + file.write(out.toUtf8()); + } + } +} + +static QString ReadCSV(const QString &data, int &pos, bool &nl) +{ + QString ret; + if (data.at(pos) != '\"') + throw qApp->translate("toChartManager", "Initial value didn't start with \" in CSV file"); + pos++; + while (pos < data.length() && + (data.at(pos) != '\"' || (pos + 1 < data.length() && + data.at(pos + 1) == '\"'))) + { + ret += data.at(pos); + if (data.at(pos) == '\"') + pos++; + pos++; + } + if (pos >= data.length()) + throw qApp->translate("toChartManager", "Missing closing \" in CSV file"); + pos++; + nl = false; + while (pos < data.length() && (data.at(pos).isSpace() || data.at(pos) == ',' || data.at(pos) == ';')) + { + if (data.at(pos) == '\n') + nl = true; + pos++; + } + return ret; +} + +void toChartManager::openChart(void) +{ + QString name = toOpenFilename(QString::fromLatin1("*.csv"), this); + if (!name.isEmpty()) + { + try + { + QString data = toReadFile(name); + int pos = 0; + + toLineChart *chart; + switch (TOMessageBox::information(toMainWidget(), + tr("Chart format"), + tr("Select format of the chart to display"), + tr("Barchart"), + tr("Linechart"), + tr("Cancel"))) + { + case 0: + chart = new toBarChart(toMainWidget()->workspace(), NULL); + chart->setAttribute(Qt::WA_DeleteOnClose); + break; + case 1: + chart = new toLineChart(toMainWidget()->workspace(), NULL); + chart->setAttribute(Qt::WA_DeleteOnClose); + break; + default: + return ; + } + chart->show(); + chart->setSamples( -1); + bool eol; + chart->setTitle(ReadCSV(data, pos, eol)); + std::list<QString> lab; + while (!eol && pos < data.length()) + lab.insert(lab.end(), ReadCSV(data, pos, eol)); + chart->setLabels(lab); + while (pos < data.length()) + { + QString t = ReadCSV(data, pos, eol); + std::list<double> val; + while (!eol && pos < data.length()) + val.insert(val.end(), ReadCSV(data, pos, eol).toDouble()); + chart->addValues(val, t); + } + } + TOCATCH + } +} + +void toChartManager::setupChart(void) +{ + toChartReceiver *chart = selectedChart(); + if (chart && ChartTool.handler()) + ChartTool.handler()->setupChart(chart->chart()); +} + +toChartReceiver *toChartManager::selectedChart(void) +{ + try + { + toTreeWidgetItem *item = List->selectedItem(); + if (item && ChartTool.handler()) + { + for (std::list<toChartReceiver *>::iterator i = ChartTool.handler()->Charts.begin(); i != ChartTool.handler()->Charts.end(); i++) + { + toResult *result = (*i)->result(); + if (result) + { + if (item->text(0) == result->connection().description(false) && + item->text(2) == result->sqlName()) + return *i; + } + } + } + } + TOCATCH + return NULL; +} + +void toChartHandler::setupChart(toLineChart *chart) +{ + for (std::list<toChartReceiver *>::iterator i = Charts.begin(); i != Charts.end(); i++) + { + if ((*i)->chart() == chart) + { + QString name = (*i)->name(); + if (!name.isNull()) + { + std::list<toChartManager::chartAlarm> alarm; + std::map<QString, std::list<toChartManager::chartAlarm> >::iterator fnda = Alarms.find(name); + if (fnda != Alarms.end()) + alarm = (*fnda).second; + + toChartManager::chartTrack file; + std::map<QString, toChartManager::chartTrack>::iterator fndt = Files.find(name); + if (fndt != Files.end()) + file = (*fndt).second; + + toChartSetup setup(chart, toMainWidget(), NULL, true); + setup.Alarms->addColumn(tr("Alarms")); + setup.Alarms->addColumn(tr("Persistent")); + setup.Alarms->setSorting(0); + setup.Alarms->setSelectionMode(toTreeWidget::Single); + setup.Persistent->setChecked(file.Persistent); + setup.Filename->setText(file.File.fileName()); + if (!setup.Filename->text().isEmpty()) + setup.Enabled->setChecked(true); + setup.ChartFrame->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, + QSizePolicy::Preferred)); + + toLineChart *t = chart->openCopy(setup.ChartFrame); + t->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, + QSizePolicy::Preferred)); + t->showLegend(false); + t->showAxisLegend(false); + setup.ChartFrame->layout()->addWidget(t); + for (std::list<toChartManager::chartAlarm>::iterator j = alarm.begin(); j != alarm.end(); j++) + new toTreeWidgetItem(setup.Alarms, + (*j).toString(), + (*j).Persistent ? tr("Persistent") : tr("Temporary")); + + if (setup.exec()) + { + if (setup.Filename->text().isEmpty() || !setup.Enabled->isChecked()) + { + if (fndt != Files.end()) + Files.erase(fndt); + } + else + { + Files[name] = toChartManager::chartTrack(setup.Filename->text(), + setup.Persistent->isChecked()); + } + if (fnda != Alarms.end()) + Alarms.erase(fnda); + alarm.clear(); + for (toTreeWidgetItem *item = setup.Alarms->firstChild(); + item; item = item->nextSibling()) + { + alarm.insert(alarm.end(), toChartManager::chartAlarm(item->text(0), + item->text(1) == tr("Persistent"))); + } + if (!alarm.empty()) + Alarms[name] = alarm; + saveSettings(); + } + } + break; + } + } +} + +void toChartManager::refresh(void) +{ + if (!ChartTool.handler()) + return ; + try + { + List->clear(); + for (std::list<toChartReceiver *>::iterator i = ChartTool.handler()->Charts.begin(); i != ChartTool.handler()->Charts.end(); i++) + { + toResult *result = (*i)->result(); + if (result) + { + toResultViewItem *item = new toResultViewMLine(List, + NULL, + result->connection().description(false)); + item->setText(1, (*i)->chart()->title()); + item->setText(2, result->sqlName()); + QString name = (*i)->name(); + if (!name.isNull()) + { + std::map<QString, std::list<chartAlarm> >::iterator fnda = ChartTool.handler()->Alarms.find(name); + if (fnda != ChartTool.handler()->Alarms.end()) + { + QString t; + for (std::list<chartAlarm>::iterator j = (*fnda).second.begin(); j != (*fnda).second.end(); j++) + { + t += (*j).toString(); + t += QString::fromLatin1("\n"); + } + if (t.length() > 0) + item->setText(4, t.mid(0, t.length() - 1)); + } + + std::map<QString, chartTrack>::iterator fndt = ChartTool.handler()->Files.find(name); + if (fndt != ChartTool.handler()->Files.end()) + item->setText(3, (*fndt).second.File.fileName()); + } + } + } + } + TOCATCH +} + +toChartHandler::toChartHandler() +{ + connect(toMainWidget(), SIGNAL(chartAdded(toLineChart *)), + this, SLOT(addChart(toLineChart *))); + connect(toMainWidget(), SIGNAL(chartRemoved(toLineChart *)), + this, SLOT(removeChart(toLineChart *))); + connect(toMainWidget(), SIGNAL(chartSetup(toLineChart *)), + this, SLOT(setupChart(toLineChart *))); + connect(&Timer, SIGNAL(timeout()), this, SLOT(alarm())); +} + +toChartHandler::~toChartHandler() +{ + ChartTool.closeHandler(); +} Copied: branches/tora3/src/obsolete/tochartmanager.h (from rev 4481, branches/tora3/src/tochartmanager.h) =================================================================== --- branches/tora3/src/obsolete/tochartmanager.h (rev 0) +++ branches/tora3/src/obsolete/tochartmanager.h 2012-10-01 14:10:13 UTC (rev 4483) @@ -0,0 +1,272 @@ + +/* BEGIN_COMMON_COPYRIGHT_HEADER + * + * TOra - An Oracle Toolkit for DBA's and developers + * + * Shared/mixed copyright is held throughout files in this product + * + * Portions Copyright (C) 2000-2001 Underscore AB + * Portions Copyright (C) 2003-2005 Quest Software, Inc. + * Portions Copyright (C) 2004-2009 Numerous Other Contributors + * + * 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; only version 2 of + * the License is valid for this program. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * As a special exception, you have permission to link this program + * with the Oracle Client libraries and distribute executables, as long + * as you follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from Oracle client libraries. + * + * Specifically you are not permitted to link this program with the + * Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech. + * And you are not permitted to distribute binaries compiled against + * these libraries. + * + * You may link this product with any GPL'd Qt library. + * + * All trademarks belong to their respective owners. + * + * END_COMMON_COPYRIGHT_HEADER */ + +#ifndef TOCHARTMANAGER_H +#define TOCHARTMANAGER_H + +#include "config.h" +#include "tohelp.h" +#include "ui_tochartsetupui.h" +#include "ui_tochartalarmui.h" + +#include <qfile.h> + +#include <QTimer> + +#include <list> +#include <map> +#include <algorithm> + +class toChartManager; +class toLineChart; +class toListView; +class toResult; +class toChartSetup; +class toChartAlarm; +class toChartHandler; + +class toChartReceiver : public QObject +{ + Q_OBJECT + + QString LastName; + toChartHandler *Parent; + toLineChart *Chart; + toResult *Result; +public: + toChartReceiver(toChartHandler *parent, toLineChart *chart); + + toLineChart *chart(void) + { + return Chart; + } + toResult *result(void); + QString name(void); +public slots: + void valueAdded(std::list<double> &value, const QString &xValues); +}; + +class toChartManager : public QWidget, public toHelpContext +{ + Q_OBJECT + + struct alarmSignal; + struct chartAlarm; + friend struct chartAlarm; + friend struct alarmSignal; + + enum action + { + StatusMessage = 0, + Email = 1, + Ignore = 2 + }; + + struct alarmSignal + { + action Action; + QString xValue; + QString Chart; + QString Alarm; + QString Extra; + alarmSignal(); + alarmSignal(action act, const QString &xvalue, const QString &chart, const QString &alarm, + const QString &extra) + : Action(act), xValue(xvalue), Chart(chart), Alarm(alarm), Extra(extra) + { } + } + ; + + struct chartTrack + { + QFile File; + bool Persistent; + + chartTrack() + { + Persistent = true; + } + chartTrack(const QString &file, bool pers) + : File(file) + { + Persistent = pers; + } + chartTrack(const chartTrack &fil) + : File(fil.File.fileName()) + { + Persistent = fil.Persistent; + } + const chartTrack &operator =(const chartTrack &fil) + { + if (fil.File.fileName() != File.fileName()) + { + File.close(); + File.setFileName(fil.File.fileName()); + } + Persistent = fil.Persistent; + return *this; + } + }; + + struct chartAlarm + { + enum operation + { + Any, + All, + Sum, + Average, + Max, + Min + }; + enum comparison + { + Equal, + NotEqual, + Less, + Greater, + LessEqual, + GreaterEqual + }; + + operation Operation; + comparison Comparison; + action Action; + double Value; + std::list<int> Columns; + bool Persistent; + bool Signal; + QString Extra; + + chartAlarm(); + chartAlarm(const QString &, bool persistent); + chartAlarm(operation oper, comparison comp, action act, + double value, std::list<int> &cols, const QString &extra, + bool persistent); + QString toString(void); + + bool checkValue(double value); + + void valueAdded(toChartHandler *handler, const QString &str, + std::list<double> &value, const QString &xValue); + }; + + QTimer Refresh; + toListView *List; + + toChartReceiver *selectedChart(void); +public: + toChartManager(QWidget *parent); + ~toChartManager(); + + friend class toChartSetup; + friend class toChartAlarm; + friend class toChartHandler; +public slots: + void refresh(void); + void setupChart(void); + void openChart(void); +}; + +class toChartHandler : public QObject +{ + Q_OBJECT + + QTimer Timer; + std::map<QString, std::list<toChartManager::chartAlarm> > Alarms; + std::map<QString, toChartManager::chartTrack> Files; + + std::list<toChartReceiver *> Charts; + std::list<toChartManager::alarmSignal> SignalAlarms; + + void loadSettings(void); + void saveSettings(void); +public: + toChartHandler(); + ~toChartHandler(); + + void valueAdded(toLineChart *chart, const QString &chartName, + std::list<double> &vale, const QString &xValue); + + friend class toChartManager; + friend struct toChartManager::alarmSignal; + friend struct toChartManager::chartAlarm; +public slots: + void alarm(void); + void addChart(toLineChart *chart); + void setupChart(toLineChart *chart); + void removeChart(toLineChart *chart); +}; + + +class toChartSetup : public QDialog, public Ui::toChartSetupUI +{ + Q_OBJECT; + + toLineChart *Chart; + +public: + toChartSetup(toLineChart *chart, QWidget* parent, const char* name, bool modal); + +public slots: + virtual void browseFile(); + + virtual QString modifyAlarm(const QString &str, bool &persistent); + virtual void addAlarm(); + virtual void modifyAlarm(); + virtual void removeAlarm(); +}; + + +class toChartAlarm : public QDialog, public Ui::toChartAlarmUI +{ + Q_OBJECT; + +public: + toChartAlarm(QWidget *parent = 0, + const char *name = 0, + bool modal = FALSE, + Qt::WFlags fl = 0); + +public slots: + virtual void changeValue(int val); +}; +#endif Copied: branches/tora3/src/obsolete/tochartsetupui.ui (from rev 4481, branches/tora3/src/tochartsetupui.ui) =================================================================== --- branches/tora3/src/obsolete/tochartsetupui.ui (rev 0) +++ branches/tora3/src/obsolete/tochartsetupui.ui 2012-10-01 14:10:13 UTC (rev 4483) @@ -0,0 +1,362 @@ +<ui version="4.0" > + <class>toChartSetupUI</class> + <widget class="QDialog" name="toChartSetupUI" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>588</width> + <height>480</height> + </rect> + </property> + <property name="windowTitle" > + <string>Chart manager setup</string> + </property> + <layout class="QGridLayout" > + <property name="leftMargin" > + <number>11</number> + </property> + <property name="topMargin" > + <number>11</number> + </property> + <property name="rightMargin" > + <number>11</number> + </property> + <property name="bottomMargin" > + <number>11</number> + </property> + <property name="horizontalSpacing" > + <number>6</number> + </property> + <property name="verticalSpacing" > + <number>6</number> + </property> + <item row="0" column="0" colspan="3" > + <layout class="QHBoxLayout" > + <property name="spacing" > + <number>6</number> + </property> + <property name="leftMargin" > + <number>0</number> + </property> + <property name="topMargin" > + <number>0</number> + </property> + <property name="rightMargin" > + <number>0</number> + </property> + <property name="bottomMargin" > + <number>0</number> + </property> + <item> + <widget class="QGroupBox" name="GroupBox1" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Maximum" hsizetype="Preferred" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title" > + <string>Track chart to file</string> + </property> + <layout class="QGridLayout" > + <property name="leftMargin" > + <number>11</number> + </property> + <property name="topMargin" > + <number>11</number> + </property> + <property name="rightMargin" > + <number>11</number> + </property> + <property name="bottomMargin" > + <number>11</number> + </property> + <property name="horizontalSpacing" > + <number>6</number> + </property> + <property name="verticalSpacing" > + <number>6</number> + </property> + <item row="2" column="0" > + <widget class="QLineEdit" name="Filename" > + <property name="enabled" > + <bool>false</bool> + </property> + </widget> + </item> + <item row="2" column="1" > + <widget class="QPushButton" name="BrowseButton" > + <property name="enabled" > + <bool>false</bool> + </property> + <property name="text" > + <string>Browse</string> + </property> + </widget> + </item> + <item row="3" column="0" colspan="2" > + <widget class="QCheckBox" name="Persistent" > + <property name="enabled" > + <bool>false</bool> + </property> + <property name="toolTip" > + <string>Remember to track this chart to this file always when starting.</string> + </property> + <property name="text" > + <string>Persistent</string> + </property> + </widget> + </item> + <item row="0" column="0" colspan="2" > + <widget class="QCheckBox" name="Enabled" > + <property name="text" > + <string>Enable tracking</string> + </property> + </widget> + </item> + <item row="1" column="0" colspan="2" > + <widget class="QLabel" name="TextLabel2" > + <property name="text" > + <string>Filename</string> + </property> + <property name="wordWrap" > + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" native="1" name="ChartFrame" > + <property name="sizePolicy" > + <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" > + <... [truncated message content] |