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

« back to all changes in this revision

Viewing changes to src/toparamget.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 "toconf.h"
 
41
#include "tohelp.h"
 
42
#include "tomemoeditor.h"
 
43
#include "toparamget.h"
 
44
#include "totool.h"
 
45
 
 
46
#include <qapplication.h>
 
47
#include <qcheckbox.h>
 
48
#include <qcombobox.h>
 
49
#include <qgrid.h>
 
50
#include <qlabel.h>
 
51
#include <qlayout.h>
 
52
#include <qlineedit.h>
 
53
#include <qpalette.h>
 
54
#include <qpushbutton.h>
 
55
#include <qregexp.h>
 
56
#include <qscrollview.h>
 
57
#include <qsizepolicy.h>
 
58
 
 
59
#include "toparamget.moc"
 
60
 
 
61
std::map<QString, std::list<QString> > toParamGet::DefaultCache;
 
62
std::map<QString, std::list<QString> > toParamGet::Cache;
 
63
 
 
64
toParamGet::toParamGet(QWidget *parent, const char *name)
 
65
        : QDialog(parent, name, true), toHelpContext(QString::fromLatin1("common.html#param"))
 
66
{
 
67
    toHelp::connectDialog(this);
 
68
    resize(500, 480);
 
69
    setCaption(tr("Define binding variables"));
 
70
 
 
71
    QGridLayout *layout = new QGridLayout(this, 3, 2);
 
72
    layout->setSpacing( 6 );
 
73
    layout->setMargin( 11 );
 
74
 
 
75
    View = new QScrollView(this);
 
76
    View->enableClipper(true);
 
77
    View->setGeometry(10, 10, 330, 480);
 
78
    View->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
 
79
    layout->addMultiCellWidget(View, 0, 2, 0, 0);
 
80
 
 
81
    Container = new QGrid(4, View->viewport());
 
82
    View->addChild(Container, 5, 5);
 
83
    Container->setSpacing(10);
 
84
    Container->setFixedWidth(View->width() - 30);
 
85
    View->viewport()->setBackgroundColor(qApp->palette().active().background());
 
86
 
 
87
    QPushButton *OkButton = new QPushButton(this, "OkButton");
 
88
    OkButton->setText(tr("&Ok"));
 
89
    OkButton->setDefault(true);
 
90
    layout->addWidget(OkButton, 0, 1);
 
91
 
 
92
    QPushButton *CancelButton = new QPushButton(this, "CancelButton");
 
93
    CancelButton->setText(tr("Cancel"));
 
94
    CancelButton->setDefault(false);
 
95
    layout->addWidget(CancelButton, 1, 1);
 
96
 
 
97
    QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
 
98
    layout->addItem(spacer, 2, 1);
 
99
 
 
100
    connect(OkButton, SIGNAL(clicked()), this, SLOT(accept()));
 
101
    connect(CancelButton, SIGNAL(clicked()), this, SLOT(reject()));
 
102
}
 
103
 
 
104
toQList toParamGet::getParam(toConnection &conn, QWidget *parent, QString &str, bool interactive)
 
