~ubuntu-branches/ubuntu/wily/tora/wily-proposed

« back to all changes in this revision

Viewing changes to src/toworksheet.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Albin Tonnerre
  • Date: 2007-05-29 13:13:36 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070529131336-85ygaddivvmkd3xc
Tags: 1.3.21pre22-1ubuntu1
* Merge from Debian unstable. Remaining Ubuntu changes:
  - debian/rules: call dh_iconcache
  - Remove g++ build dependency
* Modify Maintainer value to match Debian-Maintainer-Field Spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****
 
2
*
 
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
 
6
 
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.
 
11
 
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.
 
16
 
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.
 
20
*
 
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.
 
25
*
 
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.
 
31
*
 
32
*      You may link this product with any GPL'd Qt library such as Qt/Free
 
33
*
 
34
* All trademarks belong to their respective owners.
 
35
*
 
36
*****/
 
37
 
 
38
#include "utils.h"
 
39
 
 
40
#include "tochangeconnection.h"
 
41
#include "toconf.h"
 
42
#include "tohighlightedtext.h"
 
43
#include "tomain.h"
 
44
#include "toparamget.h"
 
45
#include "toresultbar.h"
 
46
#include "toresultcols.h"
 
47
#include "toresultcombo.h"
 
48
#include "toresultlong.h"
 
49
#include "toresultplan.h"
 
50
#include "toresultresources.h"
 
51
#include "toresultstats.h"
 
52
#include "toresultview.h"
 
53
#include "tosession.h"
 
54
#include "tosgatrace.h"
 
55
#include "totabwidget.h"
 
56
#include "totool.h"
 
57
#include "totabwidget.h"
 
58
#include "tovisualize.h"
 
59
#include "toworksheet.h"
 
60
#include "toworksheetsetupui.h"
 
61
#include "toworksheetstatistic.h"
 
62
 
 
63
#ifdef TO_KDE
 
64
#include <kfiledialog.h>
 
65
#include <kmenubar.h>
 
66
#endif
 
67
 
 
68
#include <qaccel.h>
 
69
#include <qcheckbox.h>
 
70
#include <qcheckbox.h>
 
71
#include <qcombobox.h>
 
72
#include <qfiledialog.h>
 
73
#include <qfileinfo.h>
 
74
#include <qgrid.h>
 
75
#include <qgroupbox.h>
 
76
#include <qheader.h>
 
77
#include <qinputdialog.h>
 
78
#include <qlabel.h>
 
79
#include <qlineedit.h>
 
80
#include <qlistview.h>
 
81
#include <qmenubar.h>
 
82
#include <qmessagebox.h>
 
83
#include <qmultilineedit.h>
 
84
#include <qnamespace.h>
 
85
#include <qpixmap.h>
 
86
#include <qprogressdialog.h>
 
87
#include <qpushbutton.h>
 
88
#include <qregexp.h>
 
89
#include <qsplitter.h>
 
90
#include <qtabwidget.h>
 
91
#include <qtoolbar.h>
 
92
#include <qtoolbutton.h>
 
93
#include <qtooltip.h>
 
94
#include <qworkspace.h>
 
95
 
 
96
#include "toworksheet.moc"
 
97
#include "toworksheetsetupui.moc"
 
98
 
 
99
#include "icons/clock.xpm"
 
100
#include "icons/recall.xpm"
 
101
#include "icons/describe.xpm"
 
102
#include "icons/eraselog.xpm"
 
103
#include "icons/execute.xpm"
 
104
#include "icons/executeall.xpm"
 
105
#include "icons/executestep.xpm"
 
106
#include "icons/explainplan.xpm"
 
107
#include "icons/filesave.xpm"
 
108
#include "icons/insertsaved.xpm"
 
109
#include "icons/previous.xpm"
 
110
#include "icons/refresh.xpm"
 
111
#include "icons/stop.xpm"
 
112
#include "icons/toworksheet.xpm"
 
113
#include "icons/up.xpm"
 
114
#include "icons/down.xpm"
 
115
 
 
116
#ifdef TO_KDE_KACCELMANAGER
 
117
#  include <kaccelmanager.h>
 
118
#endif
 
119
 
 
120
#define TO_ID_STATISTICS  (toMain::TO_TOOL_MENU_ID+ 0)
 
121
#define TO_ID_STOP   (toMain::TO_TOOL_MENU_ID+ 1)
 
122
#define TO_ID_PLAN   (toMain::TO_TOOL_MENU_ID+ 2)
 
123
 
 
124
#define CONF_AUTO_SAVE    "AutoSave"
 
125
#define CONF_CHECK_SAVE   "CheckSave"
 
126
#define CONF_AUTO_LOAD    "AutoLoad"
 
127
#define CONF_LOG_AT_END   "LogAtEnd"
 
128
#define CONF_LOG_MULTI    "LogMulti"
 
129
#define CONF_STATISTICS   "Statistics"
 
130
#define CONF_TIMED_STATS  "TimedStats"
 
131
#define CONF_NUMBER   "Number"
 
132
#define CONF_MOVE_TO_ERR  "MoveToError"
 
133
#define CONF_HISTORY   "History"
 
134
#define CONF_EXEC_LOG     "ExecLog"
 
135
#define CONF_TOPLEVEL_DESCRIBE "ToplevelDescribe"
 
136
 
 
137
class toWorksheetSetup : public toWorksheetSetupUI, public toSettingTab
 
138
{
 
139
    toTool *Tool;
 
140
 
 
141
public:
 
142
    toWorksheetSetup(toTool *tool, QWidget* parent = 0, const char* name = 0)
 
143
            : toWorksheetSetupUI(parent, name), toSettingTab("worksheet.html#preferences"), Tool(tool)
 
144
    {
 
145
        if (!tool->config(CONF_AUTO_SAVE, "").isEmpty())
 
146
            AutoSave->setChecked(true);
 
147
        if (!tool->config(CONF_CHECK_SAVE, "Yes").isEmpty())
 
148
            CheckSave->setChecked(true);
 
149
        if (!tool->config(CONF_LOG_AT_END, "Yes").isEmpty())
 
150
            LogAtEnd->setChecked(true);
 
151
        if (!tool->config(CONF_LOG_MULTI, "Yes").isEmpty())
 
152
            LogMulti->setChecked(true);
 
153
        MoveToError->setChecked(!tool->config(CONF_MOVE_TO_ERR, "Yes").isEmpty());
 
154
        if (!tool->config(CONF_STATISTICS, "").isEmpty())
 
155
            Statistics->setChecked(true);
 
156
        TimedStatistics->setChecked(!tool->config(CONF_TIMED_STATS, "Yes").isEmpty());
 
157
        History->setChecked(!tool->config(CONF_HISTORY, "").isEmpty());
 
158
        if (!tool->config(CONF_NUMBER, "Yes").isEmpty())
 
159
            DisplayNumber->setChecked(true);
 
160
        if (!tool->config(CONF_TOPLEVEL_DESCRIBE, "Yes").isEmpty())
 
161
            ToplevelDescribe->setChecked(true);
 
162
        DefaultFile->setText(tool->config(CONF_AUTO_LOAD, ""));
 
163
        ExecLog->setChecked(!tool->config(CONF_EXEC_LOG, "").isEmpty());
 
164
#ifdef TO_NO_ORACLE
 
165
 
 
166
        TimedStatistics->hide();
 
167
        MoveToError->hide();
 
168
        Statistics->hide();
 
169
#endif
 
170
 
 
171
    }
 
172
    virtual void saveSetting(void)
 
173
    {
 
174
        if (AutoSave->isChecked())
 
175
            Tool->setConfig(CONF_AUTO_SAVE, "Yes");
 
176
        else
 
177
            Tool->setConfig(CONF_AUTO_SAVE, "");
 
178
        if (CheckSave->isChecked())
 
179
            Tool->setConfig(CONF_CHECK_SAVE, "Yes");
 
180
        else
 
181
            Tool->setConfig(CONF_CHECK_SAVE, "");
 
182
        if (LogAtEnd->isChecked())
 
183
            Tool->setConfig(CONF_LOG_AT_END, "Yes");
 
184
        else
 
185
            Tool->setConfig(CONF_LOG_AT_END, "");
 
186
        if (LogMulti->isChecked())
 
187
            Tool->setConfig(CONF_LOG_MULTI, "Yes");
 
188
        else
 
189
            Tool->setConfig(CONF_LOG_MULTI, "");
 
190
        Tool->setConfig(CONF_TOPLEVEL_DESCRIBE, ToplevelDescribe->isChecked() ? "Yes" : "");
 
191
        Tool->setConfig(CONF_MOVE_TO_ERR, MoveToError->isChecked() ? "Yes" : "");
 
192
        Tool->setConfig(CONF_STATISTICS, Statistics->isChecked() ? "Yes" : "");
 
193
        Tool->setConfig(CONF_HISTORY, History->isChecked() ? "Yes" : "");
 
194
        Tool->setConfig(CONF_TIMED_STATS, TimedStatistics->isChecked() ? "Yes" : "");
 
195
        Tool->setConfig(CONF_NUMBER, DisplayNumber->isChecked() ? "Yes" : "");
 
196
        Tool->setConfig(CONF_EXEC_LOG, ExecLog->isChecked() ? "Yes" : "");
 
197
        Tool->setConfig(CONF_AUTO_LOAD, DefaultFile->text());
 
198
    }
 
199
public slots:
 
200
    void chooseFile(void)
 
201
    {
 
202
        QString str = toOpenFilename(DefaultFile->text(), QString::null, this);
 
203
        if (!str.isEmpty())
 
204
            DefaultFile->setText(str);
 
205
    }
 
206
};
 
207
 
 
208
class toWorksheetTool : public toTool
 
209
{
 
210
protected:
 
211
    virtual const char **pictureXPM(void)
 
212
    {
 
213
        return const_cast<const char**>(toworksheet_xpm);
 
214
    }
 
215
public:
 
216
    toWorksheetTool()
 
217
            : toTool(10, "SQL Editor")
 
218
    { }
 
219
    virtual const char *menuItem()
 
220
    {
 
221
        return "SQL Editor";
 
222
    }
 
223
    virtual QWidget *toolWindow(QWidget *main, toConnection &connection)
 
224
    {
 
225
        return new toWorksheet(main, connection);
 
226
    }
 
227
    virtual QWidget *configurationTab(QWidget *parent)
 
228
    {
 
229
        return new toWorksheetSetup(this, parent);
 
230
    }
 
231
    virtual bool canHandle(toConnection &)
 
232
    {
 
233
        return true;
 
234
    }
 
235
    virtual void closeWindow(toConnection &connection){};
 
236
};
 
237
 
 
238
static toWorksheetTool WorksheetTool;
 
239
 
 
240
class toWorksheetText : public toHighlightedText
 
241
{
 
242
    toWorksheet *Worksheet;
 
243
public:
 
244
    toWorksheetText(toWorksheet *worksheet, QWidget *parent, const char *name = NULL)
 
245
            : toHighlightedText(parent, name), Worksheet(worksheet)
 
246
    { }
 
247
    /** Reimplemented for internal reasons.
 
248
     */
 
249
    virtual void keyPressEvent(QKeyEvent *e)
 
250
    {
 
251
        if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "Ctrl+Return", "Worksheet|Execute current"))))
 
252
        {
 
253
            Worksheet->execute();
 
254
            e->accept();
 
255
        }
 
256
        else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "F8", "Worksheet|Execute all"))))
 
257
        {
 
258
            Worksheet->executeAll();
 
259
            e->accept();
 
260
        }
 
261
        else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "F9", "Worksheet|Execute next"))))
 
262
        {
 
263
            Worksheet->executeStep();
 
264
            e->accept();
 
265
        }
 
