debuggerdialogs.cpp 28.4 KB
Newer Older
hjk's avatar
hjk committed
1
2
3
4
/**************************************************************************
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
5
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
hjk's avatar
hjk committed
6
**
Eike Ziller's avatar
Eike Ziller committed
7
** Contact: http://www.qt-project.org/
hjk's avatar
hjk committed
8
9
10
11
**
**
** GNU Lesser General Public License Usage
**
hjk's avatar
hjk committed
12
13
14
15
16
17
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
hjk's avatar
hjk committed
18
**
con's avatar
con committed
19
** In addition, as a special exception, Nokia gives you certain additional
hjk's avatar
hjk committed
20
** rights. These rights are described in the Nokia Qt LGPL Exception
con's avatar
con committed
21
22
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
23
24
25
26
27
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
hjk's avatar
hjk committed
28
29
30
31
**
**************************************************************************/

#include "debuggerdialogs.h"
32
#include "debuggerstartparameters.h"
33

34
#include "debuggerconstants.h"
35
#include "debuggerprofileinformation.h"
36
#include "debuggerstringutils.h"
37
#include "cdb/cdbengine.h"
38
#include "shared/hostutils.h"
hjk's avatar
hjk committed
39

40
#include <coreplugin/icore.h>
41
#include <projectexplorer/abi.h>
42
#include <projectexplorer/profilechooser.h>
43
#include <projectexplorer/profileinformation.h>
44
#include <utils/historycompleter.h>
hjk's avatar
hjk committed
45
#include <utils/pathchooser.h>
46
#include <utils/qtcassert.h>
47
#include <utils/synchronousprocess.h>
48

hjk's avatar
hjk committed
49
50
51
#include <QAction>
#include <QApplication>
#include <QButtonGroup>
52
#include <QCheckBox>
53
#include <QDebug>
hjk's avatar
hjk committed
54
55
#include <QDialog>
#include <QDialogButtonBox>
56
57
#include <QDir>
#include <QFileDialog>
hjk's avatar
hjk committed
58
59
#include <QFormLayout>
#include <QGridLayout>
60
61
#include <QGroupBox>
#include <QHeaderView>
hjk's avatar
hjk committed
62
63
#include <QLabel>
#include <QLineEdit>
64
65
66
#include <QMessageBox>
#include <QPushButton>
#include <QRadioButton>
hjk's avatar
hjk committed
67
#include <QRegExp>
68
#include <QScrollArea>
hjk's avatar
hjk committed
69
#include <QSpinBox>
70
#include <QStandardItemModel>
71
#include <QTreeView>
hjk's avatar
hjk committed
72
73
#include <QVariant>
#include <QVBoxLayout>
74

hjk's avatar
hjk committed
75
using namespace Core;
76
using namespace ProjectExplorer;
77
78
using namespace Utils;

79
80
81
namespace Debugger {
namespace Internal {

82
83
///////////////////////////////////////////////////////////////////////
//
84
// StartApplicationDialogPrivate
85
86
87
//
///////////////////////////////////////////////////////////////////////

88
class StartApplicationDialogPrivate
89
90
{
public:
91
92
93
94
95
96
97
98
99
100
101
    ProfileChooser *profileChooser;
    PathChooser *localExecutablePathChooser;
    QLineEdit *arguments;
    PathChooser *workingDirectory;
    QCheckBox *breakAtMainCheckBox;
    QCheckBox *runInTerminalCheckBox;
    PathChooser *debuginfoPathChooser;
    QLabel *serverStartScriptLabel;
    PathChooser *serverStartScriptPathChooser;
    QComboBox *historyComboBox;
    QDialogButtonBox *buttonBox;
102
103
104
105
106
};

} // namespace Internal
} // namespace Debugger

107
Q_DECLARE_METATYPE(Debugger::Internal::StartApplicationParameters)
108
109
110
111