105
{
 
106
    std::map<QString, bool> parameters;
 
107
    std::list<QString> names;
 
108
    toParamGet *widget = NULL;
 
109
 
 
110
    enum {
 
111
        afterName,
 
112
        inString,
 
113
        normal,
 
114
        comment,
 
115
        multiComment,
 
116
        name,
 
117
        specification,
 
118
        endInput
 
119
    } state;
 
120
    state = normal;
 
121
 
 
122
    QChar endString;
 
123
    QString fname;
 
124
    QString direction;
 
125
    QString res;
 
126
 
 
127
    QString def = QString::fromLatin1("<char[4000]>");
 
128
 
 
129
    int colon = 1;
 
130
 
 
131
    int num = 0;
 
132
    for (unsigned int i = 0;i < str.length() + 1;i++)
 
133
    {
 
134
        QChar c;
 
135
        QChar nc;
 
136
        QChar pc;
 
137
 
 
138
        c = nc = pc = '\n';
 
139
 
 
140
        if(i < str.length())
 
141
            c = str.at(i);
 
142
 
 
143
        if(i < str.length() - 1)
 
144
            nc = str.at(i + 1);
 
145
 
 
146
        if(i - 1 > 0)
 
147
            pc = str.at(i - 1);
 
148
 
 
149
        if (state == normal && c == '-' && nc == '-')
 
150
            state = comment;
 
151
        else if (state == normal && c == '/' && nc == '*')
 
152
            state = multiComment;
 
153
        else
 
154
        {
 
155
            switch (state)
 
156
            {
 
157
            case inString:
 
158
                if (c == endString)
 
159
                    state = normal;
 
160
                break;
 
161
            case comment:
 
162
                if (c == '\n')
 
163
                    state = normal;
 
164
                break;
 
165
            case multiComment:
 
166
                if (c == '*' && nc == '/')
 
167
                    state = normal;
 
168
                break;
 
169
            case normal:
 
170
                switch (c.latin1())
 
171
                {
 
172
                case '\'':
 
173
                case '\"':
 
174
                    endString = c;
 
175
                    state = inString;
 
176
                    break;
 
177
                case ':':
 
178
                    // ignore ::
 
179
                    // this is a type cast for postgres, not a parameter.
 
180
                    if(nc == ':' || pc == ':')
 
181
                        break;
 
182
 
 
183
                    if(nc != '=')
 
184
                        state = name;
 
185
                    direction = "";
 
186
                    fname = "";
 
187
                    break;
 
188
                case '?':
 
189
                    fname = QString::fromLatin1("f");
 
190
                    fname += QString::number(colon);
 
191
                    colon++;
 
192
                    res += QString::fromLatin1(":");
 
193
                    res += fname;
 
194
                    res += def.mid(0, def.length() - 1);
 
195
                    c = def.at(def.length() - 1);
 
196
                    break;
 
197
                }
 
198
                break;
 
199
            case name:
 
200
                if (c.isLetterOrNumber() || c == '_')
 
201
                {
 
202
                    fname += c;
 
203
                    break;
 
204
                }
 
205
                if (fname.isEmpty() && !toIsMySQL(conn))
 
206
                {
 
207
                    toStatusMessage(tr("Missing field name"));
 
208
                    throw tr("Missing field name");
 
209
                }
 
210
                state = afterName;
 
211
            case afterName:
 
212
                if (c == '<')
 
213
                    state = specification;
 
214
                else
 
215
                {
 
216
                    state = normal;
 
217
                    res += def;
 
218
                }
 
219
                break;
 
220
            case specification:
 
221
                if (c == ',')
 
222
                    state = endInput;
 
223
                else if (c == '>')
 
224
                    state = normal;
 
225
                break;
 
226
            case endInput:
 
227
                if (c == '>')
 
228
                    state = normal;
 
229
                else
 
230
                    direction += c;
 
231
                break;
 
232
            }
 
233
        }
 
234
        if (state == normal && !fname.isEmpty())
 
235
        {
 
236
#if 0
 
237
            fname.replace(QRegExp("_"), " ");
 
238
#endif
 
239
 
 
240
            if (direction.isEmpty() || direction == "in" || direction == "inout")
 
241
            {
 
242
                if (!parameters[fname])
 
243
                {
 
244
                    parameters[fname] = true;
 
245
                    if (!widget)
 
246
                        widget = new toParamGet(parent);
 
247
                    new QLabel(fname, widget->Container);
 
248
                    QComboBox *edit = new QComboBox(widget->Container, QString::number(num));
 
249
                    edit->setEditable(true);
 
250
                    QString defval;
 
251
                    std::map<QString, std::list<QString> >::iterator fnd = Cache.find(fname);
 
252
                    if (fnd != Cache.end())
 
253
                        for (std::list<QString>::iterator i = (*fnd).second.begin();i != (*fnd).second.end();i++)
 
254
                        {
 
255
                            if (edit->count() == 0)
 
256
                                defval = *i;
 
257
                            edit->insertItem(*i);
 
258
                        }
 
259
 
 
260
                    fnd = DefaultCache.find(fname);
 
261
                    if (fnd != DefaultCache.end())
 
262
                        for (std::list<QString>::iterator i = (*fnd).second.begin();i != (*fnd).second.end();i++)
 
263
                        {
 
264
                            if (edit->count() == 0)
 
265
                                defval = *i;
 
266
                            edit->insertItem(*i);
 
267
                        }
 
268
 
 
269
                    QCheckBox *box = new QCheckBox(tr("NULL"), widget->Container);
 
270
                    connect(box, SIGNAL(toggled(bool)), edit, SLOT(setDisabled(bool)));
 
271
                    if (edit->count() > 0)
 
272
                    {
 
273
                        if (defval.isNull())
 
274
                            box->setChecked(true);
 
275
                    }
 
276
                    toParamGetButton *btn = new toParamGetButton(num, widget->Container);
 
277
                    btn->setText(tr("Edit"));
 
278
                    btn->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
 
279
                    connect(btn, SIGNAL(clicked(int)), widget, SLOT(showMemo(int)));
 
280
                    connect(box, SIGNAL(toggled(bool)), btn, SLOT(setDisabled(bool)));
 
281
                    widget->Value.insert(widget->Value.end(), edit);
 
282
                    names.insert(names.end(), fname);
 
283
 
 
284
                    QDesktopWidget *paramDesktop = new QDesktopWidget;
 
285
                    edit->setMaximumWidth(paramDesktop->availableGeometry(edit).width()*2/3);
 
286
                    edit->setMinimumWidth(100);
 
287
                    edit->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed));
 
288
                        
 
289
                    num++;
 
290
                }
 
291
            }
 
292
            fname = "";
 
293
        }
 
