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

« back to all changes in this revision

Viewing changes to todebugtext.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 "toconnection.h"
41
 
#include "todebug.h"
42
 
#include "todebugtext.h"
43
 
#include "tosql.h"
44
 
#include "todebugtext.moc"
45
 
 
46
 
#include <qapplication.h>
47
 
#include <qpainter.h>
48
 
#include <qpixmap.h>
49
 
 
50
 
#include "icons/breakpoint.xpm"
51
 
#include "icons/disbreakpoint.xpm"
52
 
 
53
 
#define TO_BREAK_COL 5
54
 
 
55
 
int toDebugText::ID = 0;
56
 
 
57
 
toBreakpointItem::toBreakpointItem(QListView *parent, QListViewItem *after,
58
 
                                   const QString &schema, const QString &type,
59
 
                                   const QString &object, int line)
60
 
        : QListViewItem(parent, after)
61
 
{
62
 
    if (schema.isNull())
63
 
        setText(2, QString::null);
64
 
    else
65
 
        setText(2, schema);
66
 
    if (object.isNull())
67
 
        setText(0, QString::null);
68
 
    else
69
 
        setText(0, object);
70
 
    if (type.isNull())
71
 
        setText(3, QString::null);
72
 
    else
73
 
        setText(3, type);
74
 
    setText(1, QString::number(line + 1));
75
 
    if (type == QString::fromLatin1("PACKAGE") ||
76
 
            type == QString::fromLatin1("PROCEDURE") ||
77
 
            type == QString::fromLatin1("FUNCTION") ||
78
 
            type == QString::fromLatin1("TYPE"))
79
 
        Namespace = TO_NAME_TOPLEVEL;
80
 
    else if (type == QString::fromLatin1("PACKAGE BODY") ||
81
 
             type == QString::fromLatin1("TYPE BODY"))
82
 
        Namespace = TO_NAME_BODY;
83
 
    else
84
 
        Namespace = TO_NAME_NONE;
85
 
    Line = line;
86
 
    setText(4, qApp->translate("toDebug", "DEFERED"));
87
 
}
88
 
 
89
 
static toSQL SQLBreakpoint("toDebug:SetBreakpoint",
90
 
                           "DECLARE\n"
91
 
                           "    proginf SYS.DBMS_DEBUG.PROGRAM_INFO;\n"
92
 
                           "    bnum BINARY_INTEGER;\n"
93
 
                           "    ret BINARY_INTEGER;\n"
94
 
                           "BEGIN\n"
95
 
                           "    proginf.Namespace:=:type<int,in>;\n"
96
 
                           "    proginf.Name:=:name<char[100],in>;\n"
97
 
                           "    proginf.Owner:=:schema<char[100],in>;\n"
98
 
                           "    proginf.DbLink:=NULL;\n"
99
 
                           "    proginf.LibUnitType:=SYS.DBMS_DEBUG.LibUnitType_Procedure;\n"
100
 
                           "    proginf.EntryPointName:=NULL;\n"
101
 
                           "    proginf.Line#:=:line<int,in>;\n"
102
 
                           "    ret:=SYS.DBMS_DEBUG.SET_BREAKPOINT(proginf,proginf.Line#,bnum,0,1);\n"
103
 
                           "    SELECT ret,bnum INTO :ret<int,out>,:bnum<int,out> FROM sys.DUAL;\n"
104
 
                           "END;",
105
 
                           "Set breakpoint, must have same bindings");
106
 
 
107
 
 
108
 
void toBreakpointItem::setBreakpoint(void)
109
 
{
110
 
    bool ok = false;
111
 
    try
112
 
    {
113
 
        try
114
 
        {
115
 
            clearBreakpoint();
116
 
        }
117
 
        TOCATCH // I don't the removal of the breakpoint to interact with the setting of the breakpoint
118
 
        toConnection &conn = toCurrentConnection(listView());
119
 
        toQList args;
120
 
        toPush(args, toQValue(Namespace));
121
 
        toPush(args, toQValue(text(0)));
122
 
        toPush(args, toQValue(text(2)));
123
 
        toPush(args, toQValue(Line + 1));
124
 
        toQuery query(conn, SQLBreakpoint, args);
125
 
        int ret = query.readValue().toInt();
126
 
        if (ret == TO_SUCCESS)
127
 
        {
128
 
            setText(TO_BREAK_COL, query.readValue());
129
 
            setText(4, qApp->translate("toDebug", "ENABLED"));
130
 
            ok = true;
131
 
        }
132
 
        else if (ret == TO_ERROR_ILLEGAL_LINE)
133
 
        {
134
 
            toStatusMessage(qApp->translate("toDebug", "Can not enable breakpoint, not a valid line. Perhaps needs to recompile."));
135
 
        }
136
 
        else if (ret == TO_ERROR_BAD_HANDLE)
137
 
        {
138
 
            toStatusMessage(qApp->translate("toDebug", "Can not enable breakpoint, not a valid object. Perhaps needs to compile."));
139
 
        }
140
 
    }
141
 
    TOCATCH
142
 
    if (!ok)
143
 
        setText(4, qApp->translate("toDebug", "NOT SET"));
144
 
}
145
 
 
146
 