namespace Debugger {
namespace Internal {

112
113
114
115
116
///////////////////////////////////////////////////////////////////////
//
// StartApplicationParameters
//
///////////////////////////////////////////////////////////////////////
117

118
class StartApplicationParameters
119
{
120
121
122
123
124
125
public:
    StartApplicationParameters();
    QString displayName() const;
    bool equals(const StartApplicationParameters &rhs) const;
    void toSettings(QSettings *) const;
    void fromSettings(const QSettings *settings);
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
    bool operator==(const StartApplicationParameters &p) const { return equals(p); }
    bool operator!=(const StartApplicationParameters &p) const { return !equals(p); }

    Id profileId;
    QString localExecutable;
    QString processArgs;
    QString workingDirectory;
    bool breakAtMain;
    bool runInTerminal;
    QString serverStartScript;
    QString debugInfoLocation;
};

StartApplicationParameters::StartApplicationParameters() :
141
    breakAtMain(false), runInTerminal(false)
142
143
144
{
}

145
bool StartApplicationParameters::equals(const StartApplicationParameters &rhs) const
146
{
147
148
149
150
151
152
153
154
    return localExecutable == rhs.localExecutable
        && processArgs == rhs.processArgs
        && workingDirectory == rhs.workingDirectory
        && breakAtMain == rhs.breakAtMain
        && runInTerminal == rhs.runInTerminal
        && serverStartScript == rhs.serverStartScript
        && profileId == rhs.profileId
        && debugInfoLocation == rhs.debugInfoLocation;
155
156
}

157
QString StartApplicationParameters::displayName() const
158
{
159
    const int maxLength = 60;
160

161
162
    QString name = QFileInfo(localExecutable).fileName() + QLatin1Char(' ') + processArgs;
    if (name.size() > 60) {
163
164
165
166
167
168
        int index = name.lastIndexOf(QLatin1Char(' '), maxLength);
        if (index == -1)
            index = maxLength;
        name.truncate(index);
        name += QLatin1String("...");
    }
169
170
171
172

    if (Profile *profile = ProfileManager::instance()->find(profileId))
        name += QString::fromLatin1(" (%1)").arg(profile->displayName());

173
174
175
    return name;
}

176
void StartApplicationParameters::toSettings(QSettings *settings) const
177
{
178
179
180
    settings->setValue(_("LastProfileId"), profileId.toString());
    settings->setValue(_("LastExternalExecutable"), localExecutable);
    settings->setValue(_("LastExternalExecutableArguments"), processArgs);
181
182
183
    settings->setValue(_("LastExternalWorkingDirectory"), workingDirectory);
    settings->setValue(_("LastExternalBreakAtMain"), breakAtMain);
    settings->setValue(_("LastExternalRunInTerminal"), runInTerminal);
184
185
    settings->setValue(_("LastServerStartScript"), serverStartScript);
    settings->setValue(_("LastDebugInfoLocation"), debugInfoLocation);
186
187
}

188
void StartApplicationParameters::fromSettings(const QSettings *settings)
189
{
190
191
192
193
    const QString profileIdString = settings->value(_("LastProfileId")).toString();
    profileId = profileIdString.isEmpty() ? Id() : Id(profileIdString);
    localExecutable = settings->value(_("LastExternalExecutable")).toString();
    processArgs = settings->value(_("LastExternalExecutableArguments")).toString();
194
195
196
    workingDirectory = settings->value(_("LastExternalWorkingDirectory")).toString();
    breakAtMain = settings->value(_("LastExternalBreakAtMain")).toBool();
    runInTerminal = settings->value(_("LastExternalRunInTerminal")).toBool();
197
198
    serverStartScript = settings->value(_("LastServerStartScript")).toString();
    debugInfoLocation = settings->value(_("LastDebugInfoLocation")).toString();
199
200
}

201
202
203
204
205
///////////////////////////////////////////////////////////////////////
//
// StartApplicationDialog
//
///////////////////////////////////////////////////////////////////////
206

207
208
StartApplicationDialog::StartApplicationDialog(QWidget *parent)
  : QDialog(parent), d(new StartApplicationDialogPrivate)
209
{
210
    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
211
212
    setWindowTitle(tr("Start Debugger"));

213
214
215
    d->localExecutablePathChooser = new PathChooser(this);
    d->localExecutablePathChooser->setExpectedKind(PathChooser::File);
    d->localExecutablePathChooser->setPromptDialogTitle(tr("Select Executable"));
216
    d->localExecutablePathChooser->lineEdit()->setHistoryKey(QLatin1String("LocalExecutable"));
217

218
    d->arguments = new QLineEdit(this);
hjk's avatar
hjk committed
219
220
    d->arguments->setCompleter(
        new HistoryCompleter(d->arguments, QLatin1String("CommandlineArguments")));
221

hjk's avatar
hjk committed
222
    d->workingDirectory = new PathChooser(this);
223
224
    d->workingDirectory->setExpectedKind(PathChooser::ExistingDirectory);
    d->workingDirectory->setPromptDialogTitle(tr("Select Working Directory"));
225
    d->workingDirectory->lineEdit()->setHistoryKey(QLatin1String("WorkingDirectory"));
226
227
228

    d->runInTerminalCheckBox = new QCheckBox(this);

229
    d->profileChooser = new ProfileChooser(this, ProfileChooser::LocalDebugging);
230
231
232
233

    d->breakAtMainCheckBox = new QCheckBox(this);
    d->breakAtMainCheckBox->setText(QString());

234
235
236
    d->serverStartScriptPathChooser = new PathChooser(this);
    d->serverStartScriptPathChooser->setExpectedKind(PathChooser::File);
    d->serverStartScriptPathChooser->setPromptDialogTitle(tr("Select Server Start Script"));
237
238
239
240
    d->serverStartScriptPathChooser->setToolTip(tr(
        "This option can be used to point to a script that will be used "
        "to start a debug server. If the field is empty, Qt Creator's "
        "default methods to set up debug servers will be used."));
241
242
    d->serverStartScriptLabel = new QLabel(tr("&Server start script:"), this);
    d->serverStartScriptLabel->setBuddy(d->serverStartScriptPathChooser);
243
244
245
246
247
248
249
    d->serverStartScriptLabel->setToolTip(d->serverStartScriptPathChooser->toolTip());

    d->debuginfoPathChooser = new PathChooser(this);
    d->debuginfoPathChooser->setPromptDialogTitle(tr("Select Location of Debugging Information"));
    d->debuginfoPathChooser->setToolTip(tr(
        "Base path for external debug information and debug sources."
        "If empty, $SYSROOT/usr/lib/debug will be chosen."));
250
251
252
253
254

    QFrame *line = new QFrame(this);
    line->setFrameShape(QFrame::HLine);
    line->setFrameShadow(QFrame::Sunken);

255
256
257
258
259
260
    QFrame *line2 = new QFrame(this);
    line2->setFrameShape(QFrame::HLine);
    line2->setFrameShadow(QFrame::Sunken);

    d->historyComboBox = new QComboBox(this);

261
262
263
264
265
    d->buttonBox = new QDialogButtonBox(this);
    d->buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
    d->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);

