1
/**************************************************************************
3
** This file is part of Qt Creator
5
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7
** Contact: Nokia Corporation (info@qt.nokia.com)
10
** GNU Lesser General Public License Usage
12
** This file may be used under the terms of the GNU Lesser General Public
13
** License version 2.1 as published by the Free Software Foundation and
14
** appearing in the file LICENSE.LGPL included in the packaging of this file.
15
** Please review the following information to ensure the GNU Lesser General
16
** Public License version 2.1 requirements will be met:
17
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19
** In addition, as a special exception, Nokia gives you certain additional
20
** rights. These rights are described in the Nokia Qt LGPL Exception
21
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25
** Alternatively, this file may be used in accordance with the terms and
26
** conditions contained in a signed written agreement between you and Nokia.
28
** If you have questions regarding the use of this file, please contact
29
** Nokia at info@qt.nokia.com.
31
**************************************************************************/
33
#include "regexpwindow.h"
36
#include <QtGui/QCheckBox>
37
#include <QtGui/QComboBox>
38
#include <QtGui/QLabel>
39
#include <QtGui/QLayout>
40
#include <QtGui/QLineEdit>
41
#include <QtGui/QContextMenuEvent>
42
#include <QtGui/QMenu>
43
#include <QtGui/QInputDialog>
45
using namespace RegExp::Internal;
47
RegExpWindow::RegExpWindow(QWidget *parent) :
49
patternLabel(new QLabel(tr("&Pattern:"))),
50
escapedPatternLabel(new QLabel(tr("&Escaped pattern:"))),
51
syntaxLabel(new QLabel(tr("&Pattern syntax:"))),
52
textLabel(new QLabel(tr("&Text:"))),
53
patternComboBox (new QComboBox),
54
escapedPatternLineEdit(new QLineEdit),
55
textComboBox(new QComboBox),
56
caseSensitiveCheckBox(new QCheckBox(tr("Case &sensitive"))),
57
minimalCheckBox(new QCheckBox(tr("&Minimal"))),
58
syntaxComboBox(new QComboBox),
59
indexLabel(new QLabel(tr("Index of match:"))),
60
matchedLengthLabel(new QLabel(tr("Matched length:"))),
61
indexEdit(new QLineEdit),
62
matchedLengthEdit(new QLineEdit)
64
QVBoxLayout *vboxLayout = new QVBoxLayout(this);
65
QGridLayout *mainLayout = new QGridLayout;
67
patternComboBox->setEditable(true);
68
patternComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
70
patternLabel->setBuddy(patternComboBox);
72
mainLayout->addWidget(patternLabel, 0, 0);
73
mainLayout->addWidget(patternComboBox, 0, 1);
75
escapedPatternLineEdit->setReadOnly(true);
76
QPalette palette = escapedPatternLineEdit->palette();
77
palette.setBrush(QPalette::Base, palette.brush(QPalette::Disabled, QPalette::Base));
78
escapedPatternLineEdit->setPalette(palette);
80
escapedPatternLabel->setBuddy(escapedPatternLineEdit);
82
mainLayout->addWidget(escapedPatternLabel, 1, 0);
83
mainLayout->addWidget(escapedPatternLineEdit, 1, 1);
85
syntaxComboBox->addItem(tr("Regular Expression v1"), QRegExp::RegExp);
86
syntaxComboBox->addItem(tr("Regular Expression v2"), QRegExp::RegExp2);
87
syntaxComboBox->addItem(tr("Wildcard"), QRegExp::Wildcard);
88
syntaxComboBox->addItem(tr("Fixed String"), QRegExp::FixedString);
90
syntaxLabel->setBuddy(syntaxComboBox);
92
mainLayout->addWidget(syntaxLabel, 2, 0);
93
mainLayout->addWidget(syntaxComboBox, 2, 1);
95
QHBoxLayout *checkBoxLayout = new QHBoxLayout;
97
caseSensitiveCheckBox->setChecked(true);
99
checkBoxLayout->addWidget(caseSensitiveCheckBox);
100
checkBoxLayout->addWidget(minimalCheckBox);
101
checkBoxLayout->addStretch(1);
103
mainLayout->addLayout(checkBoxLayout, 3, 0, 1, 2);
105
textComboBox->setEditable(true);
106
textComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
108
textLabel->setBuddy(textComboBox);
110
mainLayout->addWidget(textLabel, 4, 0);
111
mainLayout->addWidget(textComboBox, 4, 1);
113
indexEdit->setReadOnly(true);
115
mainLayout->addWidget(indexLabel, 5, 0);
116
mainLayout->addWidget(indexEdit, 5, 1);
118
matchedLengthEdit->setReadOnly(true);
120
mainLayout->addWidget(matchedLengthLabel, 6, 0);
121
mainLayout->addWidget(matchedLengthEdit, 6, 1);
123
vboxLayout->addLayout(mainLayout);
124
vboxLayout->addItem(new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding));
126
for (int i = 0; i < MaxCaptures; ++i) {
127
captureLabels[i] = new QLabel(tr("Capture %1:").arg(i));
128
captureEdits[i] = new QLineEdit;
129
captureEdits[i]->setReadOnly(true);
131
captureLabels[0]->setText(tr("Match:"));
133
for (int j = 0; j < MaxCaptures; ++j) {
134
mainLayout->addWidget(captureLabels[j], 7 + j, 0);
135
mainLayout->addWidget(captureEdits[j], 7 + j, 1);
138
connect(patternComboBox, SIGNAL(editTextChanged(const QString &)), this, SLOT(refresh()));
139
connect(textComboBox, SIGNAL(editTextChanged(const QString &)), this, SLOT(refresh()));
140
connect(caseSensitiveCheckBox, SIGNAL(toggled(bool)), this, SLOT(refresh()));
141
connect(minimalCheckBox, SIGNAL(toggled(bool)), this, SLOT(refresh()));
142
connect(syntaxComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(refresh()));
144
setWindowTitle(tr("Regular Expression"));
148
static const char escapedBackSlash[] = "\\\\";
149
static const char escapedDoubleQuote[] = "\\\"";
151
static QString escapePattern(const QString &pattern)
153
QString escaped = pattern;
154
escaped.replace(QString(QLatin1Char('\\')) , QLatin1String(escapedBackSlash));
155
const QChar doubleQuote(QLatin1Char('"'));
156
escaped.replace(doubleQuote, QString(QLatin1String(escapedDoubleQuote)));
157
escaped.prepend(doubleQuote);
158
escaped.append(doubleQuote);
162
static QString unescapePattern(QString escaped)
165
const QChar doubleQuote(QLatin1Char('"'));
166
if (escaped.endsWith(doubleQuote))
167
escaped.truncate(escaped.size() - 1);
168
if (escaped.startsWith(doubleQuote))
169
escaped.remove(0, 1);
171
const int size = escaped.size();
175
// parse out escapes. Do not just replace.
177
const QChar backSlash = QLatin1Char('\\');
178
bool escapeSeen = false;
179
for (int i = 0; i < size; i++) {
180
const QChar c = escaped.at(i);
181
if (c == backSlash && !escapeSeen)
184
pattern.push_back(c);
191
void RegExpWindow::refresh()
193
setUpdatesEnabled(false);
195
const QString pattern = patternComboBox->currentText();
196
const QString text = textComboBox->currentText();
198
escapedPatternLineEdit->setText(escapePattern(pattern));
201
const Qt::CaseSensitivity cs = caseSensitiveCheckBox->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive;
202
rx.setCaseSensitivity(cs);
203
rx.setMinimal(minimalCheckBox->isChecked());
204
const QRegExp::PatternSyntax syntax = QRegExp::PatternSyntax(
205
syntaxComboBox->itemData(syntaxComboBox->currentIndex()).toInt());
206
rx.setPatternSyntax(syntax);
208
QPalette palette = patternComboBox->palette();
210
palette.setColor(QPalette::Text,
211
textComboBox->palette().color(QPalette::Text));
213
palette.setColor(QPalette::Text, Qt::red);
215
patternComboBox->setPalette(palette);
217
indexEdit->setText(QString::number(rx.indexIn(text)));
218
matchedLengthEdit->setText(QString::number(rx.matchedLength()));
219
for (int i = 0; i < MaxCaptures; ++i) {
220
const bool enabled = i <= rx.numCaptures();
221
captureLabels[i]->setEnabled(enabled);
222
captureEdits[i]->setEnabled(enabled);
223
captureEdits[i]->setText(rx.cap(i));
226
setUpdatesEnabled(true);
229
static void saveTextCombo(const QComboBox *cb, QString ¤t, QStringList &items)
231
current = cb->currentText();
233
if (const int count = cb->count())
234
for (int i = 0;i < count; i++) {
235
const QString text = cb->itemText(i);
236
if (items.indexOf(text) == -1)
241
Settings RegExpWindow::settings() const
244
rc.m_patternSyntax = static_cast<QRegExp::PatternSyntax>(syntaxComboBox->itemData(syntaxComboBox->currentIndex()).toInt());
245
rc.m_minimal = minimalCheckBox->checkState() == Qt::Checked;
246
rc.m_caseSensitive = caseSensitiveCheckBox->checkState() == Qt::Checked;
247
saveTextCombo(patternComboBox, rc.m_currentPattern, rc.m_patterns);
248
saveTextCombo(textComboBox, rc.m_currentMatch, rc.m_matches);
252
static void restoreTextCombo(const QString ¤t, const QStringList &items, QComboBox *cb)
256
cb->lineEdit()->setText(current);
259
void RegExpWindow::setSettings(const Settings &s)
261
const int patternIndex = syntaxComboBox->findData(QVariant(s.m_patternSyntax));
262
syntaxComboBox->setCurrentIndex(patternIndex);
263
minimalCheckBox->setCheckState(s.m_minimal ? Qt::Checked : Qt::Unchecked);
264
caseSensitiveCheckBox->setCheckState(s.m_caseSensitive ? Qt::Checked : Qt::Unchecked);
265
restoreTextCombo(s.m_currentPattern, s.m_patterns, patternComboBox);
266
restoreTextCombo(s.m_currentMatch, s.m_matches, textComboBox);
269
void RegExpWindow::contextMenuEvent(QContextMenuEvent *event)
273
QAction *enterQuotedAction = menu.addAction(tr("Enter Pattern from Code..."));
274
connect(enterQuotedAction, SIGNAL(triggered()), this, SLOT(enterEscaped()));
277
QAction *clearPatternsAction = menu.addAction(tr("Clear Patterns"));
278
connect(clearPatternsAction, SIGNAL(triggered()), patternComboBox, SLOT(clear()));
280
QAction *clearTextsAction = menu.addAction(tr("Clear Text"));
281
connect(clearTextsAction, SIGNAL(triggered()), textComboBox, SLOT(clear()));
284
menu.exec(event->globalPos());
287
void RegExpWindow::enterEscaped()
289
const QString escapedPattern = QInputDialog::getText (this, tr("Enter Pattern from Code"), tr("Pattern"));
290
if ( escapedPattern.isEmpty())
292
patternComboBox->lineEdit()->setText(unescapePattern(escapedPattern));