summaryrefslogtreecommitdiffstats
path: root/kregexpeditor
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit2bda8f7717adf28da4af0d34fb82f63d2868c31d (patch)
tree8d927b7b47a90c4adb646482a52613f58acd6f8c /kregexpeditor
downloadtdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.tar.gz
tdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeutils@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kregexpeditor')
-rw-r--r--kregexpeditor/Comments4
-rw-r--r--kregexpeditor/KMultiFormListBox/Makefile.am15
-rw-r--r--kregexpeditor/KMultiFormListBox/TODO1
-rw-r--r--kregexpeditor/KMultiFormListBox/ccp.cpp83
-rw-r--r--kregexpeditor/KMultiFormListBox/ccp.h61
-rw-r--r--kregexpeditor/KMultiFormListBox/idx.xbm5
-rw-r--r--kregexpeditor/KMultiFormListBox/indexWindow.cpp97
-rw-r--r--kregexpeditor/KMultiFormListBox/indexWindow.h83
-rw-r--r--kregexpeditor/KMultiFormListBox/kmultiformlistbox-multivisible.cpp305
-rw-r--r--kregexpeditor/KMultiFormListBox/kmultiformlistbox-multivisible.h135
-rw-r--r--kregexpeditor/KMultiFormListBox/kmultiformlistbox-shower.h53
-rw-r--r--kregexpeditor/KMultiFormListBox/kmultiformlistbox-windowed.cpp213
-rw-r--r--kregexpeditor/KMultiFormListBox/kmultiformlistbox-windowed.h83
-rw-r--r--kregexpeditor/KMultiFormListBox/kmultiformlistbox.cpp104
-rw-r--r--kregexpeditor/KMultiFormListBox/kmultiformlistbox.h125
-rw-r--r--kregexpeditor/KMultiFormListBox/kmultiformlistboxentry.cpp44
-rw-r--r--kregexpeditor/KMultiFormListBox/kmultiformlistboxentry.h73
-rw-r--r--kregexpeditor/KMultiFormListBox/kmultiformlistboxfactory.cpp26
-rw-r--r--kregexpeditor/KMultiFormListBox/kmultiformlistboxfactory.h70
-rw-r--r--kregexpeditor/KMultiFormListBox/widgetwindow.cpp117
-rw-r--r--kregexpeditor/KMultiFormListBox/widgetwindow.h60
-rw-r--r--kregexpeditor/KMultiFormListBox/windowlistboxitem.cpp45
-rw-r--r--kregexpeditor/KMultiFormListBox/windowlistboxitem.h44
-rw-r--r--kregexpeditor/KWidgetStreamer/Makefile.am9
-rw-r--r--kregexpeditor/KWidgetStreamer/kwidgetstreamer.cpp177
-rw-r--r--kregexpeditor/KWidgetStreamer/kwidgetstreamer.h74
-rw-r--r--kregexpeditor/Makefile.am65
-rw-r--r--kregexpeditor/TODO49
-rw-r--r--kregexpeditor/altnregexp.cpp102
-rw-r--r--kregexpeditor/altnregexp.h47
-rw-r--r--kregexpeditor/altnwidget.cpp254
-rw-r--r--kregexpeditor/altnwidget.h65
-rw-r--r--kregexpeditor/auxbuttons.cpp121
-rw-r--r--kregexpeditor/auxbuttons.h60
-rw-r--r--kregexpeditor/characterswidget.cpp447
-rw-r--r--kregexpeditor/characterswidget.h144
-rw-r--r--kregexpeditor/charselector.cpp185
-rw-r--r--kregexpeditor/charselector.h52
-rw-r--r--kregexpeditor/compoundregexp.cpp115
-rw-r--r--kregexpeditor/compoundregexp.h54
-rw-r--r--kregexpeditor/compoundwidget.cpp324
-rw-r--r--kregexpeditor/compoundwidget.h104
-rw-r--r--kregexpeditor/concregexp.cpp157
-rw-r--r--kregexpeditor/concregexp.h49
-rw-r--r--kregexpeditor/concwidget.cpp400
-rw-r--r--kregexpeditor/concwidget.h69
-rw-r--r--kregexpeditor/dcbutton.cpp37
-rw-r--r--kregexpeditor/dcbutton.h42
-rw-r--r--kregexpeditor/dotregexp.cpp39
-rw-r--r--kregexpeditor/dotregexp.h41
-rw-r--r--kregexpeditor/drag.cpp77
-rw-r--r--kregexpeditor/drag.h45
-rw-r--r--kregexpeditor/dragaccepter.cpp139
-rw-r--r--kregexpeditor/dragaccepter.h53
-rw-r--r--kregexpeditor/editorwindow.cpp453
-rw-r--r--kregexpeditor/editorwindow.h269
-rw-r--r--kregexpeditor/emacsregexpconverter.cpp253
-rw-r--r--kregexpeditor/emacsregexpconverter.h43
-rw-r--r--kregexpeditor/errormap.cpp73
-rw-r--r--kregexpeditor/errormap.h36
-rwxr-xr-xkregexpeditor/extractrc-from-regexp85
-rw-r--r--kregexpeditor/gen_qregexplexer.cpp1980
-rw-r--r--kregexpeditor/gen_qregexpparser.cc1447
-rw-r--r--kregexpeditor/gen_qregexpparser.hh93
-rw-r--r--kregexpeditor/hi128-app-kregexpeditor.pngbin0 -> 6933 bytes
-rw-r--r--kregexpeditor/hi16-app-kregexpeditor.pngbin0 -> 801 bytes
-rw-r--r--kregexpeditor/hi22-app-kregexpeditor.pngbin0 -> 1235 bytes
-rw-r--r--kregexpeditor/hi32-app-kregexpeditor.pngbin0 -> 1391 bytes
-rw-r--r--kregexpeditor/hi48-app-kregexpeditor.pngbin0 -> 2090 bytes
-rw-r--r--kregexpeditor/hi64-app-kregexpeditor.pngbin0 -> 2895 bytes
-rw-r--r--kregexpeditor/infopage.cpp97
-rw-r--r--kregexpeditor/infopage.h37
-rw-r--r--kregexpeditor/kregexpeditor.desktop76
-rw-r--r--kregexpeditor/kregexpeditor.svgzbin0 -> 1098 bytes
-rw-r--r--kregexpeditor/kregexpeditorfactory.cpp25
-rw-r--r--kregexpeditor/kregexpeditorgui.cpp161
-rw-r--r--kregexpeditor/kregexpeditorgui.desktop62
-rw-r--r--kregexpeditor/kregexpeditorgui.h93
-rw-r--r--kregexpeditor/kregexpeditorprivate.cpp424
-rw-r--r--kregexpeditor/kregexpeditorprivate.h106
-rw-r--r--kregexpeditor/limitedcharlineedit.cpp75
-rw-r--r--kregexpeditor/limitedcharlineedit.h43
-rw-r--r--kregexpeditor/lookaheadregexp.cpp72
-rw-r--r--kregexpeditor/lookaheadregexp.h49
-rw-r--r--kregexpeditor/lookaheadwidget.cpp110
-rw-r--r--kregexpeditor/lookaheadwidget.h51
-rw-r--r--kregexpeditor/main.cpp68
-rw-r--r--kregexpeditor/multicontainerwidget.cpp265
-rw-r--r--kregexpeditor/multicontainerwidget.h50
-rw-r--r--kregexpeditor/myfontmetrics.cpp31
-rw-r--r--kregexpeditor/myfontmetrics.h27
-rw-r--r--kregexpeditor/pair.h37
-rw-r--r--kregexpeditor/picts/Makefile.am2
-rw-r--r--kregexpeditor/picts/altn.pngbin0 -> 310 bytes
-rw-r--r--kregexpeditor/picts/anychar.pngbin0 -> 616 bytes
-rw-r--r--kregexpeditor/picts/autoverify.pngbin0 -> 142 bytes
-rw-r--r--kregexpeditor/picts/begline.pngbin0 -> 244 bytes
-rw-r--r--kregexpeditor/picts/characters.pngbin0 -> 240 bytes
-rw-r--r--kregexpeditor/picts/compound.pngbin0 -> 285 bytes
-rw-r--r--kregexpeditor/picts/endline.pngbin0 -> 245 bytes
-rw-r--r--kregexpeditor/picts/error.pngbin0 -> 234 bytes
-rw-r--r--kregexpeditor/picts/neglookahead.pngbin0 -> 297 bytes
-rw-r--r--kregexpeditor/picts/nonwordboundary.pngbin0 -> 225 bytes
-rw-r--r--kregexpeditor/picts/poslookahead.pngbin0 -> 297 bytes
-rw-r--r--kregexpeditor/picts/repeat.pngbin0 -> 632 bytes
-rw-r--r--kregexpeditor/picts/select.pngbin0 -> 742 bytes
-rw-r--r--kregexpeditor/picts/text.pngbin0 -> 338 bytes
-rw-r--r--kregexpeditor/picts/verify.pngbin0 -> 141 bytes
-rw-r--r--kregexpeditor/picts/wordboundary.pngbin0 -> 210 bytes
-rw-r--r--kregexpeditor/positionregexp.cpp53
-rw-r--r--kregexpeditor/positionregexp.h46
-rw-r--r--kregexpeditor/predefined/General/Makefile.am5
-rw-r--r--kregexpeditor/predefined/General/anything.regexp11
-rw-r--r--kregexpeditor/predefined/General/spaces.regexp11
-rw-r--r--kregexpeditor/predefined/Makefile.am1
-rw-r--r--kregexpeditor/predefined/README2
-rw-r--r--kregexpeditor/qregexpparser.l319
-rw-r--r--kregexpeditor/qregexpparser.y203
-rwxr-xr-xkregexpeditor/qt-only/clean14
-rw-r--r--kregexpeditor/qt-only/compat.cpp115
-rw-r--r--kregexpeditor/qt-only/compat.h85
-rwxr-xr-xkregexpeditor/qt-only/compile28
-rw-r--r--kregexpeditor/qt-only/qt-only.pro137
-rw-r--r--kregexpeditor/qt-only/win-release.bat7
-rw-r--r--kregexpeditor/qtregexpconverter.cpp299
-rw-r--r--kregexpeditor/qtregexpconverter.h43
-rw-r--r--kregexpeditor/qtregexphighlighter.cpp71
-rw-r--r--kregexpeditor/qtregexphighlighter.h34
-rw-r--r--kregexpeditor/regexp.cpp95
-rw-r--r--kregexpeditor/regexp.h72
-rw-r--r--kregexpeditor/regexpbuttons.cpp217
-rw-r--r--kregexpeditor/regexpbuttons.h70
-rw-r--r--kregexpeditor/regexpconverter.cpp93
-rw-r--r--kregexpeditor/regexpconverter.h79
-rw-r--r--kregexpeditor/regexphighlighter.cpp44
-rw-r--r--kregexpeditor/regexphighlighter.h38
-rw-r--r--kregexpeditor/regexpwidget.cpp227
-rw-r--r--kregexpeditor/regexpwidget.h203
-rw-r--r--kregexpeditor/repeatregexp.cpp94
-rw-r--r--kregexpeditor/repeatregexp.h49
-rw-r--r--kregexpeditor/repeatwidget.cpp326
-rw-r--r--kregexpeditor/repeatwidget.h103
-rw-r--r--kregexpeditor/scrollededitorwindow.cpp144
-rw-r--r--kregexpeditor/scrollededitorwindow.h92
-rw-r--r--kregexpeditor/selectablelineedit.cpp73
-rw-r--r--kregexpeditor/selectablelineedit.h53
-rw-r--r--kregexpeditor/singlecontainerwidget.cpp132
-rw-r--r--kregexpeditor/singlecontainerwidget.h53
-rw-r--r--kregexpeditor/test-without-dl/Makefile.am8
-rw-r--r--kregexpeditor/test-without-dl/main.cpp66
-rw-r--r--kregexpeditor/textrangeregexp.cpp143
-rw-r--r--kregexpeditor/textrangeregexp.h75
-rw-r--r--kregexpeditor/textregexp.cpp81
-rw-r--r--kregexpeditor/textregexp.h50
-rw-r--r--kregexpeditor/textwidget.cpp157
-rw-r--r--kregexpeditor/textwidget.h63
-rw-r--r--kregexpeditor/triple.h40
-rw-r--r--kregexpeditor/userdefinedregexps.cpp266
-rw-r--r--kregexpeditor/userdefinedregexps.h75
-rw-r--r--kregexpeditor/util.cpp58
-rw-r--r--kregexpeditor/util.h34
-rw-r--r--kregexpeditor/verifier.cpp117
-rw-r--r--kregexpeditor/verifier.h61
-rw-r--r--kregexpeditor/verifybuttons.cpp214
-rw-r--r--kregexpeditor/verifybuttons.h79
-rw-r--r--kregexpeditor/widgetfactory.cpp209
-rw-r--r--kregexpeditor/widgetfactory.h60
-rw-r--r--kregexpeditor/zerowidgets.cpp145
-rw-r--r--kregexpeditor/zerowidgets.h125
169 files changed, 18002 insertions, 0 deletions
diff --git a/kregexpeditor/Comments b/kregexpeditor/Comments
new file mode 100644
index 0000000..71f4470
--- /dev/null
+++ b/kregexpeditor/Comments
@@ -0,0 +1,4 @@
+(1) If I do not resize the widget to be reparented then it will take up all
+ the size of its new parent, and the parent will never receive a
+ repaint event, and will thus never get a chance to resize its new child
+ to a proper size (This is namely done in repaintEvent() ).
diff --git a/kregexpeditor/KMultiFormListBox/Makefile.am b/kregexpeditor/KMultiFormListBox/Makefile.am
new file mode 100644
index 0000000..5ee885f
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/Makefile.am
@@ -0,0 +1,15 @@
+AM_CPPFLAGS = -DQT_NO_CAST_ASCII
+noinst_LTLIBRARIES = libkmultiformlistbox.la
+
+INCLUDES= -I$(srcdir)/../KWidgetStreamer $(all_includes)
+
+include_HEADERS = kmultiformlistboxentry.h kmultiformlistbox.h \
+ kmultiformlistboxfactory.h
+noinst_HEADERS = ccp.h indexWindow.h kmultiformlistbox-multivisible.h \
+ kmultiformlistbox-windowed.h widgetwindow.h windowlistboxitem.h
+libkmultiformlistbox_la_SOURCES = ccp.cpp kmultiformlistboxentry.cpp \
+ kmultiformlistbox.cpp kmultiformlistbox-multivisible.cpp \
+ kmultiformlistboxfactory.cpp indexWindow.cpp \
+ kmultiformlistbox-windowed.cpp widgetwindow.cpp windowlistboxitem.cpp
+
+METASOURCES = AUTO
diff --git a/kregexpeditor/KMultiFormListBox/TODO b/kregexpeditor/KMultiFormListBox/TODO
new file mode 100644
index 0000000..0c20864
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/TODO
@@ -0,0 +1 @@
+- cut/copy/paste should place/read data from the system clipboard.
diff --git a/kregexpeditor/KMultiFormListBox/ccp.cpp b/kregexpeditor/KMultiFormListBox/ccp.cpp
new file mode 100644
index 0000000..d64a3b2
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/ccp.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+//---------------------
+// ccp = Cut-Copy-Paste
+//---------------------
+
+#include "kmultiformlistbox-multivisible.h"
+#include "ccp.h"
+#include <qobjectlist.h>
+#include <qpopupmenu.h>
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <klocale.h>
+#endif
+
+CCP::CCP(KMultiFormListBoxMultiVisible *ee_, KMultiFormListBoxEntry *eee_) : QObject() {
+ ee = ee_;
+ eee = eee_;
+ install(eee);
+}
+
+void CCP::install(QObject *elm)
+{
+ elm->installEventFilter(this);
+ const QObjectList *children = elm->children();
+ if (children) {
+ QObjectListIt it = QObjectListIt(*children);
+
+ while (QObject *child=it.current()) {
+ if (child->inherits("KMultiFormListBoxMultiVisible")) {
+ // Stop if the widget is an KMultiFormListBox, as this widget has its own cut/copy/paste
+ }
+ else {
+ install(child);
+ }
+ ++it;
+ }
+ }
+}
+
+// This function post the Cut/Copy/Paste menu
+bool CCP::eventFilter(QObject *, QEvent *event)
+{
+ if (event->type() != QEvent::MouseButtonPress ||
+ ((QMouseEvent *) event)->button() != RightButton ||
+ ((QMouseEvent *) event)->state() != QEvent::ControlButton) {
+ return false;
+ }
+
+ QPoint pos = ((QMouseEvent *) event)->globalPos();
+
+ QPopupMenu *menu = new QPopupMenu();
+ menu->insertItem(i18n("Cut"),1);
+ menu->insertItem(i18n("Copy"),2);
+ menu->insertItem(i18n("Paste"),3);
+ menu->insertItem(i18n("Insert Blank"),4);
+
+ int res=menu->exec(pos);
+ switch (res) {
+ case 1: ee->cut(eee); break;
+ case 2: ee->copy(eee); break;
+ case 3: ee->paste(eee); break;
+ case 4: ee->addElement(eee); break;
+ }
+ return true;
+}
+
diff --git a/kregexpeditor/KMultiFormListBox/ccp.h b/kregexpeditor/KMultiFormListBox/ccp.h
new file mode 100644
index 0000000..41857a5
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/ccp.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __ccp
+#define __ccp
+
+
+/**
+ Helper class for @ref KMultiFormListBoxMultiVisible which is used to install EventFilters.
+
+ When the user presses CTRL + right mouse button then a menu should
+ appear which offers him cut and paste capabilities for the entries in
+ the KMultiFormListBoxMultiVisible.
+
+ To obtain this an event filter must be install for each subwidget of the
+ KMultiFormListBoxMultiVisible. This event filter must catch the right mouse press event and
+ post the menu. This requires a widget which has the method @ref
+ eventFilter defined. We have this helper class exactly for this purpose.
+
+ For each @ref KMultiFormListBoxEntry in the @ref KMultiFormListBoxMultiVisible widget an instance of
+ this class is associated.
+
+ CCP stand for Cut Copy and Paste
+
+ @internal
+**/
+class CCP :public QObject {
+
+private:
+ friend class KMultiFormListBoxMultiVisible;
+ /**
+ * Constructor is private so only the class @ref KMultiFormListBoxMultiVisible may create an
+ * instance of this widget.
+ **/
+ CCP(KMultiFormListBoxMultiVisible *,KMultiFormListBoxEntry *);
+
+ void install(QObject *);
+ bool eventFilter(QObject *, QEvent *);
+
+ // Instance variables.
+
+ KMultiFormListBoxMultiVisible *ee;
+ KMultiFormListBoxEntry *eee;
+};
+
+#endif /* ccp */
+
diff --git a/kregexpeditor/KMultiFormListBox/idx.xbm b/kregexpeditor/KMultiFormListBox/idx.xbm
new file mode 100644
index 0000000..e51baee
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/idx.xbm
@@ -0,0 +1,5 @@
+#define idx_width 16
+#define idx_height 12
+static char idx_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x02, 0x04, 0x02, 0x04, 0x02, 0xc4, 0x8a,
+ 0x24, 0x53, 0x14, 0x22, 0x14, 0x22, 0x24, 0x53, 0xce, 0x8a, 0x00, 0x00};
diff --git a/kregexpeditor/KMultiFormListBox/indexWindow.cpp b/kregexpeditor/KMultiFormListBox/indexWindow.cpp
new file mode 100644
index 0000000..362d012
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/indexWindow.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include "indexWindow.moc"
+#endif
+
+#include "indexWindow.h"
+#include <iostream>
+#include <qlayout.h>
+
+indexWindow::indexWindow() : QWidget(0,"", WStyle_Customize | WType_Popup)
+{
+ lb = new QListBox(this);
+ connect(lb,SIGNAL(selected(int)), this, SLOT(lbSelected(int)));
+ QHBoxLayout *lay = new QHBoxLayout(this);
+ lay->addWidget(lb);
+ lbFinish = false;
+}
+
+void indexWindow::lbSelected(int index)
+{
+ lbFinish = true;
+ hide();
+ lbFinish = false;
+ finish(index);
+}
+
+void indexWindow::finish(int index)
+{
+ itemSelected = index;
+ qApp->exit_loop();
+}
+
+
+void indexWindow::insertItem(QString txt)
+{
+ lb->insertItem(txt);
+}
+
+void indexWindow::hideEvent(QHideEvent *h)
+{
+ QWidget::hideEvent(h);
+ if (!lbFinish)
+ finish(-1);
+}
+
+
+int indexWindow::exec(const QPoint & /*start*/, int /*width*/)
+{
+ // This code is not xinerama safe, on the other hand this part of the widget
+ // is not used in KRegExpEditor. This is part of a widget which has
+ // never been completed, but which is used partly by KRegExpEditor.
+ // 23 Feb. 2003 11:28 -- Jesper K. Pedersen
+/*
+ // calculate the height of all the elements together.
+ // I need to do it this way, as sizeHint doesn't report the correct size
+ // and itemHeight doesn't neither.
+ int elm_h = lb->item(0)->height(lb) * lb->count();
+ elm_h += 2*lb->frameWidth();
+
+ QWidget *desktop = QApplication::desktop();
+ int desktop_h = desktop->height();
+ int rest_h = desktop_h - start.y();
+ int below_h = QMAX(rest_h, 200);
+
+ int start_y = start.y();
+
+ if (rest_h < 200 && elm_h > 200) {
+ start_y = desktop_h-QMIN(elm_h,200);
+ }
+
+ setGeometry(start.x(), start_y, width, QMIN(elm_h, below_h));
+ show();
+ qApp->enter_loop();
+ return itemSelected;
+*/
+ return 0;
+}
+
diff --git a/kregexpeditor/KMultiFormListBox/indexWindow.h b/kregexpeditor/KMultiFormListBox/indexWindow.h
new file mode 100644
index 0000000..3597960
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/indexWindow.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __indexWindow
+#define __indexWindow
+
+#include <qlistbox.h>
+
+/**
+ Post a toplevel listbox synchronously.
+
+ When the user presses the Idx button in the @ref KMultiFormListBox, then a
+ listbox with the elements from the KMultiFormListBox must be shown. From this
+ listbox the user should chose the element he wants to scroll to.
+ This widget takes care of posting this listbox, and ensuring that the
+ user can not do anything else before he has chosen an element.
+
+ This widget resembles the behavior of @ref QPopupMenu, the difference
+ is, however, that the QPopupMenu can not handle that the elements in the
+ menu exceed the size of the screen. This widget can.
+
+ In the future this widget may be replaced with the QPopupMenu if the
+ QPopupMenu can handle this situation. But for now - it works!
+
+ @internal
+**/
+class indexWindow : public QWidget{
+
+Q_OBJECT
+
+public:
+ indexWindow();
+
+ /**
+ This method inserts an element into the listbox which is shown when
+ the @ref exec method is invoked.
+ **/
+ void insertItem(QString txt);
+
+ /**
+ This function shows the index window with the elements inserted using
+ the @ref insertItem function. The function will not return before the
+ user has chosen an element in the listbox, or have pressed the right
+ mouse button outside the window. As a result of returning from this
+ function, the listbox is hidden.
+
+ @param start The upper left corner of the pop-up window.
+ @param width The width of the window
+ @return The index of the element chosen, or -1 if no element has been
+ chosen.
+ **/
+ int exec(const QPoint &start, int width);
+
+protected:
+ void finish(int retVal);
+ virtual void hideEvent(QHideEvent *h);
+
+protected slots:
+ void lbSelected(int);
+
+private:
+ QListBox *lb;
+ bool lbFinish;
+ int itemSelected;
+
+};
+
+#endif /* indexWindow */
+
diff --git a/kregexpeditor/KMultiFormListBox/kmultiformlistbox-multivisible.cpp b/kregexpeditor/KMultiFormListBox/kmultiformlistbox-multivisible.cpp
new file mode 100644
index 0000000..335863b
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/kmultiformlistbox-multivisible.cpp
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifdef QT_ONLY
+ #include "compat.h"
+ #include <qmessagebox.h>
+#else
+ #include <kmessagebox.h>
+ #include "kmultiformlistbox-multivisible.moc"
+#endif
+
+#include "kmultiformlistbox-multivisible.h"
+#include "indexWindow.h"
+#include "ccp.h"
+
+#include <qbitmap.h>
+
+const int indexButtonWidth = 16;
+const int indexButtonHeight = 12;
+const uchar indexButtonBits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x02, 0x04, 0x02, 0x04, 0x02, 0xc4, 0x8a,
+ 0x24, 0x53, 0x14, 0x22, 0x14, 0x22, 0x24, 0x53, 0xce, 0x8a, 0x00, 0x00
+};
+
+
+KMultiFormListBoxMultiVisible::KMultiFormListBoxMultiVisible(KMultiFormListBoxFactory *fact, QWidget *parent, const char *name)
+ : QScrollView(parent, name)
+{
+ factory = fact;
+
+ // Initialize the element list
+ elms = new WidgetList();
+
+ // Initialize the clipper.
+ enableClipper(true);
+ resizeContents(50,50); // This is required for proper functionality
+}
+
+
+
+//----------------------------------------------------------------------
+// This function returns a list of the elements in the KMultiFormListBox widget.
+//----------------------------------------------------------------------
+KMultiFormListBoxEntryList KMultiFormListBoxMultiVisible::elements()
+{
+ KMultiFormListBoxEntryList res;
+ for (QWidget *child = elms->first(); child; child=elms->next()) {
+ if (strcmp(child->name(),"seperator") != 0) {
+ res.append((KMultiFormListBoxEntry *) child);
+ }
+ }
+ return res;
+}
+
+
+//----------------------------------------------------------------------
+// This function is called whenever the KMultiFormListBox widget is resized. It is
+// necessary to ensure that the content of the clipper is resized.
+//----------------------------------------------------------------------
+void KMultiFormListBoxMultiVisible::resizeEvent(QResizeEvent *e)
+{
+ // The call of the super class ensures that the outer border is updated.
+ QScrollView::resizeEvent(e);
+
+ updateClipperContent();
+}
+
+void KMultiFormListBoxMultiVisible::updateClipperContent()
+{
+ // Extract the current size of the clipper
+ int ClipperWidth = clipper()->size().width();
+ int ClipperHeight = clipper()->size().height();
+
+ // Initialize the calculation of the size of the new clipper.
+ int totalHeight = 0;
+ int maxWidth = ClipperWidth;
+ int count = 0;
+
+
+ // calculate the required size.
+ for (QWidget *child = elms->first(); child; child=elms->next()) {
+ maxWidth = QMAX(maxWidth, child->sizeHint().width());
+ if (strcmp(child->name(), "seperator") != 0) {
+ totalHeight += child->sizeHint().height();
+ count++;
+ }
+ else {
+ totalHeight += child->size().height();
+ }
+ }
+
+ // Calculate the extra height for the elements.
+ int extra = 0;
+ if (totalHeight < ClipperHeight && count != 0) {
+ extra = (ClipperHeight - totalHeight) / count;
+ totalHeight = ClipperHeight;
+ }
+
+ // Now place the elements in the clipper.
+ int yPos = 0;
+ for (QWidget *child2 = elms->first(); child2; child2=elms->next()) {
+ int h;
+ if ( strcmp(child2->name(),"seperator") != 0) {
+ h = child2->sizeHint().height();
+ h += extra;
+ }
+ else {
+ h = child2->size().height();
+ }
+
+ moveChild(child2, 0,yPos);
+
+ child2->resize(maxWidth,h);
+ yPos += h;
+ }
+
+ // Finally call the resize procedure for the clipper to ensure that the
+ // new sizes is shown properly.
+ resizeContents(maxWidth, totalHeight);
+}
+
+
+void KMultiFormListBoxMultiVisible::addElement()
+{
+ addElement(0);
+}
+
+void KMultiFormListBoxMultiVisible::addElement(KMultiFormListBoxEntry *after)
+{
+ KMultiFormListBoxEntry *elm = factory->create(viewport());
+ insertElmIntoWidget(elm, after);
+}
+
+void KMultiFormListBoxMultiVisible::append(KMultiFormListBoxEntry *elm)
+{
+ elm->reparent(viewport(), 0, QPoint(0,0), false);
+ insertElmIntoWidget(elm, 0);
+}
+
+void KMultiFormListBoxMultiVisible::delElement(QWidget *elm)
+{
+ int index = elms->find(elm);
+ QWidget *next = elms->at(index+1);
+ if (strcmp(next->name(),"seperator") != 0) {
+ elms->removeRef(next);
+ removeChild(next);
+ }
+
+ elms->removeRef(elm);
+ removeChild(elm);
+
+ updateClipperContent();
+}
+
+void KMultiFormListBoxMultiVisible::delAnElement()
+{
+ delElement(elms->at(0));
+}
+
+void KMultiFormListBoxMultiVisible::insertElmIntoWidget(KMultiFormListBoxEntry *elm, KMultiFormListBoxEntry *after)
+{
+ // Bind the index button if it exists.
+ if (elm->indexButton()) {
+ elm->indexButton()->setPixmap(QBitmap(indexButtonWidth, indexButtonHeight,
+ indexButtonBits, true));
+ connect(elm->indexButton(), SIGNAL(clicked()), elm, SLOT(acceptIndexButton()));
+ connect(elm, SIGNAL(gotoIndex(KMultiFormListBoxEntry *)),
+ this, SLOT(showIndexList(KMultiFormListBoxEntry *)));
+ }
+
+ // Find the location to insert the new element.
+ int index = elms->count();
+ if (after) {
+ index = elms->findRef(after);
+ }
+
+ // Now show the new element.
+ elms->insert(index, elm);
+ elm->show();
+ addChild(elm,0,0); // updateClipperContent will place the child correctly.
+
+ QWidget *sep = factory->separator(viewport());
+ if (sep != 0) {
+ sep->setName("seperator");
+ sep->show();
+ addChild(sep,0,0); // updateClipperContent will place the child correctly.
+ elms->insert(index+1, sep);
+ }
+
+ updateClipperContent();
+
+ showWidget(elm); // scroll to show the new widget.
+
+ // install cut'n'paste functionallity
+ new CCP(this,elm);
+}
+
+
+//----------------------------------------------------------------------
+// This function shows the list of available Idx elements.
+//----------------------------------------------------------------------
+void KMultiFormListBoxMultiVisible::showIndexList(KMultiFormListBoxEntry *elm)
+{
+ indexWindow *menu = new indexWindow();
+
+ // Insert the elements into the menu item.
+ for (QWidget *child = elms->first(); child; child=elms->next()) {
+ if ( strcmp(child->name(), "seperator") != 0) {
+ QString txt = ((KMultiFormListBoxEntry *) child)->idxString();
+ menu->insertItem(txt);
+ }
+ }
+
+ // Calculate the location of the window
+ QPoint start;
+ int width;
+ elm->indexWindowPos(&start, &width);
+
+ // Show the window.
+ int index = menu->exec(start,width);
+
+ if (index != -1) {
+ for (QWidget *child = elms->first(); child; child=elms->next()) {
+ if ( strcmp(child->name(), "seperator") != 0) {
+
+ if (index == 0) {
+ showWidget((KMultiFormListBoxEntry *) child);
+ break;
+ }
+ index--;
+ }
+ }
+ }
+ delete menu;
+}
+
+//----------------------------------------------------------------------
+// Scroll to the loaction of the given KMultiFormListBoxEntry element.
+//----------------------------------------------------------------------
+void KMultiFormListBoxMultiVisible::showWidget(KMultiFormListBoxEntry *elm)
+{
+ setContentsPos(childX(elm), childY(elm));
+}
+
+
+void KMultiFormListBoxMultiVisible::cut(KMultiFormListBoxEntry *elm)
+{
+ if (countElements(elms) == 1) {
+ KMessageBox::information(this, i18n("Due to a bug, it is not possible to remove the last element."), i18n("Internal Error") );
+ return;
+ }
+
+ QDataStream stream(clipboard, IO_WriteOnly);
+ factory->toStream( elm, stream );
+ delElement(elm);
+}
+
+void KMultiFormListBoxMultiVisible::copy(KMultiFormListBoxEntry *elm)
+{
+ QDataStream stream(clipboard, IO_WriteOnly);
+ factory->toStream(elm, stream);
+}
+
+void KMultiFormListBoxMultiVisible::paste(KMultiFormListBoxEntry *oldElm)
+{
+ if (clipboard.size() == 0) {
+ KMessageBox::information(this, i18n("There is no element on the clipboard to paste in."));
+ return;
+ }
+
+ KMultiFormListBoxEntry *newElm = factory->create(viewport());
+ QDataStream stream( clipboard, IO_ReadOnly );
+ factory->fromStream(stream, newElm);
+ insertElmIntoWidget(newElm,oldElm);
+}
+
+
+int KMultiFormListBoxMultiVisible::countElements(WidgetList *elms)
+{
+ int count = 0;
+
+ for (QWidget *child = elms->first(); child; child=elms->next()) {
+ if (dynamic_cast<const KMultiFormListBoxEntry *>(child))
+ count++;
+ }
+
+ return count;
+}
+
+
diff --git a/kregexpeditor/KMultiFormListBox/kmultiformlistbox-multivisible.h b/kregexpeditor/KMultiFormListBox/kmultiformlistbox-multivisible.h
new file mode 100644
index 0000000..87aeba4
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/kmultiformlistbox-multivisible.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+// ------------------------------- Description ----------------------------
+// This is the KMultiFormListBox Widget. You do not need to inheret from this class,
+// your interface to it will be through the methods `append` and `elements'.
+//
+// To make an instance of the widget, you need to inherit the classes
+// `KMultiFormListBoxFactory' and `KMultiFormListBoxEntry'.
+// ------------------------------------------------------------------------
+#ifndef __kmultiformlistboxmultivisble
+#define __kmultiformlistboxmultivisble
+
+// -------------------------------- includes ------------------------------
+#include "kmultiformlistbox.h"
+//-------------------------------------------------------------------------
+
+/**
+ @internal
+*/
+class KMultiFormListBoxMultiVisible :public QScrollView, KMultiFormListBoxShower {
+
+Q_OBJECT
+
+friend class KMultiFormListBox;
+
+private:
+ /**
+ @param factory A factory used to generate the instances of KMultiFormListBoxEntry
+ class which is repeated in the KMultiFormListBox
+ @param parent A pointer to the parent widget
+ */
+ KMultiFormListBoxMultiVisible(KMultiFormListBoxFactory *factory, QWidget *parent = 0, const char *name = 0);
+
+ /**
+ @return The elements in the KMultiFormListBox
+ */
+ KMultiFormListBoxEntryList elements();
+ void append(KMultiFormListBoxEntry *);
+
+ QWidget* qWidget() { return this; }
+
+
+public slots:
+
+ /**
+ This slot should be connected to a button which lets the user know that
+ he may get more elements in this KMultiFormListBox by pressing it.
+ The button should be labeled ``More Entries'' or something similar.
+ */
+ void addElement(); // Adds an empty element to the KMultiFormListBox
+
+
+protected slots:
+
+ /**
+ When this slot is invoked then the Idx menu will be shown.
+ @param elm The KMultiFormListBoxEntry element where the Idx button was
+ pressed. This information is necessary to be able to calculate the
+ location where the drop down menu should be shown
+ */
+ void showIndexList(KMultiFormListBoxEntry *elm);
+
+protected:
+ /**
+ Copies the element pointed to by which to the clipboard and removes it
+ from the interface.
+ This function is accessed from the class @ref CCP.
+ @param which A pointer to the element to cut.
+ */
+ void cut(KMultiFormListBoxEntry *which);
+
+ /**
+ Copies the element pointed to by which to the clipboard.
+ This function is accessed from the class @ref CCP.
+ @param which A pointer to the element to copied.
+ */
+ void copy(KMultiFormListBoxEntry *which);
+
+ /**
+ Paste the element from the clipboard to the KMultiFormListBox
+ This function is accessed from the class @ref CCP.
+ @param which A pointer to the KMultiFormListBoxEntry element which the
+ clipboard element should be inserted before,.
+ */
+ void paste(KMultiFormListBoxEntry *which);
+
+ /**
+ Inserts an empty KMultiFormListBoxEntry into the widget.
+ @param which A pointer to the element which the new empty widget
+ should be inserted before.
+ */
+
+ void addElement(KMultiFormListBoxEntry *);
+
+ friend class CCP;
+
+ virtual void resizeEvent(QResizeEvent *);
+ void addElemBefore(KMultiFormListBoxEntry *newElm, QWidget *existing);
+ void insertElmIntoWidget(KMultiFormListBoxEntry *elm, KMultiFormListBoxEntry *after);
+ void showWidget(KMultiFormListBoxEntry *elm);
+ void delElement(QWidget *);
+ void delAnElement();
+ void addElemBefore(KMultiFormListBoxEntry *newElm, KMultiFormListBoxEntry *existing);
+ void updateClipperContent();
+ int countElements(WidgetList *);
+
+
+
+private:
+ // Instance variables
+
+ KMultiFormListBoxFactory *factory;
+ WidgetList *elms;
+ QPushButton *addBut;
+ QByteArray clipboard;
+};
+
+
+#endif /* kmultiformlistboxmultivisble */
+
diff --git a/kregexpeditor/KMultiFormListBox/kmultiformlistbox-shower.h b/kregexpeditor/KMultiFormListBox/kmultiformlistbox-shower.h
new file mode 100644
index 0000000..fe786d7
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/kmultiformlistbox-shower.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __kmultiformlistboxshower
+#define __kmultiformlistboxshower
+
+// -------------------------------- includes ------------------------------
+//-------------------------------------------------------------------------
+typedef QPtrList<KMultiFormListBoxEntry> KMultiFormListBoxEntryList ;
+
+/**
+ Abstract class defining the interface for widgets showing a number of @ref KMultiFormListBoxEntry.
+
+ @internal
+*/
+class KMultiFormListBoxShower {
+
+public:
+ virtual KMultiFormListBoxEntryList elements() = 0;
+
+ /** Appends the given argument to the list */
+ virtual void append(KMultiFormListBoxEntry *) = 0;
+
+ /** Return the element as a QWidget */
+ virtual QWidget* qWidget() = 0;
+
+ /** Adds an empty element. */
+ virtual void addElement() = 0;
+
+ /** Deletes an element at the given index. */
+ virtual void delElement(QWidget *) = 0;
+
+ /** Deletes any element from the list */
+ virtual void delAnElement() = 0;
+};
+
+
+#endif /* kmultiformlistboxshower */
+
diff --git a/kregexpeditor/KMultiFormListBox/kmultiformlistbox-windowed.cpp b/kregexpeditor/KMultiFormListBox/kmultiformlistbox-windowed.cpp
new file mode 100644
index 0000000..6ef14d3
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/kmultiformlistbox-windowed.cpp
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <kmessagebox.h>
+ #include <kpushbutton.h>
+ #include <kstdguiitem.h>
+ #include "kmultiformlistbox-windowed.moc"
+#endif
+
+#include "widgetwindow.h"
+#include "windowlistboxitem.h"
+
+KMultiFormListBoxWindowed::KMultiFormListBoxWindowed(KMultiFormListBoxFactory *factory, QWidget *parent,
+ bool showUpDownButtons, bool showHelpButton,
+ QString addButtonText,const char *name)
+ : QWidget( parent, name )
+{
+ _layout = new QVBoxLayout(this);
+
+ QHBoxLayout *innerLayout = new QHBoxLayout();
+ _layout->addLayout(innerLayout);
+
+ _listbox = new KListBox(this,"listbox");
+ _listbox->setSelectionMode(QListBox::Single);
+ innerLayout->addWidget(_listbox);
+
+ QVBoxLayout *buttons = new QVBoxLayout();
+ innerLayout->addLayout(buttons);
+
+ QPushButton *but = new QPushButton(addButtonText, this,"Add Button");
+ buttons->addWidget(but,0);
+ connect(but, SIGNAL(clicked()), this, SLOT(addNewElement()));
+
+ but = new QPushButton(i18n("Edit"), this,"Edit Button");
+ buttons->addWidget(but,0);
+ connect(but,SIGNAL(clicked()), this, SLOT(slotEditSelected()));
+ connect(_listbox, SIGNAL(doubleClicked(QListBoxItem *)), this, SLOT(slotEditSelected(QListBoxItem *)));
+ _buttonList.append(but);
+
+ but = new QPushButton(i18n("Delete"), this, "Delete Button");
+ buttons->addWidget(but,0);
+ connect(but, SIGNAL(clicked()), this, SLOT(slotDeleteEntry()));
+ _buttonList.append(but);
+
+ but = new QPushButton(i18n("Copy"), this, "Copy Button");
+ buttons->addWidget(but,0);
+ connect(but, SIGNAL(clicked()), this, SLOT(slotCopySelected()));
+ _buttonList.append(but);
+
+ if (showUpDownButtons) {
+ but = new QPushButton(i18n("Up"), this, "Up Button");
+ buttons->addWidget(but, 0);
+ connect(but, SIGNAL(clicked()), this, SLOT(slotMoveItemUp()));
+ _buttonList.append(but);
+
+ but = new QPushButton(i18n("Down"), this, "Down Button");
+ buttons->addWidget(but, 0);
+ connect(but, SIGNAL(clicked()), this, SLOT(slotMoveItemDown()));
+ _buttonList.append(but);
+ }
+
+ if (showHelpButton) {
+ but = new KPushButton(KStdGuiItem::help(), this, "Help Button");
+ buttons->addWidget(but, 0);
+ connect(but, SIGNAL(clicked()), this, SIGNAL(showHelp()));
+ }
+
+ buttons->addStretch(1);
+ _factory = factory;
+ slotUpdateButtonState();
+
+}
+
+KMultiFormListBoxEntryList KMultiFormListBoxWindowed::elements()
+{
+ KMultiFormListBoxEntryList list;
+ for (unsigned int i=0; i < _listbox->count(); i++) {
+ WindowListboxItem *item = (WindowListboxItem *) _listbox->item(i);
+ list.append(item->entry());
+ }
+ return list;
+}
+
+void KMultiFormListBoxWindowed::delElement(QWidget */*elm*/)
+{
+ // kdDebug() << "KMultiFormListBoxWindowed::delElement NOT YET IMPLEMENTED"<<endl;
+ // TODO
+}
+
+void KMultiFormListBoxWindowed::delAnElement()
+{
+ // kdDebug() << "KMultiFormListBoxWindowed::delAnElement NOT YET IMPLEMENTED"<<endl;
+ // TODO
+}
+
+
+void KMultiFormListBoxWindowed::append(KMultiFormListBoxEntry *elm)
+{
+ (void) new WidgetWindow(_factory, elm, _listbox);
+ slotUpdateButtonState();
+}
+
+void KMultiFormListBoxWindowed::addNewElement()
+{
+ // kdDebug() << "addNewElement " << _factory << "," << _listbox << endl;
+
+ QWidget *widget = new WidgetWindow(_factory, _listbox);
+ widget->show();
+ connect(widget, SIGNAL(finished()), this, SLOT(slotUpdateButtonState()));
+}
+
+void KMultiFormListBoxWindowed::addElement()
+{
+ new WidgetWindow(_factory, _listbox);
+ slotUpdateButtonState();
+}
+
+void KMultiFormListBoxWindowed::slotEditSelected(QListBoxItem *item)
+{
+ ((WindowListboxItem *) item)->displayWidget();
+}
+
+void KMultiFormListBoxWindowed::slotEditSelected()
+{
+ WindowListboxItem *item = selected();
+ if (item) {
+ slotEditSelected(item);
+ }
+}
+
+void KMultiFormListBoxWindowed::slotDeleteEntry()
+{
+ WindowListboxItem *item = selected();
+ if (item) {
+ int answer =
+ KMessageBox::warningContinueCancel(0, i18n("Delete item \"%1\"?").arg(item->text()),i18n("Delete Item"),KStdGuiItem::del());
+ if (answer == KMessageBox::Continue) {
+ delete item;
+ slotUpdateButtonState();
+ }
+ }
+}
+
+void KMultiFormListBoxWindowed::slotCopySelected()
+{
+ WindowListboxItem *item = selected();
+ if (item) {
+ item->clone();
+ }
+}
+
+WindowListboxItem *KMultiFormListBoxWindowed::selected()
+{
+ int i = _listbox->currentItem();
+ if (i == -1) {
+ return 0;
+ } else {
+ return (WindowListboxItem *) _listbox->item(i);
+ }
+}
+
+void KMultiFormListBoxWindowed::slotMoveItemUp()
+{
+ WindowListboxItem *item = selected();
+ if (item == 0)
+ return;
+
+ int index = _listbox->index(item);
+ if (index != 0) {
+ _listbox->takeItem(item);
+ _listbox->insertItem(item, index-1);
+ _listbox->setCurrentItem(item);
+ }
+}
+
+void KMultiFormListBoxWindowed::slotMoveItemDown()
+{
+ WindowListboxItem *item = selected();
+ if (item == 0)
+ return;
+
+ unsigned int index = _listbox->index(item);
+ if (index < _listbox->count()) {
+ _listbox->takeItem(item);
+ _listbox->insertItem(item, index+1);
+ _listbox->setCurrentItem(item);
+ }
+}
+
+void KMultiFormListBoxWindowed::slotUpdateButtonState()
+{
+ bool on = (_listbox->count() != 0);
+ for (unsigned int i=0; i<_buttonList.count(); i++) {
+ _buttonList.at(i)->setEnabled(on);
+ }
+}
diff --git a/kregexpeditor/KMultiFormListBox/kmultiformlistbox-windowed.h b/kregexpeditor/KMultiFormListBox/kmultiformlistbox-windowed.h
new file mode 100644
index 0000000..74d6d9f
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/kmultiformlistbox-windowed.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __kmultiformlistboxwindowed
+#define __kmultiformlistboxwindowed
+
+#ifdef QT_ONLY
+ #include "compat.h"
+ #include <qlistbox.h>
+#else
+ #include <klistbox.h>
+#endif
+
+#include "kmultiformlistboxfactory.h"
+#include "kmultiformlistbox.h"
+class WindowListboxItem;
+
+
+/**
+ This class implements the windowed look for a @ref KMultiFormListBox
+
+ @internal
+*/
+class KMultiFormListBoxWindowed :public QWidget, KMultiFormListBoxShower {
+
+Q_OBJECT
+
+friend class KMultiFormListBox;
+
+private:
+ KMultiFormListBoxWindowed(KMultiFormListBoxFactory *factory, QWidget *parent,
+ bool showUpDownButtons, bool showHelpButton, QString addButtonText,
+ const char *name);
+
+ KMultiFormListBoxEntryList elements();
+ const KMultiFormListBoxEntryList elements() const;
+ void append(KMultiFormListBoxEntry *);
+ WindowListboxItem *selected();
+ QWidget* qWidget() { return this; }
+
+ QVBoxLayout* _layout;
+ KMultiFormListBoxFactory* _factory;
+ QPtrList<QPushButton> _buttonList;
+ KListBox* _listbox;
+ virtual void delElement(QWidget *); // Deletes the given element
+ virtual void delAnElement();
+ void addElement();
+
+
+public slots:
+ void addNewElement();
+
+signals:
+ void showHelp();
+
+private slots:
+ void slotEditSelected();
+ void slotEditSelected(QListBoxItem *item);
+ void slotCopySelected();
+ void slotMoveItemUp();
+ void slotMoveItemDown();
+ void slotDeleteEntry();
+ void slotUpdateButtonState();
+
+};
+
+
+#endif /* kmultiformlistboxwindowed */
+
diff --git a/kregexpeditor/KMultiFormListBox/kmultiformlistbox.cpp b/kregexpeditor/KMultiFormListBox/kmultiformlistbox.cpp
new file mode 100644
index 0000000..57b5abb
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/kmultiformlistbox.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef QT_ONLY
+ #include "kmultiformlistbox.moc"
+#endif
+
+#include "kmultiformlistbox-multivisible.h"
+#include "kmultiformlistbox-windowed.h"
+
+KMultiFormListBox::KMultiFormListBox( KMultiFormListBoxFactory *factory, KMultiFormListBoxType tp, QWidget *parent,
+ bool showUpDownButtons, bool showHelpButton, QString addButtonText,
+ const char *name ) : QWidget( parent, name )
+{
+ switch ( tp ) {
+
+ case MultiVisible:
+ theWidget = new KMultiFormListBoxMultiVisible( factory, this, "KMultiFormListBox Widget" );
+ break;
+
+ case Windowed:
+ theWidget = new KMultiFormListBoxWindowed( factory, this, showUpDownButtons,
+ showHelpButton, addButtonText, "KMultiFormListBox Widget" );
+ break;
+ }
+
+ QWidget *widget = theWidget->qWidget();
+
+ QHBoxLayout *layout = new QHBoxLayout( this );
+ _factory = factory;
+ layout->addWidget( widget );
+}
+
+void KMultiFormListBox::append( KMultiFormListBoxEntry *element )
+{
+ theWidget->append( element );
+}
+
+void KMultiFormListBox::addElement()
+{
+ theWidget->addElement();
+}
+
+KMultiFormListBoxEntryList KMultiFormListBox::elements()
+{
+ return theWidget->elements();
+}
+
+const KMultiFormListBoxEntryList KMultiFormListBox::elements() const
+{
+ return const_cast<KMultiFormListBox*>(this)->elements();
+}
+
+void KMultiFormListBox::slotChangeFace( KMultiFormListBoxType /*newFace*/ )
+{
+ // TODO
+ // kdDebug() << "It's not possible yet to change the face on the fly." << endl
+ // << "Please let me (blackie@kde.org) know that you need it, and I'll work on it" << endl;
+}
+
+void KMultiFormListBox::toStream( QDataStream& stream ) const
+{
+ const KMultiFormListBoxEntryList elms = elements();
+ stream << elms.count();
+ for ( QPtrListIterator<KMultiFormListBoxEntry> it(elms); *it; ++it)
+ _factory->toStream( *it, stream );
+}
+
+void KMultiFormListBox::fromStream( QDataStream& stream )
+{
+ unsigned int fromCount, toCount;
+ stream >> fromCount;
+
+ toCount = elements().count();
+
+ // adds/remove elements in the to list, to make it have the correct length.
+ for (unsigned int j=toCount; j< fromCount; ++j) {
+ addElement();
+ }
+ for (unsigned int k=fromCount; k < toCount; ++k) {
+ theWidget->delAnElement();
+ }
+
+ KMultiFormListBoxEntryList elms = elements();
+ for (QPtrListIterator<KMultiFormListBoxEntry> it(elms); *it; ++it)
+ _factory->fromStream( stream, *it );
+}
+
+
+
diff --git a/kregexpeditor/KMultiFormListBox/kmultiformlistbox.h b/kregexpeditor/KMultiFormListBox/kmultiformlistbox.h
new file mode 100644
index 0000000..8e85808
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/kmultiformlistbox.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __kmultiformlistbox
+#define __kmultiformlistbox
+
+#include "kmultiformlistboxfactory.h"
+#include "kmultiformlistbox-shower.h"
+#include "kmultiformlistboxentry.h"
+#include <qptrlist.h>
+#include <qlayout.h>
+#include <qscrollview.h>
+
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <klocale.h>
+#endif
+
+class QDataStream;
+
+
+typedef QPtrList<KMultiFormListBoxEntry> KMultiFormListBoxEntryList ;
+typedef QPtrList<QWidget> WidgetList;
+class KMultiFormListBoxMultiVisible;
+
+/**
+ The main class used to get an KMultiFormListBox widget.
+
+ The KMultiFormListBox widget consist of a sub-widget which is repeated a
+ number of times, it is up to the end user to determine the number of times
+ the sub widget is repeated, and he may require an additional copy simply
+ by pressing a ``Add'' or ``More Entries'' button. The KMultiFormListBox
+ widget has two different faces (i.e. two different end user
+ interfaces). One (Windowed) will show a listbox from which the end user
+ can access each subwidget containing data by pressing the LMB on a name
+ for the element. The other face (MultiVisible) shows all the subwidgets in
+ one huge ``Listbox''.
+
+ To use the KMultiFormListBox widget you must create a class which is inherited
+ from the @ref KMultiFormListBoxFactory class. This new class must override the
+ function `create'. This function must return a freshly made instance of
+ the class @ref KMultiFormListBoxEntry (or a subclass of this). The KMultiFormListBoxEntry
+ instance is the one inserted into the KMultiFormListBox widget (one instance for
+ each sub widget in the KMultiFormListBox widget).
+
+ @author Jesper Kjr Pedersen <blackie@kde.org>
+ **/
+class KMultiFormListBox : public QWidget {
+
+Q_OBJECT
+
+public:
+
+ enum KMultiFormListBoxType {MultiVisible, Windowed};
+
+ /**
+ @param factory A factory used to generate the instances of
+ KMultiFormListBoxEntry class which is repeated in the KMultiFormListBox
+ @param parent A pointer to the parent widget
+ **/
+ KMultiFormListBox(KMultiFormListBoxFactory *factory,
+ KMultiFormListBoxType tp=Windowed,
+ QWidget *parent = 0, bool showUpDownButtons = true,
+ bool showHelpButton = true, QString addButtonText = i18n("Add"),
+ const char *name = 0);
+
+ /**
+ @return The elements in the KMultiFormListBox.
+ **/
+ KMultiFormListBoxEntryList elements();
+ const KMultiFormListBoxEntryList elements() const;
+
+ /**
+ TODO.
+ **/
+ void append(KMultiFormListBoxEntry *);
+
+ /** write data out to stream */
+ void toStream( QDataStream& stream ) const;
+
+ /** reads data in from stream */
+ void fromStream( QDataStream& stream );
+
+public slots:
+
+ /**
+ Adds an empty element to the KMultiFormListBox.
+
+ This slot is only required for the @ref MultiVisible face. It should
+ be connected to a button which lets the user know that he may get more
+ elements in this KMultiFormListBox by pressing it. The button should
+ be labeled ``More Entries'' or something similar.
+ **/
+ void addElement(); // Adds an empty element to the KMultiFormListBox
+
+ /**
+ Changes the face of the KMultiFormListBox.
+ @param face The new face of the KMultiFormListBox
+ **/
+ void slotChangeFace(KMultiFormListBoxType newFace);
+
+private:
+ KMultiFormListBoxShower *theWidget;
+ KMultiFormListBoxFactory *_factory;
+
+};
+
+
+#endif /* kmultiformlistbox */
+
diff --git a/kregexpeditor/KMultiFormListBox/kmultiformlistboxentry.cpp b/kregexpeditor/KMultiFormListBox/kmultiformlistboxentry.cpp
new file mode 100644
index 0000000..e6768a3
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/kmultiformlistboxentry.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifndef QT_ONLY
+ #include "kmultiformlistboxentry.moc"
+#endif
+
+#include "kmultiformlistboxentry.h"
+//----------------------------------------------------------------------
+// This function is needed to signal which of the KMultiFormListBox entries
+// the Idx button was invoked from.
+//----------------------------------------------------------------------
+void KMultiFormListBoxEntry::acceptIndexButton()
+{
+ emit gotoIndex(this);
+}
+
+
+void KMultiFormListBoxEntry::indexWindowPos(QPoint *start, int *width)
+{
+ // Calculate the position of the value widgets left-buttom border
+ QPoint global_point = valueWidget()->mapToGlobal(QPoint(0,0));
+ start->setX(global_point.x());
+ start->setY(global_point.y() + valueWidget()->height());
+
+ // Calculate the width of the list.
+ global_point = indexButton()->mapToGlobal(QPoint(0,0));
+ *width = global_point.x() + indexButton()->width() - start->x();
+}
diff --git a/kregexpeditor/KMultiFormListBox/kmultiformlistboxentry.h b/kregexpeditor/KMultiFormListBox/kmultiformlistboxentry.h
new file mode 100644
index 0000000..7937fe1
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/kmultiformlistboxentry.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __kmultiformlistboxentry
+#define __kmultiformlistboxentry
+
+#include <qpoint.h>
+#include <qwidget.h>
+#include <qpushbutton.h>
+
+/**
+ This widget must be the base class for an entry widget used in the @ref
+ KMultiFormListBox class. It is necessary for you to inherit this class to get any
+ information attached to the elements in the KMultiFormListBox.
+
+ The KMultiFormListBox widget features a fast scrolling mechanism through the Idx
+ button. If you want to use this in you KMultiFormListBox, then you must do the
+ following:
+ @li Create a @ref QPushButton as a sub-widget to your KMultiFormListBoxEntry.
+ @li Override the @ref indexButton method to return your QPushButton
+ @li Override the @ref idxString to return a @ref QString
+ with a textual representation of the content in this KMultiFormListBoxEntry. This
+ string will be used in the drop-down box which the user gets when he
+ presses the Idx button.
+ @li The drop down window must be aligned horizontal to some widget
+ (which should be next to the Idx button, to ensure a good looking GUI. The
+ position of the drop down widget may be specified in two ways: (1)
+ override the @ref valueWidget method to return a widget, to align with
+ (that is the upper right corner of the drop down window will be the
+ same as the lower right corner of this widget) or (2) override the @ref
+ indexWindowPos method to return a start point for the drop down window and
+ a width.
+ **/
+class KMultiFormListBoxEntry : public QWidget
+{
+ Q_OBJECT
+
+public:
+ KMultiFormListBoxEntry(QWidget *parent, const char *name) : QWidget(parent,name) {}
+
+ virtual QPushButton *indexButton() { return 0; }
+ virtual QWidget *valueWidget() { return 0; }
+
+ virtual void indexWindowPos(QPoint *start, int *width); // both variables are return values.
+
+ // This function must return a string representing the KMultiFormListBox. This is
+ // used when showing the fast-search menu available from the `Idx' button.
+ virtual QString idxString() { return QString::fromLatin1(""); }
+
+public slots:
+ void acceptIndexButton();
+
+signals:
+ void gotoIndex(KMultiFormListBoxEntry *);
+
+};
+
+#endif /* kmultiformlistboxentry */
+
diff --git a/kregexpeditor/KMultiFormListBox/kmultiformlistboxfactory.cpp b/kregexpeditor/KMultiFormListBox/kmultiformlistboxfactory.cpp
new file mode 100644
index 0000000..89b5d74
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/kmultiformlistboxfactory.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "kmultiformlistboxfactory.h"
+#include <qframe.h>
+
+QWidget *KMultiFormListBoxFactory::separator(QWidget *parent) {
+ QFrame* sep = new QFrame( parent );
+ sep->setFrameStyle( QFrame::HLine | QFrame::Sunken);
+ sep->setLineWidth(1);
+ return sep;
+}
diff --git a/kregexpeditor/KMultiFormListBox/kmultiformlistboxfactory.h b/kregexpeditor/KMultiFormListBox/kmultiformlistboxfactory.h
new file mode 100644
index 0000000..13f6561
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/kmultiformlistboxfactory.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+// -------------------------------- includes ------------------------------
+#ifndef __kmultiformlistboxfactory
+#define __kmultiformlistboxfactory
+#include <qobject.h>
+#include "kwidgetstreamer.h"
+class KMultiFormListBoxEntry;
+//-------------------------------------------------------------------------
+
+
+/**
+ Factory use to generate elements for the @ref KMultiFormListBox widget.
+
+ To use an @ref KMultiFormListBox, one must inherit from the class KMultiFormListBoxFactory
+ and override the method @ref create. This method must return an empty
+ element for the KMultiFormListBox (that is an @ref KMultiFormListBoxEntry or a subclass of
+ it).
+
+ If you dislike the default separator between each of the elements or
+ simply do not want a separator in the KMultiFormListBox, then you may override
+ the method @ref separator.
+**/
+class KMultiFormListBoxFactory : public KWidgetStreamer
+{
+public:
+ virtual ~KMultiFormListBoxFactory() {}
+
+ /**
+ This method must be overridden in subclasses and must return an
+ ``empty'' instance of the @ref KMultiFormListBoxEntry class, or perhaps rather
+ a subclass of this class. This instance will be owned by the caller of
+ this function.
+
+ @param parent A pointer to the parent of this KMultiFormListBoxEntry widget
+ returned.
+ @return A fresh @ref KMultiFormListBoxEntry to be used in an instance of the
+ @ref KMultiFormListBox class.
+ **/
+ virtual KMultiFormListBoxEntry *create(QWidget *parent) = 0;
+
+ /**
+ This method is used to get a separator between the elements in an @ref
+ KMultiFormListBox. The widget returned from this method will be owned by the
+ caller.
+
+ @param parent A pointer to the parent of the QWidget returned.
+ @return A widget which must be used as a separator between the @ref
+ KMultiFormListBoxEntry elements in an @ref KMultiFormListBox.
+ **/
+ virtual QWidget *separator(QWidget *parent);
+};
+
+#endif /* kmultiformlistbox */
+
diff --git a/kregexpeditor/KMultiFormListBox/widgetwindow.cpp b/kregexpeditor/KMultiFormListBox/widgetwindow.cpp
new file mode 100644
index 0000000..022e452
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/widgetwindow.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "widgetwindow.h"
+#include "windowlistboxitem.h"
+#include <iostream>
+
+WidgetWindow::WidgetWindow(KMultiFormListBoxFactory *factory, KListBox *lb)
+ :KDialogBase(Plain, i18n("Widget Configuration"), Ok | Cancel, Ok, 0, "ConfigWindow", false)
+{
+ init(factory, lb);
+}
+
+WidgetWindow::WidgetWindow(KMultiFormListBoxFactory *factory, KMultiFormListBoxEntry *widget, KListBox *lb)
+ :KDialogBase(Plain, i18n("Widget Configuration"), Ok | Cancel, Ok, 0, "ConfigWindow", false)
+{
+ init(factory, lb, widget);
+}
+
+void WidgetWindow::init(KMultiFormListBoxFactory *factory, KListBox *lb, KMultiFormListBoxEntry *widget)
+{
+ listbox = lb;
+ myFact = factory;
+
+ QFrame *frame = plainPage();
+ QHBoxLayout *lay = new QHBoxLayout(frame,0,-1,"WidgetWindow::init::lay");
+
+ if (widget != 0) {
+ myWidget = widget;
+ widget->reparent(frame, 0, QPoint(0,0));
+ }
+ else {
+ myWidget = factory->create(frame);
+ }
+ QDataStream stream( _backup, IO_WriteOnly );
+ myFact->toStream( myWidget, stream );
+
+ lay->addWidget(myWidget);
+
+ if (widget != 0) {
+ initialShow = false;
+ myListboxItem = new WindowListboxItem(listbox,myWidget->idxString(), this);
+ }
+ else {
+ initialShow = true;
+ }
+}
+
+
+
+WidgetWindow::~WidgetWindow()
+{
+ delete myWidget;
+}
+
+void WidgetWindow::slotOk()
+{
+ if (initialShow) {
+ myListboxItem = new WindowListboxItem(listbox,myWidget->idxString(), this);
+ }
+ else {
+ myListboxItem->setText(myWidget->idxString());
+ }
+ initialShow = false;
+ KDialogBase::slotOk();
+}
+
+void WidgetWindow::slotCancel()
+{
+ if (initialShow) {
+ deleteLater();
+ }
+ else {
+ QDataStream stream( _backup, IO_ReadOnly );
+ myFact->fromStream( stream, myWidget );
+ }
+ KDialogBase::slotCancel();
+}
+
+WidgetWindow *WidgetWindow::clone()
+{
+ WidgetWindow *item = new WidgetWindow(myFact, listbox);
+ QByteArray data;
+ QDataStream ws( data, IO_WriteOnly );
+ myFact->toStream( myWidget, ws );
+ QDataStream rs( data, IO_ReadOnly );
+ myFact->fromStream( rs, item->myWidget );
+
+ item->slotOk();
+ return item;
+}
+
+void WidgetWindow::display()
+{
+ QDataStream stream( _backup, IO_WriteOnly);
+ myFact->toStream( myWidget, stream );
+ show();
+}
+
+KMultiFormListBoxEntry *WidgetWindow::entry()
+{
+ return myWidget;
+}
diff --git a/kregexpeditor/KMultiFormListBox/widgetwindow.h b/kregexpeditor/KMultiFormListBox/widgetwindow.h
new file mode 100644
index 0000000..f81b359
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/widgetwindow.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __configwindow
+#define __configwindow
+
+#ifdef QT_ONLY
+ #include "compat.h"
+ #include <qlistbox.h>
+#else
+ #include <kdialogbase.h>
+ #include <klistbox.h>
+#endif
+
+#include "kmultiformlistbox-windowed.h"
+
+/**
+ @internal
+*/
+class WidgetWindow :public KDialogBase
+{
+ friend class KMultiFormListBoxWindowed;
+ friend class WindowListboxItem;
+
+ WidgetWindow(KMultiFormListBoxFactory *, KListBox *);
+ WidgetWindow(KMultiFormListBoxFactory *, KMultiFormListBoxEntry *widget, KListBox *);
+ void init(KMultiFormListBoxFactory *, KListBox *, KMultiFormListBoxEntry *widget = 0);
+ void display();
+ KMultiFormListBoxEntry *entry();
+ WidgetWindow *clone();
+ ~WidgetWindow();
+
+protected slots:
+ void slotOk();
+ void slotCancel();
+
+private:
+ KMultiFormListBoxFactory *myFact;
+ KMultiFormListBoxEntry *myWidget;
+ QByteArray _backup;
+ KListBox *listbox;
+ WindowListboxItem *myListboxItem;
+ bool initialShow;
+};
+
+#endif // configwindow
diff --git a/kregexpeditor/KMultiFormListBox/windowlistboxitem.cpp b/kregexpeditor/KMultiFormListBox/windowlistboxitem.cpp
new file mode 100644
index 0000000..41f9e5b
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/windowlistboxitem.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "windowlistboxitem.h"
+#include "widgetwindow.h"
+
+WindowListboxItem::WindowListboxItem(QListBox *lb, QString text, WidgetWindow *windowWidget)
+ :QListBoxText(lb, text), myItem(windowWidget)
+{
+}
+
+WindowListboxItem::~WindowListboxItem()
+{
+ delete myItem;
+}
+
+void WindowListboxItem::displayWidget()
+{
+ myItem->display();
+}
+
+void WindowListboxItem::clone()
+{
+ myItem->clone();
+}
+
+KMultiFormListBoxEntry *WindowListboxItem::entry()
+{
+ return myItem->entry();
+}
+
diff --git a/kregexpeditor/KMultiFormListBox/windowlistboxitem.h b/kregexpeditor/KMultiFormListBox/windowlistboxitem.h
new file mode 100644
index 0000000..2505b88
--- /dev/null
+++ b/kregexpeditor/KMultiFormListBox/windowlistboxitem.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __windowlistboxitem
+#define __windowlistboxitem
+#include <qlistbox.h>
+class WidgetWindow;
+class KMultiFormListBoxWindowed;
+class KMultiFormListBoxEntry;
+
+
+/**
+ @internal
+*/
+class WindowListboxItem :public QListBoxText
+{
+ friend class WidgetWindow;
+ friend class KMultiFormListBoxWindowed;
+public:
+ WindowListboxItem(QListBox *, QString, WidgetWindow *);
+ ~WindowListboxItem();
+ void clone();
+ void displayWidget();
+ KMultiFormListBoxEntry *entry();
+
+private:
+ WidgetWindow *myItem;
+};
+
+#endif // __windowlistboxitem
diff --git a/kregexpeditor/KWidgetStreamer/Makefile.am b/kregexpeditor/KWidgetStreamer/Makefile.am
new file mode 100644
index 0000000..c9b1260
--- /dev/null
+++ b/kregexpeditor/KWidgetStreamer/Makefile.am
@@ -0,0 +1,9 @@
+AM_CPPFLAGS = -DQT_NO_CAST_ASCII
+noinst_LTLIBRARIES = libkwidgetstreamer.la
+
+INCLUDES= -I$(srcdir)/../KMultiFormListBox $(all_includes)
+
+include_HEADERS = kwidgetstreamer.h
+libkwidgetstreamer_la_SOURCES = kwidgetstreamer.cpp
+
+METASOURCES = AUTO
diff --git a/kregexpeditor/KWidgetStreamer/kwidgetstreamer.cpp b/kregexpeditor/KWidgetStreamer/kwidgetstreamer.cpp
new file mode 100644
index 0000000..e91813a
--- /dev/null
+++ b/kregexpeditor/KWidgetStreamer/kwidgetstreamer.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "kwidgetstreamer.h"
+#include "kmultiformlistbox.h"
+#include <qobjectlist.h>
+#include <qvariant.h>
+
+
+void KWidgetStreamer::toStream(const QObject* from, QDataStream& stream )
+{
+ if ( from->inherits("KMultiFormListBox") ) {
+ // Hmm, we'll trust Qt that this dynamic_cast won't fail!
+ dynamic_cast<const KMultiFormListBox*>(from)->toStream( stream );
+ }
+
+ propertyToStream( from, stream );
+}
+
+void KWidgetStreamer::fromStream( QDataStream& stream, QObject* to )
+{
+ if ( to->inherits("KMultiFormListBox") ) {
+ // Hmm, we'll trust Qt that this dynamic_cast won't fail!
+ dynamic_cast<KMultiFormListBox*>(to)->fromStream( stream );
+ }
+
+ propertyFromStream( stream, to );
+}
+
+
+void KWidgetStreamer::propertyToStream( const QObject* from, QDataStream& stream )
+{
+ // Only handle widgets. Alternatives to widgets are layouts, validators, timers, etc.
+ if ( ! from->inherits("QWidget") )
+ return;
+
+ // Serializing all the children (if any).
+ const QObjectList* children = from->children();
+ if ( children ) {
+ stream << children->count();
+ for ( QObjectListIt it = QObjectListIt(*children); *it; ++it ) {
+ toStream( *it, stream );
+ }
+ }
+ else {
+ stream << (unsigned int) 0;
+ }
+
+ // Now stream out properties
+ for ( PropertyMapIt mapIt = _map.begin(); mapIt != _map.end(); mapIt++ ) {
+ QString tp = mapIt.key();
+ PropertyList list = mapIt.data();
+ if ( from->inherits( tp.latin1() ) ) {
+ for ( PropertyListIt it = list.begin(); it != list.end(); ++it ) {
+ QVariant prop = from->property( (*it).latin1() );
+ if ( ! prop.isValid() )
+ qWarning("Invalid property: %s:%s", tp.latin1(), (*it).latin1() );
+
+ stream << prop ;
+ }
+ }
+ }
+}
+
+
+void KWidgetStreamer::propertyFromStream( QDataStream& stream, QObject* to )
+{
+ // Only handle widgets. Alternatives to widgets are layouts, validators, timers, etc.
+ if ( ! to->inherits("QWidget") )
+ return;
+
+ // Stream in all the children (if any)
+ const QObjectList* children = to->children();
+ unsigned int count;
+
+ stream >> count;
+ if ( children ) {
+ Q_ASSERT( count == children->count() );
+ for ( QObjectListIt it = QObjectListIt(*children); *it; ++it )
+ fromStream( stream, *it );
+ }
+ else {
+ Q_ASSERT( count == 0 );
+ }
+
+ // Now stream in properties
+ for ( PropertyMapIt mapIt = _map.begin(); mapIt != _map.end(); mapIt++ ) {
+ QString tp = mapIt.key();
+ PropertyList list = mapIt.data();
+ if ( to->inherits( tp.latin1() ) ) {
+ for ( PropertyListIt it = list.begin(); it != list.end(); ++it ) {
+ QVariant value;
+ stream >> value;
+ to->setProperty((*it).latin1(), value);
+ }
+ }
+ }
+}
+
+KWidgetStreamer::KWidgetStreamer ()
+{
+ QStringList l;
+
+ // QCheckBox
+ l.clear();
+ l << QString::fromLatin1("enabled")
+ << QString::fromLatin1("checked") << QString::fromLatin1("tristate");
+ _map.insert(QString::fromLatin1("QCheckBox"), l);
+
+ // QComboBox
+ l.clear();
+ l << QString::fromLatin1("enabled")
+ << QString::fromLatin1("editable") << QString::fromLatin1("currentItem")
+ << QString::fromLatin1("maxCount") << QString::fromLatin1("insertionPolicy")
+ << QString::fromLatin1("autoCompletion");
+ _map.insert(QString::fromLatin1("QComboBox"), l);
+
+ // QDial
+ l.clear();
+ l << QString::fromLatin1("enabled")
+ << QString::fromLatin1("tracking") << QString::fromLatin1("wrapping")
+ << QString::fromLatin1("value");
+ _map.insert(QString::fromLatin1("QDial"), l);
+
+ // QLCDNumber
+ l.clear();
+ l << QString::fromLatin1("enabled")
+ << QString::fromLatin1("numDigits") << QString::fromLatin1("mode")
+ << QString::fromLatin1("segmentStyle") << QString::fromLatin1("value");
+ _map.insert(QString::fromLatin1("QLCDNumber"), l);
+
+ // QLineEdit
+ l.clear();
+ l << QString::fromLatin1("enabled")
+ << QString::fromLatin1("text") << QString::fromLatin1("maxLength")
+ << QString::fromLatin1("echoMode") << QString::fromLatin1("alignment");
+ _map.insert(QString::fromLatin1("QLineEdit"), l);
+
+ // QMultiLineEdit
+ l.clear();
+ l << QString::fromLatin1("enabled")
+ << QString::fromLatin1("text")
+ << QString::fromLatin1("alignment");
+ _map.insert(QString::fromLatin1("QTextEdit"), l);
+
+ // QRadioButton
+ l.clear();
+ l << QString::fromLatin1("enabled")
+ << QString::fromLatin1("checked");
+ _map.insert(QString::fromLatin1("QRadioButton"), l);
+
+ // QSlider
+ l.clear();
+ l << QString::fromLatin1("enabled")
+ << QString::fromLatin1("value");
+ _map.insert(QString::fromLatin1("QSlider"), l);
+
+ // QSpinBox
+ l.clear();
+ l << QString::fromLatin1("enabled")
+ << QString::fromLatin1("value");
+ _map.insert(QString::fromLatin1("QSpinBox"), l);
+}
diff --git a/kregexpeditor/KWidgetStreamer/kwidgetstreamer.h b/kregexpeditor/KWidgetStreamer/kwidgetstreamer.h
new file mode 100644
index 0000000..9534a92
--- /dev/null
+++ b/kregexpeditor/KWidgetStreamer/kwidgetstreamer.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __kwidgetstreamer
+#define __kwidgetstreamer
+#include <qmap.h>
+#include <qptrlist.h>
+#include <qstringlist.h>
+#include <qobject.h>
+
+/**
+ This class defines methods for streaming widget data.
+
+ For each widget type rules are defined telling which attributes should be
+ streamed. If you need to stream other attributes or to avoid streaming
+ certain attributes, then this may be obtained by editing the property
+ map, which is obtained by calling @ref propertyMap. For further control
+ inherit from this class and override @ref toStream and @ref fromStream.
+
+ The following example shows how you can avoid streaming
+ <tt>numDigits</tt> for a QLCDNumber. The same approach applies if you
+ want to add extra properties to be streamed.
+ <pre>
+ KWidgetStreamer streamer;
+ KWidgetStreamer::PropertyMap& map = streamer.propertyMap();
+ KWidgetStreamer::PropertyList& list = *map.find("QLCDNumber");
+ list.remove("numDigits");
+ </pre>
+**/
+class KWidgetStreamer
+{
+
+public:
+ typedef QStringList PropertyList;
+ typedef QMap< QString, PropertyList > PropertyMap;
+ typedef QMap< QString, PropertyList >::ConstIterator PropertyMapIt;
+ typedef QStringList::Iterator PropertyListIt;
+
+ KWidgetStreamer();
+ virtual ~KWidgetStreamer() {}
+
+ virtual void toStream(const QObject* from, QDataStream& stream );
+ virtual void fromStream(QDataStream& stream, QObject* to);
+
+ PropertyMap& propertyMap() { return _map; }
+
+
+protected:
+ void propertyToStream( const QObject* from, QDataStream& stream );
+ void propertyFromStream( QDataStream& stream, QObject* to );
+
+private:
+ PropertyMap _map;
+
+};
+
+
+
+#endif /* __kwidgetstreamer */
+
diff --git a/kregexpeditor/Makefile.am b/kregexpeditor/Makefile.am
new file mode 100644
index 0000000..6f8a4e4
--- /dev/null
+++ b/kregexpeditor/Makefile.am
@@ -0,0 +1,65 @@
+SUBDIRS = KWidgetStreamer KMultiFormListBox picts predefined
+
+KDE_ICON=AUTO
+
+AM_CPPFLAGS = -DQT_NO_CAST_ASCII -I$(srcdir)/KWidgetStreamer -I$(srcdir)/KMultiFormListBox $(all_includes)
+
+# (useless)
+noinst_HEADERS = \
+ kregexpeditorgui.h editorwindow.h regexpwidget.h drag.h limitedcharlineedit.h regexp.h selectablelineedit.h \
+ dragaccepter.h repeatwidget.h concwidget.h textwidget.h characterswidget.h zerowidgets.h multicontainerwidget.h \
+ scrollededitorwindow.h compoundwidget.h singlecontainerwidget.h widgetfactory.h dcbutton.h charselector.h \
+ lookaheadwidget.h textregexp.h textrangeregexp.h repeatregexp.h lookaheadregexp.h concregexp.h altnregexp.h \
+ positionregexp.h dotregexp.h infopage.h kregexpeditorprivate.h compoundregexp.h pair.h triple.h myfontmetrics.h \
+ regexpbuttons.h userdefinedregexps.h auxbuttons.h verifier.h verifybuttons.h errormap.h qtregexphighlighter.h \
+ regexpconverter.h qtregexpconverter.h emacsregexpconverter.h regexphighlighter.h util.h
+
+# The library contains all the code that is shared between the module and the app
+lib_LTLIBRARIES = libkregexpeditorcommon.la
+libkregexpeditorcommon_la_SOURCES = \
+ kregexpeditorgui.cpp editorwindow.cpp regexpwidget.cpp drag.cpp concwidget.cpp zerowidgets.cpp dragaccepter.cpp \
+ repeatwidget.cpp characterswidget.cpp altnwidget.cpp limitedcharlineedit.cpp textregexp.cpp textrangeregexp.cpp \
+ concregexp.cpp altnregexp.cpp positionregexp.cpp dotregexp.cpp repeatregexp.cpp textwidget.cpp \
+ selectablelineedit.cpp multicontainerwidget.cpp scrollededitorwindow.cpp compoundwidget.cpp \
+ singlecontainerwidget.cpp widgetfactory.cpp dcbutton.cpp gen_qregexplexer.cpp gen_qregexpparser.cc \
+ charselector.cpp lookaheadregexp.cpp lookaheadwidget.cpp regexp.cpp infopage.cpp kregexpeditorprivate.cpp \
+ compoundregexp.cpp auxbuttons.cpp myfontmetrics.cpp regexpbuttons.cpp userdefinedregexps.cpp verifier.cpp \
+ verifybuttons.cpp errormap.cpp qtregexphighlighter.cpp regexpconverter.cpp qtregexpconverter.cpp \
+ emacsregexpconverter.cpp regexphighlighter.cpp util.cpp
+
+libkregexpeditorcommon_la_LDFLAGS = $(all_libraries) -version-info 1:0:0 -no-undefined
+libkregexpeditorcommon_la_LIBADD = KMultiFormListBox/libkmultiformlistbox.la \
+ KWidgetStreamer/libkwidgetstreamer.la $(LIB_KIO)
+
+METASOURCES = AUTO
+
+service_DATA = kregexpeditorgui.desktop
+servicedir = $(kde_servicesdir)
+
+#### The dynamically-loadable module (its interface is defined in kdelibs)
+kde_module_LTLIBRARIES = libkregexpeditorgui.la
+libkregexpeditorgui_la_SOURCES = kregexpeditorfactory.cpp
+libkregexpeditorgui_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module
+libkregexpeditorgui_la_LIBADD = libkregexpeditorcommon.la
+
+#### Binary
+
+bin_PROGRAMS = kregexpeditor
+kregexpeditor_SOURCES = main.cpp
+kregexpeditor_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+kregexpeditor_LDADD = libkregexpeditorcommon.la $(LIB_KIO)
+kregexpeditor_INCLUDES = $(all_includes)
+
+xdg_apps_DATA = kregexpeditor.desktop
+
+
+##### Build rules for the parser
+
+.PHONY: parser
+parser:
+ cd $(srcdir) && flex -Pqregexp -ogen_qregexplexer.cpp qregexpparser.l
+ cd $(srcdir) && bison -d -p qregexp -o gen_qregexpparser.cc qregexpparser.y
+
+messages:
+ perl extractrc-from-regexp `find . -name "*.regexp"` > predefined-regexps.cpp
+ $(XGETTEXT) *.cpp *.h */*.cpp */*.h -o $(podir)/kregexpeditor.pot
diff --git a/kregexpeditor/TODO b/kregexpeditor/TODO
new file mode 100644
index 0000000..d8c492b
--- /dev/null
+++ b/kregexpeditor/TODO
@@ -0,0 +1,49 @@
+TODO:
+-----
+
+When the user drops something on the regular expression area that is of
+mime type text/plain, then ask the user whether he want it parsed as a
+regular expression or whether he wants it inserted as plain text (that is the text escaped)
+
+Later wishes:
+-------------
+- Make the KMultiFormListBox widget support that a line can show several entries.
+ Use this feature to show two CharSelectors on one line for selecting a single char
+ in the CharacterWidget.
+- Cleanup in the use of repaint(). Several of the repaint() can be update() instead.
+- add a checker widget, which can show what the regexp matches from a user defined text.
+- add the posibility to travers the widget using the keyboard.
+- Highlight the dragaccepter on dragEnter
+
+Back references
+---------------
+- when deleting a compound widget, which has a backreference, what should be done with the
+ back reference?
+- cut/past should preserve back reference id, while cut/copy should create
+ a new one.
+- create interface for extracting information about back references.
+
+- support back references in the regexp: "(abc|def)\1"
+
+Modules to go through to search for places to use KRegExpEditor
+---------------------------------------------------------------
+KodeKnight
+kdeadmin
+kdebase
+kdeedu
+kdegames
+kdegraphics
+kdeinstaller
+kdelibs
+kdemultimedia
+kdenetwork
+kdenonbeta
+kdepim
+kdesdk
+kdetoys
+kfte
+kmusic
+koffice
+kpfa
+ksite
+quanta
diff --git a/kregexpeditor/altnregexp.cpp b/kregexpeditor/altnregexp.cpp
new file mode 100644
index 0000000..adebf1b
--- /dev/null
+++ b/kregexpeditor/altnregexp.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "altnregexp.h"
+#include "widgetfactory.h"
+
+AltnRegExp::AltnRegExp( bool selected ) :RegExp( selected )
+{
+ // Nothing to do
+}
+
+void AltnRegExp::addRegExp( RegExp *elm )
+{
+ list.append( elm );
+ addChild( elm );
+}
+
+RegExpList AltnRegExp::children() const
+{
+ return list;
+}
+
+bool AltnRegExp::check( ErrorMap& map, bool first, bool last )
+{
+ bool possibleEmpty = false;
+ for ( RegExpListIt it(list); *it; ++it ) {
+ possibleEmpty = (*it)->check( map, first, last ) || possibleEmpty;
+ }
+ return possibleEmpty;
+}
+
+QDomNode AltnRegExp::toXml( QDomDocument* doc ) const
+{
+ QDomElement top = doc->createElement( QString::fromLocal8Bit( "Alternatives" ) );
+ for ( RegExpListIt it(list); *it; ++it ) {
+ top.appendChild( (*it)->toXml( doc ) );
+ }
+ return top;
+}
+
+bool AltnRegExp::load( QDomElement top, const QString& version )
+{
+ Q_ASSERT( top.tagName() == QString::fromLocal8Bit( "Alternatives" ) );
+
+ for ( QDomNode child = top.firstChild(); !child.isNull(); child = child.nextSibling() ) {
+ if ( ! child.isElement() )
+ continue; // User might have added a comment.
+
+ RegExp* regexp = WidgetFactory::createRegExp( child.toElement(), version );
+ if ( regexp == 0 )
+ return false;
+ addRegExp( regexp );
+ }
+ return true;
+
+}
+
+bool AltnRegExp::operator==( const RegExp& other ) const
+{
+ // TODO: merge with ConcRegExp::operator==
+
+ if ( other.type() != type() )
+ return false;
+
+ const AltnRegExp& theOther = dynamic_cast<const AltnRegExp&>( other );
+
+ if ( list.count() != theOther.list.count() )
+ return false;
+
+ RegExpListIt it1( list );
+ RegExpListIt it2( theOther.list );
+
+ for ( ; *it1 && *it2 ; ) {
+ if ( ! (**it1 == **it2) )
+ return false;
+ ++it1;
+ ++it2;
+ }
+ return true;
+}
+
+void AltnRegExp::replacePart( CompoundRegExp* replacement )
+{
+ for ( RegExpListIt it( list ); *it; ++it ) {
+ (*it)->replacePart( replacement );
+ }
+}
+
diff --git a/kregexpeditor/altnregexp.h b/kregexpeditor/altnregexp.h
new file mode 100644
index 0000000..d5d9d1e
--- /dev/null
+++ b/kregexpeditor/altnregexp.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef ALTNREGEXP_H
+#define ALTNREGEXP_H
+
+#include "regexp.h"
+
+/**
+ Abstract syntax node for `alternative' regular expression
+ @internal
+*/
+class AltnRegExp :public RegExp
+{
+public:
+ AltnRegExp( bool selected );
+
+ void addRegExp( RegExp * );
+ RegExpList children() const;
+
+ virtual bool check( ErrorMap&, bool first, bool last );
+ virtual int precedence() const { return 1;}
+ virtual QDomNode toXml( QDomDocument* doc ) const;
+ virtual bool load( QDomElement, const QString& version );
+ virtual RegExpType type() const { return ALTN;}
+ virtual bool operator==( const RegExp& other ) const;
+ virtual void replacePart( CompoundRegExp* replacement );
+
+private:
+ RegExpList list;
+};
+
+#endif // ALTNREGEXP_H
diff --git a/kregexpeditor/altnwidget.cpp b/kregexpeditor/altnwidget.cpp
new file mode 100644
index 0000000..22937ac
--- /dev/null
+++ b/kregexpeditor/altnwidget.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <klocale.h>
+ #include <kmessagebox.h>
+#endif
+
+#include "altnwidget.h"
+#include "dragaccepter.h"
+#include "concwidget.h"
+#include "altnregexp.h"
+#include <qpainter.h>
+
+AltnWidget::AltnWidget(RegExpEditorWindow* editorWindow, QWidget *parent,
+ const char *name)
+ :MultiContainerWidget(editorWindow, parent, name == 0 ? "AltnWidget" : name)
+{
+ DragAccepter *accepter = new DragAccepter(editorWindow, this);
+ accepter->resize(0,0); // See note (1) in Comments
+ _children.append(accepter);
+ _text = i18n("Alternatives");
+}
+
+AltnWidget::AltnWidget( AltnRegExp* regexp, RegExpEditorWindow* editorWindow,
+ QWidget* parent, const char* name)
+ :MultiContainerWidget( editorWindow, parent, name )
+{
+ DragAccepter *accepter = new DragAccepter(editorWindow, this);
+ accepter->resize(0,0); // See note (1) in Comments
+ _children.append(accepter);
+ _text = i18n("Alternatives");
+
+ RegExpList list = regexp->children();
+ for ( RegExpListIt it(list); *it; ++it ) {
+ RegExpWidget* child = WidgetFactory::createWidget( *it, editorWindow, this );
+ ConcWidget* conc;
+ if ( ! (conc = dynamic_cast<ConcWidget*>( child ) ) ) {
+ conc = new ConcWidget( editorWindow, child, parent );
+ }
+ append( conc );
+ }
+ updateDrawLineInfo();
+}
+
+
+void AltnWidget::addNewChild(DragAccepter *accepter, RegExpWidget *child)
+{
+ ConcWidget *conc = new ConcWidget(_editorWindow, child,this);
+ MultiContainerWidget::addNewChild( accepter, conc );
+ updateDrawLineInfo();
+ repaint();
+}
+
+void AltnWidget::setConcChild(ConcWidget *child)
+{
+ addNewConcChild( dynamic_cast<DragAccepter*>(_children.at(0)), child );
+}
+
+void AltnWidget::addNewConcChild(DragAccepter *accepter, ConcWidget *child)
+{
+ child->reparent(this, QPoint(0,0), false);
+ MultiContainerWidget::addNewChild( accepter, child );
+ updateDrawLineInfo();
+}
+
+
+QSize AltnWidget::sizeHint() const
+{
+ QPtrListIterator<RegExpWidget> it(_children);
+ // Skip the first child, as we only need half of the size of the first and the
+ // last drag accepter. Does, however, not apply when there only is onw child.
+ if ( _children.count() != 1 )
+ ++it;
+
+ _childrenWidth = 0;
+ _childrenHeight = 0;
+
+ for ( ; *it ; ++it) {
+ QSize thisChildSize = (*it)->sizeHint();
+ _childrenWidth = QMAX(_childrenWidth, thisChildSize.width());
+ _childrenHeight += thisChildSize.height();
+ }
+
+ // Now add the size of the header
+ QFontMetrics metrics = fontMetrics();
+ _textSize = metrics.size(0,_text);
+
+ int headerWidth = _textSize.width() + 2 * bdSize + 2;
+
+ _childrenWidth = QMAX(_childrenWidth, headerWidth);
+
+ return QSize(_childrenWidth + 2*pw, _childrenHeight + _textSize.height() + 1*pw );
+}
+
+void AltnWidget::paintEvent( QPaintEvent *e)
+{
+ Q_ASSERT( dynamic_cast<DragAccepter*>(_children.at(0)) );
+ // if this fails, then I should check the location of the show()
+ Q_ASSERT( _children.count() == 1 ||
+ ( _children.count() >=3 &&
+ dynamic_cast<DragAccepter*>(_children.at(_children.count()-1)) ) );
+
+ int offset = 0;
+ QSize mySize = sizeHint();
+
+ QPainter painter(this);
+ drawPossibleSelection( painter, mySize );
+
+ //-------------------------------------- First draw the border and text
+ int startY = _textSize.height()/2;
+
+ painter.drawLine(0, startY, bdSize, startY);
+ int xOffset = bdSize +1;
+
+ painter.drawText(xOffset,0,_textSize.width(), _textSize.height(),0,_text);
+ xOffset += _textSize.width() +1;
+ painter.drawLine(xOffset,startY,mySize.width(), startY);
+ painter.drawLine(0,startY,0,mySize.height());
+ painter.drawLine(mySize.width()-pw, startY, mySize.width()-pw, mySize.height());
+ painter.drawLine(0,mySize.height()-pw, mySize.width()-pw, mySize.height()-pw);
+
+ //---- Run through all the children and place them at the correct location.
+ offset = _textSize.height();
+ xOffset = pw;
+
+ for (unsigned int i = 0; i < _children.count(); i++ ) {
+
+ RegExpWidget* child = _children.at(i);
+
+ QSize childSize = child->sizeHint();
+ QSize curChildSize = child->size();
+
+ //-------------------------------------- place the child
+ int x = xOffset;
+ int y = offset;
+ int h = childSize.height();
+ if ( ( _children.count() != 1 ) && ( i == 0 || i == _children.count() -1 ) ) {
+ // first and last DragAccepter should only be half size.
+ h /= 2;
+ }
+
+ int w = _childrenWidth;
+ child->setGeometry( x, y, w, h );
+ if ( w != curChildSize.width() || h != curChildSize.height() ) {
+ // I resized the child, so give it a chance to relect thus.
+ child->update();
+ }
+
+ offset += h;
+ }
+ MultiContainerWidget::paintEvent( e );
+}
+
+RegExp* AltnWidget::regExp() const
+{
+ AltnRegExp *regexp = new AltnRegExp( isSelected() );
+
+ QPtrListIterator<RegExpWidget> it(_children);
+ ++it; // start with the second element
+ for ( ; *it; it+=2 ) {
+ regexp->addRegExp( (*it)->regExp() );
+ }
+
+ return regexp;
+}
+
+void AltnWidget::applyRegExpToSelection( RegExpType type )
+{
+ for ( unsigned int i=1; i < _children.count(); i += 2 ) {
+ RegExpWidget* child = _children.at( i );
+ if ( child->hasSelection() ) {
+ child->applyRegExpToSelection( type );
+ }
+ }
+}
+
+
+RegExp* AltnWidget::selection() const
+{
+ if ( isSelected() )
+ return regExp();
+ else {
+ QPtrListIterator<RegExpWidget> it(_children);
+ ++it; // Skip past DragAccepter
+ for ( ; *it; it+=2 ) {
+ if ( (*it)->hasSelection() ) {
+ return (*it)->selection();
+ }
+ }
+ }
+ qFatal("Selection not found");
+ return 0; // compiler shut up.
+}
+
+bool AltnWidget::validateSelection() const
+{
+ if ( _isSelected ) {
+ return true;
+ }
+
+ bool foundASelection = false;
+ QPtrListIterator<RegExpWidget> it(_children);
+ ++it; // Skip past DragAccepter
+ for ( ; *it; it+=2 ) {
+ if ( (*it)->hasSelection() ) {
+ if ( foundASelection ) {
+ KMessageBox::information( const_cast<AltnWidget*>(this),
+ i18n( "Selecting several alternatives is "
+ "currently not supported." ),
+ i18n( "Selection Invalid" ) );
+ _editorWindow->clearSelection( true );
+ return false;
+ }
+ else {
+ foundASelection = true;
+ }
+ }
+ }
+ return true;
+}
+
+void AltnWidget::updateDrawLineInfo()
+{
+ for ( unsigned int i=0; i < _children.count(); i+=2 ) {
+ bool line = ( i != 0 && i!= _children.count()-1 );
+ DragAccepter *accepter = dynamic_cast<DragAccepter*>(_children.at(i));
+ if (accepter)
+ accepter->setDrawLine( line );
+ }
+}
+
+void AltnWidget::deleteSelection()
+{
+ MultiContainerWidget::deleteSelection();
+ updateDrawLineInfo();
+}
+
diff --git a/kregexpeditor/altnwidget.h b/kregexpeditor/altnwidget.h
new file mode 100644
index 0000000..9a4f26b
--- /dev/null
+++ b/kregexpeditor/altnwidget.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef altnwidget
+#define altnwidget
+
+#include "multicontainerwidget.h"
+class AltnRegExp;
+
+/**
+ RegExp widget for alternatives.
+
+ @internal
+*/
+class AltnWidget :public MultiContainerWidget
+{
+public:
+ AltnWidget( RegExpEditorWindow* editorWindow, QWidget *parent,
+ const char *label = 0);
+ AltnWidget( AltnRegExp* regexp, RegExpEditorWindow* editorWindow,
+ QWidget* parent, const char* name = 0);
+ virtual void addNewChild(DragAccepter *accepter, RegExpWidget *child);
+ virtual QSize sizeHint() const;
+ virtual RegExp* regExp() const;
+ virtual void applyRegExpToSelection( RegExpType type );
+ virtual RegExpType type() const { return ALTN; }
+ virtual RegExp* selection() const;
+ virtual bool validateSelection() const;
+ virtual void setConcChild(ConcWidget *child);
+ virtual void addNewConcChild(DragAccepter *accepter, ConcWidget *child);
+ virtual void deleteSelection();
+
+protected:
+ virtual void paintEvent( QPaintEvent* e );
+
+private:
+ /**
+ This functions runs through all the dragaccepters and calls @ref
+ DragAccepter::setDrawLine.
+ */
+ void updateDrawLineInfo();
+
+ QString _text;
+ mutable QSize _textSize;
+
+ mutable int _maxSelectedWidth;
+ mutable int _childrenWidth;
+ mutable int _childrenHeight;
+};
+
+#endif // altnwidget
diff --git a/kregexpeditor/auxbuttons.cpp b/kregexpeditor/auxbuttons.cpp
new file mode 100644
index 0000000..ea28953
--- /dev/null
+++ b/kregexpeditor/auxbuttons.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifdef QT_ONLY
+ #include "compat.h"
+ #include "images.h"
+#else
+ #include "auxbuttons.moc"
+ #include <kiconloader.h>
+ #include <klocale.h>
+#endif
+
+#include "auxbuttons.h"
+#include <qlayout.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+#include <qtoolbutton.h>
+#include "util.h"
+
+AuxButtons::AuxButtons( QWidget* parent, const char* name = 0)
+ :QDockWindow( QDockWindow::InDock, parent, name)
+{
+ QBoxLayout* layout = boxLayout();
+
+ _undo = new QToolButton( this );
+ _undo->setIconSet( Util::getSystemIconSet(QString::fromLatin1("undo") ) );
+ layout->addWidget( _undo );
+ connect( _undo, SIGNAL(clicked()), this, SIGNAL(undo()) );
+ QToolTip::add( _undo, i18n( "Undo" ) );
+
+ _redo = new QToolButton( this );
+ _redo->setIconSet( Util::getSystemIconSet(QString::fromLatin1("redo") ) );
+ layout->addWidget( _redo );
+ connect( _redo, SIGNAL(clicked()), this, SIGNAL(redo()) );
+ QToolTip::add( _redo, i18n( "Redo" ) );
+
+ _cut = new QToolButton( this );
+ _cut->setIconSet( Util::getSystemIconSet(QString::fromLatin1("editcut") ) );
+ layout->addWidget( _cut );
+ connect( _cut, SIGNAL(clicked()), this, SIGNAL(cut()) );
+ QToolTip::add( _cut, i18n( "Cut" ) );
+
+ _copy = new QToolButton( this );
+ _copy->setIconSet( Util::getSystemIconSet(QString::fromLatin1("editcopy") ) );
+ layout->addWidget( _copy );
+ connect( _copy, SIGNAL(clicked()), this, SIGNAL(copy()) );
+ QToolTip::add( _copy, i18n( "Copy" ) );
+
+ _paste = new QToolButton( this );
+ _paste->setIconSet( Util::getSystemIconSet(QString::fromLatin1("editpaste")) );
+ layout->addWidget( _paste );
+ connect( _paste, SIGNAL(clicked()), this, SIGNAL(paste()) );
+ QToolTip::add( _paste, i18n( "Paste" ) );
+
+ _save = new QToolButton( this );
+ _save->setIconSet( Util::getSystemIconSet(QString::fromLatin1("filesave")) );
+ layout->addWidget( _save );
+ connect( _save, SIGNAL(clicked()), this, SIGNAL(save()) );
+ QToolTip::add( _save, i18n( "Save" ) );
+
+
+ QToolButton* button = new QToolButton(this);
+ button->setPixmap( Util::getSystemIcon( QString::fromLatin1("contexthelp") ) );
+ layout->addWidget( button );
+ connect(button, SIGNAL(clicked()), this, SLOT(slotEnterWhatsThis()));
+
+ _undo->setEnabled( false );
+ _redo->setEnabled( false );
+
+}
+
+void AuxButtons::slotEnterWhatsThis()
+{
+ QWhatsThis::enterWhatsThisMode ();
+}
+
+void AuxButtons::slotCanUndo( bool b )
+{
+ _undo->setEnabled( b );
+}
+
+void AuxButtons::slotCanRedo( bool b )
+{
+ _redo->setEnabled( b );
+}
+
+void AuxButtons::slotCanCut( bool b )
+{
+ _cut->setEnabled( b );
+}
+
+void AuxButtons::slotCanCopy( bool b )
+{
+ _copy->setEnabled( b );
+}
+
+void AuxButtons::slotCanPaste( bool b )
+{
+ _paste->setEnabled( b );
+}
+
+void AuxButtons::slotCanSave( bool b )
+{
+ _save->setEnabled( b );
+}
+
diff --git a/kregexpeditor/auxbuttons.h b/kregexpeditor/auxbuttons.h
new file mode 100644
index 0000000..08c33ec
--- /dev/null
+++ b/kregexpeditor/auxbuttons.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef AUXBUTTONS_H
+#define AUXBUTTONS_H
+
+#include <qdockwindow.h>
+class QComboBox;
+class QLabel;
+class QToolButton;
+
+class AuxButtons :public QDockWindow
+{
+ Q_OBJECT
+
+public:
+ AuxButtons( QWidget* parent, const char* name );
+
+signals:
+ void undo();
+ void redo();
+ void cut();
+ void copy();
+ void paste();
+ void save();
+
+public slots:
+ void slotEnterWhatsThis();
+ void slotCanUndo( bool );
+ void slotCanRedo( bool );
+ void slotCanCut( bool );
+ void slotCanCopy( bool );
+ void slotCanPaste( bool );
+ void slotCanSave( bool );
+
+private:
+ QToolButton* _undo;
+ QToolButton* _redo;
+ QToolButton* _cut;
+ QToolButton* _copy;
+ QToolButton* _paste;
+ QToolButton* _save;
+};
+
+
+#endif // AUXBUTTONS_H
diff --git a/kregexpeditor/characterswidget.cpp b/kregexpeditor/characterswidget.cpp
new file mode 100644
index 0000000..b219ed6
--- /dev/null
+++ b/kregexpeditor/characterswidget.cpp
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <kdialogbase.h>
+ #include "characterswidget.moc"
+#endif
+
+#include "characterswidget.h"
+#include "textrangeregexp.h"
+#include "regexp.h"
+#include "charselector.h"
+#include "myfontmetrics.h"
+#include "regexpconverter.h"
+
+#include <qpainter.h>
+#include <qgrid.h>
+#include <iostream>
+#include <qhgroupbox.h>
+#include <qcursor.h>
+#include <qcheckbox.h>
+
+CharacterEdits* CharactersWidget::_configWindow = 0;
+
+CharactersWidget::CharactersWidget(RegExpEditorWindow* editorWindow, QWidget *parent,
+ const char *name)
+ : RegExpWidget(editorWindow, parent, name)
+{
+ _regexp = new TextRangeRegExp( false /* not used */);
+}
+
+CharactersWidget::CharactersWidget( TextRangeRegExp* regexp, RegExpEditorWindow* editorWindow,
+ QWidget* parent, const char* name )
+ : RegExpWidget( editorWindow, parent, name )
+{
+ _regexp = dynamic_cast<TextRangeRegExp*>( regexp->clone() );
+ Q_ASSERT( _regexp );
+}
+
+CharactersWidget::~CharactersWidget()
+{
+ delete _regexp;
+}
+
+
+QSize CharactersWidget::sizeHint() const
+{
+ QFontMetrics metrics = fontMetrics();
+ _textSize = HackCalculateFontSize(metrics, title());
+ // _textSize = metrics.size(0, title());
+
+ QSize headerSize = QSize(_textSize.width() + 4 * bdSize,
+ _textSize.height());
+
+ _contentSize = HackCalculateFontSize(metrics,text());
+ // _contentSize = metrics.size(0, text());
+
+ return QSize(QMAX(headerSize.width(), bdSize + _contentSize.width() + bdSize+ 2*pw),
+ headerSize.height() + bdSize + _contentSize.height() + bdSize + 2*pw);
+}
+
+void CharactersWidget::paintEvent(QPaintEvent *e)
+{
+ QSize mySize = sizeHint();
+
+ QPainter painter(this);
+ drawPossibleSelection( painter, mySize );
+
+ int center = _textSize.height()/2;
+ int offset = 0;
+
+ // draw the horizontal line and the label
+ painter.drawLine(pw,center, bdSize,center);
+ offset += pw + 2*bdSize;
+
+ painter.drawText(offset, 0, _textSize.width(), _textSize.height(), 0, title());
+ offset += _textSize.width() + bdSize;
+
+ painter.drawLine(offset, center, mySize.width(), center);
+
+ // Draw the rest of the lines
+ int y = mySize.width() - pw;
+ int x = mySize.height() -pw;
+ painter.drawLine(0,center,0,mySize.height());
+ painter.drawLine(y,center,y,mySize.height());
+ painter.drawLine(0,x,y,x);
+
+ // Draw the text
+ painter.drawText(bdSize, bdSize+_textSize.height(), _contentSize.width(),
+ _contentSize.height(), 0, text());
+
+ RegExpWidget::paintEvent(e);
+}
+
+RegExp* CharactersWidget::regExp() const
+{
+ RegExp* r = _regexp->clone();
+ r->setSelected( isSelected() );
+ return r;
+}
+
+QString CharactersWidget::text() const
+{
+ QString res = QString::fromLatin1("");
+
+ if (_regexp->wordChar())
+ res += i18n("- A word character\n");
+
+ if (_regexp->nonWordChar())
+ res += i18n("- A non-word character\n");
+
+ if (_regexp->digit())
+ res += i18n("- A digit character\n");
+
+ if (_regexp->nonDigit())
+ res += i18n("- A non-digit character\n");
+
+ if ( _regexp->space() )
+ res += i18n("- A space character\n");
+
+ if ( _regexp->nonSpace() )
+ res += i18n("- A non-space character\n");
+
+ // Single characters
+ QStringList chars = _regexp->chars();
+ if ( !chars.isEmpty() ) {
+ QString str = chars.join( QString::fromLocal8Bit(", ") );
+ res += QString::fromLocal8Bit("- ") + str + QString::fromLocal8Bit("\n");
+ }
+
+ // Ranges characters
+ QPtrList<StringPair> range = _regexp->range();
+ for ( QPtrListIterator<StringPair> it( range ); *it; ++it ) {
+ StringPair* elm = static_cast<StringPair*>(*it);
+ if (elm) {
+ QString fromText = elm->first();
+ QString toText = elm->second();
+
+ res += QString::fromLocal8Bit("- ") + i18n("from ") + fromText + i18n(" to ") + toText + QString::fromLocal8Bit("\n");
+ }
+ }
+ return res.left(res.length()-1);
+}
+
+
+QString CharactersWidget::title() const
+{
+ if (_regexp->negate())
+ return i18n("Any Character Except");
+ else
+ return i18n("One of Following Characters");
+}
+
+
+RegExpWidget* CharactersWidget::findWidgetToEdit( QPoint globalPos )
+{
+ if ( QRect(mapToGlobal(QPoint(0,0)), size()).contains( globalPos ) )
+ return this;
+ else
+ return 0;
+}
+
+int CharactersWidget::edit()
+{
+ if ( _configWindow == 0 ) {
+ QApplication::setOverrideCursor( WaitCursor );
+ // No parent here, as this window should continue to exists.
+ _configWindow = new CharacterEdits( 0, "CharactersWidget::_configWindow" );
+ QApplication::restoreOverrideCursor();
+ }
+
+ _configWindow->move(QCursor::pos() - QPoint(_configWindow->sizeHint().width()/2,
+ _configWindow->sizeHint().height()/2));
+ int ret = _configWindow->exec(_regexp );
+ if ( ret == QDialog::Accepted ) {
+ _editorWindow->updateContent( 0 );
+ update();
+ }
+ return ret;
+}
+
+void CharacterEdits::addCharacter( QString txt )
+{
+ KMultiFormListBoxEntryList list = _single->elements();
+ for ( QPtrListIterator<KMultiFormListBoxEntry> it(list); *it; ++it ) {
+ SingleEntry* entry = dynamic_cast<SingleEntry*>( *it );
+ if ( entry && entry->isEmpty() ) {
+ entry->setText( txt );
+ return;
+ }
+ }
+
+ SingleEntry* entry = new SingleEntry( _single );
+ entry->setText( txt );
+ _single->append( entry );
+}
+
+void CharacterEdits::addRange( QString from, QString to )
+{
+ KMultiFormListBoxEntryList list = _range->elements();
+ for ( QPtrListIterator<KMultiFormListBoxEntry> it(list); *it; ++it ) {
+ RangeEntry* entry = dynamic_cast<RangeEntry*>( *it );
+ if ( entry && entry->isEmpty() ) {
+ entry->setFrom( from );
+ entry->setTo( to );
+ return;
+ }
+ }
+
+ RangeEntry* entry = new RangeEntry( _range );
+ entry->setFrom( from );
+ entry->setTo( to );
+ _range->append( entry );
+}
+
+int CharacterEdits::exec( TextRangeRegExp* regexp )
+{
+ _regexp = regexp;
+ negate->setChecked( regexp->negate() );
+ digit->setChecked( regexp->digit() );
+ _nonDigit->setChecked( regexp->nonDigit() );
+ space->setChecked( regexp->space() );
+ _nonSpace->setChecked( regexp->nonSpace() );
+ wordChar->setChecked( regexp->wordChar() );
+ _nonWordChar->setChecked( regexp->nonWordChar() );
+
+ bool enabled = (RegExpConverter::current()->features() & RegExpConverter::CharacterRangeNonItems);
+ _nonWordChar->setEnabled( enabled );
+ _nonDigit->setEnabled( enabled );
+ _nonSpace->setEnabled( enabled );
+
+ // Characters
+
+ KMultiFormListBoxEntryList list1 = _single->elements();
+ for ( QPtrListIterator<KMultiFormListBoxEntry> it(list1); *it; ++it ) {
+ SingleEntry* entry = dynamic_cast<SingleEntry*>( *it );
+ if (entry)
+ entry->setText( QString::fromLocal8Bit("") );
+ }
+ QStringList list2 = regexp->chars();
+ for ( QStringList::Iterator it2( list2.begin() ); ! (*it2).isNull(); ++it2 ) {
+ addCharacter( *it2 );
+ }
+
+ // Ranges
+ KMultiFormListBoxEntryList list3 = _range->elements();
+ for ( QPtrListIterator<KMultiFormListBoxEntry> it3(list3); *it3; ++it3 ) {
+ RangeEntry* entry = dynamic_cast<RangeEntry*>( *it3 );
+ if (entry) {
+ entry->setFrom( QString::fromLocal8Bit("") );
+ entry->setTo( QString::fromLocal8Bit("") );
+ }
+ }
+
+ QPtrList<StringPair> ranges = regexp->range();
+ for ( QPtrListIterator<StringPair> it4(ranges); *it4; ++it4 ) {
+ QString from = (*it4)->first();
+ QString to = (*it4)->second();
+ addRange(from,to);
+ }
+
+ int res = KDialogBase::exec();
+ _regexp = 0;
+ return res;
+}
+
+
+CharacterEdits::CharacterEdits( QWidget *parent, const char *name)
+ : KDialogBase( parent, name == 0 ? "CharacterEdits" : name, true,
+ i18n("Specify Characters"),
+ KDialogBase::Ok | KDialogBase::Cancel)
+{
+ QWidget* top = new QWidget( this );
+ QVBoxLayout *topLayout = new QVBoxLayout(top, 6);
+ setMainWidget( top );
+
+ negate = new QCheckBox(i18n("Do not match the characters specified here"),
+ top);
+ topLayout->addWidget( negate );
+
+
+ // The predefined box
+ QHGroupBox* predefined = new QHGroupBox(i18n("Predefined Character Ranges"),top);
+ topLayout->addWidget(predefined);
+ QGrid* grid = new QGrid(3, predefined );
+
+ wordChar = new QCheckBox(i18n("A word character"),grid);
+ digit = new QCheckBox(i18n("A digit character"),grid);
+ space = new QCheckBox(i18n("A space character"), grid);
+
+ _nonWordChar = new QCheckBox(i18n("A non-word character"),grid);
+ _nonDigit = new QCheckBox(i18n("A non-digit character"),grid);
+ _nonSpace = new QCheckBox(i18n("A non-space character"), grid);
+
+ // Single characters
+ QVGroupBox* singleBox = new QVGroupBox(i18n("Single Characters"), top );
+ topLayout->addWidget( singleBox );
+ _single = new KMultiFormListBox(new SingleFactory(), KMultiFormListBox::MultiVisible,
+ singleBox);
+ _single->addElement(); _single->addElement(); _single->addElement();
+
+ QWidget* moreW = new QWidget( singleBox );
+ QHBoxLayout* moreLay = new QHBoxLayout( moreW );
+ QPushButton* more = new QPushButton( i18n("More Entries"), moreW );
+ moreLay->addWidget( more );
+ moreLay->addStretch( 1 );
+
+ connect(more,SIGNAL(clicked()), _single, SLOT(addElement()));
+
+ // Ranges
+ QVGroupBox* rangeBox = new QVGroupBox(i18n("Character Ranges"), top );
+ topLayout->addWidget( rangeBox );
+
+ _range = new KMultiFormListBox(new RangeFactory(), KMultiFormListBox::MultiVisible,
+ rangeBox);
+ _range->addElement(); _range->addElement(); _range->addElement();
+
+ moreW = new QWidget( rangeBox );
+ moreLay = new QHBoxLayout( moreW );
+ more = new QPushButton( i18n("More Entries"), moreW );
+ moreLay->addWidget( more );
+ moreLay->addStretch( 1 );
+ connect(more,SIGNAL(clicked()), _range, SLOT(addElement()));
+ // Buttons
+ connect(this, SIGNAL(okClicked()), this, SLOT(slotOK()));
+}
+
+void CharacterEdits::slotOK()
+{
+ _regexp->setNegate( negate->isChecked() );
+
+ _regexp->setWordChar( wordChar->isChecked() );
+ _regexp->setNonWordChar( _nonWordChar->isChecked() );
+
+ _regexp->setDigit( digit->isChecked() );
+ _regexp->setNonDigit( _nonDigit->isChecked() );
+
+ _regexp->setSpace( space->isChecked() );
+ _regexp->setNonSpace( _nonSpace->isChecked() );
+
+ // single characters
+ _regexp->clearChars();
+ KMultiFormListBoxEntryList list = _single->elements();
+ for ( QPtrListIterator<KMultiFormListBoxEntry> it( list ); *it; ++it ) {
+ SingleEntry* entry = dynamic_cast<SingleEntry*>(*it);
+ if ( entry && !entry->isEmpty() ) {
+ _regexp->addCharacter( entry->text() );
+ }
+ }
+
+ // Ranges
+ _regexp->clearRange();
+ list = _range->elements();
+ for ( QPtrListIterator<KMultiFormListBoxEntry> it2( list ); *it2; ++it2 ) {
+ RangeEntry* entry = dynamic_cast<RangeEntry*>(*it2);
+ if ( entry && !entry->isEmpty() ) {
+ _regexp->addRange( entry->fromText(), entry->toText() );
+ }
+ }
+}
+
+
+SingleEntry::SingleEntry(QWidget* parent, const char* name )
+ :KMultiFormListBoxEntry( parent, name )
+{
+ QHBoxLayout* layout = new QHBoxLayout( this, 3, 6 );
+ _selector = new CharSelector( this );
+ layout->addWidget( _selector );
+ layout->addStretch(1);
+}
+
+QString SingleEntry::text() const
+{
+ return _selector->text();
+}
+
+void SingleEntry::setText( QString text )
+{
+ _selector->setText( text );
+}
+
+bool SingleEntry::isEmpty() const
+{
+ return _selector->isEmpty();
+}
+
+
+RangeEntry::RangeEntry(QWidget* parent, const char* name )
+ :KMultiFormListBoxEntry( parent, name )
+{
+ QHBoxLayout* layout = new QHBoxLayout( this, 3, 6 );
+
+ QLabel* label = new QLabel(i18n("From:"), this );
+ _from = new CharSelector( this );
+ layout->addWidget( label );
+ layout->addWidget( _from );
+
+ layout->addStretch(1);
+
+ label = new QLabel(i18n("end of range","To:"), this );
+ _to = new CharSelector( this );
+ layout->addWidget( label );
+ layout->addWidget( _to );
+}
+
+QString RangeEntry::fromText() const
+{
+ return _from->text();
+}
+
+QString RangeEntry::toText() const
+{
+ return _to->text();
+}
+
+void RangeEntry::setFrom( QString text )
+{
+ _from->setText( text );
+}
+
+void RangeEntry::setTo( QString text )
+{
+ _to->setText( text );
+}
+
+bool RangeEntry::isEmpty() const
+{
+ return _from->isEmpty() || _to->isEmpty();
+}
+
diff --git a/kregexpeditor/characterswidget.h b/kregexpeditor/characterswidget.h
new file mode 100644
index 0000000..9df89b3
--- /dev/null
+++ b/kregexpeditor/characterswidget.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef characterswidget
+#define characterswidget
+
+#ifdef QT_ONLY
+#include "compat.h"
+#else
+#include <kdialogbase.h>
+#endif
+
+#include <kmultiformlistbox.h>
+#include "regexpwidget.h"
+#include <qvgroupbox.h>
+
+class KDialogBase;
+class CharacterEdits;
+class TextRangeRegExp;
+class CharSelector;
+class QCheckBox;
+
+/**
+ RegExp widget for charcter ranges.
+ @internal
+*/
+class CharactersWidget :public RegExpWidget
+{
+public:
+ CharactersWidget(RegExpEditorWindow* editorWindow, QWidget *parent,
+ const char *label = 0);
+ CharactersWidget( TextRangeRegExp* regexp, RegExpEditorWindow* editorWindow,
+ QWidget* parent, const char* name = 0 );
+ ~CharactersWidget();
+ virtual QSize sizeHint() const;
+ virtual RegExp* regExp() const;
+ virtual RegExpType type() const { return CHARSET; }
+ virtual RegExpWidget* findWidgetToEdit( QPoint globalPos );
+ virtual int edit();
+
+protected:
+ virtual void paintEvent(QPaintEvent *event);
+ QString text() const;
+ QString title() const;
+
+private:
+ TextRangeRegExp *_regexp;
+ static CharacterEdits *_configWindow;
+
+ mutable QSize _textSize;
+ mutable QSize _contentSize;
+};
+
+
+/**
+ @internal
+*/
+class SingleEntry :public KMultiFormListBoxEntry
+{
+public:
+ SingleEntry(QWidget* parent, const char* name = 0 );
+ QString text() const;
+ void setText( QString text );
+ bool isEmpty() const;
+
+private:
+ CharSelector* _selector;
+};
+
+/**
+ @internal
+*/
+class RangeEntry :public KMultiFormListBoxEntry
+{
+public:
+ RangeEntry(QWidget* parent, const char* name = 0 );
+ QString fromText() const;
+ QString toText() const;
+ void setFrom( QString text );
+ void setTo( QString text );
+ bool isEmpty() const;
+private:
+ CharSelector *_from, *_to;
+};
+
+/**
+ @internal
+*/
+class SingleFactory :public KMultiFormListBoxFactory
+{
+public:
+ KMultiFormListBoxEntry *create(QWidget *parent) { return new SingleEntry( parent ); }
+ QWidget *separator( QWidget* ) { return 0; }
+};
+
+/**
+ @internal
+*/
+class RangeFactory :public KMultiFormListBoxFactory
+{
+public:
+ KMultiFormListBoxEntry *create(QWidget *parent) { return new RangeEntry( parent ); }
+ QWidget *separator( QWidget* ) { return 0; }
+};
+
+/**
+ @internal
+*/
+class CharacterEdits : public KDialogBase
+{
+ Q_OBJECT
+public:
+ CharacterEdits(QWidget *parent = 0, const char *name = 0);
+
+public slots:
+ int exec( TextRangeRegExp* regexp );
+
+protected slots:
+ void slotOK();
+
+private:
+ QCheckBox *negate, *wordChar, *_nonWordChar, *digit, *_nonDigit, *space, *_nonSpace;
+ KMultiFormListBox *_single, *_range;
+
+ void addCharacter( QString txt );
+ void addRange( QString from, QString to );
+ TextRangeRegExp* _regexp;
+};
+
+#endif // characterswidget
diff --git a/kregexpeditor/charselector.cpp b/kregexpeditor/charselector.cpp
new file mode 100644
index 0000000..27fd23d
--- /dev/null
+++ b/kregexpeditor/charselector.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifdef QT_ONLY
+#include "compat.h"
+#else
+#include <klocale.h>
+#include "charselector.moc"
+#endif
+
+#include "charselector.h"
+#include "limitedcharlineedit.h"
+#include "regexpconverter.h"
+#include <qlayout.h>
+#include <qwidgetstack.h>
+#include <qcombobox.h>
+
+/**
+ In the class CharSelector, three LimitedCharLineEdit are used.
+ These widgets are all used in a QWidgetStack. The LimitedCharLineEdit
+ class is basically a QLineEdit, which is limited to a certain
+ number of characters. This conflicts with the QWidgetStack, as this
+ class expects the widgets on the stack to take up all space.
+ StackContainer fills in this gab.
+*/
+class StackContainer :public QWidget
+{
+public:
+ StackContainer( QWidget* child, QWidget* parent ) : QWidget( parent )
+ {
+ QHBoxLayout* layout = new QHBoxLayout( this );
+ child->reparent( this, QPoint(0,0), false );
+ layout->addWidget( child );
+ layout->addStretch( 1 );
+ }
+};
+
+CharSelector::CharSelector( QWidget* parent, const char* name )
+ :QWidget( parent, name ), _oldIndex(0)
+{
+ QStringList items;
+ QHBoxLayout* layout = new QHBoxLayout( this, 0, 6 );
+
+ _type = new QComboBox( this, "_type" );
+ items << i18n("Normal Character")
+ << i18n("Unicode Char in Hex.")
+ << i18n("Unicode Char in Oct.")
+ << QString::fromLatin1("----")
+ << i18n("The Bell Character (\\a)")
+ << i18n("The Form Feed Character (\\f)")
+ << i18n("The Line Feed Character (\\n)")
+ << i18n("The Carriage Return Character (\\r)")
+ << i18n("The Horizontal Tab Character (\\t)")
+ << i18n("The Vertical Tab Character (\\v)");
+ _type->insertStringList( items );
+ layout->addWidget( _type );
+
+ _stack = new QWidgetStack( this, "_stack" );
+ layout->addWidget( _stack );
+
+ _normal = new LimitedCharLineEdit( LimitedCharLineEdit::NORMAL, 0, "_normal" );
+ _stack->addWidget( new StackContainer( _normal, _stack ), 0 );
+
+ _hex = new LimitedCharLineEdit( LimitedCharLineEdit::HEX, _stack, "_hex" );
+ _stack->addWidget( new StackContainer( _hex, _stack ), 1 );
+
+ _oct = new LimitedCharLineEdit( LimitedCharLineEdit::OCT, _stack, "_oct" );
+ _stack->addWidget( new StackContainer( _oct, _stack ), 2 );
+
+ _stack->raiseWidget( 0 );
+
+ connect( _type, SIGNAL( activated( int ) ), this, SLOT(slotNewItem( int ) ) );
+}
+
+void CharSelector::slotNewItem( int which )
+{
+ _type->setCurrentItem( which );
+ if ( which <= 2 ) {
+ _stack->raiseWidget( which );
+ _normal->setEnabled( true );
+ _hex->setEnabled( true );
+ _oct->setEnabled( true );
+ }
+ else if ( which == 3 ) {
+ _type->setCurrentItem( _oldIndex );
+ slotNewItem(_oldIndex);
+ return;
+ }
+ else {
+ _normal->setEnabled( false );
+ _hex->setEnabled( false );
+ _oct->setEnabled( false );
+ }
+
+ _oldIndex = which;
+}
+
+void CharSelector::setText( QString text )
+{
+ // This is the best I can do about missing character range features, unless all of
+ // textrangeregexp is to be reworked. The problem is that textrangeregexp only allows to
+ // get the characters, which would be something like \a, but \a does not work with say Emacs
+ // style regexps -- ko28 Sep. 2003 10:55 -- Jesper K. Pedersen
+ bool enabled = ( RegExpConverter::current()->features() & RegExpConverter::ExtRange );
+ _type->setEnabled( enabled );
+
+ if ( text.at(0) == QChar('\\') ) {
+ if ( text.at(1) == QChar('x') ) {
+ _hex->setText(text.mid(2));
+ slotNewItem( 1 );
+ }
+ else if ( text.at(1) == QChar('0') ) {
+ _oct->setText(text.mid(2));
+ slotNewItem( 2 );
+ }
+ else if ( text.at(1) == QChar('a') )
+ slotNewItem(4);
+ else if ( text.at(1) == QChar('f') )
+ slotNewItem(5);
+ else if ( text.at(1) == QChar('n') )
+ slotNewItem(6);
+ else if ( text.at(1) == QChar('r') )
+ slotNewItem(7);
+ else if ( text.at(1) == QChar('t') )
+ slotNewItem(8);
+ else if ( text.at(1) == QChar('v') )
+ slotNewItem(9);
+ else {
+ qWarning("Warning %s:%d Unknown escape %s", __FILE__, __LINE__, text.latin1() );
+ }
+ }
+ else {
+ slotNewItem(0);
+ _normal->setText(text);
+ }
+}
+
+bool CharSelector::isEmpty() const
+{
+ return ( _type->currentItem() == 0 && _normal->text().isEmpty() ) ||
+ ( _type->currentItem() == 1 && _hex->text().isEmpty() ) ||
+ ( _type->currentItem() == 2 && _oct->text().isEmpty() );
+}
+
+QString CharSelector::text() const
+{
+ switch ( _type->currentItem() ) {
+ case 0: // Normal Character
+ return _normal->text();
+ case 1: // Hex
+ return QString::fromLocal8Bit("\\x") + _hex->text();
+ case 2: // Oct
+ return QString::fromLocal8Bit("\\0") + _oct->text();
+ case 3: // The seperator
+ break;
+ case 4:
+ return QString::fromLatin1("\\a");
+ case 5:
+ return QString::fromLatin1("\\f");
+ case 6:
+ return QString::fromLatin1("\\n");
+ case 7:
+ return QString::fromLatin1("\\r");
+ case 8:
+ return QString::fromLatin1("\\t");
+ case 9:
+ return QString::fromLatin1("\\v");
+ }
+ return QString::null;
+}
diff --git a/kregexpeditor/charselector.h b/kregexpeditor/charselector.h
new file mode 100644
index 0000000..07aa056
--- /dev/null
+++ b/kregexpeditor/charselector.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef CHARSELECTOR_H
+#define CHARSELECTOR_H
+
+#include <qwidget.h>
+
+class QComboBox;
+class QWidgetStack;
+class LimitedCharLineEdit;
+
+class CharSelector :public QWidget
+{
+ Q_OBJECT
+
+public:
+ CharSelector( QWidget* parent, const char* name = 0 );
+ QString text() const;
+ void setText( QString text );
+ bool isEmpty() const;
+
+protected:
+ void fillComboBox();
+
+private slots:
+ void slotNewItem( int which );
+
+private:
+ QComboBox* _type;
+ QWidgetStack* _stack;
+ LimitedCharLineEdit* _normal;
+ LimitedCharLineEdit* _hex;
+ LimitedCharLineEdit* _oct;
+ int _oldIndex;
+};
+
+#endif // CHARSELECTOR_H
diff --git a/kregexpeditor/compoundregexp.cpp b/kregexpeditor/compoundregexp.cpp
new file mode 100644
index 0000000..2949b48
--- /dev/null
+++ b/kregexpeditor/compoundregexp.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <klocale.h>
+#endif
+
+#include "compoundregexp.h"
+#include "widgetfactory.h"
+
+CompoundRegExp::CompoundRegExp( bool selected, const QString& title, const QString& description, bool hidden,
+ bool allowReplace, RegExp* child)
+ : RegExp( selected ), _title( title ), _description( description ), _hidden( hidden ), _allowReplace( allowReplace ), _child( child )
+{
+ if ( child )
+ addChild( child );
+}
+
+bool CompoundRegExp::check( ErrorMap& map, bool first, bool last )
+{
+ return _child->check( map, first, last );
+}
+
+QDomNode CompoundRegExp::toXml( QDomDocument* doc ) const
+{
+ QDomElement top = doc->createElement( QString::fromLocal8Bit( "Compound" ) );
+ if (_hidden)
+ top.setAttribute( QString::fromLocal8Bit("hidden"), true );
+ if ( _allowReplace )
+ top.setAttribute( QString::fromLocal8Bit("allowReplace"), true );
+
+ QDomElement title = doc->createElement( QString::fromLocal8Bit( "Title" ) );
+ QDomText titleTxt = doc->createTextNode( _title );
+ title.appendChild( titleTxt );
+ top.appendChild( title );
+
+ QDomElement description = doc->createElement( QString::fromLocal8Bit( "Description" ) );
+ QDomText descriptionTxt = doc->createTextNode( _description );
+ description.appendChild( descriptionTxt );
+ top.appendChild( description );
+
+ top.appendChild( _child->toXml( doc ) );
+
+ return top;
+}
+
+
+bool CompoundRegExp::load( QDomElement top, const QString& version )
+{
+ Q_ASSERT( top.tagName() == QString::fromLocal8Bit("Compound") );
+ QString str = top.attribute( QString::fromLocal8Bit( "hidden" ), QString::fromLocal8Bit("0") );
+ _hidden = true; // alway hidden. (str == QString::fromLocal8Bit("1") );
+
+ str = top.attribute( QString::fromLocal8Bit( "allowReplace" ), QString::fromLocal8Bit("0") );
+ _allowReplace = (str == QString::fromLocal8Bit("1") );
+
+ for ( QDomNode node = top.firstChild(); !node.isNull(); node = node.nextSibling() ) {
+ if ( !node.isElement() )
+ continue; // skip past comments.
+ QString txt;
+ QDomElement child = node.toElement();
+ QDomNode txtNode = child.firstChild();
+ if ( txtNode.isText() )
+ txt = txtNode.toText().data();
+ if ( child.tagName() == QString::fromLocal8Bit( "Title" ) ) {
+ if ( txt.isEmpty() )
+ _title = txt;
+ else
+ _title = i18n(txt.utf8());
+ }
+ else if ( child.tagName() == QString::fromLocal8Bit( "Description" ) ) {
+ if ( txt.isEmpty() )
+ _description = txt;
+ else
+ _description = i18n(txt.utf8());
+ }
+ else {
+ _child = WidgetFactory::createRegExp( child, version );
+ if ( _child ) {
+ addChild( _child );
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ }
+ return false;
+}
+
+bool CompoundRegExp::operator==( const RegExp& other ) const
+{
+ // Note the order is important in the comparison below.
+ // Using other as the first argument, means that
+ // the following will be evaluated: other.operator== rather than (*child).operator==
+ // This means that if other is a CompoundRegExp too, then this level will be striped.
+ return ( other == *_child );
+}
diff --git a/kregexpeditor/compoundregexp.h b/kregexpeditor/compoundregexp.h
new file mode 100644
index 0000000..4e9aa8c
--- /dev/null
+++ b/kregexpeditor/compoundregexp.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef COMPOUNDREGEXP_H
+#define COMPOUNDREGEXP_H
+#include "regexp.h"
+
+/**
+ Abstract syntax node for `compound content' regular expression
+ @internal
+*/
+class CompoundRegExp :public RegExp
+{
+public:
+ CompoundRegExp( bool selected, const QString& title = QString::null,
+ const QString& description = QString::null,
+ bool hidden = false, bool allowReplace = false, RegExp* child = 0);
+
+ virtual bool check( ErrorMap&, bool first, bool last );
+ virtual int precedence() const { return _child->precedence();}
+ virtual QDomNode toXml( QDomDocument* doc ) const;
+ virtual bool load( QDomElement, const QString& version );
+ QString title() const { return _title; }
+ QString description() const { return _description; }
+ RegExp* child() const { return _child; }
+ bool hidden() const { return _hidden; }
+ bool allowReplace() const { return _allowReplace; }
+ virtual RegExpType type() const { return COMPOUND;}
+ virtual bool operator==( const RegExp& other ) const;
+
+private:
+ QString _title;
+ QString _description;
+ bool _hidden;
+ bool _allowReplace;
+ RegExp* _child;
+};
+
+
+#endif // COMPOUNDREGEXP_H
diff --git a/kregexpeditor/compoundwidget.cpp b/kregexpeditor/compoundwidget.cpp
new file mode 100644
index 0000000..3294313
--- /dev/null
+++ b/kregexpeditor/compoundwidget.cpp
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifdef QT_ONLY
+ #include "compat.h"
+ #include "images.h"
+#else
+ #include <klocale.h>
+ #include <kdialogbase.h>
+ #include <kiconloader.h>
+ #include "compoundwidget.moc"
+#endif
+
+#include "compoundwidget.h"
+#include <qlayout.h>
+#include <qcursor.h>
+#include <qlineedit.h>
+#include <qpainter.h>
+#include <qtooltip.h>
+#include "concwidget.h"
+#include "kwidgetstreamer.h"
+#include "qcheckbox.h"
+
+//================================================================================
+
+CompoundDetailWindow::CompoundDetailWindow( QWidget* parent, const char* name )
+ :QWidget( parent, name )
+{
+ QVBoxLayout* layout = new QVBoxLayout( this );
+ layout->setAutoAdd( true );
+
+ QLabel* label = new QLabel( i18n("&Title:"), this);
+ _title = new QLineEdit( this );
+ label->setBuddy( _title );
+
+ label = new QLabel( i18n("&Description:"), this );
+ _description = new QMultiLineEdit( this );
+ label->setBuddy( _description );
+
+ _allowReplace = new QCheckBox( i18n("&Automatically replace using this item"), this );
+ QToolTip::add( _allowReplace, i18n("When the content of this box is typed in to the ASCII line,<br>"
+ "this box will automatically be added around it,<br>"
+ "if this check box is selected.") );
+ _allowReplace->setChecked( true );
+
+ _title->setFocus();
+
+}
+
+QString CompoundDetailWindow::title() const
+{
+ return _title->text();
+}
+
+QString CompoundDetailWindow::description() const
+{
+ return _description->text();
+}
+
+bool CompoundDetailWindow::allowReplace() const
+{
+ return _allowReplace->isChecked();
+}
+
+void CompoundDetailWindow::setTitle( QString txt )
+{
+ _title->setText( txt );
+}
+
+void CompoundDetailWindow::setDescription( QString txt )
+{
+ _description->setText( txt );
+}
+
+void CompoundDetailWindow::setAllowReplace( bool b )
+{
+ _allowReplace->setChecked( b );
+}
+
+//================================================================================
+
+CompoundWidget::CompoundWidget( RegExpEditorWindow* editorWindow, QWidget* parent,
+ const char* name )
+ :SingleContainerWidget( editorWindow, parent, name == 0 ? "CompoundWidget" : name )
+{
+ _child = new ConcWidget( editorWindow, this );
+ init();
+}
+
+CompoundWidget::CompoundWidget( CompoundRegExp* regexp, RegExpEditorWindow* editorWindow,
+ QWidget* parent, const char* name )
+ : SingleContainerWidget( editorWindow, parent, name == 0 ? "CompoundWidget" : name )
+{
+ init();
+ _content->setTitle( regexp->title() );
+ _content->setDescription( regexp->description() );
+ _content->setAllowReplace( regexp->allowReplace() );
+ RegExpWidget* child = WidgetFactory::createWidget( regexp->child(), _editorWindow, this );
+ if ( !( _child = dynamic_cast<ConcWidget*>(child) ) ) {
+ _child = new ConcWidget( _editorWindow, child, this );
+ }
+
+ _hidden = regexp->hidden();
+}
+
+void CompoundWidget::init( )
+{
+ _configWindow = new KDialogBase( this, "_configWindow", true,
+ i18n("Configure Compound"),
+ KDialogBase::Ok | KDialogBase::Cancel );
+ _content = new CompoundDetailWindow( _configWindow );
+ _configWindow->setMainWidget( _content );
+
+ connect( _configWindow, SIGNAL(cancelClicked()), this, SLOT(slotConfigCanceled())) ;
+ connect(_configWindow, SIGNAL(finished()), this, SLOT(slotConfigWindowClosed()));
+
+ _down = getIcon( QString::fromLocal8Bit( "1downarrow" ));
+ _up = getIcon( QString::fromLocal8Bit( "1uparrow" ) );
+
+ _hidden = false;
+ _backRefId = -1;
+}
+
+QSize CompoundWidget::sizeHint() const
+{
+ QFontMetrics metrics = fontMetrics();
+ _childSize = _child->sizeHint();
+ _textSize = metrics.size( 0, _content->title() );
+
+ int width, height;
+
+ if ( _hidden ) {
+ _pixmapSize = _up.size();
+ width = 2*pw + QMAX( 2*bdSize+_textSize.width(), 2*bdSize+_pixmapSize.width());
+ height = _pixmapSize.height() + 2*bdSize + _textSize.height()+pw;
+ }
+ else {
+ _pixmapSize = _down.size();
+ int headerLineWidth = 2*pw + 2*bdSize + _pixmapSize.width();
+ if ( _textSize.width() != 0)
+ headerLineWidth += 3*bdSize + _textSize.width();
+
+ width = QMAX( 2*pw + _childSize.width(), headerLineWidth );
+ height = QMAX( _textSize.height(), _pixmapSize.height() ) +
+ 2*bdSize + _childSize.height() + pw;
+ }
+ return QSize( width, height );
+
+}
+
+void CompoundWidget::paintEvent( QPaintEvent *e )
+{
+ QSize mySize = sizeHint();
+
+ QPainter painter(this);
+ drawPossibleSelection( painter, mySize);
+
+ int horLineY, childY;
+
+ // draw top line
+ if ( _hidden ) {
+ horLineY = _pixmapSize.height()/2;
+ childY = _pixmapSize.height() + bdSize;
+ _pixmapPos = QPoint( mySize.width()-pw-bdSize-_pixmapSize.width(), 0 );
+ painter.drawLine( pw, horLineY, _pixmapPos.x(), horLineY );
+ painter.drawLine( mySize.width() - bdSize - pw, horLineY,
+ mySize.width(), horLineY);
+ painter.drawPixmap( _pixmapPos, _up );
+ }
+ else {
+ int maxH = QMAX( _textSize.height(), _pixmapSize.height() );
+ int offset = 0;
+ horLineY = maxH/2;
+ childY = maxH+bdSize;
+
+ painter.drawLine(pw, horLineY, bdSize, horLineY);
+ if ( _textSize.width() != 0 ) {
+ offset += pw + 2*bdSize;
+
+ painter.drawText(offset, horLineY-_textSize.height()/2,
+ bdSize+_textSize.width(), horLineY+_textSize.height()/2,
+ 0, _content->title());
+ offset += _textSize.width() + bdSize;
+ }
+
+ _pixmapPos = QPoint( mySize.width()-pw-bdSize-_pixmapSize.width(),
+ horLineY - _pixmapSize.height()/2 );
+
+ painter.drawLine( offset, horLineY, _pixmapPos.x(), horLineY );
+ painter.drawPixmap( _pixmapPos, _down );
+
+ painter.drawLine( mySize.width()-bdSize-pw, horLineY, mySize.width(), horLineY );
+ }
+
+ // draw rest frame
+ painter.drawLine(0, horLineY, 0, mySize.height() );
+ painter.drawLine( mySize.width()-pw, horLineY, mySize.width()-pw, mySize.height() );
+ painter.drawLine( 0, mySize.height()-pw, mySize.width(), mySize.height()-pw );
+
+ // place/size child
+ if ( _hidden ) {
+ _child->hide();
+ painter.drawText( pw+bdSize, childY,
+ pw+bdSize+_textSize.width(), childY+_textSize.height(), 0,
+ _content->title() );
+ }
+ else {
+ QSize curSize = _child->size();
+ QSize newSize = QSize( QMAX( _child->sizeHint().width(), mySize.width()-2*pw),
+ _child->sizeHint().height());
+
+ _child->move( pw, childY );
+ if ( curSize != newSize ) {
+ _child->resize(newSize);
+ // I resized the child, so give it a chance to relect thus.
+ _child->update();
+ }
+
+ _child->show();
+ }
+
+ RegExpWidget::paintEvent( e );
+}
+
+void CompoundWidget::slotConfigWindowClosed()
+{
+ _editorWindow->updateContent( 0 );
+ update();
+}
+
+void CompoundWidget::slotConfigCanceled()
+{
+ QDataStream stream( _backup, IO_ReadOnly );
+ KWidgetStreamer streamer;
+ streamer.fromStream( stream, _content );
+ repaint();
+}
+
+RegExp* CompoundWidget::regExp() const
+{
+ return new CompoundRegExp( isSelected(), _content->title(), _content->description(),
+ _hidden, _content->allowReplace(), _child->regExp() );
+}
+
+void CompoundWidget::mousePressEvent( QMouseEvent* event )
+{
+ if ( event->button() == LeftButton &&
+ QRect( _pixmapPos, _pixmapSize ).contains( event->pos() ) ) {
+ // Skip otherwise we will never see the mouse release
+ // since it is eaten by Editor window.
+ }
+ else
+ SingleContainerWidget::mousePressEvent( event );
+}
+
+void CompoundWidget::mouseReleaseEvent( QMouseEvent* event)
+{
+ if ( event->button() == LeftButton &&
+ QRect( _pixmapPos, _pixmapSize ).contains( event->pos() ) ) {
+ _hidden = !_hidden;
+ _editorWindow->updateContent( 0 );
+ repaint(); // is this necesary?
+ _editorWindow->emitChange();
+ }
+ else
+ SingleContainerWidget::mouseReleaseEvent( event );
+}
+
+bool CompoundWidget::updateSelection( bool parentSelected )
+{
+ if ( _hidden ) {
+ bool changed = RegExpWidget::updateSelection( parentSelected );
+ _child->selectWidget( _isSelected );
+ if (changed)
+ repaint();
+ return changed;
+ }
+ else {
+ return SingleContainerWidget::updateSelection( parentSelected );
+ }
+}
+
+int CompoundWidget::edit()
+{
+ _configWindow->move(QCursor::pos() - QPoint(_configWindow->sizeHint().width()/2,
+ _configWindow->sizeHint().height()/2) );
+ QDataStream stream( _backup, IO_WriteOnly );
+ KWidgetStreamer streamer;
+ streamer.toStream( _content, stream );
+ return _configWindow->exec();
+}
+
+int nextId()
+{
+ static int counter = 0;
+ return ++counter;
+}
+
+QPixmap CompoundWidget::getIcon( const QString& name )
+{
+#ifdef QT_ONLY
+ QPixmap pix;
+ pix.convertFromImage( qembed_findImage(name) );
+ return pix;
+#else
+ return SmallIcon( name );
+#endif
+}
+
+
diff --git a/kregexpeditor/compoundwidget.h b/kregexpeditor/compoundwidget.h
new file mode 100644
index 0000000..f757c05
--- /dev/null
+++ b/kregexpeditor/compoundwidget.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef compoundwidget
+#define compoundwidget
+class QLineEdit;
+class QMultiLineEdit;
+class KDialogBase;
+class QCheckBox;
+
+#include "singlecontainerwidget.h"
+#include "compoundregexp.h"
+
+/**
+ Widget containing configuration details for @ref CompoundWidget
+ @internal
+*/
+class CompoundDetailWindow :public QWidget
+{
+public:
+ CompoundDetailWindow(QWidget* parent, const char* name = 0);
+ QString title() const;
+ QString description() const;
+ bool allowReplace() const;
+ void setTitle( QString );
+ void setDescription( QString );
+ void setAllowReplace( bool );
+
+private:
+ QLineEdit* _title;
+ QMultiLineEdit* _description;
+ QCheckBox* _allowReplace;
+};
+
+
+/**
+ Comopund RegExp widget.
+
+ This widget has two purposes:
+ @li To make it possible for a user to collapse a huge regular expression
+ to take up less screen space.
+ @li To act as back references for later use.
+
+ @internal
+*/
+class CompoundWidget :public SingleContainerWidget
+{
+Q_OBJECT
+
+public:
+ CompoundWidget( RegExpEditorWindow* editorWindow, QWidget* parent,
+ const char* name = 0);
+ CompoundWidget( CompoundRegExp* regexp, RegExpEditorWindow* editorWindow,
+ QWidget* parent, const char* name = 0);
+
+ virtual bool updateSelection( bool parentSelected );
+ virtual QSize sizeHint() const;
+ virtual RegExp* regExp() const;
+ virtual RegExpType type() const { return COMPOUND; }
+ virtual int edit();
+
+protected:
+ virtual void paintEvent( QPaintEvent *e );
+ virtual void mousePressEvent( QMouseEvent* e );
+ virtual void mouseReleaseEvent( QMouseEvent* e);
+ void init();
+ QPixmap getIcon( const QString& name );
+
+protected slots:
+ void slotConfigCanceled();
+ void slotConfigWindowClosed();
+
+private:
+ bool _hidden;
+ QPixmap _up, _down;
+ mutable QSize _pixmapSize;
+ mutable QPoint _pixmapPos;
+
+ KDialogBase* _configWindow;
+ CompoundDetailWindow* _content;
+
+ mutable QSize _textSize;
+ mutable QSize _childSize;
+ QByteArray _backup;
+
+ int _backRefId;
+};
+
+
+#endif // compoundwidget
diff --git a/kregexpeditor/concregexp.cpp b/kregexpeditor/concregexp.cpp
new file mode 100644
index 0000000..4fac8d0
--- /dev/null
+++ b/kregexpeditor/concregexp.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "concregexp.h"
+#include "widgetfactory.h"
+#include "compoundregexp.h"
+
+ConcRegExp::ConcRegExp( bool selected ) :RegExp( selected )
+{
+}
+
+void ConcRegExp::addRegExp( RegExp *regExp )
+{
+ list.append(regExp);
+ addChild( regExp );
+}
+
+RegExpList ConcRegExp::children()
+{
+ return list;
+}
+
+
+bool ConcRegExp::check( ErrorMap& map, bool first, bool last)
+{
+ bool f = first;
+ bool possibleEmpty = true;
+ for ( RegExpListIt it(list); *it; ++it ) {
+ possibleEmpty = (*it)->check( map, f, last && it.atLast() ) && possibleEmpty;
+ if ( ! possibleEmpty )
+ f = false;
+ }
+ return possibleEmpty;
+}
+
+RegExp* ConcRegExp::lastRegExp()
+{
+ if ( list.count() == 0)
+ return 0;
+ else
+ return list.at( list.count()-1);
+}
+
+QDomNode ConcRegExp::toXml( QDomDocument* doc ) const
+{
+ QDomElement top = doc->createElement( QString::fromLocal8Bit("Concatenation") );
+ for ( RegExpListIt it(list); *it; ++it ) {
+ top.appendChild( (*it)->toXml( doc ) );
+ }
+ return top;
+}
+
+bool ConcRegExp::load( QDomElement top, const QString& version )
+{
+ Q_ASSERT( top.tagName() == QString::fromLocal8Bit( "Concatenation" ) );
+
+ for ( QDomNode child = top.firstChild(); !child.isNull(); child = child.nextSibling() ) {
+ if ( ! child.isElement() )
+ continue; // User might have added a comment.
+
+ RegExp* regexp = WidgetFactory::createRegExp( child.toElement(), version );
+ if ( regexp == 0 )
+ return false;
+ addRegExp( regexp );
+ }
+ return true;
+}
+
+bool ConcRegExp::operator==( const RegExp& other ) const
+{
+ // TODO: Merge with AltnRegExp::operator==
+ if ( list.count() == 1 )
+ return ( other == *(const_cast< QPtrList<RegExp>& >(list).at(0)) );
+
+ if ( other.type() != type() )
+ return false;
+
+ const ConcRegExp& theOther = dynamic_cast<const ConcRegExp&>( other );
+
+ if ( list.count() != theOther.list.count() )
+ return false;
+
+ RegExpListIt it1( list );
+ RegExpListIt it2( theOther.list );
+
+ for ( ; *it1 && *it2 ; ) {
+ if ( ! (**it1 == **it2) )
+ return false;
+ ++it1;
+ ++it2;
+ }
+ return true;
+}
+
+
+void ConcRegExp::replacePart( CompoundRegExp* replacement )
+{
+ RegExp* otherChild = replacement->child();
+ ConcRegExp* otherConc = dynamic_cast<ConcRegExp*>( otherChild );
+ if ( ! otherConc ) {
+ // Watch out for garbage here!
+ otherConc = new ConcRegExp( false );
+ otherConc->addRegExp( otherChild );
+ }
+
+ RegExpList newList;
+ RegExpListIt it1( list );
+ while ( *it1 ) {
+ (*it1)->replacePart( replacement );
+ RegExpListIt it2 = it1;
+ RegExpListIt it3( otherConc->list );
+ bool match = true;
+ int count = 0;
+
+ // See if replacement is a sublist of list starting from what it1 points at
+ for ( ; *it2 && * it3 && match ; ) {
+ if (! ( **it2 == **it3 ) )
+ match = false;
+ ++it2;
+ ++it3;
+ ++count;
+ }
+
+ if ( match && ! *it3) {
+ // I found a match, delete the element in it1, which is common with it3
+ while ( *it1 != *it2 ) {
+ RegExp* item = *it1;
+ ++it1;
+ delete item;
+ }
+ RegExp* theClone = replacement->clone();
+ newList.append( theClone );
+ addChild( theClone );
+ }
+ else {
+ newList.append( *it1 );
+ ++it1;
+ }
+ }
+ list = newList;
+}
+
+
diff --git a/kregexpeditor/concregexp.h b/kregexpeditor/concregexp.h
new file mode 100644
index 0000000..52a6342
--- /dev/null
+++ b/kregexpeditor/concregexp.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __CONCREGEXP_H
+#define __CONCREGEXP_H
+
+#include "regexp.h"
+
+
+/**
+ Abstract syntax node for `concatenated' regular expression
+ @internal
+*/
+class ConcRegExp :public RegExp
+{
+public:
+ ConcRegExp( bool selected );
+
+ void addRegExp( RegExp *);
+ RegExpList children();
+ RegExp* lastRegExp();
+
+ virtual bool check( ErrorMap&, bool first, bool last );
+ virtual int precedence() const { return 2;}
+ virtual QDomNode toXml( QDomDocument* doc ) const;
+ virtual bool load( QDomElement, const QString& version );
+ virtual RegExpType type() const {return CONC; }
+ virtual bool operator==( const RegExp& other ) const;
+ virtual void replacePart( CompoundRegExp* replacement );
+
+private:
+ RegExpList list;
+};
+
+#endif // __CONCREGEXP_H
diff --git a/kregexpeditor/concwidget.cpp b/kregexpeditor/concwidget.cpp
new file mode 100644
index 0000000..f67c49b
--- /dev/null
+++ b/kregexpeditor/concwidget.cpp
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "concregexp.h"
+#include "concwidget.h"
+#include "dragaccepter.h"
+
+#include <qpainter.h>
+
+ConcWidget::ConcWidget(RegExpEditorWindow* editorWindow, QWidget *parent,
+ const char *name)
+ :MultiContainerWidget(editorWindow, parent, name == 0 ? "concwidget" : name)
+{
+ init();
+ DragAccepter *accepter = new DragAccepter(editorWindow, this);
+ accepter->show();
+ _children.append(accepter);
+}
+
+
+ConcWidget::ConcWidget(RegExpEditorWindow* editorWindow, RegExpWidget *child,
+ QWidget *parent, const char *name)
+ :MultiContainerWidget(editorWindow, parent, name == 0 ? "concwidget" : name)
+{
+ init();
+ DragAccepter *accepter = new DragAccepter(editorWindow, this);
+ _children.append(accepter);
+ child->reparent(this, QPoint(0,0), false);
+ addNewChild(accepter, child);
+}
+
+ConcWidget::ConcWidget( RegExpEditorWindow* editorWindow, ConcWidget* origConc,
+ unsigned int start, unsigned int end)
+ :MultiContainerWidget(editorWindow, 0, "Splitted ConcWidget")
+{
+ init();
+ _children.prepend( new DragAccepter(editorWindow, this) );
+ for (unsigned int i = end; i >= start; i--) {
+ RegExpWidget* child = origConc->_children.take( i );
+ _children.prepend( child );
+ child->reparent( this, QPoint(0,0), false);
+ }
+ _children.prepend( new DragAccepter(editorWindow, this) );
+}
+
+ConcWidget::ConcWidget( ConcRegExp* regexp, RegExpEditorWindow* editorWindow,
+ QWidget* parent, const char* name )
+ :MultiContainerWidget( editorWindow, parent, name == 0 ? "concwidget" : name )
+{
+ init();
+ DragAccepter *accepter = new DragAccepter(editorWindow, this);
+ _children.append(accepter);
+
+ RegExpList list = regexp->children();
+ for ( RegExpListIt it(list); *it; ++it ) {
+ RegExpWidget* child = WidgetFactory::createWidget( *it, editorWindow, this );
+ append( child );
+ }
+}
+
+void ConcWidget::init()
+{
+ _maxSelectedHeight = 0;
+}
+
+
+QSize ConcWidget::sizeHint() const
+{
+ int childrenWidth = 0;
+ int childrenHeight = 0;
+ QPtrListIterator<RegExpWidget> it(_children);
+
+ for ( ; *it; ++it) {
+ QSize thisChildSize = (*it)->sizeHint();
+ childrenWidth += thisChildSize.width();
+ childrenHeight = QMAX(childrenHeight, thisChildSize.height());
+ }
+
+ return QSize(childrenWidth, childrenHeight);
+}
+
+void ConcWidget::paintEvent( QPaintEvent *e)
+{
+ Q_ASSERT( dynamic_cast<DragAccepter*>(_children.at(0)) );
+ // if this fails, then I should check the location of the show()
+ Q_ASSERT( _children.count() == 1 ||
+ ( _children.count() >=3 &&
+ dynamic_cast<DragAccepter*>(_children.at(_children.count()-1)) ) );
+
+ if ( _children.count() == 1) {
+ // There is only an accepter, lets give it all the space.
+ _children.at(0)->setGeometry( 0, 0, size().width(), size().height() );
+ }
+ else {
+ QSize myReqSize = sizeHint();
+ QSize mySize(QMAX(myReqSize.width(), size().width()),
+ QMAX(myReqSize.height(), size().height()));
+
+ // If the widget needs less space than it can get then this space should
+ // be given to the leftmost and rightmost accepter. So lets calculate
+ // this extra space.
+ int extra = 0;
+ if (size().width() > myReqSize.width()) {
+ extra = (size().width() - myReqSize.width())/2;
+ }
+
+ QPainter painter( this );
+
+ drawPossibleSelection( painter, mySize );
+
+ int lastHeight = 0;
+ int offset = 0;
+
+ for (unsigned int i = 1; i < _children.count(); i += 2 ) {
+ DragAccepter* accepter = dynamic_cast<DragAccepter*>(_children.at(i-1));
+ if (!accepter)
+ continue;
+ RegExpWidget* child = _children.at(i);
+
+ QSize childSize = child->sizeHint();
+ QSize curChildSize = child->size();
+
+ //----------------------------- first place the accepter
+ int x = offset;
+ int w = accepter->sizeHint().width();
+ if ( i == 1 ) w+= extra;
+ int h = QMAX( lastHeight, childSize.height() );
+ int y = (mySize.height() - h)/2;
+ accepter->setGeometry( x, y, w, h );
+
+ offset += w;
+ lastHeight = childSize.height();
+
+
+ //------------------------------ Draw Accepter selection
+ if ( accepter->isSelected() ) {
+ y = (mySize.height()-_maxSelectedHeight)/2;
+ h = _maxSelectedHeight;
+ painter.fillRect( x, y, w, h, QBrush( gray ) );
+ }
+
+ //-------------------------------------- place the child
+ x = offset;
+ h = childSize.height();
+ w = childSize.width();
+ y = (mySize.height() - h)/2;
+ child->setGeometry( x, y, w, h );
+ if ( childSize != curChildSize ) {
+ // I resized the child, so give it a chance to relect thus.
+ child->update();
+ }
+
+ offset += w;
+
+ //------------------------------ Draw Accepter selection
+ if ( child->isSelected() ) {
+ y = (mySize.height()-_maxSelectedHeight)/2;
+ h = _maxSelectedHeight;
+ painter.fillRect( x, y, w, h, QBrush( gray ) );
+ }
+ }
+
+ //---------------------- Finally place the last accepter.
+ DragAccepter* accepter =
+ dynamic_cast<DragAccepter*>(_children.at(_children.count()-1));
+ // dynamic_cast is ASSERTed at top
+ int x = offset;
+ int h = lastHeight;
+ int w = accepter->sizeHint().width() + extra;
+ int y = (mySize.height()-h)/2;
+ accepter->setGeometry( x, y, w, h );
+ }
+ MultiContainerWidget::paintEvent( e );
+}
+
+void ConcWidget::mousePressEvent ( QMouseEvent* event )
+{
+ if ( event->button() == RightButton ) {
+ _editorWindow->showRMBMenu( _editorWindow->hasSelection() );
+ }
+ else {
+ RegExpWidget::mousePressEvent( event );
+ }
+}
+
+
+
+void ConcWidget::sizeAccepter( DragAccepter* accepter, int height, int totHeight )
+{
+ if (accepter->height() != height ) {
+ accepter->resize( accepter->width(), height );
+ }
+
+ if (accepter->y() != (totHeight - height)/2) {
+ accepter->move( accepter->x(), (totHeight - height)/2 );
+ }
+}
+
+RegExp* ConcWidget::regExp() const
+{
+ QPtrListIterator<RegExpWidget> it( _children );
+ ++it; // start with the second element.
+
+ if ( _children.count() == 3 ) {
+ // Exactly one child (and two drag accepters)
+ return (*it)->regExp();
+ }
+ else {
+ ConcRegExp *regexp = new ConcRegExp( isSelected() );
+
+ for ( ; *it; it+=2 ) {
+ regexp->addRegExp( (*it)->regExp() );
+ }
+ return regexp;
+ }
+}
+
+bool ConcWidget::updateSelection(bool parentSelected)
+{
+ bool isSel = _isSelected;
+ bool changed = MultiContainerWidget::updateSelection( parentSelected );
+
+ _maxSelectedHeight = 0;
+
+ QPtrListIterator<RegExpWidget> it(_children);
+ ++it; // Skip past the first DragAccepter
+ for ( ; *it; it +=2 ) {
+ if ( (*it)->isSelected() ) {
+ _maxSelectedHeight = QMAX( _maxSelectedHeight, (*it)->sizeHint().height() );
+ }
+ }
+
+ changed = changed || isSel != _isSelected;
+ if ( changed ) {
+ repaint();
+ }
+
+ return changed;
+}
+
+void ConcWidget::getSelectionIndexes( int* start, int* end )
+{
+ *start = -1;
+ *end = -1;
+
+ // Start with element at index 1, and skip every second element, as we
+ // know they are dragAccepters.
+ for ( unsigned int index = 1; index< _children.count(); index += 2 ) {
+ RegExpWidget* child = _children.at(index);
+
+ if ( child->isSelected() ) {
+ // The child is selected at topmost level.
+ if ( *start == -1 ) {
+ *start = index;
+ }
+ }
+ else if ( *start != -1 ) {
+ // Found the end of the selection.
+ *end = index -2;
+ break;
+ }
+ }
+
+ if ( *start != -1 && *end == -1 )
+ *end = _children.count() -2;
+}
+
+void ConcWidget::applyRegExpToSelection( RegExpType type )
+{
+ int start, end;
+ getSelectionIndexes( &start, &end );
+
+ if ( start == -1 ) {
+ // No item selected at top level
+
+ QPtrListIterator<RegExpWidget> it(_children);
+ ++it; // Skip past the first DragAccepter
+ for ( ; *it ; it += 2 ) {
+ if ( (*it)->hasSelection() ) {
+ (*it)->applyRegExpToSelection( type );
+ break;
+ }
+ }
+ }
+ else {
+ // Apply RegExp to selection.
+ RegExpWidget* newElm = WidgetFactory::createWidget( _editorWindow, this, type );
+
+ if ( newElm ) {
+ ConcWidget* subSequence = new ConcWidget(_editorWindow, this, start, end);
+ newElm->setConcChild( subSequence );
+
+
+ subSequence->resize(0,0); // see note (1)
+ subSequence->reparent( newElm, QPoint(0,0), false);
+ _children.insert( start, newElm );
+ newElm->show();
+ }
+ }
+}
+
+bool ConcWidget::isSelected() const
+{
+ // A ConcWidget should be considered selected when all its elements has been selected
+ // otherwise empty ConcWidgets may be left behind when for example selection is deleted.
+ bool allSelected = true;
+ QPtrListIterator<RegExpWidget> it(_children);
+ ++it; // Skip past first DragAccepter.
+ for ( ; *it && allSelected; it += 2 ) {
+ allSelected = allSelected && (*it)->isSelected();
+ }
+
+ return allSelected;
+}
+
+RegExp* ConcWidget::selection() const
+{
+ if ( isSelected() )
+ return regExp();
+
+ bool foundAny = false;
+ bool foundMoreThanOne = false;
+ RegExp* regexp = 0;
+
+ QPtrListIterator<RegExpWidget> it(_children);
+ ++it; // Skip past the first DragAccepter
+ for ( ; (*it) ; it += 2 ) {
+ if ( (*it)->hasSelection() ) {
+ if (!foundAny) {
+ regexp = (*it)->selection();
+ foundAny = true;
+ }
+ else if ( !foundMoreThanOne ) {
+ ConcRegExp* reg = new ConcRegExp( isSelected() );
+ reg->addRegExp( regexp );
+ reg->addRegExp( (*it)->selection() );
+ regexp = reg;
+ foundMoreThanOne = true;
+ }
+ else {
+ dynamic_cast<ConcRegExp*>(regexp)->addRegExp( (*it)->selection() );
+ }
+ }
+ }
+
+ Q_ASSERT( foundAny );
+ return regexp;
+}
+
+void ConcWidget::addNewConcChild(DragAccepter *accepter, ConcWidget *other)
+{
+ for ( unsigned int i=0; i<_children.count(); i+= 2 ) {
+ RegExpWidget *ch = _children.at( i );
+ if ( ch == accepter ) {
+ // Move all the element from the `child' ConcWidget to this one.
+ // Do not copy the first one as this is a dragAccepter, and we place the widgets
+ // after this drag accepter.
+ // We must take them in pairs to avoid breaking the invariant for paintEvent,
+ // namely that every second element is a dragAccepter
+ for ( unsigned int j = other->_children.count()-1; j > 0 ; j-=2 ) {
+ RegExpWidget* newChildA = other->_children.take(j);
+ newChildA->reparent( this, QPoint(0,0), false);
+ _children.insert( i+1, newChildA );
+ RegExpWidget* newChildB = other->_children.take(j-1);
+ newChildB->reparent( this, QPoint(0,0), false);
+ _children.insert( i+1, newChildB );
+ newChildA->show();
+ newChildB->show();
+ }
+ delete other;
+ return;
+ }
+ }
+ qFatal("accepter not found");
+}
+
+bool ConcWidget::validateSelection() const
+{
+ bool cont = true;
+ QPtrListIterator<RegExpWidget> it(_children);
+ ++it; // skip past the DragAccepter.
+ for ( ; *it && cont; it += 2 ) {
+ cont = (*it)->validateSelection();
+ }
+ return cont;
+}
diff --git a/kregexpeditor/concwidget.h b/kregexpeditor/concwidget.h
new file mode 100644
index 0000000..6101ed2
--- /dev/null
+++ b/kregexpeditor/concwidget.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __concwidget
+#define __concwidget
+
+#include "multicontainerwidget.h"
+class ConcRegExp;
+
+/**
+ RegExp widget which can have several sub widget inside it.
+ This widget is invisible to the user, but act as a container around
+ other RegExp widgets
+ @internal
+*/
+class ConcWidget :public MultiContainerWidget
+{
+public:
+ ConcWidget(RegExpEditorWindow* editorWindow, QWidget *parent,
+ const char *name = 0);
+ ConcWidget(RegExpEditorWindow* editorWindow, RegExpWidget *child,
+ QWidget *parent, const char *name=0);
+ ConcWidget( RegExpEditorWindow* editorWindow, ConcWidget* origConc,
+ unsigned int start, unsigned int end);
+ ConcWidget( ConcRegExp* regexp, RegExpEditorWindow* editorWindow,
+ QWidget* parent, const char* name = 0);
+ void init();
+
+ virtual QSize sizeHint() const;
+ virtual RegExp* regExp() const;
+ virtual bool updateSelection(bool parentSelected);
+ virtual bool isSelected() const;
+
+ virtual void applyRegExpToSelection( RegExpType type );
+ virtual RegExpType type() const { return CONC; }
+ virtual RegExp* selection() const;
+ virtual void addNewConcChild(DragAccepter *accepter, ConcWidget *child);
+ virtual bool validateSelection() const;
+ virtual bool acceptWidgetInsert( RegExpType ) const { return false; }
+ virtual bool acceptWidgetPaste() const { return false; }
+ bool hasAnyChildren() { return _children.count() > 1; }
+
+protected:
+ virtual void paintEvent( QPaintEvent *e );
+ virtual void mousePressEvent ( QMouseEvent* event );
+ void sizeAccepter( DragAccepter* accepter, int height, int totHeight );
+ void getSelectionIndexes( int* start, int* end );
+ virtual void dragEnterEvent(QDragEnterEvent* event) { event->accept( false ); }
+
+private:
+ int _maxSelectedHeight;
+};
+
+
+#endif // __concwidget
diff --git a/kregexpeditor/dcbutton.cpp b/kregexpeditor/dcbutton.cpp
new file mode 100644
index 0000000..b5bdcf8
--- /dev/null
+++ b/kregexpeditor/dcbutton.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include "dcbutton.moc"
+#endif
+
+#include "dcbutton.h"
+
+DoubleClickButton::DoubleClickButton( QPixmap pixmap, QWidget* parent, const char* name )
+ : QToolButton( parent, name ? name : "DoubleClickButton" )
+{
+ setPixmap( pixmap );
+}
+
+void DoubleClickButton::mouseDoubleClickEvent( QMouseEvent* )
+{
+ emit doubleClicked();
+}
+
+
diff --git a/kregexpeditor/dcbutton.h b/kregexpeditor/dcbutton.h
new file mode 100644
index 0000000..78a18a3
--- /dev/null
+++ b/kregexpeditor/dcbutton.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef dcbutton
+#define dcbutton
+
+#include <qtoolbutton.h>
+class QMouseEvent;
+
+/**
+ QToolButton extended to emit a signal on double click.
+ @internal
+*/
+class DoubleClickButton :public QToolButton
+{
+Q_OBJECT
+
+public:
+ DoubleClickButton( QPixmap pix, QWidget* parent, const char* name = 0);
+
+protected:
+ virtual void mouseDoubleClickEvent ( QMouseEvent * );
+
+signals:
+ void doubleClicked();
+};
+
+#endif // dcbutton
diff --git a/kregexpeditor/dotregexp.cpp b/kregexpeditor/dotregexp.cpp
new file mode 100644
index 0000000..3d375be
--- /dev/null
+++ b/kregexpeditor/dotregexp.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "dotregexp.h"
+
+DotRegExp::DotRegExp( bool selected ) :RegExp( selected )
+{
+}
+
+bool DotRegExp::check( ErrorMap&, bool, bool )
+{
+ return false;
+}
+
+QDomNode DotRegExp::toXml( QDomDocument* doc ) const
+{
+ return doc->createElement( QString::fromLocal8Bit("AnyChar") );
+}
+
+bool DotRegExp::load( QDomElement /* top */, const QString& /*version*/ )
+{
+ // Nothing to do
+ return true;
+}
+
diff --git a/kregexpeditor/dotregexp.h b/kregexpeditor/dotregexp.h
new file mode 100644
index 0000000..b46cffb
--- /dev/null
+++ b/kregexpeditor/dotregexp.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef DOTREGEXP_H
+#define DOTREGEXP_H
+
+#include "regexp.h"
+
+/**
+ Abstract syntax node for "the dot" regular expression (i.e. any characters)
+ @internal
+*/
+class DotRegExp :public RegExp
+{
+public:
+
+ DotRegExp( bool selected );
+
+ virtual bool check( ErrorMap&, bool first, bool last );
+ virtual int precedence() const { return 4;}
+ virtual QDomNode toXml( QDomDocument* doc ) const;
+ virtual bool load( QDomElement, const QString& version );
+ virtual RegExpType type() const { return DOT;}
+};
+
+#endif // DOTREGEXP_H
+
diff --git a/kregexpeditor/drag.cpp b/kregexpeditor/drag.cpp
new file mode 100644
index 0000000..11ecc63
--- /dev/null
+++ b/kregexpeditor/drag.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "drag.h"
+#include "regexp.h"
+#include "regexpconverter.h"
+#include "widgetfactory.h"
+
+RegExpWidgetDrag::RegExpWidgetDrag( RegExp* regexp, QWidget* dragSource )
+ : QDragObject( dragSource ), _regexp( regexp->clone() )
+{
+}
+
+RegExpWidgetDrag::~RegExpWidgetDrag()
+{
+ delete _regexp;
+}
+
+
+bool RegExpWidgetDrag::canDecode( QDragMoveEvent* event )
+{
+ return event->provides( "KRegExpEditor/widgetdrag" );
+}
+
+RegExpWidget* RegExpWidgetDrag::decode(QDropEvent* event, RegExpEditorWindow* window,
+ QWidget* parent)
+{
+ QByteArray payload = event->encodedData("KRegExpEditor/widgetdrag" );
+ QTextStream stream( payload, IO_ReadOnly );
+ QString str = stream.read();
+ RegExp* regexp = WidgetFactory::createRegExp( str );
+ RegExpWidget* widget = WidgetFactory::createWidget( regexp, window, parent );
+ delete regexp;
+ return widget;
+}
+
+const char * RegExpWidgetDrag::format ( int i ) const
+{
+ if ( i == 0 )
+ return "KRegExpEditor/widgetdrag";
+ else if ( i == 1 )
+ return "text/plain";
+ else
+ return 0;
+}
+
+QByteArray RegExpWidgetDrag::encodedData ( const char* format ) const
+{
+ QByteArray data;
+ QTextStream stream( data, IO_WriteOnly );
+ if ( QString::fromLocal8Bit( format ).startsWith(QString::fromLocal8Bit( "KRegExpEditor/widgetdrag" ) ) ) {
+ QString xml = _regexp->toXmlString();
+ stream << xml;
+ }
+ else if ( QString::fromLocal8Bit( format ).startsWith(QString::fromLocal8Bit( "text/plain" ) ) ) {
+ stream << RegExpConverter::current()->toStr( _regexp, false );
+ }
+ else {
+ qWarning("Unexpected drag and drop format: %s", format );
+ }
+ return data;
+}
+
diff --git a/kregexpeditor/drag.h b/kregexpeditor/drag.h
new file mode 100644
index 0000000..5a074d1
--- /dev/null
+++ b/kregexpeditor/drag.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef drag_h
+#define drag_h
+
+#include <qdragobject.h>
+
+class RegExp;
+class RegExpWidget;
+class RegExpEditorWindow;
+
+/**
+ Class used for drag and drop in the RegExp widget.
+ @internal
+*/
+class RegExpWidgetDrag :public QDragObject
+{
+public:
+ RegExpWidgetDrag( RegExp* regexp , QWidget* dragSource);
+ ~RegExpWidgetDrag();
+ virtual const char * format ( int i = 0 ) const;
+ virtual QByteArray encodedData ( const char * ) const;
+ static bool canDecode(QDragMoveEvent* event);
+ static RegExpWidget* decode(QDropEvent* event, RegExpEditorWindow* window,
+ QWidget* parent);
+private:
+ RegExp* _regexp;
+};
+
+#endif // drag_h
diff --git a/kregexpeditor/dragaccepter.cpp b/kregexpeditor/dragaccepter.cpp
new file mode 100644
index 0000000..0198e58
--- /dev/null
+++ b/kregexpeditor/dragaccepter.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "dragaccepter.h"
+#include "concwidget.h"
+
+#include <qpainter.h>
+
+DragAccepter::DragAccepter(RegExpEditorWindow* editorWindow, RegExpWidget *parent,
+ const char *name)
+ : RegExpWidget(editorWindow, parent, name == 0 ? "dragaccepter" : name ),
+ _drawLine( false )
+{
+ setAcceptDrops(TRUE);
+}
+
+QSize DragAccepter::sizeHint() const
+{
+ return QSize(10,10);
+}
+
+void DragAccepter::paintEvent(QPaintEvent *e)
+{
+ QPainter painter(this);
+ drawPossibleSelection( painter, size() );
+
+ if ( _drawLine )
+ painter.drawLine( 0, height()/2, width(), height()/2 );
+
+ RegExpWidget::paintEvent(e);
+}
+
+void DragAccepter::mousePressEvent ( QMouseEvent* event )
+{
+ if ( event->button() == RightButton ) {
+ _editorWindow->showRMBMenu( _editorWindow->hasSelection() );
+ }
+ else {
+ RegExpWidget::mousePressEvent( event );
+ }
+}
+
+void DragAccepter::mouseReleaseEvent( QMouseEvent* event )
+{
+ if ( _editorWindow->isPasteing() && event->button() == LeftButton ) {
+ RegExp* regexp = _editorWindow->pasteData();
+
+ RegExpWidget *newElm = WidgetFactory::createWidget( regexp, _editorWindow, 0 );
+ if ( newElm ) {
+ ConcWidget* elm;
+ if (! (elm = dynamic_cast<ConcWidget*>( newElm ) ) ) {
+ elm = new ConcWidget( _editorWindow, newElm, 0 );
+ }
+
+ Q_ASSERT( elm );
+
+ RegExpWidget *w = dynamic_cast<RegExpWidget*>(parent());
+ if (w)
+ w->addNewConcChild(this, elm);
+ _editorWindow->updateContent( this );
+ _editorWindow->clearSelection( true );
+ }
+ }
+ else if ( _editorWindow->isInserting() && event->button() == LeftButton ) {
+ if ( WidgetFactory::isContainer( _editorWindow->insertType() ) &&
+ _editorWindow->pointSelected( mapToGlobal( event->pos() ) ) ) {
+ RegExpWidget::mouseReleaseEvent( event );
+ }
+ else {
+ RegExpWidget *child = WidgetFactory::createWidget( _editorWindow,
+ dynamic_cast<QWidget*>(parent()),
+ _editorWindow->insertType() );
+ if ( child ) {
+ RegExpWidget *w = dynamic_cast<RegExpWidget*>(parent());
+ if (w)
+ w->addNewChild(this, child);
+ _editorWindow->updateContent( child );
+ child->setFocus();
+ _editorWindow->clearSelection( true );
+ }
+ }
+ }
+ _editorWindow->slotEndActions();
+}
+
+
+void DragAccepter::dragEnterEvent(QDragEnterEvent *event)
+{
+ bool selfDrag = ( event->source() && event->source()->topLevelWidget() == topLevelWidget() && _isSelected );
+ event->accept(RegExpWidgetDrag::canDecode( event ) && !selfDrag );
+}
+
+void DragAccepter::dropEvent(QDropEvent *event)
+{
+ // The widget will be reparent afterward or part of it will, so no need to give
+ // it a parent here.
+ RegExpWidget *newElm = RegExpWidgetDrag::decode( event, _editorWindow, 0 );
+ ConcWidget* elm;
+ if ( !(elm = dynamic_cast<ConcWidget*>( newElm ) ) ) {
+ elm = new ConcWidget( _editorWindow, newElm, 0 );
+ }
+
+ Q_ASSERT( elm );
+
+ RegExpWidget *rew = dynamic_cast<RegExpWidget*>(parent());
+ if (rew)
+ rew->addNewConcChild(this, elm);
+ QWidget *w = dynamic_cast<QWidget*>(parent());
+ if (w)
+ w->update();
+ _editorWindow->updateContent( this );
+
+ bool selfDrag = ( event->source() && event->source()->topLevelWidget() == topLevelWidget() );
+ if ( ! selfDrag )
+ _editorWindow->clearSelection( true );
+ else {
+ // selection should not be cleared here, since we might want to delete it.
+ }
+ event->accept();
+}
+
+RegExp* DragAccepter::regExp() const
+{
+ return 0;
+}
diff --git a/kregexpeditor/dragaccepter.h b/kregexpeditor/dragaccepter.h
new file mode 100644
index 0000000..48af09f
--- /dev/null
+++ b/kregexpeditor/dragaccepter.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __dragaccepter
+#define __dragaccepter
+
+#include "regexpwidget.h"
+class MultiContainerWidget;
+
+/**
+ RegExp widget representing a "spot" in which new RegExp widgets can be inserted.
+ @internal
+*/
+class DragAccepter :public RegExpWidget
+{
+ friend class MultiContainerWidget;
+
+public:
+ DragAccepter(RegExpEditorWindow* editorWindow, RegExpWidget *parent,
+ const char *name = 0);
+ QSize sizeHint() const;
+ virtual RegExp* regExp() const;
+ virtual RegExpType type() const { return DRAGACCEPTER; }
+ void setDrawLine( bool drawLine ) { _drawLine = drawLine; }
+
+protected:
+ virtual void mousePressEvent ( QMouseEvent* event );
+ virtual void mouseReleaseEvent( QMouseEvent* event );
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void dropEvent(QDropEvent *event);
+ virtual void paintEvent(QPaintEvent *);
+ virtual bool acceptWidgetInsert( RegExpType ) const { return true; }
+ virtual bool acceptWidgetPaste() const { return true; }
+
+private:
+ bool _drawLine;
+};
+
+#endif // __dragaccepter
diff --git a/kregexpeditor/editorwindow.cpp b/kregexpeditor/editorwindow.cpp
new file mode 100644
index 0000000..e8c4ac8
--- /dev/null
+++ b/kregexpeditor/editorwindow.cpp
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifdef QT_ONLY
+ #include "compat.h"
+ #include "images.h"
+#else
+ #include <klocale.h>
+ #include <kmessagebox.h>
+// #include <kfiledialog.h>
+ #include <kstandarddirs.h>
+ #include <kiconloader.h>
+ #include "editorwindow.moc"
+ #include <klineeditdlg.h>
+#endif
+
+#include "editorwindow.h"
+#include "concwidget.h"
+#include <qlayout.h>
+#include <qpainter.h>
+#include <qaccel.h>
+#include <qcursor.h>
+#include <qclipboard.h>
+#include <qpopupmenu.h>
+#include "regexp.h"
+#include "userdefinedregexps.h"
+#include <qfileinfo.h>
+
+RegExpEditorWindow::RegExpEditorWindow( QWidget *parent, const char *name)
+ : QWidget(parent, name, Qt::WPaintUnclipped)
+{
+ _top = new ConcWidget(this, this);
+ _layout = new QHBoxLayout( this);
+ _layout->addWidget(_top);
+ _top->setToplevel();
+ _undrawSelection = false;
+ _menu = 0;
+ _insertInAction = false;
+ _pasteInAction = false;
+ _pasteData = 0;
+
+ QAccel* accel = new QAccel( this );
+ accel->connectItem( accel->insertItem( CTRL+Key_C ), this, SLOT( slotCopy() ) );
+ accel->connectItem( accel->insertItem( CTRL+Key_X ), this, SLOT( slotCut() ) );
+ accel->connectItem( accel->insertItem( Key_Delete ), this, SLOT( slotCut() ) );
+ accel->connectItem( accel->insertItem( Key_BackSpace ), this, SLOT( slotCut() ) );
+ accel->connectItem( accel->insertItem( CTRL+Key_V ), this, SLOT( slotStartPasteAction() ) );
+ accel->connectItem( accel->insertItem( Key_Escape ), this, SLOT( slotEndActions() ) );
+ accel->connectItem( accel->insertItem( CTRL+Key_S ), this, SLOT( slotSave() ) );
+
+ connect( this, SIGNAL( change() ), this, SLOT( emitVerifyRegExp() ) );
+}
+
+RegExp* RegExpEditorWindow::regExp() const
+{
+ return _top->regExp();
+}
+
+void RegExpEditorWindow::mousePressEvent ( QMouseEvent* event )
+{
+ setFocus();
+ updateContent( 0 );
+
+ _start = event->pos();
+ _lastPoint = QPoint(0,0);
+
+ if ( pointSelected( event->globalPos() ) ) {
+ _isDndOperation = true;
+ }
+ else {
+ _isDndOperation = false;
+ _selection = QRect();
+ _top->updateSelection( false );
+
+ QWidget::mousePressEvent( event );
+ }
+ grabMouse();
+}
+
+bool RegExpEditorWindow::pointSelected( QPoint p ) const
+{
+ QRect rect = _top->selectionRect();
+ return rect.contains(p);
+}
+
+void RegExpEditorWindow::mouseMoveEvent ( QMouseEvent* event )
+{
+ if ( _isDndOperation ) {
+ if ( ( _start - event->pos() ).manhattanLength() > QApplication::startDragDistance() ) {
+ RegExp* regexp = _top->selection();
+ if ( !regexp )
+ return;
+ QDragObject *d = new RegExpWidgetDrag( regexp, this );
+ delete regexp;
+
+ bool del = d->drag();
+ if ( del )
+ slotDeleteSelection();
+ else {
+ clearSelection( true );
+ }
+ releaseMouse();
+ emit change();
+ emit canSave( _top->hasAnyChildren() );
+ }
+ }
+ else {
+ QPainter p( this );
+ p.setRasterOp( Qt::NotROP );
+ p.setPen( Qt::DotLine );
+
+ // remove last selection rectangle
+ if ( ! _lastPoint.isNull() && _undrawSelection ) {
+ p.drawRect(QRect(_start, _lastPoint));
+ }
+
+ // Note this line must come after the old rect has been removed
+ // and before the new one is draw otherwise the update event which this
+ // line invokes, will remove a line, which later will be drawn instead of
+ // removed during NotROP.
+ _top->updateSelection( false );
+ emit scrolling( event->pos() );
+
+ p.drawRect(QRect(_start, event->pos()));
+ _undrawSelection = true;
+ _lastPoint = event->pos();
+
+ _selection = QRect(mapToGlobal(_start), mapToGlobal(_lastPoint)).normalize();
+ }
+}
+
+void RegExpEditorWindow::mouseReleaseEvent( QMouseEvent *event)
+{
+ releaseMouse();
+ QWidget::mouseReleaseEvent( event);
+
+ // remove last selection rectangle
+ QPainter p( this );
+ p.setRasterOp( Qt::NotROP );
+ p.setPen( Qt::DotLine );
+ if ( ! _lastPoint.isNull() ) {
+ p.drawRect(QRect(_start, _lastPoint));
+ }
+ _top->validateSelection();
+ _top->updateAll();
+ emit anythingSelected( hasSelection() );
+ if ( hasSelection() ) {
+ emit verifyRegExp();
+ }
+}
+
+bool RegExpEditorWindow::selectionOverlap( QPoint pos, QSize size ) const
+{
+ QRect child(pos, size);
+
+ return (_selection.intersects(child) && ! child.contains(_selection));
+}
+
+bool RegExpEditorWindow::hasSelection() const
+{
+ return _top->hasSelection();
+}
+
+void RegExpEditorWindow::clearSelection( bool update )
+{
+ _top->clearSelection();
+ if ( update )
+ _top->updateAll();
+ emit anythingSelected(false);
+}
+
+void RegExpEditorWindow::slotInsertRegExp( RegExpType type )
+{
+ _insertInAction = true;
+ _insertTp = type;
+
+ updateCursorUnderPoint();
+ setFocus();
+}
+
+void RegExpEditorWindow::slotInsertRegExp( RegExp* regexp )
+{
+ if ( _pasteData )
+ delete _pasteData;
+
+ _pasteData = regexp->clone();
+ _pasteInAction = true;
+ updateCursorUnderPoint();
+ setFocus();
+}
+
+void RegExpEditorWindow::slotDoSelect()
+{
+ _pasteInAction = false;
+ _insertInAction = false;
+
+ // I need to update the cursor recursively, as a repaint may not have been issued yet
+ // when this method is invoked. This means that when the repaint comes, the cursor may
+ // move to an other widget.
+ _top->updateCursorRecursively();
+}
+
+void RegExpEditorWindow::slotDeleteSelection()
+{
+ if ( ! hasSelection() ) {
+ KMessageBox::information(this, i18n( "There is no selection."), i18n("Missing Selection") );
+ }
+ else {
+ _top->deleteSelection();
+ }
+ updateContent( 0 );
+}
+
+void RegExpEditorWindow::updateContent( QWidget* focusChild)
+{
+ QPoint p(0,0);
+ if ( focusChild )
+ p = focusChild->mapTo( this, QPoint(0,0) );
+
+ _top->update();
+ emit contentChanged( p );
+}
+
+QSize RegExpEditorWindow::sizeHint() const
+{
+ return _top->sizeHint();
+}
+
+void RegExpEditorWindow::paintEvent( QPaintEvent* event )
+{
+ QWidget::paintEvent( event );
+ _undrawSelection = false;
+}
+
+void RegExpEditorWindow::slotCut()
+{
+ cut( QCursor::pos() );
+ emit change();
+ emit canSave( _top->hasAnyChildren() );
+}
+
+void RegExpEditorWindow::cut( QPoint pos )
+{
+ cutCopyAux( pos );
+ slotDeleteSelection();
+}
+
+void RegExpEditorWindow::slotCopy()
+{
+ copy( QCursor::pos() );
+}
+
+void RegExpEditorWindow::copy( QPoint pos )
+{
+ cutCopyAux( pos );
+ clearSelection( true );
+}
+
+
+void RegExpEditorWindow::cutCopyAux( QPoint pos )
+{
+ if ( !hasSelection() ) {
+ RegExpWidget* widget = _top->widgetUnderPoint( pos, true );
+ if ( !widget ) {
+ KMessageBox::information(this, i18n("There is no widget under cursor."), i18n("Invalid Operation") );
+ return;
+ }
+ else {
+ widget->updateSelection( true ); // HACK!
+ }
+ }
+
+ RegExp* regexp = _top->selection();
+ RegExpWidgetDrag *clipboardData = new RegExpWidgetDrag( regexp, this );
+ delete regexp;
+
+ QClipboard* clipboard = qApp->clipboard();
+ clipboard->setData( clipboardData );
+ emit anythingOnClipboard( true );
+ emit canSave( _top->hasAnyChildren() );
+}
+
+
+void RegExpEditorWindow::slotStartPasteAction()
+{
+ QByteArray data = qApp->clipboard()->data()->encodedData( "KRegExpEditor/widgetdrag" );
+ QTextStream stream( data, IO_ReadOnly );
+ QString str = stream.read();
+
+ RegExp* regexp = WidgetFactory::createRegExp( str );
+ if ( regexp )
+ slotInsertRegExp( regexp );
+}
+
+void RegExpEditorWindow::slotEndActions() {
+ emit doneEditing();
+ emit change();
+ emit canSave( _top->hasAnyChildren() );
+}
+
+void RegExpEditorWindow::showRMBMenu( bool enableCutCopy )
+{
+ enum CHOICES { CUT, COPY, PASTE, SAVE, EDIT };
+
+ if ( !_menu ) {
+ _menu = new QPopupMenu( 0 );
+ _menu->insertItem(getIcon(QString::fromLocal8Bit("editcut")),
+ i18n("C&ut"), CUT);
+ _menu->insertItem(getIcon(QString::fromLocal8Bit("editcopy")),
+ i18n("&Copy"), COPY);
+ _menu->insertItem(getIcon(QString::fromLocal8Bit("editpaste")),
+ i18n("&Paste"), PASTE);
+ _menu->insertSeparator();
+ _menu->insertItem(getIcon(QString::fromLocal8Bit("edit")),
+ i18n("&Edit"), EDIT);
+ _menu->insertItem(getIcon(QString::fromLocal8Bit("filesave")),
+ i18n("&Save Regular Expression..."), SAVE);
+ }
+
+ _menu->setItemEnabled( CUT, enableCutCopy );
+ _menu->setItemEnabled( COPY, enableCutCopy );
+
+ if ( ! qApp->clipboard()->data()->provides( "KRegExpEditor/widgetdrag" ) )
+ _menu->setItemEnabled( PASTE, false );
+ else
+ _menu->setItemEnabled( PASTE, true );
+
+ _menu->setItemEnabled( SAVE, _top->hasAnyChildren() );
+
+ RegExpWidget* editWidget = _top->findWidgetToEdit( QCursor::pos() );
+
+ _menu->setItemEnabled( EDIT, editWidget );
+
+ QPoint pos = QCursor::pos();
+ int choice = _menu->exec( pos );
+ switch ( choice ) {
+ case COPY: copy( pos ); break;
+ case CUT: cut( pos ); break;
+ case PASTE: slotStartPasteAction(); break;
+ case SAVE: slotSave(); break;
+ case EDIT: editWidget->edit(); break;
+ }
+ emit change();
+ emit canSave( _top->hasAnyChildren() );
+}
+
+void RegExpEditorWindow::applyRegExpToSelection( RegExpType tp )
+{
+ _top->applyRegExpToSelection( tp );
+}
+
+void RegExpEditorWindow::slotSave()
+{
+ QString dir = WidgetWinItem::path();
+ QString txt;
+
+#ifdef QT_ONLY
+ txt = QInputDialog::getText( tr("Name for regexp"), tr("Enter name:") );
+ if ( txt.isNull() )
+ return;
+#else
+ KLineEditDlg dlg(i18n("Enter name:"), QString::null, this);
+ dlg.setCaption(i18n("Name for Regular Expression"));
+ if (!dlg.exec()) return;
+ txt = dlg.text();
+#endif
+
+ QString fileName = dir + QString::fromLocal8Bit("/") + txt + QString::fromLocal8Bit(".regexp");
+ QFileInfo finfo( fileName );
+ if ( finfo.exists() ) {
+ int answer = KMessageBox::warningContinueCancel( this, i18n("<p>Overwrite named regular expression <b>%1</b></p>").arg(txt), QString::null, i18n("Overwrite"));
+ if ( answer != KMessageBox::Continue )
+ return;
+ }
+
+ QFile file( fileName );
+ if ( ! file.open(IO_WriteOnly) ) {
+ KMessageBox::sorry( this, i18n("Could not open file for writing: %1").arg(fileName) );
+ return;
+ }
+
+ // Convert to XML.
+ RegExp* regexp = _top->regExp();
+ QString xml = regexp->toXmlString();
+ delete regexp;
+
+ QTextStream stream(&file);
+ stream << xml;
+
+ file.close();
+ emit savedRegexp();
+}
+
+
+void RegExpEditorWindow::slotSetRegExp( RegExp* regexp )
+{
+ // I have no clue why the following line is necesarry, but if it is not here
+ // then the editor area is messed up when calling slotSetRegExp before starting the eventloop.
+ qApp->processEvents();
+
+ delete _top;
+ RegExpWidget* widget = WidgetFactory::createWidget( regexp, this, this );
+ if ( ! (_top = dynamic_cast<ConcWidget*>( widget ) ) ) {
+ // It was not a ConcWidget
+ _top = new ConcWidget( this, widget, this );
+ }
+ _top->setToplevel();
+
+ _top->show();
+ _layout->addWidget( _top );
+ clearSelection( true ); // HACK?
+ emit canSave( _top->hasAnyChildren() );
+}
+
+void RegExpEditorWindow::updateCursorUnderPoint()
+{
+ RegExpWidget* widget = _top->widgetUnderPoint( QCursor::pos(), false );
+ if ( widget )
+ widget->updateCursorShape();
+}
+
+void RegExpEditorWindow::emitVerifyRegExp()
+{
+ emit verifyRegExp();
+}
+
+
+QIconSet RegExpEditorWindow::getIcon( const QString& name )
+{
+#ifdef QT_ONLY
+ QPixmap pix;
+ pix.convertFromImage( qembed_findImage( name ) );
+ return pix;
+#else
+ return SmallIconSet( name );
+#endif
+}
+
diff --git a/kregexpeditor/editorwindow.h b/kregexpeditor/editorwindow.h
new file mode 100644
index 0000000..e925c59
--- /dev/null
+++ b/kregexpeditor/editorwindow.h
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef editorwindow_h
+#define editorwindow_h
+
+#include "drag.h"
+#include "widgetfactory.h"
+#include <qmultilineedit.h>
+#include <qlabel.h>
+#include <qiconset.h>
+class RegExp;
+class RegExpWidget;
+class QHBoxLayout;
+
+/** Widget representing the editor window of a regular expression editor.
+
+ @internal
+ This widget represent the editor part (That is the location where the
+ regexp widgets are located).
+
+ Furthermore, it also responsible for:
+ @li Widget traversal operations (see e.g. @ref hasSelection, @ref
+ clearSelection, and @ref applyRegExpToSelection ).
+ @li Containing global information for regexp editing. (See @ref
+ _pasteData and @ref _insertInAction )
+
+ All subclasses of @ref RegExpWidget contains a pointer to the @ref
+ RegExpEditorWindow which the widget is a child of. They use this
+ pointer to start operations like rubber band selection, cut/paste etc.
+*/
+class RegExpEditorWindow :public QWidget
+{
+ Q_OBJECT
+
+public:
+ RegExpEditorWindow(QWidget *parent, const char *name = 0);
+
+ /**
+ Returns an object which represent the regular expression "drawn" in
+ the editor window. This object is capable of generating a textual
+ representation of the regexp (see @ref RegExp::emacs, and @ref
+ RegExp::perl etc)
+ */
+ RegExp* regExp() const;
+
+ /**
+ This method returns true if the rectangle starting at `globalPos' with
+ size `size' overlaps the rubber-band rectangle.
+ Note this method is only valid while doing rubber-band
+ selection. Afterwards, use @ref pointSelected instead.
+ */
+ bool selectionOverlap( QPoint globalPos, QSize size ) const;
+
+ /**
+ returns true if `pos' lays on top of a widget that is selected.
+ */
+ bool pointSelected( QPoint pos ) const;
+
+ /**
+ returns true if the editor has a selection.
+ */
+ bool hasSelection() const;
+
+ /**
+ clears the selection, and if `update', invokes update on all the
+ widgets
+ */
+ void clearSelection( bool update );
+
+ /**
+ invoked update on the top widget, and ensures that `focusChild' is
+ visible. It's valid for `focusChild' to be 0.
+ */
+ void updateContent(QWidget* focusChild);
+
+ RegExp* pasteData() { return _pasteData; }
+ bool isPasteing() const { return _pasteInAction; }
+ bool isInserting() const { return _insertInAction; }
+
+ /**
+ Returns the type currently being inserted.
+ This is the type, which was given to @ref slotInsertRegExp
+ */
+ RegExpType insertType() const { return _insertTp; }
+
+ /**
+ Create a regexp widget, so that it wraps around the current selected
+ regexp.
+ */
+ void applyRegExpToSelection( RegExpType tp );
+
+ /**
+ Pops up the RMB menu, which contains cut, copy, past, ...
+ */
+ void showRMBMenu( bool enableCutCopy );
+
+ virtual QSize sizeHint() const;
+
+public slots:
+
+ /**
+ Set the editor window to the regular expression given as argument
+ */
+ void slotSetRegExp( RegExp* regexp );
+
+ /**
+ Change editing mode to insertion. This means that the cursor will
+ change to a cross (where ever inserting of the `type' is allowed),
+ and the next mouse press in allowed places will result in that a
+ regular expression of type `type' will be inserted there.
+
+ Note this method do not do the actual insertion.
+
+ This method is used when the user presses one of the buttons to the
+ right of the editor window.
+ */
+ void slotInsertRegExp( RegExpType type );
+
+ /**
+ Change editing state to selection.
+ */
+ void slotDoSelect();
+
+ /**
+ Like @ref slotInsertRegExp above. This time, however, data will be
+ submitted in as a RegExp pointer.
+
+ Note this method do not do the actual insertion.
+
+ This method is called when the user pastes data (using the RPM menu),
+ or when a regular expression is loaded from file.
+ */
+ void slotInsertRegExp( RegExp* regexp );
+
+ /**
+ see @ref RegExpWidget::deleteSelection
+ */
+ void slotDeleteSelection();
+
+ /**
+ This method is invoked when the user selects paste in the RMB menu. It
+ will change the mouse cursor etc. as described in @ref
+ slotInsertRegExp
+ */
+ void slotStartPasteAction();
+
+ /**
+ Ends an insert or paste action. This involves changing cursor back to
+ normal cursor.
+ */
+ void slotEndActions();
+
+ void emitChange() { emit change(); }
+
+ void updateCursorUnderPoint();
+
+ void slotCut();
+ void slotCopy();
+ void slotSave();
+
+signals:
+ /**
+ This signal is emitted whenever the content of the editor window is
+ changed.
+
+ If focusPoint is non-null then this point should be made visible
+ */
+ void contentChanged( QPoint focusPoint );
+
+ /**
+ This signal is emitted whenever mouse is being dragged in the editor
+ window. `focusPoint' is the mouse' current position.
+ */
+ void scrolling( QPoint focusPoint );
+
+ /**
+ see @ref RegExpScrolledEditorWindow::doneEditing
+ */
+ void doneEditing();
+
+ /**
+ see @ref RegExpScrolledEditorWindow::change
+ */
+ void change();
+
+ /**
+ see @ref RegExpScrolledEditorWindow::savedRegexp
+ */
+ void savedRegexp();
+
+ /**
+ see @ref RegExpScrolledEditorWindow::verifyRegExp
+ */
+ void verifyRegExp();
+
+ void anythingSelected( bool );
+ void anythingOnClipboard( bool );
+ void canSave( bool );
+
+
+protected:
+ virtual void mousePressEvent ( QMouseEvent* event );
+ virtual void mouseMoveEvent ( QMouseEvent* event );
+ virtual void mouseReleaseEvent( QMouseEvent *event);
+ virtual void paintEvent( QPaintEvent* event );
+
+protected slots:
+ virtual void emitVerifyRegExp();
+
+private:
+ void cutCopyAux( QPoint pos );
+ void copy( QPoint pos );
+ void cut( QPoint pos );
+
+private:
+ /** This points to the top @ref RegExpWidget in the editor window. */
+ ConcWidget *_top;
+
+ /** This points to the layout manager for the editor window */
+ QHBoxLayout* _layout;
+
+ /** Start point and last point draw. Used when doing rubber band selection */
+ QPoint _start, _lastPoint;
+
+ /** The area which the rubber band selection is over */
+ QRect _selection;
+
+ /**
+ True when a rubber band selection rectangle is drawn, and need to be
+ un-drawn before next rubber band selection rectangle may be drawn.
+ */
+ bool _undrawSelection;
+
+ /** true when a paste action is in action (see @ref isPasteing ). */
+ bool _pasteInAction;
+
+ /** true when an insert action is in action (see @ref isInserting ). */
+ bool _insertInAction;
+
+ /** The type being inserted (see @ref insertType ) */
+ RegExpType _insertTp;
+
+ /** The data being inserted (see @ref pasteData ) */
+ RegExp* _pasteData;
+
+ /** Popup menu used for RMB */
+ QPopupMenu* _menu;
+
+ QIconSet getIcon( const QString& name );
+
+ bool _isDndOperation;
+};
+
+#endif // editorwindow_h
diff --git a/kregexpeditor/emacsregexpconverter.cpp b/kregexpeditor/emacsregexpconverter.cpp
new file mode 100644
index 0000000..327d04c
--- /dev/null
+++ b/kregexpeditor/emacsregexpconverter.cpp
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2002-2004 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#include "emacsregexpconverter.h"
+#include "regexp.h"
+#include "altnregexp.h"
+#include "concregexp.h"
+#include "lookaheadregexp.h"
+#include "textrangeregexp.h"
+#include "textregexp.h"
+#include "compoundregexp.h"
+#include "dotregexp.h"
+#include "positionregexp.h"
+#include "repeatregexp.h"
+
+#include <kmessagebox.h>
+#include <klocale.h>
+bool EmacsRegExpConverter::canParse()
+{
+ return false;
+}
+
+QString EmacsRegExpConverter::toString( AltnRegExp* regexp, bool markSelection )
+{
+ QString res;
+
+ bool first = true;
+ RegExpList list = regexp->children();
+ for ( RegExpListIt it(list); *it; ++it ) {
+ if ( !first ) {
+ res += QString::fromLatin1("\\|");
+ }
+ first = false;
+ res += toStr( *it, markSelection );
+ }
+ return res;
+
+}
+
+QString EmacsRegExpConverter::toString( ConcRegExp* regexp, bool markSelection )
+{
+ QString res;
+
+ RegExpList list = regexp->children();
+ for ( RegExpListIt it(list); *it; ++it ) {
+ QString startPar = QString::fromLocal8Bit("");
+ QString endPar = QString::fromLocal8Bit("");
+ if ( (*it)->precedence() < regexp->precedence() ) {
+ startPar = QString::fromLatin1( "\\(" );
+ endPar = QString::fromLatin1( "\\)" );
+ }
+
+ res += startPar + toStr( *it, markSelection ) + endPar;
+ }
+
+ return res;
+
+}
+
+QString EmacsRegExpConverter::toString( LookAheadRegExp* /*regexp*/, bool /*markSelection*/ )
+{
+ static bool haveWarned = false;
+ if ( ! haveWarned ) {
+ KMessageBox::sorry( 0, i18n("Look ahead regular expressions not supported in Emacs style") );
+ haveWarned = true;
+ }
+
+ return QString::null;
+}
+
+QString EmacsRegExpConverter::toString( TextRangeRegExp* regexp, bool /*markSelection*/ )
+{
+ QString txt;
+
+ bool foundCarrot = false;
+ bool foundDash = false;
+ bool foundParenthesis = false;
+
+ // print the single characters, but keep "^" as the very
+ // last element of the characters.
+ QStringList chars = regexp->chars();
+ for (unsigned int i = 0; i< chars.count(); i++) {
+ if ( *chars.at(i) == QChar(']') ) {
+ foundParenthesis = true;
+ }
+ else if ( *chars.at(i) == QChar('-') ) {
+ foundDash = true;
+ }
+ else if ( *chars.at(i) == QChar('^') ) {
+ foundCarrot = true;
+ }
+ else {
+ txt.append( *chars.at(i) );
+ }
+ }
+
+ // Now insert the ranges.
+ QPtrList<StringPair> ranges = regexp->range();
+ for ( QPtrListIterator<StringPair> it(ranges); *it; ++it ) {
+ txt.append((*it)->first()+ QString::fromLatin1("-")+ (*it)->second());
+ }
+
+ // Ok, its time to build each part of the regexp, here comes the rule:
+ // if a ']' is one of the characters, then it must be the first one in the
+ // list (after then opening '[' and eventually negation '^')
+ // Next if a '-' is one of the characters, then it must come
+ // finally if '^' is one of the characters, then it must not be the first
+ // one!
+
+ QString res = QString::fromLatin1("[");
+
+ if ( regexp->negate() )
+ res.append(QString::fromLatin1("^"));
+
+
+ // a ']' must be the first character in teh range.
+ if ( foundParenthesis ) {
+ res.append(QString::fromLatin1("]"));
+ }
+
+ // a '-' must be the first character ( only coming after a ']')
+ if ( foundDash ) {
+ res.append(QString::fromLatin1("-"));
+ }
+
+ res += txt;
+
+ // Insert equivalents to \s,\S,\d,\D,\w, and \W
+ // non-digit, non-space, and non-word is not supported in Emacs style
+ if ( regexp->digit() )
+ res += QString::fromLocal8Bit("0-9");
+ if ( regexp->space() )
+ res += QString::fromLocal8Bit(" ") + QString( QChar( (char) 9 ) ); // Tab char
+ if ( regexp->wordChar() )
+ res += QString::fromLocal8Bit("a-zA-Z");
+
+ if ( foundCarrot ) {
+ res.append( QChar( '^' ) );
+ }
+
+ res.append(QString::fromLatin1("]"));
+
+ return res;
+}
+
+QString EmacsRegExpConverter::toString( CompoundRegExp* regexp, bool markSelection )
+{
+ return toStr( regexp->child(), markSelection );
+}
+
+QString EmacsRegExpConverter::toString( DotRegExp* /*regexp*/, bool /*markSelection*/ )
+{
+ return QString::fromLatin1( "." );
+}
+
+QString EmacsRegExpConverter::toString( PositionRegExp* regexp, bool /*markSelection*/ )
+{
+ static bool haveWarned = false;
+ switch ( regexp->position()) {
+ case PositionRegExp::BEGLINE:
+ return QString::fromLatin1("^");
+ case PositionRegExp::ENDLINE:
+ return QString::fromLatin1("$");
+ case PositionRegExp::WORDBOUNDARY:
+ case PositionRegExp::NONWORDBOUNDARY:
+ if ( ! haveWarned ) {
+ KMessageBox::sorry( 0, i18n( "Word boundary and non word boundary is not supported in Emacs syntax" ) );
+ haveWarned = true;
+ return QString::fromLatin1("");
+ }
+ }
+ return QString::fromLatin1("");
+}
+
+QString EmacsRegExpConverter::toString( RepeatRegExp* regexp, bool markSelection )
+{
+ RegExp* child = regexp->child();
+ QString cText = toStr( child, markSelection );
+ QString startPar;
+ QString endPar;
+
+ if ( child->precedence() < regexp->precedence() ) {
+ startPar = QString::fromLatin1( "\\(" );
+ endPar = QString::fromLatin1( "\\)" );
+ }
+
+ if (regexp->min() == 0 && regexp->max() == -1) {
+ return startPar + cText +endPar + QString::fromLocal8Bit("*");
+ }
+ else if ( regexp->min() == 0 && regexp->max() == 1 ) {
+ return startPar + cText + endPar + QString::fromLocal8Bit("?");
+ }
+ else if ( regexp->min() == 1 && regexp->max() == -1 ) {
+ return startPar + cText + endPar + QString::fromLocal8Bit("+");
+ }
+ else {
+ QString res = QString::fromLatin1("");
+ for ( int i = 0; i < regexp->min(); ++i ) {
+ res += QString::fromLatin1( "\\(" ) + cText + QString::fromLatin1( "\\)" );
+ }
+ if ( regexp->max() != -1 ) {
+ for ( int i = regexp->min(); i < regexp->max(); ++i ) {
+ res += QString::fromLatin1("\\(") + cText + QString::fromLatin1("\\)?");
+ }
+ }
+ else
+ res += QString::fromLatin1("+");
+
+ return res;
+ }
+}
+
+QString EmacsRegExpConverter::toString( TextRegExp* regexp, bool /*markSelection*/ )
+{
+ QValueList<QChar> list;
+ list << QChar('$')
+ << QChar('^')
+ << QChar('.')
+ << QChar('*')
+ << QChar('+')
+ << QChar('?')
+ << QChar('[')
+ << QChar(']')
+ << QChar('\\');
+
+ QString res = escape( regexp->text(), list, QChar('\\') );
+ return res;
+}
+
+QString EmacsRegExpConverter::name()
+{
+ return QString::fromLatin1( "Emacs" );
+}
+
+int EmacsRegExpConverter::features()
+{
+ return WordStart | WordEnd;
+}
diff --git a/kregexpeditor/emacsregexpconverter.h b/kregexpeditor/emacsregexpconverter.h
new file mode 100644
index 0000000..bbc9e94
--- /dev/null
+++ b/kregexpeditor/emacsregexpconverter.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2002-2004 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifndef EMACSREGEXPCONVERTER_H
+#define EMACSREGEXPCONVERTER_H
+
+#include "regexpconverter.h"
+
+class EmacsRegExpConverter :public RegExpConverter
+{
+public:
+ virtual bool canParse();
+ virtual QString name();
+ virtual int features();
+ virtual QString toString( AltnRegExp*, bool markSelection );
+ virtual QString toString( ConcRegExp*, bool markSelection );
+ virtual QString toString( LookAheadRegExp*, bool markSelection );
+ virtual QString toString( TextRangeRegExp*, bool markSelection );
+ virtual QString toString( CompoundRegExp*, bool markSelection );
+ virtual QString toString( DotRegExp*, bool markSelection );
+ virtual QString toString( PositionRegExp*, bool markSelection );
+ virtual QString toString( RepeatRegExp*, bool markSelection );
+ virtual QString toString( TextRegExp*, bool markSelection );
+};
+
+
+#endif /* EMACSREGEXPCONVERTER_H */
+
diff --git a/kregexpeditor/errormap.cpp b/kregexpeditor/errormap.cpp
new file mode 100644
index 0000000..c452ddb
--- /dev/null
+++ b/kregexpeditor/errormap.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <kmessagebox.h>
+ #include <klocale.h>
+#endif
+
+#include "errormap.h"
+
+ErrorMap::ErrorMap() : _prevLineStartError( false ), _prevLineEndError( false ), _prevLookAHeadError( false )
+{
+}
+
+void ErrorMap::start()
+{
+ _lineStartError = false;
+ _lineEndError = false;
+ _lookAHeadError = false;
+}
+
+void ErrorMap::end()
+{
+ _prevLineStartError = _lineStartError;
+ _prevLineEndError = _lineEndError;
+ _prevLookAHeadError = _lookAHeadError;
+}
+
+void ErrorMap::lineStartError()
+{
+ if ( ! _prevLineStartError ) {
+ KMessageBox::information( 0, i18n("Your regular expression is invalid, due to something preceding a 'line start'."),
+ i18n("Regular Expression Error"), QString::fromLatin1("KRegExpEditorLineStartError") );
+ }
+ _lineStartError = true;
+}
+
+void ErrorMap::lineEndError()
+{
+ if ( !_prevLineEndError ) {
+ KMessageBox::information( 0, i18n("Your regular expression is invalid, due to something following a 'line end'."),
+ i18n("Regular Expression Error"), QString::fromLatin1("KRegExpEditorLineEndError") );
+ }
+ _lineEndError = true;
+}
+
+
+void ErrorMap::lookAheadError()
+{
+ if ( !_prevLookAHeadError ) {
+ KMessageBox::information( 0, i18n("Your regular expression is invalid. 'Look Ahead' regular expression must be the last sub expression."),
+ i18n("Regular Expression Error"), QString::fromLatin1("KRegExpEditorLookAHeadError") );
+ }
+ _lookAHeadError = true;
+}
+
diff --git a/kregexpeditor/errormap.h b/kregexpeditor/errormap.h
new file mode 100644
index 0000000..88034dd
--- /dev/null
+++ b/kregexpeditor/errormap.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef ERRORMAP_H
+#define ERRORMAP_H
+
+class ErrorMap
+{
+public:
+ ErrorMap();
+ void start();
+ void end();
+ void lineStartError();
+ void lineEndError();
+ void lookAheadError();
+private:
+ bool _lineStartError, _prevLineStartError;
+ bool _lineEndError, _prevLineEndError;
+ bool _lookAHeadError, _prevLookAHeadError;
+};
+
+#endif
diff --git a/kregexpeditor/extractrc-from-regexp b/kregexpeditor/extractrc-from-regexp
new file mode 100755
index 0000000..70c30ad
--- /dev/null
+++ b/kregexpeditor/extractrc-from-regexp
@@ -0,0 +1,85 @@
+#! /usr/bin/perl
+# This file is a modified version of extractrc, with the only addition that it Title|Description in the textstring regexp.
+#
+# This script extracts messages from designer (.ui) and XMLGIU (.rc) files
+# and writes on standard output (usually redirected to rc.cpp)
+# the equivalent i18n() calls so that xgettext can parse them.
+
+$filename = "";
+@filenames = ();
+
+sub writeoutstring($)
+{
+ print STDOUT "i18n(\"@_[0]\"); // $filename \n";
+}
+
+while (defined ($ARGV[0]))
+{
+ $_ = shift;
+ $filename = $_; # maybe check for options
+
+if (! $filename) {
+ print STDERR "no file to open\n";
+ exit 1;
+}
+
+$string = "";
+$intext = 0;
+$linenr = 0;
+$inskippedprop = 0;
+
+open(FILE, $filename);
+
+READING: while ( <FILE> ) {
+ $linenr++;
+ if ($linenr == 1 && ($_ !~ /^<!DOCTYPE/) && ($_ !~ /^<\?xml/)) {
+ last READING;
+ }
+
+ $string .= "\\n" . $_;
+ chomp($string);
+
+ $textstring = '([tT][eE][xX][tT]|[tT]itle|[dD]escription|string|whatsthis|tooltip)>';
+
+ # The 'database' property contains strings that shouldn't be translated
+ if ($inskippedprop == 0 && ($string =~ /<property name=\"database\"/)) {
+ $inskippedprop = 1;
+ } elsif ($inskippedprop == 1 && ($string =~ /<\/property/)) {
+ $inskippedprop = 0;
+ $string = "";
+ }
+
+ if ($inskippedprop == 0 && $intext == 0) {
+ if ($string =~ /<$textstring/) {
+ $string =~ s/^.*<$textstring//;
+ $intext = 1;
+ $starting_linenr = $linenr;
+ } else {
+ $string = "";
+ }
+ }
+
+ if (($intext == 1) && ($string =~ /<\/$textstring/)) {
+ my $text = $string;
+ $text =~ s/<\/$textstring.*$//;
+ $text =~ s/&lt;/</g;
+ $text =~ s/&gt;/>/g;
+ $text =~ s/&amp;/&/g;
+ $text =~ s/\"/\\\"/g;
+ writeoutstring($text);
+ $string =~ s/^.*<\/$textstring//;
+ $intext = 0;
+ # Text can be multiline in .ui files (possibly), but we warn about it in XMLGUI .rc files.
+ if ($linenr != $starting_linenr && $filename =~ m/\.rc$/) {
+ print STDERR "there is <text> floating $filename\n";
+ }
+ }
+
+}
+
+if ($intext == 1) {
+ print STDERR "parsing error in $filename $linenr\n";
+ exit 1;
+}
+
+}
diff --git a/kregexpeditor/gen_qregexplexer.cpp b/kregexpeditor/gen_qregexplexer.cpp
new file mode 100644
index 0000000..30f2284
--- /dev/null
+++ b/kregexpeditor/gen_qregexplexer.cpp
@@ -0,0 +1,1980 @@
+#define yy_create_buffer qregexp_create_buffer
+#define yy_delete_buffer qregexp_delete_buffer
+#define yy_scan_buffer qregexp_scan_buffer
+#define yy_scan_string qregexp_scan_string
+#define yy_scan_bytes qregexp_scan_bytes
+#define yy_flex_debug qregexp_flex_debug
+#define yy_init_buffer qregexp_init_buffer
+#define yy_flush_buffer qregexp_flush_buffer
+#define yy_load_buffer_state qregexp_load_buffer_state
+#define yy_switch_to_buffer qregexp_switch_to_buffer
+#define yyin qregexpin
+#define yyleng qregexpleng
+#define yylex qregexplex
+#define yyout qregexpout
+#define yyrestart qregexprestart
+#define yytext qregexptext
+
+#line 19 "gen_qregexplexer.cpp"
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * yyless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+
+#define yywrap() 1
+#define YY_SKIP_YYWRAP
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 29
+#define YY_END_OF_BUFFER 30
+static yyconst short int yy_accept[53] =
+ { 0,
+ 0, 0, 30, 28, 29, 13, 18, 19, 21, 23,
+ 12, 22, 28, 28, 14, 28, 20, 0, 0, 25,
+ 0, 27, 27, 26, 2, 4, 6, 8, 9, 1,
+ 3, 5, 7, 27, 0, 0, 24, 17, 15, 16,
+ 25, 11, 26, 10, 0, 11, 10, 11, 10, 11,
+ 10, 0
+ } ;
+
+static yyconst int yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 3, 1, 1, 4, 1, 1, 1, 5,
+ 6, 7, 8, 9, 1, 10, 1, 11, 12, 12,
+ 12, 12, 12, 12, 12, 13, 13, 14, 1, 1,
+ 15, 1, 16, 1, 17, 18, 17, 19, 17, 17,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 20, 1, 1, 1, 21, 1, 1, 1,
+ 22, 23, 24, 25, 1, 1, 26, 27, 17, 28,
+
+ 17, 26, 1, 1, 1, 1, 1, 1, 1, 29,
+ 1, 1, 1, 29, 30, 29, 1, 29, 31, 32,
+ 1, 1, 33, 34, 35, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst int yy_meta[36] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 1, 1, 1, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 2, 2, 2, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst short int yy_base[59] =
+ { 0,
+ 0, 33, 53, 137, 137, 137, 32, 137, 137, 137,
+ 137, 137, 2, 67, 137, 19, 137, 0, 20, 18,
+ 12, 137, 0, 6, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 0, 34, 94, 137, 137, 137, 137,
+ 137, 9, 39, 0, 97, 48, 0, 50, 0, 137,
+ 137, 137, 132, 134, 27, 22, 11, 7
+ } ;
+
+static yyconst short int yy_def[59] =
+ { 0,
+ 53, 53, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 54, 52, 52, 52, 52, 52, 54, 54,
+ 54, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 55, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 56, 52, 52, 57, 52, 58, 52,
+ 52, 0, 52, 52, 52, 52, 52, 52
+ } ;
+
+static yyconst short int yy_nxt[173] =
+ { 0,
+ 52, 5, 38, 6, 7, 8, 9, 10, 51, 11,
+ 42, 42, 49, 39, 40, 12, 43, 43, 43, 46,
+ 46, 13, 14, 47, 15, 20, 21, 35, 44, 36,
+ 36, 36, 16, 17, 5, 20, 6, 7, 8, 9,
+ 10, 41, 11, 41, 45, 45, 45, 18, 12, 43,
+ 43, 43, 52, 37, 13, 14, 52, 15, 48, 48,
+ 50, 50, 52, 52, 52, 16, 17, 22, 37, 22,
+ 22, 22, 22, 22, 22, 22, 22, 23, 24, 24,
+ 22, 22, 22, 22, 25, 26, 27, 28, 22, 22,
+ 22, 22, 29, 30, 31, 29, 32, 33, 34, 22,
+
+ 22, 22, 35, 52, 36, 36, 36, 45, 45, 45,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 37, 52,
+ 52, 37, 4, 4, 19, 19, 3, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52
+ } ;
+
+static yyconst short int yy_chk[173] =
+ { 0,
+ 0, 1, 18, 1, 1, 1, 1, 1, 58, 1,
+ 23, 23, 57, 18, 18, 1, 24, 24, 24, 42,
+ 42, 1, 1, 56, 1, 13, 13, 16, 55, 16,
+ 16, 16, 1, 1, 2, 21, 2, 2, 2, 2,
+ 2, 20, 2, 19, 35, 35, 35, 7, 2, 43,
+ 43, 43, 3, 16, 2, 2, 0, 2, 46, 46,
+ 48, 48, 0, 0, 0, 2, 2, 14, 35, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+
+ 14, 14, 36, 0, 36, 36, 36, 45, 45, 45,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 36, 0,
+ 0, 45, 53, 53, 54, 54, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "qregexpparser.l"
+#define INITIAL 0
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#line 21 "qregexpparser.l"
+ #include <qstring.h>
+ #include "textrangeregexp.h"
+ #include "gen_qregexpparser.hh"
+#ifdef QT_ONLY
+ #include "compat.h"
+#endif
+ void parseRange( char* txt, int* min, int* max );
+ RegExp* parseCharClass( char* match );
+#line 464 "gen_qregexplexer.cpp"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 38 "qregexpparser.l"
+
+#line 617 "gen_qregexplexer.cpp"
+
+ if ( yy_init )
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! yy_current_buffer )
+ yy_current_buffer =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 53 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 137 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+
+do_action: /* This label is used only to access EOF actions. */
+
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yy_hold_char;
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 39 "qregexpparser.l"
+return TOK_PosWordChar;
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 40 "qregexpparser.l"
+return TOK_PosNonWordChar;
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 41 "qregexpparser.l"
+{
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->setDigit( true );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 47 "qregexpparser.l"
+{
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->setNonDigit( true );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 53 "qregexpparser.l"
+{
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->setSpace( true );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 59 "qregexpparser.l"
+{
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->setNonSpace( true );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 65 "qregexpparser.l"
+{
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->setWordChar( true );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 71 "qregexpparser.l"
+{
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->setNonWordChar( true );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 77 "qregexpparser.l"
+{
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->addCharacter( QString::fromLocal8Bit( yytext ) );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 84 "qregexpparser.l"
+{
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->addCharacter( QString::fromLocal8Bit(yytext) );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 90 "qregexpparser.l"
+{
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->addCharacter( QString::fromLocal8Bit(yytext) );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 96 "qregexpparser.l"
+return TOK_Dot;
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 97 "qregexpparser.l"
+return TOK_Dollar;
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 98 "qregexpparser.l"
+return TOK_Carat;
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 99 "qregexpparser.l"
+return TOK_MagicLeftParent;
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 100 "qregexpparser.l"
+return TOK_PosLookAhead;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 101 "qregexpparser.l"
+return TOK_NegLookAhead;
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 102 "qregexpparser.l"
+return TOK_LeftParen;
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 103 "qregexpparser.l"
+return TOK_RightParent;
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 104 "qregexpparser.l"
+return TOK_Bar;
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 105 "qregexpparser.l"
+{ qregexplval.range.min = 0; qregexplval.range.max=-1; return TOK_Quantifier; }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 106 "qregexpparser.l"
+{ qregexplval.range.min = 0; qregexplval.range.max=1; return TOK_Quantifier; }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 107 "qregexpparser.l"
+{ qregexplval.range.min = 1; qregexplval.range.max=-1; return TOK_Quantifier; }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 108 "qregexpparser.l"
+{ parseRange( yytext, &qregexplval.range.min, &qregexplval.range.max ); return TOK_Quantifier; }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 109 "qregexpparser.l"
+{ qregexplval.regexp = parseCharClass(yytext); return TOK_CharClass; }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 110 "qregexpparser.l"
+{ qregexplval.backRef = atoi( yytext+1 ); return TOK_BackRef; }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 111 "qregexpparser.l"
+{ qregexplval.ch = yytext[1]; return TOK_EscapeChar; }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 112 "qregexpparser.l"
+{ qregexplval.ch = yytext[0]; return TOK_Char; }
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 114 "qregexpparser.l"
+ECHO;
+ YY_BREAK
+#line 890 "gen_qregexplexer.cpp"
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between yy_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap() )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+ {
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( yy_current_buffer->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset =
+ (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yy_flex_realloc( (void *) b->yy_ch_buf,
+ b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+
+ for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 53 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+ }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+ {
+ register int yy_is_jam;
+ register char *yy_cp = yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 53 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 52);
+
+ return yy_is_jam ? 0 : yy_current_state;
+ }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+ {
+ register char *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest = &yy_current_buffer->yy_ch_buf[
+ yy_current_buffer->yy_buf_size + 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+ }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+ {
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* This was really a NUL. */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /* fall through */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ return EOF;
+
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+
+ return c;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+ {
+ if ( ! yy_current_buffer )
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+ {
+ if ( yy_current_buffer == new_buffer )
+ return;
+
+ if ( yy_current_buffer )
+ {
+ /* Flush out information for old buffer. */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+ {
+ if ( ! b )
+ return;
+
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yy_flex_free( (void *) b->yy_ch_buf );
+
+ yy_flex_free( (void *) b );
+ }
+
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+#include<unistd.h>
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+ {
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == yy_current_buffer )
+ yy_load_buffer_state();
+ }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+ {
+ int len;
+ for ( len = 0; yy_str[len]; ++len )
+ ;
+
+ return yy_scan_bytes( yy_str, len );
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+ {
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+ {
+ if ( yy_start_stack_ptr >= yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof( int );
+
+ if ( ! yy_start_stack )
+ yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size );
+
+ if ( ! yy_start_stack )
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack" );
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+ }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+ {
+ if ( --yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+ }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+ {
+ return yy_start_stack[yy_start_stack_ptr - 1];
+ }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+ {
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+ }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+ {
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+ {
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+ }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+ {
+ return (void *) malloc( size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+ {
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+ {
+ free( ptr );
+ }
+
+#if YY_MAIN
+int main()
+ {
+ yylex();
+ return 0;
+ }
+#endif
+#line 114 "qregexpparser.l"
+
+
+void setParseData( QString qstr ) {
+ const char* cstr;
+ if ( qstr.isNull() )
+ cstr = "";
+ else
+ cstr = qstr.latin1();
+ yy_switch_to_buffer( yy_scan_string( cstr ) );
+}
+
+/**
+ This function parses a range in a form similar to "{3,4}", "{,7}"
+ etc. and returns the value in the integers pointed to by min and max.
+*/
+void parseRange( char* txt, int* min, int* max )
+{
+
+ /*
+ case txt min max
+ 1 {} 0 -1
+ 2 {,} 0 -1
+ 3 {5} 5 5
+ 4 {5,} 5 -1
+ 5 {,7} 0 7
+ 6 {5,7} 5 7
+ */
+ char c;
+ int i = 1;
+ int minimum=0, maximum=0;
+ int minFound=0, maxFound=0, commaFound = 0;
+
+ while ( (c = txt[i++]) != ',' && c != '}') {
+ minimum = minimum*10+ c-'0';
+ minFound=1;
+ }
+
+ if ( c == ',' )
+ commaFound = 1;
+
+ if ( c != '}' ) {
+ while ( (c = txt[i++]) != '}') {
+ maximum = maximum*10+ c-'0';
+ maxFound = 1;
+ }
+ }
+
+ *min = minimum;
+ if ( maxFound )
+ *max = maximum; /* case 5,6 */
+ else if ( !minFound )
+ *max = -1; /* case 1,2 */
+ else if ( commaFound )
+ *max = -1; /* case 4 */
+ else
+ *max = minimum; /* case 3 */
+}
+
+
+/**
+ This function parses a character range like "[^ab1-4]".
+*/
+RegExp* parseCharClass( char* match )
+{
+ TextRangeRegExp* res = new TextRangeRegExp( false );
+ QString txt = QString::fromLocal8Bit( match );
+ txt = txt.mid(1,txt.length()-2);
+
+ unsigned int i = 0;
+ QChar ch = txt.at(i++);
+ QString pendingChar;
+ QString thisChar;
+ bool charPending = false;
+ bool rangePending = false;
+ bool flushPending = false;
+
+ if ( ch == QChar('^') ) {
+ res->setNegate( true );
+ ch = txt.at(i++);
+ }
+
+ do {
+ // If a character is pending, and the next char is '-' then we are
+ // possible looking at a range.
+ if ( ch == QChar('-') && charPending ) {
+ rangePending = true;
+ ch = txt.at(i++);
+ continue;
+ }
+
+ // If we have a pending character, but do not also have a pending
+ // range, then the pending character was not part of a range, and
+ // should therefore just be added as a single character.
+ if ( charPending && !rangePending ) {
+ res->addCharacter( pendingChar );
+ charPending = false;
+ }
+
+ if ( ch == QChar('\\') ) {
+ // Handle the cases where an escape character is specified.
+ ch = txt.at(i++);
+
+ if ( ch == QChar('a') || ch == QChar('f') || ch == QChar('n') || ch == QChar('r') || ch == QChar('t') || ch == QChar('v') ) {
+ // These are just seen as normal characters.
+ thisChar = QString::fromLocal8Bit("\\") + ch;
+ }
+ else if ( ch == QChar('d') ) {
+ // The following characters represent character groups. If any of
+ // these are seen in a range, then the range is ignored, thus [a-\s]
+ // matches an 'a', a '-', and a space (\s means space).
+ res->setDigit( true );
+ flushPending = true;
+ }
+ else if ( ch == QChar('D') ) {
+ res->setNonDigit( true );
+ flushPending = true;
+ }
+ else if ( ch == QChar('s') ) {
+ res->setSpace( true );
+ flushPending = true;
+ }
+ else if ( ch == QChar('S') ) {
+ res->setNonSpace( true );
+ flushPending = true;
+ }
+ else if ( ch == QChar('w') ) {
+ res->setWordChar( true );
+ flushPending = true;
+ }
+ else if ( ch == QChar('W') ) {
+ res->setNonWordChar( true );
+ flushPending = true;
+ }
+ else if ( ch == QChar('x') || ch == QChar('X') ) {
+ // This is a hexidecimal character: \xHHHH
+ QString str;
+ for ( int j=0; j<4; j++) {
+ ch = txt.at(i++);
+ if ( ch == 'a' || ch == 'A' || ch == 'b' || ch == 'B' || ch == 'c' || ch == 'C' || ch == 'd' || ch == 'D' ||
+ ch == 'e' || ch == 'E' || ch == 'f' || ch == 'F' ||
+ ch == '0' || ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5' || ch == '6' || ch == '7' ||
+ ch == '8' || ch == '9' )
+ str += ch;
+ else
+ i--;
+ }
+ thisChar = QString::fromLocal8Bit("\\x") + str;
+ }
+ else if ( ch == QChar('0') ) {
+ // This is an octal character
+ QString str;
+ for ( int j=0; j<4; j++) {
+ ch = txt.at(i++);
+ if ( ch == '0' || ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5' || ch == '6' || ch == '7' )
+ str += ch;
+ else
+ i--;
+ }
+ thisChar = QString::fromLocal8Bit("\\x") + str ;
+ }
+ else {
+ // Anything else escaped just means the character itself.
+ thisChar = ch;
+ }
+ }
+ else {
+ // A non escaped character.
+ thisChar = ch;
+ }
+
+ // The characters \s,\S,\w,\W,\d or \D, can not be part of a range,
+ // thus if they are meet in what looks like a range, then the
+ // characters of the range is justed seen as normal non range
+ // characters. thus [a-\s] matches an 'a', a '-', and a space (\s means
+ // space).
+ if ( flushPending ) {
+ if ( charPending )
+ res->addCharacter( pendingChar );
+ if ( rangePending )
+ res->addCharacter( QString::fromLocal8Bit("-") );
+ flushPending = false;
+ charPending = false;
+ rangePending = false;
+ }
+ else {
+ if ( rangePending ) {
+ res->addRange( pendingChar, thisChar );
+ charPending = false;
+ rangePending = false;
+ }
+ else {
+ pendingChar = thisChar;
+ charPending = true;
+ }
+ }
+ ch = txt.at(i++);
+ }
+ while ( ch != QChar(']') && i <= txt.length() );
+
+ if ( charPending )
+ res->addCharacter( pendingChar );
+ if ( rangePending )
+ res->addCharacter( QString::fromLocal8Bit("-") );
+
+ return res;
+}
diff --git a/kregexpeditor/gen_qregexpparser.cc b/kregexpeditor/gen_qregexpparser.cc
new file mode 100644
index 0000000..b366293
--- /dev/null
+++ b/kregexpeditor/gen_qregexpparser.cc
@@ -0,0 +1,1447 @@
+/* A Bison parser, made from qregexpparser.y, by GNU bison 1.75. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* Written by Richard Stallman by simplifying the original so called
+ ``semantic'' parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+/* If NAME_PREFIX is specified substitute the variables and functions
+ names. */
+#define yyparse qregexpparse
+#define yylex qregexplex
+#define yyerror qregexperror
+#define yylval qregexplval
+#define yychar qregexpchar
+#define yydebug qregexpdebug
+#define yynerrs qregexpnerrs
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ TOK_Dot = 258,
+ TOK_Dollar = 259,
+ TOK_Carat = 260,
+ TOK_MagicLeftParent = 261,
+ TOK_PosLookAhead = 262,
+ TOK_NegLookAhead = 263,
+ TOK_LeftParen = 264,
+ TOK_RightParent = 265,
+ TOK_Bar = 266,
+ TOK_Quantifier = 267,
+ TOK_BackRef = 268,
+ TOK_CharClass = 269,
+ TOK_Char = 270,
+ TOK_EscapeChar = 271,
+ TOK_PosWordChar = 272,
+ TOK_PosNonWordChar = 273
+ };
+#endif
+#define TOK_Dot 258
+#define TOK_Dollar 259
+#define TOK_Carat 260
+#define TOK_MagicLeftParent 261
+#define TOK_PosLookAhead 262
+#define TOK_NegLookAhead 263
+#define TOK_LeftParen 264
+#define TOK_RightParent 265
+#define TOK_Bar 266
+#define TOK_Quantifier 267
+#define TOK_BackRef 268
+#define TOK_CharClass 269
+#define TOK_Char 270
+#define TOK_EscapeChar 271
+#define TOK_PosWordChar 272
+#define TOK_PosNonWordChar 273
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 18 "qregexpparser.y"
+
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <klocale.h>
+ #include <kmessagebox.h>
+#endif
+
+ #include <qstring.h>
+ #include <stdlib.h>
+
+ #include "regexp.h"
+ #include "textregexp.h"
+ #include "textrangeregexp.h"
+ #include "repeatregexp.h"
+ #include "lookaheadregexp.h"
+ #include "concregexp.h"
+ #include "altnregexp.h"
+ #include "positionregexp.h"
+ #include "dotregexp.h"
+ #include "compoundregexp.h"
+
+ extern int yylex();
+ extern void setParseData( QString str );
+ int yyerror (const char *);
+ void setParseResult( RegExp* );
+ RegExp* parseQtRegExp( QString qstr, bool* ok );
+ static RegExp* parseResult;
+ static int _index;
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#ifndef YYSTYPE
+#line 49 "qregexpparser.y"
+typedef union {
+ struct {
+ int min;
+ int max;
+ } range;
+ int backRef;
+ RegExp* regexp;
+ char ch;
+} yystype;
+/* Line 193 of /usr/share/bison/yacc.c. */
+#line 159 "gen_qregexpparser.cc"
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+#ifndef YYLTYPE
+typedef struct yyltype
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} yyltype;
+# define YYLTYPE yyltype
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 213 of /usr/share/bison/yacc.c. */
+#line 180 "gen_qregexpparser.cc"
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# else
+# ifndef YYSTACK_USE_ALLOCA
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+# define YYSTACK_ALLOC malloc
+# define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+ && (! defined (__cplusplus) \
+ || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ short yyss;
+ YYSTYPE yyvs;
+ };
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAX)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ register YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+ typedef signed char yysigned_char;
+#else
+ typedef short yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 27
+#define YYLAST 47
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 19
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 8
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 27
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 36
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 273
+
+#define YYTRANSLATE(X) \
+ ((unsigned)(X) <= YYMAXUTOK ? yytranslate[X] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned char yyprhs[] =
+{
+ 0, 0, 3, 4, 6, 8, 12, 14, 17, 20,
+ 22, 25, 27, 30, 32, 36, 40, 44, 48, 50,
+ 52, 54, 56, 58, 60, 62, 64, 66
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+ 21, 0, -1, -1, 22, -1, 20, -1, 22, 11,
+ 23, -1, 23, -1, 22, 11, -1, 11, 23, -1,
+ 11, -1, 23, 24, -1, 24, -1, 25, 12, -1,
+ 25, -1, 9, 22, 10, -1, 6, 22, 10, -1,
+ 7, 22, 10, -1, 8, 22, 10, -1, 14, -1,
+ 26, -1, 4, -1, 5, -1, 3, -1, 13, -1,
+ 17, -1, 18, -1, 15, -1, 16, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned char yyrline[] =
+{
+ 0, 80, 80, 82, 83, 86, 96, 97, 107, 112,
+ 115, 129, 136, 139, 142, 145, 146, 149, 152, 153,
+ 154, 155, 156, 157, 172, 173, 176, 182
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "TOK_Dot", "TOK_Dollar", "TOK_Carat",
+ "TOK_MagicLeftParent", "TOK_PosLookAhead", "TOK_NegLookAhead",
+ "TOK_LeftParen", "TOK_RightParent", "TOK_Bar", "TOK_Quantifier",
+ "TOK_BackRef", "TOK_CharClass", "TOK_Char", "TOK_EscapeChar",
+ "TOK_PosWordChar", "TOK_PosNonWordChar", "$accept", "empty", "regexp",
+ "expression", "term", "factor", "atom", "char", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const unsigned short yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned char yyr1[] =
+{
+ 0, 19, 20, 21, 21, 22, 22, 22, 22, 22,
+ 23, 23, 24, 24, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 26, 26
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 0, 1, 1, 3, 1, 2, 2, 1,
+ 2, 1, 2, 1, 3, 3, 3, 3, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const unsigned char yydefact[] =
+{
+ 2, 22, 20, 21, 0, 0, 0, 0, 9, 23,
+ 18, 26, 27, 24, 25, 4, 0, 3, 6, 11,
+ 13, 19, 0, 0, 0, 0, 8, 1, 7, 10,
+ 12, 15, 16, 17, 14, 5
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yysigned_char yydefgoto[] =
+{
+ -1, 15, 16, 17, 18, 19, 20, 21
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -18
+static const yysigned_char yypact[] =
+{
+ -1, -18, -18, -18, -1, -1, -1, -1, 18, -18,
+ -18, -18, -18, -18, -18, -18, 11, 8, 18, -18,
+ 16, -18, 19, 31, 34, 36, 18, -18, 18, -18,
+ -18, -18, -18, -18, -18, 18
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yysigned_char yypgoto[] =
+{
+ -18, -18, -18, 33, -8, -17, -18, -18
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, parse error. */
+#define YYTABLE_NINF -1
+static const unsigned char yytable[] =
+{
+ 26, 29, 1, 2, 3, 4, 5, 6, 7, 29,
+ 8, 27, 9, 10, 11, 12, 13, 14, 29, 28,
+ 35, 1, 2, 3, 4, 5, 6, 7, 30, 31,
+ 28, 9, 10, 11, 12, 13, 14, 22, 23, 24,
+ 25, 32, 28, 0, 33, 28, 34, 28
+};
+
+static const yysigned_char yycheck[] =
+{
+ 8, 18, 3, 4, 5, 6, 7, 8, 9, 26,
+ 11, 0, 13, 14, 15, 16, 17, 18, 35, 11,
+ 28, 3, 4, 5, 6, 7, 8, 9, 12, 10,
+ 11, 13, 14, 15, 16, 17, 18, 4, 5, 6,
+ 7, 10, 11, -1, 10, 11, 10, 11
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned char yystos[] =
+{
+ 0, 3, 4, 5, 6, 7, 8, 9, 11, 13,
+ 14, 15, 16, 17, 18, 20, 21, 22, 23, 24,
+ 25, 26, 22, 22, 22, 22, 23, 0, 11, 24,
+ 12, 10, 10, 10, 10, 23
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrlab1
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yychar1 = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror ("syntax error: cannot back up"); \
+ YYERROR; \
+ } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+ are run). */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ Current.first_line = Rhs[1].first_line; \
+ Current.first_column = Rhs[1].first_column; \
+ Current.last_line = Rhs[N].last_line; \
+ Current.last_column = Rhs[N].last_column;
+#endif
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#define YYLEX yylex ()
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+# define YYDSYMPRINT(Args) \
+do { \
+ if (yydebug) \
+ yysymprint Args; \
+} while (0)
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YYDSYMPRINT(Args)
+#endif /* !YYDEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined (__GLIBC__) && defined (_STRING_H)
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ register const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ register char *yyd = yydest;
+ register const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*-----------------------------.
+| Print this symbol on YYOUT. |
+`-----------------------------*/
+
+static void
+#if defined (__STDC__) || defined (__cplusplus)
+yysymprint (FILE* yyout, int yytype, YYSTYPE yyvalue)
+#else
+yysymprint (yyout, yytype, yyvalue)
+ FILE* yyout;
+ int yytype;
+ YYSTYPE yyvalue;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvalue;
+
+ if (yytype < YYNTOKENS)
+ {
+ YYFPRINTF (yyout, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+ YYPRINT (yyout, yytoknum[yytype], yyvalue);
+# endif
+ }
+ else
+ YYFPRINTF (yyout, "nterm %s (", yytname[yytype]);
+
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+ YYFPRINTF (yyout, ")");
+}
+#endif /* YYDEBUG. */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+static void
+#if defined (__STDC__) || defined (__cplusplus)
+yydestruct (int yytype, YYSTYPE yyvalue)
+#else
+yydestruct (yytype, yyvalue)
+ int yytype;
+ YYSTYPE yyvalue;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvalue;
+
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+ into yyparse. The argument should have type void *.
+ It should actually point to an object.
+ Grammar actions can access the variable by casting it
+ to the proper pointer type. */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+# define YYPARSE_PARAM_DECL
+# else
+# define YYPARSE_PARAM_ARG YYPARSE_PARAM
+# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+# endif
+#else /* !YYPARSE_PARAM */
+# define YYPARSE_PARAM_ARG
+# define YYPARSE_PARAM_DECL
+#endif /* !YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+# ifdef YYPARSE_PARAM
+int yyparse (void *);
+# else
+int yyparse (void);
+# endif
+#endif
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Number of parse errors so far. */
+int yynerrs;
+
+
+int
+yyparse (YYPARSE_PARAM_ARG)
+ YYPARSE_PARAM_DECL
+{
+
+ register int yystate;
+ register int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yychar1 = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short yyssa[YYINITDEPTH];
+ short *yyss = yyssa;
+ register short *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK (yyvsp--, yyssp--)
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks.
+ */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyoverflowlab;
+# else
+ /* Extend the stack our own way. */
+ if (yystacksize >= YYMAXDEPTH)
+ goto yyoverflowlab;
+ yystacksize *= 2;
+ if (yystacksize > YYMAXDEPTH)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyoverflowlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyssp >= yyss + yystacksize - 1)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with. */
+
+ if (yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ yychar = YYEOF; /* Don't call YYLEX any more. */
+
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE (yychar);
+
+ /* We have to keep this `#if YYDEBUG', since we use variables
+ which are defined only if `YYDEBUG' is set. */
+ YYDPRINTF ((stderr, "Next token is "));
+ YYDSYMPRINT ((stderr, yychar1, yylval));
+ YYDPRINTF ((stderr, "\n"));
+ }
+
+ /* If the proper action on seeing token YYCHAR1 is to reduce or to
+ detect an error, take that action. */
+ yyn += yychar1;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yychar1)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+ YYDPRINTF ((stderr, "Shifting token %d (%s), ",
+ yychar, yytname[yychar1]));
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+
+#if YYDEBUG
+ /* We have to keep this `#if YYDEBUG', since we use variables which
+ are defined only if `YYDEBUG' is set. */
+ if (yydebug)
+ {
+ int yyi;
+
+ YYFPRINTF (stderr, "Reducing via rule %d (line %d), ",
+ yyn - 1, yyrline[yyn]);
+
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyn]; yyrhs[yyi] >= 0; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+ YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+ }
+#endif
+ switch (yyn)
+ {
+ case 3:
+#line 82 "qregexpparser.y"
+ { setParseResult( yyvsp[0].regexp) ; }
+ break;
+
+ case 4:
+#line 83 "qregexpparser.y"
+ { setParseResult( new ConcRegExp( false ) ); }
+ break;
+
+ case 5:
+#line 86 "qregexpparser.y"
+ {
+ if ( dynamic_cast<AltnRegExp*>( yyvsp[-2].regexp ) ) {
+ yyval.regexp = yyvsp[-2].regexp;
+ }
+ else {
+ yyval.regexp = new AltnRegExp( false );
+ dynamic_cast<AltnRegExp*>( yyval.regexp )->addRegExp( yyvsp[-2].regexp );
+ }
+ dynamic_cast<AltnRegExp*>( yyval.regexp )->addRegExp( yyvsp[0].regexp );
+ }
+ break;
+
+ case 6:
+#line 96 "qregexpparser.y"
+ { yyval.regexp = yyvsp[0].regexp; }
+ break;
+
+ case 7:
+#line 97 "qregexpparser.y"
+ {
+ if ( dynamic_cast<AltnRegExp*>( yyvsp[-1].regexp ) ) {
+ yyval.regexp = yyvsp[-1].regexp;
+ }
+ else {
+ yyval.regexp = new AltnRegExp( false );
+ dynamic_cast<AltnRegExp*>( yyval.regexp )->addRegExp( yyvsp[-1].regexp );
+ }
+ dynamic_cast<AltnRegExp*>( yyval.regexp )->addRegExp( new TextRegExp( false, QString::fromLatin1("") ) );
+ }
+ break;
+
+ case 8:
+#line 107 "qregexpparser.y"
+ {
+ yyval.regexp = new AltnRegExp( false );
+ dynamic_cast<AltnRegExp*>( yyval.regexp )->addRegExp( new TextRegExp( false, QString::fromLatin1("") ) );
+ dynamic_cast<AltnRegExp*>( yyval.regexp )->addRegExp( yyvsp[0].regexp );
+ }
+ break;
+
+ case 9:
+#line 112 "qregexpparser.y"
+ { yyval.regexp = new AltnRegExp( false ); }
+ break;
+
+ case 10:
+#line 115 "qregexpparser.y"
+ {
+ RegExp* last = dynamic_cast<ConcRegExp*>( yyvsp[-1].regexp )->lastRegExp();
+ TextRegExp *reg1, *reg2;
+
+ if ( last && ( reg1 = dynamic_cast<TextRegExp*>( last ) ) &&
+ ( reg2 = dynamic_cast<TextRegExp*>( yyvsp[0].regexp ) ) ) {
+ reg1->append( reg2->text() );
+ delete reg2;
+ }
+ else {
+ dynamic_cast<ConcRegExp*>(yyval.regexp)->addRegExp( yyvsp[0].regexp );
+ }
+ yyval.regexp = yyvsp[-1].regexp;
+ }
+ break;
+
+ case 11:
+#line 129 "qregexpparser.y"
+ {
+ ConcRegExp* reg = new ConcRegExp( false );
+ reg->addRegExp( yyvsp[0].regexp );
+ yyval.regexp = reg;
+ }
+ break;
+
+ case 12:
+#line 136 "qregexpparser.y"
+ {
+ yyval.regexp = new RepeatRegExp( false, yyvsp[0].range.min, yyvsp[0].range.max, yyvsp[-1].regexp );
+ }
+ break;
+
+ case 13:
+#line 139 "qregexpparser.y"
+ { yyval.regexp = yyvsp[0].regexp; }
+ break;
+
+ case 14:
+#line 142 "qregexpparser.y"
+ {
+ yyval.regexp = yyvsp[-1].regexp;
+ }
+ break;
+
+ case 15:
+#line 145 "qregexpparser.y"
+ { yyval.regexp = yyvsp[-1].regexp; }
+ break;
+
+ case 16:
+#line 146 "qregexpparser.y"
+ {
+ yyval.regexp = new LookAheadRegExp( false, LookAheadRegExp::POSITIVE, yyvsp[-1].regexp );
+ }
+ break;
+
+ case 17:
+#line 149 "qregexpparser.y"
+ {
+ yyval.regexp = new LookAheadRegExp( false, LookAheadRegExp::NEGATIVE, yyvsp[-1].regexp );
+ }
+ break;
+
+ case 18:
+#line 152 "qregexpparser.y"
+ { yyval.regexp = yyvsp[0].regexp; }
+ break;
+
+ case 19:
+#line 153 "qregexpparser.y"
+ { yyval.regexp = yyvsp[0].regexp; }
+ break;
+
+ case 20:
+#line 154 "qregexpparser.y"
+ { yyval.regexp = new PositionRegExp( false, PositionRegExp::ENDLINE ); }
+ break;
+
+ case 21:
+#line 155 "qregexpparser.y"
+ { yyval.regexp = new PositionRegExp( false, PositionRegExp::BEGLINE ); }
+ break;
+
+ case 22:
+#line 156 "qregexpparser.y"
+ { yyval.regexp = new DotRegExp( false ); }
+ break;
+
+ case 23:
+#line 157 "qregexpparser.y"
+ {
+ QString match = QString::fromLocal8Bit("\\%1").arg( yyvsp[0].backRef );
+ yyval.regexp = new TextRegExp( false, match );
+ KMessageBox::information(0,i18n("<qt>Back reference regular expressions are not supported.<p>"
+ "<tt>\\1</tt>, <tt>\\2</tt>, ... are <i>back references</i>, meaning they refer to "
+ "previous matches. "
+ "Unfortunately this is not supported in the current version of this editor.<p>"
+ "In the graphical area the text <b>%1</b> has been inserted. This is however "
+ "just a workaround to ensure that the application handles the regexp at all. "
+ "Therefore, as soon as you edit the regular expression in the graphical area, "
+ "the back reference will be replaced by matching the text <b>%2</b> literally.")
+ .arg( match ).arg( match ),
+ i18n("Back reference regular expressions not supported"),
+ QString::fromLocal8Bit("backReferenceNotSupported") );
+ }
+ break;
+
+ case 24:
+#line 172 "qregexpparser.y"
+ { yyval.regexp = new PositionRegExp( false, PositionRegExp::WORDBOUNDARY ); }
+ break;
+
+ case 25:
+#line 173 "qregexpparser.y"
+ { yyval.regexp = new PositionRegExp( false, PositionRegExp::NONWORDBOUNDARY ); }
+ break;
+
+ case 26:
+#line 176 "qregexpparser.y"
+ {
+ if ( yyvsp[0].ch == '{' || yyvsp[0].ch == '}' || yyvsp[0].ch == '[' || yyvsp[0].ch == ']' || yyvsp[0].ch == '\\' ) {
+ yyerror( "illigal character - needs escaping" );
+ }
+ yyval.regexp = new TextRegExp( false, QString::fromLocal8Bit("%1").arg(yyvsp[0].ch));
+ }
+ break;
+
+ case 27:
+#line 182 "qregexpparser.y"
+ { yyval.regexp = new TextRegExp( false, QString::fromLocal8Bit("%1").arg(yyvsp[0].ch)); }
+ break;
+
+
+ }
+
+/* Line 1016 of /usr/share/bison/yacc.c. */
+#line 1209 "gen_qregexpparser.cc"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+
+
+#if YYDEBUG
+ if (yydebug)
+ {
+ short *yyssp1 = yyss - 1;
+ YYFPRINTF (stderr, "state stack now");
+ while (yyssp1 != yyssp)
+ YYFPRINTF (stderr, " %d", *++yyssp1);
+ YYFPRINTF (stderr, "\n");
+ }
+#endif
+
+ *++yyvsp = yyval;
+
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (YYPACT_NINF < yyn && yyn < YYLAST)
+ {
+ YYSIZE_T yysize = 0;
+ int yytype = YYTRANSLATE (yychar);
+ char *yymsg;
+ int yyx, yycount;
+
+ yycount = 0;
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ yysize += yystrlen (yytname[yyx]) + 15, yycount++;
+ yysize += yystrlen ("parse error, unexpected ") + 1;
+ yysize += yystrlen (yytname[yytype]);
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg != 0)
+ {
+ char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
+ yyp = yystpcpy (yyp, yytname[yytype]);
+
+ if (yycount < 5)
+ {
+ yycount = 0;
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *));
+ yyx++)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ const char *yyq = ! yycount ? ", expecting " : " or ";
+ yyp = yystpcpy (yyp, yyq);
+ yyp = yystpcpy (yyp, yytname[yyx]);
+ yycount++;
+ }
+ }
+ yyerror (yymsg);
+ YYSTACK_FREE (yymsg);
+ }
+ else
+ yyerror ("parse error; also virtual memory exhausted");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror ("parse error");
+ }
+ goto yyerrlab1;
+
+
+/*----------------------------------------------------.
+| yyerrlab1 -- error raised explicitly by an action. |
+`----------------------------------------------------*/
+yyerrlab1:
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ {
+ /* Pop the error token. */
+ YYPOPSTACK;
+ /* Pop the rest of the stack. */
+ while (yyssp > yyss)
+ {
+ YYDPRINTF ((stderr, "Error: popping "));
+ YYDSYMPRINT ((stderr,
+ yystos[*yyssp],
+ *yyvsp));
+ YYDPRINTF ((stderr, "\n"));
+ yydestruct (yystos[*yyssp], *yyvsp);
+ YYPOPSTACK;
+ }
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
+ yychar, yytname[yychar1]));
+ yydestruct (yychar1, yylval);
+ yychar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ YYDPRINTF ((stderr, "Error: popping "));
+ YYDSYMPRINT ((stderr,
+ yystos[*yyssp], *yyvsp));
+ YYDPRINTF ((stderr, "\n"));
+
+ yydestruct (yystos[yystate], *yyvsp);
+ yyvsp--;
+ yystate = *--yyssp;
+
+
+#if YYDEBUG
+ if (yydebug)
+ {
+ short *yyssp1 = yyss - 1;
+ YYFPRINTF (stderr, "Error: state stack now");
+ while (yyssp1 != yyssp)
+ YYFPRINTF (stderr, " %d", *++yyssp1);
+ YYFPRINTF (stderr, "\n");
+ }
+#endif
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ YYDPRINTF ((stderr, "Shifting error token, "));
+
+ *++yyvsp = yylval;
+
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here. |
+`----------------------------------------------*/
+yyoverflowlab:
+ yyerror ("parser stack overflow");
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ return yyresult;
+}
+
+
+#line 185 "qregexpparser.y"
+
+
+RegExp* parseQtRegExp( QString qstr, bool* ok ) {
+ _index = 0;
+ parseResult = 0;
+ setParseData( qstr );
+ yyparse();
+ *ok = ( yynerrs == 0 );
+ return parseResult;
+}
+
+void setParseResult( RegExp* regexp ) {
+ parseResult = regexp;
+}
+
+int yyerror(const char *) {
+ yynerrs++;
+ return 0;
+}
+
diff --git a/kregexpeditor/gen_qregexpparser.hh b/kregexpeditor/gen_qregexpparser.hh
new file mode 100644
index 0000000..19b2558
--- /dev/null
+++ b/kregexpeditor/gen_qregexpparser.hh
@@ -0,0 +1,93 @@
+/* A Bison parser, made from qregexpparser.y, by GNU bison 1.75. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+#ifndef BISON_GEN_QREGEXPPARSER_HH
+# define BISON_GEN_QREGEXPPARSER_HH
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ TOK_Dot = 258,
+ TOK_Dollar = 259,
+ TOK_Carat = 260,
+ TOK_MagicLeftParent = 261,
+ TOK_PosLookAhead = 262,
+ TOK_NegLookAhead = 263,
+ TOK_LeftParen = 264,
+ TOK_RightParent = 265,
+ TOK_Bar = 266,
+ TOK_Quantifier = 267,
+ TOK_BackRef = 268,
+ TOK_CharClass = 269,
+ TOK_Char = 270,
+ TOK_EscapeChar = 271,
+ TOK_PosWordChar = 272,
+ TOK_PosNonWordChar = 273
+ };
+#endif
+#define TOK_Dot 258
+#define TOK_Dollar 259
+#define TOK_Carat 260
+#define TOK_MagicLeftParent 261
+#define TOK_PosLookAhead 262
+#define TOK_NegLookAhead 263
+#define TOK_LeftParen 264
+#define TOK_RightParent 265
+#define TOK_Bar 266
+#define TOK_Quantifier 267
+#define TOK_BackRef 268
+#define TOK_CharClass 269
+#define TOK_Char 270
+#define TOK_EscapeChar 271
+#define TOK_PosWordChar 272
+#define TOK_PosNonWordChar 273
+
+
+
+
+#ifndef YYSTYPE
+#line 49 "qregexpparser.y"
+typedef union {
+ struct {
+ int min;
+ int max;
+ } range;
+ int backRef;
+ RegExp* regexp;
+ char ch;
+} yystype;
+/* Line 1281 of /usr/share/bison/yacc.c. */
+#line 86 "gen_qregexpparser.hh"
+# define YYSTYPE yystype
+#endif
+
+extern YYSTYPE qregexplval;
+
+
+#endif /* not BISON_GEN_QREGEXPPARSER_HH */
+
diff --git a/kregexpeditor/hi128-app-kregexpeditor.png b/kregexpeditor/hi128-app-kregexpeditor.png
new file mode 100644
index 0000000..e1ea769
--- /dev/null
+++ b/kregexpeditor/hi128-app-kregexpeditor.png
Binary files differ
diff --git a/kregexpeditor/hi16-app-kregexpeditor.png b/kregexpeditor/hi16-app-kregexpeditor.png
new file mode 100644
index 0000000..86f7882
--- /dev/null
+++ b/kregexpeditor/hi16-app-kregexpeditor.png
Binary files differ
diff --git a/kregexpeditor/hi22-app-kregexpeditor.png b/kregexpeditor/hi22-app-kregexpeditor.png
new file mode 100644
index 0000000..11a7991
--- /dev/null
+++ b/kregexpeditor/hi22-app-kregexpeditor.png
Binary files differ
diff --git a/kregexpeditor/hi32-app-kregexpeditor.png b/kregexpeditor/hi32-app-kregexpeditor.png
new file mode 100644
index 0000000..af0f3f7
--- /dev/null
+++ b/kregexpeditor/hi32-app-kregexpeditor.png
Binary files differ
diff --git a/kregexpeditor/hi48-app-kregexpeditor.png b/kregexpeditor/hi48-app-kregexpeditor.png
new file mode 100644
index 0000000..fc589c9
--- /dev/null
+++ b/kregexpeditor/hi48-app-kregexpeditor.png
Binary files differ
diff --git a/kregexpeditor/hi64-app-kregexpeditor.png b/kregexpeditor/hi64-app-kregexpeditor.png
new file mode 100644
index 0000000..81013f9
--- /dev/null
+++ b/kregexpeditor/hi64-app-kregexpeditor.png
Binary files differ
diff --git a/kregexpeditor/infopage.cpp b/kregexpeditor/infopage.cpp
new file mode 100644
index 0000000..8f373c5
--- /dev/null
+++ b/kregexpeditor/infopage.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <klocale.h>
+ #include <kapplication.h>
+#endif
+
+#include "infopage.h"
+
+InfoPage::InfoPage( QWidget* parent, const char* name )
+ :KTextBrowser( parent, name )
+{
+ QString txt =
+ QString::fromLatin1( "<qt>" ) +
+ i18n( "Translators, feel free to add yourself in the text below, asking for a postcard ;-), "
+ "also feel free to add a section saying <h2>Translators</h2>. "
+ "Kind regards, and thanks for your work - Jesper.",
+ "<h1>Regular Expression Editor</h1>"
+ "<p>What you are currently looking at is an editor for <i>Regular Expressions</i>.</p>"
+ "<p>The upper part in the middle is the editing area, the lower part is a verification window where you can "
+ "try your regular expressions right away. The row of buttons is the editing actions. "
+ "This is actually very similar to common drawing programs. Select an editing tool to start "
+ "editing your regular expression, and press the mouse button in the editing area where you want "
+ "this item inserted.</p>"
+ "<p>For a more detailed description of this editor see the <a href=\"doc://\">info pages</a></p>"
+
+ "<h2>What is a regular expression?</h2>"
+ "If you do not know what a regular expression is, then it might be a good idea "
+ "to read <a href=\"doc://whatIsARegExp\">the introduction to regular expressions</a>.<p>");
+
+#ifdef HOUSEOFFUSION
+ txt += tr("<h2>House Of Fusion note</h2>"
+ "If you want to donate money to continue development on the KRegExpEditor port for "
+ "house of fusion then please contact Michael Dinowitz (mdinowit@houseoffusion.com).");
+#endif
+ txt += i18n( "<h2>Send the author an electronic postcard</h2>"
+ "I don't get any money for working on KRegExpEditor, "
+ "I therefore appreciate it very much when users tell me what they think about my work. "
+ "I would therefore be very happy if you <a href=\"mailto:blackie@kde.org?subject=KRegExpEditor\">"
+ "sent me a short mail</a>, telling me that you use my regular expression editor."
+
+ "<h2>Author</h2>"
+ "<a href=\"http://www.blackie.dk/\">Jesper K. Pedersen</a> &lt;<a href=\"mailto:blackie@kde.org\">blackie@kde.org</a>&gt;")
+ + QString::fromLatin1( "</qt>" );
+ setText( txt );
+}
+
+void InfoPage::setSource ( const QString& name )
+{
+#ifdef QT_ONLY
+ mimeSourceFactory()->setFilePath( QStringList() << QString::fromLatin1("manual/"));
+ QString nm = name;
+ if ( nm.endsWith("/") )
+ nm = nm.left( nm.length()-1);
+
+ if ( nm.startsWith("mailto:") ) {
+ QMessageBox::information( this, tr("Support mail"), tr("Please send the mail to blackie@kde.org") );
+ return;
+ }
+ if ( nm.startsWith( "http:" ) )
+ return;
+
+
+ if ( nm == "doc://" )
+ nm = "doc://index";
+
+ if ( nm.startsWith( QString::fromLocal8Bit("doc://") ) ) {
+ nm = nm.mid(6) + ".html";
+ }
+
+ QTextBrowser::setSource( nm );
+#else
+ if ( name.startsWith( QString::fromLocal8Bit("doc://") ) ) {
+ kapp->invokeHelp( name.mid(6, name.length()-7), QString::fromLocal8Bit("KRegExpEditor") );
+ }
+ else {
+ KTextBrowser::setSource( name ); // handle mailto and other links
+ }
+#endif
+}
diff --git a/kregexpeditor/infopage.h b/kregexpeditor/infopage.h
new file mode 100644
index 0000000..b518979
--- /dev/null
+++ b/kregexpeditor/infopage.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef infopage_h
+#define infopage_h
+
+#ifdef QT_ONLY
+ #include "compat.h"
+ #include <qtextbrowser.h>
+#else
+ # include <ktextbrowser.h>
+#endif
+
+class InfoPage :public KTextBrowser
+{
+public:
+ InfoPage( QWidget* parent, const char* name );
+ virtual void setSource ( const QString& name );
+};
+
+
+
+#endif
diff --git a/kregexpeditor/kregexpeditor.desktop b/kregexpeditor/kregexpeditor.desktop
new file mode 100644
index 0000000..ebffee5
--- /dev/null
+++ b/kregexpeditor/kregexpeditor.desktop
@@ -0,0 +1,76 @@
+[Desktop Entry]
+Name=KRegExpEditor
+Name[cs]=Editor regulárních výrazů
+Name[et]=Regulaaravaldiste redaktor
+Name[fa]=KRegExp ویرایشگر
+Name[hi]=के-रेग-एक्सप-एडीटर
+Name[pa]=KRegExp ਸੰਪਾਦਕ
+Name[pl]=Edytor wyrażeń regularnych
+Name[sv]=Kregexpeditor
+Name[ta]= KRegExp தொகுப்பி
+Name[tg]=KМуҳаррири Ифодаҳои Муқаррарӣ
+Name[wa]=Aspougneu d' erîlêyès ratourneures
+Name[zh_TW]=正規表示式編輯器
+Exec=kregexpeditor
+DocPath=KRegExpEditor/index.html
+GenericName=Regular Expression Editor
+GenericName[ar]=محرّر التعابير النظامية
+GenericName[bg]=Редактор на регулярни изрази
+GenericName[br]=Aozer an troiennoù reolataet
+GenericName[bs]=Editor regularnih izraza
+GenericName[ca]=Editor d'expressions regulars
+GenericName[cs]=Editor regulárních výrazů
+GenericName[cy]=Golygydd Mynegiadau Rheolaidd
+GenericName[da]=Editor for regulære udtryk
+GenericName[de]=Editor für reguläre Ausdrücke
+GenericName[el]=Επεξεργαστής κανονικών εκφράσεων
+GenericName[eo]=Redaktilo por regulesprimoj
+GenericName[es]=Editor de expresiones regulares
+GenericName[et]=Regulaaravaldiste redaktor
+GenericName[eu]=Adierazpen Erregularren Editorea
+GenericName[fa]=ویرایشگر عبارت منظم
+GenericName[fi]=Säännöllisten lausekkeiden muokkain
+GenericName[fr]=Éditeur d'expressions régulières
+GenericName[ga]=Eagarthóir Sloinn Ionadaíochta
+GenericName[he]=עורך ביטויים רגולריים
+GenericName[hi]=रेगुलर एक्सप्रेशन संपादक
+GenericName[hu]=Kifejezésszerkesztő
+GenericName[is]=Ritill fyrir reglulegar segðir
+GenericName[it]=Editor di espressioni regolari
+GenericName[ja]=正規表現エディタ
+GenericName[ka]=მარტივი გამოსახულების რედაქტორი
+GenericName[kk]=Үлгі өрнегінің редакторы
+GenericName[km]=កម្មវិធី​និពន្ធ​កន្សោម​ធម្មតា
+GenericName[lt]=Įprastųjų išraiškų redaktorius
+GenericName[mk]=Уредувач на регуларни изрази
+GenericName[ms]=Penyunting Ungkapan Nalar (regexp)
+GenericName[nb]=Tekstbehandler for regulære uttrykk
+GenericName[nds]=Editor för Regulere Utdrück
+GenericName[ne]=नियमित अभिव्यक्ति सम्पादक
+GenericName[nl]=Editor voor regular expressions
+GenericName[nn]=Program for skriving av regulære uttrykk
+GenericName[pa]=ਨਿਯਮਤ ਸਮੀਕਰਨ ਸੰਪਾਦਕ
+GenericName[pl]=Edytor wyrażeń regularnych
+GenericName[pt]=Editor de Expressões Regulares
+GenericName[pt_BR]=Editor de Expressões Regulares
+GenericName[ro]=Editor de expresii regulate
+GenericName[ru]=Редактор регулярных выражений
+GenericName[sk]=Editor regulárnych výrazov
+GenericName[sl]=Urejevalnik regularnih izrazov
+GenericName[sr]=Уређивач регуларних израза
+GenericName[sr@Latn]=Uređivač regularnih izraza
+GenericName[sv]=Editor för reguljära uttryck
+GenericName[ta]=இயல்பான கூற்று தொகுப்பான்
+GenericName[tg]=Муҳаррири Ифодаҳои Муқаррарӣ
+GenericName[tr]=Tam İfade Düzenleyici
+GenericName[uk]=Редактор формальних виразів
+GenericName[uz]=Doimiy ifoda tahrirchi
+GenericName[uz@cyrillic]=Доимий ифода таҳрирчи
+GenericName[wa]=Aspougneu d' erîlêyès ratourneures
+GenericName[zh_CN]=正规表达式编辑器
+GenericName[zh_TW]=正規表示式編輯器
+Terminal=false
+Type=Application
+X-KDE-StartupNotify=true
+Categories=Qt;KDE;Utility;X-KDE-More;
+Icon=kregexpeditor
diff --git a/kregexpeditor/kregexpeditor.svgz b/kregexpeditor/kregexpeditor.svgz
new file mode 100644
index 0000000..a91263c
--- /dev/null
+++ b/kregexpeditor/kregexpeditor.svgz
Binary files differ
diff --git a/kregexpeditor/kregexpeditorfactory.cpp b/kregexpeditor/kregexpeditorfactory.cpp
new file mode 100644
index 0000000..bcddd63
--- /dev/null
+++ b/kregexpeditor/kregexpeditorfactory.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifndef QT_ONLY
+#include <kgenericfactory.h>
+#include "kregexpeditorgui.h"
+typedef K_TYPELIST_2( KRegExpEditorGUI, KRegExpEditorGUIDialog ) Products;
+K_EXPORT_COMPONENT_FACTORY( libkregexpeditorgui,
+ KGenericFactory<Products>( "kregexpeditor" ) )
+#endif
diff --git a/kregexpeditor/kregexpeditorgui.cpp b/kregexpeditor/kregexpeditorgui.cpp
new file mode 100644
index 0000000..e8f8051
--- /dev/null
+++ b/kregexpeditor/kregexpeditorgui.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <klocale.h>
+ #include <kgenericfactory.h>
+ #include <kapplication.h>
+ #include "kregexpeditorgui.moc"
+#endif
+
+#include "kregexpeditorgui.h"
+// #include <unistd.h> // DO I need this?
+#include <stdio.h>
+#include "kregexpeditorprivate.h"
+#include <qlayout.h>
+
+const QString KRegExpEditorGUI::version = QString::fromLocal8Bit("1.0");
+
+
+KRegExpEditorGUI::KRegExpEditorGUI(QWidget *parent, const char *name,
+ const QStringList & )
+ : QWidget( parent, name)
+{
+ QHBoxLayout* layout = new QHBoxLayout( this, 6 );
+ _editor = new KRegExpEditorPrivate( this, "_editor" );
+ layout->addWidget( _editor );
+ connect( _editor, SIGNAL( canUndo(bool) ), this, SIGNAL( canUndo(bool) ) );
+ connect( _editor, SIGNAL( canRedo(bool) ), this, SIGNAL( canRedo(bool) ) );
+ connect( _editor, SIGNAL( changes(bool) ), this, SIGNAL( changes(bool) ) );
+}
+
+QString KRegExpEditorGUI::regExp() const
+{
+ return _editor->regexp();
+}
+
+void KRegExpEditorGUI::redo()
+{
+ _editor->slotRedo();
+}
+
+void KRegExpEditorGUI::undo()
+{
+ _editor->slotUndo();
+}
+
+void KRegExpEditorGUI::setRegExp( const QString &regexp )
+{
+ _editor->slotSetRegexp( regexp );
+}
+
+KRegExpEditorGUIDialog::KRegExpEditorGUIDialog( QWidget *parent,
+ const char *name,
+ const QStringList & )
+ : KDialogBase( KDialogBase::Plain, i18n("Regular Expression Editor"),
+ KDialogBase::Ok | KDialogBase::Cancel | KDialogBase::Help, KDialogBase::Ok,
+ parent, name ? name : "KRegExpDialog" )
+{
+ QFrame* frame = plainPage();
+ QVBoxLayout* layout = new QVBoxLayout( frame, 6 );
+ layout->setAutoAdd( true );
+ _editor = new KRegExpEditorGUI( frame );
+
+ connect( _editor, SIGNAL( canUndo(bool) ), this, SIGNAL( canUndo(bool) ) );
+ connect( _editor, SIGNAL( canRedo(bool) ), this, SIGNAL( canRedo(bool) ) );
+ connect( _editor, SIGNAL( changes(bool) ), this, SIGNAL( changes(bool) ) );
+ resize( 640, 400 );
+
+ setHelp( QString::null, QString::fromLocal8Bit( "KRegExpEditor" ) );
+#ifdef QT_ONLY
+ connect( this, SIGNAL( helpClicked() ), _editor, SLOT( showHelp() ) );
+#endif
+}
+
+
+QString KRegExpEditorGUIDialog::regExp() const
+{
+ return _editor->regExp();
+}
+
+void KRegExpEditorGUIDialog::setRegExp( const QString &regexp )
+{
+ _editor->setRegExp( regexp );
+}
+
+void KRegExpEditorGUIDialog::redo()
+{
+ _editor->redo();
+}
+
+void KRegExpEditorGUIDialog::undo()
+{
+ _editor->undo();
+}
+
+void KRegExpEditorGUIDialog::doSomething( QString method, void* arguments )
+{
+ _editor->doSomething( method, arguments );
+}
+
+void KRegExpEditorGUI::doSomething( QString method, void* arguments )
+{
+ if ( method == QString::fromLatin1( "setCaseSensitive" ) ) {
+ _editor->setCaseSensitive( (bool) arguments );
+ }
+ else if ( method == QString::fromLatin1("setMinimal") ) {
+ _editor->setMinimal( (bool) arguments );
+ }
+ else if ( method == QString::fromLatin1("setSyntax") ) {
+ _editor->setSyntax( *((QString*) arguments) );
+ }
+ else if ( method == QString::fromLatin1("setAllowNonQtSyntax") ) {
+ _editor->setAllowNonQtSyntax( (bool) arguments );
+ }
+ else {
+ qFatal( "%s", tr("Method '%1' is not valid!").arg(method).latin1() );
+ }
+}
+
+void KRegExpEditorGUIDialog::setMatchText( const QString& txt )
+{
+ _editor->setMatchText( txt );
+}
+
+void KRegExpEditorGUI::setMatchText( const QString& txt )
+{
+ _editor->setMatchText( txt );
+}
+
+
+void KRegExpEditorGUI::showHelp()
+{
+#ifdef QT_ONLY
+ _editor->showHelp();
+#else
+ kapp->invokeHelp( QString::null, QString::fromLocal8Bit( "KRegExpEditor" ) );
+#endif
+}
+
+#ifndef QT_ONLY
+typedef K_TYPELIST_2( KRegExpEditorGUI, KRegExpEditorGUIDialog ) Products;
+K_EXPORT_COMPONENT_FACTORY( libkregexpeditorgui,
+ KGenericFactory<Products>( "kregexpeditor" ) )
+#endif
diff --git a/kregexpeditor/kregexpeditorgui.desktop b/kregexpeditor/kregexpeditorgui.desktop
new file mode 100644
index 0000000..23e3896
--- /dev/null
+++ b/kregexpeditor/kregexpeditorgui.desktop
@@ -0,0 +1,62 @@
+[Desktop Entry]
+Type=Service
+Name=RegExp Editor Widget
+Name[af]=Regexp Redigeerder Gui-element
+Name[ar]=أداة محرر التعابير النظامية
+Name[az]=Qaydalıİfadə Editor Pəncərəsi
+Name[bg]=Редактор на регулярни изрази
+Name[ca]=Estri editor RegExp
+Name[cs]=Editor regulárních výrazů
+Name[cy]=Teclyn Golygydd RegExp
+Name[da]=RegExp Editor-kontrol
+Name[de]=RegExp-Bedienelement
+Name[el]=Γραφικό συστατικό επεξεργασίας κανονικών εκφράσεων
+Name[eo]=Redaktilo por regulesprimoj
+Name[es]=Ventana de edición RegExp
+Name[et]=Regulaaravaldiste redaktori komponent
+Name[eu]=RegExp Editore Widgeta
+Name[fa]=RegExp عنصر ویرایشگر
+Name[fi]=Säännöllisten lauseiden muokkain
+Name[fr]=Composant éditeur d'exp. rég.
+Name[ga]=Giuirléid Eagarthóireachta Sloinn Ionadaíochta
+Name[he]=פריט עורך הביטויים הסדירים
+Name[hi]=रेग-एक्सपी संपादक विजेट
+Name[hr]=Widget za uređivanje RegExp-a (regularnih izraza)
+Name[hu]=Grafikus objektum reguláris kifejezések szerkesztéséhez
+Name[it]=Elemento grafico dell'editor di espressioni regolari
+Name[ja]=正規表現エディタウィジェット
+Name[kk]=Үлгі өрнегінің өңдеу бөлшегі
+Name[km]=វត្ថុ​មើល​ឃើញកម្មវិធី​និពន្ធ RegExp
+Name[lt]=RegExp redaktoriaus valdiklis
+Name[lv]=RegExp Redaktora Widžets
+Name[mk]=графичка контрола за уредување RegExp
+Name[ms]=Wijet Penyunting RegExp
+Name[mt]=Editur ta' RegExp
+Name[nb]=Skjermelement RegExp tekstbehandler
+Name[nds]=RegExp Editor-Bedeenelement
+Name[ne]=RegExp सम्पादक विजेट
+Name[nn]=Skjermelement for redigering av regulære uttrykk
+Name[pl]=Edytor wyrażeń regularnych
+Name[pt]=Item de Edição de Expressões Regulares
+Name[pt_BR]=Widget do Editor de Expressões Regulares
+Name[ro]=Componentă editare expresii regulate
+Name[ru]=Виджет редактора регулярных выражений
+Name[sk]=Prvok Editor regulárnych výrazov
+Name[sl]=Gradnik urejevalnika RegExp
+Name[sr]=Контрола уређивача регуларних израза
+Name[sr@Latn]=Kontrola uređivača regularnih izraza
+Name[sv]=Grafisk komponent för att redigera reguljära uttryck
+Name[ta]= RegExp தொகுப்பான் சாளரம்
+Name[tg]=Ҷузъи Муҳаррири Ифодаҳои Муқаррарӣ
+Name[th]=คอนโทรลแก้ไข RegExp
+Name[tr]=RegExp Düzenleyici Aleti
+Name[uk]=Віджет редактору регулярних виразів
+Name[ven]=Widget ya musengulusi wa RegExp
+Name[wa]=Ahesse aspougneu d' erîlêyès ratourneures
+Name[xh]=RegExp Umhleli we Widget
+Name[zh_CN]=正则表达式编辑器部件
+Name[zh_TW]=正規表示式編輯小程式
+Name[zu]=RegExp Umhleli we-widget
+X-KDE-Library=libkregexpeditorgui
+InitialPreference=2
+ServiceTypes=KRegExpEditor/KRegExpEditor
diff --git a/kregexpeditor/kregexpeditorgui.h b/kregexpeditor/kregexpeditorgui.h
new file mode 100644
index 0000000..6bcd5e6
--- /dev/null
+++ b/kregexpeditor/kregexpeditorgui.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef kregexpeditorgui_h
+#define kregexpeditorgui_h
+
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <kdialogbase.h>
+#endif
+
+#include <kregexpeditorinterface.h>
+
+class KRegExpEditorPrivate;
+
+/**
+ Regular Expression Editor.
+
+ @author Jesper Kjr Pedersen <blackie@kde.org>
+ @version 0.1
+ **/
+class KDE_EXPORT KRegExpEditorGUI :public QWidget, public KRegExpEditorInterface
+{
+ Q_OBJECT
+ Q_PROPERTY( QString regexp READ regExp WRITE setRegExp )
+public:
+ KRegExpEditorGUI( QWidget *parent, const char *name = 0,
+ const QStringList & = QStringList() );
+ virtual QString regExp() const;
+
+ static const QString version;
+
+signals:
+ /** This signal tells whether undo is available. */
+ virtual void canRedo( bool );
+ virtual void canUndo( bool );
+ virtual void changes( bool );
+
+public slots:
+ virtual void redo();
+ virtual void undo();
+ virtual void setRegExp( const QString &regexp );
+ virtual void doSomething( QString method, void* arguments );
+ virtual void setMatchText( const QString& );
+ void showHelp();
+
+private:
+ KRegExpEditorPrivate* _editor;
+};
+
+class KDE_EXPORT KRegExpEditorGUIDialog : public KDialogBase, public KRegExpEditorInterface
+{
+ Q_OBJECT
+ Q_PROPERTY( QString regexp READ regExp WRITE setRegExp )
+public:
+ KRegExpEditorGUIDialog( QWidget *parent, const char *name, const QStringList &args );
+
+ virtual QString regExp() const;
+
+signals:
+ /** This signal tells whether undo is available. */
+ virtual void canRedo( bool );
+ virtual void canUndo( bool );
+ virtual void changes( bool );
+
+public slots:
+ virtual void redo();
+ virtual void undo();
+ virtual void setRegExp( const QString &regexp );
+ virtual void doSomething( QString method, void* arguments );
+ virtual void setMatchText( const QString& );
+
+private:
+ KRegExpEditorGUI *_editor;
+};
+
+#endif
+
diff --git a/kregexpeditor/kregexpeditorprivate.cpp b/kregexpeditor/kregexpeditorprivate.cpp
new file mode 100644
index 0000000..b13a655
--- /dev/null
+++ b/kregexpeditor/kregexpeditorprivate.cpp
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <klocale.h>
+ #include <kiconloader.h>
+ #include <kstandarddirs.h>
+ #include <kmessagebox.h>
+ #include "kregexpeditorprivate.moc"
+#endif
+
+#include <qlineedit.h>
+#include <qtooltip.h>
+#include <qtoolbutton.h>
+#include "kregexpeditorprivate.h"
+#include "scrollededitorwindow.h"
+#include "regexpbuttons.h"
+//#include <unistd.h> // What do I need this for?
+#include <stdio.h>
+#include "infopage.h"
+#include <qsplitter.h>
+#include <qdockarea.h>
+#include "userdefinedregexps.h"
+#include "auxbuttons.h"
+#include <qaccel.h>
+#include <qtimer.h>
+#include "verifier.h"
+#include <qfile.h>
+#include "verifybuttons.h"
+#include <qwhatsthis.h>
+
+KRegExpEditorPrivate::KRegExpEditorPrivate(QWidget *parent, const char *name)
+ : QWidget(parent, name), _updating( false ), _autoVerify( true )
+{
+ setMinimumSize(730,300);
+ QDockArea* area = new QDockArea( Horizontal, QDockArea::Normal, this );
+ area->setMinimumSize(2,2);
+ QDockArea* verArea1 = new QDockArea( Vertical, QDockArea::Normal, this );
+ verArea1->setMinimumSize(2,2);
+ QDockArea* verArea2 = new QDockArea( Vertical, QDockArea::Reverse, this );
+ verArea2->setMinimumSize(2,2);
+
+ // The DockWindows.
+ _regExpButtons = new RegExpButtons( area, "KRegExpEditorPrivate::regExpButton" );
+ _verifyButtons = new VerifyButtons( area, "KRegExpEditorPrivate::VerifyButtons" );
+ _auxButtons = new AuxButtons( area, "KRegExpEditorPrivate::AuxButtons" );
+ _userRegExps = new UserDefinedRegExps( verArea1, "KRegExpEditorPrivate::userRegExps" );
+ _userRegExps->setResizeEnabled( true );
+ QWhatsThis::add( _userRegExps, i18n( "In this window you will find predefined regular expressions. Both regular expressions "
+ "you have developed and saved, and regular expressions shipped with the system." ));
+
+ // Editor window
+ _editor = new QSplitter( Vertical, this, "KRegExpEditorPrivate::_editor" );
+
+ _scrolledEditorWindow =
+ new RegExpScrolledEditorWindow( _editor, "KRegExpEditorPrivate::_scrolledEditorWindow" );
+ QWhatsThis::add( _scrolledEditorWindow, i18n( "In this window you will develop your regular expressions. "
+ "Select one of the actions from the action buttons above, and click the mouse in this "
+ "window to insert the given action."));
+
+ _info = new InfoPage( this, "_info" );
+ _verifier = new Verifier( _editor, "KRegExpEditorPrivate::_verifier" );
+ connect( _verifier, SIGNAL( textChanged() ), this, SLOT( maybeVerify() ) );
+ QWhatsThis::add( _verifier, i18n("Type in some text in this window, and see what the regular expression you have developed matches.<p>"
+ "Each second match will be colored in red and each other match will be colored blue, simply so you "
+ "can distinguish them from each other.<p>"
+ "If you select part of the regular expression in the editor window, then this part will be "
+ "highlighted - This allows you to <i>debug</i> your regular expressions") );
+
+ _editor->hide();
+ _editor->setSizes( QValueList<int>() << _editor->height()/2 << _editor->height()/2 );
+
+ QVBoxLayout *topLayout = new QVBoxLayout( this, 0, 6, "KRegExpEditorPrivate::topLayout" );
+ topLayout->addWidget( area );
+ QHBoxLayout* rows = new QHBoxLayout; // I need to cal addLayout explicit to get stretching right.
+ topLayout->addLayout( rows, 1 );
+
+ rows->addWidget( verArea1 );
+ rows->addWidget( _editor, 1 );
+ rows->addWidget( _info, 1 );
+ rows->addWidget( verArea2 );
+
+ // Connect the buttons
+ connect( _regExpButtons, SIGNAL( clicked( int ) ), _scrolledEditorWindow, SLOT( slotInsertRegExp( int ) ) );
+ connect( _regExpButtons, SIGNAL( doSelect() ), _scrolledEditorWindow, SLOT( slotDoSelect() ) );
+ connect( _userRegExps, SIGNAL( load( RegExp* ) ), _scrolledEditorWindow, SLOT( slotInsertRegExp( RegExp* ) ) );
+
+ connect( _regExpButtons, SIGNAL( clicked( int ) ), _userRegExps, SLOT( slotUnSelect() ) );
+ connect( _regExpButtons, SIGNAL( doSelect() ), _userRegExps, SLOT( slotUnSelect() ) );
+ connect( _userRegExps, SIGNAL( load( RegExp* ) ), _regExpButtons, SLOT( slotUnSelect() ) );
+
+ connect( _scrolledEditorWindow, SIGNAL( doneEditing() ), _regExpButtons, SLOT( slotSelectNewAction() ) );
+ connect( _scrolledEditorWindow, SIGNAL( doneEditing() ), _userRegExps, SLOT( slotSelectNewAction() ) );
+
+ connect( _regExpButtons, SIGNAL( clicked( int ) ), this, SLOT( slotShowEditor() ) );
+ connect( _userRegExps, SIGNAL( load( RegExp* ) ), this, SLOT( slotShowEditor() ) );
+ connect( _regExpButtons, SIGNAL( doSelect() ), this, SLOT( slotShowEditor() ) );
+
+ connect( _scrolledEditorWindow, SIGNAL( savedRegexp() ), _userRegExps, SLOT( slotPopulateUserRegexps() ) );
+
+ connect( _auxButtons, SIGNAL( undo() ), this, SLOT( slotUndo() ) );
+ connect( _auxButtons, SIGNAL( redo() ), this, SLOT( slotRedo() ) );
+ connect( _auxButtons, SIGNAL( cut() ), _scrolledEditorWindow, SLOT( slotCut() ) );
+ connect( _auxButtons, SIGNAL( copy() ), _scrolledEditorWindow, SLOT( slotCopy() ) );
+ connect( _auxButtons, SIGNAL( paste() ), _scrolledEditorWindow, SLOT( slotPaste() ) );
+ connect( _auxButtons, SIGNAL( save() ), _scrolledEditorWindow, SLOT( slotSave() ) );
+ connect( _verifyButtons, SIGNAL( autoVerify( bool ) ), this, SLOT( setAutoVerify( bool ) ) );
+ connect( _verifyButtons, SIGNAL( verify() ), this, SLOT( doVerify() ) );
+ connect( _verifyButtons, SIGNAL( changeSyntax( const QString& ) ), this, SLOT( setSyntax( const QString& ) ) );
+
+ connect( this, SIGNAL( canUndo( bool ) ), _auxButtons, SLOT( slotCanUndo( bool ) ) );
+ connect( this, SIGNAL( canRedo( bool ) ), _auxButtons, SLOT( slotCanRedo( bool ) ) );
+ connect( _scrolledEditorWindow, SIGNAL( anythingSelected( bool ) ), _auxButtons, SLOT( slotCanCut( bool ) ) );
+ connect( _scrolledEditorWindow, SIGNAL( anythingSelected( bool ) ), _auxButtons, SLOT( slotCanCopy( bool ) ) );
+ connect( _scrolledEditorWindow, SIGNAL( anythingOnClipboard( bool ) ), _auxButtons, SLOT( slotCanPaste( bool ) ) );
+ connect( _scrolledEditorWindow, SIGNAL( canSave( bool ) ), _auxButtons, SLOT( slotCanSave( bool ) ) );
+
+ connect( _scrolledEditorWindow, SIGNAL( verifyRegExp() ), this, SLOT( maybeVerify() ) );
+
+ connect( _verifyButtons, SIGNAL( loadVerifyText( const QString& ) ), this, SLOT( setVerifyText( const QString& ) ) );
+
+ // connect( _verifier, SIGNAL( countChanged( int ) ), _verifyButtons, SLOT( setMatchCount( int ) ) );
+
+ // Qt anchors do not work for <pre>...</pre>, thefore scrolling to next/prev match
+ // do not work. Enable this when they work.
+ // connect( _verifyButtons, SIGNAL( gotoFirst() ), _verifier, SLOT( gotoFirst() ) );
+ // connect( _verifyButtons, SIGNAL( gotoPrev() ), _verifier, SLOT( gotoPrev() ) );
+ // connect( _verifyButtons, SIGNAL( gotoNext() ), _verifier, SLOT( gotoNext() ) );
+ // connect( _verifyButtons, SIGNAL( gotoLast() ), _verifier, SLOT( gotoLast() ) );
+ // connect( _verifier, SIGNAL( goForwardPossible( bool ) ), _verifyButtons, SLOT( enableForwardButtons( bool ) ) );
+ // connect( _verifier, SIGNAL( goBackwardPossible( bool ) ), _verifyButtons, SLOT( enableBackwardButtons( bool ) ) );
+
+ _auxButtons->slotCanPaste( false );
+ _auxButtons->slotCanCut( false );
+ _auxButtons->slotCanCopy( false );
+ _auxButtons->slotCanSave( false );
+
+
+ // Line Edit
+ QHBoxLayout* layout = new QHBoxLayout( topLayout, 6 );
+ QLabel* label = new QLabel( i18n("ASCII syntax:"), this );
+ layout->addWidget( label );
+ clearButton = new QToolButton( this );
+ const QString icon( QString::fromLatin1( QApplication::reverseLayout() ? "clear_left" : "locationbar_erase" ) );
+ QIconSet clearIcon = SmallIconSet( icon );
+ clearButton->setIconSet( clearIcon );
+ layout->addWidget( clearButton );
+ QToolTip::add( clearButton, i18n("Clear expression") );
+ _regexpEdit = new QLineEdit( this );
+ layout->addWidget( _regexpEdit );
+ QWhatsThis::add( _regexpEdit, i18n( "This is the regular expression in ASCII syntax. You are likely only "
+ "to be interested in this if you are a programmer, and need to "
+ "develop a regular expression using QRegExp.<p>"
+ "You may develop your regular expression both by using the graphical "
+ "editor, and by typing the regular expression in this line edit.") );
+
+#ifdef QT_ONLY
+ QPixmap pix( "icons/error.png" );
+#else
+ QPixmap pix = KGlobal::iconLoader()->loadIcon(locate("data", QString::fromLatin1("kregexpeditor/pics/error.png") ), KIcon::Toolbar );
+#endif
+ _error = new QLabel( this );
+ _error->setPixmap( pix );
+ layout->addWidget( _error );
+ _error->hide();
+
+ _timer = new QTimer(this);
+
+ connect( _scrolledEditorWindow, SIGNAL( change() ), this, SLOT( slotUpdateLineEdit() ) );
+ connect( _regexpEdit, SIGNAL(textChanged( const QString& ) ), this, SLOT( slotTriggerUpdate() ) );
+ connect( _timer, SIGNAL( timeout() ), this, SLOT( slotTimeout() ) );
+ connect( clearButton, SIGNAL( clicked() ), _regexpEdit, SLOT( clear() ) );
+
+ // Push an initial empty element on the stack.
+ _undoStack.push( _scrolledEditorWindow->regExp() );
+ _redoStack.setAutoDelete( true );
+
+ QAccel* accel = new QAccel( this );
+ accel->connectItem( accel->insertItem( CTRL+Key_Z ), this, SLOT( slotUndo() ) );
+ accel->connectItem( accel->insertItem( CTRL+Key_R ), this, SLOT( slotRedo() ) );
+
+ setSyntax( QString::fromLatin1( "Qt" ) );
+}
+
+QString KRegExpEditorPrivate::regexp()
+{
+ RegExp* regexp = _scrolledEditorWindow->regExp();
+ QString res = RegExpConverter::current()->toStr( regexp, false );
+ delete regexp;
+ return res;
+}
+
+void KRegExpEditorPrivate::slotUpdateEditor( const QString & txt)
+{
+ _updating = true;
+ bool ok;
+ if ( !RegExpConverter::current()->canParse() ) {
+ // This can happend if the application set a text through the API.
+ }
+ else {
+ RegExp* result = RegExpConverter::current()->parse( txt, &ok );
+ if ( ok ) {
+ QPtrList<CompoundRegExp> list = _userRegExps->regExps();
+ for ( QPtrListIterator<CompoundRegExp> it( list ); *it; ++it ) {
+ result->replacePart( *it );
+ }
+
+ _scrolledEditorWindow->slotSetRegExp( result );
+ _error->hide();
+ maybeVerify( );
+ recordUndoInfo();
+ result->check( _errorMap );
+ }
+ else {
+ _error->show();
+ if ( _autoVerify )
+ _verifier->clearRegexp();
+ }
+ delete result;
+ }
+ _updating = false;
+}
+
+void KRegExpEditorPrivate::slotUpdateLineEdit()
+{
+ if ( _updating )
+ return;
+ _updating = true;
+
+ RegExp* regexp = _scrolledEditorWindow->regExp();
+ regexp->check( _errorMap );
+
+ QString str = RegExpConverter::current()->toStr( regexp, false );
+ _regexpEdit->setText( str );
+ delete regexp;
+
+ recordUndoInfo();
+
+ _updating = false;
+}
+
+void KRegExpEditorPrivate::recordUndoInfo()
+{
+ Q_ASSERT( _updating );
+
+ // Update undo/redo stacks
+ RegExp* regexp = _scrolledEditorWindow->regExp();
+ if ( regexp->toXmlString() != _undoStack.top()->toXmlString() ) {
+ _undoStack.push( regexp );
+ _redoStack = QPtrStack<RegExp>();
+ emitUndoRedoSignals();
+ }
+}
+
+void KRegExpEditorPrivate::slotRedo()
+{
+ if ( _redoStack.count() != 0 ) {
+ _undoStack.push(_redoStack.pop());
+ _scrolledEditorWindow->slotSetRegExp( _undoStack.top() );
+ slotUpdateLineEdit();
+ emitUndoRedoSignals();
+ maybeVerify();
+ }
+}
+
+void KRegExpEditorPrivate::slotUndo()
+{
+ if ( _undoStack.count() > 1 ) {
+ _redoStack.push(_undoStack.pop());
+ _scrolledEditorWindow->slotSetRegExp( _undoStack.top() );
+ slotUpdateLineEdit();
+ emitUndoRedoSignals();
+ maybeVerify();
+ }
+}
+
+void KRegExpEditorPrivate::slotShowEditor()
+{
+ _info->hide();
+ _editor->show();
+}
+
+void KRegExpEditorPrivate::emitUndoRedoSignals()
+{
+ emit canUndo( _undoStack.count() > 1 );
+ emit changes( _undoStack.count() > 1 );
+ emit canRedo( _redoStack.count() > 0 );
+}
+
+void KRegExpEditorPrivate::slotSetRegexp( QString regexp )
+{
+ _regexpEdit->setText( regexp );
+}
+
+void KRegExpEditorPrivate::slotTriggerUpdate()
+{
+ /* ### Guess this timeout value should be configurable somewhere, or (even
+ * better: do some kind of benchmark each time the editor view gets updated
+ * to measure how long it takes on the client system to render the editor
+ * with the current complexity. That way we'd get good response times for
+ * simple regexps, and flicker-free display for complex regexps.
+ * - Frerich
+ */
+ if ( !_updating ) {
+ _timer->start( 300, true );
+ slotShowEditor();
+ }
+}
+
+void KRegExpEditorPrivate::slotTimeout()
+{
+ slotUpdateEditor( _regexpEdit->text() );
+}
+
+void KRegExpEditorPrivate::setMatchText( const QString& text )
+{
+ bool autoVerify = _autoVerify;
+ _autoVerify = false;
+ _verifier->setText( text );
+ _autoVerify = autoVerify;
+}
+
+void KRegExpEditorPrivate::maybeVerify()
+{
+ if ( _autoVerify )
+ doVerify();
+ else
+ _verifyButtons->setMatchCount(-1);
+}
+
+void KRegExpEditorPrivate::doVerify()
+{
+ bool autoVerify = _autoVerify; // prevent loop due to verify emit changed, which calls maybeVerify
+ _autoVerify = false;
+ RegExp* regexp = _scrolledEditorWindow->regExp();
+
+ _verifier->verify( RegExpConverter::current()->toStr( regexp, true ) );
+ delete regexp;
+ _autoVerify = autoVerify;
+}
+
+void KRegExpEditorPrivate::setAutoVerify( bool on )
+{
+ _autoVerify = on;
+ if ( !_autoVerify )
+ _verifier->clearRegexp();
+ else
+ doVerify();
+}
+
+void KRegExpEditorPrivate::setVerifyText( const QString& fileName )
+{
+ bool autoVerify = _autoVerify;
+ _autoVerify = false;
+ QFile file( fileName );
+ if ( !file.open( IO_ReadOnly ) ) {
+ KMessageBox::sorry(0, i18n("Could not open file '%1' for reading").arg( fileName ) );
+ }
+ else {
+ QTextStream s( &file );
+ QString txt = s.read();
+ file.close();
+ RegExp* regexp = _scrolledEditorWindow->regExp();
+ _verifier->setText( txt );
+ _verifier->verify( RegExpConverter::current()->toStr( regexp, true ) );
+ delete regexp;
+ }
+ _autoVerify = autoVerify;
+}
+
+void KRegExpEditorPrivate::setCaseSensitive( bool b )
+{
+ _verifier->setCaseSensitive( b );
+}
+
+void KRegExpEditorPrivate::setMinimal( bool b )
+{
+ _verifier->setMinimal( b );
+}
+
+void KRegExpEditorPrivate::setSyntax( const QString& syntax )
+{
+ RegExpConverter* converter = _verifyButtons->setSyntax( syntax );
+ RegExpConverter::setCurrent( converter );
+ if ( converter->canParse() ) {
+ _regexpEdit->setReadOnly( false );
+ _regexpEdit->setBackgroundMode( Qt::PaletteBase );
+ }
+ else {
+ _regexpEdit->setReadOnly( true );
+ _regexpEdit->setBackgroundMode( Qt::PaletteBackground );
+ }
+ _regExpButtons->setFeatures( converter->features() );
+ _verifier->setHighlighter( converter->highlighter(_verifier) );
+ slotUpdateLineEdit();
+}
+
+void KRegExpEditorPrivate::showHelp()
+{
+ _info->show();
+ _editor->hide();
+}
+
+void KRegExpEditorPrivate::setAllowNonQtSyntax( bool b )
+{
+ _verifyButtons->setAllowNonQtSyntax( b );
+}
diff --git a/kregexpeditor/kregexpeditorprivate.h b/kregexpeditor/kregexpeditorprivate.h
new file mode 100644
index 0000000..2e40fad
--- /dev/null
+++ b/kregexpeditor/kregexpeditorprivate.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef kregexpeditorprivate_h
+#define kregexpeditorprivate_h
+
+#include <qlabel.h>
+#include <qptrstack.h>
+#include "regexp.h"
+#include "errormap.h"
+class QTimer;
+
+class RegExpScrolledEditorWindow;
+class QLineEdit;
+class InfoPage;
+class UserDefinedRegExps;
+class QSplitter;
+class Verifier;
+class VerifyButtons;
+class AuxButtons;
+class RegExpLineEdit;
+class RegExpConverter;
+class RegExpButtons;
+class QToolButton;
+
+/**
+ Widget used to build a regular expression
+
+ @author Jesper K. Pedersen <blackie@kde.org>
+ @version 0.1
+**/
+class KRegExpEditorPrivate :public QWidget
+{
+ Q_OBJECT
+
+public:
+ KRegExpEditorPrivate( QWidget *parent, const char *name = 0 );
+ QString regexp();
+ void setMinimal( bool );
+ void setCaseSensitive( bool );
+ void setAllowNonQtSyntax( bool );
+
+protected slots:
+ void slotUpdateEditor( const QString & );
+ void slotUpdateLineEdit();
+ void slotShowEditor();
+ void slotTriggerUpdate();
+ void slotTimeout();
+ void maybeVerify();
+ void doVerify();
+ void setAutoVerify( bool );
+ void setVerifyText( const QString& fileName );
+
+public slots:
+ void slotUndo();
+ void slotRedo();
+ void slotSetRegexp( QString regexp );
+ void setMatchText( const QString& text );
+ void setSyntax( const QString& );
+ void showHelp();
+
+signals:
+ void canUndo( bool );
+ void canRedo( bool );
+ void changes( bool );
+
+protected:
+ void recordUndoInfo();
+ void emitUndoRedoSignals();
+
+private:
+ RegExpScrolledEditorWindow* _scrolledEditorWindow;
+ RegExpButtons* _regExpButtons;
+ VerifyButtons* _verifyButtons;
+ AuxButtons *_auxButtons;
+ InfoPage* _info;
+ QLineEdit* _regexpEdit;
+ QSplitter* _editor;
+ bool _updating;
+ QLabel* _error;
+ QPtrStack<RegExp> _undoStack;
+ QPtrStack<RegExp> _redoStack;
+ UserDefinedRegExps* _userRegExps;
+ QTimer* _timer;
+ Verifier* _verifier;
+ bool _autoVerify;
+ ErrorMap _errorMap;
+ QToolButton *clearButton;
+};
+
+#endif
+
diff --git a/kregexpeditor/limitedcharlineedit.cpp b/kregexpeditor/limitedcharlineedit.cpp
new file mode 100644
index 0000000..9631603
--- /dev/null
+++ b/kregexpeditor/limitedcharlineedit.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "limitedcharlineedit.h"
+#include <qvalidator.h>
+
+/**
+ @internal
+ A Validator for the @ref LimitedCharLineEdit
+*/
+class Validator :public QValidator
+{
+public:
+ Validator( LimitedCharLineEdit::Mode mode, QWidget* parent )
+ :QValidator( parent, "Validator" ), _mode(mode)
+ {
+ }
+
+ virtual QValidator::State validate( QString& txt, int & /*pos*/ ) const
+ {
+ if ( _mode == LimitedCharLineEdit::NORMAL ||
+ (_mode == LimitedCharLineEdit::HEX &&
+ QRegExp(QString::fromLocal8Bit("^[0-9A-Fa-f]*$")).search( txt ) != -1) ||
+ (_mode == LimitedCharLineEdit::OCT &&
+ QRegExp(QString::fromLocal8Bit("^[0-7]*$")).search( txt ) != -1 ) ) {
+ return QValidator::Acceptable;
+ }
+ else {
+ return QValidator::Invalid;
+ }
+ }
+
+private:
+ LimitedCharLineEdit::Mode _mode;
+};
+
+
+void LimitedCharLineEdit::keyPressEvent ( QKeyEvent *event )
+{
+ QLineEdit::keyPressEvent( event );
+ if ( text().length() == _count && !event->text().isNull() )
+ focusNextPrevChild(true);
+}
+
+LimitedCharLineEdit::LimitedCharLineEdit( Mode mode, QWidget* parent, const char* name )
+ :QLineEdit( parent, name ), _mode(mode)
+{
+ if ( mode == NORMAL )
+ _count = 1;
+ else if ( mode == HEX )
+ _count = 4;
+ else
+ _count = 4;
+
+ setMaxLength( _count );
+ setFixedSize( fontMetrics().width('A')*5+5, sizeHint().height());
+
+ setValidator( new Validator( mode, this ) );
+}
+
+
diff --git a/kregexpeditor/limitedcharlineedit.h b/kregexpeditor/limitedcharlineedit.h
new file mode 100644
index 0000000..d4654c6
--- /dev/null
+++ b/kregexpeditor/limitedcharlineedit.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __limitedcharlineedit
+#define __limitedcharlineedit
+
+#include <qlineedit.h>
+
+/**
+ QLineEdit which only accepts a prespecified number of character.
+ @internal
+*/
+class LimitedCharLineEdit :public QLineEdit
+{
+public:
+ enum Mode { NORMAL = 0, HEX = 1, OCT = 2 };
+
+ LimitedCharLineEdit(Mode mode, QWidget* parent, const char *name = 0);
+
+protected:
+ virtual void keyPressEvent ( QKeyEvent * );
+
+private:
+ Mode _mode;
+ unsigned int _count;
+};
+
+#endif
+
diff --git a/kregexpeditor/lookaheadregexp.cpp b/kregexpeditor/lookaheadregexp.cpp
new file mode 100644
index 0000000..7415ca4
--- /dev/null
+++ b/kregexpeditor/lookaheadregexp.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "lookaheadregexp.h"
+#include "errormap.h"
+
+LookAheadRegExp::LookAheadRegExp( bool selected, TYPE tp, RegExp* child )
+ : RegExp( selected ), _child( child ), _tp( tp )
+{
+ if ( child )
+ addChild( child );
+}
+
+bool LookAheadRegExp::check( ErrorMap& map, bool , bool last )
+{
+ if ( !last ) {
+ map.lookAheadError();
+ }
+ return true;
+}
+
+
+QDomNode LookAheadRegExp::toXml( QDomDocument* doc ) const
+{
+ QDomElement top;
+ if ( _tp == POSITIVE )
+ top = doc->createElement( QString::fromLocal8Bit("PositiveLookAhead") );
+ else
+ top = doc->createElement( QString::fromLocal8Bit("NegativeLookAhead") );
+
+ top.appendChild( _child->toXml( doc ) );
+ return top;
+}
+
+bool LookAheadRegExp::load( QDomElement top, const QString& version )
+{
+ _child = readRegExp( top, version );
+ if ( _child ) {
+ addChild( _child );
+ return true;
+ }
+ else
+ return false;
+}
+
+
+bool LookAheadRegExp::operator==( const RegExp& other ) const
+{
+ if ( type() != other.type() )
+ return false;
+
+ const LookAheadRegExp& theOther = dynamic_cast<const LookAheadRegExp&>( other );
+
+ if ( lookAheadType() != theOther.lookAheadType() )
+ return false;
+
+ return ( *_child == *(theOther._child) );
+}
diff --git a/kregexpeditor/lookaheadregexp.h b/kregexpeditor/lookaheadregexp.h
new file mode 100644
index 0000000..9021710
--- /dev/null
+++ b/kregexpeditor/lookaheadregexp.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __LOOKAHEADREGEXP_H
+#define __LOOKAHEADREGEXP_H
+
+#include "regexp.h"
+
+/**
+ Abstract syntax node for `repeated content' regular expression
+ @internal
+*/
+class LookAheadRegExp :public RegExp
+{
+public:
+ enum TYPE { POSITIVE, NEGATIVE };
+
+ LookAheadRegExp( bool selected, TYPE tp, RegExp* child = 0);
+
+ virtual bool check( ErrorMap&, bool first, bool last );
+ virtual int precedence() const { return 4;}
+ virtual QDomNode toXml( QDomDocument* doc ) const;
+ virtual bool load( QDomElement, const QString& version );
+ RegExp* child() const { return _child; }
+ TYPE lookAheadType() const { return _tp; }
+ virtual RegExpType type() const { return LOOKAHEAD;}
+ virtual bool operator==( const RegExp& other ) const;
+ virtual void replacePart( CompoundRegExp* replacement ) { _child->replacePart( replacement ); }
+
+private:
+ RegExp* _child;
+ TYPE _tp;
+};
+
+#endif // __LOOKAHEADREGEXP_H
diff --git a/kregexpeditor/lookaheadwidget.cpp b/kregexpeditor/lookaheadwidget.cpp
new file mode 100644
index 0000000..b724a3c
--- /dev/null
+++ b/kregexpeditor/lookaheadwidget.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <klocale.h>
+ #include "lookaheadwidget.moc"
+#endif
+
+#include "lookaheadwidget.h"
+#include "lookaheadregexp.h"
+#include "concwidget.h"
+#include <qpainter.h>
+
+LookAheadWidget::LookAheadWidget( RegExpEditorWindow* editorWindow, RegExpType tp, QWidget* parent, const char* name )
+ :SingleContainerWidget(editorWindow, parent, name ? name : "LookAheadWidget" ), _tp(tp)
+{
+ _child = new ConcWidget( editorWindow, this );
+ init();
+}
+
+LookAheadWidget::LookAheadWidget( LookAheadRegExp* regexp, RegExpEditorWindow* editorWindow, RegExpType tp,
+ QWidget* parent, const char* name )
+ :SingleContainerWidget( editorWindow, parent, name ? name : "LookAheadWidget" ), _tp(tp)
+{
+ RegExpWidget* child = WidgetFactory::createWidget( regexp->child(), editorWindow, this );
+ if ( ! (_child = dynamic_cast<ConcWidget*>( child ) ) )
+ _child = new ConcWidget( editorWindow, child, this );
+
+ init();
+}
+
+void LookAheadWidget::init()
+{
+ if ( _tp == POSLOOKAHEAD )
+ _text = i18n("Pos. Look Ahead");
+ else
+ _text = i18n("Neg. Look Ahead");
+}
+
+RegExp* LookAheadWidget::regExp() const
+{
+ return new LookAheadRegExp( isSelected(), ( (_tp == POSLOOKAHEAD) ? LookAheadRegExp::POSITIVE : LookAheadRegExp::NEGATIVE),
+ _child->regExp() );
+}
+
+QSize LookAheadWidget::sizeHint() const
+{
+ // TODO: Merge with RepeatWidget::sizeHint
+ QFontMetrics metrics = fontMetrics();
+ _textSize = metrics.size( 0, _text );
+
+ _childSize = _child->sizeHint();
+
+ int height = _textSize.height() + bdSize + _childSize.height() + bdSize + 2*pw;
+ int width = 2 * pw + QMAX(_childSize.width(), 4*bdSize + _textSize.width());
+ return QSize(width,height);
+}
+
+void LookAheadWidget::paintEvent( QPaintEvent *e )
+{
+ // TODO: Merge with RepeatWidget::paintEvent
+ QSize mySize = sizeHint();
+ QPainter painter(this);
+
+ drawPossibleSelection( painter, mySize );
+
+ // move the child to its position and resize it.
+ _child->move(pw,_textSize.height()+bdSize);
+ _child->resize(mySize.width() - 2*pw, _childSize.height());
+
+ // Draw the border and the text.
+ int startY = _textSize.height()/2;
+
+ // Top lines and text
+ painter.drawLine(pw,startY,bdSize,startY);
+ painter.drawText(pw+2*bdSize,0,_textSize.width(), _textSize.height(),0, _text);
+ int offset = pw + 3*bdSize + _textSize.width();
+ painter.drawLine(offset,startY,mySize.width()-pw,startY);
+
+ // horizontal lines
+ painter.drawLine(0,startY,0,mySize.height()-pw);
+ painter.drawLine(mySize.width()-pw,startY,mySize.width()-pw, mySize.height()-pw);
+
+ // buttom line
+ painter.drawLine(0, mySize.height()-pw, mySize.width()-pw, mySize.height()-pw);
+
+ SingleContainerWidget::paintEvent(e);
+}
+
+RegExpWidget* LookAheadWidget::findWidgetToEdit( QPoint globalPos )
+{
+ return _child->findWidgetToEdit( globalPos );
+}
diff --git a/kregexpeditor/lookaheadwidget.h b/kregexpeditor/lookaheadwidget.h
new file mode 100644
index 0000000..5e244b8
--- /dev/null
+++ b/kregexpeditor/lookaheadwidget.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __lookaheadwidget
+#define __lookaheadwidget
+
+#include "singlecontainerwidget.h"
+class LookAheadRegExp;
+
+class LookAheadWidget :public SingleContainerWidget
+{
+ Q_OBJECT
+public:
+ LookAheadWidget( RegExpEditorWindow* editorWindow, RegExpType tp, QWidget* parent, const char* name = 0 );
+ LookAheadWidget( LookAheadRegExp* regexp, RegExpEditorWindow* editorWindow, RegExpType tp,
+ QWidget* parent, const char* name = 0);
+
+ virtual RegExp* regExp() const;
+ virtual RegExpType type() const { return _tp; }
+ virtual QSize sizeHint() const;
+ virtual RegExpWidget* findWidgetToEdit( QPoint globalPos );
+
+
+protected:
+ void init();
+ virtual void paintEvent( QPaintEvent *e );
+
+
+private:
+ RegExpType _tp;
+ QString _text;
+
+ mutable QSize _textSize;
+ mutable QSize _childSize;
+};
+
+#endif // __lookaheadwidget
diff --git a/kregexpeditor/main.cpp b/kregexpeditor/main.cpp
new file mode 100644
index 0000000..bde19e9
--- /dev/null
+++ b/kregexpeditor/main.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifdef QT_ONLY
+ #include "compat.h"
+ #include <qapplication.h>
+#else
+ #include <kaboutdata.h>
+ #include <kapplication.h>
+ #include <kcmdlineargs.h>
+ #include <klocale.h>
+ #include <kpushbutton.h>
+#endif
+
+#include "kregexpeditorgui.h"
+#include <qlayout.h>
+
+int main( int argc, char* argv[] )
+{
+#ifdef QT_ONLY
+ QApplication myapp( argc, argv );
+#else
+ KAboutData aboutData( "kregexpeditor", I18N_NOOP("RegExp Editor"),
+ "1.0", I18N_NOOP("Editor for Regular Expressions"),
+ KAboutData::License_GPL,
+ "(c) 2002-2003 Jesper K. Pedersen");
+ KCmdLineArgs::init(argc, argv, &aboutData);
+ KApplication myapp;
+#endif
+
+ QDialog* top = new QDialog( 0 );
+ QVBoxLayout* lay = new QVBoxLayout( top, 6 );
+
+ KRegExpEditorGUI* iface = new KRegExpEditorGUI( top, "_editor", QStringList() );
+ iface->doSomething( QString::fromLatin1("setAllowNonQtSyntax"), (bool*) true );
+ lay->addWidget( iface );
+
+ QHBoxLayout* lay2 = new QHBoxLayout( lay, 6 );
+ KPushButton* help = new KPushButton( KStdGuiItem::help(), top );
+ KPushButton* quit = new KPushButton( KStdGuiItem::quit(), top );
+
+ lay2->addWidget( help );
+ lay2->addStretch(1);
+ lay2->addWidget( quit );
+
+ QObject::connect( help, SIGNAL( clicked() ), iface, SLOT( showHelp() ) );
+ QObject::connect( quit, SIGNAL( clicked() ), qApp, SLOT( quit() ) );
+
+ top->show();
+ QObject::connect( qApp, SIGNAL( lastWindowClosed() ), qApp, SLOT( quit() ) );
+ myapp.exec();
+}
+
diff --git a/kregexpeditor/multicontainerwidget.cpp b/kregexpeditor/multicontainerwidget.cpp
new file mode 100644
index 0000000..b4ae399
--- /dev/null
+++ b/kregexpeditor/multicontainerwidget.cpp
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "multicontainerwidget.h"
+#include "dragaccepter.h"
+
+MultiContainerWidget::MultiContainerWidget( RegExpEditorWindow* editorWindow,
+ QWidget* parent, const char* name)
+ :RegExpWidget( editorWindow, parent, name )
+{
+}
+
+void MultiContainerWidget::append( RegExpWidget* child )
+{
+ child->reparent( this, QPoint(0,0), false );
+ _children.append( child );
+ _children.append( new DragAccepter( _editorWindow, this ) );
+}
+
+bool MultiContainerWidget::hasSelection() const
+{
+ if ( _isSelected )
+ return true;
+
+ QPtrListIterator<RegExpWidget> it(_children);
+ ++it; // Move past the first dragAccepter
+ for ( ; *it; it += 2 ) {
+ if ( (*it)->hasSelection() ) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void MultiContainerWidget::clearSelection()
+{
+ _isSelected = false;
+ for ( unsigned int i = 0; i< _children.count(); i++ ) {
+ _children.at(i)->clearSelection();
+ }
+}
+
+
+void MultiContainerWidget::deleteSelection()
+{
+ // run from the back to the front (which we do since we delete items on the run)
+ // When deleting children, delete the drag accepter to its right.
+ for ( int i = (int) _children.count()-2; i > 0; i -=2 ) {
+
+ RegExpWidget* child = _children.at( i );
+ if ( child->isSelected() ) {
+ delete _children.at( i+1 );
+ _children.remove( i+1 );
+ delete child;
+ _children.remove(i);
+ }
+ else if ( child->hasSelection() ) {
+ child->deleteSelection();
+ }
+ }
+ _isSelected = false;
+ update();
+}
+
+void MultiContainerWidget::addNewChild(DragAccepter *accepter, RegExpWidget *child)
+{
+ for ( unsigned int i=0; i<_children.count(); i+= 2 ) {
+ RegExpWidget *ch = _children.at( i );
+ if ( ch == accepter ) {
+ // Insert the new child
+ _children.insert( i+1, child );
+
+ // Insert an accepter as the next element.
+ DragAccepter *accepter = new DragAccepter( _editorWindow, this );
+
+ _children.insert( i+2, accepter );
+
+ // These two show's must come here otherwise a paintevent
+ // will be invoked, where the invariant, that a accepter is located at
+ // every second element.
+ child->show();
+ accepter->show();
+
+ update();
+
+ return;
+ }
+ }
+ qFatal("Accepter not found in list");
+}
+
+bool MultiContainerWidget::updateSelection(bool parentSelected)
+{
+ bool changed = false;
+ bool isSel = _isSelected;
+ QMemArray<bool> oldState(_children.count());
+ QMemArray<bool> newState(_children.count());
+
+ for (int i = 0; i< (int)_children.count();i++) {
+ oldState[i] = _children.at(i)->isSelected();
+ }
+
+ RegExpWidget::updateSelection( parentSelected );
+
+ int first;
+ int last;
+
+ // scan for the first selected item.
+ for (first = 1; first < (int) _children.count(); first+= 2 ) {
+ RegExpWidget* child = _children.at(first);
+ changed = child->updateSelection( _isSelected ) || changed;
+ newState[first] = child->isSelected();
+ if ( child->isSelected() )
+ break;
+ }
+
+ // scan for the last selected item
+ for (last = _children.count()-2; last>first; last -= 2) {
+ RegExpWidget* child = _children.at(last);
+ changed = child->updateSelection( _isSelected ) || changed;
+ newState[last] = child->isSelected();
+ if ( child->isSelected() )
+ break;
+ }
+
+ // everything between first and last must be selected.
+ for (int j = first+2; j<last; j+=2) {
+ RegExpWidget* child = _children.at(j);
+
+ changed = child->updateSelection( true ) || changed;
+ newState[j] = true;
+ }
+
+ // update drag accepters.
+ for (int k = 0; k< (int) _children.count(); k+=2) {
+ RegExpWidget* child = _children.at(k);
+ bool select;
+ if ( k == 0 || k == (int)_children.count()-1) {
+ // The elements at the border is only selected if the parent is selected.
+ select = _isSelected;
+ }
+ else {
+ // Drag accepters in the middle is selected if the elements at both
+ // sides are selected.
+ select = newState[k-1] && newState[k+1];
+ }
+
+ bool isChildSel = child->isSelected();
+ DragAccepter *accepter = dynamic_cast<DragAccepter*>(child);
+ if (accepter)
+ accepter->_isSelected = select;
+ if ( select != isChildSel )
+ child->repaint();
+ }
+
+ changed = changed || isSel != _isSelected;
+ if ( changed ) {
+ repaint();
+ }
+
+ return changed;
+}
+
+
+
+QRect MultiContainerWidget::selectionRect() const
+{
+ if ( _isSelected )
+ return QRect( mapToGlobal( QPoint(0,0) ), size() );
+ else {
+ QRect res;
+ QPtrListIterator<RegExpWidget> it(_children);
+ ++it; // Move past the first dragAccepter
+ for ( ; *it; it +=2 ) {
+ if ( (*it)->hasSelection() ) {
+ QRect childSel = (*it)->selectionRect();
+ if ( res.isNull() )
+ res = childSel;
+ else {
+ QRect newRes;
+ newRes.setLeft( QMIN( res.left(), childSel.left() ) );
+ newRes.setTop( QMIN( res.top(), childSel.top() ) );
+ newRes.setRight( QMAX( res.right(), childSel.right() ) );
+ newRes.setBottom( QMAX( res.bottom(), childSel.bottom() ) );
+ res = newRes;
+ }
+ }
+ }
+ return res;
+ }
+}
+
+RegExpWidget* MultiContainerWidget::widgetUnderPoint( QPoint globalPos, bool justVisibleWidgets )
+{
+ unsigned int start, incr;
+ if ( justVisibleWidgets ) {
+ start = 1;
+ incr = 2;
+ }
+ else {
+ start = 0;
+ incr = 1;
+ }
+
+ for ( unsigned int i = start; i < _children.count(); i+=incr ) {
+ RegExpWidget* wid = _children.at(i)->widgetUnderPoint( globalPos, justVisibleWidgets );
+ if ( wid )
+ return wid;
+ }
+ if ( justVisibleWidgets )
+ return 0;
+ else {
+ return RegExpWidget::widgetUnderPoint( globalPos, justVisibleWidgets );
+ }
+}
+
+RegExpWidget* MultiContainerWidget::findWidgetToEdit( QPoint globalPos )
+{
+ for ( unsigned int i = 1; i < _children.count(); i+=2 ) {
+ RegExpWidget* wid = _children.at(i)->findWidgetToEdit( globalPos );
+ if ( wid )
+ return wid;
+ }
+ return 0;
+}
+
+void MultiContainerWidget::selectWidget( bool sel )
+{
+ RegExpWidget::selectWidget( sel );
+ QPtrListIterator<RegExpWidget> it(_children);
+ for ( ; *it ; ++it ) {
+ (*it)->selectWidget( sel );
+ }
+ update();
+}
+
+void MultiContainerWidget::updateAll()
+{
+ for ( QPtrListIterator<RegExpWidget> it(_children); *it ; ++it ) {
+ (*it)->updateAll();
+ }
+ RegExpWidget::updateAll();
+}
+
+void MultiContainerWidget::updateCursorRecursively()
+{
+ for ( QPtrListIterator<RegExpWidget> it(_children); *it ; ++it ) {
+ (*it)->updateCursorRecursively();
+ }
+ updateCursorShape();
+}
diff --git a/kregexpeditor/multicontainerwidget.h b/kregexpeditor/multicontainerwidget.h
new file mode 100644
index 0000000..3fa4095
--- /dev/null
+++ b/kregexpeditor/multicontainerwidget.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __multicontainerwidget
+#define __multicontainerwidget
+
+#include "regexpwidget.h"
+
+/**
+ Abstract RegExp widget class representing widgets having multible children.
+ @internal
+*/
+class MultiContainerWidget :public RegExpWidget
+{
+public:
+ MultiContainerWidget( RegExpEditorWindow* editorWindow, QWidget* parent = 0,
+ const char* name = 0);
+ virtual bool hasSelection() const;
+ virtual void clearSelection();
+ virtual void deleteSelection();
+ virtual void addNewChild(DragAccepter *accepter, RegExpWidget *child);
+ virtual bool updateSelection(bool parentSelected);
+ virtual QRect selectionRect() const;
+ virtual RegExpWidget* widgetUnderPoint( QPoint globalPos, bool justVisibleWidgets );
+ virtual RegExpWidget* findWidgetToEdit( QPoint globalPos );
+ virtual void selectWidget( bool sel );
+ virtual void updateAll();
+ virtual void updateCursorRecursively();
+
+protected:
+ void append( RegExpWidget* child );
+ QPtrList<RegExpWidget> _children;
+};
+
+
+#endif // __multicontainerwidget
diff --git a/kregexpeditor/myfontmetrics.cpp b/kregexpeditor/myfontmetrics.cpp
new file mode 100644
index 0000000..cdf29b2
--- /dev/null
+++ b/kregexpeditor/myfontmetrics.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "myfontmetrics.h"
+
+QSize HackCalculateFontSize(QFontMetrics fm, QString str )
+{
+ QStringList list = QStringList::split( QString::fromLatin1("\n"), str );
+ int maxWidth = 0;
+ int height = 0;
+ for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
+ QSize size = fm.size( 0, *it );
+ maxWidth = QMAX( maxWidth, size.width() );
+ height += size.height();
+ }
+ return QSize( maxWidth, height );
+}
diff --git a/kregexpeditor/myfontmetrics.h b/kregexpeditor/myfontmetrics.h
new file mode 100644
index 0000000..649d32b
--- /dev/null
+++ b/kregexpeditor/myfontmetrics.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __MYFONTMETRICS_H
+#define __MYFONTMETRICS_H
+#include <qfontmetrics.h>
+#include <qstringlist.h>
+
+// QFontMetrics::size is broken, therefore I need this hack until it works in QT3
+
+QSize HackCalculateFontSize(QFontMetrics fm, QString str );
+
+#endif
diff --git a/kregexpeditor/pair.h b/kregexpeditor/pair.h
new file mode 100644
index 0000000..b7296c5
--- /dev/null
+++ b/kregexpeditor/pair.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __pair_h
+#define __pair_h
+
+/**
+ @internal
+*/
+template<class F, class S> class Pair
+{
+public:
+ Pair() {}
+ Pair(F first, S second) : _first(first), _second(second) {}
+ F first() { return _first; }
+ S second() { return _second; }
+private:
+ F _first;
+ S _second;
+
+};
+
+#endif // __pair_h
diff --git a/kregexpeditor/picts/Makefile.am b/kregexpeditor/picts/Makefile.am
new file mode 100644
index 0000000..32b5061
--- /dev/null
+++ b/kregexpeditor/picts/Makefile.am
@@ -0,0 +1,2 @@
+pics_DATA= altn.png begline.png compound.png neglookahead.png poslookahead.png select.png wordboundary.png anychar.png characters.png endline.png nonwordboundary.png repeat.png text.png error.png autoverify.png verify.png
+picsdir = $(kde_datadir)/kregexpeditor/pics
diff --git a/kregexpeditor/picts/altn.png b/kregexpeditor/picts/altn.png
new file mode 100644
index 0000000..900a1e9
--- /dev/null
+++ b/kregexpeditor/picts/altn.png
Binary files differ
diff --git a/kregexpeditor/picts/anychar.png b/kregexpeditor/picts/anychar.png
new file mode 100644
index 0000000..11048ca
--- /dev/null
+++ b/kregexpeditor/picts/anychar.png
Binary files differ
diff --git a/kregexpeditor/picts/autoverify.png b/kregexpeditor/picts/autoverify.png
new file mode 100644
index 0000000..af68612
--- /dev/null
+++ b/kregexpeditor/picts/autoverify.png
Binary files differ
diff --git a/kregexpeditor/picts/begline.png b/kregexpeditor/picts/begline.png
new file mode 100644
index 0000000..3465a9e
--- /dev/null
+++ b/kregexpeditor/picts/begline.png
Binary files differ
diff --git a/kregexpeditor/picts/characters.png b/kregexpeditor/picts/characters.png
new file mode 100644
index 0000000..7f218bf
--- /dev/null
+++ b/kregexpeditor/picts/characters.png
Binary files differ
diff --git a/kregexpeditor/picts/compound.png b/kregexpeditor/picts/compound.png
new file mode 100644
index 0000000..a56c9bb
--- /dev/null
+++ b/kregexpeditor/picts/compound.png
Binary files differ
diff --git a/kregexpeditor/picts/endline.png b/kregexpeditor/picts/endline.png
new file mode 100644
index 0000000..29b512e
--- /dev/null
+++ b/kregexpeditor/picts/endline.png
Binary files differ
diff --git a/kregexpeditor/picts/error.png b/kregexpeditor/picts/error.png
new file mode 100644
index 0000000..4738f60
--- /dev/null
+++ b/kregexpeditor/picts/error.png
Binary files differ
diff --git a/kregexpeditor/picts/neglookahead.png b/kregexpeditor/picts/neglookahead.png
new file mode 100644
index 0000000..3cc0291
--- /dev/null
+++ b/kregexpeditor/picts/neglookahead.png
Binary files differ
diff --git a/kregexpeditor/picts/nonwordboundary.png b/kregexpeditor/picts/nonwordboundary.png
new file mode 100644
index 0000000..b22f4d4
--- /dev/null
+++ b/kregexpeditor/picts/nonwordboundary.png
Binary files differ
diff --git a/kregexpeditor/picts/poslookahead.png b/kregexpeditor/picts/poslookahead.png
new file mode 100644
index 0000000..492692b
--- /dev/null
+++ b/kregexpeditor/picts/poslookahead.png
Binary files differ
diff --git a/kregexpeditor/picts/repeat.png b/kregexpeditor/picts/repeat.png
new file mode 100644
index 0000000..2646111
--- /dev/null
+++ b/kregexpeditor/picts/repeat.png
Binary files differ
diff --git a/kregexpeditor/picts/select.png b/kregexpeditor/picts/select.png
new file mode 100644
index 0000000..e04ab17
--- /dev/null
+++ b/kregexpeditor/picts/select.png
Binary files differ
diff --git a/kregexpeditor/picts/text.png b/kregexpeditor/picts/text.png
new file mode 100644
index 0000000..8b256ca
--- /dev/null
+++ b/kregexpeditor/picts/text.png
Binary files differ
diff --git a/kregexpeditor/picts/verify.png b/kregexpeditor/picts/verify.png
new file mode 100644
index 0000000..dd76b7c
--- /dev/null
+++ b/kregexpeditor/picts/verify.png
Binary files differ
diff --git a/kregexpeditor/picts/wordboundary.png b/kregexpeditor/picts/wordboundary.png
new file mode 100644
index 0000000..0e89a6b
--- /dev/null
+++ b/kregexpeditor/picts/wordboundary.png
Binary files differ
diff --git a/kregexpeditor/positionregexp.cpp b/kregexpeditor/positionregexp.cpp
new file mode 100644
index 0000000..df5311f
--- /dev/null
+++ b/kregexpeditor/positionregexp.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "positionregexp.h"
+#include "errormap.h"
+
+PositionRegExp::PositionRegExp( bool selected, PositionType tp ) :RegExp( selected )
+{
+ _tp = tp;
+}
+
+bool PositionRegExp::check( ErrorMap& map, bool first , bool last )
+{
+ if ( _tp == BEGLINE && !first) {
+ map.lineStartError();
+ }
+ else if ( _tp == ENDLINE && !last ) {
+ map.lineEndError();
+ }
+ return true;
+}
+
+QDomNode PositionRegExp::toXml( QDomDocument* doc ) const
+{
+ switch (_tp) {
+ case BEGLINE: return doc->createElement(QString::fromLocal8Bit( "BegLine" ) );
+ case ENDLINE: return doc->createElement(QString::fromLocal8Bit( "EndLine" ) );
+ case WORDBOUNDARY: return doc->createElement(QString::fromLocal8Bit( "WordBoundary" ) );
+ case NONWORDBOUNDARY: return doc->createElement(QString::fromLocal8Bit( "NonWordBoundary" ) );
+ }
+ return QDomNode();
+}
+
+bool PositionRegExp::load( QDomElement /* top */, const QString& /*version*/ )
+{
+ // Nothing to do.
+ return true;
+}
+
diff --git a/kregexpeditor/positionregexp.h b/kregexpeditor/positionregexp.h
new file mode 100644
index 0000000..db90f93
--- /dev/null
+++ b/kregexpeditor/positionregexp.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __POSITIONREGEXP_H
+#define __POSITIONREGEXP_H
+
+#include "regexp.h"
+
+/**
+ Abstract syntax node for `positions' regular expression
+ @internal
+*/
+class PositionRegExp :public RegExp
+{
+public:
+ enum PositionType { BEGLINE, ENDLINE, WORDBOUNDARY, NONWORDBOUNDARY };
+
+ PositionRegExp( bool selected, PositionType tp );
+ PositionType position() const { return _tp; }
+
+ virtual bool check( ErrorMap&, bool first, bool last );
+ virtual int precedence() const { return 4;}
+ virtual QDomNode toXml( QDomDocument* doc ) const;
+ virtual bool load( QDomElement, const QString& version );
+ virtual RegExpType type() const { return POSITION ;}
+
+private:
+ PositionType _tp;
+
+};
+
+#endif // __POSITIONREGEXP_H
diff --git a/kregexpeditor/predefined/General/Makefile.am b/kregexpeditor/predefined/General/Makefile.am
new file mode 100644
index 0000000..338481b
--- /dev/null
+++ b/kregexpeditor/predefined/General/Makefile.am
@@ -0,0 +1,5 @@
+pkg_DATA = spaces.regexp anything.regexp
+
+pkgdir = $(kde_datadir)/kregexpeditor/predefined/general
+
+EXTRA_DIST = $(pkg_DATA)
diff --git a/kregexpeditor/predefined/General/anything.regexp b/kregexpeditor/predefined/General/anything.regexp
new file mode 100644
index 0000000..d016906
--- /dev/null
+++ b/kregexpeditor/predefined/General/anything.regexp
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<!DOCTYPE RegularExpression PUBLIC "-//KDE//KRegexpEditor DTD 1.0//EN" "http://www.blackie.dk/kreg.dtd">
+<RegularExpression version="1.0" >
+ <Compound allowReplace="1" >
+ <Title>anything</Title>
+ <Description>This regular expression matches anything.</Description>
+ <Repeat lower="0" upper="-1" >
+ <AnyChar/>
+ </Repeat>
+ </Compound>
+</RegularExpression>
diff --git a/kregexpeditor/predefined/General/spaces.regexp b/kregexpeditor/predefined/General/spaces.regexp
new file mode 100644
index 0000000..5bf8696
--- /dev/null
+++ b/kregexpeditor/predefined/General/spaces.regexp
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<!DOCTYPE RegularExpression PUBLIC "-//KDE//KRegexpEditor DTD 1.0//EN" "http://www.blackie.dk/kreg.dtd">
+<RegularExpression version="1.0" >
+ <Compound allowReplace="1" >
+ <Title>spaces</Title>
+ <Description>Matches an arbitrary amount of whitespace.</Description>
+ <Repeat lower="0" upper="-1" >
+ <TextRange space="1" />
+ </Repeat>
+ </Compound>
+</RegularExpression>
diff --git a/kregexpeditor/predefined/Makefile.am b/kregexpeditor/predefined/Makefile.am
new file mode 100644
index 0000000..05812f8
--- /dev/null
+++ b/kregexpeditor/predefined/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS=General
diff --git a/kregexpeditor/predefined/README b/kregexpeditor/predefined/README
new file mode 100644
index 0000000..7740948
--- /dev/null
+++ b/kregexpeditor/predefined/README
@@ -0,0 +1,2 @@
+This directory contains the predefined regular expressions.
+Only one level of sub directories is supported.
diff --git a/kregexpeditor/qregexpparser.l b/kregexpeditor/qregexpparser.l
new file mode 100644
index 0000000..4fb90cc
--- /dev/null
+++ b/kregexpeditor/qregexpparser.l
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+%option noyywrap
+
+%{
+ #include <qstring.h>
+ #include "textrangeregexp.h"
+ #include "gen_qregexpparser.hh"
+#ifdef QT_ONLY
+ #include "compat.h"
+#endif
+ void parseRange( char* txt, int* min, int* max );
+ RegExp* parseCharClass( char* match );
+%}
+
+Escape \\.
+BackRef \\[1-9][0-9]*
+CharClass \[^?\]?[^]]*\]
+Range \{[0-9]*(,[0-9]*)?\}
+HexChar \\x[0-9a-fA-F]{1,4}
+OctChar \\0[0-7]{1,4}
+SpecialEsc \\[afnrtv]
+%%
+"\\b" return TOK_PosWordChar;
+"\\B" return TOK_PosNonWordChar;
+"\\d" {
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->setDigit( true );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+"\\D" {
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->setNonDigit( true );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+"\\s" {
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->setSpace( true );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+"\\S" {
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->setNonSpace( true );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+"\\w" {
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->setWordChar( true );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+"\\W" {
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->setNonWordChar( true );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+{SpecialEsc} {
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->addCharacter( QString::fromLocal8Bit( yytext ) );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+
+{HexChar} {
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->addCharacter( QString::fromLocal8Bit(yytext) );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+{OctChar} {
+ TextRangeRegExp* regexp = new TextRangeRegExp( false );
+ regexp->addCharacter( QString::fromLocal8Bit(yytext) );
+ qregexplval.regexp = regexp;
+ return TOK_CharClass;
+ }
+"." return TOK_Dot;
+"$" return TOK_Dollar;
+"^" return TOK_Carat;
+"(?:" return TOK_MagicLeftParent;
+"(?=" return TOK_PosLookAhead;
+"(?!" return TOK_NegLookAhead;
+"(" return TOK_LeftParen;
+")" return TOK_RightParent;
+"|" return TOK_Bar;
+"*" { qregexplval.range.min = 0; qregexplval.range.max=-1; return TOK_Quantifier; }
+"?" { qregexplval.range.min = 0; qregexplval.range.max=1; return TOK_Quantifier; }
+"+" { qregexplval.range.min = 1; qregexplval.range.max=-1; return TOK_Quantifier; }
+{Range} { parseRange( yytext, &qregexplval.range.min, &qregexplval.range.max ); return TOK_Quantifier; }
+{CharClass} { qregexplval.regexp = parseCharClass(yytext); return TOK_CharClass; }
+{BackRef} { qregexplval.backRef = atoi( yytext+1 ); return TOK_BackRef; }
+{Escape} { qregexplval.ch = yytext[1]; return TOK_EscapeChar; }
+. { qregexplval.ch = yytext[0]; return TOK_Char; }
+
+%%
+
+void setParseData( QString qstr ) {
+ const char* cstr;
+ if ( qstr.isNull() )
+ cstr = "";
+ else
+ cstr = qstr.latin1();
+ yy_switch_to_buffer( yy_scan_string( cstr ) );
+}
+
+/**
+ This function parses a range in a form similar to "{3,4}", "{,7}"
+ etc. and returns the value in the integers pointed to by min and max.
+*/
+void parseRange( char* txt, int* min, int* max )
+{
+
+ /*
+ case txt min max
+ 1 {} 0 -1
+ 2 {,} 0 -1
+ 3 {5} 5 5
+ 4 {5,} 5 -1
+ 5 {,7} 0 7
+ 6 {5,7} 5 7
+ */
+ char c;
+ int i = 1;
+ int minimum=0, maximum=0;
+ int minFound=0, maxFound=0, commaFound = 0;
+
+ while ( (c = txt[i++]) != ',' && c != '}') {
+ minimum = minimum*10+ c-'0';
+ minFound=1;
+ }
+
+ if ( c == ',' )
+ commaFound = 1;
+
+ if ( c != '}' ) {
+ while ( (c = txt[i++]) != '}') {
+ maximum = maximum*10+ c-'0';
+ maxFound = 1;
+ }
+ }
+
+ *min = minimum;
+ if ( maxFound )
+ *max = maximum; /* case 5,6 */
+ else if ( !minFound )
+ *max = -1; /* case 1,2 */
+ else if ( commaFound )
+ *max = -1; /* case 4 */
+ else
+ *max = minimum; /* case 3 */
+}
+
+
+/**
+ This function parses a character range like "[^ab1-4]".
+*/
+RegExp* parseCharClass( char* match )
+{
+ TextRangeRegExp* res = new TextRangeRegExp( false );
+ QString txt = QString::fromLocal8Bit( match );
+ txt = txt.mid(1,txt.length()-2);
+
+ unsigned int i = 0;
+ QChar ch = txt.at(i++);
+ QString pendingChar;
+ QString thisChar;
+ bool charPending = false;
+ bool rangePending = false;
+ bool flushPending = false;
+
+ if ( ch == QChar('^') ) {
+ res->setNegate( true );
+ ch = txt.at(i++);
+ }
+
+ do {
+ // If a character is pending, and the next char is '-' then we are
+ // possible looking at a range.
+ if ( ch == QChar('-') && charPending ) {
+ rangePending = true;
+ ch = txt.at(i++);
+ continue;
+ }
+
+ // If we have a pending character, but do not also have a pending
+ // range, then the pending character was not part of a range, and
+ // should therefore just be added as a single character.
+ if ( charPending && !rangePending ) {
+ res->addCharacter( pendingChar );
+ charPending = false;
+ }
+
+ if ( ch == QChar('\\') ) {
+ // Handle the cases where an escape character is specified.
+ ch = txt.at(i++);
+
+ if ( ch == QChar('a') || ch == QChar('f') || ch == QChar('n') || ch == QChar('r') || ch == QChar('t') || ch == QChar('v') ) {
+ // These are just seen as normal characters.
+ thisChar = QString::fromLocal8Bit("\\") + ch;
+ }
+ else if ( ch == QChar('d') ) {
+ // The following characters represent character groups. If any of
+ // these are seen in a range, then the range is ignored, thus [a-\s]
+ // matches an 'a', a '-', and a space (\s means space).
+ res->setDigit( true );
+ flushPending = true;
+ }
+ else if ( ch == QChar('D') ) {
+ res->setNonDigit( true );
+ flushPending = true;
+ }
+ else if ( ch == QChar('s') ) {
+ res->setSpace( true );
+ flushPending = true;
+ }
+ else if ( ch == QChar('S') ) {
+ res->setNonSpace( true );
+ flushPending = true;
+ }
+ else if ( ch == QChar('w') ) {
+ res->setWordChar( true );
+ flushPending = true;
+ }
+ else if ( ch == QChar('W') ) {
+ res->setNonWordChar( true );
+ flushPending = true;
+ }
+ else if ( ch == QChar('x') || ch == QChar('X') ) {
+ // This is a hexidecimal character: \xHHHH
+ QString str;
+ for ( int j=0; j<4; j++) {
+ ch = txt.at(i++);
+ if ( ch == 'a' || ch == 'A' || ch == 'b' || ch == 'B' || ch == 'c' || ch == 'C' || ch == 'd' || ch == 'D' ||
+ ch == 'e' || ch == 'E' || ch == 'f' || ch == 'F' ||
+ ch == '0' || ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5' || ch == '6' || ch == '7' ||
+ ch == '8' || ch == '9' )
+ str += ch;
+ else
+ i--;
+ }
+ thisChar = QString::fromLocal8Bit("\\x") + str;
+ }
+ else if ( ch == QChar('0') ) {
+ // This is an octal character
+ QString str;
+ for ( int j=0; j<4; j++) {
+ ch = txt.at(i++);
+ if ( ch == '0' || ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5' || ch == '6' || ch == '7' )
+ str += ch;
+ else
+ i--;
+ }
+ thisChar = QString::fromLocal8Bit("\\x") + str ;
+ }
+ else {
+ // Anything else escaped just means the character itself.
+ thisChar = ch;
+ }
+ }
+ else {
+ // A non escaped character.
+ thisChar = ch;
+ }
+
+ // The characters \s,\S,\w,\W,\d or \D, can not be part of a range,
+ // thus if they are meet in what looks like a range, then the
+ // characters of the range is justed seen as normal non range
+ // characters. thus [a-\s] matches an 'a', a '-', and a space (\s means
+ // space).
+ if ( flushPending ) {
+ if ( charPending )
+ res->addCharacter( pendingChar );
+ if ( rangePending )
+ res->addCharacter( QString::fromLocal8Bit("-") );
+ flushPending = false;
+ charPending = false;
+ rangePending = false;
+ }
+ else {
+ if ( rangePending ) {
+ res->addRange( pendingChar, thisChar );
+ charPending = false;
+ rangePending = false;
+ }
+ else {
+ pendingChar = thisChar;
+ charPending = true;
+ }
+ }
+ ch = txt.at(i++);
+ }
+ while ( ch != QChar(']') && i <= txt.length() );
+
+ if ( charPending )
+ res->addCharacter( pendingChar );
+ if ( rangePending )
+ res->addCharacter( QString::fromLocal8Bit("-") );
+
+ return res;
+}
diff --git a/kregexpeditor/qregexpparser.y b/kregexpeditor/qregexpparser.y
new file mode 100644
index 0000000..0faaf98
--- /dev/null
+++ b/kregexpeditor/qregexpparser.y
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+%{
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <klocale.h>
+ #include <kmessagebox.h>
+#endif
+
+ #include <qstring.h>
+ #include <stdlib.h>
+
+ #include "regexp.h"
+ #include "textregexp.h"
+ #include "textrangeregexp.h"
+ #include "repeatregexp.h"
+ #include "lookaheadregexp.h"
+ #include "concregexp.h"
+ #include "altnregexp.h"
+ #include "positionregexp.h"
+ #include "dotregexp.h"
+ #include "compoundregexp.h"
+
+ extern int yylex();
+ extern void setParseData( QString str );
+ int yyerror (const char *);
+ void setParseResult( RegExp* );
+ RegExp* parseQtRegExp( QString qstr, bool* ok );
+ static RegExp* parseResult;
+ static int _index;
+%}
+
+%union {
+ struct {
+ int min;
+ int max;
+ } range;
+ int backRef;
+ RegExp* regexp;
+ char ch;
+}
+
+%token TOK_Dot
+%token TOK_Dollar
+%token TOK_Carat
+%token TOK_MagicLeftParent
+%token TOK_PosLookAhead
+%token TOK_NegLookAhead
+%token TOK_LeftParen
+%token TOK_RightParent
+%token TOK_Bar
+%token TOK_Quantifier
+%token TOK_BackRef
+%token TOK_CharClass
+%token TOK_Char
+%token TOK_EscapeChar
+%token TOK_PosWordChar
+%token TOK_PosNonWordChar
+
+%start regexp
+
+%%
+
+empty : /* nothing */ ;
+
+regexp : expression { setParseResult( $<regexp>1) ; }
+ | empty { setParseResult( new ConcRegExp( false ) ); }
+ ;
+
+expression : expression TOK_Bar term {
+ if ( dynamic_cast<AltnRegExp*>( $<regexp>1 ) ) {
+ $<regexp>$ = $<regexp>1;
+ }
+ else {
+ $<regexp>$ = new AltnRegExp( false );
+ dynamic_cast<AltnRegExp*>( $<regexp>$ )->addRegExp( $<regexp>1 );
+ }
+ dynamic_cast<AltnRegExp*>( $<regexp>$ )->addRegExp( $<regexp>3 );
+ }
+ | term { $<regexp>$ = $<regexp>1; }
+ | expression TOK_Bar {
+ if ( dynamic_cast<AltnRegExp*>( $<regexp>1 ) ) {
+ $<regexp>$ = $<regexp>1;
+ }
+ else {
+ $<regexp>$ = new AltnRegExp( false );
+ dynamic_cast<AltnRegExp*>( $<regexp>$ )->addRegExp( $<regexp>1 );
+ }
+ dynamic_cast<AltnRegExp*>( $<regexp>$ )->addRegExp( new TextRegExp( false, QString::fromLatin1("") ) );
+ }
+ | TOK_Bar term {
+ $<regexp>$ = new AltnRegExp( false );
+ dynamic_cast<AltnRegExp*>( $<regexp>$ )->addRegExp( new TextRegExp( false, QString::fromLatin1("") ) );
+ dynamic_cast<AltnRegExp*>( $<regexp>$ )->addRegExp( $<regexp>2 );
+ }
+ | TOK_Bar { $<regexp>$ = new AltnRegExp( false ); }
+ ;
+
+term : term factor {
+ RegExp* last = dynamic_cast<ConcRegExp*>( $<regexp>1 )->lastRegExp();
+ TextRegExp *reg1, *reg2;
+
+ if ( last && ( reg1 = dynamic_cast<TextRegExp*>( last ) ) &&
+ ( reg2 = dynamic_cast<TextRegExp*>( $<regexp>2 ) ) ) {
+ reg1->append( reg2->text() );
+ delete reg2;
+ }
+ else {
+ dynamic_cast<ConcRegExp*>($<regexp>$)->addRegExp( $<regexp>2 );
+ }
+ $<regexp>$ = $<regexp>1;
+ }
+ | factor {
+ ConcRegExp* reg = new ConcRegExp( false );
+ reg->addRegExp( $<regexp>1 );
+ $<regexp>$ = reg;
+ }
+ ;
+
+factor : atom TOK_Quantifier {
+ $<regexp>$ = new RepeatRegExp( false, $<range>2.min, $<range>2.max, $<regexp>1 );
+ }
+ | atom { $<regexp>$ = $<regexp>1; }
+ ;
+
+atom : TOK_LeftParen expression TOK_RightParent {
+ $<regexp>$ = $<regexp>2;
+ }
+ | TOK_MagicLeftParent expression TOK_RightParent { $<regexp>$ = $<regexp>2; }
+ | TOK_PosLookAhead expression TOK_RightParent {
+ $<regexp>$ = new LookAheadRegExp( false, LookAheadRegExp::POSITIVE, $<regexp>2 );
+ }
+ | TOK_NegLookAhead expression TOK_RightParent {
+ $<regexp>$ = new LookAheadRegExp( false, LookAheadRegExp::NEGATIVE, $<regexp>2 );
+ }
+ | TOK_CharClass { $<regexp>$ = $<regexp>1; }
+ | char { $<regexp>$ = $<regexp>1; }
+ | TOK_Dollar { $<regexp>$ = new PositionRegExp( false, PositionRegExp::ENDLINE ); }
+ | TOK_Carat { $<regexp>$ = new PositionRegExp( false, PositionRegExp::BEGLINE ); }
+ | TOK_Dot { $<regexp>$ = new DotRegExp( false ); }
+ | TOK_BackRef {
+ QString match = QString::fromLocal8Bit("\\%1").arg( $<backRef>1 );
+ $<regexp>$ = new TextRegExp( false, match );
+ KMessageBox::information(0,i18n("<qt>Back reference regular expressions are not supported.<p>"
+ "<tt>\\1</tt>, <tt>\\2</tt>, ... are <i>back references</i>, meaning they refer to "
+ "previous matches. "
+ "Unfortunately this is not supported in the current version of this editor.<p>"
+ "In the graphical area the text <b>%1</b> has been inserted. This is however "
+ "just a workaround to ensure that the application handles the regexp at all. "
+ "Therefore, as soon as you edit the regular expression in the graphical area, "
+ "the back reference will be replaced by matching the text <b>%2</b> literally.")
+ .arg( match ).arg( match ),
+ i18n("Back reference regular expressions not supported"),
+ QString::fromLocal8Bit("backReferenceNotSupported") );
+ }
+ | TOK_PosWordChar { $<regexp>$ = new PositionRegExp( false, PositionRegExp::WORDBOUNDARY ); }
+ | TOK_PosNonWordChar { $<regexp>$ = new PositionRegExp( false, PositionRegExp::NONWORDBOUNDARY ); }
+ ;
+
+char : TOK_Char {
+ if ( $<ch>1 == '{' || $<ch>1 == '}' || $<ch>1 == '[' || $<ch>1 == ']' || $<ch>1 == '\\' ) {
+ yyerror( "illigal character - needs escaping" );
+ }
+ $<regexp>$ = new TextRegExp( false, QString::fromLocal8Bit("%1").arg($<ch>1));
+ }
+ | TOK_EscapeChar { $<regexp>$ = new TextRegExp( false, QString::fromLocal8Bit("%1").arg($<ch>1)); }
+ ;
+
+%%
+
+RegExp* parseQtRegExp( QString qstr, bool* ok ) {
+ _index = 0;
+ parseResult = 0;
+ setParseData( qstr );
+ yyparse();
+ *ok = ( yynerrs == 0 );
+ return parseResult;
+}
+
+void setParseResult( RegExp* regexp ) {
+ parseResult = regexp;
+}
+
+int yyerror(const char *) {
+ yynerrs++;
+ return 0;
+}
diff --git a/kregexpeditor/qt-only/clean b/kregexpeditor/qt-only/clean
new file mode 100755
index 0000000..57e9a6d
--- /dev/null
+++ b/kregexpeditor/qt-only/clean
@@ -0,0 +1,14 @@
+#!/bin/sh
+rm *.o
+rm *.obj
+rm -rf manual
+rm -rf predefined
+rm -rf icons
+rm unistd.h
+find -lname \* -maxdepth 1 | xargs rm
+rm moc_*
+rm images.h
+rm gen_*
+rm -rf kregexpeditor*
+rm Makefile
+rm kregexpeditor.zip
diff --git a/kregexpeditor/qt-only/compat.cpp b/kregexpeditor/qt-only/compat.cpp
new file mode 100644
index 0000000..7dbc7b4
--- /dev/null
+++ b/kregexpeditor/qt-only/compat.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2002-2004 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#include "compat.h"
+
+QString i18n( const QString& a) {
+ return QObject::tr(a);
+}
+
+QString i18n( const QString& a, const QString& b) {
+ return QObject::tr(b,a);
+}
+
+KDialogBase::KDialogBase( int /*dialogFace*/, const QString &caption, int buttonMask,
+ ButtonCode defaultButton, QWidget *parent, const char *name,
+ bool modal )
+ :QDialog( parent, name, modal )
+{
+ init( buttonMask, defaultButton, caption );
+}
+
+KDialogBase::KDialogBase( QWidget* parent, const char* name, bool modal,
+ const QString& caption, int buttonMask )
+ : QDialog( parent, name, modal )
+{
+ init( buttonMask, Ok, caption );
+}
+
+void KDialogBase::init( int buttonMask, ButtonCode /*defaultButton*/, const QString& caption )
+{
+ setCaption( caption );
+ _layout = new QVBoxLayout( this, 6 );
+ QHBoxLayout* buts = new QHBoxLayout( _layout, 6 );
+ QPushButton* but;
+ if ( buttonMask & Help ) {
+ but = new QPushButton( tr("Help"), this );
+ buts->addWidget( but );
+ connect( but, SIGNAL( clicked() ), this, SIGNAL( helpClicked() ) );
+ }
+ buts->addStretch(1);
+ if ( buttonMask & Ok ) {
+ but = new QPushButton( tr("OK"), this );
+ buts->addWidget( but );
+ connect( but, SIGNAL( clicked() ), this, SLOT( slotOk() ) );
+ }
+ if ( buttonMask & Cancel ) {
+ but = new QPushButton( tr("Cancel"), this );
+ buts->addWidget( but );
+ connect( but, SIGNAL( clicked() ), this, SLOT( slotCancel() ) );
+ }
+}
+
+void KDialogBase::setMainWidget( QWidget* top )
+{
+ top->reparent( this, 0, QPoint(0,0) );
+ _layout->insertWidget( 0, top );
+}
+
+QFrame* KDialogBase::plainPage()
+{
+ QFrame* frame = new QFrame( this );
+ setMainWidget( frame );
+ return frame;
+}
+
+void KDialogBase::slotOk()
+{
+ accept();
+ emit okClicked();
+ emit finished();
+}
+
+void KDialogBase::slotCancel()
+{
+ reject();
+ emit cancelClicked();
+ emit finished();
+}
+
+int KMessageBox::warningYesNo(QWidget *parent, const QString &text, const QString &caption )
+{
+ int code = warning( parent, caption, text, tr("No"), tr("Yes") );
+ if ( code == 0 )
+ return Yes;
+ else
+ return No;
+}
+
+int KMessageBox::information( QWidget* parent, const QString& text, const QString& caption,
+ const QString& /*dontShowAgainName*/ )
+{
+ return QMessageBox::information( parent, caption, text );
+}
+
+int KMessageBox::sorry( QWidget* parent, const QString& text, const QString& caption )
+{
+ return QMessageBox::information( parent, caption, text );
+}
+
+
diff --git a/kregexpeditor/qt-only/compat.h b/kregexpeditor/qt-only/compat.h
new file mode 100644
index 0000000..edf9ced
--- /dev/null
+++ b/kregexpeditor/qt-only/compat.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2002-2004 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifndef COMPAT_H
+#define COMPAT_H
+#include <qobject.h>
+#include <qmessagebox.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qinputdialog.h>
+#include <qframe.h>
+
+QString i18n( const QString& a);
+QString i18n( const QString& a, const QString& b);
+#define isatty(x) 0
+
+#define KTextBrowser QTextBrowser
+#define KListBox QListBox
+#define KFileDialog QFileDialog
+#define KPushButton QPushButton
+
+class KDialogBase :public QDialog
+{
+ Q_OBJECT
+
+public:
+ enum ButtonCode {Ok = 1, Cancel, Help};
+ enum DialogType { Plain };
+
+ KDialogBase ( int dialogFace, const QString &caption, int buttonMask,
+ ButtonCode defaultButton,
+ QWidget *parent=0, const char *name=0, bool modal=true );
+
+ KDialogBase( QWidget* parent, const char* name = 0, bool modal = true,
+ const QString& caption = QString::null,
+ int buttonMask = 0 );
+
+ void init( int buttonMask, ButtonCode /*defaultButton*/, const QString& caption );
+ void setMainWidget( QWidget* top );
+ QFrame* plainPage();
+ void setHelp( const QString&, const QString& ) {}
+
+public slots:
+ void slotOk();
+ void slotCancel();
+
+signals:
+ void okClicked();
+ void cancelClicked();
+ void finished();
+ void helpClicked();
+
+private:
+ QVBoxLayout* _layout;
+};
+
+class KMessageBox :public QMessageBox
+{
+ Q_OBJECT
+public:
+ enum ButtonCode { Ok = 1, Cancel = 2, Yes = 3, No = 4, Continue = 5 };
+ static int warningYesNo (QWidget *parent, const QString &text,
+ const QString &caption = QString::null );
+ static int information( QWidget* parent, const QString& text, const QString& caption = QString::null,
+ const QString& /*dontShowAgainName*/ = QString::null );
+ static int sorry( QWidget* parent, const QString& text, const QString& caption = QString::null );
+};
+
+#endif /* COMPAT_H */
+
diff --git a/kregexpeditor/qt-only/compile b/kregexpeditor/qt-only/compile
new file mode 100755
index 0000000..d6fb6c6
--- /dev/null
+++ b/kregexpeditor/qt-only/compile
@@ -0,0 +1,28 @@
+#!/bin/bash
+# On Linux do this
+ln -s ../*.{cpp,h,y,l} .
+ln -s ../{KMultiFormListBox,KWidgetStreamer}/*.{cpp,h} .
+ln -s $KDESRC/kdelibs/interfaces/kregexpeditor/kregexpeditorinterface.h .
+ln -s gen_qregexpparser.cc gen_qregexpparser.cpp
+touch unistd.h
+mkdir icons
+cp ../picts/* icons
+cp $KDEDIR/share/icons/crystalsvg/22x22/actions/{undo,redo,editcut,editcopy,editpaste,fileopen,filesave,contexthelp,1downarrow,1uparrow}.png icons
+mkdir predefined
+mkdir predefined/General
+cp ../predefined/General/*.regexp predefined/General
+
+flex -Pqregexp -ogen_qregexplexer.cpp qregexpparser.l
+bison -d -p qregexp -o gen_qregexpparser.cc qregexpparser.y
+
+mkdir manual
+cd manual
+meinproc $KDESRC/kdeutils/doc/KRegExpEditor/index.docbook
+for x in *.html; do sed 's/<img src="help:[^>]*>//' < $x > tmp.html; mv tmp.html $x; done
+cp $KDESRC/kdeutils/doc/KRegExpEditor/*.png .
+cd ..
+(cd icons; $QTDIR/tools/qembed/qembed --images *.png > ../images.h)
+
+# Now on windows do the following
+qmake
+make
diff --git a/kregexpeditor/qt-only/qt-only.pro b/kregexpeditor/qt-only/qt-only.pro
new file mode 100644
index 0000000..9af8b97
--- /dev/null
+++ b/kregexpeditor/qt-only/qt-only.pro
@@ -0,0 +1,137 @@
+TEMPLATE = app
+INCLUDEPATH += .
+DEFINES += QT_ONLY
+TARGET = kregexpeditor
+
+win32-msvc:QMAKE_CXXFLAGS += /GX /GR
+QMAKE_CLEAN+=vc60.pdb kdexecutor.dsp
+
+
+# If this is a compile for House Of Fusion, then add the following line
+DEFINES+=HOUSEOFFUSION
+
+# Input
+HEADERS += altnregexp.h \
+ altnwidget.h \
+ auxbuttons.h \
+ ccp.h \
+ characterswidget.h \
+ charselector.h \
+ compoundregexp.h \
+ compoundwidget.h \
+ concregexp.h \
+ concwidget.h \
+ dcbutton.h \
+ dotregexp.h \
+ drag.h \
+ dragaccepter.h \
+ editorwindow.h \
+ emacsregexpconverter.h \
+ errormap.h \
+ gen_qregexpparser.hh \
+ indexWindow.h \
+ infopage.h \
+ kmultiformlistbox-multivisible.h \
+ kmultiformlistbox-shower.h \
+ kmultiformlistbox-windowed.h \
+ kmultiformlistbox.h \
+ kmultiformlistboxentry.h \
+ kmultiformlistboxfactory.h \
+ kregexpeditorgui.h \
+ kregexpeditorprivate.h \
+ kwidgetstreamer.h \
+ limitedcharlineedit.h \
+ lookaheadregexp.h \
+ lookaheadwidget.h \
+ multicontainerwidget.h \
+ myfontmetrics.h \
+ pair.h \
+ positionregexp.h \
+ qtregexpconverter.h \
+ qtregexphighlighter.h \
+ regexp.h \
+ regexpbuttons.h \
+ regexpconverter.h \
+ regexphighlighter.h \
+ regexpwidget.h \
+ repeatregexp.h \
+ repeatwidget.h \
+ scrollededitorwindow.h \
+ selectablelineedit.h \
+ singlecontainerwidget.h \
+ textrangeregexp.h \
+ textregexp.h \
+ textwidget.h \
+ triple.h \
+ userdefinedregexps.h \
+ verifier.h \
+ verifybuttons.h \
+ widgetfactory.h \
+ widgetwindow.h \
+ windowlistboxitem.h \
+ zerowidgets.h\
+ compat.h \
+ images.h
+
+#LEXSOURCES += qregexpparser.l
+#YACCSOURCES += qregexpparser.y
+YACC=bison
+SOURCES += altnregexp.cpp \
+ altnwidget.cpp \
+ auxbuttons.cpp \
+ ccp.cpp \
+ characterswidget.cpp \
+ charselector.cpp \
+ compoundregexp.cpp \
+ compoundwidget.cpp \
+ concregexp.cpp \
+ concwidget.cpp \
+ dcbutton.cpp \
+ dotregexp.cpp \
+ drag.cpp \
+ dragaccepter.cpp \
+ editorwindow.cpp \
+ emacsregexpconverter.cpp \
+ errormap.cpp \
+ gen_qregexplexer.cpp \
+ indexWindow.cpp \
+ infopage.cpp \
+ kmultiformlistbox-multivisible.cpp \
+ kmultiformlistbox-windowed.cpp \
+ kmultiformlistbox.cpp \
+ kmultiformlistboxentry.cpp \
+ kmultiformlistboxfactory.cpp \
+ kregexpeditorgui.cpp \
+ kregexpeditorprivate.cpp \
+ kwidgetstreamer.cpp \
+ limitedcharlineedit.cpp \
+ lookaheadregexp.cpp \
+ lookaheadwidget.cpp \
+ main.cpp \
+ multicontainerwidget.cpp \
+ myfontmetrics.cpp \
+ positionregexp.cpp \
+ qtregexpconverter.cpp \
+ qtregexphighlighter.cpp \
+ regexp.cpp \
+ regexpbuttons.cpp \
+ regexpconverter.cpp \
+ regexphighlighter.cpp \
+ regexpwidget.cpp \
+ repeatregexp.cpp \
+ repeatwidget.cpp \
+ scrollededitorwindow.cpp \
+ selectablelineedit.cpp \
+ singlecontainerwidget.cpp \
+ textrangeregexp.cpp \
+ textregexp.cpp \
+ textwidget.cpp \
+ userdefinedregexps.cpp \
+ verifier.cpp \
+ verifybuttons.cpp \
+ widgetfactory.cpp \
+ widgetwindow.cpp \
+ windowlistboxitem.cpp \
+ zerowidgets.cpp \
+ gen_qregexpparser.cpp \
+ compat.cpp
diff --git a/kregexpeditor/qt-only/win-release.bat b/kregexpeditor/qt-only/win-release.bat
new file mode 100644
index 0000000..967afc8
--- /dev/null
+++ b/kregexpeditor/qt-only/win-release.bat
@@ -0,0 +1,7 @@
+md kregexpeditor
+cp -r kregexpeditor.exe predefined kregexpeditor
+copy q:\3.1.2-mt\lib\qt-mt312.dll kregexpeditor
+copy c:\winnt\system32\MSVCRTD.DLL kregexpeditor
+copy c:\winnt\system32\MSVCP60D.DLL kregexpeditor
+cp -r manual kregexpeditor
+c:\zip\zip -r kregexpeditor.zip kregexpeditor
diff --git a/kregexpeditor/qtregexpconverter.cpp b/kregexpeditor/qtregexpconverter.cpp
new file mode 100644
index 0000000..198d7dd
--- /dev/null
+++ b/kregexpeditor/qtregexpconverter.cpp
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2002-2004 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#include "qtregexpconverter.h"
+#include "qtregexphighlighter.h"
+#include "regexp.h"
+#include "textregexp.h"
+#include "altnregexp.h"
+#include "concregexp.h"
+#include "lookaheadregexp.h"
+#include "textrangeregexp.h"
+#include "compoundregexp.h"
+#include "dotregexp.h"
+#include "positionregexp.h"
+#include "repeatregexp.h"
+
+extern RegExp* parseQtRegExp( QString str, bool *ok );
+extern RegExp* parseDataQtRegExp();
+
+bool QtRegExpConverter::canParse()
+{
+ return true;
+}
+
+
+RegExp* QtRegExpConverter::parse( const QString& txt, bool* ok )
+{
+ return parseQtRegExp( txt, ok );
+}
+
+QString QtRegExpConverter::toString( AltnRegExp* regexp, bool markSelection )
+{
+ QString res;
+
+ bool first = true;
+ RegExpList list = regexp->children();
+ for ( RegExpListIt it(list); *it; ++it ) {
+ if ( !first ) {
+ res += QString::fromLatin1( "|" );
+ }
+ first = false;
+ if ( markSelection && !regexp->isSelected() && (*it)->isSelected() ) {
+ res += QString::fromLatin1("(") + toStr( *it, markSelection ) + QString::fromLatin1(")");
+ }
+ else {
+ res += toStr( *it, markSelection );
+ }
+ }
+ return res;
+}
+
+QString QtRegExpConverter::toString( ConcRegExp* regexp, bool markSelection )
+{
+ QString res;
+ bool childSelected = false;
+
+ RegExpList list = regexp->children();
+ for ( RegExpListIt it(list); *it; ++it ) {
+ QString startPar = QString::fromLocal8Bit("");
+ QString endPar = QString::fromLocal8Bit("");
+ if ( (*it)->precedence() < regexp->precedence() ) {
+ if ( markSelection )
+ startPar = QString::fromLocal8Bit("(?:");
+ else
+ startPar = QString::fromLatin1( "(" );
+ endPar = QString::fromLatin1( ")" );
+ }
+
+ // Note these two have different tests! They are activated in each their iteration of the loop.
+ if ( markSelection && !childSelected && !regexp->isSelected() && (*it)->isSelected() ) {
+ res += QString::fromLatin1("(");
+ childSelected = true;
+ }
+
+ if ( markSelection && childSelected && !regexp->isSelected() && !(*it)->isSelected() ) {
+ res += QString::fromLatin1(")");
+ childSelected= false;
+ }
+
+ res += startPar + toStr( *it, markSelection ) + endPar;
+ }
+ if ( markSelection && childSelected && !regexp->isSelected() ) {
+ res += QString::fromLatin1(")");
+ }
+ return res;
+}
+
+QString QtRegExpConverter::toString( LookAheadRegExp* regexp, bool markSelection )
+{
+ if ( regexp->lookAheadType() == LookAheadRegExp::POSITIVE )
+ return QString::fromLatin1( "(?=" ) + toStr( regexp->child(), markSelection ) + QString::fromLocal8Bit( ")" );
+ else
+ return QString::fromLatin1( "(?!" ) + toStr( regexp->child(), markSelection ) + QString::fromLocal8Bit( ")" );
+}
+
+QString QtRegExpConverter::toString( TextRangeRegExp* regexp, bool /*markSelection*/ )
+{
+ QString txt;
+
+ bool foundCarrot = false;
+ bool foundDash = false;
+ bool foundParenthesis = false;
+
+ // Now print the rest of the single characters, but keep "^" as the very
+ // last element of the characters.
+ QStringList chars = regexp->chars();
+ for (unsigned int i = 0; i< chars.count(); i++) {
+ if ( *chars.at(i) == QChar( ']' ) ) {
+ foundParenthesis = true;
+ }
+ else if ( *chars.at(i) == QChar( '-' ) ) {
+ foundDash = true;
+ }
+ else if ( *chars.at(i) == QChar( '^' ) ) {
+ foundCarrot = true;
+ }
+ else {
+ txt.append( *chars.at(i) );
+ }
+ }
+
+ // Now insert the ranges.
+ QPtrList<StringPair> ranges = regexp->range();
+ for ( QPtrListIterator<StringPair> it(ranges); *it; ++it ) {
+ txt.append((*it)->first()+ QString::fromLatin1("-")+ (*it)->second());
+ }
+
+ // Ok, its time to build each part of the regexp, here comes the rule:
+ // if a ']' is one of the characters, then it must be the first one in the
+ // list (after then opening '[' and eventually negation '^')
+ // Next if a '-' is one of the characters, then it must come
+ // finally if '^' is one of the characters, then it must not be the first
+ // one!
+
+ QString res = QString::fromLatin1("[");
+
+ if ( regexp->negate() )
+ res.append(QString::fromLatin1("^"));
+
+
+ // a ']' must be the first character in teh range.
+ if ( foundParenthesis ) {
+ res.append(QString::fromLatin1("]"));
+ }
+
+ // a '-' must be the first character ( only coming after a ']')
+ if ( foundDash ) {
+ res.append(QString::fromLatin1("-"));
+ }
+
+ res += txt;
+
+ // Insert \s,\S,\d,\D,\w, and \W
+ if ( regexp->digit() )
+ res += QString::fromLocal8Bit("\\d");
+ if ( regexp->nonDigit() )
+ res += QString::fromLocal8Bit("\\D");
+ if ( regexp->space() )
+ res += QString::fromLocal8Bit("\\s");
+ if ( regexp->nonSpace() )
+ res += QString::fromLocal8Bit("\\S");
+ if ( regexp->wordChar() )
+ res += QString::fromLocal8Bit("\\w");
+ if ( regexp->nonWordChar() )
+ res += QString::fromLocal8Bit("\\W");
+
+
+ if ( foundCarrot ) {
+ res.append( QChar( '^' ) );
+ }
+
+ res.append(QString::fromLatin1("]"));
+
+ return res;
+}
+
+QString QtRegExpConverter::toString( CompoundRegExp* regexp, bool markSelection )
+{
+ if ( markSelection && !regexp->isSelected() && regexp->child()->isSelected() )
+ return QString::fromLatin1( "(" ) + toStr( regexp->child(), markSelection ) + QString::fromLatin1( ")" );
+ else
+ return toStr( regexp->child(), markSelection );
+}
+
+QString QtRegExpConverter::toString( DotRegExp* /*regexp*/, bool /*markSelection*/ )
+{
+ return QString::fromLatin1( "." );
+}
+
+QString QtRegExpConverter::toString( PositionRegExp* regexp, bool /*markSelection*/ )
+{
+ switch (regexp->position()) {
+ case PositionRegExp::BEGLINE:
+ return QString::fromLatin1("^");
+ case PositionRegExp::ENDLINE:
+ return QString::fromLatin1("$");
+ case PositionRegExp::WORDBOUNDARY:
+ return QString::fromLatin1("\\b");
+ case PositionRegExp::NONWORDBOUNDARY:
+ return QString::fromLatin1("\\B");
+ }
+ Q_ASSERT( false );
+ return QString::fromLatin1("");
+}
+
+QString QtRegExpConverter::toString( RepeatRegExp* regexp, bool markSelection )
+{
+ RegExp* child = regexp->child();
+ QString cText = toStr( child, markSelection );
+ QString startPar;
+ QString endPar;
+
+ if ( markSelection ) {
+ if ( !regexp->isSelected() && child->isSelected()) {
+ startPar = QString::fromLatin1( "(" );
+ endPar = QString::fromLatin1( ")" );
+ }
+ else if ( child->precedence() < regexp->precedence() ) {
+ startPar = QString::fromLatin1( "(?:" );
+ endPar = QString::fromLatin1( ")" );
+ }
+ }
+ else if ( child->precedence() < regexp->precedence() ) {
+ startPar = QString::fromLatin1( "(" );
+ endPar = QString::fromLatin1( ")" );
+ }
+
+ if ( regexp->min() == 0 && regexp->max() == -1) {
+ return startPar + cText +endPar + QString::fromLocal8Bit("*");
+ }
+ else if ( regexp->min() == 0 && regexp->max() == 1 ) {
+ return startPar + cText + endPar + QString::fromLocal8Bit("?");
+ }
+ else if ( regexp->min() == 1 && regexp->max() == -1 ) {
+ return startPar + cText + endPar + QString::fromLocal8Bit("+");
+ }
+ else if ( regexp->max() == -1 ) {
+ return startPar + cText + endPar + QString::fromLocal8Bit("{") +
+ QString::number( regexp->min() ) + QString::fromLocal8Bit(",") +
+ QString::fromLocal8Bit("}");
+ }
+ else {
+ return startPar + cText + endPar + QString::fromLocal8Bit("{") +
+ QString::number( regexp->min() ) + QString::fromLocal8Bit(",") +
+ QString::number( regexp->max() ) + QString::fromLocal8Bit("}");
+ }
+}
+
+QString QtRegExpConverter::toString( TextRegExp* regexp, bool /*markSelection*/ )
+{
+ QValueList<QChar> list;
+ list << QChar('$')
+ << QChar('^')
+ << QChar('.')
+ << QChar('*')
+ << QChar('+')
+ << QChar('?')
+ << QChar('[')
+ << QChar(']')
+ << QChar('\\')
+ << QChar('{')
+ << QChar('}')
+ << QChar('(')
+ << QChar(')')
+ << QChar('|');
+
+ QString res = escape( regexp->text(), list, QChar('\\') );
+ return res;
+}
+
+QString QtRegExpConverter::name()
+{
+ return QString::fromLatin1( "Qt" );
+}
+
+int QtRegExpConverter::features()
+{
+ return WordBoundary | NonWordBoundary | PosLookAhead | NegLookAhead | CharacterRangeNonItems | ExtRange;
+}
+
+RegexpHighlighter* QtRegExpConverter::highlighter( QTextEdit* edit )
+{
+ return new QtRegexpHighlighter( edit );
+}
diff --git a/kregexpeditor/qtregexpconverter.h b/kregexpeditor/qtregexpconverter.h
new file mode 100644
index 0000000..100dcf3
--- /dev/null
+++ b/kregexpeditor/qtregexpconverter.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2002-2004 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifndef QTREGEXPCONVERTER_H
+#define QTREGEXPCONVERTER_H
+#include "regexpconverter.h"
+
+class QtRegExpConverter :public RegExpConverter
+{
+public:
+ virtual bool canParse();
+ virtual RegExp* parse( const QString&, bool* ok );
+ virtual QString name();
+ virtual int features();
+ virtual QString toString( AltnRegExp*, bool markSelection );
+ virtual QString toString( ConcRegExp*, bool markSelection );
+ virtual QString toString( LookAheadRegExp*, bool markSelection );
+ virtual QString toString( TextRangeRegExp*, bool markSelection );
+ virtual QString toString( CompoundRegExp*, bool markSelection );
+ virtual QString toString( DotRegExp*, bool markSelection );
+ virtual QString toString( PositionRegExp*, bool markSelection );
+ virtual QString toString( RepeatRegExp*, bool markSelection );
+ virtual QString toString( TextRegExp*, bool markSelection );
+ RegexpHighlighter* highlighter( QTextEdit* edit );
+};
+
+#endif /* QTREGEXPCONVERTER_H */
+
diff --git a/kregexpeditor/qtregexphighlighter.cpp b/kregexpeditor/qtregexphighlighter.cpp
new file mode 100644
index 0000000..1983b89
--- /dev/null
+++ b/kregexpeditor/qtregexphighlighter.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "qtregexphighlighter.h"
+#include <qregexp.h>
+QtRegexpHighlighter::QtRegexpHighlighter( QTextEdit* editor )
+ :RegexpHighlighter( editor ), _editor( editor )
+{
+}
+
+int QtRegexpHighlighter::highlightParagraph( const QString & text, int endStateOfLastPara )
+{
+ QRegExp regexp( _regexp );
+ regexp.setCaseSensitive( _caseSensitive );
+ regexp.setMinimal( _minimal );
+
+ setFormat( 0, text.length(), _editor->font(), Qt::black );
+
+ if ( !regexp.isValid() || regexp.isEmpty() ) {
+ return 0;
+ }
+
+ // ------------------------------ Process with the regular expression.
+ QColor colors[] = { Qt::red, Qt::blue };
+ int color = endStateOfLastPara;
+ if ( color < 0 || color > 1 )
+ color = 0;
+
+ int index = 0;
+ int start, length;
+ while ( (index = regexp.search( text, index ) ) != -1 && index < (int) text.length()) {
+ if ( regexp.pos(1) != -1 ) {
+ start = regexp.pos(1);
+ length = regexp.cap(1).length();
+ }
+ else {
+ start = index;
+ length = regexp.matchedLength();
+ }
+
+ if ( start != index )
+ setFormat( index, start-index, colors[color] );
+
+ QFont font = _editor->font();
+ font.setUnderline( true );
+ font.setPointSize( (int) (font.pointSize() * 1.3) );
+ setFormat( start, length, font, colors[color] );
+
+ if ( length + (start-index) != regexp.matchedLength() )
+ setFormat( start+length, regexp.matchedLength()-length-(start-index), colors[color] );
+
+ index += QMAX( 1, regexp.matchedLength() ); // ensure progress when matching for example ^ or \b
+ color = (color+1)%2;
+ }
+ return color;
+}
+
diff --git a/kregexpeditor/qtregexphighlighter.h b/kregexpeditor/qtregexphighlighter.h
new file mode 100644
index 0000000..bb57bda
--- /dev/null
+++ b/kregexpeditor/qtregexphighlighter.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef QTREGEXPHIGHLIGHTER_H
+#define QTREGEXPHIGHLIGHTER_H
+#include "regexphighlighter.h"
+#include <qtextedit.h>
+
+class QtRegexpHighlighter :public RegexpHighlighter
+{
+public:
+ QtRegexpHighlighter( QTextEdit* verifier );
+ virtual int highlightParagraph ( const QString & text, int endStateOfLastPara );
+
+private:
+ QTextEdit* _editor;
+};
+
+#endif /* QTREGEXPHIGHLIGHTER_H */
+
diff --git a/kregexpeditor/regexp.cpp b/kregexpeditor/regexp.cpp
new file mode 100644
index 0000000..31450f1
--- /dev/null
+++ b/kregexpeditor/regexp.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include "regexp.h"
+#include "widgetfactory.h"
+#include "kregexpeditorgui.h"
+#include "errormap.h"
+
+RegExp::RegExp( bool selected ) : _parent(0), _destructing( false ), _selected( selected )
+{
+ // Nothing to do
+}
+
+RegExp::~RegExp()
+{
+ _destructing = true;
+ for ( QPtrListIterator<RegExp> it(_children); *it; ++it ) {
+ delete *it;
+ }
+ if ( _parent )
+ _parent->removeChild( this );
+ _parent = 0;
+}
+
+void RegExp::addChild( RegExp* child )
+{
+ _children.append( child );
+ child->setParent( this );
+}
+
+void RegExp::removeChild( RegExp* child )
+{
+ if ( ! _destructing ) {
+ _children.remove( child );
+ }
+}
+
+void RegExp::setParent( RegExp* parent )
+{
+ _parent = parent;
+}
+
+RegExp* RegExp::readRegExp( QDomElement top, const QString& version )
+{
+ for ( QDomNode node = top.firstChild(); !node.isNull(); node = node.nextSibling() ) {
+ if (!node.isElement() )
+ continue; // skip past comments
+ RegExp* regexp = WidgetFactory::createRegExp(node.toElement(), version );
+ return regexp;
+ }
+ return 0;
+}
+
+QString RegExp::toXmlString() const
+{
+ QDomDocument doc;
+ doc.setContent( QString::fromLatin1( "<RegularExpression/>" ) );
+ QDomNode top = doc.documentElement();
+ top.toElement().setAttribute(QString::fromLocal8Bit("version"), KRegExpEditorGUI::version);
+
+ QDomNode elm = toXml( &doc );
+
+ top.appendChild( elm );
+ QString xmlString = QString::fromLocal8Bit("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<!DOCTYPE RegularExpression PUBLIC \"-//KDE//KRegexpEditor DTD 1.0//EN\" \"http://www.blackie.dk/kreg.dtd\">\n") + doc.toString();
+
+ return xmlString;
+}
+
+RegExp* RegExp::clone() const
+{
+ return WidgetFactory::createRegExp( toXmlString() );
+}
+
+void RegExp::check( ErrorMap& map )
+{
+ map.start();
+ check( map, true, true );
+ map.end();
+}
+
+
diff --git a/kregexpeditor/regexp.h b/kregexpeditor/regexp.h
new file mode 100644
index 0000000..86bd796
--- /dev/null
+++ b/kregexpeditor/regexp.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef REGEXP_H
+#define REGEXP_H
+
+#include <qdom.h>
+#include <qptrlist.h>
+
+class CompoundRegExp;
+class ErrorMap;
+
+/**
+ Abstract syntax tree for regular expressions.
+ @internal
+*/
+class RegExp
+{
+public:
+ RegExp( bool selected );
+ virtual ~RegExp();
+
+ virtual int precedence() const = 0;
+ virtual QDomNode toXml( QDomDocument* doc ) const = 0;
+ virtual bool load( QDomElement, const QString& version ) = 0;
+ QString toXmlString() const;
+
+ void check( ErrorMap& );
+ virtual bool check( ErrorMap&, bool first, bool last ) = 0;
+
+ void addChild( RegExp* child );
+ void removeChild( RegExp* child );
+ void setParent( RegExp* parent );
+ RegExp* clone() const;
+ virtual bool operator==( const RegExp& other ) const { return ( type() == other.type() ); }
+
+ enum RegExpType { CONC, TEXT, DOT, POSITION, REPEAT, ALTN, COMPOUND, LOOKAHEAD, TEXTRANGE };
+ virtual RegExpType type() const = 0;
+ virtual void replacePart( CompoundRegExp* /* replacement */ ) {}
+ bool isSelected() const { return _selected; }
+ void setSelected( bool b ) { _selected = b; }
+
+protected:
+ RegExp* readRegExp( QDomElement top, const QString& version );
+
+private:
+ RegExp() {} // disable
+ QPtrList<RegExp> _children;
+ RegExp* _parent;
+ bool _destructing;
+ bool _selected;
+};
+
+typedef QPtrList<RegExp> RegExpList;
+typedef QPtrListIterator<RegExp> RegExpListIt;
+
+#endif // REGEXP_H
+
diff --git a/kregexpeditor/regexpbuttons.cpp b/kregexpeditor/regexpbuttons.cpp
new file mode 100644
index 0000000..eae7da0
--- /dev/null
+++ b/kregexpeditor/regexpbuttons.cpp
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifdef QT_ONLY
+ #include "compat.h"
+ #include "images.h"
+#else
+ #include <kiconloader.h>
+ #include <klocale.h>
+ #include <kstandarddirs.h>
+ #include "regexpbuttons.moc"
+#endif
+
+#include "regexpbuttons.h"
+#include "dcbutton.h"
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qbuttongroup.h>
+#include <qlayout.h>
+#include <qsignalmapper.h>
+#include "regexpconverter.h"
+
+RegExpButtons::RegExpButtons( QWidget *parent, const char *name )
+ : QDockWindow( QDockWindow::InDock, parent, name), _keepMode(false)
+{
+ QBoxLayout *layout = boxLayout();
+
+ _grp = new QButtonGroup(this);
+ _grp->hide();
+ _grp->setExclusive( true );
+
+ _mapper = new QSignalMapper( this, "RegExpButtons::_mapper" );
+ connect( _mapper, SIGNAL( mapped(int) ), this, SIGNAL( clicked(int) ) );
+
+ // The "select" button.
+ _selectBut = new QToolButton( this);
+
+#ifdef QT_ONLY
+ QPixmap pix;
+ pix.convertFromImage( qembed_findImage( "select" ) );
+#else
+ QPixmap pix = KGlobal::iconLoader()->loadIcon(locate("data", QString::fromLatin1("kregexpeditor/pics/select.png") ), KIcon::Toolbar );
+#endif
+
+ _selectBut->setPixmap( pix );
+ layout->addWidget( _selectBut );
+ _grp->insert(_selectBut);
+ _selectBut->setToggleButton( true );
+ connect( _selectBut, SIGNAL(clicked()), SIGNAL(doSelect()));
+ connect( _selectBut, SIGNAL(clicked()), this, SLOT(slotSetNonKeepMode()) );
+
+ QToolTip::add( _selectBut, i18n("Selection tool"));
+ QWhatsThis::add( _selectBut, i18n("<qt>This will change the state of the editor to <i>selection state</i>.<p>"
+ "In this state you will not be inserting <i>regexp items</i>, but instead select them. "
+ "To select a number of items, press down the left mouse button and drag it over the items.<p>"
+ "When you have selected a number of items, you may use cut/copy/paste. These functions are "
+ "found in the right mouse button menu.</qt>"));
+
+ // Insert buttons.
+ DoubleClickButton* but;
+
+ but = insert(TEXT, "text", i18n("Text"),
+ i18n( "<qt>This will insert a text field, where you may write text. The text you write will "
+ "be matched literally. (i.e. you do not need to escape any characters)</qt>" ) );
+ layout->addWidget( but );
+
+
+ but = insert(CHARSET, "characters", i18n("A single character specified in a range"),
+ i18n("<qt>This will match a single character from a predefined range.<p>"
+ "When you insert this widget a dialog box will appear, which lets you specify "
+ "which characters this <i>regexp item</i> will match.</qt>") );
+ layout->addWidget( but );
+
+
+ but = insert(DOT, "anychar", i18n("Any character"),
+ i18n("<qt>This will match any single character</qt>") );
+ layout->addWidget( but );
+
+
+ but = insert(REPEAT, "repeat", i18n("Repeated content"),
+ i18n("<qt>This <i>regexp item</i> will repeat the <i>regexp items</i> it surrounds "
+ "a specified number of times.<p>"
+ "The number of times to repeat may be specified using ranges. e.g. You may specify "
+ "that it should match from 2 to 4 times, that it should match exactly 5 times, or "
+ "that it should match at least one time.<p>"
+ "Examples:<br>"
+ "If you specify that it should match <i>any</i> time, and the content it surrounds "
+ "is <tt>abc</tt>, then this <i>regexp item</i> will match the empty string, "
+ "the string <tt>abc</tt>, the string <tt>abcabc</tt>, the string <tt>abcabcabcabc</tt>, "
+ "etc.</qt>") );
+ layout->addWidget( but );
+
+
+ but = insert(ALTN, "altn", i18n("Alternatives"),
+ i18n("<qt>This <i>regexp item</i> will match any of its alternatives.</p>"
+ "You specify alternatives by placing <i>regexp items</i> on top of "
+ "each other inside this widget.</qt>") );
+ layout->addWidget( but );
+
+
+ but = insert(COMPOUND, "compound", i18n("Compound regexp"),
+ i18n("<qt>This <i>regexp item</i> serves two purposes:"
+ "<ul><li>It makes it possible for you to collapse a huge <i>regexp item</i> into "
+ "a small box. This makes it easier for you to get an overview of large "
+ "<i>regexp items</i>. This is especially useful if you load a predefined <i>regexp item</i> "
+ "you perhaps don't care about the inner workings of.") );
+ layout->addWidget( but );
+
+
+ but = insert(BEGLINE, "begline", i18n("Beginning of line"),
+ i18n("<qt>This will match the beginning of a line.</qt>") );
+ layout->addWidget( but );
+
+
+ but = insert(ENDLINE, "endline", i18n("End of line"),
+ i18n("<qt>This will match the end of a line.</qt>") );
+ layout->addWidget( but );
+
+
+ _wordBoundary = insert(WORDBOUNDARY, "wordboundary", i18n("Word boundary"),
+ i18n("<qt>This asserts a word boundary (This part does not actually match any characters)</qt>") );
+ layout->addWidget( _wordBoundary );
+
+ _nonWordBoundary = insert(NONWORDBOUNDARY, "nonwordboundary", i18n("Non Word boundary"),
+ i18n("<qt>This asserts a non-word boundary "
+ "(This part does not actually match any characters)</qt>") );
+ layout->addWidget( _nonWordBoundary );
+
+ _posLookAhead = insert(POSLOOKAHEAD, "poslookahead", i18n("Positive Look Ahead"),
+ i18n("<qt>This asserts a regular expression (This part does not actually match any characters). "
+ "You can only use this at the end of a regular expression.</qt>") );
+ layout->addWidget( _posLookAhead );
+
+ _negLookAhead = insert(NEGLOOKAHEAD, "neglookahead", i18n("Negative Look Ahead"),
+ i18n("<qt>This asserts a regular expression that must not match "
+ "(This part does not actually match any characters). "
+ "You can only use this at the end of a regular expression.</qt>") );
+ layout->addWidget( _negLookAhead );
+}
+
+DoubleClickButton* RegExpButtons::insert(RegExpType tp, const char* name, QString tooltip, QString whatsthis)
+{
+#ifdef QT_ONLY
+ QPixmap pix;
+ pix.convertFromImage( qembed_findImage( QString::fromLatin1( name ) ) );
+#else
+ QPixmap pix = KGlobal::iconLoader()->loadIcon(locate("data", QString::fromLatin1("kregexpeditor/pics/")+QString::fromLatin1(name) +
+ QString::fromLatin1(".png") ), KIcon::Toolbar );
+#endif
+
+ DoubleClickButton* but = new DoubleClickButton( pix, this, "RegExpButtons::but");
+
+ _mapper->setMapping( but, tp );
+
+ connect( but, SIGNAL( clicked() ), _mapper, SLOT( map() ) );
+ connect( but, SIGNAL( clicked() ), this, SLOT( slotSetNonKeepMode() ) );
+ connect( but, SIGNAL( doubleClicked() ), this, SLOT( slotSetKeepMode() ) );
+
+ _grp->insert( but );
+ but->setToggleButton( true );
+ QToolTip::add( but, tooltip );
+ QWhatsThis::add( but, whatsthis );
+
+ return but;
+}
+
+void RegExpButtons::slotUnSelect()
+{
+ if ( _grp->selected() ) {
+ QToolButton *pb = static_cast<QToolButton*>(_grp->selected());
+ if (pb) {
+ pb->setOn( false );
+ }
+ }
+}
+
+void RegExpButtons::slotSetKeepMode( )
+{
+ _keepMode = true;
+}
+
+void RegExpButtons::slotSetNonKeepMode( )
+{
+ _keepMode = false;
+}
+
+void RegExpButtons::slotSelectNewAction()
+{
+ if ( ! _keepMode ) {
+ emit doSelect();
+ _grp->setButton(_grp->id(_selectBut));
+ }
+}
+
+void RegExpButtons::setFeatures( int features )
+{
+ _wordBoundary->setShown( features & RegExpConverter::WordBoundary );
+ _nonWordBoundary->setShown( features & RegExpConverter::NonWordBoundary );
+ _posLookAhead->setShown( features & RegExpConverter::PosLookAhead );
+ _negLookAhead->setShown( features & RegExpConverter::NegLookAhead );
+
+}
+
diff --git a/kregexpeditor/regexpbuttons.h b/kregexpeditor/regexpbuttons.h
new file mode 100644
index 0000000..5671810
--- /dev/null
+++ b/kregexpeditor/regexpbuttons.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __REGEXPBUTTONS_H
+#define __REGEXPBUTTONS_H
+
+#include <qdockwindow.h>
+#include "widgetfactory.h"
+class DoubleClickButton;
+class QButtonGroup;
+class QToolButton;
+class QSignalMapper;
+
+
+class RegExpButtons :public QDockWindow
+{
+ Q_OBJECT
+
+public:
+ RegExpButtons( QWidget *parent, const char *name = 0 );
+ void setFeatures( int features );
+
+protected:
+ DoubleClickButton* insert(RegExpType tp, const char* file, QString tooltip, QString whatsthis);
+
+public slots:
+ void slotSelectNewAction();
+ void slotUnSelect();
+
+protected slots:
+ void slotSetKeepMode();
+ void slotSetNonKeepMode();
+
+signals:
+ void clicked( int );
+ void doSelect();
+
+private:
+ QButtonGroup* _grp;
+ QToolButton* _selectBut;
+ QToolButton* _wordBoundary;
+ QToolButton* _nonWordBoundary;
+ QToolButton* _posLookAhead;
+ QToolButton* _negLookAhead;
+ QSignalMapper* _mapper; // single click Mapper.
+
+ /**
+ This variable is true if the use wishes to continue editing in the
+ selected mode after the previous editing is completed (that is, if the
+ user has double clicked the buttons).
+ */
+ bool _keepMode;
+};
+
+
+#endif // __REGEXPBUTTON_H
diff --git a/kregexpeditor/regexpconverter.cpp b/kregexpeditor/regexpconverter.cpp
new file mode 100644
index 0000000..2d53e20
--- /dev/null
+++ b/kregexpeditor/regexpconverter.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2002-2004 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#include "regexpconverter.h"
+
+#include "altnregexp.h"
+#include "concregexp.h"
+#include "lookaheadregexp.h"
+#include "textrangeregexp.h"
+#include "compoundregexp.h"
+#include "dotregexp.h"
+#include "positionregexp.h"
+#include "repeatregexp.h"
+#include "textregexp.h"
+#include <qtextedit.h>
+#include "regexphighlighter.h"
+
+RegExpConverter* RegExpConverter::_current = 0;
+RegExp* RegExpConverter::parse( const QString&, bool* ok )
+{
+ ok = false;
+ return new DotRegExp( false ); // This method should never be called.
+}
+
+// This function needs to be called toStr rather than toString, as it is not possible to
+// over load function across inheritance!
+QString RegExpConverter::toStr( RegExp* regexp, bool markSelection )
+{
+ switch (regexp->type()) {
+ case RegExp::CONC: return toString( static_cast<ConcRegExp*>( regexp ), markSelection);
+ case RegExp::TEXT: return toString( static_cast<TextRegExp*>( regexp ), markSelection );
+ case RegExp::DOT: return toString( static_cast<DotRegExp*>( regexp ), markSelection );
+ case RegExp::POSITION: return toString( static_cast<PositionRegExp*>( regexp ), markSelection );
+ case RegExp::REPEAT: return toString( static_cast<RepeatRegExp*>( regexp ), markSelection );
+ case RegExp::ALTN: return toString( static_cast<AltnRegExp*>( regexp ), markSelection );
+ case RegExp::COMPOUND: return toString( static_cast<CompoundRegExp*>( regexp ), markSelection );
+ case RegExp::LOOKAHEAD: return toString( static_cast<LookAheadRegExp*>( regexp ), markSelection );
+ case RegExp::TEXTRANGE: return toString( static_cast<TextRangeRegExp*>( regexp ), markSelection );
+ }
+ qWarning("We shouldn't get here!");
+ return QString::fromLatin1( "" );
+}
+
+
+QString RegExpConverter::escape( QString text, QValueList<QChar> chars, QChar escapeChar) const
+{
+ QString res;
+ for (unsigned int i=0; i<text.length(); i++) {
+ for (unsigned int j=0; j<chars.count(); j++) {
+ if ( text.at(i) == (chars[j]) ) {
+ res.append( escapeChar );
+ break;
+ }
+ }
+ res.append( text.at(i) );
+ }
+
+ return res;
+}
+
+/**
+ Returns a QSyntaxHighlighter to be used in the virifyer widget.
+*/
+RegexpHighlighter* RegExpConverter::highlighter( QTextEdit* )
+{
+ return 0;
+}
+
+RegExpConverter* RegExpConverter::current()
+{
+ return _current;
+}
+
+void RegExpConverter::setCurrent( RegExpConverter* converter)
+{
+ _current = converter;
+}
+
diff --git a/kregexpeditor/regexpconverter.h b/kregexpeditor/regexpconverter.h
new file mode 100644
index 0000000..ddb1e54
--- /dev/null
+++ b/kregexpeditor/regexpconverter.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2002-2004 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifndef REGEXPCONVERTER_H
+#define REGEXPCONVERTER_H
+
+#include <qstring.h>
+#include <qvaluelist.h>
+
+class QTextEdit;
+class AltnRegExp;
+class ConcRegExp;
+class LookAheadRegExp;
+class TextRangeRegExp;
+class CompoundRegExp;
+class DotRegExp;
+class PositionRegExp;
+class RepeatRegExp;
+class TextRegExp;
+class RegexpHighlighter;
+class RegExp;
+
+class RegExpConverter
+{
+public:
+ enum Features {
+ WordBoundary = 0x01,
+ NonWordBoundary = 0x02,
+ WordStart = 0x04,
+ WordEnd = 0x08,
+ PosLookAhead = 0x10,
+ NegLookAhead = 0x20,
+ CharacterRangeNonItems = 0x40,
+ ExtRange = 0x80
+ };
+
+ virtual bool canParse() = 0;
+ virtual QString name() = 0;
+ virtual int features() = 0;
+ virtual RegExp* parse( const QString&, bool* ok );
+ QString toStr( RegExp*, bool markSelection );
+ virtual RegexpHighlighter* highlighter( QTextEdit* );
+
+ static void setCurrent( RegExpConverter* );
+ static RegExpConverter* current();
+
+protected:
+ virtual QString toString( AltnRegExp*, bool markSelection ) = 0;
+ virtual QString toString( ConcRegExp*, bool markSelection ) = 0;
+ virtual QString toString( LookAheadRegExp*, bool markSelection ) = 0;
+ virtual QString toString( TextRangeRegExp*, bool markSelection ) = 0;
+ virtual QString toString( CompoundRegExp*, bool markSelection ) = 0;
+ virtual QString toString( DotRegExp*, bool markSelection ) = 0;
+ virtual QString toString( PositionRegExp*, bool markSelection ) = 0;
+ virtual QString toString( RepeatRegExp*, bool markSelection ) = 0;
+ virtual QString toString( TextRegExp*, bool markSelection ) = 0;
+ QString escape( QString text, QValueList<QChar> chars, QChar escapeChar) const;
+
+private:
+ static RegExpConverter* _current;
+};
+
+#endif /* REGEXPCONVERTER_H */
+
diff --git a/kregexpeditor/regexphighlighter.cpp b/kregexpeditor/regexphighlighter.cpp
new file mode 100644
index 0000000..3034ee1
--- /dev/null
+++ b/kregexpeditor/regexphighlighter.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#include "regexphighlighter.h"
+
+RegexpHighlighter::RegexpHighlighter( QTextEdit* edit )
+ :QSyntaxHighlighter( edit ), _caseSensitive( false ), _minimal( false )
+{
+}
+
+void RegexpHighlighter::setRegExp( const QString& regexp )
+{
+ _regexp = regexp;
+}
+
+void RegexpHighlighter::setCaseSensitive( bool b )
+{
+ _caseSensitive = b;
+}
+
+void RegexpHighlighter::setMinimal( bool b )
+{
+ _minimal = b;
+}
+
+
+
+
+
diff --git a/kregexpeditor/regexphighlighter.h b/kregexpeditor/regexphighlighter.h
new file mode 100644
index 0000000..92219b1
--- /dev/null
+++ b/kregexpeditor/regexphighlighter.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifndef REGEXPHIGHLIGHTER_H
+#define REGEXPHIGHLIGHTER_H
+#include <qsyntaxhighlighter.h>
+
+class RegexpHighlighter :public QSyntaxHighlighter
+{
+public:
+ RegexpHighlighter( QTextEdit* edit );
+ void setRegExp( const QString& regexp );
+ void setCaseSensitive( bool );
+ void setMinimal( bool );
+
+protected:
+ QString _regexp;
+ bool _caseSensitive, _minimal;
+
+};
+
+#endif /* REGEXPHIGHLIGHTER_H */
+
diff --git a/kregexpeditor/regexpwidget.cpp b/kregexpeditor/regexpwidget.cpp
new file mode 100644
index 0000000..2ee2aa7
--- /dev/null
+++ b/kregexpeditor/regexpwidget.cpp
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include "regexpwidget.moc"
+#endif
+
+#include "regexpwidget.h"
+#include <iostream>
+#include <qpainter.h>
+#include <qcursor.h>
+#include "concwidget.h"
+#include "dragaccepter.h"
+
+const int RegExpWidget::pw = 1;
+const int RegExpWidget::bdSize = 5;
+const int RegExpWidget::space = 5;
+
+RegExpWidget::RegExpWidget(RegExpEditorWindow* editorWindow, QWidget *parent,
+ const char *name)
+ : QWidget(parent, name ? name : "RegExpWidget", WNoMousePropagation ),
+ _editorWindow( editorWindow ), _isSelected( false ), _isToplevel( false )
+{
+}
+
+
+void RegExpWidget::addNewChild(DragAccepter *, RegExpWidget *)
+{
+ qFatal("This widget should not expect any children");
+}
+
+void RegExpWidget::addNewConcChild(DragAccepter *, ConcWidget *)
+{
+ qFatal("This widget should not expect any children");
+}
+
+void RegExpWidget::setConcChild(ConcWidget *)
+{
+ qFatal("This widget should not expect any children");
+}
+
+bool RegExpWidget::updateSelection(bool parentSelected)
+{
+ bool selected = ( parentSelected ||
+ _editorWindow->selectionOverlap( mapToGlobal( QPoint(0,0) ), size() ) )
+ && !_isToplevel;
+
+ if ( _isSelected != selected ) {
+ // Selection state changed
+ _isSelected = selected;
+ repaint();
+ return true;
+ }
+ return false;
+}
+
+void RegExpWidget::drawPossibleSelection( QPainter& painter, QSize mySize )
+{
+ if ( _isSelected ) {
+ painter.fillRect( 0, 0, mySize.width(), mySize.height(), QBrush( gray ) );
+ }
+}
+
+bool RegExpWidget::isSelected() const
+{
+ return _isSelected;
+}
+
+bool RegExpWidget::hasSelection() const
+{
+ return _isSelected;
+}
+
+void RegExpWidget::clearSelection()
+{
+ _isSelected = false;
+}
+
+void RegExpWidget::applyRegExpToSelection( RegExpType )
+{
+ qFatal("This method should not be called for this widget");
+}
+
+void RegExpWidget::deleteSelection()
+{
+ qFatal("This method should be overridden if needed!");
+}
+
+RegExp* RegExpWidget::selection() const
+{
+ return regExp();
+}
+
+int RegExpWidget::edit()
+{
+ qFatal("This method should be overridden if needed!");
+ return 0; // Compiler shut up
+}
+
+void RegExpWidget::mousePressEvent ( QMouseEvent* event )
+{
+ if ( _editorWindow->isPasteing() || _editorWindow->isInserting() )
+ return;
+
+ if ( event->button() == LeftButton ) {
+ if ( ! _editorWindow->pointSelected( QCursor::pos() ) ) {
+ _editorWindow->clearSelection( true );
+ if ( dynamic_cast<DragAccepter*>(this) == 0 && dynamic_cast<ConcWidget*>(this) == 0 ) {
+ selectWidget( true );
+ }
+ }
+
+ QMouseEvent ev( event->type(), mapTo(_editorWindow, event->pos()),
+ event->button(), event->state());
+ QApplication::sendEvent( _editorWindow, &ev );
+ }
+ else if ( event->button() == RightButton ) {
+ _editorWindow->showRMBMenu( true );
+ }
+
+ // currently (Qt3.0) it seems like qt do not accept that the accept flag is set,
+ // and thus sends the event to the parent - given that the following line is in.
+ // It doesn't make any change to leave it out.
+ // 25 Oct. 2001 19:03 -- Jesper K. Pedersen
+ // QWidget::mousePressEvent( event );
+}
+
+void RegExpWidget::mouseReleaseEvent( QMouseEvent* )
+{
+ if ( _editorWindow->isInserting() && acceptWidgetInsert( _editorWindow->insertType() ) ) {
+ if ( !_editorWindow->hasSelection() )
+ _isSelected = true;
+
+ _editorWindow->applyRegExpToSelection( _editorWindow->insertType() );
+ _editorWindow->clearSelection( true );
+ _editorWindow->updateContent( this );
+ _editorWindow->slotEndActions();
+ _editorWindow->updateCursorUnderPoint();
+ }
+}
+
+QRect RegExpWidget::selectionRect() const
+{
+ return QRect( mapToGlobal( QPoint(0,0) ), size() );
+}
+
+
+void RegExpWidget::enterEvent( QEvent * )
+{
+ updateCursorShape();
+}
+
+void RegExpWidget::updateCursorShape()
+{
+ QCursor cursor;
+
+ if ( _editorWindow->isPasteing() ) {
+ if ( acceptWidgetPaste() )
+ cursor = CrossCursor;
+ else
+ cursor = ForbiddenCursor;
+ }
+ else if ( _editorWindow->isInserting() ) {
+ if ( acceptWidgetInsert( _editorWindow->insertType() ) )
+ cursor = CrossCursor;
+ else
+ cursor = ForbiddenCursor;
+ }
+ else
+ cursor = arrowCursor;
+
+ setCursor( cursor );
+}
+
+void RegExpWidget::updateCursorRecursively()
+{
+ updateCursorShape();
+}
+
+
+bool RegExpWidget::acceptWidgetPaste() const
+{
+ return false;
+}
+
+bool RegExpWidget::acceptWidgetInsert( RegExpType tp ) const
+{
+ return WidgetFactory::isContainer( tp );
+}
+
+RegExpWidget* RegExpWidget::widgetUnderPoint( QPoint globalPos, bool )
+{
+ if ( QRect(mapToGlobal( QPoint(0,0) ), size() ).contains( globalPos ) )
+ return this;
+ else
+ return 0;
+}
+
+void RegExpWidget::selectWidget( bool sel)
+{
+ _isSelected = sel;
+ update();
+}
+
+void RegExpWidget::updateAll()
+{
+ update();
+}
+
+
diff --git a/kregexpeditor/regexpwidget.h b/kregexpeditor/regexpwidget.h
new file mode 100644
index 0000000..e0c038d
--- /dev/null
+++ b/kregexpeditor/regexpwidget.h
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __regexpwidget
+#define __regexpwidget
+
+#include "editorwindow.h"
+
+class DragAccepter;
+class RegExp;
+class ConcWidget;
+class RegExpEditorWindow;
+
+/**
+ Base class for all regular expression widgets.
+ @internal
+*/
+class RegExpWidget :public QWidget
+{
+Q_OBJECT
+
+public:
+ RegExpWidget(RegExpEditorWindow* editorWindow, QWidget *parent,
+ const char *label = 0);
+
+ /*======================================================================
+ Construction, child management
+ ======================================================================*/
+ /**
+ Add `child' to the parent of this widget in place of `accepter'
+ This method only applies to container widgets (see @ref
+ SingleContainerWidget, and @ref MultiContainerWidget).
+ */
+ virtual void addNewChild(DragAccepter *accepter, RegExpWidget *child);
+
+ /**
+ Inserts all the children of `child' into this widget in place of
+ `accepter'.
+ This method only applies to container widgets (see @ref
+ SingleContainerWidget, and @ref MultiContainerWidget).
+ */
+ virtual void addNewConcChild(DragAccepter *accepter, ConcWidget *child);
+
+ /**
+ Set `child' as the ConcWidget. This method should only be invoked when
+ the widget has just been constructed.
+ This method only applies to container widgets (see @ref
+ SingleContainerWidget, and @ref MultiContainerWidget).
+ */
+ virtual void setConcChild(ConcWidget *child);
+
+ /* ======================================================================
+ Selection
+ ======================================================================*/
+
+ /**
+ Marks this widget as being the immediate child of the editor
+ window. That is the topmost regular expression widget.
+
+ This information is necessary when drawing the widget, and when
+ drawing the selection.
+ */
+ void setToplevel() { _isToplevel = true; }
+
+ /**
+ Returns true if this widget is selected.
+ */
+ virtual bool isSelected() const;
+
+ /**
+ Returns true if this widget or one of its children is selected.
+ */
+ virtual bool hasSelection() const;
+
+ virtual void updateAll();
+
+ /**
+ Update selection information for this widget.
+ @param parentSelected indicates whether the parent is selected.
+ @return true if the selection state has changed for the widget since
+ the last time the widget was painted. `repaint' is invoked on the widget if
+ selection state is changed, to ensure that selection is visible.
+ */
+ virtual bool updateSelection(bool parentSelected);
+
+ /**
+ Clears the selection and repaints the widget if `update' is true.
+ */
+ virtual void clearSelection();
+
+ /**
+ Deletes the regexp widgets containing selection.
+ */
+ virtual void deleteSelection();
+
+ /**
+ See @ref RegExpEditorWindow::applyRegExpToSelection
+ */
+ virtual void applyRegExpToSelection( RegExpType type );
+
+ /**
+ Validate that selection is OK. Returns false if not.
+
+ Only one alternative may be selected in @ref AltnWidget. This
+ limitation is to make implementation of a number of functions simpler.
+ */
+ virtual bool validateSelection() const { return true; }
+
+ /**
+ Returns the rectangle which makes up the selection.
+ */
+ virtual QRect selectionRect() const;
+
+ /** Selects the RegExp widget and all its chidlren*/
+ virtual void selectWidget( bool sel );
+
+ /*======================================================================
+ Misc
+ ======================================================================*/
+
+ /** Returns the RegExp widget, which is rooted in this regexp widget. */
+ virtual RegExp* regExp() const = 0;
+
+ /** returns the current selection */
+ virtual RegExp* selection() const;
+
+ /** returns the type of this regular expression widget. */
+ virtual RegExpType type() const = 0;
+
+ /**
+ updates the cursor to be one of
+ @li normal selection cursor
+ @li accept cursor for insert/paste
+ @li reject cursor for insert/paste
+ */
+ void updateCursorShape();
+
+ virtual void updateCursorRecursively();
+
+ /**
+ Returns the regexp widget under point. If `justVisibleWidgets' is
+ true, @ref ConcWidget is ignored. That is, a ConcWidget will not be returned.
+ */
+ virtual RegExpWidget* widgetUnderPoint( QPoint globalPos, bool justVisibleWidgets );
+
+ /**
+ Returns the widget under point which can be edited. That is the
+ "innermost" widget editable.
+ */
+ virtual RegExpWidget* findWidgetToEdit( QPoint /* globalPos */) { return 0; }
+
+ /**
+ Edits the current widget. That is, bring up the dialog, which is
+ available for @ref ConcWidget, @ref CompoundWidget, and @ref
+ CharactersWidget.
+ */
+ virtual int edit();
+
+protected:
+ /** Draws a selection rectangle for the current widget. */
+ virtual void drawPossibleSelection( QPainter& painter, QSize mySize);
+
+ /** Returns true if the widget accepts paste actions. */
+ virtual bool acceptWidgetPaste() const;
+
+ /**
+ Returns true if the widget accept the given RegExpType to be inserted
+ */
+ virtual bool acceptWidgetInsert( RegExpType ) const;
+
+ virtual void mousePressEvent ( QMouseEvent* event );
+
+ virtual void mouseReleaseEvent( QMouseEvent* );
+ virtual void enterEvent( QEvent * );
+
+ RegExpEditorWindow* _editorWindow;
+
+ /** True if the widget is selected. */
+ bool _isSelected;
+
+ /** See @ref setToplevel */
+ bool _isToplevel;
+
+ static const int pw; // width of pen
+ static const int bdSize; // width between borders and text etc.
+ static const int space; // TODO.
+};
+
+#endif // __regexpwidget
diff --git a/kregexpeditor/repeatregexp.cpp b/kregexpeditor/repeatregexp.cpp
new file mode 100644
index 0000000..d58736c
--- /dev/null
+++ b/kregexpeditor/repeatregexp.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include "kmessagebox.h"
+ #include <klocale.h>
+#endif
+
+#include "repeatregexp.h"
+
+RepeatRegExp::RepeatRegExp( bool selected, int lower, int upper, RegExp* child) : RegExp( selected )
+{
+ _lower = lower;
+ _upper = upper;
+ _child = child;
+ if (child)
+ addChild( child );
+}
+
+bool RepeatRegExp::check( ErrorMap& map, bool first, bool last )
+{
+ _child->check( map, first, last );
+ return ( _lower == 0 );
+}
+
+QDomNode RepeatRegExp::toXml( QDomDocument* doc ) const
+{
+ QDomElement top = doc->createElement( QString::fromLocal8Bit("Repeat") );
+ top.setAttribute( QString::fromLocal8Bit("lower"), _lower );
+ top.setAttribute( QString::fromLocal8Bit("upper"), _upper );
+ top.appendChild( _child->toXml( doc ) );
+ return top;
+}
+
+bool RepeatRegExp::load( QDomElement top, const QString& version )
+{
+ Q_ASSERT( top.tagName() == QString::fromLocal8Bit( "Repeat" ) );
+ QString lower = top.attribute( QString::fromLocal8Bit("lower"), QString::fromLocal8Bit("0") );
+ QString upper = top.attribute( QString::fromLocal8Bit("upper"), QString::fromLocal8Bit("0") );
+ bool ok;
+ _lower = lower.toInt( &ok );
+ if ( !ok ) {
+ KMessageBox::sorry( 0, i18n("<p>Value for attribute <b>%1</b> was not an integer for element "
+ "<b>%2</b></p><p>It contained the value <b>%3</b></p>")
+ .arg(QString::fromLatin1("lower")).arg(QString::fromLatin1("Repeat")).arg(lower),
+ i18n("Error While Loading From XML File") ) ;
+ _lower = 0;
+ }
+ _upper = upper.toInt( &ok );
+ if ( !ok ) {
+ KMessageBox::sorry( 0, i18n("<p>Value for attribute <b>%1</b> was not an integer for element "
+ "<b>%2</b></p><p>It contained the value <b>%3</b></p>")
+ .arg(QString::fromLatin1("upper")).arg(QString::fromLatin1("Repeat")).arg(upper),
+ i18n("Error While Loading From XML File") ) ;
+ _upper = -1;
+ }
+
+ _child = readRegExp( top, version );
+ if ( _child ) {
+ addChild( _child );
+ return true;
+ }
+ else
+ return false;
+}
+
+bool RepeatRegExp::operator==( const RegExp& other ) const
+{
+ if ( type() != other.type() )
+ return false;
+
+ const RepeatRegExp& theOther = dynamic_cast<const RepeatRegExp&>( other );
+ if ( _lower != theOther._lower || _upper != theOther._upper )
+ return false;
+
+ return (*_child == *(theOther._child) );
+}
+
diff --git a/kregexpeditor/repeatregexp.h b/kregexpeditor/repeatregexp.h
new file mode 100644
index 0000000..21e32cd
--- /dev/null
+++ b/kregexpeditor/repeatregexp.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __REPEATREGEXP_H
+#define __REPEATREGEXP_H
+
+#include "regexp.h"
+
+/**
+ Abstract syntax node for `repeated content' regular expression
+ @internal
+*/
+class RepeatRegExp :public RegExp
+{
+public:
+ RepeatRegExp( bool selected, int lower = 0, int upper = 0, RegExp* child = 0);
+
+ virtual bool check( ErrorMap&, bool first, bool last );
+ virtual int precedence() const { return 3;}
+ virtual QDomNode toXml( QDomDocument* doc ) const;
+ virtual bool load( QDomElement, const QString& version );
+ int min() const { return _lower; }
+ int max() const { return _upper; }
+ RegExp* child() const { return _child; }
+ virtual RegExpType type() const { return REPEAT;}
+ virtual bool operator==( const RegExp& other ) const;
+ virtual void replacePart( CompoundRegExp* replacement ) { _child->replacePart( replacement ); }
+
+private:
+ int _lower;
+ int _upper;
+ RegExp* _child;
+};
+
+#endif // __REPEATREGEXP_H
diff --git a/kregexpeditor/repeatwidget.cpp b/kregexpeditor/repeatwidget.cpp
new file mode 100644
index 0000000..27215e4
--- /dev/null
+++ b/kregexpeditor/repeatwidget.cpp
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <klocale.h>
+ #include <kdialogbase.h>
+ #include "repeatwidget.moc"
+#endif
+
+#include "repeatwidget.h"
+#include "concwidget.h"
+#include "repeatregexp.h"
+#include <qpainter.h>
+#include <qcursor.h>
+#include <qspinbox.h>
+#include <qradiobutton.h>
+#include <qlayout.h>
+#include <qgrid.h>
+#include <qvbuttongroup.h>
+#include "kwidgetstreamer.h"
+
+RepeatWidget::RepeatWidget(RegExpEditorWindow* editorWindow, QWidget *parent,
+ const char *name)
+ : SingleContainerWidget(editorWindow, parent, name ? name : "RepeatWidget")
+{
+ _child = new ConcWidget(editorWindow, this);
+ init();
+}
+
+RepeatWidget::RepeatWidget( RepeatRegExp* regexp, RegExpEditorWindow* editorWindow,
+ QWidget* parent, const char* name )
+ :SingleContainerWidget( editorWindow, parent, name )
+{
+ init();
+ RegExpWidget* child = WidgetFactory::createWidget( regexp->child(), editorWindow, this );
+ if ( ! (_child = dynamic_cast<ConcWidget*>( child ) ) )
+ _child = new ConcWidget( editorWindow, child, this );
+
+ if ( regexp->max() == -1 ) {
+ if ( regexp->min() == 0 ) {
+ _content->set( RepeatRangeWindow::ANY, regexp->min(), regexp->max() );
+ }
+ else {
+ _content->set( RepeatRangeWindow::ATLEAST, regexp->min(), regexp->max() );
+ }
+ }
+ else {
+ if ( regexp->min() == 0 ) {
+ _content->set( RepeatRangeWindow::ATMOST, regexp->min(), regexp->max() );
+ }
+ else if ( regexp->min() == regexp->max() ) {
+ _content->set( RepeatRangeWindow::EXACTLY, regexp->min(), regexp->max() );
+ }
+ else {
+ _content->set( RepeatRangeWindow::MINMAX, regexp->min(), regexp->max() );
+ }
+ }
+}
+
+void RepeatWidget::init()
+{
+ _configWindow = new KDialogBase( this, "_configWindow", true,
+ i18n("Number of Times to Repeat Content"),
+ KDialogBase::Ok | KDialogBase::Cancel);
+ _content = new RepeatRangeWindow( _configWindow );
+ _configWindow->setMainWidget( _content );
+ connect( _configWindow, SIGNAL( cancelClicked() ), this, SLOT( slotConfigCanceled() ) );
+ connect(_configWindow, SIGNAL(finished()), this, SLOT(slotConfigWindowClosed()));
+}
+
+
+QSize RepeatWidget::sizeHint() const
+{
+ // TODO: Merge with LookAheadWidget::sizeHint
+ QFontMetrics metrics = fontMetrics();
+ _textSize = metrics.size( 0, _content->text() );
+
+ _childSize = _child->sizeHint();
+
+ int height = _textSize.height() + bdSize + _childSize.height() + bdSize + 2*pw;
+ int width = 2 * pw + QMAX(_childSize.width(), 4*bdSize + _textSize.width());
+ return QSize(width,height);
+}
+
+void RepeatWidget::paintEvent( QPaintEvent *e )
+{
+ // TODO: Merge with LookAheadWidget::paintEvent
+ QSize mySize = sizeHint();
+ QPainter painter(this);
+
+ drawPossibleSelection( painter, mySize );
+
+ // move the child to its position and resize it.
+ _child->move(pw,_textSize.height()+bdSize);
+ QSize curChildSize = _child->size();
+ QSize newChildSize = QSize(mySize.width() - 2*pw, _childSize.height());
+ if ( curChildSize != newChildSize ) {
+ _child->resize(newChildSize);
+ // I resized the child, so give it a chance to relect thus.
+ _child->update();
+ }
+
+ // Draw the border and the text.
+ int startY = _textSize.height()/2;
+
+ // Top lines and text
+ painter.drawLine(pw,startY,bdSize,startY);
+ painter.drawText(pw+2*bdSize,0,_textSize.width(), _textSize.height(),0,
+ _content->text());
+ int offset = pw + 3*bdSize + _textSize.width();
+ painter.drawLine(offset,startY,mySize.width()-pw,startY);
+
+ // horizontal lines
+ painter.drawLine(0,startY,0,mySize.height()-pw);
+ painter.drawLine(mySize.width()-pw,startY,mySize.width()-pw, mySize.height()-pw);
+
+ // buttom line
+ painter.drawLine(0, mySize.height()-pw, mySize.width()-pw, mySize.height()-pw);
+
+ SingleContainerWidget::paintEvent(e);
+}
+
+RegExp* RepeatWidget::regExp() const
+{
+ return new RepeatRegExp( isSelected(), _content->min(), _content->max(), _child->regExp() );
+}
+
+void RepeatWidget::slotConfigWindowClosed()
+{
+ _editorWindow->updateContent( 0 );
+ update();
+}
+
+void RepeatWidget::slotConfigCanceled()
+{
+ QDataStream stream( _backup, IO_ReadOnly );
+ KWidgetStreamer streamer;
+ streamer.fromStream( stream, _content );
+ repaint();
+}
+
+int RepeatWidget::edit()
+{
+ _configWindow->move(QCursor::pos() - QPoint(_configWindow->sizeHint().width()/2,
+ _configWindow->sizeHint().height()/2) );
+ QDataStream stream( _backup, IO_WriteOnly );
+ KWidgetStreamer streamer;
+ streamer.toStream( _content, stream );
+
+ return _configWindow->exec();
+}
+
+//--------------------------------------------------------------------------------
+RepeatRangeWindow::RepeatRangeWindow( QWidget* parent, const char* name )
+ : QVBox( parent, name ? name : "RepeatRangeWindow" )
+{
+ setSpacing( 6 );
+
+ _group = new QVButtonGroup( i18n("Times to Match"), this, "groupbox" );
+
+ // Any number of times
+ QRadioButton* radioBut = new QRadioButton(i18n("Any number of times (including zero times)"),
+ _group,
+ "RepeatRangeWindow::choice any times");
+
+ _group->insert(radioBut, ANY);
+
+ QWidget* container = new QWidget( _group );
+ QHBoxLayout* lay = new QHBoxLayout( container );
+ QGrid* grid = new QGrid( 3, container );
+ grid->setSpacing( 5 );
+
+ lay->addWidget( grid );
+ lay->addStretch( 1 );
+
+ createLine( grid, i18n( "At least" ), &_leastTimes, ATLEAST );
+ createLine( grid, i18n( "At most" ), &_mostTimes, ATMOST );
+ createLine( grid, i18n( "Exactly" ), &_exactlyTimes, EXACTLY );
+
+ // from ___ to ___ times
+ radioBut = new QRadioButton(i18n( "From" ), grid, "RepeatRangeWindow::from");
+ _group->insert( radioBut, MINMAX );
+
+ _rangeFrom = new QSpinBox( 1, 999, 1, grid);
+
+ QHBox* box = new QHBox( grid );
+ box->setSpacing( 5 );
+
+ (void) new QLabel(i18n( "to" ), box);
+ _rangeTo = new QSpinBox( 1, 999, 1, box );
+ (void) new QLabel( i18n( "time(s)" ), box );
+
+ connect( _rangeFrom, SIGNAL( valueChanged( int ) ), this, SLOT( slotUpdateMaxVal( int ) ) );
+ connect( _rangeTo, SIGNAL( valueChanged( int ) ), this, SLOT( slotUpdateMinVal( int ) ) );
+
+ // set a default button.
+ _group->setButton(ANY);
+ slotItemChange( ANY );
+
+
+ connect( _group, SIGNAL( clicked( int ) ), this, SLOT( slotItemChange( int ) ) );
+}
+
+
+void RepeatRangeWindow::createLine( QWidget* parent, QString text, QSpinBox** spin, REPEATTYPE tp )
+{
+
+ QRadioButton* radioBut = new QRadioButton(text, parent);
+ *spin = new QSpinBox( 1, 999, 1, parent);
+ (*spin)->setValue(1);
+
+ (void) new QLabel(i18n("time(s)"), parent);
+ _group->insert(radioBut, tp);
+}
+
+void RepeatRangeWindow::slotItemChange( int which )
+{
+ _leastTimes->setEnabled( false );
+ _mostTimes->setEnabled( false );
+ _exactlyTimes->setEnabled( false );
+ _rangeFrom->setEnabled( false );
+ _rangeTo->setEnabled( false );
+
+ switch ( which ) {
+ case ANY: break;
+ case ATLEAST: _leastTimes->setEnabled( true ); break;
+ case ATMOST: _mostTimes->setEnabled( true ); break;
+ case EXACTLY: _exactlyTimes->setEnabled( true ); break;
+ case MINMAX:
+ _rangeFrom->setEnabled( true );
+ _rangeTo->setEnabled( true );
+ break;
+ }
+}
+
+void RepeatRangeWindow::slotUpdateMinVal( int maxVal )
+{
+ if ( _rangeFrom->value() > maxVal ) {
+ _rangeFrom->setValue( maxVal );
+ }
+}
+
+void RepeatRangeWindow::slotUpdateMaxVal( int minVal )
+{
+ if ( _rangeTo->value() < minVal ) {
+ _rangeTo->setValue( minVal );
+ }
+}
+
+QString RepeatRangeWindow::text()
+{
+ switch ( _group->id(_group->selected()) ) {
+ case ANY: return i18n("Repeated Any Number of Times");
+ case ATLEAST: return i18n("Repeated at Least 1 Time", "Repeated at Least %n Times", _leastTimes->value() );
+ case ATMOST: return i18n("Repeated at Most 1 Time", "Repeated at Most %n Times", _mostTimes->value() );
+ case EXACTLY: return i18n("Repeated Exactly 1 Time", "Repeated Exactly %n Times", _exactlyTimes->value() );
+ case MINMAX: return i18n("Repeated From %1 to %2 Times")
+ .arg( _rangeFrom->value() ).arg( _rangeTo->value() );
+ }
+ qFatal("Fall through!");
+ return QString::fromLocal8Bit("");
+}
+
+int RepeatRangeWindow::min()
+{
+ switch ( _group->id(_group->selected()) ) {
+ case ANY: return 0;
+ case ATLEAST: return _leastTimes->value();
+ case ATMOST: return 0;
+ case EXACTLY: return _exactlyTimes->value();
+ case MINMAX: return _rangeFrom->value();
+ }
+ qFatal("Fall through!");
+ return -1;
+}
+
+int RepeatRangeWindow::max()
+{
+ switch ( _group->id(_group->selected()) ) {
+ case ANY: return -1;
+ case ATLEAST: return -1;
+ case ATMOST: return _mostTimes->value();
+ case EXACTLY: return _exactlyTimes->value();
+ case MINMAX: return _rangeTo->value();
+ }
+ qFatal("Fall through!");
+ return -1;
+}
+
+void RepeatRangeWindow::set( REPEATTYPE tp, int min, int max )
+{
+ _group->setButton( tp );
+ switch ( tp ) {
+ case ANY:
+ break;
+ case ATLEAST:
+ _leastTimes->setValue( min );
+ break;
+ case ATMOST:
+ _mostTimes->setValue( max );
+ break;
+ case EXACTLY:
+ _exactlyTimes->setValue( min );
+ break;
+ case MINMAX:
+ _rangeFrom->setValue( min );
+ _rangeTo->setValue( max );
+ break;
+ }
+}
diff --git a/kregexpeditor/repeatwidget.h b/kregexpeditor/repeatwidget.h
new file mode 100644
index 0000000..434b4cb
--- /dev/null
+++ b/kregexpeditor/repeatwidget.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __repeatwidget
+#define __repeatwidget
+
+#include "singlecontainerwidget.h"
+#include <qvbox.h>
+class QButtonGroup;
+class KDialogBase;
+class QCheckBox;
+class QSpinBox;
+class RepeatRegExp;
+
+/**
+ Widget containging the configuration for a @ref RepeatWidget
+ @internal
+*/
+class RepeatRangeWindow :public QVBox
+{
+Q_OBJECT
+
+public:
+ enum REPEATTYPE {ANY, ATLEAST, ATMOST, EXACTLY, MINMAX};
+
+ RepeatRangeWindow( QWidget* parent, const char* name = 0 );
+ QString text();
+ int min();
+ int max();
+ void set( REPEATTYPE tp, int min, int max );
+
+protected slots:
+ void slotItemChange( int which );
+ void slotUpdateMinVal( int minVal );
+ void slotUpdateMaxVal( int minVal );
+
+
+private:
+ void createLine( QWidget* parent, QString text, QSpinBox** spin, REPEATTYPE tp );
+
+ QSpinBox* _leastTimes;
+ QSpinBox* _mostTimes;
+ QSpinBox* _exactlyTimes;
+ QSpinBox* _rangeFrom;
+ QSpinBox* _rangeTo;
+ QButtonGroup* _group;
+};
+
+
+
+
+
+/**
+ RegExp widget for `repeated content'
+ @internal
+*/
+class RepeatWidget :public SingleContainerWidget
+{
+Q_OBJECT
+
+public:
+ RepeatWidget( RegExpEditorWindow* editorWindow, QWidget *parent,
+ const char *name = 0);
+ RepeatWidget( RepeatRegExp* regexp, RegExpEditorWindow* editorWindow,
+ QWidget* parent, const char* name = 0);
+ void init();
+ virtual QSize sizeHint() const;
+ virtual RegExp* regExp() const;
+ virtual RegExpType type() const { return REPEAT; }
+ virtual int edit();
+
+protected:
+ virtual void paintEvent( QPaintEvent *e );
+
+protected slots:
+ void slotConfigCanceled();
+ void slotConfigWindowClosed();
+
+private:
+ KDialogBase* _configWindow;
+ RepeatRangeWindow* _content;
+
+ mutable QSize _textSize;
+ mutable QSize _childSize;
+ QByteArray _backup;
+};
+
+
+#endif // __repeatwidget
diff --git a/kregexpeditor/scrollededitorwindow.cpp b/kregexpeditor/scrollededitorwindow.cpp
new file mode 100644
index 0000000..8518db9
--- /dev/null
+++ b/kregexpeditor/scrollededitorwindow.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef QT_ONLY
+ #include "scrollededitorwindow.moc"
+#endif
+
+#include "scrollededitorwindow.h"
+#include "editorwindow.h"
+
+RegExpScrolledEditorWindow::RegExpScrolledEditorWindow( QWidget* parent, const char* name)
+ : QWidget(parent, name)
+{
+ _scrollView = new QScrollView( this );
+ _editorWindow = new RegExpEditorWindow( _scrollView->viewport());
+ _scrollView->addChild( _editorWindow );
+ _scrollView->setResizePolicy( QScrollView::Manual );
+
+ connect( _editorWindow, SIGNAL( contentChanged( QPoint ) ),
+ this, SLOT( slotUpdateContentSize( QPoint ) ) );
+
+ connect( _editorWindow, SIGNAL( scrolling( QPoint ) ),
+ this, SLOT( slotScroll( QPoint ) ) );
+
+ connect( _editorWindow, SIGNAL( doneEditing() ), this, SIGNAL( doneEditing() ) );
+
+ connect( _editorWindow, SIGNAL( change() ), this, SIGNAL( change() ) );
+ connect( _editorWindow, SIGNAL( savedRegexp() ), this, SIGNAL( savedRegexp() ) );
+
+ connect( _editorWindow, SIGNAL( anythingSelected(bool) ), this, SIGNAL( anythingSelected(bool) ) );
+ connect( _editorWindow, SIGNAL( anythingOnClipboard(bool) ), this, SIGNAL( anythingOnClipboard(bool) ) );
+ connect( _editorWindow, SIGNAL( canSave(bool) ), this, SIGNAL( canSave(bool) ) );
+ connect( _editorWindow, SIGNAL( verifyRegExp() ), this, SIGNAL( verifyRegExp() ) );
+}
+
+void RegExpScrolledEditorWindow::slotSetRegExp( RegExp* regexp )
+{
+ _editorWindow->slotSetRegExp( regexp );
+ slotUpdateContentSize(QPoint());
+}
+
+void RegExpScrolledEditorWindow::slotInsertRegExp( int tp)
+{
+ _editorWindow->slotInsertRegExp( (RegExpType) tp );
+}
+
+void RegExpScrolledEditorWindow::slotInsertRegExp( RegExp* regexp)
+{
+ _editorWindow->slotInsertRegExp( regexp );
+}
+
+void RegExpScrolledEditorWindow::slotDeleteSelection()
+{
+ _editorWindow->slotDeleteSelection();
+}
+
+void RegExpScrolledEditorWindow::slotDoSelect()
+{
+ _editorWindow->slotDoSelect();
+}
+
+void RegExpScrolledEditorWindow::slotCut()
+{
+ _editorWindow->slotCut();
+}
+
+void RegExpScrolledEditorWindow::slotCopy()
+{
+ _editorWindow->slotCopy();
+}
+
+void RegExpScrolledEditorWindow::slotPaste()
+{
+ _editorWindow->slotStartPasteAction();
+}
+
+void RegExpScrolledEditorWindow::slotSave()
+{
+ _editorWindow->slotSave();
+}
+
+RegExp* RegExpScrolledEditorWindow::regExp()
+{
+ return _editorWindow->regExp();
+}
+
+void RegExpScrolledEditorWindow::resizeEvent( QResizeEvent *event )
+{
+ _scrollView->resize( event->size() );
+ slotUpdateContentSize(QPoint());
+}
+
+void RegExpScrolledEditorWindow::slotUpdateContentSize( QPoint focusPoint )
+{
+ QSize childSize = _editorWindow->sizeHint();
+ QSize vpSize = _scrollView->viewportSize(10,10);
+
+ bool change = false;
+
+ if ( childSize.width() < vpSize.width() ) {
+ childSize.setWidth( vpSize.width() );
+ change = true;
+ }
+
+ if ( childSize.height() < vpSize.height() ) {
+ childSize.setHeight( vpSize.height() );
+ change = true;
+ }
+
+ if ( change ||
+ _scrollView->contentsWidth() != childSize.width() ||
+ _scrollView->contentsHeight() != childSize.height() ) {
+ _editorWindow->resize( childSize );
+ _scrollView->resizeContents( childSize.width(), childSize.height() );
+ }
+
+ if ( !focusPoint.isNull() ) {
+ _scrollView->ensureVisible ( focusPoint.x(), focusPoint.y(), 250,250 );
+ }
+
+}
+
+
+// TODO: add timers, which will make the widget scroll when mouse is located
+// outside the QScrollView.
+void RegExpScrolledEditorWindow::slotScroll( QPoint focusPoint )
+{
+ _scrollView->ensureVisible( focusPoint.x(), focusPoint.y() );
+}
+
diff --git a/kregexpeditor/scrollededitorwindow.h b/kregexpeditor/scrollededitorwindow.h
new file mode 100644
index 0000000..725b224
--- /dev/null
+++ b/kregexpeditor/scrollededitorwindow.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __scrolledEditorWindow
+#define __scrolledEditorWindow
+
+#include <qhbox.h>
+class QScrollView;
+class RegExpEditorWindow;
+class RegExp;
+
+
+/**
+ Regular Expression editor window.
+*/
+class RegExpScrolledEditorWindow :public QWidget
+{
+ Q_OBJECT
+public:
+ RegExpScrolledEditorWindow( QWidget *parent = 0, const char* name = 0);
+ RegExp* regExp();
+
+private:
+ RegExpScrolledEditorWindow() {}; // Dont use!
+
+
+protected:
+ virtual void resizeEvent( QResizeEvent* );
+
+public slots:
+ void slotSetRegExp( RegExp* );
+ void slotInsertRegExp( int );
+ void slotInsertRegExp( RegExp* );
+ void slotDeleteSelection();
+ void slotDoSelect();
+ void slotCut();
+ void slotCopy();
+ void slotSave();
+ void slotPaste();
+
+protected slots:
+ void slotUpdateContentSize( QPoint focusPoint );
+ void slotScroll( QPoint focusPoint );
+
+ signals:
+ /**
+ This signal is emited when the user has completed an editing
+ action. The application may chose to call @ref slotDoSelect as a
+ consequence to reset to selection mode.
+ */
+ void doneEditing();
+
+ /**
+ This signal is emited whenever a change has taked place in the editor widget
+ */
+ void change();
+
+ /**
+ This signal is emitted when the user saves a regular expression.
+ */
+ void savedRegexp();
+
+ void anythingSelected( bool );
+ void anythingOnClipboard( bool );
+ void canSave( bool );
+
+ /**
+ This signal is emitted when the regular expression has changed, or
+ when the selection has changed.
+ */
+ void verifyRegExp();
+
+private:
+ RegExpEditorWindow* _editorWindow;
+ QScrollView* _scrollView;
+};
+
+#endif // __scrolledEditorWindow
diff --git a/kregexpeditor/selectablelineedit.cpp b/kregexpeditor/selectablelineedit.cpp
new file mode 100644
index 0000000..98aff72
--- /dev/null
+++ b/kregexpeditor/selectablelineedit.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#ifndef QT_ONLY
+ #include "selectablelineedit.moc"
+#endif
+
+#include "selectablelineedit.h"
+
+SelectableLineEdit::SelectableLineEdit( RegExpWidget* owner, QWidget* parent, const char* name)
+ : QLineEdit( parent, name ), _owner(owner)
+{
+ connect( this, SIGNAL( textChanged( const QString & ) ), this,
+ SLOT( slotKeyPressed() ) );
+ setAcceptDrops( false );
+}
+
+void SelectableLineEdit::setSelected( bool selected )
+{
+ if ( selected ) {
+ QPalette pal = palette().copy();
+ pal.setBrush( QColorGroup::Base, gray );
+ setPalette( pal );
+ }
+ else {
+ unsetPalette();
+ }
+ repaint();
+}
+
+QSize SelectableLineEdit::sizeHint() const
+{
+ int frameWidth = frame() ? 8 : 4; // from QLineEdit source
+ QFontMetrics metrics = fontMetrics();
+ int actualSize = metrics.width( text() );
+ int charWidth = metrics.maxWidth();
+ int height = QLineEdit::sizeHint().height();
+
+ int width;
+ if ( hasFocus() )
+ width = actualSize+6*charWidth + frameWidth;
+ else
+ width = QMAX(actualSize, charWidth) + frameWidth;
+ return QSize( width , height );
+}
+
+void SelectableLineEdit::slotKeyPressed()
+{
+ int frameWidth = frame() ? 8 : 4; // from QLineEdit source
+
+ QFontMetrics metrics = fontMetrics();
+ int actualSize = metrics.width( text() );
+
+ if ( actualSize > size().width()-frameWidth ) {
+ repaint();
+ emit parentPleaseUpdate();
+ }
+}
diff --git a/kregexpeditor/selectablelineedit.h b/kregexpeditor/selectablelineedit.h
new file mode 100644
index 0000000..653d85c
--- /dev/null
+++ b/kregexpeditor/selectablelineedit.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __selectablelineedit
+#define __selectablelineedit
+#include <qlineedit.h>
+class RegExpWidget;
+
+/**
+ A specialized QLineEdit for use in @ref TextWidget.
+
+ This widget has two main features:
+ @li when the @ref TextWidget which contains it is selected, then the
+ line edit is grayed like the rest of the widgets.
+ @li When the widget does not have the focus, it is resized to only be
+ large enough to contain the text written in it.
+
+ @internal
+*/
+class SelectableLineEdit :public QLineEdit
+{
+Q_OBJECT
+
+public:
+ SelectableLineEdit( RegExpWidget* owner, QWidget* parent = 0, const char* name = 0);
+ void setSelected( bool selected );
+ virtual QSize sizeHint() const;
+
+protected slots:
+ void slotKeyPressed();
+
+signals:
+ void parentPleaseUpdate();
+
+private:
+ RegExpWidget* _owner;
+};
+
+#endif
diff --git a/kregexpeditor/singlecontainerwidget.cpp b/kregexpeditor/singlecontainerwidget.cpp
new file mode 100644
index 0000000..4782dd9
--- /dev/null
+++ b/kregexpeditor/singlecontainerwidget.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef QT_ONLY
+ #include "singlecontainerwidget.moc"
+#endif
+
+#include "singlecontainerwidget.h"
+#include "concwidget.h"
+
+SingleContainerWidget::SingleContainerWidget(RegExpEditorWindow* editorWindow,
+ QWidget* parent, const char* name)
+ : RegExpWidget( editorWindow, parent, name )
+{
+}
+
+bool SingleContainerWidget::updateSelection( bool parentSelected )
+{
+ bool changed = RegExpWidget::updateSelection( parentSelected );
+ changed = _child->updateSelection( _isSelected ) && changed;
+ if (changed)
+ repaint();
+
+ return changed;
+}
+
+bool SingleContainerWidget::hasSelection() const
+{
+ return _isSelected || _child->hasSelection();
+}
+
+void SingleContainerWidget::clearSelection()
+{
+ _isSelected = false;
+ _child->clearSelection();
+}
+
+void SingleContainerWidget::deleteSelection()
+{
+ _child->deleteSelection();
+ update();
+}
+
+void SingleContainerWidget::applyRegExpToSelection( RegExpType type )
+{
+ _child->applyRegExpToSelection( type );
+}
+
+RegExp* SingleContainerWidget::selection() const
+{
+ if ( isSelected() )
+ return regExp();
+ else
+ return _child->selection();
+}
+
+bool SingleContainerWidget::validateSelection() const
+{
+ return _child->validateSelection();
+}
+
+QRect SingleContainerWidget::selectionRect() const
+{
+ if ( _isSelected )
+ return QRect( mapToGlobal( QPoint(0,0) ), size() );
+ else
+ return _child->selectionRect();
+}
+
+RegExpWidget* SingleContainerWidget::widgetUnderPoint( QPoint globalPos, bool justVisibleWidgets )
+{
+ RegExpWidget* wid = _child->widgetUnderPoint( globalPos, justVisibleWidgets );
+ if ( wid )
+ return wid;
+ else {
+ // The child didn't contain the point, then lets see if this widget
+ // itself does.
+ return RegExpWidget::widgetUnderPoint( globalPos, justVisibleWidgets );
+ }
+}
+
+RegExpWidget* SingleContainerWidget::findWidgetToEdit( QPoint globalPos )
+{
+ RegExpWidget* wid = _child->findWidgetToEdit( globalPos );
+ if ( wid )
+ return wid;
+ else if ( QRect(mapToGlobal(QPoint(0,0)), size()).contains( globalPos ) )
+ return this;
+ else
+ return 0;
+}
+
+void SingleContainerWidget::setConcChild( ConcWidget* conc )
+{
+ delete _child;
+ _child = conc;
+}
+
+void SingleContainerWidget::selectWidget( bool sel )
+{
+ RegExpWidget::selectWidget( sel );
+ _child->selectWidget( sel );
+ update();
+}
+
+void SingleContainerWidget::updateAll()
+{
+ _child->updateAll();
+ RegExpWidget::updateAll();
+}
+
+void SingleContainerWidget::updateCursorRecursively()
+{
+ _child->updateCursorRecursively();
+ updateCursorShape();
+}
+
+
diff --git a/kregexpeditor/singlecontainerwidget.h b/kregexpeditor/singlecontainerwidget.h
new file mode 100644
index 0000000..8f07e6a
--- /dev/null
+++ b/kregexpeditor/singlecontainerwidget.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __singlecontainer
+#define __singlecontainer
+#include "regexpwidget.h"
+
+/**
+ Abstract class representing RegExp widgets having a single child.
+*/
+class SingleContainerWidget :public RegExpWidget
+{
+Q_OBJECT
+
+public:
+ SingleContainerWidget( RegExpEditorWindow* editorWindow, QWidget* parent,
+ const char* name = 0);
+
+ virtual bool updateSelection( bool parentSelected );
+ virtual bool hasSelection() const;
+ virtual void clearSelection();
+ virtual void deleteSelection();
+ virtual void applyRegExpToSelection( RegExpType type );
+ virtual RegExp* selection() const;
+ virtual bool validateSelection() const;
+ virtual QRect selectionRect() const;
+ virtual RegExpWidget* widgetUnderPoint( QPoint globalPos, bool justVisibleWidgets );
+ virtual RegExpWidget* findWidgetToEdit( QPoint globalPos );
+ virtual void setConcChild( ConcWidget* child );
+ virtual void selectWidget( bool sel );
+ virtual void updateAll();
+ virtual void updateCursorRecursively();
+
+protected:
+ ConcWidget *_child;
+};
+
+
+#endif // __singlecontainer
diff --git a/kregexpeditor/test-without-dl/Makefile.am b/kregexpeditor/test-without-dl/Makefile.am
new file mode 100644
index 0000000..2162d09
--- /dev/null
+++ b/kregexpeditor/test-without-dl/Makefile.am
@@ -0,0 +1,8 @@
+check_PROGRAMS = regexptest
+regexptest_SOURCES = main.cpp
+regexptest_LDFLAGS = $(all_libraries)
+regexptest_LDADD = ../libkregexpeditorgui.la $(LIB_KSYCOCA)
+INCLUDES = $(all_includes)
+KDE_CXXFLAGS = -g
+
+METASOURCES = AUTO
diff --git a/kregexpeditor/test-without-dl/main.cpp b/kregexpeditor/test-without-dl/main.cpp
new file mode 100644
index 0000000..54610ac
--- /dev/null
+++ b/kregexpeditor/test-without-dl/main.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <qfile.h>
+#include "../kregexpeditorgui.h"
+class ShootABug :public QObject
+{
+public:
+ virtual bool eventFilter( QObject* recv, QEvent* event )
+ {
+ if ( event->type() == QEvent::MouseButtonPress &&
+ dynamic_cast<QMouseEvent*>(event)->state() == Qt::ControlButton ) {
+ // Ctrl + left mouse click.
+
+ qDebug("----------------------------------------------------");
+ qDebug((QString("Widget name : ") + QString( recv->name() )).latin1() );
+ qDebug((QString("Widget class: ") + QString( recv->className() )).latin1() );
+ qDebug("\nObject info:");
+ recv->dumpObjectInfo();
+ qDebug("\nObject tree:");
+ recv->dumpObjectTree();
+ qDebug("----------------------------------------------------");
+ return false;
+ }
+ return false;
+ }
+};
+
+int main( int argc, char* argv[] )
+{
+ KCmdLineArgs::init(argc, argv, "RegExp Example","","");
+ KApplication myapp( argc, argv );
+
+ qApp->installEventFilter( new ShootABug() );
+
+ KRegExpEditorGUIDialog* iface = new KRegExpEditorGUIDialog( 0, "_editor", QStringList() );
+ iface->setRegExp( QString::fromLatin1( "#include" ) );
+ iface->doSomething( "setMinimal", (void*) false );
+ iface->doSomething( "setSyntax", (void*) new QString( QString::fromLatin1( "Emacs" ) ) );
+ iface->doSomething( "setShowSyntaxCombo", (bool*) true );
+
+ QFile file("/packages/kde-src/kdeutils/kregexpeditor/test/main.cpp");
+ file.open(IO_ReadOnly);
+ QTextStream stream( &file);
+ QString txt = stream.read();
+ iface->setMatchText( txt );
+
+ iface->exec();
+}
+
diff --git a/kregexpeditor/textrangeregexp.cpp b/kregexpeditor/textrangeregexp.cpp
new file mode 100644
index 0000000..73c2923
--- /dev/null
+++ b/kregexpeditor/textrangeregexp.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <klocale.h>
+ #include <kmessagebox.h>
+#endif
+
+#include "textrangeregexp.h"
+#include "regexpconverter.h"
+
+TextRangeRegExp::TextRangeRegExp( bool selected ) : RegExp( selected ),
+ _negate(false), _digit(false), _nonDigit(false), _space(false), _nonSpace(false), _wordChar(false), _nonWordChar(false)
+{
+}
+
+TextRangeRegExp::~TextRangeRegExp()
+{
+}
+
+
+void TextRangeRegExp::addCharacter( QString str )
+{
+ _chars.append( str );
+}
+
+void TextRangeRegExp::addRange(QString from, QString to)
+{
+ _ranges.append( new StringPair( from, to ) );
+}
+
+bool TextRangeRegExp::check( ErrorMap&, bool, bool )
+{
+ return false;
+}
+
+QDomNode TextRangeRegExp::toXml( QDomDocument* doc ) const
+{
+ QDomElement top = doc->createElement( QString::fromLocal8Bit( "TextRange" ) );
+
+ if ( _negate )
+ top.setAttribute( QString::fromLocal8Bit("negate"), true );
+ if ( _digit )
+ top.setAttribute( QString::fromLocal8Bit("digit"), true );
+ if ( _nonDigit )
+ top.setAttribute( QString::fromLocal8Bit("nonDigit"), true );
+ if ( _space )
+ top.setAttribute( QString::fromLocal8Bit("space"), true );
+ if ( _nonSpace )
+ top.setAttribute( QString::fromLocal8Bit("nonSpace"), true );
+ if ( _wordChar )
+ top.setAttribute( QString::fromLocal8Bit("wordChar"), true );
+ if ( _nonWordChar )
+ top.setAttribute( QString::fromLocal8Bit("nonWordChar"), true );
+
+ for ( QStringList::ConstIterator it = _chars.begin(); it != _chars.end(); ++it ) {
+ QDomElement elm = doc->createElement( QString::fromLocal8Bit( "Character" ) );
+ elm.setAttribute( QString::fromLocal8Bit( "char" ), *it );
+ top.appendChild( elm );
+ }
+
+ for ( QPtrListIterator<StringPair> it2(_ranges); *it2; ++it2 ) {
+ QDomElement elm = doc->createElement( QString::fromLocal8Bit( "Range" ) );
+ elm.setAttribute( QString::fromLocal8Bit( "from" ), (*it2)->first() );
+ elm.setAttribute( QString::fromLocal8Bit( "to" ), (*it2)->second() );
+ top.appendChild( elm );
+ }
+ return top;
+}
+
+bool TextRangeRegExp::load( QDomElement top, const QString& /*version*/ )
+{
+ Q_ASSERT( top.tagName() == QString::fromLocal8Bit( "TextRange" ) );
+ QString str;
+ QString one = QString::fromLocal8Bit("1");
+ QString zero = QString::fromLocal8Bit("0");
+
+ str = top.attribute( QString::fromLocal8Bit("negate"), zero );
+ _negate = ( str == one );
+
+ str = top.attribute( QString::fromLocal8Bit("digit"), zero );
+ _digit = ( str == one );
+
+ str = top.attribute( QString::fromLocal8Bit("nonDigit"), zero );
+ _nonDigit = ( str == one );
+
+ str = top.attribute( QString::fromLocal8Bit("space"), zero );
+ _space = ( str == one );
+
+ str = top.attribute( QString::fromLocal8Bit("nonSpace"), zero );
+ _nonSpace = ( str == one );
+
+ str = top.attribute( QString::fromLocal8Bit("wordChar"), zero );
+ _wordChar = ( str == one );
+
+ str = top.attribute( QString::fromLocal8Bit("nonWordChar"), zero );
+ _nonWordChar = ( str == one );
+
+ for ( QDomNode node = top.firstChild(); !node.isNull(); node = node.nextSibling() ) {
+ if ( !node.isElement() )
+ continue; // Skip comments.
+ QDomElement child = node.toElement();
+
+ if ( child.tagName() == QString::fromLocal8Bit( "Character" ) ) {
+ QString ch = child.attribute( QString::fromLocal8Bit( "char" ) );
+ addCharacter( ch );
+ }
+ else if ( child.tagName() == QString::fromLocal8Bit( "Range" ) ) {
+ QString from = child.attribute( QString::fromLocal8Bit( "from" ) );
+ QString to = child.attribute( QString::fromLocal8Bit( "to" ) );
+ addRange( from, to );
+ }
+ else {
+ KMessageBox::sorry( 0, i18n("<p>Invalid sub element to element <b>TextRange</b>. Tag was <b>%1</b></p>").arg(child.tagName()),
+ i18n("Error While Loading From XML File") ) ;
+ return false;
+ }
+ }
+ return true;
+}
+
+bool TextRangeRegExp::operator==( const RegExp& other ) const
+{
+ return ( RegExpConverter::current()->toStr( const_cast<TextRangeRegExp*>( this ), false ) ==
+ RegExpConverter::current()->toStr( const_cast<RegExp*>( &other ), false ) );
+}
+
diff --git a/kregexpeditor/textrangeregexp.h b/kregexpeditor/textrangeregexp.h
new file mode 100644
index 0000000..de1785e
--- /dev/null
+++ b/kregexpeditor/textrangeregexp.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __TEXTRANGEREGEXP_H
+#define __TEXTRANGEREGEXP_H
+
+#include "regexp.h"
+#include "pair.h"
+#include <qstringlist.h>
+
+typedef Pair<QString,QString> StringPair;
+
+/**
+ Abstract syntax node for `text range' regular expression
+
+ @internal
+*/
+class TextRangeRegExp :public RegExp
+{
+public:
+ TextRangeRegExp( bool selected );
+ virtual ~TextRangeRegExp();
+
+ void addCharacter( QString ch );
+ QStringList chars() const { return _chars; }
+ void clearChars() { _chars.clear(); }
+
+ void addRange( QString from, QString to );
+ QPtrList<StringPair> range() const { return _ranges; }
+ void clearRange() { _ranges.clear(); }
+
+ void setNegate( bool set ) { _negate = set; }
+ void setDigit( bool set ) { _digit = set; }
+ void setNonDigit( bool set ) { _nonDigit = set; }
+ void setSpace( bool set ) { _space = set; }
+ void setNonSpace( bool set ) { _nonSpace = set; }
+ void setWordChar( bool set ) { _wordChar = set; }
+ void setNonWordChar( bool set ) { _nonWordChar = set; }
+
+ bool negate() const { return _negate; }
+ bool digit() const { return _digit; }
+ bool nonDigit() const { return _nonDigit; }
+ bool space() const { return _space; }
+ bool nonSpace() const { return _nonSpace; }
+ bool wordChar() const { return _wordChar; }
+ bool nonWordChar() const { return _nonWordChar; }
+
+ virtual bool check( ErrorMap&, bool first, bool last );
+ virtual int precedence() const { return 4;}
+ virtual QDomNode toXml( QDomDocument* doc ) const;
+ virtual bool load( QDomElement, const QString& version );
+ virtual RegExpType type() const { return TEXTRANGE;}
+ virtual bool operator==( const RegExp& other ) const;
+
+private:
+ bool _negate, _digit, _nonDigit, _space, _nonSpace, _wordChar, _nonWordChar;
+ QStringList _chars;
+ QPtrList<StringPair> _ranges;
+};
+
+#endif // __TEXTRANGEREGEXP_H
diff --git a/kregexpeditor/textregexp.cpp b/kregexpeditor/textregexp.cpp
new file mode 100644
index 0000000..7d5d02c
--- /dev/null
+++ b/kregexpeditor/textregexp.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <kmessagebox.h>
+ #include <klocale.h>
+#endif
+
+#include "textregexp.h"
+
+TextRegExp::TextRegExp( bool selected, QString text) :RegExp( selected )
+{
+ _text = text;
+}
+
+bool TextRegExp::check( ErrorMap&, bool, bool )
+{
+ return false;
+}
+
+
+void TextRegExp::append( QString str )
+{
+ _text.append( str );
+}
+
+QDomNode TextRegExp::toXml( QDomDocument* doc ) const
+{
+ QDomElement top = doc->createElement(QString::fromLocal8Bit("Text"));
+ QDomText text = doc->createTextNode( _text );
+ top.appendChild( text );
+ return top;
+}
+
+bool TextRegExp::load( QDomElement top, const QString& /*version*/)
+{
+ Q_ASSERT( top.tagName() == QString::fromLocal8Bit( "Text" ) );
+ if ( top.hasChildNodes() ) {
+ QDomNode child = top.firstChild();
+ if ( ! child.isText() ) {
+ KMessageBox::sorry( 0, i18n("<p>Element <b>Text</b> did not contain any textual data.</p>"),
+ i18n("Error While Loading From XML File") ) ;
+ return false;
+ }
+ QDomText txtNode = child.toText();
+ _text = txtNode.data();
+ }
+ else {
+ _text = QString::fromLatin1( "" );
+ }
+
+ return true;
+}
+
+bool TextRegExp::operator==( const RegExp& other ) const {
+ if ( other.type() != type() )
+ return false;
+
+ const TextRegExp& theOther = dynamic_cast<const TextRegExp&>( other );
+ if ( text() == theOther.text() )
+ return true;
+
+ return false;
+}
+
diff --git a/kregexpeditor/textregexp.h b/kregexpeditor/textregexp.h
new file mode 100644
index 0000000..f98d0e9
--- /dev/null
+++ b/kregexpeditor/textregexp.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __textregexp_h
+#define __textregexp_h
+
+#include "regexp.h"
+
+/**
+ Abstract syntax node for `text' regular expression
+ @internal
+*/
+class TextRegExp :public RegExp
+{
+public:
+ TextRegExp( bool selected, QString text = QString::null);
+
+ virtual bool check( ErrorMap&, bool first, bool last );
+ virtual int precedence() const {
+ if ( _text.length() > 1 )
+ return 2;
+ else
+ return 4;
+ }
+ QString text() const { return _text; }
+ virtual QDomNode toXml( QDomDocument* doc ) const;
+ virtual bool load( QDomElement, const QString& version );
+ void append( QString str);
+ virtual RegExpType type() const { return TEXT;}
+ virtual bool operator==( const RegExp& other ) const;
+
+private:
+ QString _text;
+};
+
+#endif // __textregexp_h
diff --git a/kregexpeditor/textwidget.cpp b/kregexpeditor/textwidget.cpp
new file mode 100644
index 0000000..c36d1a8
--- /dev/null
+++ b/kregexpeditor/textwidget.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef QT_ONLY
+ #include "textwidget.moc"
+#endif
+
+#include "textwidget.h"
+#include "textregexp.h"
+#include "selectablelineedit.h"
+#include <qlayout.h>
+
+TextWidget::TextWidget(RegExpEditorWindow* editorWindow, QWidget *parent,
+ const char *name)
+ :RegExpWidget(editorWindow, parent, name)
+{
+ init( QString::fromLocal8Bit("") );
+}
+
+TextWidget::TextWidget( TextRegExp* regexp, RegExpEditorWindow* editorWindow,
+ QWidget* parent, const char* name )
+ : RegExpWidget( editorWindow, parent, name )
+{
+ init(regexp->text());
+}
+
+void TextWidget::init( const QString& txt )
+{
+ QHBoxLayout *lay = new QHBoxLayout(this);
+ _edit = new SelectableLineEdit( this, this, "TextWidget::edit" );
+ _edit->setDragEnabled( false ); //otherwise QLineEdit::mouseMoveEvent will set the cursor over and over again.
+ lay->addWidget(_edit);
+
+ _edit->setText( txt );
+
+ connect( _edit, SIGNAL( parentPleaseUpdate() ), this, SLOT(slotUpdate()) );
+ setFocusProxy( _edit );
+ _edit->installEventFilter( this );
+ connect( _edit, SIGNAL( textChanged( const QString & ) ), _editorWindow, SLOT( emitChange() ) );
+}
+
+
+void TextWidget::slotUpdate()
+{
+ // I need to force the parent to repaint, as the size change of this
+ // widget may not be enough for the parent to change size, and in that
+ // case the parent would not repaint, and the text widget would not be
+ // resized.
+ QWidget *p = static_cast<QWidget*>(parent());
+ if (p)
+ p->repaint();
+ _editorWindow->updateContent( this );
+}
+
+QSize TextWidget::sizeHint() const
+{
+ return _edit->sizeHint();
+}
+
+void TextWidget::paintEvent( QPaintEvent *e)
+{
+ RegExpWidget::paintEvent(e);
+}
+
+void TextWidget::selectWidget( bool sel )
+{
+ _edit->setSelected( sel );
+}
+
+bool TextWidget::updateSelection(bool parentSelected)
+{
+ bool changed = RegExpWidget::updateSelection( parentSelected );
+
+ // I need to call this function all the time, else the rubber band will
+ // not be correctly deleted in the line edit.
+ _edit->setSelected( _isSelected );
+ return changed;
+}
+void TextWidget::updateAll()
+{
+ _edit->update();
+ update();
+}
+
+void TextWidget::clearSelection()
+{
+ _isSelected = false;
+ _edit->setSelected( false );
+}
+
+RegExp* TextWidget::regExp() const
+{
+ return new TextRegExp( isSelected(), _edit->text() );
+}
+
+bool TextWidget::eventFilter( QObject*, QEvent* event)
+{
+ // This is an event filter (in contrast to methods in SelectableLineEdit),
+ // otherwise lots of functions would need to be exported from TextWidget.
+ if ( event->type() == QEvent::MouseButtonRelease ) {
+ if ( _editorWindow->isInserting() ) {
+ if ( acceptWidgetInsert( _editorWindow->insertType() ) ) {
+ mouseReleaseEvent( static_cast<QMouseEvent*>(event) );
+ }
+ return true;
+ }
+ }
+ else if ( event->type() == QEvent::MouseButtonPress ) {
+ if ( _editorWindow->isInserting() ) {
+ return true;
+ }
+ else if ( isSelected() ) {
+ QMouseEvent* e = static_cast<QMouseEvent*>( event );
+ QMouseEvent ev( event->type(), mapTo(_editorWindow, e->pos()),
+ e->button(), e->state());
+ QApplication::sendEvent( _editorWindow, &ev );
+ return true;
+ }
+ }
+
+ else if ( event->type() == QEvent::Enter ) {
+ if ( _editorWindow->isInserting() ) {
+ if ( acceptWidgetInsert( _editorWindow->insertType() ) ) {
+ _edit->setCursor(crossCursor);
+ }
+ else {
+ _edit->setCursor(forbiddenCursor);
+ }
+ }
+ else if ( isSelected() ) {
+ _edit->setCursor( arrowCursor );
+ }
+ else {
+ _edit->setCursor( ibeamCursor );
+ }
+ }
+ else if ( event->type() == QEvent::MouseButtonDblClick && _editorWindow->isInserting() ) {
+ return true;
+ }
+ return false;
+}
+
+
diff --git a/kregexpeditor/textwidget.h b/kregexpeditor/textwidget.h
new file mode 100644
index 0000000..9a5c0be
--- /dev/null
+++ b/kregexpeditor/textwidget.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __textwidget
+#define __textwidget
+
+#include "regexpwidget.h"
+class SelectableLineEdit;
+class TextRegExp;
+
+/**
+ RegExp widget representing text.
+
+ @internal
+*/
+class TextWidget : public RegExpWidget
+{
+ Q_OBJECT
+
+public:
+ TextWidget(RegExpEditorWindow* editorWindow, QWidget *parent,
+ const char *name = 0);
+ TextWidget( TextRegExp* regexp, RegExpEditorWindow* editorWindow,
+ QWidget* parent, const char* name = 0);
+ virtual QSize sizeHint() const;
+ virtual RegExp* regExp() const;
+ virtual RegExpType type() const { return TEXT; }
+ virtual void updateAll();
+ virtual void selectWidget( bool );
+
+protected:
+ void init( const QString& text );
+ virtual void paintEvent( QPaintEvent *e );
+ virtual bool updateSelection( bool parentSelected );
+ virtual void clearSelection();
+ virtual bool eventFilter( QObject*, QEvent* );
+
+protected slots:
+ void slotUpdate();
+
+private:
+ QString text;
+ SelectableLineEdit *_edit;
+ QSize textSize, boxSize, editSize;
+};
+
+
+
+#endif // __textwidget
diff --git a/kregexpeditor/triple.h b/kregexpeditor/triple.h
new file mode 100644
index 0000000..c44276c
--- /dev/null
+++ b/kregexpeditor/triple.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __triple_h
+#define __triple_h
+
+/**
+ @internal
+*/
+template<class F, class S, class T> class Triple
+{
+public:
+ Triple() {};
+ Triple(F first, S second, T third) : _first(first), _second(second),
+ _third(third) {}
+ F first() { return _first; }
+ S second() { return _second; }
+ T third() { return _third; }
+private:
+ F _first;
+ S _second;
+ T _third;
+
+};
+
+#endif // __triple_h
diff --git a/kregexpeditor/userdefinedregexps.cpp b/kregexpeditor/userdefinedregexps.cpp
new file mode 100644
index 0000000..de2f675
--- /dev/null
+++ b/kregexpeditor/userdefinedregexps.cpp
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifdef QT_ONLY
+ #include "compat.h"
+#else
+ #include <klineeditdlg.h>
+ #include <klocale.h>
+ #include <kmessagebox.h>
+ #include <kstandarddirs.h>
+ #include <kdebug.h>
+ #include "userdefinedregexps.moc"
+#endif
+
+#include "userdefinedregexps.h"
+#include <qheader.h>
+#include <qpopupmenu.h>
+#include <qdir.h>
+#include "widgetfactory.h"
+#include "compoundregexp.h"
+#include <qlayout.h>
+#include <qlabel.h>
+
+UserDefinedRegExps::UserDefinedRegExps( QWidget *parent, const char *name )
+ : QDockWindow( QDockWindow::InDock, parent, name)
+{
+ QWidget* top = new QWidget( this );
+ QVBoxLayout* lay = new QVBoxLayout( top, 6 );
+ lay->setAutoAdd( true );
+
+ QLabel* label = new QLabel( i18n("Compound regular expressions:"), top );
+
+ // This is to avoid that the label set the minimum width for the window.
+ label->setMinimumSize(1,0);
+
+ _userDefined = new QListView( top, "UserDefinedRegExps::_userDefined" );
+ _userDefined->addColumn( QString::null );
+ _userDefined->header()->hide();
+ // _userDefined->setRootIsDecorated( true );
+ setWidget( top );
+ slotPopulateUserRegexps();
+
+ connect( _userDefined, SIGNAL(clicked(QListViewItem*)), this, SLOT(slotLoad(QListViewItem*)) );
+ connect( _userDefined, SIGNAL(rightButtonPressed(QListViewItem*,const QPoint&, int )),
+ this, SLOT( slotEdit( QListViewItem*, const QPoint& ) ) );
+}
+
+void UserDefinedRegExps::slotPopulateUserRegexps()
+{
+ _userDefined->clear();
+ _regExps.clear();
+
+ createItems( i18n("User Defined"), WidgetWinItem::path(), true );
+
+#ifdef QT_ONLY
+ QStringList dirs;
+ dirs << QString::fromLatin1( "predefined" );
+#else
+ QStringList dirs = KGlobal::dirs()->findDirs( "data", QString::fromLocal8Bit("kregexpeditor/predefined/") );
+#endif
+
+ for ( QStringList::iterator it1 = dirs.begin(); it1 != dirs.end(); ++it1 ) {
+ QDir dir( *it1, QString::null, QDir::Name, QDir::Dirs );
+ QStringList subdirs = dir.entryList();
+ for ( QStringList::iterator it2 = subdirs.begin(); it2 != subdirs.end(); ++it2 ) {
+ if ( *it2 == QString::fromLocal8Bit(".") || *it2 == QString::fromLocal8Bit("..") )
+ continue;
+ createItems( *it2, *it1 + QString::fromLocal8Bit("/") + *it2, false );
+ }
+ }
+
+}
+
+void UserDefinedRegExps::createItems( const QString& _title, const QString& dir, bool usersRegExp )
+{
+ QString title = _title;
+ if (_title == QString::fromLatin1("general"))
+ title = i18n("General");
+
+ QListViewItem* lvItem = new QListViewItem( _userDefined, title );
+ lvItem->setOpen( true );
+
+ QDir directory( dir );
+ QStringList files = directory.entryList( QString::fromLocal8Bit("*.regexp") );
+ for ( QStringList::Iterator it = files.begin(); it != files.end(); ++it ) {
+ QString fileName = dir + QString::fromLocal8Bit("/") + *it;
+
+ QFile file( fileName );
+ if ( ! file.open(IO_ReadOnly) ) {
+ KMessageBox::sorry( this, i18n("Could not open file for reading: %1").arg(fileName) );
+ continue;
+ }
+
+ QTextStream stream( &file );
+ QString data = stream.read();
+ file.close();
+
+ RegExp* regexp = WidgetFactory::createRegExp( data );
+ if ( ! regexp ) {
+ KMessageBox::sorry( this, i18n("File %1 containing user defined regular expression contained an error").arg( fileName ) );
+ continue;
+ }
+
+ new WidgetWinItem( *it, regexp, usersRegExp, lvItem );
+
+ // Insert the regexp into the list of compound regexps
+ if ( regexp->type() == RegExp::COMPOUND ) {
+ CompoundRegExp* cregexp = dynamic_cast<CompoundRegExp*>( regexp );
+ if ( cregexp && cregexp->allowReplace() )
+ _regExps.append( cregexp );
+ }
+ }
+}
+
+const QPtrList<CompoundRegExp> UserDefinedRegExps::regExps() const
+{
+ return _regExps;
+}
+
+
+void UserDefinedRegExps::slotUnSelect()
+{
+ _userDefined->clearSelection();
+}
+
+void UserDefinedRegExps::slotLoad(QListViewItem* item)
+{
+ if ( !item || ! dynamic_cast<WidgetWinItem*>(item) ) {
+ // Mouse pressed outside a widget.
+ return;
+ }
+
+ WidgetWinItem* wwi = dynamic_cast<WidgetWinItem*>(item);
+ if (wwi) {
+ emit load( wwi->regExp() );
+ }
+}
+
+void UserDefinedRegExps::slotEdit( QListViewItem* item, const QPoint& pos )
+{
+ QPopupMenu* menu = new QPopupMenu( this );
+ menu->insertItem(i18n("Delete"), 1 );
+ menu->insertItem(i18n("Rename..."), 2 );
+ if ( !item || ! dynamic_cast<WidgetWinItem*>( item ) ) {
+ // menu not selected on an item
+ menu->setItemEnabled( 1, false );
+ menu->setItemEnabled( 2, false );
+ }
+ else {
+ // Only allow rename and delete of users own regexps.
+ WidgetWinItem* winItem = dynamic_cast<WidgetWinItem*>( item );
+ if ( winItem && ! winItem->isUsersRegExp() ) {
+ menu->setItemEnabled( 1, false );
+ menu->setItemEnabled( 2, false );
+ }
+ }
+
+ int which = menu->exec( pos );
+
+ if ( which == 1 ) { // Delete
+ WidgetWinItem* winItem = dynamic_cast<WidgetWinItem*>( item );
+ Q_ASSERT( winItem );
+ QFile file( winItem->fileName() );
+ Q_ASSERT( file.exists() );
+ file.remove();
+ delete item;
+ }
+ else if ( which == 2 ) { // Rename
+ WidgetWinItem* winItem = dynamic_cast<WidgetWinItem*>( item );
+ Q_ASSERT( winItem );
+
+ QString oldFile = winItem->fileName();
+ QString oldName = winItem->name();
+
+ QString txt;
+#ifdef QT_ONLY
+ txt = QInputDialog::getText( tr("Rename Regular Expression"), tr("New name:") );
+#else
+ KLineEditDlg dlg(i18n("New name:"), oldName, this);
+ dlg.setCaption(i18n("Rename Item"));
+ bool ok = dlg.exec();
+ if ( ok )
+ txt = dlg.text();
+#endif
+ if ( !txt.isNull() && oldName != txt ) {
+ QString fileName = WidgetWinItem::path() + QString::fromLocal8Bit("/") + txt + QString::fromLocal8Bit(".regexp");
+ QFileInfo finfo( fileName );
+ if ( finfo.exists() ) {
+ int answer = KMessageBox::warningYesNo( this, i18n("<p>Overwrite named regular expression <b>%1</b>?</p>").arg(txt), QString::null, i18n("Overwrite"), i18n("Do Not Overwrite") );
+ if ( answer != KMessageBox::Yes )
+ return;
+
+ // An item with this name already exists.
+ delete winItem;
+ }
+ else
+ winItem->setName( txt );
+ QDir dir;
+ dir.rename( oldFile, fileName );
+ }
+ }
+
+
+ delete menu;
+}
+
+void UserDefinedRegExps::slotSelectNewAction()
+{
+ slotUnSelect();
+}
+
+WidgetWinItem::WidgetWinItem( QString fileName, RegExp* regexp, bool usersRegExp, QListViewItem* parent )
+ :QListViewItem( parent ), _regexp( regexp ), _usersRegExp ( usersRegExp )
+{
+ int index = fileName.findRev(QString::fromLocal8Bit(".regexp"));
+ _name = fileName.left(index);
+
+ setText( 0, _name );
+}
+
+QString WidgetWinItem::fileName() const
+{
+ return path() + QString::fromLocal8Bit("/") +_name + QString::fromLocal8Bit(".regexp");
+}
+
+RegExp* WidgetWinItem::regExp() const
+{
+ return _regexp;
+}
+
+QString WidgetWinItem::name() const
+{
+ return _name;
+}
+
+void WidgetWinItem::setName( const QString& nm )
+{
+ _name = nm;
+ setText( 0, nm );
+}
+
+QString WidgetWinItem::path()
+{
+#ifdef QT_ONLY
+ return QString::fromLatin1( "predefined" );
+#else
+ return locateLocal("data", QString::fromLocal8Bit("KRegExpEditor/"));
+#endif
+}
+
+
+
diff --git a/kregexpeditor/userdefinedregexps.h b/kregexpeditor/userdefinedregexps.h
new file mode 100644
index 0000000..358aa73
--- /dev/null
+++ b/kregexpeditor/userdefinedregexps.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+#ifndef __USERDEFINEDREGEXPS_H
+#define __USERDEFINEDREGEXPS_H
+#include <qdockwindow.h>
+#include <qlistview.h>
+
+#include "compoundregexp.h"
+
+class QPoint;
+class RegExp;
+
+class UserDefinedRegExps :public QDockWindow
+{
+Q_OBJECT
+
+public:
+ UserDefinedRegExps( QWidget *parent, const char *name = 0 );
+ const QPtrList<CompoundRegExp> regExps() const;
+
+public slots:
+ void slotSelectNewAction();
+
+protected slots:
+ void slotLoad(QListViewItem* item);
+ void slotEdit( QListViewItem* item, const QPoint& pos );
+ void slotPopulateUserRegexps();
+ void slotUnSelect();
+
+protected:
+ void createItems( const QString& title, const QString& dir, bool usersRegExp );
+
+signals:
+ void load( RegExp* );
+
+private:
+ QListView* _userDefined;
+ QPtrList<CompoundRegExp> _regExps;
+};
+
+class WidgetWinItem :public QListViewItem
+{
+public:
+ WidgetWinItem( QString name, RegExp* regexp, bool users, QListViewItem* parent );
+ static QString path();
+
+ QString fileName() const;
+ RegExp* regExp() const;
+ QString name() const;
+ void setName( const QString& );
+ bool isUsersRegExp() const { return _usersRegExp; }
+
+private:
+ QString _name;
+ RegExp* _regexp;
+ bool _usersRegExp;
+};
+
+
+#endif // __USERDEFINEDREGEXPS_H
diff --git a/kregexpeditor/util.cpp b/kregexpeditor/util.cpp
new file mode 100644
index 0000000..8bff5de
--- /dev/null
+++ b/kregexpeditor/util.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2002-2004 Jesper K. Pedersen <blackie@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#include "util.h"
+#include <kiconloader.h>
+#include <kstandarddirs.h>
+QPixmap Util::getKRegExpEditorIcon( const QString& name )
+{
+#ifdef QT_ONLY
+ QPixmap pix;
+ pix.convertFromImage( qembed_findImage(name) );
+ return pix;
+#else
+ return KGlobal::iconLoader()->loadIcon(locate("data", QString::fromLatin1("kregexpeditor/pics/") +name ),
+ KIcon::Toolbar );
+#endif
+}
+
+QPixmap Util::getSystemIcon( const QString& name )
+{