    QFormLayout *formLayout = new QFormLayout();
266
    formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
267
    formLayout->addRow(tr("&Target:"), d->profileChooser);
268
269
270
271
    formLayout->addRow(tr("Local &executable:"), d->localExecutablePathChooser);
    formLayout->addRow(tr("Command line &arguments:"), d->arguments);
    formLayout->addRow(tr("&Working directory:"), d->workingDirectory);
    formLayout->addRow(tr("Run in &terminal:"), d->runInTerminalCheckBox);
272
    formLayout->addRow(tr("Break at \"&main\":"), d->breakAtMainCheckBox);
273
    formLayout->addRow(d->serverStartScriptLabel, d->serverStartScriptPathChooser);
274
    formLayout->addRow(tr("Debug &information:"), d->debuginfoPathChooser);
275
    formLayout->addRow(line2);
276
    formLayout->addRow(tr("&Recent:"), d->historyComboBox);
277
278
279

    QVBoxLayout *verticalLayout = new QVBoxLayout(this);
    verticalLayout->addLayout(formLayout);
280
    verticalLayout->addStretch();
281
    verticalLayout->addWidget(line);
282
283
    verticalLayout->addWidget(d->buttonBox);

284
    connect(d->localExecutablePathChooser, SIGNAL(changed(QString)), SLOT(updateState()));
285
286
287
288
    connect(d->buttonBox, SIGNAL(accepted()), SLOT(accept()));
    connect(d->buttonBox, SIGNAL(rejected()), SLOT(reject()));
    connect(d->historyComboBox, SIGNAL(currentIndexChanged(int)),
            SLOT(historyIndexChanged(int)));
289

290
    updateState();
291
292
}

293
StartApplicationDialog::~StartApplicationDialog()
294
{
295
    delete d;
296
297
}

298
void StartApplicationDialog::setHistory(const QList<StartApplicationParameters> &l)
299
{
300
301
    d->historyComboBox->clear();
    for (int i = l.size(); --i >= 0; ) {
302
303
        const StartApplicationParameters &p = l.at(i);
        if (!p.localExecutable.isEmpty())
304
305
            d->historyComboBox->addItem(p.displayName(), QVariant::fromValue(p));
    }
306
307
}

308
void StartApplicationDialog::hideStartScript()
309
{
310
311
    d->serverStartScriptPathChooser->setVisible(false);
    d->serverStartScriptLabel->setVisible(false);
312
313
}

314
void StartApplicationDialog::historyIndexChanged(int index)
315
{
316
317
318
319
320
    if (index < 0)
        return;
    const QVariant v = d->historyComboBox->itemData(index);
    QTC_ASSERT(v.canConvert<StartApplicationParameters>(), return);
    setParameters(v.value<StartApplicationParameters>());
321
322
}

323
Id StartApplicationDialog::profileId() const
324
{
325
    return d->profileChooser->currentProfileId();
326
327
}

328
void StartApplicationDialog::updateState()
329
{
330
331
    bool okEnabled = d->localExecutablePathChooser->isValid();
    d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(okEnabled);
332
333
}

334
bool StartApplicationDialog::run(QWidget *parent, QSettings *settings, DebuggerStartParameters *sp)
335
{
336
337
    const QString settingsGroup = QLatin1String("DebugMode");
    const QString arrayName = QLatin1String("StartApplication");
338

339
    QList<StartApplicationParameters> history;
340
    settings->beginGroup(settingsGroup);
341
342
343
344
345
346
347
348
349
    if (const int arraySize = settings->beginReadArray(arrayName)) {
        for (int i = 0; i < arraySize; ++i) {
            settings->setArrayIndex(i);
            StartApplicationParameters p;
            p.fromSettings(settings);
            history.append(p);
        }
    } else {
        history.append(StartApplicationParameters());
350
351
352
353
    }
    settings->endArray();
    settings->endGroup();

354
    StartApplicationDialog dialog(parent);
355
356
    dialog.setHistory(history);
    dialog.setParameters(history.back());
357
358
    if (sp->startMode == AttachToRemoteServer)
        dialog.hideStartScript();
359
360
361
    if (dialog.exec() != QDialog::Accepted)
        return false;

362
    const StartApplicationParameters newParameters = dialog.parameters();
363
    if (newParameters != history.back()) {
364
365
366
367
368
369
370
371
372
373
374
        history.append(newParameters);
        while (history.size() > 10)
            history.takeFirst();
        settings->beginGroup(settingsGroup);
        settings->beginWriteArray(arrayName);
        for (int i = 0; i < history.size(); ++i) {
            settings->setArrayIndex(i);
            history.at(i).toSettings(settings);
        }
        settings->endArray();
        settings->endGroup();
375
376
    }

377
    Profile *profile = dialog.d->profileChooser->currentProfile();
378
    QTC_ASSERT(profile, return false);
379
    fillParameters(sp, profile);
380
381
382

    sp->executable = newParameters.localExecutable;
    sp->displayName = newParameters.displayName();
383
384
    sp->workingDirectory = newParameters.workingDirectory;
    sp->useTerminal = newParameters.runInTerminal;
385
386
    if (!newParameters.processArgs.isEmpty())
        sp->processArgs = newParameters.processArgs;
387
388
389
    sp->breakOnMain = newParameters.breakAtMain;
    sp->serverStartScript = newParameters.serverStartScript;
    sp->debugInfoLocation = newParameters.debugInfoLocation;
390
391
392
393

    bool isLocal = DeviceProfileInformation::device(profile)->type()
         == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE;
    sp->startMode = isLocal ? StartExternal : StartRemoteProcess;
394
395
396
    return true;
}

397
StartApplicationParameters StartApplicationDialog::parameters() const
398
{
399
400
    StartApplicationParameters result;
    result.localExecutable = d->localExecutablePathChooser->path();
401
402
403
    result.serverStartScript = d->serverStartScriptPathChooser->path();
    result.profileId = d->profileChooser->currentProfileId();
    result.debugInfoLocation = d->debuginfoPathChooser->path();
404
405
406
407
    result.processArgs = d->arguments->text();
    result.workingDirectory = d->workingDirectory->path();
    result.breakAtMain = d->breakAtMainCheckBox->isChecked();
    result.runInTerminal = d->runInTerminalCheckBox->isChecked();
408
409
410
    return result;
}

411
void StartApplicationDialog::setParameters(const StartApplicationParameters &p)
412
{
413
414
    d->profileChooser->setCurrentProfileId(p.profileId);
    d->localExecutablePathChooser->setPath(p.localExecutable);
415
416
    d->serverStartScriptPathChooser->setPath(p.serverStartScript);
    d->debuginfoPathChooser->setPath(p.debugInfoLocation);
417
418
419
420
421
    d->arguments->setText(p.processArgs);
    d->workingDirectory->setPath(p.workingDirectory);
    d->runInTerminalCheckBox->setChecked(p.runInTerminal);
    d->breakAtMainCheckBox->setChecked(p.breakAtMain);
    updateState();
hjk's avatar
hjk committed
422
}
423

424
425
426
427
428
429
///////////////////////////////////////////////////////////////////////
//
// AttachToQmlPortDialog
//
///////////////////////////////////////////////////////////////////////

hjk's avatar
hjk committed
430
431
432
433
class AttachToQmlPortDialogPrivate
{
public:
    QSpinBox *portSpinBox;
434
    ProfileChooser *profileChooser;
hjk's avatar
hjk committed
435
436
};

437
438
AttachToQmlPortDialog::AttachToQmlPortDialog(QWidget *parent)
  : QDialog(parent),
hjk's avatar
hjk committed
439
    d(new AttachToQmlPortDialogPrivate)
440
441
{
    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
hjk's avatar
hjk committed
442
    setWindowTitle(tr("Start Debugger"));
443

444
    d->profileChooser = new ProfileChooser(this);
hjk's avatar
hjk committed
445
446
447
448
449
450
451

    d->portSpinBox = new QSpinBox(this);
    d->portSpinBox->setMaximum(65535);
    d->portSpinBox->setValue(3768);

    QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
    buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
452
    buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
hjk's avatar
hjk committed
453
454

    QFormLayout *formLayout = new QFormLayout();
455
456
    formLayout->addRow(tr("Target:"), d->profileChooser);
    formLayout->addRow(tr("&Port:"), d->portSpinBox);
hjk's avatar
hjk committed
457

458
    QVBoxLayout *verticalLayout = new QVBoxLayout(this);
hjk's avatar
hjk committed
459
460
461
    verticalLayout->addLayout(formLayout);
    verticalLayout->addWidget(buttonBox);

462
463
    connect(buttonBox, SIGNAL(accepted()), SLOT(accept()));
    connect(buttonBox, SIGNAL(rejected()), SLOT(reject()));
464
465
466
467
}

AttachToQmlPortDialog::~AttachToQmlPortDialog()
{
hjk's avatar
hjk committed
468
    delete d;
469
470
471
472
}

void AttachToQmlPortDialog::setPort(const int port)
{
hjk's avatar
hjk committed
473
    d->portSpinBox->setValue(port);
474
475
476
477
}

int AttachToQmlPortDialog::port() const
{
hjk's avatar
hjk committed
478
    return d->portSpinBox->value();
479
480
}

481
Profile *AttachToQmlPortDialog::profile() const
482
{
483
    return d->profileChooser->currentProfile();
484
485
}

hjk's avatar
hjk committed
486
void AttachToQmlPortDialog::setProfileId(const Id &id)
487
{
hjk's avatar
hjk committed
488
    d->profileChooser->setCurrentProfileId(id);
489
490
}

491
// --------- StartRemoteCdbDialog
492
static QString cdbRemoteHelp()
493
494
495
496
497
498
499
500
501
502
503
{
    const char *cdbConnectionSyntax =
            "Server:Port<br>"
            "tcp:server=Server,port=Port[,password=Password][,ipversion=6]\n"
            "tcp:clicon=Server,port=Port[,password=Password][,ipversion=6]\n"
            "npipe:server=Server,pipe=PipeName[,password=Password]\n"
            "com:port=COMPort,baud=BaudRate,channel=COMChannel[,password=Password]\n"
            "spipe:proto=Protocol,{certuser=Cert|machuser=Cert},server=Server,pipe=PipeName[,password=Password]\n"
            "ssl:proto=Protocol,{certuser=Cert|machuser=Cert},server=Server,port=Socket[,password=Password]\n"
            "ssl:proto=Protocol,{certuser=Cert|machuser=Cert},clicon=Server,port=Socket[,password=Password]";

504
505
    const QString ext32 = QDir::toNativeSeparators(CdbEngine::extensionLibraryName(false));
    const QString ext64 = QDir::toNativeSeparators(CdbEngine::extensionLibraryName(true));
506
507
508
509
510
    return  StartRemoteCdbDialog::tr(
                "<html><body><p>The remote CDB needs to load the matching Qt Creator CDB extension "
                "(<code>%1</code> or <code>%2</code>, respectively).</p><p>Copy it onto the remote machine and set the "
                "environment variable <code>%3</code> to point to its folder.</p><p>"
                "Launch the remote CDB as <code>%4 &lt;executable&gt;</code> "
511
                "to use TCP/IP as communication protocol.</p><p>Enter the connection parameters as:</p>"
512
513
514
515
516
517
518
519
520
521
522
523
524
                "<pre>%5</pre></body></html>").
            arg(ext32, ext64, QLatin1String("_NT_DEBUGGER_EXTENSION_PATH"),
                QLatin1String("cdb.exe -server tcp:port=1234"),
                QLatin1String(cdbConnectionSyntax));
}

StartRemoteCdbDialog::StartRemoteCdbDialog(QWidget *parent) :
    QDialog(parent), m_okButton(0), m_lineEdit(new QLineEdit)
{
    setWindowTitle(tr("Start a CDB Remote Session"));
    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);

