summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/release/dev/regex-explorer.rst6
-rw-r--r--Source/QtDialog/CMakeLists.txt4
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx10
-rw-r--r--Source/QtDialog/CMakeSetupDialog.h1
-rw-r--r--Source/QtDialog/RegexExplorer.cxx166
-rw-r--r--Source/QtDialog/RegexExplorer.h48
-rw-r--r--Source/QtDialog/RegexExplorer.ui155
7 files changed, 390 insertions, 0 deletions
diff --git a/Help/release/dev/regex-explorer.rst b/Help/release/dev/regex-explorer.rst
new file mode 100644
index 0000000..2147816
--- /dev/null
+++ b/Help/release/dev/regex-explorer.rst
@@ -0,0 +1,6 @@
+regex-explorer
+--------------
+
+* The Qt base CMake GUI got a Regular Expression Explorer which could be used to
+ create and evaluate regular expressions in real-time. The explorer window
+ is available via the ``Tools`` menu.
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index 66fd18b..cad11f5 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -113,12 +113,15 @@ set(SRCS
QCMakeCacheView.h
QCMakeWidgets.cxx
QCMakeWidgets.h
+ RegexExplorer.cxx
+ RegexExplorer.h
)
QT4_WRAP_UI(UI_SRCS
CMakeSetupDialog.ui
Compilers.ui
CrossCompiler.ui
AddCacheEntry.ui
+ RegexExplorer.ui
)
QT4_WRAP_CPP(MOC_SRCS
AddCacheEntry.h
@@ -128,6 +131,7 @@ QT4_WRAP_CPP(MOC_SRCS
QCMake.h
QCMakeCacheView.h
QCMakeWidgets.h
+ RegexExplorer.h
)
QT4_ADD_RESOURCES(RC_SRCS CMakeSetup.qrc)
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index 748dd7d..2b12834 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -33,6 +33,7 @@
#include "QCMakeCacheView.h"
#include "AddCacheEntry.h"
#include "FirstConfigure.h"
+#include "RegexExplorer.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
@@ -125,6 +126,9 @@ CMakeSetupDialog::CMakeSetupDialog()
this, SLOT(doInstallForCommandLine()));
#endif
ToolsMenu->addSeparator();
+ ToolsMenu->addAction(tr("Regular Expression Explorer..."),
+ this, SLOT(doRegexExplorerDialog()));
+ ToolsMenu->addSeparator();
ToolsMenu->addAction(tr("&Find in Output..."),
this, SLOT(doOutputFindDialog()),
QKeySequence::Find);
@@ -1272,6 +1276,12 @@ void CMakeSetupDialog::doOutputFindDialog()
}
}
+void CMakeSetupDialog::doRegexExplorerDialog()
+{
+ RegexExplorer dialog(this);
+ dialog.exec();
+}
+
void CMakeSetupDialog::doOutputFindPrev()
{
doOutputFindNext(false);
diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h
index 1b26c64..bfd2bc9 100644
--- a/Source/QtDialog/CMakeSetupDialog.h
+++ b/Source/QtDialog/CMakeSetupDialog.h
@@ -82,6 +82,7 @@ protected slots:
void doOutputFindNext(bool directionForward = true);
void doOutputFindPrev();
void doOutputErrorNext();
+ void doRegexExplorerDialog();
protected:
diff --git a/Source/QtDialog/RegexExplorer.cxx b/Source/QtDialog/RegexExplorer.cxx
new file mode 100644
index 0000000..dfcf048
--- /dev/null
+++ b/Source/QtDialog/RegexExplorer.cxx
@@ -0,0 +1,166 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Kitware, Inc., Gregor Jasny
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "RegexExplorer.h"
+
+RegexExplorer::RegexExplorer(QWidget* p) : QDialog(p), m_matched(false)
+{
+ this->setupUi(this);
+
+ for(int i = 1; i < cmsys::RegularExpression::NSUBEXP; ++i)
+ {
+ matchNumber->addItem(
+ QString("Match %1").arg(QString::number(i)),
+ QVariant(i));
+ }
+ matchNumber->setCurrentIndex(0);
+}
+
+void RegexExplorer::setStatusColor(QWidget* widget, bool successful)
+{
+ QColor color = successful ? QColor(0, 127, 0) : Qt::red;
+
+ QPalette palette = widget->palette();
+ palette.setColor(QPalette::Foreground, color);
+ widget->setPalette(palette);
+}
+
+void RegexExplorer::on_regularExpression_textChanged(const QString& text)
+{
+#ifdef QT_NO_STL
+ m_regex = text.toAscii().constData();
+#else
+ m_regex = text.toStdString();
+#endif
+
+ bool validExpression =
+ stripEscapes(m_regex) && m_regexParser.compile(m_regex);
+ if(!validExpression)
+ {
+ m_regexParser.set_invalid();
+ }
+
+ setStatusColor(labelRegexValid, validExpression);
+
+ on_inputText_textChanged();
+}
+
+void RegexExplorer::on_inputText_textChanged()
+{
+ if(m_regexParser.is_valid())
+ {
+ QString plainText = inputText->toPlainText();
+#ifdef QT_NO_STL
+ m_text = plainText.toAscii().constData();
+#else
+ m_text = plainText.toStdString();
+#endif
+ m_matched = m_regexParser.find(m_text);
+ }
+ else
+ {
+ m_matched = false;
+ }
+
+ setStatusColor(labelRegexMatch, m_matched);
+
+ if(!m_matched)
+ {
+ clearMatch();
+ return;
+ }
+
+#ifdef QT_NO_STL
+ QString matchText = m_regexParser.match(0).c_str();
+#else
+ QString matchText = QString::fromStdString(m_regexParser.match(0));
+#endif
+ match0->setPlainText(matchText);
+
+ on_matchNumber_currentIndexChanged(matchNumber->currentIndex());
+}
+
+void RegexExplorer::on_matchNumber_currentIndexChanged(int index)
+{
+ if(!m_matched)
+ {
+ return;
+ }
+
+ QVariant itemData = matchNumber->itemData(index);
+ int idx = itemData.toInt();
+
+ if(idx < 1 || idx >= cmsys::RegularExpression::NSUBEXP)
+ {
+ return;
+ }
+
+#ifdef QT_NO_STL
+ QString match = m_regexParser.match(idx).c_str();
+#else
+ QString match = QString::fromStdString(m_regexParser.match(idx));
+#endif
+ matchN->setPlainText(match);
+}
+
+void RegexExplorer::clearMatch()
+{
+ match0->clear();
+ matchN->clear();
+}
+
+bool RegexExplorer::stripEscapes(std::string& source)
+{
+ const char* in = source.c_str();
+
+ std::string result;
+ result.reserve(source.size());
+
+ for(char inc = *in; inc != '\0'; inc = *++in)
+ {
+ if(inc == '\\')
+ {
+ char nextc = in[1];
+ if(nextc == 't')
+ {
+ result.append(1, '\t');
+ in++;
+ }
+ else if(nextc == 'n')
+ {
+ result.append(1, '\n');
+ in++;
+ }
+ else if(nextc == 't')
+ {
+ result.append(1, '\t');
+ in++;
+ }
+ else if(isalnum(nextc) || nextc == '\0')
+ {
+ return false;
+ }
+ else
+ {
+ result.append(1, nextc);
+ in++;
+ }
+ }
+ else
+ {
+ result.append(1, inc);
+ }
+ }
+
+ source = result;
+ return true;
+}
diff --git a/Source/QtDialog/RegexExplorer.h b/Source/QtDialog/RegexExplorer.h
new file mode 100644
index 0000000..2ac9c3e
--- /dev/null
+++ b/Source/QtDialog/RegexExplorer.h
@@ -0,0 +1,48 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Kitware, Inc., Gregor Jasny
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef RegexExplorer_h
+#define RegexExplorer_h
+
+#include <string>
+#include <cmsys/RegularExpression.hxx>
+#include <QDialog>
+
+#include "ui_RegexExplorer.h"
+
+class QString;
+class QWidget;
+
+class RegexExplorer : public QDialog, public Ui::RegexExplorer
+{
+ Q_OBJECT
+public:
+ RegexExplorer(QWidget* p);
+
+private slots:
+ void on_regularExpression_textChanged(const QString& text);
+ void on_inputText_textChanged();
+ void on_matchNumber_currentIndexChanged(int index);
+
+private:
+ static void setStatusColor(QWidget* widget, bool successful);
+ static bool stripEscapes(std::string& regex);
+
+ void clearMatch();
+
+ cmsys::RegularExpression m_regexParser;
+ std::string m_text;
+ std::string m_regex;
+ bool m_matched;
+};
+
+#endif
diff --git a/Source/QtDialog/RegexExplorer.ui b/Source/QtDialog/RegexExplorer.ui
new file mode 100644
index 0000000..2c2d761
--- /dev/null
+++ b/Source/QtDialog/RegexExplorer.ui
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>RegexExplorer</class>
+ <widget class="QDialog" name="RegexExplorer">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>639</width>
+ <height>555</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Regular Expression Explorer</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Input Text</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="inputText"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Regular Expression</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelRegexValid">
+ <property name="text">
+ <string>Valid</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelRegexMatch">
+ <property name="text">
+ <string>Match</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="regularExpression"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Complete Match</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="match0">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QComboBox" name="matchNumber">
+ <property name="editable">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="matchN">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>