266
        else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "Shift+F9", "Worksheet|Execute newline separated"))))
 
267
        {
 
268
            Worksheet->executeNewline();
 
269
            e->accept();
 
270
        }
 
271
        else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "F7", "Worksheet|Execute saved SQL"))))
 
272
        {
 
273
            Worksheet->executeSaved();
 
274
            e->accept();
 
275
        }
 
276
        else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "Shift+F7", "Worksheet|Insert saved SQL"))))
 
277
        {
 
278
            Worksheet->insertSaved();
 
279
            e->accept();
 
280
        }
 
281
        else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "F4", "Worksheet|Describe under cursor"))))
 
282
        {
 
283
            Worksheet->describe();
 
284
            e->accept();
 
285
        }
 
286
        else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "Alt+Up", "Worksheet|Previous log entry"))))
 
287
        {
 
288
            Worksheet->executePreviousLog();
 
289
            e->accept();
 
290
        }
 
291
        else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "Alt+Down", "Worksheet|Next log entry"))))
 
292
        {
 
293
            Worksheet->executeNextLog();
 
294
            e->accept();
 
295
        }
 
296
        else
 
297
        {
 
298
            toHighlightedText::keyPressEvent(e);
 
299
        }
 
300
    }
 
301
    virtual bool editSave(bool askfile)
 
302
    {
 
303
        bool ret = toHighlightedText::editSave(askfile);
 
304
        Worksheet->setCaption();
 
305
        return ret;
 
306
    }
 
307
    virtual bool editOpen(QString suggestedFile)
 
308
    {
 
309
        int ret = 1;
 
310
        if (isModified())
 
311
        {
 
312
            ret = TOMessageBox::information(this,
 
313
                                            qApp->translate("toWorksheetText", "Save changes?"),
 
314
                                            qApp->translate("toWorksheetText", "The editor has been changed. Do you want to save them,\n"
 
315
                                                            "discard changes or open file in new worksheet?"),
 
316
                                            qApp->translate("toWorksheetText", "&Save"),
 
317
                                            qApp->translate("toWorksheetText", "&Discard"),
 
318
                                            qApp->translate("toWorksheetText", "&New worksheet"), 0);
 
319
            if (ret < 0)
 
320
                return false;
 
321
            else if (ret == 0)
 
322
            {
 
323
                if (!editSave(false))
 
324
                    return false;
 
325
            }
 
326
        }
 
327
 
 
328
        QString fname;
 
329
        if (suggestedFile != QString::null)
 
330
            fname = suggestedFile;
 
331
        else
 
332
        {
 
333
            QFileInfo file(filename());
 
334
            fname = toOpenFilename(file.dirPath(), QString::null, this);
 
335
        }
 
336
        if (fname.isEmpty())
 
337
            return false;
 
338
        try
 
339
        {
 
340
            if (ret == 2)
 
341
                toWorksheet::fileWorksheet(fname);
 
342
            else
 
343
            {
 
344
                openFilename(fname);
 
345
                Worksheet->setCaption();
 
346
            }
 
347
            return true;
 
348
        }
 
349
        TOCATCH
 
350
 
 
351
        return false;
 
352
    }
 
353
};
 
354
 
 
355
void toWorksheet::viewResources(void)
 
356
{
 
357
    try
 
358
    {
 
359
        QString address = toSQLToAddress(connection(), QueryString);
 
360
 
 
361
        Resources->changeParams(address);
 
362
 
 
363
        QString sql = toSQL::string(TOSQL_LONGOPS, connection());
 
364
        sql += "   AND b.SQL_Address||':'||b.SQL_Hash_Value = :addr<char[100]>";
 
365
        LongOps->setSQL(sql);
 
366
        LongOps->clearParams();
 
367
        LongOps->changeParams(address);
 
368
    }
 
369
    TOCATCH
 
370
}
 
371
 
 
372
#define TOWORKSHEET "toWorksheet:"
 
373
 
 
374
void toWorksheet::setup(bool autoLoad)
 