    QGroupBox *groupBox = new QGroupBox;
525

526
527
528
    QLabel *helpLabel = new QLabel(cdbRemoteHelp());
    helpLabel->setWordWrap(true);
    helpLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
529

530
531
532
    QLabel *label = new QLabel(tr("&Connection:"));
    label->setBuddy(m_lineEdit);
    m_lineEdit->setMinimumWidth(400);
533
534
535
536
537

    QDialogButtonBox *box = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);

    QFormLayout *formLayout = new QFormLayout;
    formLayout->addRow(helpLabel);
538
539
540
    formLayout->addRow(label, m_lineEdit);
    groupBox->setLayout(formLayout);

541
    QVBoxLayout *vLayout = new QVBoxLayout(this);
542
543
    vLayout->addWidget(groupBox);
    vLayout->addWidget(box);
544

545
546
    m_okButton = box->button(QDialogButtonBox::Ok);
    m_okButton->setEnabled(false);
547
548
549

    connect(m_lineEdit, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));
    connect(m_lineEdit, SIGNAL(returnPressed()), m_okButton, SLOT(animateClick()));
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
    connect(box, SIGNAL(accepted()), this, SLOT(accept()));
    connect(box, SIGNAL(rejected()), this, SLOT(reject()));
}

void StartRemoteCdbDialog::accept()
{
    if (!m_lineEdit->text().isEmpty())
        QDialog::accept();
}