static toSQL SQLClearBreakpoint("toDebug:ClearBreakpoint",
147
 
                                "DECLARE\n"
148
 
                                "    bnum BINARY_INTEGER;\n"
149
 
                                "    ret BINARY_INTEGER;\n"
150
 
                                "BEGIN\n"
151
 
                                "    bnum:=:bnum<int,in>;\n"
152
 
                                "    ret:=SYS.DBMS_DEBUG.DELETE_BREAKPOINT(bnum);\n"
153
 
                                "    SELECT ret INTO :ret<int,out> FROM sys.DUAL;\n"
154
 
                                "END;",
155
 
                                "Clear breakpoint, must have same bindings");
156
 
 
157
 
/** If something goes wrong it throws an exception (type QString with the error message */
158
 
void toBreakpointItem::clearBreakpoint()
159
 
{
160
 
    if (text(4) == qApp->translate("toDebug", "ENABLED") && !text(TO_BREAK_COL).isEmpty())
161
 
    {
162
 
        toConnection &conn = toCurrentConnection(listView());
163
 
        toQList args;
164
 
        toPush(args, toQValue(text(TO_BREAK_COL)));
165
 
        toQuery query(conn, SQLClearBreakpoint, args);
166
 
        int res = query.readValue().toInt();
167
 
 
168
 
        if (res != TO_SUCCESS && res != TO_NO_SUCH_BREAKPOINT)
169
 
        {
170
 
            QString message = qApp->translate("toDebug", "Failed to remove breakpoint (Reason %1)").arg(res);
171
 
            toStatusMessage(message);
172
 
            throw(message);
173
 
        }
174
 
 
175
 
    }
176
 
    setText(4, qApp->translate("toDebug", "DISABLED"));
177
 
}
178
 
 
179
 
#define DEBUG_INDENT 10
180
 
 
181
 
static toSQL SQLReadSource("toDebug:ReadSource",
182
 
                           "SELECT Text FROM SYS.All_Source\n"
183
 
                           " WHERE OWNER = :f1<char[101]>\n"
184
 
                           "   AND NAME = :f2<char[101]>\n"
185
 
                           "   AND TYPE = :f3<char[101]>\n"
186
 
                           " ORDER BY Type,Line",
187
 
                           "Read sourcecode for object");
188
 
static toSQL SQLReadErrors("toDebug:ReadErrors",
189
 
                           "SELECT Line-1,Text FROM SYS.All_Errors\n"
190
 
                           " WHERE OWNER = :f1<char[101]>\n"
191
 
                           "   AND NAME = :f2<char[101]>\n"
192
 
                           "   AND TYPE = :f3<char[101]>\n"
193
 
                           " ORDER BY Type,Line",
194
 
                           "Get lines with errors in object (Observe first line 0)");
195
 
 
196
 
bool toDebugText::readErrors(toConnection &conn)
197
 
{
198
 
    try
199
 
    {
200
 
        toQuery errors(conn, SQLReadErrors, Schema, Object, Type);
201
 
        std::map<int, QString> Errors;
202
 
 
203
 
        while (!errors.eof())
204
 
        {
205
 
            int line = errors.readValue().toInt();
206
 
            Errors[line] += QString::fromLatin1(" ");
207
 
            Errors[line] += errors.readValue();
208
 
        }
209
 
        setErrors(Errors);
210
 
        return true;
211
 
    }
212
 
    TOCATCH
213
 
    return false;
214
 
}
215
 
bool toDebugText::readData(toConnection &conn, QListView *Stack)
216
 