375
{
 
376
    QToolBar *toolbar = toAllocBar(this, tr("SQL worksheet"));
 
377
 
 
378
    new QToolButton(QPixmap(const_cast<const char**>(execute_xpm)),
 
379
                    tr("Execute current statement"),
 
380
                    tr("Execute current statement"),
 
381
                    this, SLOT(execute(void)),
 
382
                    toolbar);
 
383
    new QToolButton(QPixmap(const_cast<const char**>(executestep_xpm)),
 
384
                    tr("Step through statements"),
 
385
                    tr("Step through statements"),
 
386
                    this, SLOT(executeStep(void)),
 
387
                    toolbar);
 
388
    new QToolButton(QPixmap(const_cast<const char**>(executeall_xpm)),
 
389
                    tr("Execute all statements"),
 
390
                    tr("Execute all statements"),
 
391
                    this, SLOT(executeAll(void)),
 
392
                    toolbar);
 
393
    toolbar->addSeparator();
 
394
    new QToolButton(QPixmap(const_cast<const char**>(refresh_xpm)),
 
395
                    tr("Reexecute Last Statement"),
 
396
                    tr("Reexecute Last Statement"),
 
397
                    this, SLOT(refreshSetup(void)),
 
398
                    toolbar);
 
399
    RefreshSeconds = 60;
 
400
    connect(&RefreshTimer, SIGNAL(timeout()), this, SLOT(refresh()));
 
401
 
 
402
    LastLine = LastOffset = -1;
 
403
    LastID = 0;
 
404
 
 
405
    if (Light)
 
406
    {
 
407
        Editor = new toWorksheetText(this, this);
 
408
#ifdef TO_KDE_KACCELMANAGER
 
409
        KAcceleratorManager::setNoAccel( Editor );
 
410
#endif
 
411
        Current = Result = new toResultLong(this);
 
412
        Result->hide();
 
413
        connect(Result, SIGNAL(done(void)), this, SLOT(queryDone(void)));
 
414
        connect(Result, SIGNAL(firstResult(const QString &, const toConnection::exception &, bool)),
 
415
                this, SLOT(addLog(const QString &, const toConnection::exception &, bool)));
 
416
        ResultTab = NULL;
 
417
        Plan = NULL;
 
418
        CurrentTab = NULL;
 
419
        Resources = NULL;
 
420
        Statistics = NULL;
 
421
        Logging = NULL;
 
422
        LastLogItem = NULL;
 
423
        StatisticButton = NULL;
 
424
        StatTab = NULL;
 
425
        Columns = NULL;
 
426
        Refresh = NULL;
 
427
        ToolMenu = NULL;
 
428
        Visualize = NULL;
 
429
        WaitChart = IOChart = NULL;
 
430
        toolbar->addSeparator();
 
431
        StopButton = new QToolButton(QPixmap(const_cast<const char**>(stop_xpm)),
 
432
                                     tr("Stop execution"),
 
433
                                     tr("Stop execution"),
 
434
                                     Result, SLOT(stop(void)),
 
435
                                     toolbar);
 
436
        StopButton->setEnabled(false);
 
437
        toolbar->setStretchableWidget(Started = new QLabel(toolbar, TO_KDE_TOOLBAR_WIDGET));
 
438
        Started->setAlignment(AlignRight | AlignVCenter | ExpandTabs);
 
439
    }
 
440
    else
 
441
    {
 
442
        QSplitter *splitter = new QSplitter(Vertical, this);
 
443
 
 
444
        Editor = new toWorksheetText(this, splitter);
 
445
#ifdef TO_KDE_KACCELMANAGER
 
446
        KAcceleratorManager::setNoAccel( Editor );
 
447
#endif
 
448
        ResultTab = new toTabWidget(splitter);
 
449
        QVBox *box = new QVBox(ResultTab);
 
450
        ResultTab->addTab(box, tr("&Result"));
 
451
 
 
452
        Current = Result = new toResultLong(box);
 
453
        connect(Result, SIGNAL(done(void)), this, SLOT(queryDone(void)));
 
454
        connect(Result, SIGNAL(firstResult(const QString &, const toConnection::exception &, bool)),
 
455
                this, SLOT(addLog(const QString &, const toConnection::exception &, bool)));
 
456
 
 
457
        bool toplevel = !WorksheetTool.config(CONF_TOPLEVEL_DESCRIBE, "Yes").isEmpty();
 
458
        Columns = new toResultCols(box, "description", toplevel ? WType_TopLevel : 0);
 
459
        Columns->hide();
 
460
 
 
461
        ResultTab->setTabEnabled(Columns, false);
 
462
        Plan = new toResultPlan(ResultTab);
 
463
        ResultTab->addTab(Plan, tr("E&xecution plan"));
 
464
 
 
465
        ResourceSplitter = new QSplitter(Vertical, ResultTab);
 
466
        Resources = new toResultResources(ResourceSplitter);
 
467
 
 
468
        LongOps = new toResultLong(ResourceSplitter);
 
469
 
 
470
        Visualize = new toVisualize(Result, ResultTab);
 
471
        ResultTab->addTab(Visualize, tr("&Visualize"));
 
472
        ResultTab->addTab(ResourceSplitter, tr("&Information"));
 
473
        ResultTab->setTabShown(ResourceSplitter, Resources->handled());
 
474
 
 
475
        StatTab = new QVBox(ResultTab);
 
476
        {
 
477
            QToolBar *stattool = toAllocBar(StatTab, tr("Worksheet Statistics"));
 
478
            new QToolButton(QPixmap(const_cast<const char**>(filesave_xpm)),
 
479
                            tr("Save statistics for later analysis"),
 
480
                            tr("Save statistics for later analysis"),
 
481
                            this, SLOT(saveStatistics(void)),
 
482
                            stattool);
 
483
            stattool->setStretchableWidget(new QLabel(stattool));
 
484
        }
 
485
        splitter = new QSplitter(Horizontal, StatTab);
 
486
        Statistics = new toResultStats(true, splitter);
 
487
        Statistics->setTabWidget(ResultTab);
 
488
        WaitChart = new toResultBar(splitter);
 
489
        try
 
490
        {
 
491
            WaitChart->setSQL(toSQL::sql(TO_SESSION_WAIT));
 
492
        }
 
493
        catch (...)
 
494
        {}
 
495
        WaitChart->setTitle(tr("Wait states"));
 
496
        WaitChart->setYPostfix(QString::fromLatin1("ms/s"));
 
497
        WaitChart->setSamples( -1);
 
498
        WaitChart->start();
 
499
        connect(Statistics, SIGNAL(sessionChanged(const QString &)),
 
500
                WaitChart, SLOT(changeParams(const QString &)));
 
501
        IOChart = new toResultBar(splitter);
 
502
        try
 
503
        {
 
504
            IOChart->setSQL(toSQL::sql(TO_SESSION_IO));
 
505
        }
 
506
        catch (...)
 
507
        {}
 
508
        IOChart->setTitle(tr("I/O"));
 
509
        IOChart->setYPostfix(tr("blocks/s"));
 
510
        IOChart->setSamples( -1);
 
511
        IOChart->start();
 
512
        connect(Statistics, SIGNAL(sessionChanged(const QString &)),
 
513
                IOChart, SLOT(changeParams(const QString &)));
 
514
        ResultTab->addTab(StatTab, tr("&Statistics"));
 
515
        ResultTab->setTabEnabled(StatTab, false);
 
516
 
 
517
        Logging = new toListView(ResultTab);
 
518
        ResultTab->addTab(Logging, tr("&Logging"));
 
519
        Logging->addColumn(tr("SQL"));
 
520
        Logging->addColumn(tr("Result"));
 
521
        Logging->addColumn(tr("Timestamp"));
 
522
        Logging->addColumn(tr("Duration"));
 
523
        Logging->setColumnAlignment(3, AlignRight);
 
524
        Logging->setSelectionMode(QListView::Single);
 
525
        connect(Logging, SIGNAL(selectionChanged(QListViewItem *)), this, SLOT(executeLog()));
 
526
        LastLogItem = NULL;
 
527
 
 
528
        toolbar->addSeparator();
 
529
        new QToolButton(QPixmap(const_cast<const char**>(describe_xpm)),
 
530
                        tr("Describe under cursor"),
 
531
                        tr("Describe under cursor"),
 
532
                        this, SLOT(describe(void)),
 
533
                        toolbar);
 
534
        PlanButton = new QToolButton(QPixmap(const_cast<const char**>(explainplan_xpm)),
 
535
                                     tr("Explain plan of current statement"),
 
536
                                     tr("Explain plan of current statement"),
 
537
                                     this, SLOT(explainPlan(void)),
 
538
                                     toolbar);
 
539
        PlanButton->setEnabled(Plan->handled());
 
540
        StopButton = new QToolButton(QPixmap(const_cast<const char**>(stop_xpm)),
 
541
                                     tr("Stop execution"),
 
542
                                     tr("Stop execution"),
 
543
                                     this, SLOT(stop(void)),
 
544
                                     toolbar);
 
545
        StopButton->setEnabled(false);
 
546
        toolbar->addSeparator();
 
547
        new QToolButton(QPixmap(const_cast<const char**>(eraselog_xpm)),
 
548
                        tr("Clear execution log"),
 
549
                        tr("Clear execution log"),
 
550
                        this, SLOT(eraseLogButton(void)),
 
551
                        toolbar);
 
552
 
 
553
        toolbar->addSeparator();
 
554
        StatisticButton = new QToolButton(toolbar);
 
555
        StatisticButton->setToggleButton(true);
 
556
        StatisticButton->setIconSet(QIconSet(QPixmap(const_cast<const char**>(clock_xpm))));
 
557
        connect(StatisticButton, SIGNAL(toggled(bool)), this, SLOT(enableStatistic(bool)));
 
558
        QToolTip::add
 
559
            (StatisticButton, tr("Gather session statistic of execution"));
 
560
#ifdef TO_NO_ORACLE
 
561
 
 
562
        QLabel *label =
 
563
#endif
 
564
            new QLabel(tr("Refresh") + " ", toolbar, TO_KDE_TOOLBAR_WIDGET);
 
565
        Refresh = toRefreshCreate(toolbar, TO_KDE_TOOLBAR_WIDGET);
 
566
#ifdef TO_NO_ORACLE
 
567
 
 
568
        label->hide();
 
569
        Refresh->hide();
 
570
#else
 
571
 
 
572
        toolbar->addSeparator();
 
573
#endif
 
574
 
 
575
        connect(Refresh, SIGNAL(activated(const QString &)), this, SLOT(changeRefresh(const QString &)));
 
576
        connect(StatisticButton, SIGNAL(toggled(bool)), Refresh, SLOT(setEnabled(bool)));
 
577
        Refresh->setEnabled(false);
 
578
        Refresh->setFocusPolicy(NoFocus);
 
579
 
 
580
        new QToolButton(QPixmap(const_cast<const char**>(up_xpm)),
 
581
                        tr("Previous log entry"),
 
582
                        tr("Previous log entry"),
 
583
                        this, SLOT(executePreviousLog()),
 
584
                        toolbar);
 
585
        new QToolButton(QPixmap(const_cast<const char**>(down_xpm)),
 
586
                        tr("Next log entry"),
 
587
                        tr("Next log entry"),
 
588
                        this, SLOT(executeNextLog()),
 
589
                        toolbar);
 
590
        toolbar->addSeparator();
 
591
 
 
592
        InsertSavedButton = new toPopupButton(QPixmap(const_cast<const char**>(insertsaved_xpm)),
 
593
                                              tr("Insert current saved SQL"),
 
594
                                              tr("Insert current saved SQL"),
 
595
                                              toolbar);
 
596
        InsertSavedMenu = new QPopupMenu(InsertSavedButton);
 
597
        InsertSavedButton->setPopup(InsertSavedMenu);
 
598
        connect(InsertSavedMenu, SIGNAL(aboutToShow()), this, SLOT(showInsertSaved()));
 
599
        connect(InsertSavedMenu, SIGNAL(activated(int)), this, SLOT(insertSaved(int)));
 
600
 
 
601
        SavedButton = new toPopupButton(QPixmap(const_cast<const char**>(recall_xpm)),
 
602
                                        tr("Run current saved SQL"),
 
603
                                        tr("Run current saved SQL"),
 
604
                                        toolbar);
 
605
        SavedMenu = new QPopupMenu(SavedButton);
 
606
        SavedButton->setPopup(SavedMenu);
 
607
        connect(SavedMenu, SIGNAL(aboutToShow()), this, SLOT(showSaved()));
 
608
        connect(SavedMenu, SIGNAL(activated(int)), this, SLOT(executeSaved(int)));
 
609
 
 
610
        new QToolButton(QPixmap(const_cast<const char**>(previous_xpm)),
 
611
                        tr("Save last SQL"),
 
612
                        tr("Save last SQL"),
 
613
                        this, SLOT(saveLast(void)),
 
614
                        toolbar);
 
615
 
 
616
        toolbar->setStretchableWidget(Started = new QLabel(toolbar, TO_KDE_TOOLBAR_WIDGET));
 
617
        Started->setAlignment(AlignRight | AlignVCenter | ExpandTabs);
 
618
 
 
619
        Schema = new toResultCombo(toolbar);
 
620
        Schema->setSQL(toSQL::sql(toSQL::TOSQL_USERLIST));
 
621
        if (toIsMySQL(connection()))
 
622
            Schema->setSelected(connection().database());
 
623
        else if (toIsOracle(connection()) || toIsSapDB(connection()))
 
624
            Schema->setSelected(connection().user().upper());
 
625
        else
 
626
            Schema->setSelected(connection().user());
 
627
        connect(Schema, SIGNAL(activated(int)), this, SLOT(changeSchema()));
 
628
        try
 
629
        {
 
630
            Schema->refresh();
 
631
        }
 
632
        catch (...)
 
633
        {}
 
634
 
 
635
        new toChangeConnection(toolbar, TO_KDE_TOOLBAR_WIDGET);
 
636
 
 
637
        connect(ResultTab, SIGNAL(currentChanged(QWidget *)),
 
638
                this, SLOT(changeResult(QWidget *)));
 
639
 
 
640
        if (autoLoad)
 
641
        {
 
642
            Editor->setFilename(WorksheetTool.config(CONF_AUTO_LOAD, ""));
 
643
            if (!Editor->filename().isEmpty())
 
644
            {
 
645
                try
 
646
                {
 
647
                    QCString data = toReadFile(Editor->filename());
 
648
                    Editor->setText(QString::fromLocal8Bit(data));
 
649
                    Editor->setModified(false);
 
650
                }
 
651
                TOCATCH
 
652
            }
 
653
        }
 
654
 
 
655
        ToolMenu = NULL;
 
656
        connect(toMainWidget()->workspace(), SIGNAL(windowActivated(QWidget *)),
 
657
                this, SLOT(windowActivated(QWidget *)));
 
658
 
 
659
        try
 
660
        {
 
661
            if (connection().provider() == "Oracle")
 
662
            {
 
663
                if (!WorksheetTool.config(CONF_STATISTICS, "").isEmpty())
 
664
                {
 
665
                    show();
 
666
                    StatisticButton->setOn(true);
 
667
                }
 
668
            }
 
669
            else
 
670
            {
 
671
                StatisticButton->setShown(false);
 
672
            }
 
673
        }
 
674
        TOCATCH
 
675
 
 
676
        connect(this, SIGNAL(connectionChange()), this, SLOT(connectionChanged()));
 
677
    }
 
678
    Editor->setAnalyzer(connection().analyzer());
 
679
    connect(Editor, SIGNAL(displayMenu(QPopupMenu *)), this, SLOT(displayMenu(QPopupMenu *)));
 
680
 
 
681
    connect(&Poll, SIGNAL(timeout()), this, SLOT(poll()));
 
682
    setFocusProxy(Editor);
 
683
}
 
684
 
 
685
toWorksheet::toWorksheet(QWidget *main, toConnection &connection, bool autoLoad)
 
686
        : toToolWidget(WorksheetTool, "worksheet.html", main, connection), Light(false)
 
687
{
 
688
    setup(autoLoad);
 
689
}
 
690
 
 
691
toWorksheet::toWorksheet(QWidget *main, const char *name, toConnection &connection)
 
692
        : toToolWidget(WorksheetTool, "worksheetlight.html", main, connection, name), Light(true)
 
693
{
 
694
    setup(false);
 
695
}
 
696
 
 
697
void toWorksheet::changeRefresh(const QString &str)
 
698
{
 
699
    try
 
700
    {
 
701
        if (!Light && StopButton->isEnabled() && StatisticButton->isOn())
 
702
            toRefreshParse(timer(), str);
 
703
    }
 
704
    TOCATCH
 
705
}
 
706
 
 
707
void toWorksheet::windowActivated(QWidget *widget)
 
708
{
 
709
    if (Light)
 
710
        return ;
 
711
 
 
712
    QWidget *w = this;
 
713
    while (w && w != widget)
 
714
    {
 
715
        w = w->parentWidget();
 
716
    }
 
717
 
 
718
    if (widget == w)
 
719
    {
 
720
        if (!ToolMenu)
 
721
        {
 
722
            ToolMenu = new QPopupMenu(this);
 
723
            ToolMenu->insertItem(QPixmap(const_cast<const char**>(execute_xpm)),
 
724
                                 tr("&Execute Current"), this, SLOT(execute(void)),
 
725
                                 toKeySequence(tr("Ctrl+Return", "Worksheet|Execute current")));
 
726
            ToolMenu->insertItem(QPixmap(const_cast<const char**>(executestep_xpm)),
 
727
                                 tr("Execute &Next"), this, SLOT(executeStep(void)),
 
728
                                 toKeySequence(tr("F9", "Worksheet|Execute next")));
 
729
            ToolMenu->insertItem(QPixmap(const_cast<const char**>(executeall_xpm)),
 
730
                                 tr("Execute &All"), this, SLOT(executeAll(void)),
 
731
                                 toKeySequence(tr("F8", "Worksheet|Execute all")));
 
732
            ToolMenu->insertItem(tr("Execute &Newline Separated"), this,
 
733
                                 SLOT(executeNewline(void)),
 
734
                                 toKeySequence(tr("Shift+F9", "Worksheet|Execute newline separated")));
 
735
            ToolMenu->insertItem(QPixmap(const_cast<const char**>(refresh_xpm)),
 
736
                                 tr("&Reexecute Last Statement"), this, SLOT(refresh(void)),
 
737
                                 toKeySequence(tr("F5", "Worksheet|Reexecute last statement")));
 
738
            if (connection().provider() == "Oracle")
 
739
                ToolMenu->insertItem(tr("Check syntax of buffer"),
 
740
                                     this, SLOT(parseAll()),
 
741
                                     toKeySequence(tr("Ctrl+F9", "Worksheet|Check syntax of buffer")));
 
742
            ToolMenu->insertSeparator();
 
743
            ToolMenu->insertItem(QPixmap(const_cast<const char**>(describe_xpm)),
 
744
                                 tr("&Describe Under Cursor"), this, SLOT(describe(void)),
 
745
                                 toKeySequence(tr("F4", "Worksheet|Describe under cursor")));
 
746
            ToolMenu->insertItem(tr("&Explain current statement"), this, SLOT(explainPlan(void)),
 
747
                                 toKeySequence(tr("F3", "Worksheet|Explain plan")), TO_ID_PLAN);
 
748
            if (connection().provider() == "Oracle")
 
749
                ToolMenu->insertItem(tr("&Enable Statistics"), this, SLOT(toggleStatistic(void)),
 
750
                                     0, TO_ID_STATISTICS);
 
751
            ToolMenu->insertItem(QPixmap(const_cast<const char**>(stop_xpm)),
 
752
                                 tr("&Stop Execution"), Result, SLOT(stop(void)),
 
753
                                 0, TO_ID_STOP);
 
754
            ToolMenu->insertSeparator();
 
755
            ToolMenu->insertItem(tr("Execute Saved SQL"),
 
756
                                 this, SLOT(executeSaved()),
 
757
                                 toKeySequence(tr("F7", "Worksheet|Execute saved SQL")));
 
758
            ToolMenu->insertItem(tr("Select Saved SQL"),
 
759
                                 this, SLOT(selectSaved()),
 
760
                                 toKeySequence(tr("Ctrl+Shift+S", "Worksheet|Select saved SQL")));
 
761
            ToolMenu->insertItem(QPixmap(const_cast<const char**>(previous_xpm)),
 
762
                                 tr("Save last SQL"),
 
763
                                 this, SLOT(saveLast()));
 
764
            ToolMenu->insertItem(tr("Edit Saved SQL..."),
 
765
                                 this, SLOT(editSaved()));
 
766
            ToolMenu->insertSeparator();
 
767
            ToolMenu->insertItem(tr("Previous Log Entry"), this, SLOT(executePreviousLog()),
 
768
                                 toKeySequence(tr("Alt+Up", "Worksheet|Previous log entry")));
 
769
            ToolMenu->insertItem(tr("Next Log Entry"), this, SLOT(executeNextLog()),
 
770
                                 toKeySequence(tr("Alt+Down", "Worksheet|Next log entry")));
 
771
            ToolMenu->insertItem(QPixmap(const_cast<const char**>(eraselog_xpm)),
 
772
                                 tr("Erase &Log"), this, SLOT(eraseLogButton(void)));
 
773
 
 
774
 
 
775
            toMainWidget()->menuBar()->insertItem(tr("Edit&or"), ToolMenu, -1, toToolMenuIndex());
 
776
            ToolMenu->setItemEnabled(TO_ID_STOP, StopButton->isEnabled());
 
777
            ToolMenu->setItemChecked(TO_ID_STATISTICS, StatisticButton->isOn());
 
778
            ToolMenu->setItemEnabled(TO_ID_PLAN, Plan->handled());
 
779
        }
 
780
    }
 
781
    else
 
782
    {
 
783
        delete ToolMenu;
 
784
        ToolMenu = NULL;
 
785
    }
 
786
}
 