StartRemoteCdbDialog::~StartRemoteCdbDialog()
{
}

void StartRemoteCdbDialog::textChanged(const QString &t)
{
    m_okButton->setEnabled(!t.isEmpty());
}

QString StartRemoteCdbDialog::connection() const
{
    const QString rc = m_lineEdit->text();
    // Transform an IP:POrt ('localhost:1234') specification into full spec
    QRegExp ipRegexp(QLatin1String("([\\w\\.\\-_]+):([0-9]{1,4})"));
    QTC_ASSERT(ipRegexp.isValid(), return QString());
    if (ipRegexp.exactMatch(rc))
576
        return QString::fromLatin1("tcp:server=%1,port=%2").arg(ipRegexp.cap(1), ipRegexp.cap(2));
577
578
579
580
581
582
583
584
585
    return rc;
}

void StartRemoteCdbDialog::setConnection(const QString &c)
{
    m_lineEdit->setText(c);
    m_okButton->setEnabled(!c.isEmpty());
}

586
587
588
589
590
AddressDialog::AddressDialog(QWidget *parent) :
        QDialog(parent),
        m_lineEdit(new QLineEdit),
        m_box(new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel))
{
Leena Miettinen's avatar
Leena Miettinen committed
591
    setWindowTitle(tr("Select Start Address"));
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
    QHBoxLayout *hLayout = new QHBoxLayout;
    hLayout->addWidget(new QLabel(tr("Enter an address: ")));
    hLayout->addWidget(m_lineEdit);
    QVBoxLayout *vLayout = new QVBoxLayout;
    vLayout->addLayout(hLayout);
    vLayout->addWidget(m_box);
    setLayout(vLayout);

    connect(m_box, SIGNAL(accepted()), this, SLOT(accept()));
    connect(m_box, SIGNAL(rejected()), this, SLOT(reject()));
    connect(m_lineEdit, SIGNAL(returnPressed()), this, SLOT(accept()));
    connect(m_lineEdit, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));

    setOkButtonEnabled(false);
}