{
217
 
    QListViewItem *item = NULL;
218
 
    if (Stack && Stack->firstChild())
219
 
        for (item = Stack->firstChild();item->firstChild();item = item->firstChild())
220
 
            ;
221
 
    try
222
 
    {
223
 
        toQuery lines(conn, SQLReadSource, Schema, Object, Type);
224
 
 
225
 
        QString str;
226
 
        while (!lines.eof())
227
 
            str += lines.readValue();
228
 
        setText(str);
229
 
        setModified(false);
230
 
        setCurrent( -1);
231
 
 
232
 
        if (str.isEmpty())
233
 
            return false;
234
 
        else
235
 
        {
236
 
            if (item &&
237
 
                    Schema == item->text(2) &&
238
 
                    Object == item->text(0) &&
239
 
                    Type == item->text(3))
240
 
                setCurrent(item->text(1).toInt() - 1);
241
 
 
242
 
            return readErrors(conn);
243
 
        }
244
 
    }
245
 
    TOCATCH
246
 
    return false;
247
 
}
248
 
 
249
 
void toDebugText::setData(const QString &schema, const QString &type, const QString &object)
250
 
{
251
 
    Schema = schema;
252
 
    Type = type;
253
 
    Object = object;
254
 
    CurrentItem = FirstItem = NULL;
255
 
    NoBreakpoints = false;
256
 
    update();
257
 
}
258
 
 
259
 
toDebugText::toDebugText(QListView *breakpoints,
260
 
                         QWidget *parent,
261
 
                         toDebug *debugger)
262
 
        : toHighlightedText(parent, QString::number(++ID).latin1()),
263
 
        Debugger(debugger),
264
 
        Breakpoints(breakpoints)
265
 
{
266
 
    //setLeftIgnore(DEBUG_INDENT);
267
 
    setMarginWidth(0, 25);
268
 
    setMarginWidth(1, 10);
269
 
    setMarginSensitivity(0,true);
270
 
    setMarginSensitivity(1,true);
271
 
    CurrentItem = FirstItem = NULL;
272
 
    NoBreakpoints = false;
273
 
    connect(this,SIGNAL(marginClicked(int, int, Qt::ButtonState)),this, SLOT(toggleBreakpoint(int, int, Qt::ButtonState)));
274
 
    breakMarker=markerDefine(new QPixmap(const_cast<const char**>(breakpoint_xpm)));
275
 
    disabledBreakMarker=markerDefine(new QPixmap(const_cast<const char**>(disbreakpoint_xpm)));
276
 
    setMarginMarkerMask(1,2^breakMarker|2^disabledBreakMarker);
277
 
}
278
 
 
279
 
bool toDebugText::checkItem(toBreakpointItem *item)
280
 
{
281
 
    if (!item)
282
 
        return false;
283
 
    if (item->text(2) == Schema &&
284
 
            item->text(3) == Type &&
285
 
            item->text(0) == Object)
286
 
        return true;
287
 
    return false;
288
 
}
289
 
 
290
 
void toDebugText::clear(void)
291
 
{
292
 
    setData(QString::null, QString::null, QString::null);
293
 
    FirstItem = CurrentItem = NULL;
294
 
    NoBreakpoints = false;
295
 
    toHighlightedText::clear();
296
 
}
297
 
 
298
 
bool toDebugText::hasBreakpoint(int row) // This has to leave CurrentItem on the breakpoint
299
 
{
300
 
    if (!FirstItem && !NoBreakpoints)
301
 
    {
302
 
        FirstItem = dynamic_cast<toBreakpointItem *>(Breakpoints->firstChild());
303
 
        while (!checkItem(FirstItem) && FirstItem)
304
 
            FirstItem = dynamic_cast<toBreakpointItem *>(FirstItem->nextSibling());
305
 
        if (!FirstItem)
306
 
            NoBreakpoints = true;
307
 
        CurrentItem = FirstItem;
308
 
    }
309
 
 
310
 
    if (!NoBreakpoints)
311
 
    {
312
 
        toBreakpointItem *next = dynamic_cast<toBreakpointItem *>(CurrentItem->nextSibling());
313
 
        bool hasNext = checkItem(next);
314
 
        int nextLine = hasNext ? next->line() : row + 1;
315
 
 
316
 
        if (CurrentItem->line() == row)
317
 
            return true;
318
 
        if (row == nextLine)
319
 
        {
320
 
            CurrentItem = next;
321
 
            return true;
322
 
        }
323
 
        if (!hasNext && row > CurrentItem->line())
324
 
            return false;
325
 
        if (row < CurrentItem->line())
326
 
        {
327
 
            if (CurrentItem == FirstItem)
328
 
                return false;
329
 
            CurrentItem = FirstItem;
330
 
            return hasBreakpoint(row);
331
 
        }
332
 
        if (row > nextLine)
333
 
        {
334
 
            CurrentItem = next;
335
 
            return hasBreakpoint(row);
336
 
        }
337
 
    }
338
 
    return false;
339
 
}
340
 
 
341
 