787
 
 
788
void toWorksheet::connectionChanged(void)
 
789
{
 
790
    try
 
791
    {
 
792
        StatisticButton->setShown(connection().provider() == "Oracle");
 
793
        ResultTab->setTabShown(ResourceSplitter, Resources->handled());
 
794
        Editor->setAnalyzer(connection().analyzer());
 
795
        PlanButton->setEnabled(Plan->handled());
 
796
        delete ToolMenu;
 
797
        ToolMenu = NULL;
 
798
        windowActivated(this);
 
799
    }
 
800
    TOCATCH
 
801
}
 
802
 
 
803
bool toWorksheet::checkSave(bool input)
 
804
{
 
805
    if (Light)
 
806
        return true;
 
807
    if (Editor->isModified())
 
808
    {
 
809
        if (WorksheetTool.config(CONF_AUTO_SAVE, "").isEmpty() ||
 
810
                Editor->filename().isEmpty())
 
811
        {
 
812
            if (!WorksheetTool.config(CONF_CHECK_SAVE, "Yes").isEmpty())
 
813
            {
 
814
                if (input)
 
815
                {
 
816
                    QString conn;
 
817
                    try
 
818
                    {
 
819
                        conn = connection().description();
 
820
                    }
 
821
                    catch (...)
 
822
                    {
 
823
                        conn += QString::fromLatin1("unknown connection");
 
824
                    }
 
825
                    QString str = tr("Save changes to editor for %1").arg(conn);
 
826
                    if (!Editor->filename().isEmpty())
 
827
                        str += QString::fromLatin1("\n(") + Editor->filename() + QString::fromLatin1(")");
 
828
                    int ret = TOMessageBox::information(this,
 
829
                                                        tr("Save file"),
 
830
                                                        str,
 
831
                                                        tr("&Yes"), tr("&No"), tr("Cancel"), 0, 2);
 
832
                    if (ret == 1)
 
833
                        return true;
 
834
                    else if (ret == 2)
 
835
                        return false;
 
836
                }
 
837
                else
 
838
                    return true;
 
839
            }
 
840
            else
 
841
                return true;
 
842
            if (Editor->filename().isEmpty() && input)
 
843
                Editor->setFilename(toSaveFilename(Editor->filename(), QString::null, this));
 
844
            if (Editor->filename().isEmpty())
 
845
                return false;
 
846
        }
 
847
        if (!toWriteFile(Editor->filename(), Editor->text()))
 
848
            return false;
 
849
        Editor->setModified(false);
 
850
    }
 
851
    return true;
 
852
}
 
853
 
 
854
bool toWorksheet::close(bool del)
 
855
{
 
856
    if (checkSave(true))
 
857
    {
 
858
        Result->stop();
 
859
        return QVBox::close(del);
 
860
    }
 
861
    return false;
 
862
}
 
863
 
 
864
toWorksheet::~toWorksheet()
 
865
{
 
866
    checkSave(false);
 
867
    eraseLogButton();
 
868
}
 
869
 
 
870
#define LARGE_BUFFER 4096
 
871
 
 
872
void toWorksheet::changeResult(QWidget *widget)
 
873
{
 
874
    CurrentTab = widget;
 
875
    if (QueryString.length())
 
876
    {
 
877
        if (CurrentTab == Plan)
 
878
            Plan->query(QueryString);
 
879
        else if (CurrentTab == ResourceSplitter)
 
880
            viewResources();
 
881
        else if (CurrentTab == Statistics && Result->running())
 
882
            Statistics->refreshStats(false);
 
883
    }
 
884
}
 
885
 
 
886
void toWorksheet::refresh(void)
 
887
{
 
888
    if (!QueryString.isEmpty())
 
889
        query(QueryString, Normal);
 
890
    if (RefreshSeconds > 0)
 
891
        RefreshTimer.start(RefreshSeconds*1000, true);
 
892
}
 
893
 
 
894
static QString unQuote(const QString &str)
 
895
{
 
896
    if (str.at(0).latin1() == '\"' && str.at(str.length() - 1).latin1() == '\"')
 
897
        return str.left(str.length() - 1).right(str.length() - 2);
 
898
    return str.upper();
 
899
}
 
900
 
 
901
bool toWorksheet::describe(const QString &query)
 
902
{
 
903
    try
 
904
    {
 
905
        QRegExp white(QString::fromLatin1("[ \r\n\t.]+"));
 
906
        QStringList part = QStringList::split(white, query);
 
907
        if (part[0].upper() == QString::fromLatin1("DESC") ||
 
908
                part[0].upper() == QString::fromLatin1("DESCRIBE"))
 
909
        {
 
910
            if (Light)
 
911
                return true;
 
912
            if (toIsOracle(connection()))
 
913
            {
 
914
                if (part.count() == 2)
 
915
                {
 
916
                    Columns->changeParams(unQuote(part[1]));
 
917
                }
 
918
                else if (part.count() == 3)
 
919
                {
 
920
                    Columns->changeParams(unQuote(part[1]), unQuote(part[2]));
 
921
                }
 
922
                else
 
923
                    throw tr("Wrong number of parameters for describe");
 
924
            }
 
925
            else if (connection().provider() == "MySQL")
 
926
            {
 
927
                if (part.count() == 2)
 
928
                {
 
929
                    Columns->changeParams(part[1]);
 
930
                }
 
931
                else
 
932
                    throw tr("Wrong number of parameters for describe");
 
933
            }
 
934
            Current->hide();
 
935
            Columns->show();
 
936
            Current = Columns;
 
937
            return true;
 
938
        }
 
939
        else
 
940
        {
 
941
            if (Light)
 
942
                return false;
 
943
            QWidget *curr = ResultTab->currentPage();
 
944
            Current->hide();
 
945
            Result->show();
 
946
            Current = Result;
 
947
            if (curr == Columns)
 
948
                ResultTab->showPage(Result);
 
949
            return false;
 
950
        }
 
951
    }
 
952
    TOCATCH
 
953
    return false;
 
954
}
 
955
 
 
956
void toWorksheet::query(const QString &str, execType type)
 
