3
* TOra - An Oracle Toolkit for DBA's and developers
4
* Copyright (C) 2003-2005 Quest Software, Inc
5
* Portions Copyright (C) 2005 Other Contributors
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; only version 2 of
10
* the License is valid for this program.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
* As a special exception, you have permission to link this program
22
* with the Oracle Client libraries and distribute executables, as long
23
* as you follow the requirements of the GNU GPL in regard to all of the
24
* software in the executable aside from Oracle client libraries.
26
* Specifically you are not permitted to link this program with the
27
* Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech.
28
* And you are not permitted to distribute binaries compiled against
29
* these libraries without written consent from Quest Software, Inc.
30
* Observe that this does not disallow linking to the Qt Free Edition.
32
* You may link this product with any GPL'd Qt library such as Qt/Free
34
* All trademarks belong to their respective owners.
40
#include "tobarchart.h"
42
#include "toconnection.h"
43
#include "tolinechart.h"
45
#include "toresultview.h"
52
# include <kmenubar.h>
55
#include <qcheckbox.h>
56
#include <qcombobox.h>
59
#include <qlineedit.h>
61
#include <qmessagebox.h>
62
#include <qpopupmenu.h>
64
#include <qtoolbutton.h>
65
#include <qvalidator.h>
66
#include <qworkspace.h>
68
#include "tochartalarmui.moc"
69
#include "tochartmanager.moc"
70
#include "tochartsetupui.moc"
72
#include "icons/chart.xpm"
73
#include "icons/fileopen.xpm"
74
#include "icons/refresh.xpm"
76
class toChartTool : public toTool
79
toChartHandler *Handler;
80
toChartManager *Window;
83
: toTool(930, "Chart Manager")
87
virtual QWidget *toolWindow(QWidget *, toConnection &)
93
Window = new toChartManager(toMainWidget()->workspace());
94
Window->setCaption(qApp->translate("toChartTool", "Chart Manager"));
95
Window->setIcon(QPixmap(const_cast<const char**>(chart_xpm)));
103
virtual void customSetup(int toolid)
105
toMainWidget()->editMenu()->insertItem(QPixmap(const_cast<const char**>(chart_xpm)),
106
qApp->translate("toChartTool", "Chart Manager..."), toolid);
108
Handler = new toChartHandler();
110
void closeWindow(void)
114
void closeHandler(void)
119
toChartHandler *handler()
123
toChartManager *manager()
128
virtual bool canHandle(toConnection &)
134
static toChartTool ChartTool;
136
class toChartAlarm : public toChartAlarmUI
139
toChartAlarm(QWidget *parent = 0, const char *name = 0, bool modal = FALSE, WFlags fl = 0)
140
: toChartAlarmUI(parent, name, modal, fl)
142
virtual void changeValue(int val)
145
ExtraLabel->setText(qApp->translate("toChartAlarm", "Email"));
147
ExtraLabel->setText(QString::null);
149
Extra->setEnabled(val == 1);
153
class toChartSetup : public toChartSetupUI
157
toChartSetup(toLineChart *chart, QWidget* parent, const char* name, bool modal)
158
: toChartSetupUI(parent, name, modal)
163
virtual void browseFile()
165
QString str = toOpenFilename(Filename->text(), QString::fromLatin1("*.csv"), this);
167
Filename->setText(str);
169
virtual QString modifyAlarm(const QString &str, bool &persistent)
171
toChartManager::chartAlarm alarm(str, persistent);
172
toChartAlarm diag(this, NULL, true);
173
diag.Operation->setCurrentItem((int)alarm.Operation);
174
diag.Comparison->setCurrentItem((int)alarm.Comparison);
175
diag.Action->setCurrentItem((int)alarm.Action);
176
diag.Value->setText(QString::number(alarm.Value));
177
diag.changeValue((int)alarm.Action);
178
diag.Value->setValidator(new QDoubleValidator(diag.Value));
179
diag.Extra->setText(alarm.Extra);
180
std::list<int>::iterator sel = alarm.Columns.begin();
181
diag.Charts->addColumn(qApp->translate("toChartSetup", "Charts"));
182
diag.Charts->setSelectionMode(QListView::Multi);
183
QListViewItem *item = NULL;
184
std::list<QString>::iterator lab = Chart->labels().begin();
185
for (int i = 0;lab != Chart->labels().end();i++, lab++)
187
item = new QListViewItem(diag.Charts, item, *lab);
188
if (sel != alarm.Columns.end() && *sel == i)
190
item->setSelected(true);
194
diag.Persistent->setChecked(persistent);
197
persistent = diag.Persistent->isChecked();
199
alarm.Columns.clear();
200
for (QListViewItem *item = diag.Charts->firstChild();item;item = item->nextSibling())
202
if (item->isSelected())
203
alarm.Columns.insert(alarm.Columns.end(), i);
206
alarm.Action = (toChartManager::action)diag.Action->currentItem();
207
alarm.Operation = (toChartManager::chartAlarm::operation)diag.Operation->currentItem();
208
alarm.Comparison = (toChartManager::chartAlarm::comparison)diag.Comparison->currentItem();
209
alarm.Value = diag.Value->text().toDouble();
210
alarm.Extra = diag.Extra->text();
211
return alarm.toString();
213
return QString::null;
215
virtual void addAlarm()
217
toChartManager::chartAlarm alarm;
218
QString str = modifyAlarm(alarm.toString(), alarm.Persistent);
220
new QListViewItem(Alarms, str, alarm.Persistent ? qApp->translate("toChartSetup", "Persistent") : qApp->translate("toChartSetup", "Temporary"));
222
virtual void modifyAlarm()
224
QListViewItem *item = Alarms->selectedItem();
227
bool pers = item->text(1) == qApp->translate("toChartSetup", "Persistent");
228
QString str = modifyAlarm(item->text(0), pers);
231
item->setText(0, str);
232
item->setText(1, pers ? qApp->translate("toChartSetup", "Persistent") : qApp->translate("toChartSetup", "Temporary"));
236
virtual void removeAlarm()
238
delete Alarms->selectedItem();
242
toChartReceiver::toChartReceiver(toChartHandler *parent, toLineChart *chart)
248
connect(Chart, SIGNAL(valueAdded(std::list<double> &, const QString &)),
249
this, SLOT(valueAdded(std::list<double> &, const QString &)));
252
toResult *toChartReceiver::result(void)
255
Result = dynamic_cast<toResult *>(Chart);
259
QString toChartReceiver::name(void)
261
if (!Result || Result->sqlName().isEmpty())
262
return QString::null;
265
LastName = Result->connection().description(false) + QString::fromLatin1(":") + QString::fromLatin1(Result->sqlName());
272
void toChartReceiver::valueAdded(std::list<double> &value, const QString &xValues)
274
Parent->valueAdded(Chart, name(), value, xValues);
277
toChartManager::toChartManager(QWidget *main)
278
: QVBox(main), toHelpContext(QString::fromLatin1("chartmanager.html"))
280
QToolBar *toolbar = toAllocBar(this, tr("Chart Manager"));
282
new QToolButton(QPixmap(const_cast<const char**>(refresh_xpm)),
285
this, SLOT(refresh()),
287
toolbar->addSeparator();
288
new QToolButton(QPixmap(const_cast<const char**>(fileopen_xpm)),
289
tr("Open tracker file"),
290
tr("Open tracker file"),
291
this, SLOT(openChart()),
293
new QToolButton(QPixmap(const_cast<const char**>(chart_xpm)),
296
this, SLOT(setupChart()),
299
toolbar->setStretchableWidget(new QLabel(toolbar, TO_KDE_TOOLBAR_WIDGET));
301
List = new toListView(this);
302
List->addColumn(tr("Connection"));
303
List->addColumn(tr("Title"));
304
List->addColumn(tr("ID"));
305
List->addColumn(tr("Tracking"));
306
List->addColumn(tr("Alarms"));
308
List->setSelectionMode(QListView::Single);
311
connect(toMainWidget()->workspace(), SIGNAL(windowActivated(QWidget *)),
312
this, SLOT(windowActivated(QWidget *)));
313
connect(&Refresh, SIGNAL(timeout()), this, SLOT(refresh()));
318
void toChartManager::windowActivated(QWidget *widget)
324
ToolMenu = new QPopupMenu(this);
325
ToolMenu->insertItem(QPixmap(const_cast<const char**>(refresh_xpm)), tr("&Refresh"),
326
this, SLOT(refresh(void)),
327
toKeySequence(tr("F5", "Chart Manager|Refresh")));
329
toMainWidget()->menuBar()->insertItem(tr("&Chart Manager"), ToolMenu, -1, toToolMenuIndex());
339
toChartManager::~toChartManager()
341
ChartTool.closeWindow();
344
void toChartHandler::addChart(toLineChart *chart)
346
Charts.insert(Charts.end(), new toChartReceiver(this, chart));
347
toChartManager *manager = ChartTool.manager();
349
manager->Refresh.start(1, true);
352
void toChartHandler::removeChart(toLineChart *chart)
354
for (std::list<toChartReceiver *>::iterator i = Charts.begin();i != Charts.end();i++)
356
if ((*i)->chart() == chart)
358
QString name = (*i)->name();
361
std::map<QString, std::list<toChartManager::chartAlarm> >::iterator fnda = Alarms.find(name);
362
if (fnda != Alarms.end())
365
for (std::list<toChartManager::chartAlarm>::iterator j = (*fnda).second.begin();j != (*fnda).second.end();)
367
if (!(*j).Persistent)
369
(*fnda).second.erase(j);
370
j = (*fnda).second.begin();
382
std::map<QString, toChartManager::chartTrack>::iterator fndt = Files.find(name);
383
if (fndt != Files.end())
385
if (!(*fndt).second.Persistent)
392
toChartManager *manager = ChartTool.manager();
394
manager->Refresh.start(1, true);
400
toChartManager::alarmSignal::alarmSignal(void)
405
toChartManager::chartAlarm::chartAlarm(const QString &inp, bool pers)
415
// The \01 is just one character unlikely to be in an email address
416
int ret = sscanf(inp.utf8(), "%s %s %s %lf %s %[^\01]", oper, cols, comp, &Value, act, extra);
417
if (ret != 5 && ret != 6)
426
QString t = QString::fromLatin1(oper);
427
if (t == QString::fromLatin1("min"))
429
else if (t == QString::fromLatin1("all"))
431
else if (t == QString::fromLatin1("sum"))
433
else if (t == QString::fromLatin1("average"))
435
else if (t == QString::fromLatin1("max"))
440
t = QString::fromUtf8(cols);
443
QStringList lst = QStringList::split(QString::fromLatin1(","), t.mid(1, t.length() - 2));
444
for (unsigned int i = 0;i < lst.count();i++)
445
Columns.insert(Columns.end(), lst[i].toInt());
449
t = QString::fromLatin1(comp);
450
if (t == QString::fromLatin1("="))
454
else if (t == QString::fromLatin1("!="))
456
Comparison = NotEqual;
458
else if (t == QString::fromLatin1("<"))
462
else if (t == QString::fromLatin1(">"))
464
Comparison = Greater;
466
else if (t == QString::fromLatin1("<="))
468
Comparison = LessEqual;
470
else if (t == QString::fromLatin1(">="))
472
Comparison = GreaterEqual;
479
t = QString::fromLatin1(act);
480
if (t == QString::fromLatin1("StatusMessage"))
481
Action = StatusMessage;
482
else if (t == QString::fromLatin1("Email"))
487
Extra = QString::fromUtf8(extra);
490
toChartManager::chartAlarm::chartAlarm()
495
Action = StatusMessage;
500
toChartManager::chartAlarm::chartAlarm(operation oper, comparison comp, action act,
501
double value, std::list<int> &cols, const QString &extra,
510
Persistent = persistent;
514
QString toChartManager::chartAlarm::toString(void)
520
t = QString::fromLatin1("any");
523
t = QString::fromLatin1("all");
526
t = QString::fromLatin1("sum");
529
t = QString::fromLatin1("average");
532
t = QString::fromLatin1("max");
535
t = QString::fromLatin1("min");
538
t += QString::fromLatin1(" (");
540
for (std::list<int>::iterator i = Columns.begin();i != Columns.end();i++)
545
t += QString::fromLatin1(",");
546
t += QString::number(*i);
548
t += QString::fromLatin1(")");
552
t += QString::fromLatin1(" = ");
555
t += QString::fromLatin1(" != ");
558
t += QString::fromLatin1(" < ");
561
t += QString::fromLatin1(" > ");
564
t += QString::fromLatin1(" <= ");
567
t += QString::fromLatin1(" >= ");
570
t += QString::number(Value);
574
t += QString::fromLatin1(" StatusMessage");
577
t += QString::fromLatin1(" Email");
580
t += QString::fromLatin1(" Ignore");
583
if (!Extra.isEmpty())
585
t += QString::fromLatin1(" ");
591
bool toChartManager::chartAlarm::checkValue(double val)
611
void toChartManager::chartAlarm::valueAdded(toChartHandler *handler,
613
std::list<double> &value,
614
const QString &xValue)
616
std::list<double> vals;
617
std::list<double>::iterator i = value.begin();
618
std::list<int>::iterator j = Columns.begin();
619
for (int id = 0;j != Columns.end() && i != value.end();i++, id++)
623
vals.insert(vals.end(), *i);
632
for (std::list<double>::iterator i = vals.begin();i != vals.end();i++)
643
for (std::list<double>::iterator i = vals.begin();i != vals.end();i++)
654
for (std::list<double>::iterator i = vals.begin();i != vals.end();i++)
656
sig = checkValue(val);
662
for (std::list<double>::iterator i = vals.begin();i != vals.end();i++)
664
sig = checkValue(val / vals.size());
671
for (std::list<double>::iterator i = vals.begin();i != vals.end();i++)
679
val = std::max(*i, val);
681
sig = checkValue(val);
688
for (std::list<double>::iterator i = vals.begin();i != vals.end();i++)
696
val = std::min(*i, val);
698
sig = checkValue(val);
706
handler->SignalAlarms.insert(handler->SignalAlarms.end(),
707
alarmSignal(Action, xValue, str, toString(), Extra));
708
handler->Timer.start(1, true);
715
void toChartHandler::saveSettings(void)
719
for (std::map<QString, toChartManager::chartTrack>::iterator i = Files.begin();i != Files.end();i++)
721
if ((*i).second.Persistent)
724
QCString name = QCString("Files:") + QString::number(num).latin1();
725
ChartTool.setConfig(name + ":Name", (*i).first);
726
ChartTool.setConfig(name + ":Spec", (*i).second.File.name());
729
ChartTool.setConfig("FilesCount", QString::number(num));
733
for (std::map<QString, std::list<toChartManager::chartAlarm> >::iterator i = Alarms.begin();
734
i != Alarms.end();i++)
736
for (std::list<toChartManager::chartAlarm>::iterator j = (*i).second.begin();j != (*i).second.end();j++)
741
QCString name = QCString("Alarms:") + QString::number(num).latin1();
742
ChartTool.setConfig(name + ":Name", (*i).first);
743
ChartTool.setConfig(name + ":Spec", (*j).toString());
747
ChartTool.setConfig("AlarmCount", QString::number(num));
749
toTool::saveConfig();
752
void toChartHandler::loadSettings(void)
755
for (int num = ChartTool.config("FilesCount", "0").toInt();num > 0;num--)
757
QCString name = QCString("Files:") + QString::number(num).latin1();
758
QString t = ChartTool.config(name + ":Name", "");
759
QString s = ChartTool.config(name + ":Spec", "");
760
if (!t.isEmpty() && !s.isEmpty())
761
Files[t] = toChartManager::chartTrack(s, true);
765
for (int num = ChartTool.config("AlarmCount", "0").toInt();num > 0;num--)
767
QCString name = QCString("Alarms:") + QString::number(num).latin1();
768
QString t = ChartTool.config(name + ":Name", "");
769
QString s = ChartTool.config(name + ":Spec", "");
770
if (!t.isEmpty() && !s.isEmpty())
771
Alarms[t].insert(Alarms[t].end(), toChartManager::chartAlarm(s, true));
776
void toChartHandler::alarm(void)
778
while (!SignalAlarms.empty())
780
toChartManager::alarmSignal signal = toShift(SignalAlarms);
781
if (signal.Action == toChartManager::StatusMessage)
782
toStatusMessage(tr("ALARM:") + signal.Chart + QString::fromLatin1(": ") + signal.Alarm + QString::fromLatin1(": ") + signal.xValue);
783
else if (signal.Action == toChartManager::Email)
784
new toSMTP(QString::fromLatin1(TOAPPNAME " <noreply@localhost>"),
786
tr("TOra alert:") + " " + signal.Chart,
787
tr("A defined alert value was detected:\n\n%1\n\nAt: %2").arg(signal.Alarm).arg(signal.xValue));
791
void toChartHandler::valueAdded(toLineChart *chart,
792
const QString &chartName,
793
std::list<double> &value,
794
const QString &xValue)
796
std::map<QString, std::list<toChartManager::chartAlarm> >::iterator fnda = Alarms.find(chartName);
797
if (fnda != Alarms.end())
799
std::list<toChartManager::chartAlarm> &alarms = (*fnda).second;
800
for (std::list<toChartManager::chartAlarm>::iterator i = alarms.begin();i != alarms.end();i++)
801
(*i).valueAdded(this, chartName, value, xValue);
804
std::map<QString, toChartManager::chartTrack>::iterator fndt = Files.find(chartName);
805
if (fndt != Files.end())
807
QFile &file = (*fndt).second.File;
813
file.open(IO_Raw | IO_WriteOnly | IO_Append);
817
static QRegExp quote(QString::fromLatin1("\""));
821
QString t = chart->title();
822
t.replace(quote, QString::fromLatin1("\"\""));
824
std::list<QString> labels = chart->labels();
825
for (std::list<QString>::iterator i = labels.begin();i != labels.end();i++)
829
t.replace(quote, QString::fromLatin1("\"\""));
835
t.replace(quote, QString::fromLatin1("\"\""));
837
for (std::list<double>::iterator i = value.begin();i != value.end();i++)
840
out += QString::number(*i);
843
file.writeBlock(out, out.length());
848
static QString ReadCSV(const QCString &data, unsigned int &pos, bool &nl)
851
if (data.at(pos) != '\"')
852
throw qApp->translate("toChartManager", "Initial value didn't start with \" in CSV file");
854
while (pos < data.length() &&
855
(data.at(pos) != '\"' || (pos + 1 < data.length() &&
856
data.at(pos + 1) == '\"')))
859
if (data.at(pos) == '\"')
863
if (pos >= data.length())
864
throw qApp->translate("toChartManager", "Missing closing \" in CSV file");
867
while (pos < data.length() && (isspace(data.at(pos)) || data.at(pos) == ',' || data.at(pos) == ';'))
869
if (data.at(pos) == '\n')
873
return QString::fromUtf8(ret);
876
void toChartManager::openChart(void)
878
QString name = toOpenFilename(QString::null, QString::fromLatin1("*.csv"), this);
883
QCString data = toReadFile(name);
884
unsigned int pos = 0;
887
switch (TOMessageBox::information(toMainWidget(),
889
tr("Select format of the chart to display"),
895
chart = new toBarChart(toMainWidget()->workspace(), NULL,
899
chart = new toLineChart(toMainWidget()->workspace(), NULL,
906
chart->setSamples( -1);
908
chart->setTitle(ReadCSV(data, pos, eol));
909
std::list<QString> lab;
910
while (!eol && pos < data.length())
911
lab.insert(lab.end(), ReadCSV(data, pos, eol));
912
chart->setLabels(lab);
913
while (pos < data.length())
915
QString t = ReadCSV(data, pos, eol);
916
std::list<double> val;
917
while (!eol && pos < data.length())
918
val.insert(val.end(), ReadCSV(data, pos, eol).toDouble());
919
chart->addValues(val, t);
926
void toChartManager::setupChart(void)
928
toChartReceiver *chart = selectedChart();
929
if (chart && ChartTool.handler())
930
ChartTool.handler()->setupChart(chart->chart());
933
toChartReceiver *toChartManager::selectedChart(void)
937
QListViewItem *item = List->selectedItem();
938
if (item && ChartTool.handler())
940
for (std::list<toChartReceiver *>::iterator i = ChartTool.handler()->Charts.begin();i != ChartTool.handler()->Charts.end();i++)
942
toResult *result = (*i)->result();
945
if (item->text(0) == result->connection().description(false) &&
946
item->text(2) == result->sqlName())
956
void toChartHandler::setupChart(toLineChart *chart)
958
for (std::list<toChartReceiver *>::iterator i = Charts.begin();i != Charts.end();i++)
960
if ((*i)->chart() == chart)
962
QString name = (*i)->name();
965
std::list<toChartManager::chartAlarm> alarm;
966
std::map<QString, std::list<toChartManager::chartAlarm> >::iterator fnda = Alarms.find(name);
967
if (fnda != Alarms.end())
968
alarm = (*fnda).second;
970
toChartManager::chartTrack file;
971
std::map<QString, toChartManager::chartTrack>::iterator fndt = Files.find(name);
972
if (fndt != Files.end())
973
file = (*fndt).second;
975
toChartSetup setup(chart, toMainWidget(), NULL, true);
976
setup.Alarms->addColumn(tr("Alarms"));
977
setup.Alarms->addColumn(tr("Persistent"));
978
setup.Alarms->setSorting(0);
979
setup.Alarms->setSelectionMode(QListView::Single);
980
setup.Persistent->setChecked(file.Persistent);
981
setup.Filename->setText(file.File.name());
982
if (!setup.Filename->text().isEmpty())
983
setup.Enabled->setChecked(true);
984
setup.ChartFrame->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,
985
QSizePolicy::Preferred));
987
toLineChart *t = chart->openCopy(setup.ChartFrame);
988
t->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,
989
QSizePolicy::Preferred));
990
t->showLegend(false);
991
t->showAxisLegend(false);
992
for (std::list<toChartManager::chartAlarm>::iterator j = alarm.begin();j != alarm.end();j++)
993
new QListViewItem(setup.Alarms,
995
(*j).Persistent ? tr("Persistent") : tr("Temporary"));
999
if (setup.Filename->text().isEmpty() || !setup.Enabled->isChecked())
1001
if (fndt != Files.end())
1006
Files[name] = toChartManager::chartTrack(setup.Filename->text(),
1007
setup.Persistent->isChecked());
1009
if (fnda != Alarms.end())
1012
for (QListViewItem *item = setup.Alarms->firstChild();
1013
item;item = item->nextSibling())
1015
alarm.insert(alarm.end(), toChartManager::chartAlarm(item->text(0),
1016
item->text(1) == tr("Persistent")));
1019
Alarms[name] = alarm;
1028
void toChartManager::refresh(void)
1030
if (!ChartTool.handler())
1035
for (std::list<toChartReceiver *>::iterator i = ChartTool.handler()->Charts.begin();i != ChartTool.handler()->Charts.end();i++)
1037
toResult *result = (*i)->result();
1040
toResultViewItem *item = new toResultViewMLine(List,
1042
result->connection().description(false));
1043
item->setText(1, (*i)->chart()->title());
1044
item->setText(2, result->sqlName());
1045
QString name = (*i)->name();
1048
std::map<QString, std::list<chartAlarm> >::iterator fnda = ChartTool.handler()->Alarms.find(name);
1049
if (fnda != ChartTool.handler()->Alarms.end())
1052
for (std::list<chartAlarm>::iterator j = (*fnda).second.begin();j != (*fnda).second.end();j++)
1054
t += (*j).toString();
1055
t += QString::fromLatin1("\n");
1058
item->setText(4, t.mid(0, t.length() - 1));
1061
std::map<QString, chartTrack>::iterator fndt = ChartTool.handler()->Files.find(name);
1062
if (fndt != ChartTool.handler()->Files.end())
1063
item->setText(3, (*fndt).second.File.name());
1071
toChartHandler::toChartHandler()
1073
connect(toMainWidget(), SIGNAL(chartAdded(toLineChart *)),
1074
this, SLOT(addChart(toLineChart *)));
1075
connect(toMainWidget(), SIGNAL(chartRemoved(toLineChart *)),
1076
this, SLOT(removeChart(toLineChart *)));
1077
connect(toMainWidget(), SIGNAL(chartSetup(toLineChart *)),
1078
this, SLOT(setupChart(toLineChart *)));
1079
connect(&Timer, SIGNAL(timeout()), this, SLOT(alarm()));
1082
toChartHandler::~toChartHandler()
1084
ChartTool.closeHandler();