void AddressDialog::setOkButtonEnabled(bool v)
{
    m_box->button(QDialogButtonBox::Ok)->setEnabled(v);
}

bool AddressDialog::isOkButtonEnabled() const
{
    return m_box->button(QDialogButtonBox::Ok)->isEnabled();
}

619
620
void AddressDialog::setAddress(quint64 a)
{
621
    m_lineEdit->setText(QLatin1String("0x") + QString::number(a, 16));
622
623
}

624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
quint64 AddressDialog::address() const
{
    return m_lineEdit->text().toULongLong(0, 16);
}

void AddressDialog::accept()
{
    if (isOkButtonEnabled())
        QDialog::accept();
}

void AddressDialog::textChanged()
{
    setOkButtonEnabled(isValid());
}

bool AddressDialog::isValid() const
{
    const QString text = m_lineEdit->text();
    bool ok = false;
    text.toULongLong(&ok, 16);
    return ok;
}

648
649
650
651
652
653
///////////////////////////////////////////////////////////////////////
//
// StartRemoteEngineDialog
//
///////////////////////////////////////////////////////////////////////

654
655
656
657
658
659
660
661
662
663
664
665
666
class StartRemoteEngineDialogPrivate
{
public:
    QLineEdit *host;
    QLineEdit *username;
    QLineEdit *password;
    QLineEdit *enginePath;
    QLineEdit *inferiorPath;
    QDialogButtonBox *buttonBox;
};