957
{
 
958
    Result->stop();
 
959
    RefreshTimer.stop();
 
960
 
 
961
    QRegExp strq(QString::fromLatin1("'[^']*'"));
 
962
    QString chk = str.lower();
 
963
    chk.replace(strq, QString::fromLatin1(" "));
 
964
    bool code = false;
 
965
    static QRegExp codere(QString::fromLatin1("[^a-z0-9]end\\s+[a-z0-9_-]*;$"), true);
 
966
    static QRegExp codere2(QString::fromLatin1("[^a-z0-9]end;"), true);
 
967
 
 
968
    if (codere.match(chk) >= 0 || codere2.match(chk) >= 0)
 
969
        code = true;
 
970
 
 
971
    QueryString = str;
 
972
    if (!code && QueryString.length() > 0 && QueryString.at(QueryString.length() - 1) == ';')
 
973
        QueryString.truncate(QueryString.length() - 1);
 
974
 
 
975
    bool nobinds = false;
 
976
    chk = str.lower();
 
977
    chk.replace(strq, QString::fromLatin1(" "));
 
978
    chk = chk.simplifyWhiteSpace();
 
979
    chk.replace(QRegExp(QString::fromLatin1(" or replace ")), QString::fromLatin1(" "));
 
980
    if (chk.startsWith(QString::fromLatin1("create trigger ")))
 
981
        nobinds = true;
 
982
 
 
983
    if (type == OnlyPlan)
 
984
    {
 
985
        ResultTab->showPage(Plan);
 
986
        Plan->query(str);
 
987
    }
 
988
    else if (!describe(QueryString))
 
989
    {
 
990
 
 
991
        toSQLParse::stringTokenizer tokens(str);
 
992
        QString first = tokens.getToken(true).upper();
 
993
        if (first == QString::fromLatin1("REM") ||
 
994
                first == QString::fromLatin1("ASSIGN") ||
 
995
                first == QString::fromLatin1("PROMPT") ||
 
996
                first == QString::fromLatin1("COLUMN") ||
 
997
                first == QString::fromLatin1("SPOOL") ||
 
998
                first == QString::fromLatin1("STORE"))
 
999
        {
 
1000
            QString t = tr("Ignoring SQL*Plus command");
 
1001
            Timer.start();
 
1002
            addLog(QueryString, toConnection::exception(t), false);
 
1003
            toStatusMessage(t, true);
 
1004
            return ;
 
1005
        }
 
1006
 
 
1007
        toQList param;
 
1008
        if (!nobinds)
 
1009
            try
 
1010
            {
 
1011
                param = toParamGet::getParam(connection(), this, QueryString);
 
1012
            }
 
1013
            catch (...)
 
1014
            {
 
1015
                return ;
 
1016
            }
 
1017
        toStatusMessage(tr("Processing query"), true);
 
1018
 
 
1019
        if (type == Parse)
 
1020
        {
 
1021
            try
 
1022
            {
 
1023
                First = false;
 
1024
                Timer.start();
 
1025
                connection().parse(QueryString);
 
1026
            }
 
1027
            catch (const QString &exc)
 
1028
            {
 
1029
                addLog(QueryString, exc, true);
 
1030
            }
 
1031
        }
 
1032
        else if (type == Direct)
 
1033
        {
 
1034
            try
 
1035
            {
 
1036
                First = false;
 
1037
                Timer.start();
 
1038
                QString buffer;
 
1039
                if (WorksheetTool.config(CONF_HISTORY, "").isEmpty() && !Light)
 
1040
                {
 
1041
                    toQuery query(connection(), toQuery::Long, QueryString, param);
 
1042
                    if (query.rowsProcessed() > 0)
 
1043
                        buffer = tr("%1 rows processed").arg((int)query.rowsProcessed());
 
1044
                    else
 
1045
                        buffer = tr("Query executed");
 
1046
                }
 
1047
                else
 
1048
                {
 
1049
                    toResultView *query = new toResultView(Current->parentWidget());
 
1050
 
 
1051
                    try
 
1052
                    {
 
1053
                        query->query(QueryString, param);
 
1054
                        if (query->query() && query->query()->rowsProcessed() > 0)
 
1055
                            buffer = tr("%1 rows processed").arg((int)query->query()->rowsProcessed());
 
1056
                        else
 
1057
                            buffer = tr("Query executed");
 
1058
                        Current->hide();
 
1059
                        Current = query;
 
1060
                        Current->show();
 
1061
                    }
 
1062
                    catch (...)
 
1063
                    {
 
1064
                        delete query;
 
1065
                        throw;
 
1066
                    }
 
1067
                }
 
1068
 
 
1069
                addLog(QueryString, toConnection::exception(buffer), false);
 
1070
            }
 
1071
            catch (const QString &exc)
 
1072
            {
 
1073
                addLog(QueryString, exc, true);
 
1074
            }
 
1075
        }
 
1076
        else
 
1077
        {
 
1078
            First = false;
 
1079
            Timer.start();
 
1080
            StopButton->setEnabled(true);
 
1081
            Poll.start(1000);
 
1082
            QToolTip::add
 
1083
                (Started, tr("Duration while query has been running\n\n") + QueryString);
 
1084
            if (ToolMenu)
 
1085
                ToolMenu->setItemEnabled(TO_ID_STOP, true);
 
1086
            Result->setNumberColumn(!WorksheetTool.config(CONF_NUMBER, "Yes").isEmpty());
 
1087
            try
 
1088
            {
 
1089
                saveHistory();
 
1090
                Result->setSQL(QString::null);
 
1091
                Result->query(QueryString, param);
 
1092
                if (Light)
 
1093
                    return ;
 
1094
                if (CurrentTab == Visualize)
 
1095
                    Visualize->display();
 
1096
                else if (CurrentTab == Plan)
 
1097
                    Plan->query(QueryString);
 
1098
                else if (CurrentTab == ResourceSplitter)
 
1099
                    viewResources();
 
1100
            }
 
1101
            catch (const toConnection::exception &exc)
 
1102
            {
 
1103
                addLog(QueryString, exc, true);
 
1104
            }
 
1105
            catch (const QString &exc)
 
1106
            {
 
1107
                addLog(QueryString, exc, true);
 
1108
            }
 
1109
            if (!Light)
 
1110
            {
 
1111
                try
 
1112
                {
 
1113
                    if (StatisticButton->isOn())
 
1114
                        toRefreshParse(timer(), Refresh->currentText());
 
1115
                }
 
1116
                TOCATCH
 
1117
            }
 
1118
            Result->setSQLName(QueryString.simplifyWhiteSpace().left(40));
 
1119
        }
 
1120
    }
 
1121
}
 
1122
 
 
1123
void toWorksheet::saveHistory(void)
 
1124
{
 
1125
    if (WorksheetTool.config(CONF_HISTORY, "").isEmpty())
 
1126
        return ;
 
1127
    if (Result->firstChild() && Current == Result && !Light)
 
1128
    {
 
1129
        History[LastID] = Result;
 
1130
        Result->hide();
 
1131
        Result->stop();
 
1132
        disconnect(Result, SIGNAL(done(void)), this, SLOT(queryDone(void)));
 
1133
        disconnect(Result, SIGNAL(firstResult(const QString &, const toConnection::exception &, bool)),
 
1134
                   this, SLOT(addLog(const QString &, const toConnection::exception &, bool)));
 
1135
        disconnect(StopButton, SIGNAL(clicked(void)), Result, SLOT(stop(void)));
 
1136
 
 
1137
        Result = new toResultLong(Result->parentWidget());
 
1138
        if (StatisticButton->isOn())
 
1139
            enableStatistic(true);
 
1140
        Result->show();
 
1141
        Current = Result;
 
1142
        connect(StopButton, SIGNAL(clicked(void)), Result, SLOT(stop(void)));
 
1143
        connect(Result, SIGNAL(done(void)), this, SLOT(queryDone(void)));
 
1144
        connect(Result, SIGNAL(firstResult(const QString &, const toConnection::exception &, bool)),
 
1145
                this, SLOT(addLog(const QString &, const toConnection::exception &, bool)));
 
1146
    }
 
1147
}
 
1148
 
 
1149
QString toWorksheet::duration(int dur, bool hundreds)
 
1150
{
 
1151
    char buf[100];
 
1152
    if (dur >= 3600000)
 
1153
    {
 
1154
        if (hundreds)
 
1155
            sprintf(buf, "%d:%02d:%02d.%02d", dur / 3600000, (dur / 60000) % 60, (dur / 1000) % 60, (dur / 10) % 100);
 
1156
        else
 
1157
            sprintf(buf, "%d:%02d:%02d", dur / 3600000, (dur / 60000) % 60, (dur / 1000) % 60);
 
1158
    }
 
1159
    else
 
1160
    {
 
1161
        if (hundreds)
 
1162
            sprintf(buf, "%d:%02d.%02d", dur / 60000, (dur / 1000) % 60, (dur / 10) % 100);
 
1163
        else
 
1164
            sprintf(buf, "%d:%02d", dur / 60000, (dur / 1000) % 60);
 
1165
    }
 
1166
    return QString::fromLatin1(buf);
 
1167
}
 
1168
 
 
1169
void toWorksheet::addLog(const QString &sql, const toConnection::exception &result, bool error)
 
1170
{
 
1171
    QString now;
 
1172
    try
 
1173
    {
 
1174
        now = toNow(connection());
 
1175
    }
 
1176
    catch (...)
 
1177
    {
 
1178
        now = QString::fromLatin1("Unknown");
 
1179
    }
 
1180
    toResultViewItem *item = NULL;
 
1181
 
 
1182
    LastID++;
 
1183
 
 
1184
    int dur = 0;
 
1185
    if (!Timer.isNull())
 
1186
        dur = Timer.elapsed();
 
1187
    First = true;
 
1188
 
 
1189
    if (!Light)
 
1190
    {
 
1191
        if (WorksheetTool.config(CONF_LOG_MULTI, "Yes").isEmpty())
 
1192
        {
 
1193
            if (WorksheetTool.config(CONF_LOG_AT_END, "Yes").isEmpty())
 
1194
                item = new toResultViewItem(Logging, NULL);
 
1195
            else
 
1196
                item = new toResultViewItem(Logging, LastLogItem);
 
1197
        }
 
1198
        else if (WorksheetTool.config(CONF_LOG_AT_END, "Yes").isEmpty())
 
1199
            item = new toResultViewMLine(Logging, NULL);
 
1200
        else
 
1201
            item = new toResultViewMLine(Logging, LastLogItem);
 
1202
        item->setText(0, sql);
 
1203
 
 
1204
        LastLogItem = item;
 
1205
        item->setText(1, result);
 
1206
        item->setText(2, now);
 
1207
        if (!WorksheetTool.config(CONF_HISTORY, "").isEmpty())
 
1208
            item->setText(4, QString::number(LastID));
 
1209
        item->setText(5, QString::number(result.offset()));
 
1210
    }
 
1211
 
 
1212
    if (result.offset() >= 0 && LastLine >= 0 && LastOffset >= 0 &&
 
1213
            !WorksheetTool.config(CONF_MOVE_TO_ERR, "Yes").isEmpty())
 
1214
    {
 
1215
        QChar cmp = '\n';
 
1216
        int lastnl = 0;
 
1217
        int lines = 0;
 
1218
        for (int i = 0;i < result.offset();i++)
 
1219
        {
 
1220
            if (sql.at(i) == cmp)
 
1221
            {
 
1222
                LastOffset = 0;
 
1223
                lastnl = i + 1;
 
1224
                lines++;
 
1225
            }
 
1226
        }
 
1227
        Editor->setCursorPosition(LastLine + lines, LastOffset + result.offset() - lastnl);
 
1228
        LastLine = LastOffset = -1;
 
1229
    }
 
1230
 
 
1231
    QString buf = duration(dur);
 
1232
 
 
1233
    if (!Light)
 
1234
    {
 
1235
        item->setText(3, buf);
 
1236
 
 
1237
        QListViewItem *last = Logging->currentItem();
 
1238
        toResultViewItem *citem = NULL;
 
1239
        if (last)
 
1240
            citem = dynamic_cast<toResultViewItem *>(last);
 
1241
        if (!citem || citem->allText(0) != sql)
 
1242
        {
 
1243
            disconnect(Logging, SIGNAL(selectionChanged(QListViewItem *)), this, SLOT(executeLog()));
 
1244
            Logging->setSelected(item, true);
 
1245
            connect(Logging, SIGNAL(selectionChanged(QListViewItem *)), this, SLOT(executeLog()));
 
1246
            Logging->ensureItemVisible(item);
 
1247
        }
 
1248
    }
 
1249
 
 
1250
    {
 
1251
        QString str = result;
 
1252
        str += "\n" + tr("(Duration %1)").arg(buf);
 
1253
        if (error)
 
1254
 
 
1255
            toStatusMessage(str);
 
1256
        else
 
1257
            toStatusMessage(str, false, false);
 
1258
    }
 
1259
    if (!Light && !error)
 
1260
        changeResult(CurrentTab);
 
1261
 
 
1262
    static QRegExp re(QString::fromLatin1("^[1-9]\\d* rows processed$"));
 
1263
    try
 
1264
    {
 
1265
        if (result.contains(re))
 
1266
        {
 
1267
            if (!toConfigurationSingle::Instance().globalConfig(CONF_AUTO_COMMIT, "").isEmpty())
 
1268
                connection().commit();
 
1269
            else
 
1270
                toMainWidget()->setNeedCommit(connection());
 
1271
        }
 
1272
    }
 
1273
    TOCATCH
 
1274
    saveDefaults();
 
1275
}
 
1276
 
 
1277
void toWorksheet::execute(toSQLParse::tokenizer &tokens, int line, int pos, execType type)
 