void toDebugText::mouseMoveEvent(QMouseEvent *me)
342
 
{
343
 
    QRect view = childrenRect ();
344
 
    if (me->x() > DEBUG_INDENT + view.left())
345
 
    {
346
 
        if (LastX <= DEBUG_INDENT + view.left())
347
 
            setCursor(Qt::ibeamCursor);
348
 
        if (me->state() != 0)
349
 
            toHighlightedText::mouseMoveEvent(me);
350
 
    }
351
 
    else
352
 
    {
353
 
        if (LastX > DEBUG_INDENT + view.left())
354
 
            setCursor(Qt::ibeamCursor);
355
 
        setCursor(Qt::arrowCursor);
356
 
    }
357
 
    LastX = me->x();
358
 
}
359
 
 
360
 
void toDebugText::toggleBreakpoint(int row, bool enable)
361
 
{
362
 
    if (Schema.isEmpty() ||
363
 
            Type.isEmpty() ||
364
 
            Object.isEmpty())
365
 
        return ;
366
 
 
367
 
    int curcol;
368
 
    if (row < 0)
369
 
        getCursorPosition (&row, &curcol);
370
 
    if (row >= 0)
371
 
    {
372
 
        if (hasBreakpoint(row))
373
 
        {
374
 
            try
375
 
            {
376
 
                if (enable)
377
 
                {
378
 
                    if (CurrentItem->text(4) == qApp->translate("toDebug", "DISABLED")){
379
 
                        CurrentItem->setText(4, qApp->translate("toDebug", "DEFERED"));
380
 
                        markerDelete(row,disabledBreakMarker);
381
 
                        markerAdd(row,breakMarker);
382
 
                    }else{
383
 
                        CurrentItem->clearBreakpoint();
384
 
                        markerDelete(row,breakMarker);
385
 
                        markerAdd(row,disabledBreakMarker);
386
 
                    }
387
 
                }
388
 
                else
389
 
                {
390
 
                    CurrentItem->clearBreakpoint();
391
 
                    delete CurrentItem;
392
 
                    markerDelete(row,breakMarker);
393
 
                    markerDelete(row,disabledBreakMarker);
394
 
                    if (FirstItem == CurrentItem)
395
 
                    {
396
 
                        NoBreakpoints = false;
397
 
                        CurrentItem = FirstItem = NULL;
398
 
                    }
399
 
                    else
400
 
                        CurrentItem = FirstItem;
401
 
                }
402
 
            }
403
 
            TOCATCH
404
 
 
405
 
        }
406
 
        else if (!enable)
407
 
        {
408
 
            markerAdd(row,breakMarker);
409
 
            if (CurrentItem && CurrentItem->line() > row)
410
 
                new toBreakpointItem(Breakpoints, NULL,
411
 
                                     Schema, Type, Object, row);
412
 
            else
413
 
                new toBreakpointItem(Breakpoints, CurrentItem,
414
 
                                     Schema, Type, Object, row);
415
 
            FirstItem = CurrentItem = NULL;
416
 
            NoBreakpoints = false;
417
 
        }
418
 
        //updateCell(row, 0, false);
419
 
    }
420
 
}
421
 
 
422
 
 
423
 
void toDebugText::toggleBreakpoint(int margin, int line, Qt::ButtonState   state){
424
 
  if(margin<=1) 
425
 
    toggleBreakpoint(line);
426
 
}
427
 
 
428
 
 
429
 
void toDebugText::exportData(std::map<QCString, QString> &data, const QCString &prefix)
430
 
{
431
 
    toHighlightedText::exportData(data, prefix);
432
 
    data[prefix + ":Schema"] = Schema;
433
 
    data[prefix + ":Object"] = Object;
434
 
    data[prefix + ":Type"] = Type;
435
 
}
436
 
 
437
 
void toDebugText::importData(std::map<QCString, QString> &data, const QCString &prefix)
438
 
{
439
 
    toHighlightedText::importData(data, prefix);
440
 
    Schema = data[prefix + ":Schema"];
441
 
    Object = data[prefix + ":Object"];
442
 
    Type = data[prefix + ":Type"];
443
 
    NoBreakpoints = false;
444
 
}