294
        if (i < str.length())
 
295
            res += c;
 
296
    }
 
297
 
 
298
    toQList ret;
 
299
    if (widget)
 
300
    {
 
301
        (*widget->Value.begin())->setFocus();
 
302
        if (!interactive || widget->exec())
 
303
        {
 
304
            std::list<QString>::iterator cn = names.begin();
 
305
            for (std::list<QComboBox *>::iterator i = widget->Value.begin();i != widget->Value.end();i++)
 
306
            {
 
307
                QComboBox *current = *i;
 
308
                QString val;
 
309
                if (current)
 
310
                {
 
311
                    if (current->isEnabled())
 
312
                        val = current->currentText();
 
313
                    else
 
314
                        val = QString::null;
 
315
                }
 
316
                if (cn != names.end())
 
317
                {
 
318
                    std::list<QString> &lst = Cache[*cn];
 
319
                    for (std::list<QString>::iterator i = lst.begin();i != lst.end();i++)
 
320
                        if ((*i) == val)
 
321
                        {
 
322
                            lst.erase(i);
 
323
                            break;
 
324
                        }
 
325
                    lst.insert(lst.begin(), val);
 
326
 
 
327
                    std::map<QString, std::list<QString> >::iterator fnd = DefaultCache.find(*cn);
 
328
                    if (fnd != DefaultCache.find(*cn))
 
329
                        for (std::list<QString>::iterator i = (*fnd).second.begin();i != (*fnd).second.end();i++)
 
330
                            if ((*i) == val)
 
331
                            {
 
332
                                (*fnd).second.erase(i);
 
333
                                break;
 
334
                            }
 
335
 
 
336
                    cn++;
 
337
                }
 
338
                ret.insert(ret.end(), val);
 
339
            }
 
340
            delete widget;
 
341
        }
 
342
        else
 
343
        {
 
344
            delete widget;
 
345
            toStatusMessage(tr("Aborted execution"), false, false);
 
346
            throw tr("Aborted execution");
 
347
        }
 
348
    }
 
349
    str = res;
 
350
    return ret;
 
351
}
 
352
 
 
353
void toParamGet::setDefault(toConnection &, const QString &name, const QString &val)
 
354
{
 
355
    std::map<QString, std::list<QString> >::iterator fnd = Cache.find(name);
 
356
    if (fnd != Cache.end())
 
357
        for (std::list<QString>::iterator i = (*fnd).second.begin();i != (*fnd).second.end();i++)
 
358
            if (val == *i)
 
359
                return ;
 
360
 
 
361
    std::list<QString> &lst = DefaultCache[name];
 
362
    for (std::list<QString>::iterator i = lst.begin();i != lst.end();i++)
 
363
        if ((*i) == val)
 
364
        {
 
365
            lst.erase(i);
 
366
            break;
 
367
        }
 
368
    lst.insert(lst.begin(), val);
 
369
}
 
370
 
 
371
void toParamGet::showMemo(int row)
 
372
{
 
373
    QObject *obj = child(QString::number(row));
 
374
    if (obj)
 
375
    {
 
376
        toMemoEditor *memo = new toMemoEditor(this,
 
377
                                              ((QComboBox *) obj)->currentText(),
 
378
                                              row,
 
379
                                              0,
 
380
                                              false,
 
381
                                              true);
 
382
        if (memo->exec())
 
383
            ((QComboBox *)obj)->setCurrentText(memo->text());
 
384
    }
 
385
}
 
386
 
 
387
void toParamGet::resizeEvent(QResizeEvent *e)
 
388
{
 
389
    QDialog::resizeEvent(e);
 
390
    Container->setFixedWidth(View->width() - 30);
 
391
}