1278
{
 
1279
    LastLine = line;
 
1280
    LastOffset = pos;
 
1281
    int endLine,endCol;
 
1282
    if(Editor->lines()<=tokens.line()){
 
1283
     endLine=Editor->lines()-1;
 
1284
     endCol=Editor->lineLength(Editor->lines()-1);
 
1285
    }else{
 
1286
      endLine=tokens.line();
 
1287
      if(Editor->lineLength(tokens.line())<=tokens.offset())
 
1288
        endCol=Editor->lineLength(tokens.line());
 
1289
      else{
 
1290
        endCol=tokens.offset();
 
1291
      }
 
1292
    }
 
1293
    Editor->setSelection(line, pos, endLine,endCol);
 
1294
    QString t = Editor->selectedText();
 
1295
 
 
1296
    bool comment = false;
 
1297
    bool multiComment = false;
 
1298
    int oline = line;
 
1299
    int opos = pos;
 
1300
    unsigned int i;
 
1301
 
 
1302
    for (i = 0;i < t.length() - 1;i++)
 
1303
    {
 
1304
        if (comment)
 
1305
        {
 
1306
            if (t.at(i).latin1() == '\n')
 
1307
                comment = false;
 
1308
        }
 
1309
        else if (multiComment)
 
1310
        {
 
1311
            if (t.at(i).latin1() == '*' &&
 
1312
                    t.at(i + 1).latin1() == '/')
 
1313
            {
 
1314
                multiComment = false;
 
1315
                i++;
 
1316
            }
 
1317
        }
 
1318
        else if (t.at(i).latin1() == '-' &&
 
1319
                 t.at(i + 1).latin1() == '-')
 
1320
            comment = true;
 
1321
        else if (t.at(i).latin1() == '/' &&
 
1322
                 t.at(i + 1).latin1() == '/')
 
1323
            comment = true;
 
1324
        else if (t.at(i).latin1() == '/' &&
 
1325
                 t.at(i + 1).latin1() == '*')
 
1326
            multiComment = true;
 
1327
        else if (!t.at(i).isSpace() && t.at(i) != '/')
 
1328
            break;
 
1329
 
 
1330
        if (t.at(i).latin1() == '\n')
 
1331
        {
 
1332
            line++;
 
1333
            pos = 0;
 
1334
        }
 
1335
        else
 
1336
            pos++;
 
1337
    }
 
1338
 
 
1339
    if (line != oline ||
 
1340
            pos != opos)
 
1341
    {
 
1342
        LastLine = line;
 
1343
        LastOffset = pos;
 
1344
        Editor->setSelection(line, pos, endLine, endCol);
 
1345
        t = t.mid(i);
 
1346
    }
 
1347
    if (t.length())
 
1348
        query(t, type);
 
1349
}
 
1350
 
 
1351
void toWorksheet::execute()
 
1352
{
 
1353
    if (Editor->hasSelectedText())
 
1354
    {
 
1355
        query(Editor->selectedText(), Normal);
 
1356
        return ;
 
1357
    }
 
1358
 
 
1359
    toSQLParse::editorTokenizer tokens(Editor);
 
1360
 
 
1361
    int cpos, cline;
 
1362
    Editor->getCursorPosition(&cline, &cpos);
 
1363
 
 
1364
    int line;
 
1365
    int pos;
 
1366
    do
 
1367
    {
 
1368
        line = tokens.line();
 
1369
        pos = tokens.offset();
 
1370
        toSQLParse::parseStatement(tokens);
 
1371
    }
 
1372
    while (tokens.line() < cline ||
 
1373
            (tokens.line() == cline && tokens.offset() < cpos));
 
1374
 
 
1375
    execute(tokens, line, pos, Normal);
 
1376
}
 
1377
 
 
1378
void toWorksheet::explainPlan()
 
1379
{
 
1380
    if (Editor->hasSelectedText())
 
1381
    {
 
1382
        query(Editor->selectedText(), OnlyPlan);
 
1383
        return ;
 
1384
    }
 
1385
 
 
1386
    toSQLParse::editorTokenizer tokens(Editor);
 
1387
 
 
1388
    int cpos, cline;
 
1389
    Editor->getCursorPosition(&cline, &cpos);
 
1390
 
 
1391
    int line;
 
1392
    int pos;
 
1393
    do
 
1394
    {
 
1395
        line = tokens.line();
 
1396
        pos = tokens.offset();
 
1397
        toSQLParse::parseStatement(tokens);
 
1398
    }
 
1399
    while (tokens.line() < cline ||
 
1400
            (tokens.line() == cline && tokens.offset() < cpos));
 
1401
 
 
1402
    execute(tokens, line, pos, OnlyPlan);
 
1403
}
 
1404
 
 
1405
void toWorksheet::executeStep()
 
1406
{
 
1407
    toSQLParse::editorTokenizer tokens(Editor);
 
1408
 
 
1409
    int cpos, cline;
 
1410
    Editor->getCursorPosition(&cline, &cpos);
 
1411
 
 
1412
    int line;
 
1413
    int pos;
 
1414
    do
 
1415
    {
 
1416
        line = tokens.line();
 
1417
        pos = tokens.offset();
 
1418
        toSQLParse::parseStatement(tokens);
 
1419
    }
 
1420
    while (tokens.line() < cline ||
 
1421
            (tokens.line() == cline && tokens.offset() <= cpos));
 
1422
 
 
1423
    execute(tokens, line, pos, Normal);
 
1424
}
 
1425
 
 
1426
void toWorksheet::executeAll()
 
1427
{
 
1428
    toSQLParse::editorTokenizer tokens(Editor);
 
1429
 
 
1430
    int cpos, cline;
 
1431
    Editor->getCursorPosition(&cline, &cpos);
 
1432
 
 
1433
    QProgressDialog dialog(tr("Executing all statements"),
 
1434
                           tr("Cancel"),
 
1435
                           Editor->lines(),
 
1436
                           this,
 
1437
                           "Progress",
 
1438
                           true);
 
1439
    int line;
 
1440
    int pos;
 
1441
    bool ignore = true;
 
1442
    do
 
1443
    {
 
1444
        line = tokens.line();
 
1445
        pos = tokens.offset();
 
1446
        dialog.setProgress(line);
 
1447
        qApp->processEvents();
 
1448
        if (dialog.wasCancelled())
 
1449
            break;
 
1450
        toSQLParse::parseStatement(tokens);
 
1451
 
 
1452
        if (ignore && (tokens.line() > cline ||
 
1453
                       (tokens.line() == cline &&
 
1454
                        tokens.offset() >= cpos)))
 
1455
        {
 
1456
            ignore = false;
 
1457
            cline = line;
 
1458
            cpos = pos;
 
1459
        }
 
1460
 
 
1461
        if (tokens.line() < Editor->lines() && !ignore)
 
1462
        {
 
1463
            execute(tokens, line, pos, Direct);
 
1464
            if (Current)
 
1465
            {
 
1466
                toResultView *last = dynamic_cast<toResultView *>(Current);
 
1467
                if (!WorksheetTool.config(CONF_HISTORY, "").isEmpty() &&
 
1468
                        last && last->firstChild())
 
1469
                    History[LastID] = last;
 
1470
            }
 
1471
        }
 
1472
    }
 
1473
    while (tokens.line() < Editor->lines());
 
1474
 
 
1475
    Editor->setSelection(cline, cpos, tokens.line(), tokens.offset());
 
1476
}
 
1477
 
 
1478
void toWorksheet::parseAll()
 
1479
{
 
1480
    toSQLParse::editorTokenizer tokens(Editor);
 
1481
 
 
1482
    int cpos, cline;
 
1483
    Editor->getCursorPosition(&cline, &cpos);
 
1484
 
 
1485
    QProgressDialog dialog(tr("Parsing all statements"),
 
1486
                           tr("Cancel"),
 
1487
                           Editor->lines(),
 
1488
                           this,
 
1489
                           "Progress",
 
1490
                           true);
 
1491
    int line;
 
1492
    int pos;
 
1493
    bool ignore = true;
 
1494
    do
 
1495
    {
 
1496
        line = tokens.line();
 
1497
        pos = tokens.offset();
 
1498
        dialog.setProgress(line);
 
1499
        qApp->processEvents();
 
1500
        if (dialog.wasCancelled())
 
1501
            break;
 
1502
        toSQLParse::parseStatement(tokens);
 
1503
 
 
1504
        if (ignore && (tokens.line() > cline ||
 
1505
                       (tokens.line() == cline &&
 
1506
                        tokens.offset() >= cpos)))
 
1507
        {
 
1508
            ignore = false;
 
1509
            cline = line;
 
1510
            cpos = pos;
 
1511
        }
 
1512
 
 
1513
        if (tokens.line() < Editor->lines() && !ignore)
 
1514
        {
 
1515
            execute(tokens, line, pos, Parse);
 
1516
            if (Current)
 
1517
            {
 
1518
                toResultView *last = dynamic_cast<toResultView *>(Current);
 
1519
                if (!WorksheetTool.config(CONF_HISTORY, "").isEmpty() &&
 
1520
                        last && last->firstChild())
 
1521
                    History[LastID] = last;
 
1522
            }
 
1523
        }
 
1524
    }
 
1525
    while (tokens.line() < Editor->lines());
 
1526
 
 
1527
    Editor->setSelection(cline, cpos, tokens.line(), tokens.offset());
 
1528
}
 
1529
 
 
1530
void toWorksheet::eraseLogButton()
 
1531
{
 
1532
    if (Light)
 
1533
        return ;
 
1534
    Logging->clear();
 
1535
    LastLogItem = NULL;
 
1536
    for (std::map<int, QWidget *>::iterator i = History.begin();i != History.end();i++)
 
1537
        delete (*i).second;
 
1538
    History.clear();
 
1539
}
 
1540
 
 
1541
void toWorksheet::queryDone(void)
 
1542
{
 
1543
    if (!First && !QueryString.isEmpty())
 
1544
        addLog(QueryString, toConnection::exception(tr("Aborted")), false);
 
1545
    else
 
1546
        emit executed();
 
1547
    try
 
1548
    {
 
1549
        timer()->stop();
 
1550
    }
 
1551
    TOCATCH
 
1552
    StopButton->setEnabled(false);
 
1553
    Poll.stop();
 
1554
    if (ToolMenu)
 
1555
        ToolMenu->setItemEnabled(TO_ID_STOP, false);
 
1556
    saveDefaults();
 
1557
}
 
1558
 
 
1559
void toWorksheet::saveDefaults(void)
 
1560
{
 
1561
    QListViewItem *item = Result->firstChild();
 
1562
    if (item)
 
1563
    {
 
1564
        QHeader *head = Result->header();
 
1565
        for (int i = 0;i < Result->columns();i++)
 
1566
        {
 
1567
            toResultViewItem *resItem = dynamic_cast<toResultViewItem *>(item);
 
1568
            QString str;
 
1569
            if (resItem)
 
1570
                str = resItem->allText(i);
 
1571
            else if (item)
 
1572
                str = item->text(i);
 
1573
 
 
1574
            try
 
1575
            {
 
1576
                toParamGet::setDefault(connection(), head->label(i).lower(), toUnnull(toQValue(str)));
 
1577
            }
 
1578
            TOCATCH
 
1579
        }
 
1580
    }
 
1581
}
 
1582
 
 
1583
#define ENABLETIMED "ALTER SESSION SET TIMED_STATISTICS = TRUE"
 
1584
 
 
1585
void toWorksheet::enableStatistic(bool ena)
 
1586
{
 
1587
    if (ena)
 
1588
    {
 
1589
        Result->setStatistics(Statistics);
 
1590
        ResultTab->setTabEnabled(StatTab, true);
 
1591
        if (ToolMenu)
 
1592
            ToolMenu->setItemChecked(TO_ID_STATISTICS, true);
 
1593
        Statistics->clear();
 
1594
        if (!WorksheetTool.config(CONF_TIMED_STATS, "Yes").isEmpty())
 
1595
        {
 
1596
            try
 
1597
            {
 
1598
                connection().allExecute(QString::fromLatin1(ENABLETIMED));
 
1599
                connection().addInit(QString::fromLatin1(ENABLETIMED));
 
1600
            }
 
1601
            TOCATCH
 
1602
        }
 
1603
    }
 
1604
    else
 
1605
    {
 
1606
        try
 
1607
        {
 
1608
            connection().delInit(QString::fromLatin1(ENABLETIMED));
 
1609
        }
 
1610
        catch (...)
 
1611
        {}
 
1612
        Result->setStatistics(NULL);
 
1613
        ResultTab->setTabEnabled(StatTab, false);
 
1614
        if (ToolMenu)
 
1615
            ToolMenu->setItemChecked(TO_ID_STATISTICS, false);
 
1616
    }
 
1617
}
 
1618
 
 
1619
void toWorksheet::executeNewline(void)
 