StartRemoteEngineDialog::StartRemoteEngineDialog(QWidget *parent)
    : QDialog(parent), d(new StartRemoteEngineDialogPrivate)
667
{
668
    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
669
670
671
672
    setWindowTitle(tr("Start Remote Engine"));

    d->host = new QLineEdit(this);
    d->host->setText(QString());
hjk's avatar
hjk committed
673
    d->host->setCompleter(new HistoryCompleter(d->host, QLatin1String("HostName")));
674
675

    d->username = new QLineEdit(this);
hjk's avatar
hjk committed
676
    d->username->setCompleter(new HistoryCompleter(d->username, QLatin1String("UserName")));
677
678
679
680
681

    d->password = new QLineEdit(this);
    d->password->setEchoMode(QLineEdit::Password);

    d->enginePath = new QLineEdit(this);
hjk's avatar
hjk committed
682
    d->enginePath->setCompleter(new HistoryCompleter(d->enginePath, QLatin1String("EnginePath")));
683
684

    d->inferiorPath = new QLineEdit(this);
hjk's avatar
hjk committed
685
    d->inferiorPath->setCompleter(new HistoryCompleter(d->inferiorPath, QLatin1String("InferiorPath")));
686
687
688
689
690

    d->buttonBox = new QDialogButtonBox(this);
    d->buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);

    QFormLayout *formLayout = new QFormLayout();
691
    formLayout->addRow(tr("&Host:"), d->host);
Friedemann Kleint's avatar
Friedemann Kleint committed
692
    formLayout->addRow(tr("&Username:"), d->username);
693
694
695
    formLayout->addRow(tr("&Password:"), d->password);
    formLayout->addRow(tr("&Engine path:"), d->enginePath);
    formLayout->addRow(tr("&Inferior path:"), d->inferiorPath);