1620
{
 
1621
    int cline, epos;
 
1622
 
 
1623
    Editor->getCursorPosition(&cline, &epos);
 
1624
 
 
1625
    if (cline > 0)
 
1626
        cline--;
 
1627
    while (cline > 0)
 
1628
    {
 
1629
        QString data = Editor->text(cline).simplifyWhiteSpace();
 
1630
        if (data.length() == 0 || data == QString::fromLatin1(" "))
 
1631
        {
 
1632
            cline++;
 
1633
            break;
 
1634
        }
 
1635
        cline--;
 
1636
    }
 
1637
 
 
1638
    while (cline < Editor->lines())
 
1639
    {
 
1640
        QString data = Editor->text(cline).simplifyWhiteSpace();
 
1641
        if (data.length() != 0 && data != QString::fromLatin1(" "))
 
1642
            break;
 
1643
        cline++;
 
1644
    }
 
1645
 
 
1646
    int eline = cline;
 
1647
 
 
1648
    while (eline < Editor->lines())
 
1649
    {
 
1650
        QString data = Editor->text(eline).simplifyWhiteSpace();
 
1651
        if (data.length() == 0 || data == QString::fromLatin1(" "))
 
1652
        {
 
1653
            eline--;
 
1654
            break;
 
1655
        }
 
1656
        epos = Editor->text(eline).length();
 
1657
        eline++;
 
1658
    }
 
1659
    Editor->setSelection(cline, 0, eline, epos);
 
1660
    LastLine = cline;
 
1661
    LastOffset = 0;
 
1662
    if (Editor->hasSelectedText())
 
1663
        query(Editor->selectedText(), Normal);
 
1664
}
 
1665
 
 
1666
void toWorksheet::describe(void)
 
1667
{
 
1668
    if (Light)
 
1669
        return ;
 
1670
 
 
1671
    QString owner, table;
 
1672
    Editor->tableAtCursor(owner, table);
 
1673
 
 
1674
    if (owner.isNull())
 
1675
        Columns->changeParams(table);
 
1676
    else
 
1677
        Columns->changeParams(owner, table);
 
1678
    if (!Columns->isTopLevel())
 
1679
        Current->hide();
 
1680
    Columns->show();
 
1681
    Current = Columns;
 
1682
}
 
1683
 
 
1684
void toWorksheet::executeSaved(void)
 
1685
{
 
1686
    if (Light)
 
1687
        return ;
 
1688
 
 
1689
    LastLine = LastOffset = -1;
 
1690
 
 
1691
    if (SavedLast.length() > 0)
 
1692
    {
 
1693
        try
 
1694
        {
 
1695
            query(toSQL::string(SavedLast, connection()), Normal);
 
1696
        }
 
1697
        TOCATCH
 
1698
    }
 
1699
}
 
1700
 
 
1701
void toWorksheet::insertSaved(void)
 
1702
{
 
1703
    if (Light)
 
1704
        return ;
 
1705
 
 
1706
    LastLine = LastOffset = -1;
 
1707
 
 
1708
    if (InsertSavedLast.length() > 0)
 
1709
    {
 
1710
        try
 
1711
        {
 
1712
            Editor->setText(toSQL::string(InsertSavedLast, connection()));
 
1713
        }
 
1714
        TOCATCH
 
1715
    }
 
1716
}
 
1717
 
 
1718
void toWorksheet::executeSaved(int id)
 
1719
{
 
1720
    std::list<QCString> def = toSQL::range(TOWORKSHEET);
 
1721
    for (std::list<QCString>::iterator i = def.begin();i != def.end();i++)
 
1722
    {
 
1723
        id--;
 
1724
        if (id == 0)
 
1725
        {
 
1726
            SavedLast = *i;
 
1727
            executeSaved();
 
1728
            break;
 
1729
        }
 
1730
    }
 
1731
}
 
1732
 
 
1733
void toWorksheet::insertSaved(int id)
 
1734
{
 
1735
    std::list<QCString> def = toSQL::range(TOWORKSHEET);
 
1736
    for (std::list<QCString>::iterator i = def.begin();i != def.end();i++)
 
1737
    {
 
1738
        id--;
 
1739
        if (id == 0)
 
1740
        {
 
1741
            InsertSavedLast = *i;
 
1742
            insertSaved();
 
1743
            break;
 
1744
        }
 
1745
    }
 
1746
}
 
1747
 
 
1748
void toWorksheet::showSaved(void)
 
1749
{
 
1750
    static QRegExp colon(QString::fromLatin1(":"));
 
1751
    std::list<QCString> def = toSQL::range(TOWORKSHEET);
 
1752
    SavedMenu->clear();
 
1753
    std::map<QString, QPopupMenu *> menues;
 
1754
    int id = 0;
 
1755
    for (std::list<QCString>::iterator sql = def.begin();sql != def.end();sql++)
 
1756
    {
 
1757
 
 
1758
        id++;
 
1759
 
 
1760
        QStringList spl = QStringList::split(colon, QString::fromLatin1(*sql));
 
1761
        spl.remove(spl.begin());
 
1762
 
 
1763
        if (spl.count() > 0)
 
1764
        {
 
1765
            QString name = spl.last();
 
1766
            spl.remove(spl.fromLast());
 
1767
 
 
1768
            QPopupMenu *menu;
 
1769
            if (spl.count() == 0)
 
1770
                menu = SavedMenu;
 
1771
            else
 
1772
            {
 
1773
                QStringList exs = spl;
 
1774
                while (exs.count() > 0 && menues.find(exs.join(QString::fromLatin1(":"))) == menues.end())
 
1775
                    exs.remove(exs.fromLast());
 
1776
                if (exs.count() == 0)
 
1777
                    menu = SavedMenu;
 
1778
                else
 
1779
                    menu = menues[exs.join(QString::fromLatin1(":"))];
 
1780
                QString subname = exs.join(QString::fromLatin1(":"));
 
1781
                for (unsigned int i = exs.count();i < spl.count();i++)
 
1782
                {
 
1783
                    QPopupMenu *next = new QPopupMenu(this);
 
1784
                    connect(next, SIGNAL(activated(int)), this, SLOT(executeSaved(int)));
 
1785
                    if (i != 0)
 
1786
                        subname += QString::fromLatin1(":");
 
1787
                    subname += spl[i];
 
1788
                    menu->insertItem(spl[i], next);
 
1789
                    menu = next;
 
1790
                    menues[subname] = menu;
 
1791
                }
 
1792
            }
 
1793
            menu->insertItem(name, id);
 
1794
        }
 
1795
    }
 
1796
}
 
1797
 
 
1798
void toWorksheet::showInsertSaved(void)
 
1799
{
 
1800
    static QRegExp colon(QString::fromLatin1(":"));
 
1801
    std::list<QCString> def = toSQL::range(TOWORKSHEET);
 
1802
    InsertSavedMenu->clear();
 
1803
    std::map<QString, QPopupMenu *> menues;
 
1804
    int id = 0;
 
1805
    for (std::list<QCString>::iterator sql = def.begin();sql != def.end();sql++)
 
1806
    {
 
1807
 
 
1808
        id++;
 
1809
 
 
1810
        QStringList spl = QStringList::split(colon, QString::fromLatin1(*sql));
 
1811
        spl.remove(spl.begin());
 
1812
 
 
1813
        if (spl.count() > 0)
 
1814
        {
 
1815
            QString name = spl.last();
 
1816
            spl.remove(spl.fromLast());
 
1817
 
 
1818
            QPopupMenu *menu;
 
1819
            if (spl.count() == 0)
 
1820
                menu = InsertSavedMenu;
 
1821
            else
 
1822
            {
 
1823
                QStringList exs = spl;
 
1824
                while (exs.count() > 0 && menues.find(exs.join(QString::fromLatin1(":"))) == menues.end())
 
1825
                    exs.remove(exs.fromLast());
 
1826
                if (exs.count() == 0)
 
1827
                    menu = InsertSavedMenu;
 
1828
                else
 
1829
                    menu = menues[exs.join(QString::fromLatin1(":"))];
 
1830
                QString subname = exs.join(QString::fromLatin1(":"));
 
1831
                for (unsigned int i = exs.count();i < spl.count();i++)
 
1832
                {
 
1833
                    QPopupMenu *next = new QPopupMenu(this);
 
1834
                    connect(next, SIGNAL(activated(int)), this, SLOT(insertSaved(int)));
 
1835
                    if (i != 0)
 
1836
                        subname += QString::fromLatin1(":");
 
1837
                    subname += spl[i];
 
1838
                    menu->insertItem(spl[i], next);
 
1839
                    menu = next;
 
1840
                    menues[subname] = menu;
 
1841
                }
 
1842
            }
 
1843
            menu->insertItem(name, id);
 
1844
        }
 
1845
    }
 
1846
}
 
1847
 
 
1848
 
 
1849
void toWorksheet::editSaved(void)
 
1850
{
 
1851
    QCString sql = TOWORKSHEET;
 
1852
    sql += "Untitled";
 
1853
    toMainWidget()->editSQL(QString::fromLatin1(sql));
 
1854
}
 
1855
 
 
1856
void toWorksheet::selectSaved()
 
1857
{
 
1858
    SavedMenu->popup(SavedButton->mapToGlobal(QPoint(0, SavedButton->height())));
 
1859
}
 
1860
 
 
1861
void toWorksheet::insertStatement(const QString &str)
 
1862
{
 
1863
    QString txt = Editor->text();
 
1864
 
 
1865
    int i = txt.find(str);
 
1866
 
 
1867
    if (i >= 0)
 
1868
    {
 
1869
        int startCol, endCol;
 
1870
        int startRow, endRow;
 
1871
        
 
1872
        Editor->findPosition(i, startRow, startCol);
 
1873
        Editor->findPosition(i + str.length(), endRow, endCol);
 
1874
        
 
1875
        if (Editor->text(endRow).at(endCol) == ';')
 
1876
            endCol++;
 
1877
        Editor->setSelection(startRow, startCol, endRow, endCol);
 
1878
    }
 
1879
    else
 
1880
    {
 
1881
        QString t = str;
 
1882
        if (str.right(1) != ";")
 
1883
        {
 
1884
            t += ";";
 
1885
        }
 
1886
 
 
1887
        Editor->insert(t, true);
 
1888
    }
 
1889
}
 
1890
 
 
1891
void toWorksheet::executePreviousLog(void)
 
1892
{
 
1893
    if (Light)
 
1894
        return ;
 
1895
 
 
1896
    Result->stop();
 
1897
 
 
1898
    LastLine = LastOffset = -1;
 
1899
    saveHistory();
 
1900
 
 
1901
    QListViewItem *item = Logging->currentItem();
 
1902
    if (item)
 
1903
    {
 
1904
        QListViewItem *pt = Logging->firstChild();
 
1905
        while (pt && pt->nextSibling() != item)
 
1906
            pt = pt->nextSibling();
 
1907
 
 
1908
        if (pt)
 
1909
            Logging->setSelected(pt, true);
 
1910
    }
 
1911
}
 
1912
 
 
1913
void toWorksheet::executeLog(void)
 
1914
{
 
1915
    if (Light)
 
1916
        return ;
 
1917
 
 
1918
    Result->stop();
 
1919
 
 
1920
    LastLine = LastOffset = -1;
 
1921
    saveHistory();
 
1922
 
 
1923
    QListViewItem *ci = Logging->currentItem();
 
1924
    toResultViewItem *item = dynamic_cast<toResultViewItem *>(ci);
 
1925
    if (item)
 
1926
    {
 
1927
        insertStatement(item->allText(0));
 
1928
 
 
1929
        if (item->text(4).isEmpty())
 
1930
        {
 
1931
            if (!WorksheetTool.config(CONF_EXEC_LOG, "").isEmpty())
 
1932
                query(item->allText(0), Normal);
 
1933
        }
 
1934
        else
 
1935
        {
 
1936
            std::map<int, QWidget *>::iterator i = History.find(item->text(4).toInt());
 
1937
            QueryString = item->allText(0);
 
1938
            changeResult(ResultTab->currentPage());
 
1939
            if (i != History.end() && (*i).second)
 
1940
            {
 
1941
                Current->hide();
 
1942
                Current = (*i).second;
 
1943
                Current->show();
 
1944
            }
 
1945
        }
 
1946
    }
 
1947
}
 
1948
 
 
1949
void toWorksheet::executeNextLog(void)
 
1950
{
 
1951
    if (Light)
 
1952
        return ;
 
1953
 
 
1954
    Result->stop();
 
1955
 
 
1956
    LastLine = LastOffset = -1;
 
1957
    saveHistory();
 
1958
 
 
1959
    QListViewItem *item = Logging->currentItem();
 
1960
    if (item && item->nextSibling())
 
1961
    {
 
1962
        toResultViewItem *next = dynamic_cast<toResultViewItem *>(item->nextSibling());
 
1963
        if (next)
 
1964
            Logging->setSelected(next, true);
 
1965
    }
 
1966
}
 
1967
 
 
1968
void toWorksheet::poll(void)
 
1969
{
 
1970
    Started->setText(duration(Timer.elapsed(), false));
 
1971
}
 
1972
 
 
1973
void toWorksheet::saveLast(void)
 
1974
{
 
1975
    if (QueryString.isEmpty())
 
1976
    {
 
1977
        TOMessageBox::warning(this, tr("No SQL to save"),
 
1978
                              tr("You haven't executed any SQL yet"),
 
1979
                              tr("&Ok"));
 
1980
        return ;
 
1981
    }
 
1982
    bool ok = false;
 
1983
    QCString name = QInputDialog::getText(tr("Enter title"),
 
1984
                                          tr("Enter the title in the menu of the saved SQL,\n"
 
1985
                                             "submenues are separated by a ':' character."),
 
1986
                                          QLineEdit::Normal, QString::null, &ok, this).latin1();
 
1987
    if (ok && !name.isEmpty())
 
1988
    {
 
1989
        try
 
1990
        {
 
1991
            toSQL::updateSQL(TOWORKSHEET + name,
 
1992
                             QueryString,
 
1993
                             tr("Undescribed"),
 
1994
                             "Any",
 
1995
                             connection().provider());
 
1996
            toSQL::saveSQL(toConfigurationSingle::Instance().globalConfig(CONF_SQL_FILE, DEFAULT_SQL_FILE));
 
1997
        }
 
1998
        TOCATCH
 
1999
    }
 
2000
}
 
2001
 
 
2002
void toWorksheet::saveStatistics(void)
 
2003
{
 
2004
    std::map<QCString, QString> stat;
 
2005
 
 
2006
    Statistics->exportData(stat, "Stat");
 
2007
    IOChart->exportData(stat, "IO");
 
2008
    WaitChart->exportData(stat, "Wait");
 
2009
    if (Plan->firstChild())
 
2010
        Plan->exportData(stat, "Plan");
 
2011
    else
 
2012
        toStatusMessage(tr("No plan available to save"), false, false);
 
2013
    stat["Description"] = QueryString;
 
2014
 
 
2015
    toWorksheetStatistic::saveStatistics(stat);
 
2016
}
 
2017
 
 
2018
void toWorksheet::exportData(std::map<QCString, QString> &data, const QCString &prefix)
 
2019
{
 
2020
    Editor->exportData(data, prefix + ":Edit");
 
2021
    if (StatisticButton->isOn())
 
2022
        data[prefix + ":Stats"] = Refresh->currentText();
 
2023
    toToolWidget::exportData(data, prefix);
 
2024
}
 
2025
 
 
2026
void toWorksheet::importData(std::map<QCString, QString> &data, const QCString &prefix)
 
2027
{
 
2028
    Editor->importData(data, prefix + ":Edit");
 
2029
    QString stat = data[prefix + ":Stats"];
 
2030
    if (stat)
 
2031
    {
 
2032
        for (int i = 0;i < Refresh->count();i++)
 
2033
        {
 
2034
            if (Refresh->text(i) == stat)
 
2035
            {
 
2036
                Refresh->setCurrentItem(i);
 
2037
                break;
 
2038
            }
 
2039
        }
 
2040
        StatisticButton->setOn(true);
 
2041
    }
 
2042
    else
 
2043
        StatisticButton->setOn(false);
 
2044
 
 
2045
    toToolWidget::importData(data, prefix);
 
2046
    setCaption();
 
2047
}
 
2048
 
 
2049
void toWorksheet::setCaption(void)
 
2050
{
 
2051
    QString name = WorksheetTool.name();
 
2052
    if (! Editor->filename().isEmpty())
 
2053
    {
 
2054
        QFileInfo file(Editor->filename());
 
2055
        name += QString::fromLatin1(" ") + file.fileName();
 
2056
    }
 
2057
    toToolCaption(this, name);
 
2058
}
 
2059
 
 
2060
toWorksheet *toWorksheet::fileWorksheet(const QString &file)
 
2061
{
 
2062
    toWorksheet *worksheet = new toWorksheet(toMainWidget()->workspace(),
 
2063
                             toMainWidget()->currentConnection(),
 
2064
                             false);
 
2065
    worksheet->editor()->openFilename(file);
 
2066
    worksheet->setCaption();
 
2067
    worksheet->show();
 
2068
    toMainWidget()->windowsMenu();
 
2069
    return worksheet;
 
2070
}
 
2071
 
 
2072
void toWorksheet::refreshSetup(void)
 
2073
{
 
2074
    bool ok = false;
 
2075
    int num = QInputDialog::getInteger(tr("Enter refreshrate"),
 
2076
                                       tr("Refresh rate of query in seconds"),
 
2077
                                       RefreshSeconds, 0, 1000000, 1, &ok, this);
 
2078
    if (ok)
 
2079
    {
 
2080
        RefreshSeconds = num;
 
2081
        RefreshTimer.start(num*1000);
 
2082
    }
 
2083
    else
 
2084
        RefreshTimer.stop();
 
2085
}
 
2086
 
 
2087
void toWorksheet::stop(void)
 
2088
{
 
2089
    RefreshTimer.stop();
 
2090
    Result->stop();
 
2091
}
 
2092
 
 
2093
void toWorksheet::displayMenu(QPopupMenu *menu)
 
2094
{
 
2095
    menu->insertSeparator(0);
 
2096
    if (!Light)
 
2097
    {
 
2098
        menu->insertItem(tr("&Explain current statement"), this, SLOT(explainPlan(void)),
 
2099
                         toKeySequence(tr("F3", "Worksheet|Explain plan")), TO_ID_PLAN, 0);
 
2100
        menu->insertItem(QPixmap(const_cast<const char**>(describe_xpm)),
 
2101
                         tr("&Describe Under Cursor"), this, SLOT(describe(void)),
 
2102
                         toKeySequence(tr("F4", "Worksheet|Describe under cursor")), 0, 0);
 
2103
        menu->insertSeparator(0);
 
2104
    }
 
2105
    if (connection().provider() == "Oracle")
 
2106
        menu->insertItem(tr("Check syntax of buffer"),
 
2107
                         this, SLOT(parseAll()),
 
2108
                         toKeySequence(tr("Ctrl+F9", "Worksheet|Check syntax of buffer")), 0, 0);
 
2109
    menu->insertItem(QPixmap(const_cast<const char**>(refresh_xpm)),
 
2110
                     tr("&Reexecute Last Statement"), this, SLOT(refresh(void)),
 
2111
                     toKeySequence(tr("F5", "Worksheet|Reexecute last statement")), 0, 0);
 
2112
    menu->insertItem(tr("Execute &Newline Separated"), this,
 
2113
                     SLOT(executeNewline(void)),
 
2114
                     toKeySequence(tr("Shift+F9", "Worksheet|Execute newline separated")), 0, 0);
 
2115
    menu->insertItem(QPixmap(const_cast<const char**>(executeall_xpm)),
 
2116
                     tr("Execute &All"), this, SLOT(executeAll(void)),
 
2117
                     toKeySequence(tr("F8", "Worksheet|Execute all")), 0, 0);
 
2118
    menu->insertItem(QPixmap(const_cast<const char**>(executestep_xpm)),
 
2119
                     tr("Execute &Next"), this, SLOT(executeStep(void)),
 
2120
                     toKeySequence(tr("F9", "Worksheet|Execute next")), 0, 0);
 
2121
    menu->insertItem(QPixmap(const_cast<const char**>(execute_xpm)),
 
2122
                     tr("&Execute Current"), this, SLOT(execute(void)),
 
2123
                     toKeySequence(tr("Ctrl+Return", "Worksheet|Execute current")), 0, 0);
 
2124
 
 
2125
    menu->insertSeparator();
 
2126
    if (!Light)
 
2127
    {
 
2128
        if (connection().provider() == "Oracle")
 
2129
            menu->insertItem(tr("&Enable Statistics"), this, SLOT(toggleStatistic(void)),
 
2130
                             0, TO_ID_STATISTICS);
 
2131
    }
 
2132
    menu->insertItem(QPixmap(const_cast<const char**>(stop_xpm)),
 
2133
                     tr("&Stop Execution"), Result, SLOT(stop(void)),
 
2134
                     0, TO_ID_STOP);
 
2135
    if (!Light)
 
2136
    {
 
2137
        menu->insertSeparator();
 
2138
        menu->insertItem(tr("Execute Saved SQL"),
 
2139
                         this, SLOT(executeSaved()),
 
2140
                         toKeySequence(tr("F7", "Worksheet|Execute saved SQL")));
 
2141
        menu->insertItem(tr("Insert Saved SQL"),
 
2142
                         this, SLOT(insertSaved()),
 
2143
                         toKeySequence(tr("Shift+F7", "Worksheet|Insert saved SQL")));
 
2144
        menu->insertItem(tr("Select Saved SQL"),
 
2145
                         this, SLOT(selectSaved()),
 
2146
                         toKeySequence(tr("Ctrl+Shift+S", "Worksheet|Select saved SQL")));
 
2147
        menu->insertItem(QPixmap(const_cast<const char**>(previous_xpm)),
 
2148
                         tr("Save last SQL"),
 
2149
                         this, SLOT(saveLast()));
 
2150
    }
 
2151
}
 
2152
 
 
2153
#define CHANGE_CURRENT_SCHEMA QString("ALTER SESSION SET CURRENT_SCHEMA = ")
 
2154
 
 
2155
void toWorksheet::changeSchema(void)
 
2156
{
 
2157
    try
 
2158
    {
 
2159
        QString schema = Schema->selected();
 
2160
        toConnection &conn = connection();
 
2161
        if (toIsOracle(conn))
 
2162
        {
 
2163
            QString sql = CHANGE_CURRENT_SCHEMA + schema;
 
2164
            conn.allExecute(sql);
 
2165
            for (std::list<QString>::const_iterator i = conn.initStrings().begin();i != conn.initStrings().end();i++)
 
2166
            {
 
2167
                if ((*i).startsWith(CHANGE_CURRENT_SCHEMA))
 
2168
                {
 
2169
                    conn.delInit(*i);
 
2170
                    break;
 
2171
                }
 
2172
            }
 
2173
            conn.addInit(sql);
 
2174
        }
 
2175
        else if (toIsMySQL(conn))
 
2176
        {
 
2177
            conn.allExecute(QString("USE %1").arg(schema));
 
2178
            conn.setDatabase(schema);
 
2179
        }
 
2180
        else
 
2181
            throw QString("No support for changing schema for this database");
 
2182
    }
 
2183
    TOCATCH
 
2184
}