696
697
698
699
700
701
702
703

    QVBoxLayout *verticalLayout = new QVBoxLayout(this);
    verticalLayout->addLayout(formLayout);
    verticalLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
    verticalLayout->addWidget(d->buttonBox);

    connect(d->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
    connect(d->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
704
705
706
707
}

StartRemoteEngineDialog::~StartRemoteEngineDialog()
{
708
    delete d;
709
710
711
712
}

QString StartRemoteEngineDialog::host() const
{
713
    return d->host->text();
714
715
716
717
}

QString StartRemoteEngineDialog::username() const
{
718
    return d->username->text();
719
720
721
722
}

QString StartRemoteEngineDialog::password() const
{
723
    return d->password->text();
724
725
726
727
}

QString StartRemoteEngineDialog::inferiorPath() const
{
728
    return d->inferiorPath->text();
729
730
731
732
}

QString StartRemoteEngineDialog::enginePath() const
{
733
    return d->enginePath->text();
734
735
}

736
737
738
739
740
741
742
743
744
745
746
///////////////////////////////////////////////////////////////////////
//
// TypeFormatsDialogUi
//
///////////////////////////////////////////////////////////////////////

class TypeFormatsDialogPage : public QWidget
{
public:
    TypeFormatsDialogPage()
    {
747
748
749
750
751
752
753
        m_layout = new QGridLayout;
        m_layout->setColumnStretch(0, 2);
        QVBoxLayout *vboxLayout = new QVBoxLayout;
        vboxLayout->addLayout(m_layout);
        vboxLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Ignored,
                                            QSizePolicy::MinimumExpanding));
        setLayout(vboxLayout);
754
755
756
757
758
    }

    void addTypeFormats(const QString &type,
        const QStringList &typeFormats, int current)
    {
759
760
        const int row = m_layout->rowCount();
        int column = 0;
761
        QButtonGroup *group = new QButtonGroup(this);
762
        m_layout->addWidget(new QLabel(type), row, column++);
763
764
        for (int i = -1; i != typeFormats.size(); ++i) {
            QRadioButton *choice = new QRadioButton(this);
Friedemann Kleint's avatar
Friedemann Kleint committed
765
            choice->setText(i == -1 ? TypeFormatsDialog::tr("Reset") : typeFormats.at(i));
766
            m_layout->addWidget(choice, row, column++);
767
768
769
770
771
772
            if (i == current)
                choice->setChecked(true);
            group->addButton(choice, i);
        }
    }
private:
773
    QGridLayout *m_layout;
774
775
776
777
778
779
780
781
782
783
784
};

class TypeFormatsDialogUi
{
public:
    TypeFormatsDialogUi(TypeFormatsDialog *q)
    {
        tabs = new QTabWidget(q);

        buttonBox = new QDialogButtonBox(q);
        buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
785
786

        QVBoxLayout *layout = new QVBoxLayout(q);
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
        layout->addWidget(tabs);
        layout->addWidget(buttonBox);
        q->setLayout(layout);
    }

    void addPage(const QString &name)
    {
        TypeFormatsDialogPage *page = new TypeFormatsDialogPage;
        pages.append(page);
        QScrollArea *scroller = new QScrollArea;
        scroller->setWidgetResizable(true);
        scroller->setWidget(page);
        scroller->setFrameStyle(QFrame::NoFrame);
        tabs->addTab(scroller, name);
    }

public:
    QList<TypeFormatsDialogPage *> pages;
805
    QDialogButtonBox *buttonBox;
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821

private:
    QTabWidget *tabs;
};


///////////////////////////////////////////////////////////////////////
//
// TypeFormatsDialog
//
///////////////////////////////////////////////////////////////////////


TypeFormatsDialog::TypeFormatsDialog(QWidget *parent)
   : QDialog(parent), m_ui(new TypeFormatsDialogUi(this))
{
822
823
    setWindowTitle(tr("Type Formats"));
    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
    m_ui->addPage(tr("Qt Types"));
    m_ui->addPage(tr("Standard Types"));
    m_ui->addPage(tr("Misc Types"));

    connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(accept()));
    connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(reject()));
}

TypeFormatsDialog::~TypeFormatsDialog()
{
    delete m_ui;
}

void TypeFormatsDialog::addTypeFormats(const QString &type0,
    const QStringList &typeFormats, int current)
{
    QString type = type0;
841
    type.replace(QLatin1String("__"), QLatin1String("::"));
842
843
844
845
846
847
848
849
850
851
852
853
854
    int pos = 2;
    if (type.startsWith(QLatin1Char('Q')))
        pos = 0;
    else if (type.startsWith(QLatin1String("std::")))
        pos = 1;
    m_ui->pages[pos]->addTypeFormats(type, typeFormats, current);
}

TypeFormats TypeFormatsDialog::typeFormats() const
{
    return TypeFormats();
}

855
856
} // namespace Internal
} // namespace Debugger