summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--apps/Applications/tinykate.desktop8
-rwxr-xr-xnoncore/apps/tinykate/install13
-rw-r--r--noncore/apps/tinykate/libkate/document/katebuffer.cpp179
-rw-r--r--noncore/apps/tinykate/libkate/document/katebuffer.h143
-rw-r--r--noncore/apps/tinykate/libkate/document/katecmd.cpp58
-rw-r--r--noncore/apps/tinykate/libkate/document/katecmd.h57
-rw-r--r--noncore/apps/tinykate/libkate/document/katecmds.cpp278
-rw-r--r--noncore/apps/tinykate/libkate/document/katecmds.h94
-rw-r--r--noncore/apps/tinykate/libkate/document/katedialogs.cpp588
-rw-r--r--noncore/apps/tinykate/libkate/document/katedialogs.h160
-rw-r--r--noncore/apps/tinykate/libkate/document/katedocument.cpp3169
-rw-r--r--noncore/apps/tinykate/libkate/document/katedocument.h569
-rw-r--r--noncore/apps/tinykate/libkate/document/katedocumentIface.h32
-rw-r--r--noncore/apps/tinykate/libkate/document/katehighlight.cpp1459
-rw-r--r--noncore/apps/tinykate/libkate/document/katehighlight.h349
-rw-r--r--noncore/apps/tinykate/libkate/document/katesyntaxdocument.cpp306
-rw-r--r--noncore/apps/tinykate/libkate/document/katesyntaxdocument.h73
-rw-r--r--noncore/apps/tinykate/libkate/document/katetextline.cpp289
-rw-r--r--noncore/apps/tinykate/libkate/document/katetextline.h359
-rw-r--r--noncore/apps/tinykate/libkate/interfaces/document.h103
-rw-r--r--noncore/apps/tinykate/libkate/interfaces/interfaces.cpp51
-rw-r--r--noncore/apps/tinykate/libkate/interfaces/view.h160
-rw-r--r--noncore/apps/tinykate/libkate/ktexteditor/ktexteditor.cpp140
-rw-r--r--noncore/apps/tinykate/libkate/ktexteditor/ktexteditor.h239
-rw-r--r--noncore/apps/tinykate/libkate/libkate.pro90
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kaction.h8
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kapplication.cpp8
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kapplication.h11
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kcolorbtn.cpp84
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kcolorbtn.h92
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kcolorbutton.h4
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kcolordialog.cpp6
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kcolordialog.h14
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kconfig.cpp181
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kconfig.h51
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kdatepicker.cpp405
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kdatepicker.h177
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kdatetbl.cpp718
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kdatetbl.h308
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kdebug.h112
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kdialog.h16
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kdialogbase.cpp214
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kdialogbase.h105
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kemailsettings.cpp6
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kemailsettings.h32
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kfiledialog.h21
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kfontdialog.cpp6
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kfontdialog.h14
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kglobal.cpp49
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kglobal.h27
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kglobalsettings.cpp17
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kglobalsettings.h15
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kiconloader.cpp33
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kiconloader.h31
-rw-r--r--noncore/apps/tinykate/libkate/microkde/klineedit.h13
-rw-r--r--noncore/apps/tinykate/libkate/microkde/klineeditdlg.h8
-rw-r--r--noncore/apps/tinykate/libkate/microkde/klistview.h24
-rw-r--r--noncore/apps/tinykate/libkate/microkde/klocale.cpp530
-rw-r--r--noncore/apps/tinykate/libkate/microkde/klocale.h53
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kmessagebox.cpp90
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kmessagebox.h46
-rw-r--r--noncore/apps/tinykate/libkate/microkde/knotifyclient.h14
-rw-r--r--noncore/apps/tinykate/libkate/microkde/knumvalidator.cpp8
-rw-r--r--noncore/apps/tinykate/libkate/microkde/knumvalidator.h14
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kpopupmenu.h8
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kprinter.h8
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kprocess.cpp15
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kprocess.h16
-rw-r--r--noncore/apps/tinykate/libkate/microkde/krestrictedline.h13
-rw-r--r--noncore/apps/tinykate/libkate/microkde/krun.cpp6
-rw-r--r--noncore/apps/tinykate/libkate/microkde/krun.h13
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kseparator.h8
-rw-r--r--noncore/apps/tinykate/libkate/microkde/ksharedptr.h142
-rw-r--r--noncore/apps/tinykate/libkate/microkde/ksimpleconfig.h12
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kstandarddirs.cpp39
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kstandarddirs.h23
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kstaticdeleter.h35
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kstddirs.h23
-rw-r--r--noncore/apps/tinykate/libkate/microkde/ktempfile.cpp25
-rw-r--r--noncore/apps/tinykate/libkate/microkde/ktempfile.h20
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kunload.h6
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kurlrequester.cpp14
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kurlrequester.h17
-rw-r--r--noncore/apps/tinykate/libkate/qt3back/README12
-rw-r--r--noncore/apps/tinykate/libkate/qt3back/qregexp3.cpp3767
-rw-r--r--noncore/apps/tinykate/libkate/qt3back/qregexp3.h111
-rw-r--r--noncore/apps/tinykate/libkate/view/kateundohistory.cpp271
-rw-r--r--noncore/apps/tinykate/libkate/view/kateundohistory.h114
-rw-r--r--noncore/apps/tinykate/libkate/view/kateview.cpp2923
-rw-r--r--noncore/apps/tinykate/libkate/view/kateview.h865
-rw-r--r--noncore/apps/tinykate/libkate/view/kateviewdialog.cpp556
-rw-r--r--noncore/apps/tinykate/libkate/view/kateviewdialog.h194
-rw-r--r--noncore/apps/tinykate/main.cpp29
-rw-r--r--noncore/apps/tinykate/pics/edit-redo.xpm90
-rw-r--r--noncore/apps/tinykate/pics/edit-undo.xpm90
-rw-r--r--noncore/apps/tinykate/pics/file-new.xpm24
-rw-r--r--noncore/apps/tinykate/pics/file-open.xpm25
-rw-r--r--noncore/apps/tinykate/pics/file-save.xpm24
-rw-r--r--noncore/apps/tinykate/tinykate.cpp199
-rw-r--r--noncore/apps/tinykate/tinykate.desktop6
-rw-r--r--noncore/apps/tinykate/tinykate.h62
-rw-r--r--noncore/apps/tinykate/tinykate.pro16
-rw-r--r--noncore/apps/tinykate/tinykate_icon.xpm20
-rw-r--r--pics/tinykate/tinykate.pngbin0 -> 1635 bytes
104 files changed, 22372 insertions, 0 deletions
diff --git a/apps/Applications/tinykate.desktop b/apps/Applications/tinykate.desktop
new file mode 100644
index 0000000..3555ce2
--- a/dev/null
+++ b/apps/Applications/tinykate.desktop
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Categories =
+Comment = A texteditor with syntax highlighting
+Exec = tinykate
+File =
+Icon = tinykate/tinykate
+Name = TinyKATE
+Type = Applications
diff --git a/noncore/apps/tinykate/install b/noncore/apps/tinykate/install
new file mode 100755
index 0000000..912c91b
--- a/dev/null
+++ b/noncore/apps/tinykate/install
@@ -0,0 +1,13 @@
+#!/bin/sh
+if [ a$OPIEDIR = a ]
+then
+echo OPIEDIR must be set
+exit
+fi
+[ -f $OPIEDIR/pics/tinykate_icon.xpm ] || cp tinykate_icon.xpm $OPIEDIR/pics/
+[ -f $OPIEDIR/apps/tinykate.desktop ] || cp tinykate.desktop $OPIEDIR/apps/
+mv $OPIEDIR/Makefile $OPIEDIR/Makefile.orig
+sed "s/APPS=/&tinykate \\\\ \\
+ /" $OPIEDIR/Makefile.orig >> $OPIEDIR/Makefile
+echo You may wish to move the desktop file in to
+echo an appropriate subdirectory of the menus.
diff --git a/noncore/apps/tinykate/libkate/document/katebuffer.cpp b/noncore/apps/tinykate/libkate/document/katebuffer.cpp
new file mode 100644
index 0000000..22a4917
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katebuffer.cpp
@@ -0,0 +1,179 @@
+/*
+ This file is part of KWrite
+ Copyright (c) 2000 Waldo Bastian <bastian@kde.org>
+ Copyright (c) 2002 Joseph Wenninger <jowenn@kde.org>
+
+ $Id$
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+
+#include "katebuffer.h"
+
+// Includes for reading file
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <qfile.h>
+#include <qtextstream.h>
+
+#include <qtimer.h>
+#include <qtextcodec.h>
+
+//
+
+#include <assert.h>
+#include <kdebug.h>
+
+/**
+ * Create an empty buffer.
+ */
+KWBuffer::KWBuffer()
+{
+ clear();
+}
+
+void
+KWBuffer::clear()
+{
+ m_stringListIt=0;
+ m_stringListCurrent=0;
+ m_stringList.clear();
+ m_lineCount=1;
+ m_stringListIt = m_stringList.append(new TextLine());
+}
+
+/**
+ * Insert a file at line @p line in the buffer.
+ */
+void
+KWBuffer::insertFile(int line, const QString &file, QTextCodec *codec)
+{
+ if (line) {
+ qDebug("insert File only supports insertion at line 0 == file opening");
+ return;
+ }
+ clear();
+ QFile iofile(file);
+ iofile.open(IO_ReadOnly);
+ QTextStream stream(&iofile);
+ stream.setCodec(codec);
+ QString qsl;
+ int count=0;
+ for (count=0;((qsl=stream.readLine())!=QString::null); count++)
+ {
+ if (count==0)
+ {
+ (*m_stringListIt)->append(qsl.unicode(),qsl.length());
+ }
+ else
+ {
+ TextLine::Ptr tl=new TextLine();
+ tl ->append(qsl.unicode(),qsl.length());
+ m_stringListIt=m_stringList.append(tl);
+ }
+ }
+ if (count!=0)
+ {
+ m_stringListCurrent=count-1;
+ m_lineCount=count;
+ }
+}
+
+void
+KWBuffer::loadFilePart()
+{
+}
+
+
+void
+KWBuffer::insertData(int line, const QByteArray &data, QTextCodec *codec)
+{
+}
+
+void
+KWBuffer::slotLoadFile()
+{
+ loadFilePart();
+// emit linesChanged(m_totalLines);
+ emit linesChanged(20);
+}
+
+/**
+ * Return the total number of lines in the buffer.
+ */
+int
+KWBuffer::count()
+{
+ qDebug("m_stringList.count %d",m_stringList.count());
+ return m_lineCount;
+// return m_stringList.count();
+// return m_totalLines;
+}
+
+
+void KWBuffer::seek(int i)
+{
+ if (m_stringListCurrent == i)
+ return;
+ while(m_stringListCurrent < i)
+ {
+ ++m_stringListCurrent;
+ ++m_stringListIt;
+ }
+ while(m_stringListCurrent > i)
+ {
+ --m_stringListCurrent;
+ --m_stringListIt;
+ }
+}
+
+
+TextLine::Ptr
+KWBuffer::line(int i)
+{
+ if (i>=m_stringList.count()) return 0;
+ seek(i);
+ return *m_stringListIt;
+}
+
+void
+KWBuffer::insertLine(int i, TextLine::Ptr line)
+{
+ seek(i);
+ m_stringListIt = m_stringList.insert(m_stringListIt, line);
+ m_stringListCurrent = i;
+ m_lineCount++;
+}
+
+
+void
+KWBuffer::removeLine(int i)
+{
+ seek(i);
+ m_stringListIt = m_stringList.remove(m_stringListIt);
+ m_stringListCurrent = i;
+ m_lineCount--;
+}
+
+void
+KWBuffer::changeLine(int i)
+{
+}
+
diff --git a/noncore/apps/tinykate/libkate/document/katebuffer.h b/noncore/apps/tinykate/libkate/document/katebuffer.h
new file mode 100644
index 0000000..9088498
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katebuffer.h
@@ -0,0 +1,143 @@
+/*
+ This file is part of KWrite
+ Copyright (c) 2000 Waldo Bastian <bastian@kde.org>
+ Copyright (c) 2002 Joseph Wenninger <jowenn@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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _KWBUFFER_H_
+#define _KWBUFFER_H_
+
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qlist.h>
+#include <qobject.h>
+#include <qtimer.h>
+
+#include "katetextline.h"
+
+class QTextCodec;
+
+/**
+ * The KWBuffer class maintains a collections of lines.
+ * It allows to maintain state information in a lazy way.
+ * It handles swapping out of data using secondary storage.
+ *
+ * It is designed to handle large amounts of text-data efficiently
+ * with respect to CPU and memory usage.
+ *
+ * @author Waldo Bastian <bastian@kde.org>
+ */
+class KWBuffer : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * Create an empty buffer.
+ */
+ KWBuffer();
+
+ /**
+ * Insert a file at line @p line in the buffer.
+ * Using @p codec to decode the file.
+ */
+ void insertFile(int line, const QString &file, QTextCodec *codec);
+
+ /**
+ * Insert a block of data at line @p line in the buffer.
+ * Using @p codec to decode the file.
+ */
+ void insertData(int line, const QByteArray &data, QTextCodec *codec);
+
+ /**
+ * Return the total number of lines in the buffer.
+ */
+ int count();
+
+ /**
+ * Return line @p i
+ */
+ TextLine::Ptr line(int i);
+
+ /**
+ * Insert @p line in front of line @p i
+ */
+ void insertLine(int i, TextLine::Ptr line);
+
+ /**
+ * Remove line @p i
+ */
+ void removeLine(int i);
+
+ /**
+ * Change line @p i
+ */
+ void changeLine(int i);
+
+ /**
+ * Clear the buffer.
+ */
+ void clear();
+
+signals:
+
+ void textChanged();
+ /**
+ * Emitted during loading.
+ */
+ void linesChanged(int lines);
+ void needHighlight(long,long);
+
+protected:
+ /**
+ * Make sure @p buf gets loaded.
+ */
+ void loadBlock(KWBufBlock *buf);
+
+ /**
+ * Make sure @p buf gets parsed.
+ */
+ void parseBlock(KWBufBlock *buf);
+
+ /**
+ * Mark @p buf dirty.
+ */
+ void dirtyBlock(KWBufBlock *buf);
+
+ /**
+ * Find the block containing line @p i
+ */
+ KWBufBlock *findBlock(int i);
+
+ /**
+ * Load a part of the file that is currently loading.
+ */
+ void loadFilePart();
+
+protected slots:
+ void slotLoadFile();
+
+protected:
+ TextLine::List m_stringList;
+ TextLine::List::Iterator m_stringListIt;
+ int m_stringListCurrent;
+ int m_lineCount;
+ void seek(int i);
+
+
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/document/katecmd.cpp b/noncore/apps/tinykate/libkate/document/katecmd.cpp
new file mode 100644
index 0000000..beebaa2
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katecmd.cpp
@@ -0,0 +1,58 @@
+/***************************************************************************
+ katecmd.cpp - description
+ -------------------
+ begin : Mon Feb 5 2001
+ copyright : (C) 2001 by Christoph Cullmann
+ (C) 2002 by Joseph Wenninger
+ email : crossfire@babylon2k.de
+ jowenn@kde.org
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "katecmd.h"
+#include "katecmds.h"
+
+
+#include "katedocument.h"
+
+KateCmd::KateCmd (KateDocument *doc) : QObject (doc)
+{
+ myDoc = doc;
+
+ myParser.append (new KateCommands::InsertTime (myDoc));
+ myParser.append (new KateCommands::SedReplace (myDoc));
+ myParser.append (new KateCommands::Character (myDoc));
+}
+
+KateCmd::~KateCmd ()
+{
+}
+
+void KateCmd::execCmd (QString cmd, KateView *view)
+{
+ for (uint i=0; i<myParser.count(); i++)
+ {
+ if (myParser.at(i)->execCmd (cmd, view))
+ break;
+ }
+}
+
+KateCmdParser::KateCmdParser (KateDocument *doc)
+{
+ myDoc = doc;
+}
+
+KateCmdParser::~KateCmdParser()
+{
+}
+
+
diff --git a/noncore/apps/tinykate/libkate/document/katecmd.h b/noncore/apps/tinykate/libkate/document/katecmd.h
new file mode 100644
index 0000000..72158cc
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katecmd.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ katecmd.h - description
+ -------------------
+ begin : Mon Feb 5 2001
+ copyright : (C) 2001 by Christoph Cullmann
+ (C) 2002 by Joseph Wenninger
+ email : crossfire@babylon2k.de
+ jowenn@kde.org
+
+***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef _KATE_CMD_H
+#define _KATE_CMD_H
+
+#include <qobject.h>
+#include <qstring.h>
+#include <qlist.h>
+#include <katedocument.h>
+
+class KateCmdParser
+{
+ public:
+ KateCmdParser (KateDocument *doc=0L);
+ virtual ~KateCmdParser ();
+
+ virtual bool execCmd (QString cmd=0L, KateView *view=0L)=0;
+
+ private:
+ KateDocument *myDoc;
+};
+
+class KateCmd : public QObject
+{
+ Q_OBJECT
+
+ public:
+ KateCmd (KateDocument *doc=0L);
+ ~KateCmd ();
+
+ void execCmd (QString cmd=0L, KateView *view=0L);
+
+ private:
+ KateDocument *myDoc;
+ QList<KateCmdParser> myParser;
+};
+
+#endif
+
diff --git a/noncore/apps/tinykate/libkate/document/katecmds.cpp b/noncore/apps/tinykate/libkate/document/katecmds.cpp
new file mode 100644
index 0000000..3647853
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katecmds.cpp
@@ -0,0 +1,278 @@
+/***************************************************************************
+ katecmds.cpp - description
+ -------------------
+ copyright : (C) 2001 by The Kate Team
+ (C) 2002 by Joseph Wenninger
+ email : kwrite-devel@kde.org
+ jowenn@kde.org
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include "katecmds.h"
+#include <qregexp.h>
+#include <qregexp3.h>
+#include <qdatetime.h>
+#include "katedocument.h"
+#include <kdebug.h>
+
+namespace KateCommands
+{
+
+
+bool InsertTime::execCmd(QString cmd, KateView *view)
+{
+ if (cmd.left(5) == "time")
+ {
+ view->insertText(QTime::currentTime().toString());
+ return true;
+ }
+
+ return false;
+}
+
+static void replace(QString &s, const QString &needle, const QString &with)
+{
+ int pos=0;
+ while (1)
+ {
+ pos=s.find(needle, pos);
+ if (pos==-1) break;
+ s.replace(pos, needle.length(), with);
+ pos+=with.length();
+ }
+
+}
+
+// stolen from QString::replace
+static void replace(QString &s, QRegExp3 &rx, const QString &with)
+{
+ if (s.isEmpty()) return;
+ int index = 0;
+ int slen = with.length();
+ int len;
+ while (index < (int)s.length())
+ {
+ index = rx.search(s, index);
+ len = rx.matchedLength();
+ if ( index >= 0 )
+ {
+ s.replace(index, len, with);
+ index += slen;
+ if (!len)
+ break; // Avoid infinite loop on 0-length matches, e.g. [a-z]*
+ }
+ else
+ break;
+ }
+}
+
+
+
+static int backslashString(const QString &haystack, const QString &needle, int index)
+{
+ int len=haystack.length();
+ int searchlen=needle.length();
+ bool evenCount=true;
+ while (index<len)
+ {
+ if (haystack[index]=='\\')
+ {
+ evenCount=!evenCount;
+ }
+ else
+ { // isn't a slash
+ if (!evenCount)
+ {
+ if (haystack.mid(index, searchlen)==needle)
+ return index-1;
+ }
+ evenCount=true;
+ }
+ index++;
+
+ }
+
+ return -1;
+}
+
+
+// exchange "\t" for the actual tab character, for example
+static void exchangeAbbrevs(QString &str)
+{
+ // the format is (findreplace)*[nullzero]
+ char *magic="a\x07t\t";
+
+ while (*magic)
+ {
+ int index=0;
+ char replace=magic[1];
+ while ((index=backslashString(str, QChar(*magic), index))!=-1)
+ {
+ str.replace(index, 2, QChar(replace));
+ index++;
+ }
+ magic++;
+ magic++;
+ }
+}
+
+QString SedReplace::sedMagic(QString textLine, QString find, QString rep, bool noCase, bool repeat)
+{
+ QRegExp3 matcher(find, noCase);
+
+ int start=0;
+ while (start!=-1)
+ {
+ start=matcher.search(textLine, start);
+
+ if (start==-1) break;
+
+ int length=matcher.matchedLength();
+
+
+ // now set the backreferences in the replacement
+ QStringList backrefs=matcher.capturedTexts();
+ int refnum=1;
+
+ QStringList::Iterator i = backrefs.begin();
+ ++i;
+
+ for (; i!=backrefs.end(); ++i)
+ {
+ // I need to match "\\" or "", but not "\"
+ QString number=QString::number(refnum);
+
+ int index=0;
+ while (index!=-1)
+ {
+ index=backslashString(rep, number, index);
+ if (index>=0)
+ {
+ rep.replace(index, 2, *i);
+ index+=(*i).length();
+ }
+ }
+
+ refnum++;
+ }
+
+ textLine.replace(start, length, rep);
+ if (!repeat) break;
+ start+=rep.length();
+ }
+
+ replace(textLine, "\\\\", "\\");
+ replace(textLine, "\\/", "/");
+
+ return textLine;
+}
+
+
+static void setLineText(KateView *view, int line, const QString &text)
+{
+// view->doc()->removeLine(line);
+// view->doc()->insertLine(text, line);
+ view->doc()->replaceLine(text,line);
+}
+
+bool SedReplace::execCmd(QString cmd, KateView *view)
+{
+ kdDebug(13010)<<"SedReplace::execCmd()"<<endl;
+ if (QRegExp("[$%]?s/.+/.*/[ig]*").find(cmd, 0)==-1)
+ return false;
+
+ bool fullFile=cmd[0]=='%';
+ bool noCase=cmd[cmd.length()-1]=='i' || cmd[cmd.length()-2]=='i';
+ bool repeat=cmd[cmd.length()-1]=='g' || cmd[cmd.length()-2]=='g';
+ bool onlySelect=cmd[0]=='$';
+
+ QRegExp3 splitter("^[$%]?s/((?:[^\\\\/]|\\\\[\\\\/\\$0-9tadDsSwW])*)/((?:[^\\\\/]|\\\\[\\\\/\\$0-9tadDsSwW])*)/[ig]*$");
+ if (splitter.search(cmd)<0) return false;
+
+ QString find=splitter.cap(1);
+ kdDebug(13010)<< "SedReplace: find=" << find.latin1() <<endl;
+
+ QString replace=splitter.cap(2);
+ exchangeAbbrevs(replace);
+ kdDebug(13010)<< "SedReplace: replace=" << replace.latin1() <<endl;
+
+
+ if (fullFile)
+ {
+ int numLines=view->doc()->numLines();
+ for (int line=0; line < numLines; line++)
+ {
+ QString text=view->textLine(line);
+ text=sedMagic(text, find, replace, noCase, repeat);
+ setLineText(view, line, text);
+ }
+ }
+ else if (onlySelect)
+ {
+ // Not implemented
+ }
+ else
+ { // just this line
+ QString textLine=view->currentTextLine();
+ int line=view->currentLine();
+ textLine=sedMagic(textLine, find, replace, noCase, repeat);
+ setLineText(view, line, textLine);
+ }
+ return true;
+}
+
+bool Character::execCmd(QString cmd, KateView *view)
+{
+ // hex, octal, base 9+1
+ QRegExp3 num("^char: *(0?x[0-9A-Fa-f]{1,4}|0[0-7]{1,6}|[0-9]{1,3})$");
+ if (num.search(cmd)==-1) return false;
+
+ cmd=num.cap(1);
+
+ // identify the base
+
+ unsigned short int number=0;
+ int base=10;
+ if (cmd[0]=='x' || cmd.left(2)=="0x")
+ {
+ cmd.replace(QRegExp("^0?x"), "");
+ base=16;
+ }
+ else if (cmd[0]=='0')
+ base=8;
+ bool ok;
+ number=cmd.toUShort(&ok, base);
+ if (!ok || number==0) return false;
+ if (number<=255)
+ {
+ char buf[2];
+ buf[0]=(char)number;
+ buf[1]=0;
+ view->insertText(QString(buf));
+ }
+ else
+ { // do the unicode thing
+ QChar c(number);
+ view->insertText(QString(&c, 1));
+ }
+
+ return true;
+}
+
+bool Fifo::execCmd(QString cmd, KateView *view)
+{
+
+}
+
+}
+
+// vim: noet
+
diff --git a/noncore/apps/tinykate/libkate/document/katecmds.h b/noncore/apps/tinykate/libkate/document/katecmds.h
new file mode 100644
index 0000000..bbd5937
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katecmds.h
@@ -0,0 +1,94 @@
+/***************************************************************************
+ katecmds.h - description
+ -------------------
+ copyright : (C) 2001 by The Kate Team
+ (C) 2002 by Joseph Wenninger
+ email : kwrite-devel@kde.org
+ jowenn@kde.org
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef _KATECMDS_H
+#define _KATECMDS_H
+
+#include "katecmd.h"
+
+
+/**
+ * this namespace will be maintained by Charles Samuels <charles@kde.org>
+ * so we're going to be using this indentation style here.
+ *
+ * Respect my style, and I'll respect your's!
+ **/
+namespace KateCommands
+{
+
+/**
+ * This is by Christoph Cullmann
+ **/
+class InsertTime : public KateCmdParser
+{
+public:
+ InsertTime(KateDocument *doc=0) : KateCmdParser(doc) { }
+
+ bool execCmd(QString cmd=0, KateView *view=0);
+};
+
+/**
+ * -- Charles Samuels <charles@kde.org>
+ * Support vim/sed find and replace
+ * s/search/replace/ find search, replace with replace on this line
+ * %s/search/replace/ do the same to the whole file
+ * s/search/replace/i do the S. and R., but case insensitively
+ * $s/search/replace/ do the search are replacement to the selection only
+ *
+ * $s/// is currently unsupported
+ **/
+class SedReplace : public KateCmdParser
+{
+public:
+ SedReplace(KateDocument *doc=0) : KateCmdParser(doc) { }
+
+ bool execCmd(QString cmd=0, KateView *view=0);
+private:
+ static QString sedMagic(QString textLine, QString find, QString replace, bool noCase, bool repeat);
+};
+
+/**
+ * insert a unicode or ascii character
+ * base 9+1: 1234
+ * hex: 0x1234 or x1234
+ * octal: 01231
+ *
+ * prefixed with "char:"
+ **/
+class Character : public KateCmdParser
+{
+public:
+ Character(KateDocument *doc=0) : KateCmdParser(doc) { }
+
+ bool execCmd(QString cmd=0, KateView *view=0);
+};
+
+class Fifo : public KateCmdParser
+{
+public:
+ Fifo(KateDocument *doc=0) : KateCmdParser(doc) { }
+
+ bool execCmd(QString cmd=0, KateView *view=0);
+};
+
+}
+
+// vim: noet
+
+#endif
+
diff --git a/noncore/apps/tinykate/libkate/document/katedialogs.cpp b/noncore/apps/tinykate/libkate/document/katedialogs.cpp
new file mode 100644
index 0000000..2f0ed7b
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katedialogs.cpp
@@ -0,0 +1,588 @@
+/***************************************************************************
+ katedialogs.cpp - description
+ -------------------
+ copyright : (C) 2001 by The Kate Team
+ (C) 2002 by Joseph Wenninger
+ email : kwrite-devel@kde.org
+ jowenn@kde.org
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include "katedialogs.h"
+#include <klocale.h>
+#include <kdebug.h>
+#include <qgroupbox.h>
+#include <qvgroupbox.h>
+#include <qhgroupbox.h>
+#include <qhbox.h>
+#include <qvbox.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qwidgetstack.h>
+#include <qlabel.h>
+#include <qlistview.h>
+#include <qlineedit.h>
+#include <qcombobox.h>
+#include <qcheckbox.h>
+//FIXME #include <kcharsets.h>
+#include <kglobal.h>
+#include <qmap.h>
+#include <kmessagebox.h>
+#include <kstddirs.h>
+
+
+/*******************************************************************************************************************
+* Context Editor *
+*******************************************************************************************************************/
+
+StyleChanger::StyleChanger( QWidget *parent )
+ : QWidget(parent)
+{
+ QLabel *label;
+
+ QGridLayout *glay = new QGridLayout( this, 4, 3, 0, KDialog::spacingHint() );
+ CHECK_PTR(glay);
+ glay->addColSpacing( 1, KDialog::spacingHint() ); // Looks better
+ glay->setColStretch( 2, 10 );
+
+ col = new KColorButton(this);
+ CHECK_PTR(col);
+ connect(col,SIGNAL(changed(const QColor &)),this,SLOT(changed()));
+ label = new QLabel(col,i18n("Normal:"),this);
+ CHECK_PTR(label);
+ glay->addWidget(label,0,0);
+ glay->addWidget(col,1,0);
+
+ selCol = new KColorButton(this);
+ CHECK_PTR(selCol);
+ connect(selCol,SIGNAL(changed(const QColor &)),this,SLOT(changed()));
+ label = new QLabel(selCol,i18n("Selected:"),this);
+ CHECK_PTR(label);
+ glay->addWidget(label,2,0);
+ glay->addWidget(selCol,3,0);
+
+ bold = new QCheckBox(i18n("Bold"),this);
+ CHECK_PTR(bold);
+ connect(bold,SIGNAL(clicked()),SLOT(changed()));
+ glay->addWidget(bold,1,2);
+
+ italic = new QCheckBox(i18n("Italic"),this);
+ CHECK_PTR(italic);
+ connect(italic,SIGNAL(clicked()),SLOT(changed()));
+ glay->addWidget(italic,2,2);
+}
+
+void StyleChanger::setRef(ItemStyle *s) {
+
+ style = s;
+ col->setColor(style->col);
+ selCol->setColor(style->selCol);
+ bold->setChecked(style->bold);
+ italic->setChecked(style->italic);
+
+}
+
+void StyleChanger::setEnabled(bool enable) {
+
+ col->setEnabled(enable);
+ selCol->setEnabled(enable);
+ bold->setEnabled(enable);
+ italic->setEnabled(enable);
+}
+
+void StyleChanger::changed() {
+
+ if (style) {
+ style->col = col->color();
+ style->selCol = selCol->color();
+ style->bold = bold->isChecked();
+ style->italic = italic->isChecked();
+ }
+}
+
+HighlightDialog::HighlightDialog( HlManager *hlManager, ItemStyleList *styleList,
+ HlDataList *highlightDataList,
+ int hlNumber, QWidget *parent,
+ const char *name, bool modal )
+ :KDialogBase(parent,name,modal,i18n("Highlight Settings"), Ok|Cancel, Ok)
+{
+// QVBox *page = makeVBoxMainWidget();
+ QFrame *page=addPage("FIXME");
+ (new QVBoxLayout(page))->setAutoAdd(true);
+ content=new HighlightDialogPage(hlManager,styleList,highlightDataList,hlNumber,page);
+}
+
+void HighlightDialog::done(int r)
+{
+ kdDebug(13010)<<"HighlightDialod done"<<endl;
+ content->saveData();
+ KDialogBase::done(r);
+}
+
+HighlightDialogPage::HighlightDialogPage(HlManager *hlManager, ItemStyleList *styleList,
+ HlDataList* highlightDataList,
+ int hlNumber,QWidget *parent, const char *name)
+ :QTabWidget(parent,name),defaultItemStyleList(styleList),hlData(0L)
+
+{
+
+ // defaults =========================================================
+
+ QFrame *page1 = new QFrame(this);
+ addTab(page1,i18n("&Defaults"));
+ QGridLayout *grid = new QGridLayout(page1, 1, 1);
+
+ QVGroupBox *dvbox1 = new QVGroupBox( i18n("Default Item Styles"), page1 );
+ /*QLabel *label = */new QLabel( i18n("Item:"), dvbox1 );
+ QComboBox *styleCombo = new QComboBox( false, dvbox1 );
+ defaultStyleChanger = new StyleChanger( dvbox1 );
+ for( int i = 0; i < hlManager->defaultStyles(); i++ ) {
+ styleCombo->insertItem(hlManager->defaultStyleName(i));
+ }
+ connect(styleCombo, SIGNAL(activated(int)), this, SLOT(defaultChanged(int)));
+ grid->addWidget(dvbox1, 0,0);
+
+ defaultChanged(0);
+
+ // highlight modes =====================================================
+
+ QFrame *page2 = new QFrame(this);
+ addTab(page2,i18n("&Highlight Modes"));
+ //grid = new QGridLayout(page2,2,2);
+ QVBoxLayout *bl=new QVBoxLayout(page2);
+ bl->setAutoAdd(true);
+ QHGroupBox *hbox1 = new QHGroupBox( i18n("Config Select"), page2 );
+ hbox1->layout()->setMargin(5);
+ QVBox *vbox1=new QVBox(hbox1);
+// grid->addMultiCellWidget(vbox1,0,0,0,1);
+ QVGroupBox *vbox2 = new QVGroupBox( i18n("Item Style"), page2 );
+// grid->addWidget(vbox2,1,0);
+ QVGroupBox *vbox3 = new QVGroupBox( i18n("Highlight Auto Select"), hbox1 );
+ //grid->addWidget(vbox3,1,1);
+
+ QLabel *label = new QLabel( i18n("Highlight:"), vbox1 );
+ hlCombo = new QComboBox( false, vbox1 );
+ QHBox *modHl = new QHBox(vbox1);
+// connect(new QPushButton(i18n("New"),modHl),SIGNAL(clicked()),this,SLOT(hlNew()));
+// connect(new QPushButton(i18n("Edit"),modHl),SIGNAL(clicked()),this,SLOT(hlEdit()));
+ connect( hlCombo, SIGNAL(activated(int)),
+ this, SLOT(hlChanged(int)) );
+ for( int i = 0; i < hlManager->highlights(); i++) {
+ hlCombo->insertItem(hlManager->hlName(i));
+ }
+ hlCombo->setCurrentItem(hlNumber);
+
+
+ label = new QLabel( i18n("Item:"), vbox2 );
+ itemCombo = new QComboBox( false, vbox2 );
+ connect( itemCombo, SIGNAL(activated(int)), this, SLOT(itemChanged(int)) );
+
+ label = new QLabel( i18n("File Extensions:"), vbox3 );
+ wildcards = new QLineEdit( vbox3 );
+ label = new QLabel( i18n("Mime Types:"), vbox3 );
+ mimetypes = new QLineEdit( vbox3 );
+
+
+ styleDefault = new QCheckBox(i18n("Default"), vbox2 );
+ connect(styleDefault,SIGNAL(clicked()),SLOT(changed()));
+ styleChanger = new StyleChanger( vbox2 );
+
+ hlDataList = highlightDataList;
+ hlChanged(hlNumber);
+}
+
+
+void HighlightDialogPage::defaultChanged(int z)
+{
+ defaultStyleChanger->setRef(defaultItemStyleList->at(z));
+}
+
+
+void HighlightDialogPage::hlChanged(int z)
+{
+ writeback();
+
+ hlData = hlDataList->at(z);
+
+ wildcards->setText(hlData->wildcards);
+ mimetypes->setText(hlData->mimetypes);
+
+ itemCombo->clear();
+ for (ItemData *itemData = hlData->itemDataList.first(); itemData != 0L;
+ itemData = hlData->itemDataList.next()) {
+ kdDebug(13010) << itemData->name << endl;
+ itemCombo->insertItem(i18n(itemData->name.latin1()));
+ }
+
+ itemChanged(0);
+}
+
+void HighlightDialogPage::itemChanged(int z)
+{
+ itemData = hlData->itemDataList.at(z);
+
+ styleDefault->setChecked(itemData->defStyle);
+ styleChanger->setRef(itemData);
+}
+
+void HighlightDialogPage::changed()
+{
+ itemData->defStyle = styleDefault->isChecked();
+}
+
+void HighlightDialogPage::writeback() {
+ if (hlData) {
+ hlData->wildcards = wildcards->text();
+ hlData->mimetypes = mimetypes->text();
+ }
+}
+
+void HighlightDialogPage::saveData() {
+ kdDebug(13010)<<"HighlightDialogPage::saveData()"<<endl;
+ writeback();
+}
+
+
+void HighlightDialogPage::hlEdit() {
+ HlEditDialog diag(0,0,"hlEdit", true,hlData);
+ diag.show();
+}
+
+void HighlightDialogPage::hlNew() {
+ HlEditDialog diag(0,0,"hlEdit",true,0);
+ diag.show();
+}
+
+
+HlEditDialog::HlEditDialog(HlManager *,QWidget *parent, const char *name, bool modal,HlData *data)
+ :KDialogBase(KDialogBase::Swallow, i18n("Highlight Conditions"), Ok|Cancel, Ok, parent, name, modal)
+{
+ currentItem=0;
+ transTableCnt=0;
+ QHBox *wid=new QHBox(this);
+ QVBox *lbox=new QVBox(wid);
+ contextList=new KListView(lbox);
+ contextList->setRootIsDecorated(true);
+ contextList->addColumn(i18n("Syntax structure"));
+ contextList->setSorting(-1);
+ QHBox *bbox=new QHBox(lbox);
+ QPushButton *addContext=new QPushButton(i18n("New Context"),bbox);
+ QPushButton *addItem=new QPushButton(i18n("New Item"),bbox);
+ QVGroupBox *opt = new QVGroupBox( i18n("Options"), wid);
+ stack=new QWidgetStack(opt);
+ initContextOptions(contextOptions=new QVBox(stack));
+ stack->addWidget(contextOptions,HlEContext);
+ initItemOptions(itemOptions=new QVBox(stack));
+ stack->addWidget(itemOptions,HlEItem);
+ stack->raiseWidget(HlEContext);
+ setMainWidget(wid);
+ if (data!=0) loadFromDocument(data);
+ else newDocument();
+ connect(contextList,SIGNAL(currentChanged( QListViewItem*)),this,SLOT(currentSelectionChanged ( QListViewItem * )));
+ connect(addContext,SIGNAL(clicked()),this,SLOT(contextAddNew()));
+ connect(addItem,SIGNAL(clicked()),this,SLOT(ItemAddNew()));
+ }
+
+void HlEditDialog::newDocument()
+{
+ KStandardDirs *dirs = KGlobal::dirs();
+ QStringList list=dirs->findAllResources("data","kate/syntax/syntax.template",false,true);
+ for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ HlData data("","",*it);
+ loadFromDocument(&data);
+ return;
+ }
+ KMessageBox::error(this,i18n("Can't find template file"));
+}
+
+
+void HlEditDialog::initContextOptions(QVBox *co)
+{
+ if( co!=0)
+ {
+ QHBox *tmp = new QHBox(co);
+ (void) new QLabel(i18n("Description:"),tmp);
+ ContextDescr=new QLineEdit(tmp);
+ tmp= new QHBox(co);
+ (void) new QLabel(i18n("Attribute:"),tmp);
+ ContextAttribute=new QComboBox(tmp);
+ tmp= new QHBox(co);
+ (void) new QLabel(i18n("LineEnd:"),tmp);
+ ContextLineEnd = new QComboBox(tmp);
+ connect(ContextDescr,SIGNAL(textChanged(const QString&)),this,SLOT(contextDescrChanged(const QString&)));
+ connect(ContextLineEnd,SIGNAL(activated(int)),this,SLOT(contextLineEndChanged(int)));
+ connect(ContextAttribute,SIGNAL(activated(int)),this,SLOT(contextAttributeChanged(int)));
+ }
+ else
+ kdDebug(13010)<<"initContextOptions: Widget is 0"<<endl;
+}
+
+
+void HlEditDialog::insertTranslationList(QString tag, QString trans,int length)
+ {
+ ItemInfo data(trans,length);
+ id2tag.insert(transTableCnt,tag);
+ id2info.insert(transTableCnt,data);
+ tag2id.insert(tag,transTableCnt);
+ transTableCnt++;
+ }
+
+
+void HlEditDialog::initItemOptions(QVBox *co)
+{
+ if (co!=0)
+ {
+ QHBox *tmp = new QHBox(co);
+ (void) new QLabel(i18n("Type:"),tmp);
+ ItemType = new QComboBox(tmp);
+ tmp= new QHBox(co);
+ (void) new QLabel(i18n("Parameter:"),tmp);
+ ItemParameter= new QLineEdit(tmp);
+ tmp= new QHBox(co);
+ (void) new QLabel(i18n("Attribute:"),tmp);
+ ItemAttribute= new QComboBox(tmp);
+ (void) new QLabel(i18n("Context switch:"),tmp);
+ ItemContext = new QComboBox(tmp);
+ co->setSpacing(15);
+ QPushButton *delItem=new QPushButton(i18n("Delete this item"),co);
+
+ /* init translation lists */
+ insertTranslationList("CharDetect","CharDetect",1);
+ insertTranslationList("2CharDetect","2CharDetect",2);
+ insertTranslationList("RangeDetect","RangeDetect",2);
+ insertTranslationList("StringDetect","StringDetect",-1);
+ insertTranslationList("AnyChar","AnyChar",-1);
+ insertTranslationList("RegExpr","RegExpr",-1);
+ insertTranslationList("Int","Int",0);
+ insertTranslationList("Float","Float",0);
+ insertTranslationList("keyword","keyword",0);
+ insertTranslationList("dataType","dataType",0);
+ ItemType->clear();
+ for (int i=0; i<transTableCnt; i++) ItemType->insertItem(id2info[i].trans_i18n);
+ connect(ItemType,SIGNAL(activated(int)),this,SLOT(ItemTypeChanged(int)));
+ connect(ItemParameter,SIGNAL(textChanged(const QString&)),this,SLOT(ItemParameterChanged(const QString&)));
+ connect(ItemAttribute,SIGNAL(activated(int)),this,SLOT(ItemAttributeChanged(int)));
+ connect(ItemContext,SIGNAL(activated(int)),this,SLOT(ItemContextChanged(int)));
+ }
+ else
+ kdDebug(13010)<<"initItemOptions: Widget is 0"<<endl;
+}
+
+void HlEditDialog::loadFromDocument(HlData *hl)
+{
+ struct syntaxContextData *data;
+ QListViewItem *last=0,*lastsub=0;
+
+ HlManager::self()->syntax->setIdentifier(hl->identifier);
+ data=HlManager::self()->syntax->getGroupInfo("highlighting","context");
+ int i=0;
+ if (data)
+ {
+ while (HlManager::self()->syntax->nextGroup(data)) //<context tags>
+ {
+ kdDebug(13010)<< "Adding context to list"<<endl;
+ last= new QListViewItem(contextList,last,
+ HlManager::self()->syntax->groupData(data,QString("name")),
+ QString("%1").arg(i),
+ HlManager::self()->syntax->groupData(data,QString("attribute")),
+ HlManager::self()->syntax->groupData(data,QString("lineEndContext")));
+ i++;
+ lastsub=0;
+ while (HlManager::self()->syntax->nextItem(data))
+ {
+ kdDebug(13010)<< "Adding item to list"<<endl;
+ lastsub=addContextItem(last,lastsub,data);
+ }
+
+
+ }
+ if (data) HlManager::self()->syntax->freeGroupInfo(data);
+ }
+ ContextAttribute->clear();
+ ItemAttribute->clear();
+ data=HlManager::self()->syntax->getGroupInfo("highlighting","itemData");
+ while (HlManager::self()->syntax->nextGroup(data))
+ {
+ ContextAttribute->insertItem(HlManager::self()->syntax->groupData(data,QString("name")));
+ ItemAttribute->insertItem(HlManager::self()->syntax->groupData(data,QString("name")));
+ }
+ if (data) HlManager::self()->syntax->freeGroupInfo(data);
+}
+
+QListViewItem *HlEditDialog::addContextItem(QListViewItem *_parent,QListViewItem *prev,struct syntaxContextData *data)
+ {
+
+ kdDebug(13010)<<HlManager::self()->syntax->groupItemData(data,QString("name")) << endl;
+
+ QString dataname=HlManager::self()->syntax->groupItemData(data,QString(""));
+ QString attr=(HlManager::self()->syntax->groupItemData(data,QString("attribute")));
+ QString context=(HlManager::self()->syntax->groupItemData(data,QString("context")));
+ char chr;
+ if (! HlManager::self()->syntax->groupItemData(data,QString("char")).isEmpty())
+ chr= (HlManager::self()->syntax->groupItemData(data,QString("char")).latin1())[0];
+ else
+ chr=0;
+ QString stringdata=HlManager::self()->syntax->groupItemData(data,QString("String"));
+ char chr1;
+ if (! HlManager::self()->syntax->groupItemData(data,QString("char1")).isEmpty())
+ chr1= (HlManager::self()->syntax->groupItemData(data,QString("char1")).latin1())[0];
+ else
+ chr1=0;
+ bool insensitive=(HlManager::self()->syntax->groupItemData(data,QString("insensitive"))==QString("TRUE"));
+ QString param("");
+ if ((dataname=="keyword") || (dataname=="dataType")) param=dataname;
+ else if (dataname=="CharDetect") param=chr;
+ else if ((dataname=="2CharDetect") || (dataname=="RangeDetect")) param=QString("%1%2").arg(chr).arg(chr1);
+ else if ((dataname=="StringDetect") || (dataname=="AnyChar") || (dataname=="RegExpr")) param=stringdata;
+ else kdDebug(13010)<<"***********************************"<<endl<<"Unknown entry for Context:"<<dataname<<endl;
+ kdDebug(13010)<<dataname << endl;
+ return new QListViewItem(_parent,prev,i18n(dataname.latin1())+" "+param,dataname,param,attr,context);
+ }
+
+
+void HlEditDialog::currentSelectionChanged ( QListViewItem *it)
+ {
+ kdDebug(13010)<<"Update data view"<<endl<<"Depth:"<<it->depth()<<endl;
+ currentItem=it;
+ if (it->depth()==0) showContext();
+ else showItem();
+ }
+
+
+/****************************************************************************/
+/* CONTEXTS */
+/****************************************************************************/
+
+
+void HlEditDialog::showContext()
+ {
+ stack->raiseWidget(HlEContext);
+ ContextDescr->setText(currentItem->text(0));
+ ContextAttribute->setCurrentItem(currentItem->text(2).toInt());
+ ContextLineEnd->clear();
+ for (QListViewItem *it=contextList->firstChild();it;it=it->nextSibling())
+ ContextLineEnd->insertItem(it->text(0));
+ ContextLineEnd->setCurrentItem(currentItem->text(3).toInt());
+// ContextAttribute->setText(currentItem->text(1));
+// ContextLineEnd->setText(currentItem->text(2));
+ }
+
+void HlEditDialog::contextDescrChanged(const QString& name)
+ {
+ if (currentItem)
+ {
+ currentItem->setText(0,name);
+ ContextLineEnd->changeItem(name,currentItem->text(3).toInt());
+ }
+ }
+
+void HlEditDialog::contextAttributeChanged(int id)
+{
+ if (currentItem)
+ {
+ currentItem->setText(2,QString("%1").arg(id));
+ }
+}
+
+void HlEditDialog::contextLineEndChanged(int id)
+{
+ kdDebug(13010)<<"contextLineEndChanged"<<endl;
+ if (currentItem)
+ {
+ currentItem->setText(3,QString("%1").arg(id));
+ }
+}
+
+void HlEditDialog::contextAddNew()
+{
+ QListViewItem *it=contextList->firstChild();
+ for (;it->nextSibling()!=0;it=it->nextSibling());
+ it=new QListViewItem(contextList,it,i18n("New Context"),QString("%1").arg(it->text(1).toInt()),"0","0");
+ contextList->setSelected(it,true);
+}
+
+/****************************************************************************/
+/* ITEMS */
+/****************************************************************************/
+
+void HlEditDialog::showItem()
+ {
+ stack->raiseWidget(HlEItem);
+ ItemContext->clear();
+ for (QListViewItem *it=contextList->firstChild();it;it=it->nextSibling())
+ ItemContext->insertItem(it->text(0));
+ ItemContext->setCurrentItem(currentItem->text(4).toInt());
+ ItemAttribute->setCurrentItem(currentItem->text(3).toInt());
+ QMap<QString,int>::Iterator iter=tag2id.find(currentItem->text(1));
+ if (iter==tag2id.end())
+ kdDebug(13010)<<"Oops, unknown itemtype in showItem: "<<currentItem->text(1)<<endl;
+ else
+ {
+ ItemType->setCurrentItem(*iter);
+ if (id2info[*iter].length==0) ItemParameter->hide();
+ else
+ {
+ ItemParameter->setMaxLength(id2info[*iter].length);
+ ItemParameter->show();
+ ItemParameter->setText(currentItem->text(2));
+ }
+ }
+
+ }
+
+void HlEditDialog::ItemTypeChanged(int id)
+{
+ if (currentItem)
+ {
+ currentItem->setText(1,id2tag[id]);
+ ItemParameter->setMaxLength(id2info[id].length);
+ ItemParameterChanged(ItemParameter->text());
+ }
+}
+
+void HlEditDialog::ItemParameterChanged(const QString& name)
+{
+ if (currentItem)
+ {
+ currentItem->setText(2,name);
+ currentItem->setText(0,id2info[ItemType->currentItem()].trans_i18n+" "+currentItem->text(2));
+ }
+}
+
+void HlEditDialog::ItemAttributeChanged(int attr)
+{
+ if (currentItem)
+ {
+ currentItem->setText(3,QString("%1").arg(attr));
+ }
+}
+
+void HlEditDialog::ItemContextChanged(int cont)
+{
+ if (currentItem)
+ {
+ currentItem->setText(4,QString("%1").arg(cont));
+ }
+}
+
+void HlEditDialog::ItemAddNew()
+{
+ QListViewItem *it;
+ if (currentItem)
+ {
+ if (currentItem->depth()==0) it=currentItem->firstChild();
+ else
+ it=currentItem;
+ if (it) for (;it->nextSibling();it=it->nextSibling());
+ (void) new QListViewItem(it ? it->parent() : currentItem,it,"StringDetect "+i18n("New Item"),"StringDetect",i18n("New Item"),0,it ? it->parent()->text(1) : currentItem->text(1));
+ }
+}
diff --git a/noncore/apps/tinykate/libkate/document/katedialogs.h b/noncore/apps/tinykate/libkate/document/katedialogs.h
new file mode 100644
index 0000000..f37f45a
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katedialogs.h
@@ -0,0 +1,160 @@
+/***************************************************************************
+ katedialogs.h - description
+ -------------------
+ copyright : (C) 2001 by The Kate Team
+ (C) 2002 by Joseph Wenninger
+ email : kwrite-devel@kde.org
+ jowenn@kde.org
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef KATEDIALOGS_H
+#define KATEDIALOGS_H
+#include <kdialog.h>
+#include <kdialogbase.h>
+#include "katesyntaxdocument.h"
+#include "katehighlight.h"
+#include <klistview.h>
+#include <qtabwidget.h>
+#include <kcolorbutton.h>
+
+class QWidgetStack;
+class QVBox;
+class KListView;
+class QListViewItem;
+struct syntaxContextData;
+class QCheckBox;
+//class ItemFont;
+#define HlEUnknown 0
+#define HlEContext 1
+#define HlEItem 2
+ //--------
+
+
+class StyleChanger : public QWidget {
+ Q_OBJECT
+ public:
+ StyleChanger(QWidget *parent );
+ void setRef(ItemStyle *);
+ void setEnabled(bool);
+ protected slots:
+ void changed();
+ protected:
+ ItemStyle *style;
+ KColorButton *col;
+ KColorButton *selCol;
+ QCheckBox *bold;
+ QCheckBox *italic;
+};
+
+class HighlightDialogPage : public QTabWidget
+{
+ Q_OBJECT
+ public:
+ HighlightDialogPage(HlManager *, ItemStyleList *, HlDataList *, int hlNumber,
+ QWidget *parent=0, const char *name=0);
+ void saveData();
+
+ protected slots:
+ void defaultChanged(int);
+
+ void hlChanged(int);
+ void itemChanged(int);
+ void changed();
+ void hlEdit();
+ void hlNew();
+ protected:
+ StyleChanger *defaultStyleChanger;
+ ItemStyleList *defaultItemStyleList;
+
+ void writeback();
+ QComboBox *itemCombo, *hlCombo;
+ QLineEdit *wildcards;
+ QLineEdit *mimetypes;
+ QCheckBox *styleDefault;
+ StyleChanger *styleChanger;
+
+ HlDataList *hlDataList;
+ HlData *hlData;
+ ItemData *itemData;
+};
+
+class ItemInfo
+{
+ public:
+ ItemInfo():trans_i18n(),length(0){};
+ ItemInfo(QString _trans,int _length):trans_i18n(_trans),length(_length){};
+ QString trans_i18n;
+ int length;
+};
+
+class HighlightDialog : public KDialogBase
+{
+ Q_OBJECT
+ public:
+ HighlightDialog( HlManager *hlManager, ItemStyleList *styleList,
+ HlDataList *highlightDataList,
+ int hlNumber, QWidget *parent,
+ const char *name=0, bool modal=true );
+ private:
+ HighlightDialogPage *content;
+ protected:
+ virtual void done(int r);
+};
+
+class HlEditDialog : public KDialogBase
+{
+ Q_OBJECT
+ public:
+ HlEditDialog(HlManager *,QWidget *parent=0, const char *name=0, bool modal=true, HlData *data=0);
+ private:
+ class QWidgetStack *stack;
+ class QVBox *contextOptions, *itemOptions;
+ class KListView *contextList;
+ class QListViewItem *currentItem;
+ void initContextOptions(class QVBox *co);
+ void initItemOptions(class QVBox *co);
+ void loadFromDocument(HlData *hl);
+ void showContext();
+ void showItem();
+
+ QListViewItem *addContextItem(QListViewItem *_parent,QListViewItem *prev,struct syntaxContextData *data);
+ void insertTranslationList(QString tag, QString trans,int length);
+ void newDocument();
+
+ class QLineEdit *ContextDescr;
+ class QComboBox *ContextAttribute;
+ class QComboBox *ContextLineEnd;
+
+ class QComboBox *ItemType;
+ class QComboBox *ItemContext;
+ class QLineEdit *ItemParameter;
+ class QComboBox *ItemAttribute;
+
+ class QMap<int,QString> id2tag;
+ class QMap<int,ItemInfo> id2info;
+ class QMap<QString,int> tag2id;
+ int transTableCnt;
+ protected slots:
+ void currentSelectionChanged ( QListViewItem * );
+ void contextDescrChanged(const QString&);
+ void contextLineEndChanged(int);
+ void contextAttributeChanged(int);
+ void contextAddNew();
+
+ void ItemTypeChanged(int id);
+ void ItemParameterChanged(const QString& name);
+ void ItemAttributeChanged(int attr);
+ void ItemContextChanged(int cont);
+ void ItemAddNew();
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/document/katedocument.cpp b/noncore/apps/tinykate/libkate/document/katedocument.cpp
new file mode 100644
index 0000000..0d84bcf
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katedocument.cpp
@@ -0,0 +1,3169 @@
+/***************************************************************************
+ katedocument.cpp - description
+ -------------------
+ begin : Mon Jan 15 2001
+ copyright : (C) 2001 by Christoph "Crossfire" Cullmann
+ (C) 2002 by Joseph Wenninger
+ email : crossfire@babylon2k.de
+ jowenn@kde.org
+
+***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+/*
+ Copyright (C) 1998, 1999 Jochen Wilhelmy
+ digisnap@cs.tu-berlin.de
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "katedocument.h"
+
+
+#include <qfileinfo.h>
+#include <qdatetime.h>
+
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <qpe/config.h>
+#include <qstring.h>
+
+#include <sys/time.h>
+#include <unistd.h>
+
+#include <stdio.h>
+
+#include <qtimer.h>
+#include <qobject.h>
+#include <qapplication.h>
+#include <qclipboard.h>
+#include <qfont.h>
+#include <qpainter.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qtextcodec.h>
+#include <kglobal.h>
+
+#include <klocale.h>
+//#include <kcharsets.h>
+#include <kdebug.h>
+//#include <kinstance.h>
+
+#include <kglobalsettings.h>
+//#include <kaction.h>
+//#include <kstdaction.h>
+
+#include "../view/kateview.h"
+#include "katebuffer.h"
+#include "katetextline.h"
+
+#include "katecmd.h"
+
+KateAction::KateAction(Action a, PointStruc &cursor, int len, const QString &text)
+ : action(a), cursor(cursor), len(len), text(text) {
+}
+
+KateActionGroup::KateActionGroup(PointStruc &aStart, int type)
+ : start(aStart), action(0L), undoType(type) {
+}
+
+KateActionGroup::~KateActionGroup() {
+ KateAction *current, *next;
+
+ current = action;
+ while (current) {
+ next = current->next;
+ delete current;
+ current = next;
+ }
+}
+
+void KateActionGroup::insertAction(KateAction *a) {
+ a->next = action;
+ action = a;
+}
+
+const char * KateActionGroup::typeName(int type)
+{
+ // return a short text description of the given undo group type suitable for a menu
+ // not the lack of i18n's, the caller is expected to handle translation
+ switch (type) {
+ case ugPaste : return "Paste Text";
+ case ugDelBlock : return "Selection Overwrite";
+ case ugIndent : return "Indent";
+ case ugUnindent : return "Unindent";
+ case ugComment : return "Comment";
+ case ugUncomment : return "Uncomment";
+ case ugReplace : return "Text Replace";
+ case ugSpell : return "Spell Check";
+ case ugInsChar : return "Typing";
+ case ugDelChar : return "Delete Text";
+ case ugInsLine : return "New Line";
+ case ugDelLine : return "Delete Line";
+ }
+ return "";
+}
+
+const int KateDocument::maxAttribs = 32;
+
+QStringList KateDocument::searchForList = QStringList();
+QStringList KateDocument::replaceWithList = QStringList();
+
+uint KateDocument::uniqueID = 0;
+
+QPtrDict<KateDocument::KateDocPrivate>* KateDocument::d_ptr = 0;
+
+
+KateDocument::KateDocument(bool bSingleViewMode, bool bBrowserView,
+ QWidget *parentWidget, const char *widgetName,
+ QObject *, const char *)
+ : Kate::Document (),
+ myFont(KGlobalSettings::generalFont()), myFontBold(KGlobalSettings::generalFont()), myFontItalic(KGlobalSettings::generalFont()), myFontBI(KGlobalSettings::generalFont()),
+ myFontMetrics (myFont), myFontMetricsBold (myFontBold), myFontMetricsItalic (myFontItalic), myFontMetricsBI (myFontBI),
+ hlManager(HlManager::self ())
+{
+
+ d(this)->hlSetByUser = false;
+ PreHighlightedTill=0;
+ RequestPreHighlightTill=0;
+
+ m_bSingleViewMode=bSingleViewMode;
+ m_bBrowserView = bBrowserView;
+
+ m_url = QString::null;
+
+ // NOTE: QFont::CharSet doesn't provide all the charsets KDE supports
+ // (esp. it doesn't distinguish between UTF-8 and iso10646-1)
+
+ myEncoding = QString::fromLatin1(QTextCodec::codecForLocale()->name());
+
+ maxLength = -1;
+
+ setFont (KGlobalSettings::generalFont());
+
+ myDocID = uniqueID;
+ uniqueID++;
+
+ myDocName = QString ("");
+ fileInfo = new QFileInfo ();
+
+ myCmd = new KateCmd (this);
+
+ connect(this,SIGNAL(modifiedChanged ()),this,SLOT(slotModChanged ()));
+
+ buffer = new KWBuffer;
+ connect(buffer, SIGNAL(linesChanged(int)), this, SLOT(slotBufferChanged()));
+// connect(buffer, SIGNAL(textChanged()), this, SIGNAL(textChanged()));
+ connect(buffer, SIGNAL(needHighlight(long,long)),this,SLOT(slotBufferHighlight(long,long)));
+
+ colors[0] = KGlobalSettings::baseColor();
+ colors[1] = KGlobalSettings::highlightColor();
+
+ m_attribs = new Attribute[maxAttribs];
+
+ m_highlight = 0L;
+ tabChars = 8;
+
+ m_singleSelection = false;
+
+ newDocGeometry = false;
+ readOnly = false;
+ newDoc = false;
+
+ modified = false;
+
+ undoList.setAutoDelete(true);
+ undoState = 0;
+ undoSteps = 50;
+
+ pseudoModal = 0L;
+ clear();
+
+ setHighlight(0); //calls updateFontData()
+ // if the user changes the highlight with the dialog, notify the doc
+ connect(hlManager,SIGNAL(changed()),SLOT(hlChanged()));
+
+ newDocGeometry = false;
+
+ readConfig();
+
+ setReadOnly(false);
+}
+
+void KateDocument::setDontChangeHlOnSave()
+{
+ d(this)->hlSetByUser = true;
+}
+
+void KateDocument::setFont (QFont font)
+{
+ kdDebug()<<"Kate:: setFont"<<endl;
+ int oldwidth=myFontMetrics.width('W'); //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0
+ myFont = font;
+ myFontBold = QFont (font);
+ myFontBold.setBold (true);
+
+ myFontItalic = QFont (font);
+ myFontItalic.setItalic (true);
+
+ myFontBI = QFont (font);
+ myFontBI.setBold (true);
+ myFontBI.setItalic (true);
+
+ myFontMetrics = CachedFontMetrics (myFont);
+ myFontMetricsBold = CachedFontMetrics (myFontBold);
+ myFontMetricsItalic = CachedFontMetrics (myFontItalic);
+ myFontMetricsBI = CachedFontMetrics (myFontBI);
+ int newwidth=myFontMetrics.width('W'); //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0
+ maxLength=maxLength*(float)newwidth/(float)oldwidth; //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0
+
+ updateFontData();
+ updateViews(); //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0
+
+}
+
+long KateDocument::needPreHighlight(long till)
+{
+ int max=numLines()-1;
+ if (till>max)
+ {
+ till=max;
+ }
+ if (PreHighlightedTill>=till) return -1;
+
+ long tmp=RequestPreHighlightTill;
+ if (RequestPreHighlightTill<till)
+ {
+ RequestPreHighlightTill=till;
+ if (tmp<=PreHighlightedTill) QTimer::singleShot(10,this,SLOT(doPreHighlight()));
+ }
+ return RequestPreHighlightTill;
+}
+
+void KateDocument::doPreHighlight()
+{
+ int from = PreHighlightedTill;
+ int till = PreHighlightedTill+200;
+ int max = numLines()-1;
+ if (till > max)
+ {
+ till = max;
+ }
+ PreHighlightedTill = till;
+ updateLines(from,till);
+ emit preHighlightChanged(PreHighlightedTill);
+ if (PreHighlightedTill<RequestPreHighlightTill)
+ QTimer::singleShot(10,this,SLOT(doPreHighlight()));
+}
+
+KateDocument::~KateDocument()
+{
+ m_highlight->release();
+
+ if ( !m_bSingleViewMode )
+ {
+ m_views.setAutoDelete( true );
+ m_views.clear();
+ m_views.setAutoDelete( false );
+ }
+ delete_d(this);
+}
+
+void KateDocument::openURL(const QString &filename)
+{
+
+ m_file=filename;
+ fileInfo->setFile (m_file);
+ setMTime();
+
+ if (!fileInfo->exists() || !fileInfo->isReadable())
+ {
+ qDebug("File doesn't exit or couldn't be read");
+ return false;
+ }
+
+ buffer->clear();
+#warning fixme
+// buffer->insertFile(0, m_file, KGlobal::charsets()->codecForName(myEncoding));
+ qDebug("Telling buffer to open file");
+ buffer->insertFile(0, m_file, QTextCodec::codecForLocale());
+
+ setMTime();
+
+ if (myWordWrap)
+ wrapText (myWordWrapAt);
+
+ int hl = hlManager->wildcardFind( m_file );
+
+ setHighlight(hl);
+
+ updateLines();
+ updateViews();
+
+ emit fileNameChanged();
+
+ return true;
+}
+
+bool KateDocument::saveFile()
+{
+ QFile f( m_file );
+ if ( !f.open( IO_WriteOnly ) )
+ return false; // Error
+
+ QTextStream stream(&f);
+
+ stream.setEncoding(QTextStream::RawUnicode); // disable Unicode headers
+#warning fixme
+// stream.setCodec(KGlobal::charsets()->codecForName(myEncoding));
+ stream.setCodec(QTextCodec::codecForLocale()); // this line sets the mapper to the correct codec
+
+ int maxLine = numLines();
+ int line = 0;
+ while(true)
+ {
+ stream << getTextLine(line)->getString();
+ line++;
+ if (line >= maxLine) break;
+
+ if (eolMode == KateDocument::eolUnix) stream << "\n";
+ else if (eolMode == KateDocument::eolDos) stream << "\r\n";
+ else if (eolMode == KateDocument::eolMacintosh) stream << '\r';
+ };
+ f.close();
+
+ fileInfo->setFile (m_file);
+ setMTime();
+
+ if (!(d(this)->hlSetByUser))
+ {
+ int hl = hlManager->wildcardFind( m_file );
+
+ setHighlight(hl);
+ }
+ emit fileNameChanged ();
+
+ return (f.status() == IO_Ok);
+}
+
+KTextEditor::View *KateDocument::createView( QWidget *parent, const char *name )
+{
+ return new KateView( this, parent, name);
+}
+
+QString KateDocument::textLine( int line ) const
+{
+ TextLine::Ptr l = getTextLine( line );
+ if ( !l )
+ return QString();
+
+ return l->getString();
+}
+
+void KateDocument::replaceLine(const QString& s,int line)
+{
+ remove_Line(line,false);
+ insert_Line(s,line,true);
+}
+
+void KateDocument::insertLine( const QString &str, int l ) {
+ insert_Line(str,l,true);
+}
+
+void KateDocument::insert_Line(const QString& s,int line, bool update)
+{
+ kdDebug(13020)<<"KateDocument::insertLine "<<s<<QString(" %1").arg(line)<<endl;
+ TextLine::Ptr TL=new TextLine();
+ TL->append(s.unicode(),s.length());
+ buffer->insertLine(line,TL);
+ if (update)
+ {
+ newDocGeometry=true;
+ updateLines(line);
+ updateViews();
+ }
+}
+
+void KateDocument::insertAt( const QString &s, int line, int col, bool )
+{
+ VConfig c;
+ c.view = 0; // ### FIXME
+ c.cursor.x = col;
+ c.cursor.y = line;
+ c.cXPos = 0; // ### FIXME
+ c.flags = 0; // ### FIXME
+ insert( c, s );
+}
+
+void KateDocument::removeLine( int line ) {
+ remove_Line(line,true);
+}
+
+void KateDocument::remove_Line(int line,bool update)
+{
+ kdDebug(13020)<<"KateDocument::removeLine "<<QString("%1").arg(line)<<endl;
+ buffer->removeLine(line);
+// newDocGeometry=true;
+// if line==0)
+ if (update)
+ {
+ updateLines(line);
+ updateViews();
+ }
+}
+
+int KateDocument::length() const
+{
+ return text().length();
+}
+
+void KateDocument::setSelection( int , int , int , int )
+{
+}
+
+bool KateDocument::hasSelection() const
+{
+ return (selectEnd >= selectStart);
+}
+
+QString KateDocument::selection() const
+{
+ uint flags = 0;
+ TextLine::Ptr textLine;
+ int len, z, start, end, i;
+
+ len = 1;
+ if (!(flags & KateView::cfVerticalSelect)) {
+ for (z = selectStart; z <= selectEnd; z++) {
+ textLine = getTextLine(z);
+ len += textLine->numSelected();
+ if (textLine->isSelected()) len++;
+ }
+ QString s;
+ len = 0;
+ for (z = selectStart; z <= selectEnd; z++) {
+ textLine = getTextLine(z);
+ end = 0;
+ do {
+ start = textLine->findUnselected(end);
+ end = textLine->findSelected(start);
+ for (i = start; i < end; i++) {
+ s[len] = textLine->getChar(i);
+ len++;
+ }
+ } while (start < end);
+ if (textLine->isSelected()) {
+ s[len] = '\n';
+ len++;
+ }
+ }
+// s[len] = '\0';
+ return s;
+ } else {
+ for (z = selectStart; z <= selectEnd; z++) {
+ textLine = getTextLine(z);
+ len += textLine->numSelected() + 1;
+ }
+ QString s;
+ len = 0;
+ for (z = selectStart; z <= selectEnd; z++) {
+ textLine = getTextLine(z);
+ end = 0;
+ do {
+ start = textLine->findUnselected(end);
+ end = textLine->findSelected(start);
+ for (i = start; i < end; i++) {
+ s[len] = textLine->getChar(i);
+ len++;
+ }
+ } while (start < end);
+ s[len] = '\n';
+ len++;
+ }
+// s[len] = '\0'; // the final \0 is not counted in length()
+ return s;
+ }
+}
+
+int KateDocument::numLines() const
+{
+ return buffer->count();
+}
+
+
+TextLine::Ptr KateDocument::getTextLine(int line) const
+{
+ // This is a hack to get this stuff working.
+ return buffer->line(line);
+}
+
+int KateDocument::textLength(int line) {
+ TextLine::Ptr textLine = getTextLine(line);
+ if (!textLine) return 0;
+ return textLine->length();
+}
+
+void KateDocument::setTabWidth(int chars) {
+ if (tabChars == chars) return;
+ if (chars < 1) chars = 1;
+ if (chars > 16) chars = 16;
+ tabChars = chars;
+ updateFontData();
+
+ maxLength = -1;
+ for (int i=0; i < buffer->count(); i++)
+ {
+ TextLine::Ptr textLine = buffer->line(i);
+ int len = textWidth(textLine,textLine->length());
+ if (len > maxLength) {
+ maxLength = len;
+ longestLine = textLine;
+ }
+ }
+}
+
+void KateDocument::setReadOnly(bool m) {
+ KTextEditor::View *view;
+
+ if (m != readOnly) {
+ readOnly = m;
+// if (readOnly) recordReset();
+ for (view = m_views.first(); view != 0L; view = m_views.next() ) {
+ emit static_cast<KateView *>( view )->newStatus();
+ }
+ }
+}
+
+bool KateDocument::isReadOnly() const {
+ return readOnly;
+}
+
+void KateDocument::setNewDoc( bool m )
+{
+// KTextEditor::View *view;
+
+ if ( m != newDoc )
+ {
+ newDoc = m;
+//// if (readOnly) recordReset();
+// for (view = m_views.first(); view != 0L; view = m_views.next() ) {
+// emit static_cast<KateView *>( view )->newStatus();
+// }
+ }
+}
+
+bool KateDocument::isNewDoc() const {
+ return newDoc;
+}
+
+void KateDocument::setModified(bool m) {
+ KTextEditor::View *view;
+
+ if (m != modified) {
+ modified = m;
+ for (view = m_views.first(); view != 0L; view = m_views.next() ) {
+ emit static_cast<KateView *>( view )->newStatus();
+ }
+ emit modifiedChanged ();
+ }
+}
+
+bool KateDocument::isModified() const {
+ return modified;
+}
+
+void KateDocument::readConfig()
+{
+ KConfig *config = KGlobal::config();
+ config->setGroup("Kate Document");
+
+ myWordWrap = config->readBoolEntry("Word Wrap On", false);
+ myWordWrapAt = config->readNumEntry("Word Wrap At", 80);
+ if (myWordWrap)
+ wrapText (myWordWrapAt);
+
+ setTabWidth(config->readNumEntry("TabWidth", 8));
+ setUndoSteps(config->readNumEntry("UndoSteps", 50));
+ m_singleSelection = config->readBoolEntry("SingleSelection", false);
+ myEncoding = config->readEntry("Encoding", QString::fromLatin1(QTextCodec::codecForLocale()->name()));
+ setFont (config->readFontEntry("Font", &myFont));
+
+ colors[0] = config->readColorEntry("Color Background", &colors[0]);
+ colors[1] = config->readColorEntry("Color Selected", &colors[1]);
+
+ config->sync();
+}
+
+void KateDocument::writeConfig()
+{
+ KConfig *config = KGlobal::config();
+ config->setGroup("Kate Document");
+#if 0
+ cofig->writeEntry("Word Wrap On", myWordWrap);
+ config->writeEntry("Word Wrap At", myWordWrapAt);
+ config->writeEntry("TabWidth", tabChars);
+ config->writeEntry("UndoSteps", undoSteps);
+ config->writeEntry("SingleSelection", m_singleSelection);
+ config->writeEntry("Encoding", myEncoding);
+ config->writeEntry("Font", myFont);
+ config->writeEntry("Color Background", colors[0]);
+ config->writeEntry("Color Selected", colors[1]);
+#endif
+ config->sync();
+}
+
+void KateDocument::readSessionConfig(KConfig *config)
+{
+ m_url = config->readEntry("URL"); // ### doesn't this break the encoding? (Simon)
+ setHighlight(hlManager->nameFind(config->readEntry("Highlight")));
+ // anders: restore bookmarks if possible
+ QValueList<int> l = config->readIntListEntry("Bookmarks");
+ if ( l.count() ) {
+ for (uint i=0; i < l.count(); i++) {
+ if ( numLines() < l[i] ) break;
+ getTextLine( l[i] )->addMark( Bookmark );
+ }
+ }
+}
+
+void KateDocument::writeSessionConfig(KConfig *config)
+{
+#if 0
+ config->writeEntry("URL", m_url); // ### encoding?? (Simon)
+ config->writeEntry("Highlight", m_highlight->name());
+ // anders: save bookmarks
+ QList<Kate::Mark> l = marks();
+ QValueList<int> ml;
+ for (uint i=0; i < l.count(); i++) {
+ if ( l.at(i)->type == 1) // only save bookmarks
+ ml << l.at(i)->line;
+ }
+ if ( ml.count() )
+ config->writeEntry("Bookmarks", ml);
+#endif
+}
+
+
+void KateDocument::setHighlight(int n) {
+ Highlight *h;
+
+// hlNumber = n;
+
+ h = hlManager->getHl(n);
+ if (h == m_highlight) {
+ updateLines();
+ } else {
+ if (m_highlight != 0L) m_highlight->release();
+ h->use();
+ m_highlight = h;
+ makeAttribs();
+ }
+ PreHighlightedTill=0;
+ RequestPreHighlightTill=0;
+ emit(highlightChanged());
+}
+
+void KateDocument::makeAttribs() {
+ qDebug("KateDocument::makeAttribs()");
+ m_numAttribs = hlManager->makeAttribs(m_highlight, m_attribs, maxAttribs);
+ updateFontData();
+ updateLines();
+}
+
+void KateDocument::updateFontData() {
+ int maxAscent, maxDescent;
+ int tabWidth;
+ KateView *view;
+
+ maxAscent = myFontMetrics.ascent();
+ maxDescent = myFontMetrics.descent();
+ tabWidth = myFontMetrics.width(' ');
+
+ fontHeight = maxAscent + maxDescent + 1;
+ fontAscent = maxAscent;
+ m_tabWidth = tabChars*tabWidth;
+
+ for (view = views.first(); view != 0L; view = views.next() ) {
+ view->myViewInternal->drawBuffer->resize(view->width(),fontHeight);
+ view->tagAll();
+ view->updateCursor();
+ }
+}
+
+void KateDocument::hlChanged() { //slot
+ makeAttribs();
+ updateViews();
+}
+
+
+void KateDocument::addView(KTextEditor::View *view) {
+ views.append( static_cast<KateView *>( view ) );
+ KTextEditor::Document::addView( view );
+ connect( static_cast<KateView *>( view ), SIGNAL( destroyed() ), this, SLOT( slotViewDestroyed() ) );
+}
+
+void KateDocument::removeView(KTextEditor::View *view) {
+// if (undoView == view) recordReset();
+ disconnect( static_cast<KateView *>( view ), SIGNAL( destroyed() ), this, SLOT( slotViewDestroyed() ) );
+ views.removeRef( static_cast<KateView *>( view ) );
+ KTextEditor::Document::removeView( view );
+}
+
+void KateDocument::slotViewDestroyed()
+{
+ views.removeRef( static_cast<const KateView *>( sender() ) );
+}
+
+bool KateDocument::ownedView(KateView *view) {
+ // do we own the given view?
+ return (views.containsRef(view) > 0);
+}
+
+bool KateDocument::isLastView(int numViews) {
+ return ((int) views.count() == numViews);
+}
+
+int KateDocument::textWidth(const TextLine::Ptr &textLine, int cursorX) {
+ int x;
+ int z;
+ QChar ch;
+ Attribute *a;
+
+ x = 0;
+ for (z = 0; z < cursorX; z++) {
+ ch = textLine->getChar(z);
+ a = &m_attribs[textLine->getAttr(z)];
+
+ if (ch == '\t')
+ x += m_tabWidth - (x % m_tabWidth);
+ else if (a->bold && a->italic)
+ x += myFontMetricsBI.width(ch);
+ else if (a->bold)
+ x += myFontMetricsBold.width(ch);
+ else if (a->italic)
+ x += myFontMetricsItalic.width(ch);
+ else
+ x += myFontMetrics.width(ch);
+ }
+ return x;
+}
+
+int KateDocument::textWidth(PointStruc &cursor) {
+ if (cursor.x < 0)
+ cursor.x = 0;
+ if (cursor.y < 0)
+ cursor.y = 0;
+ if (cursor.y >= numLines())
+ cursor.y = lastLine();
+ return textWidth(getTextLine(cursor.y),cursor.x);
+}
+
+int KateDocument::textWidth(bool wrapCursor, PointStruc &cursor, int xPos) {
+ int len;
+ int x, oldX;
+ int z;
+ QChar ch;
+ Attribute *a;
+
+ if (cursor.y < 0) cursor.y = 0;
+ if (cursor.y > lastLine()) cursor.y = lastLine();
+ TextLine::Ptr textLine = getTextLine(cursor.y);
+ len = textLine->length();
+
+ x = oldX = z = 0;
+ while (x < xPos && (!wrapCursor || z < len)) {
+ oldX = x;
+ ch = textLine->getChar(z);
+ a = &m_attribs[textLine->getAttr(z)];
+
+ if (ch == '\t')
+ x += m_tabWidth - (x % m_tabWidth);
+ else if (a->bold && a->italic)
+ x += myFontMetricsBI.width(ch);
+ else if (a->bold)
+ x += myFontMetricsBold.width(ch);
+ else if (a->italic)
+ x += myFontMetricsItalic.width(ch);
+ else
+ x += myFontMetrics.width(ch);
+
+ z++;
+ }
+ if (xPos - oldX < x - xPos && z > 0) {
+ z--;
+ x = oldX;
+ }
+ cursor.x = z;
+ return x;
+}
+
+
+int KateDocument::textPos(const TextLine::Ptr &textLine, int xPos) {
+ int x, oldX;
+ int z;
+ QChar ch;
+ Attribute *a;
+
+ x = oldX = z = 0;
+ while (x < xPos) { // && z < len) {
+ oldX = x;
+ ch = textLine->getChar(z);
+ a = &m_attribs[textLine->getAttr(z)];
+
+ if (ch == '\t')
+ x += m_tabWidth - (x % m_tabWidth);
+ else if (a->bold && a->italic)
+ x += myFontMetricsBI.width(ch);
+ else if (a->bold)
+ x += myFontMetricsBold.width(ch);
+ else if (a->italic)
+ x += myFontMetricsItalic.width(ch);
+ else
+ x += myFontMetrics.width(ch);
+
+ z++;
+ }
+ if (xPos - oldX < x - xPos && z > 0) {
+ z--;
+ // newXPos = oldX;
+ }// else newXPos = x;
+ return z;
+}
+
+int KateDocument::textWidth() {
+ return int(maxLength + 8);
+}
+
+int KateDocument::textHeight() {
+ return numLines()*fontHeight;
+}
+
+void KateDocument::insert(VConfig &c, const QString &s) {
+ int pos;
+ QChar ch;
+ QString buf;
+
+ if (s.isEmpty()) return;
+
+ recordStart(c, KateActionGroup::ugPaste);
+
+ pos = 0;
+ if (!(c.flags & KateView::cfVerticalSelect)) {
+ do {
+ ch = s[pos];
+ if (ch.isPrint() || ch == '\t') {
+ buf += ch; // append char to buffer
+ } else if (ch == '\n') {
+ recordAction(KateAction::newLine, c.cursor); // wrap contents behind cursor to new line
+ recordInsert(c, buf); // append to old line
+// c.cursor.x += buf.length();
+ buf.truncate(0); // clear buffer
+ c.cursor.y++;
+ c.cursor.x = 0;
+ }
+ pos++;
+ } while (pos < (int) s.length());
+ } else {
+ int xPos;
+
+ xPos = textWidth(c.cursor);
+ do {
+ ch = s[pos];
+ if (ch.isPrint() || ch == '\t') {
+ buf += ch;
+ } else if (ch == '\n') {
+ recordInsert(c, buf);
+ c.cursor.x += buf.length();
+ buf.truncate(0);
+ c.cursor.y++;
+ if (c.cursor.y >= numLines())
+ recordAction(KateAction::insLine, c.cursor);
+ c.cursor.x = textPos(getTextLine(c.cursor.y), xPos);
+ }
+ pos++;
+ } while (pos < (int) s.length());
+ }
+ recordInsert(c, buf);
+ c.cursor.x += buf.length();
+ recordEnd(c);
+}
+
+void KateDocument::insertFile(VConfig &c, QIODevice &dev)
+{
+ recordStart(c, KateActionGroup::ugPaste);
+
+ QString buf;
+ QChar ch, last;
+
+ QTextStream stream( &dev );
+
+ while ( !stream.atEnd() ) {
+ stream >> ch;
+
+ if (ch.isPrint() || ch == '\t') {
+ buf += ch;
+ } else if (ch == '\n' || ch == '\r') {
+ if (last != '\r' || ch != '\n') {
+ recordAction(KateAction::newLine, c.cursor);
+ recordInsert(c, buf);
+ buf.truncate(0);
+ c.cursor.y++;
+ c.cursor.x = 0;
+ }
+ last = ch;
+ }
+ }
+
+ recordInsert(c, buf);
+ recordEnd(c);
+}
+
+int KateDocument::currentColumn(PointStruc &cursor) {
+ return getTextLine(cursor.y)->cursorX(cursor.x,tabChars);
+}
+
+bool KateDocument::insertChars(VConfig &c, const QString &chars) {
+ int z, pos, l;
+ bool onlySpaces;
+ QChar ch;
+ QString buf;
+
+ TextLine::Ptr textLine = getTextLine(c.cursor.y);
+
+ pos = 0;
+ onlySpaces = true;
+ for (z = 0; z < (int) chars.length(); z++) {
+ ch = chars[z];
+ if (ch == '\t' && c.flags & KateView::cfReplaceTabs) {
+ l = tabChars - (textLine->cursorX(c.cursor.x, tabChars) % tabChars);
+ while (l > 0) {
+ buf.insert(pos, ' ');
+ pos++;
+ l--;
+ }
+ } else if (ch.isPrint() || ch == '\t') {
+ buf.insert(pos, ch);
+ pos++;
+ if (ch != ' ') onlySpaces = false;
+ if (c.flags & KateView::cfAutoBrackets) {
+ if (ch == '(') buf.insert(pos, ')');
+ if (ch == '[') buf.insert(pos, ']');
+ if (ch == '{') buf.insert(pos, '}');
+ }
+ }
+ }
+ //pos = cursor increment
+
+ //return false if nothing has to be inserted
+ if (buf.isEmpty()) return false;
+
+ //auto deletion of the marked text occurs not very often and can therefore
+ // be recorded separately
+ if (c.flags &KateView:: cfDelOnInput) delMarkedText(c);
+
+ recordStart(c, KateActionGroup::ugInsChar);
+ recordReplace(c/*.cursor*/, (c.flags & KateView::cfOvr) ? buf.length() : 0, buf);
+ c.cursor.x += pos;
+
+ if (myWordWrap && myWordWrapAt > 0) {
+ int line;
+ const QChar *s;
+// int pos;
+ PointStruc actionCursor;
+
+ line = c.cursor.y;
+ do {
+ textLine = getTextLine(line);
+ s = textLine->getText();
+ l = textLine->length();
+ for (z = myWordWrapAt; z < l; z++) if (!s[z].isSpace()) break; //search for text to wrap
+ if (z >= l) break; // nothing more to wrap
+ pos = myWordWrapAt;
+ for (; z >= 0; z--) { //find wrap position
+ if (s[z].isSpace()) {
+ pos = z + 1;
+ break;
+ }
+ }
+ //pos = wrap position
+
+ if (line == c.cursor.y && pos <= c.cursor.x) {
+ //wrap cursor
+ c.cursor.y++;
+ c.cursor.x -= pos;
+ }
+
+ if (line == lastLine() || (getTextLine(line+1)->length() == 0) ) {
+ //at end of doc: create new line
+ actionCursor.x = pos;
+ actionCursor.y = line;
+ recordAction(KateAction::newLine,actionCursor);
+ } else {
+ //wrap
+ actionCursor.y = line + 1;
+ if (!s[l - 1].isSpace()) { //add space in next line if necessary
+ actionCursor.x = 0;
+ recordInsert(actionCursor, " ");
+ }
+ actionCursor.x = textLine->length() - pos;
+ recordAction(KateAction::wordWrap, actionCursor);
+ }
+ line++;
+ } while (true);
+ }
+ recordEnd(c);
+ return true;
+}
+
+QString tabString(int pos, int tabChars) {
+ QString s;
+ while (pos >= tabChars) {
+ s += '\t';
+ pos -= tabChars;
+ }
+ while (pos > 0) {
+ s += ' ';
+ pos--;
+ }
+ return s;
+}
+
+void KateDocument::newLine(VConfig &c) {
+
+ //auto deletion of marked text is done by the view to have a more
+ // "low level" KateDocument::newLine method
+ recordStart(c, KateActionGroup::ugInsLine);
+
+ if (!(c.flags & KateView::cfAutoIndent)) {
+ recordAction(KateAction::newLine,c.cursor);
+ c.cursor.y++;
+ c.cursor.x = 0;
+ } else {
+ TextLine::Ptr textLine = getTextLine(c.cursor.y);
+ int pos = textLine->firstChar();
+ if (c.cursor.x < pos) c.cursor.x = pos; // place cursor on first char if before
+
+ int y = c.cursor.y;
+ while ((y > 0) && (pos < 0)) { // search a not empty text line
+ textLine = getTextLine(--y);
+ pos = textLine->firstChar();
+ }
+ recordAction(KateAction::newLine, c.cursor);
+ c.cursor.y++;
+ c.cursor.x = 0;
+ if (pos > 0) {
+ pos = textLine->cursorX(pos, tabChars);
+// if (getTextLine(c.cursor.y)->length() > 0) {
+ QString s = tabString(pos, (c.flags & KateView::cfSpaceIndent) ? 0xffffff : tabChars);
+ recordInsert(c.cursor, s);
+ pos = s.length();
+// }
+// recordInsert(c.cursor, QString(textLine->getText(), pos));
+ c.cursor.x = pos;
+ }
+ }
+
+ recordEnd(c);
+}
+
+void KateDocument::killLine(VConfig &c) {
+
+ recordStart(c, KateActionGroup::ugDelLine);
+ c.cursor.x = 0;
+ recordDelete(c.cursor, 0xffffff);
+ if (c.cursor.y < lastLine()) {
+ recordAction(KateAction::killLine, c.cursor);
+ }
+ recordEnd(c);
+}
+
+void KateDocument::backspace(VConfig &c) {
+
+ if (c.cursor.x <= 0 && c.cursor.y <= 0) return;
+
+ if (c.cursor.x > 0) {
+ recordStart(c, KateActionGroup::ugDelChar);
+ if (!(c.flags & KateView::cfBackspaceIndents)) {
+ // ordinary backspace
+ c.cursor.x--;
+ recordDelete(c.cursor, 1);
+ } else {
+ // backspace indents: erase to next indent position
+ int l = 1; // del one char
+
+ TextLine::Ptr textLine = getTextLine(c.cursor.y);
+ int pos = textLine->firstChar();
+ if (pos < 0 || pos >= c.cursor.x) {
+ // only spaces on left side of cursor
+ // search a line with less spaces
+ int y = c.cursor.y;
+ while (y > 0) {
+ textLine = getTextLine(--y);
+ pos = textLine->firstChar();
+ if (pos >= 0 && pos < c.cursor.x) {
+ l = c.cursor.x - pos; // del more chars
+ break;
+ }
+ }
+ }
+ // break effectively jumps here
+ c.cursor.x -= l;
+ recordDelete(c.cursor, l);
+ }
+ } else {
+ // c.cursor.x == 0: wrap to previous line
+ recordStart(c, KateActionGroup::ugDelLine);
+ c.cursor.y--;
+ c.cursor.x = getTextLine(c.cursor.y)->length();
+ recordAction(KateAction::delLine,c.cursor);
+ }
+ recordEnd(c);
+}
+
+
+void KateDocument::del(VConfig &c) {
+ TextLine::Ptr textLine = getTextLine(c.cursor.y);
+ int len = (c.flags & KateView::cfRemoveSpaces) ? textLine->lastChar() : textLine->length();
+ if (c.cursor.x < len/*getTextLine(c.cursor.y)->length()*/) {
+ // delete one character
+ recordStart(c, KateActionGroup::ugDelChar);
+ recordDelete(c.cursor, 1);
+ recordEnd(c);
+ } else {
+ if (c.cursor.y < lastLine()) {
+ // wrap next line to this line
+ textLine->truncate(c.cursor.x); // truncate spaces
+ recordStart(c, KateActionGroup::ugDelLine);
+ recordAction(KateAction::delLine,c.cursor);
+ recordEnd(c);
+ }
+ }
+}
+
+void KateDocument::clear() {
+ PointStruc cursor;
+ KateView *view;
+
+ setPseudoModal(0L);
+ cursor.x = cursor.y = 0;
+ for (view = views.first(); view != 0L; view = views.next() ) {
+ view->updateCursor(cursor);
+ view->tagAll();
+ }
+
+ eolMode = KateDocument::eolUnix;
+
+ buffer->clear();
+ longestLine = buffer->line(0);
+
+ maxLength = 0;
+
+ select.x = -1;
+
+ selectStart = 0xffffff;
+ selectEnd = 0;
+ oldMarkState = false;
+
+ setModified(false);
+
+ undoList.clear();
+ currentUndo = 0;
+ newUndo();
+}
+
+void KateDocument::cut(VConfig &c) {
+
+ if (selectEnd < selectStart) return;
+
+ copy(c.flags);
+ delMarkedText(c);
+}
+
+void KateDocument::copy(int flags) {
+
+ if (selectEnd < selectStart) return;
+
+ QString s = markedText(flags);
+ if (!s.isEmpty()) {
+//#if defined(_WS_X11_)
+ if (m_singleSelection)
+ disconnect(QApplication::clipboard(), SIGNAL(dataChanged()), this, 0);
+//#endif
+ QApplication::clipboard()->setText(s);
+//#if defined(_WS_X11_)
+ if (m_singleSelection) {
+ connect(QApplication::clipboard(), SIGNAL(dataChanged()),
+ this, SLOT(clipboardChanged()));
+ }
+//#endif
+ }
+}
+
+void KateDocument::paste(VConfig &c) {
+ QString s = QApplication::clipboard()->text();
+ if (!s.isEmpty()) {
+ insert(c, s);
+ }
+}
+
+void KateDocument::toggleRect(int start, int end, int x1, int x2) {
+ int z, line;
+ bool t;
+
+ if (x1 > x2) {
+ z = x1;
+ x1 = x2;
+ x2 = z;
+ }
+ if (start > end) {
+ z = start;
+ start = end;
+ end = z;
+ }
+
+ t = false;
+ for (line = start; line < end; line++) {
+ int x, oldX, s, e, newX1, newX2;
+ QChar ch;
+ Attribute *a;
+
+ TextLine::Ptr textLine = getTextLine(line);
+
+ //--- speed optimization
+ //s = textPos(textLine, x1, newX1);
+ x = oldX = z = 0;
+ while (x < x1) { // && z < len) {
+ oldX = x;
+ ch = textLine->getChar(z);
+ a = &m_attribs[textLine->getAttr(z)];
+
+ if (ch == '\t')
+ x += m_tabWidth - (x % m_tabWidth);
+ else if (a->bold && a->italic)
+ x += myFontMetricsBI.width(ch);
+ else if (a->bold)
+ x += myFontMetricsBold.width(ch);
+ else if (a->italic)
+ x += myFontMetricsItalic.width(ch);
+ else
+ x += myFontMetrics.width(ch);
+
+ z++;
+ }
+ s = z;
+ if (x1 - oldX < x - x1 && z > 0) {
+ s--;
+ newX1 = oldX;
+ } else newX1 = x;
+ //e = textPos(textLine, x2, newX2);
+ while (x < x2) { // && z < len) {
+ oldX = x;
+ ch = textLine->getChar(z);
+ a = &m_attribs[textLine->getAttr(z)];
+
+ if (ch == '\t')
+ x += m_tabWidth - (x % m_tabWidth);
+ else if (a->bold && a->italic)
+ x += myFontMetricsBI.width(ch);
+ else if (a->bold)
+ x += myFontMetricsBold.width(ch);
+ else if (a->italic)
+ x += myFontMetricsItalic.width(ch);
+ else
+ x += myFontMetrics.width(ch);
+
+ z++;
+ }
+ e = z;
+ if (x2 - oldX < x - x2 && z > 0) {
+ e--;
+ newX2 = oldX;
+ } else newX2 = x;
+ //---
+
+ if (e > s) {
+ textLine->toggleSelect(s, e);
+ tagLineRange(line, newX1, newX2);
+ t = true;
+ }
+ }
+ if (t) {
+ end--;
+// tagLines(start, end);
+
+ if (start < selectStart) selectStart = start;
+ if (end > selectEnd) selectEnd = end;
+ emit selectionChanged();
+ }
+}
+
+void KateDocument::selectTo(VConfig &c, PointStruc &cursor, int cXPos) {
+ //c.cursor = old cursor position
+ //cursor = new cursor position
+
+ if (c.cursor.x != select.x || c.cursor.y != select.y) {
+ //new selection
+
+ if (!(c.flags & KateView::cfKeepSelection)) deselectAll();
+// else recordReset();
+
+ anchor = c.cursor;
+ aXPos = c.cXPos;
+ }
+
+ if (!(c.flags & KateView::cfVerticalSelect)) {
+ //horizontal selections
+ int x, y, sXPos;
+ int ex, ey, eXPos;
+ bool sel;
+
+ if (cursor.y > c.cursor.y || (cursor.y == c.cursor.y && cursor.x > c.cursor.x)) {
+ x = c.cursor.x;
+ y = c.cursor.y;
+ sXPos = c.cXPos;
+ ex = cursor.x;
+ ey = cursor.y;
+ eXPos = cXPos;
+ sel = true;
+ } else {
+ x = cursor.x;
+ y = cursor.y;
+ sXPos = cXPos;
+ ex = c.cursor.x;
+ ey = c.cursor.y;
+ eXPos = c.cXPos;
+ sel = false;
+ }
+
+// tagLines(y, ye);
+ if (y < ey) {
+ //tagLineRange(y, sXPos, 0xffffff);
+ tagLines(y, ey -1);
+ tagLineRange(ey, 0, eXPos);
+ } else tagLineRange(y, sXPos, eXPos);
+
+ if (y < selectStart) selectStart = y;
+ if (ey > selectEnd) selectEnd = ey;
+
+ TextLine::Ptr textLine = getTextLine(y);
+
+ if (c.flags & KateView::cfXorSelect) {
+ //xor selection with old selection
+ while (y < ey) {
+ textLine->toggleSelectEol(x);
+ x = 0;
+ y++;
+ textLine = getTextLine(y);
+ }
+ textLine->toggleSelect(x, ex);
+ } else {
+ //set selection over old selection
+
+ if (anchor.y > y || (anchor.y == y && anchor.x > x)) {
+ if (anchor.y < ey || (anchor.y == ey && anchor.x < ex)) {
+ sel = !sel;
+ while (y < anchor.y) {
+ textLine->selectEol(sel, x);
+ x = 0;
+ y++;
+ textLine = getTextLine(y);
+ }
+ textLine->select(sel, x, anchor.x);
+ x = anchor.x;
+ }
+ sel = !sel;
+ }
+ while (y < ey) {
+ textLine->selectEol(sel, x);
+ x = 0;
+ y++;
+ textLine = getTextLine(y);
+ }
+ textLine->select(sel, x, ex);
+ }
+ } else {
+ //vertical (block) selections
+// int ax, sx, ex;
+
+// ax = textWidth(anchor);
+// sx = textWidth(start);
+// ex = textWidth(end);
+
+ toggleRect(c.cursor.y + 1, cursor.y + 1, aXPos, c.cXPos);
+ toggleRect(anchor.y, cursor.y + 1, c.cXPos, cXPos);
+ }
+ select = cursor;
+ optimizeSelection();
+ emit selectionChanged();
+}
+
+
+void KateDocument::selectAll() {
+ int z;
+ TextLine::Ptr textLine;
+
+ select.x = -1;
+
+// if (selectStart != 0 || selectEnd != lastLine()) recordReset();
+
+ selectStart = 0;
+ selectEnd = lastLine();
+
+ tagLines(selectStart,selectEnd);
+
+ for (z = selectStart; z < selectEnd; z++) {
+ textLine = getTextLine(z);
+ textLine->selectEol(true,0);
+ }
+ textLine = getTextLine(z);
+ textLine->select(true,0,textLine->length());
+ emit selectionChanged();
+}
+
+void KateDocument::deselectAll() {
+ select.x = -1;
+ if (selectEnd < selectStart) return;
+
+// recordReset();
+
+ tagLines(selectStart,selectEnd);
+
+ for (int z = selectStart; z <= selectEnd; z++) {
+ TextLine::Ptr textLine = getTextLine(z);
+ textLine->selectEol(false,0);
+ }
+ selectStart = 0xffffff;
+ selectEnd = 0;
+ emit selectionChanged();
+}
+
+void KateDocument::invertSelection() {
+ TextLine::Ptr textLine;
+
+ select.x = -1;
+
+// if (selectStart != 0 || selectEnd != lastLine()) recordReset();
+
+ selectStart = 0;
+ selectEnd = lastLine();
+
+ tagLines(selectStart,selectEnd);
+
+ for (int z = selectStart; z < selectEnd; z++) {
+ textLine = getTextLine(z);
+ textLine->toggleSelectEol(0);
+ }
+ textLine = getTextLine(selectEnd);
+ textLine->toggleSelect(0,textLine->length());
+ optimizeSelection();
+ emit selectionChanged();
+}
+
+void KateDocument::selectWord(PointStruc &cursor, int flags) {
+ int start, end, len;
+
+ TextLine::Ptr textLine = getTextLine(cursor.y);
+ len = textLine->length();
+ start = end = cursor.x;
+ while (start > 0 && m_highlight->isInWord(textLine->getChar(start - 1))) start--;
+ while (end < len && m_highlight->isInWord(textLine->getChar(end))) end++;
+ if (end <= start) return;
+ if (!(flags & KateView::cfKeepSelection)) deselectAll();
+// else recordReset();
+
+ textLine->select(true, start, end);
+
+ anchor.x = start;
+ select.x = end;
+ anchor.y = select.y = cursor.y;
+ tagLines(cursor.y, cursor.y);
+ if (cursor.y < selectStart) selectStart = cursor.y;
+ if (cursor.y > selectEnd) selectEnd = cursor.y;
+ emit selectionChanged();
+}
+
+void KateDocument::selectLength(PointStruc &cursor, int length, int flags) {
+ int start, end;
+
+ TextLine::Ptr textLine = getTextLine(cursor.y);
+ start = cursor.x;
+ end = start + length;
+ if (end <= start) return;
+ if (!(flags & KateView::cfKeepSelection)) deselectAll();
+
+ textLine->select(true, start, end);
+
+ anchor.x = start;
+ select.x = end;
+ anchor.y = select.y = cursor.y;
+ tagLines(cursor.y, cursor.y);
+ if (cursor.y < selectStart) selectStart = cursor.y;
+ if (cursor.y > selectEnd) selectEnd = cursor.y;
+ emit selectionChanged();
+}
+
+void KateDocument::doIndent(VConfig &c, int change) {
+
+ c.cursor.x = 0;
+
+ recordStart(c, (change < 0) ? KateActionGroup::ugUnindent
+ : KateActionGroup::ugIndent);
+
+ if (selectEnd < selectStart) {
+ // single line
+ optimizeLeadingSpace(c.cursor.y, c.flags, change);
+ } else {
+ // entire selection
+ TextLine::Ptr textLine;
+ int line, z;
+ QChar ch;
+
+ if (c.flags & KateView::cfKeepIndentProfile && change < 0) {
+ // unindent so that the existing indent profile doesn´t get screwed
+ // if any line we may unindent is already full left, don't do anything
+ for (line = selectStart; line <= selectEnd; line++) {
+ textLine = getTextLine(line);
+ if (textLine->isSelected() || textLine->numSelected()) {
+ for (z = 0; z < tabChars; z++) {
+ ch = textLine->getChar(z);
+ if (ch == '\t') break;
+ if (ch != ' ') {
+ change = 0;
+ goto jumpOut;
+ }
+ }
+ }
+ }
+ jumpOut:;
+ }
+
+ for (line = selectStart; line <= selectEnd; line++) {
+ textLine = getTextLine(line);
+ if (textLine->isSelected() || textLine->numSelected()) {
+ optimizeLeadingSpace(line, c.flags, change);
+ }
+ }
+ }
+ // recordEnd now removes empty undo records
+ recordEnd(c.view, c.cursor, c.flags | KateView::cfPersistent);
+}
+
+/*
+ Optimize the leading whitespace for a single line.
+ If change is > 0, it adds indentation units (tabChars)
+ if change is == 0, it only optimizes
+ If change is < 0, it removes indentation units
+ This will be used to indent, unindent, and optimal-fill a line.
+ If excess space is removed depends on the flag cfKeepExtraSpaces
+ which has to be set by the user
+*/
+void KateDocument::optimizeLeadingSpace(int line, int flags, int change) {
+ int len;
+ int chars, space, okLen;
+ QChar ch;
+ int extra;
+ QString s;
+ PointStruc cursor;
+
+ TextLine::Ptr textLine = getTextLine(line);
+ len = textLine->length();
+ space = 0; // length of space at the beginning of the textline
+ okLen = 0; // length of space which does not have to be replaced
+ for (chars = 0; chars < len; chars++) {
+ ch = textLine->getChar(chars);
+ if (ch == ' ') {
+ space++;
+ if (flags & KateView::cfSpaceIndent && okLen == chars) okLen++;
+ } else if (ch == '\t') {
+ space += tabChars - space % tabChars;
+ if (!(flags & KateView::cfSpaceIndent) && okLen == chars) okLen++;
+ } else break;
+ }
+
+ space += change*tabChars; // modify space width
+ // if line contains only spaces it will be cleared
+ if (space < 0 || chars == len) space = 0;
+
+ extra = space % tabChars; // extra spaces which don´t fit the indentation pattern
+ if (flags & KateView::cfKeepExtraSpaces) chars -= extra;
+
+ if (flags & KateView::cfSpaceIndent) {
+ space -= extra;
+ ch = ' ';
+ } else {
+ space /= tabChars;
+ ch = '\t';
+ }
+
+ // don´t replace chars which are already ok
+ cursor.x = QMIN(okLen, QMIN(chars, space));
+ chars -= cursor.x;
+ space -= cursor.x;
+ if (chars == 0 && space == 0) return; //nothing to do
+
+ s.fill(ch, space);
+
+//printf("chars %d insert %d cursor.x %d\n", chars, insert, cursor.x);
+ cursor.y = line;
+ recordReplace(cursor, chars, s);
+}
+
+void KateDocument::doComment(VConfig &c, int change)
+{
+ c.flags |=KateView:: cfPersistent;
+
+ recordStart(c, (change < 0) ? KateActionGroup::ugUncomment
+ : KateActionGroup::ugComment);
+
+ QString startComment = m_highlight->getCommentStart();
+ QString startLineComment = m_highlight->getCommentSingleLineStart();
+ QString endComment = m_highlight->getCommentEnd();
+
+ int startCommentLen = startComment.length();
+ int startLineCommentLen = startLineComment.length();
+ int endCommentLen = endComment.length();
+
+ if (change > 0)
+ {
+ if ( !hasMarkedText() )
+ {
+ if (startLineComment != "")
+ {
+ // Add a start comment mark
+ c.cursor.x = 0;
+ recordReplace(c.cursor, 0, startLineComment);
+ }
+ else if ((startComment != "") && (endComment != ""))
+ {
+ // Add a start comment mark
+ c.cursor.x = 0;
+ recordReplace(c.cursor, 0, startComment);
+
+ // Add an end comment mark
+ TextLine* textline = getTextLine(c.cursor.y);
+ c.cursor.x = textline->length();
+ recordReplace(c.cursor, 0, endComment);
+ c.cursor.x = 0;
+ }
+ }
+ else if ((startComment != "") && (endComment != ""))
+ {
+ QString marked (c.view->markedText ());
+ int preDeleteLine = -1, preDeleteCol = -1;
+ c.view->getCursorPosition (&preDeleteLine, &preDeleteCol);
+
+ if (marked.length() > 0)
+ c.view->keyDelete ();
+
+ int line = -1, col = -1;
+ c.view->getCursorPosition (&line, &col);
+
+ c.view->insertText (startComment + marked + endComment);
+ }
+ }
+ else
+ {
+ if ( !hasMarkedText() )
+ {
+ TextLine* textline = getTextLine(c.cursor.y);
+
+ if(textline->startingWith(startLineComment))
+ {
+ // Remove start comment mark
+ c.cursor.x = 0;
+ recordReplace(c.cursor, startLineCommentLen, "");
+ }
+ else if (textline->startingWith(startComment) && textline->endingWith(endComment))
+ {
+ // Remove start comment mark
+ c.cursor.x = 0;
+ recordReplace(c.cursor, startCommentLen, "");
+
+ // Remove end comment mark
+ if(endComment != "")
+ {
+ c.cursor.x = textline->length() - endCommentLen;
+ recordReplace(c.cursor, endCommentLen, "");
+ c.cursor.x = 0;
+ }
+ }
+ }
+ else
+ {
+ QString marked (c.view->markedText ());
+ int preDeleteLine = -1, preDeleteCol = -1;
+ c.view->getCursorPosition (&preDeleteLine, &preDeleteCol);
+
+ int start = marked.find (startComment);
+ int end = marked.findRev (endComment);
+
+ if ((start > -1) && (end > -1))
+ {
+ marked.remove (start, startCommentLen);
+ marked.remove (end-startCommentLen, endCommentLen);
+
+ c.view->keyDelete ();
+
+ int line = -1, col = -1;
+ c.view->getCursorPosition (&line, &col);
+ c.view->insertText (marked);
+ }
+ }
+ }
+
+ recordEnd(c.view, c.cursor, c.flags | KateView::cfPersistent);
+}
+
+
+QString KateDocument::text() const
+{
+ QString s;
+
+ for (int i=0; i < buffer->count(); i++)
+ {
+ TextLine::Ptr textLine = buffer->line(i);
+ s.insert(s.length(), textLine->getText(), textLine->length());
+ if ( (i < (buffer->count()-1)) )
+ s.append('\n');
+ }
+
+ return s;
+}
+
+QString KateDocument::getWord(PointStruc &cursor) {
+ int start, end, len;
+
+ TextLine::Ptr textLine = getTextLine(cursor.y);
+ len = textLine->length();
+ start = end = cursor.x;
+ while (start > 0 && m_highlight->isInWord(textLine->getChar(start - 1))) start--;
+ while (end < len && m_highlight->isInWord(textLine->getChar(end))) end++;
+ len = end - start;
+ return QString(&textLine->getText()[start], len);
+}
+
+void KateDocument::setText(const QString &s) {
+ int pos;
+ QChar ch;
+
+ clear();
+
+ int line=1;
+
+ TextLine::Ptr textLine = buffer->line(0);
+ for (pos = 0; pos <= (int) s.length(); pos++) {
+ ch = s[pos];
+ if (ch.isPrint() || ch == '\t') {
+ textLine->append(&ch, 1);
+ } else if (ch == '\n')
+ {
+ textLine = new TextLine();
+ buffer->insertLine (line, textLine);
+ line++;
+ }
+ }
+ updateLines();
+}
+
+
+QString KateDocument::markedText(int flags) {
+ TextLine::Ptr textLine;
+ int len, z, start, end, i;
+
+ len = 1;
+ if (!(flags & KateView::cfVerticalSelect)) {
+ for (z = selectStart; z <= selectEnd; z++) {
+ textLine = getTextLine(z);
+ len += textLine->numSelected();
+ if (textLine->isSelected()) len++;
+ }
+ QString s;
+ len = 0;
+ for (z = selectStart; z <= selectEnd; z++) {
+ textLine = getTextLine(z);
+ end = 0;
+ do {
+ start = textLine->findUnselected(end);
+ end = textLine->findSelected(start);
+ for (i = start; i < end; i++) {
+ s[len] = textLine->getChar(i);
+ len++;
+ }
+ } while (start < end);
+ if (textLine->isSelected()) {
+ s[len] = '\n';
+ len++;
+ }
+ }
+// s[len] = '\0';
+ return s;
+ } else {
+ for (z = selectStart; z <= selectEnd; z++) {
+ textLine = getTextLine(z);
+ len += textLine->numSelected() + 1;
+ }
+ QString s;
+ len = 0;
+ for (z = selectStart; z <= selectEnd; z++) {
+ textLine = getTextLine(z);
+ end = 0;
+ do {
+ start = textLine->findUnselected(end);
+ end = textLine->findSelected(start);
+ for (i = start; i < end; i++) {
+ s[len] = textLine->getChar(i);
+ len++;
+ }
+ } while (start < end);
+ s[len] = '\n';
+ len++;
+ }
+// s[len] = '\0'; // the final \0 is not counted in length()
+ return s;
+ }
+}
+
+void KateDocument::delMarkedText(VConfig &c/*, bool undo*/) {
+ int end = 0;
+
+ if (selectEnd < selectStart) return;
+
+ // the caller may have already started an undo record for the current action
+// if (undo)
+
+ //auto deletion of the marked text occurs not very often and can therefore
+ // be recorded separately
+ recordStart(c, KateActionGroup::ugDelBlock);
+
+ for (c.cursor.y = selectEnd; c.cursor.y >= selectStart; c.cursor.y--) {
+ TextLine::Ptr textLine = getTextLine(c.cursor.y);
+
+ c.cursor.x = textLine->length();
+ do {
+ end = textLine->findRevUnselected(c.cursor.x);
+ if (end == 0) break;
+ c.cursor.x = textLine->findRevSelected(end);
+ recordDelete(c.cursor, end - c.cursor.x);
+ } while (true);
+ end = c.cursor.x;
+ c.cursor.x = textLine->length();
+ if (textLine->isSelected()) recordAction(KateAction::delLine,c.cursor);
+ }
+ c.cursor.y++;
+ /*if (end < c.cursor.x)*/ c.cursor.x = end;
+
+ selectEnd = -1;
+ select.x = -1;
+
+ /*if (undo)*/ recordEnd(c);
+}
+
+void KateDocument::tagLineRange(int line, int x1, int x2) {
+ int z;
+
+ for (z = 0; z < (int) views.count(); z++) {
+ views.at(z)->tagLines(line, line, x1, x2);
+ }
+}
+
+void KateDocument::tagLines(int start, int end) {
+ int z;
+
+ for (z = 0; z < (int) views.count(); z++) {
+ views.at(z)->tagLines(start, end, 0, 0xffffff);
+ }
+}
+
+void KateDocument::tagAll() {
+ int z;
+
+ for (z = 0; z < (int) views.count(); z++) {
+ views.at(z)->tagAll();
+ }
+}
+
+void KateDocument::updateLines(int startLine, int endLine, int flags, int cursorY) {
+ TextLine::Ptr textLine;
+ int line, last_line;
+ int ctxNum, endCtx;
+// kdDebug(13020)<<"******************KateDocument::updateLines Checkpoint 1"<<endl;
+ if (buffer->line(startLine)==0) {kdDebug(13020)<<"********************No buffer for line " << startLine << " found**************"<<endl; return;};
+// kdDebug(13020)<<"KateDocument::updateLines Checkpoint 2"<<endl;
+ last_line = lastLine();
+// if (endLine >= last_line) endLine = last_line;
+
+ line = startLine;
+ ctxNum = 0;
+ if (line > 0) ctxNum = getTextLine(line - 1)->getContext();
+ do {
+// kdDebug(13020)<<QString("**************Working on line: %1").arg(line)<<endl;
+ textLine = getTextLine(line);
+ if (textLine==0) kdDebug(13020)<<"****updateLines()>> error textLine==0"<<endl;
+ if (line <= endLine && line != cursorY) {
+ if (flags & KateView::cfRemoveSpaces) textLine->removeSpaces();
+ updateMaxLength(textLine);
+ }
+ endCtx = textLine->getContext();
+ qDebug("DOHIGHLIGHT");
+ ctxNum = m_highlight->doHighlight(ctxNum,textLine);
+ textLine->setContext(ctxNum);
+ line++;
+ } while ((buffer->line(line)!=0) && (line <= endLine || endCtx != ctxNum));
+// kdDebug(13020)<<"updateLines :: while loop left"<<endl;
+ tagLines(startLine, line - 1);
+}
+
+
+void KateDocument::updateMaxLength(TextLine::Ptr &textLine) {
+ int len;
+
+ len = textWidth(textLine,textLine->length());
+
+ if (len > maxLength) {
+ longestLine = textLine;
+ maxLength = len;
+ newDocGeometry = true;
+ } else {
+ if (!longestLine || (textLine == longestLine && len <= maxLength*3/4)) {
+ maxLength = -1;
+ for (int i = 0; i < numLines();i++) {
+ textLine = getTextLine(i);
+ len = textWidth(textLine,textLine->length());
+ if (len > maxLength) {
+ maxLength = len;
+ longestLine = textLine;
+ }
+ }
+ newDocGeometry = true;
+ }
+ }
+}
+
+void KateDocument::slotBufferChanged() {
+ newDocGeometry = true;
+ //updateLines();//JW
+ updateViews();
+}
+
+void KateDocument::slotBufferHighlight(long start,long stop) {
+ kdDebug(13020)<<"KateDocument::slotBufferHighlight"<<QString("%1-%2").arg(start).arg(stop)<<endl;
+ updateLines(start,stop);
+// buffer->startLoadTimer();
+}
+
+void KateDocument::updateViews(KateView *exclude) {
+ KateView *view;
+ int flags;
+ bool markState = hasMarkedText();
+
+ flags = (newDocGeometry) ? KateView::ufDocGeometry : 0;
+ for (view = views.first(); view != 0L; view = views.next() ) {
+ if (view != exclude) view->updateView(flags);
+
+ // notify every view about the changed mark state....
+ if (oldMarkState != markState) emit view->newMarkStatus();
+ }
+ oldMarkState = markState;
+ newDocGeometry = false;
+}
+
+QColor &KateDocument::cursorCol(int x, int y) {
+ int attr;
+ Attribute *a;
+
+ TextLine::Ptr textLine = getTextLine(y);
+ attr = textLine->getRawAttr(x);
+ a = &m_attribs[attr & taAttrMask];
+ if (attr & taSelected) return a->selCol; else return a->col;
+}
+
+void KateDocument::paintTextLine(QPainter &paint, int line, int xStart, int xEnd, bool showTabs)
+{
+ paintTextLine (paint, line, 0, xStart, xEnd, showTabs);
+}
+
+void KateDocument::paintTextLine(QPainter &paint, int line, int y, int xStart, int xEnd, bool showTabs)
+{
+ TextLine::Ptr textLine;
+ int len;
+ const QChar *s;
+ int z, x;
+ QChar ch;
+ Attribute *a = 0L;
+ int attr, nextAttr;
+ int xs;
+ int xc, zc;
+
+ if (line > lastLine()) {
+ paint.fillRect(0, y, xEnd - xStart,fontHeight, colors[0]);
+ return;
+ }
+
+ textLine = getTextLine(line);
+ len = textLine->length();
+ s = textLine->getText();
+
+ // skip to first visible character
+ x = 0;
+ z = 0;
+ do {
+ xc = x;
+ zc = z;
+ if (z == len) break;
+ ch = s[z];//textLine->getChar(z);
+ if (ch == '\t') {
+ x += m_tabWidth - (x % m_tabWidth);
+ } else {
+ a = &m_attribs[textLine->getAttr(z)];
+
+ if (a->bold && a->italic)
+ x += myFontMetricsBI.width(ch);
+ else if (a->bold)
+ x += myFontMetricsBold.width(ch);
+ else if (a->italic)
+ x += myFontMetricsItalic.width(ch);
+ else
+ x += myFontMetrics.width(ch);
+ }
+ z++;
+ } while (x <= xStart);
+
+ // draw background
+ xs = xStart;
+ attr = textLine->getRawAttr(zc);
+ while (x < xEnd)
+ {
+ nextAttr = textLine->getRawAttr(z);
+ if ((nextAttr ^ attr) & taSelected)
+ {
+ if (attr & taSelected)
+ paint.fillRect(xs - xStart, y, x - xs, fontHeight, colors[1]);
+ else
+ paint.fillRect(xs - xStart, y, x - xs, fontHeight, colors[0]);
+
+ xs = x;
+ attr = nextAttr;
+ }
+
+ if (z == len) break;
+
+ ch = s[z];//textLine->getChar(z);
+
+ if (ch == '\t')
+ x += m_tabWidth - (x % m_tabWidth);
+ else
+ {
+ a = &m_attribs[textLine->getAttr(z)];
+
+ if (a->bold && a->italic)
+ x += myFontMetricsBI.width(ch);
+ else if (a->bold)
+ x += myFontMetricsBold.width(ch);
+ else if (a->italic)
+ x += myFontMetricsItalic.width(ch);
+ else
+ x += myFontMetrics.width(ch);
+ }
+ z++;
+ }
+
+ if (attr & taSelected)
+ paint.fillRect(xs - xStart, y, xEnd - xs, fontHeight, colors[1]);
+ else
+ paint.fillRect(xs - xStart, y, xEnd - xs, fontHeight, colors[0]);
+
+ len = z; //reduce length to visible length
+
+ // draw text
+ x = xc;
+ z = zc;
+ y += fontAscent;// -1;
+ attr = -1;
+ while (z < len) {
+ ch = s[z];//textLine->getChar(z);
+ if (ch == '\t') {
+ if (z > zc) {
+ //this should cause no copy at all
+ QConstString str((QChar *) &s[zc], z - zc /*+1*/);
+ QString s = str.string();
+ paint.drawText(x - xStart, y, s);
+
+ if (a->bold && a->italic)
+ x += myFontMetricsBI.width(s);
+ else if (a->bold)
+ x += myFontMetricsBold.width(s);
+ else if (a->italic)
+ x += myFontMetricsItalic.width(s);
+ else
+ x += myFontMetrics.width(s);
+ }
+ zc = z +1;
+
+ if (showTabs) {
+ nextAttr = textLine->getRawAttr(z);
+ if (nextAttr != attr) {
+ attr = nextAttr;
+ a = &m_attribs[attr & taAttrMask];
+
+ if (attr & taSelected) paint.setPen(a->selCol);
+ else paint.setPen(a->col);
+
+ if (a->bold && a->italic)
+ paint.setFont(myFontBI);
+ else if (a->bold)
+ paint.setFont(myFontBold);
+ else if (a->italic)
+ paint.setFont(myFontItalic);
+ else
+ paint.setFont(myFont);
+ }
+
+// paint.drawLine(x - xStart, y -2, x - xStart, y);
+// paint.drawLine(x - xStart, y, x - xStart + 2, y);
+ paint.drawPoint(x - xStart, y);
+ paint.drawPoint(x - xStart +1, y);
+ paint.drawPoint(x - xStart, y -1);
+ }
+ x += m_tabWidth - (x % m_tabWidth);
+ } else {
+ nextAttr = textLine->getRawAttr(z);
+ if (nextAttr != attr) {
+ if (z > zc) {
+ QConstString str((QChar *) &s[zc], z - zc /*+1*/);
+ QString s = str.string();
+ paint.drawText(x - xStart, y, s);
+
+ if (a->bold && a->italic)
+ x += myFontMetricsBI.width(s);
+ else if (a->bold)
+ x += myFontMetricsBold.width(s);
+ else if (a->italic)
+ x += myFontMetricsItalic.width(s);
+ else
+ x += myFontMetrics.width(s);
+ zc = z;
+ }
+ attr = nextAttr;
+ a = &m_attribs[attr & taAttrMask];
+
+ if (attr & taSelected) paint.setPen(a->selCol);
+ else paint.setPen(a->col);
+
+ if (a->bold && a->italic)
+ paint.setFont(myFontBI);
+ else if (a->bold)
+ paint.setFont(myFontBold);
+ else if (a->italic)
+ paint.setFont(myFontItalic);
+ else
+ paint.setFont(myFont);
+ }
+ }
+ z++;
+ }
+ if (z > zc) {
+ QConstString str((QChar *) &s[zc], z - zc /*+1*/);
+ paint.drawText(x - xStart, y, str.string());
+ }
+}
+
+// Applies the search context, and returns whether a match was found. If one is,
+// the length of the string matched is also returned.
+bool KateDocument::doSearch(SConfig &sc, const QString &searchFor) {
+ int line, col;
+ int searchEnd;
+ int bufLen, tlen;
+ QChar *t;
+ TextLine::Ptr textLine;
+ int pos, newPos;
+
+ if (searchFor.isEmpty()) return false;
+
+ bufLen = 0;
+ t = 0L;
+
+ line = sc.cursor.y;
+ col = sc.cursor.x;
+ if (!(sc.flags & KateView::sfBackward)) {
+ //forward search
+ if (sc.flags & KateView::sfSelected) {
+ if (line < selectStart) {
+ line = selectStart;
+ col = 0;
+ }
+ searchEnd = selectEnd;
+ } else searchEnd = lastLine();
+
+ while (line <= searchEnd) {
+ textLine = getTextLine(line);
+ tlen = textLine->length();
+ if (tlen > bufLen) {
+ delete t;
+ bufLen = (tlen + 255) & (~255);
+ t = new QChar[bufLen];
+ }
+ memcpy(t, textLine->getText(), tlen*sizeof(QChar));
+ if (sc.flags & KateView::sfSelected) {
+ pos = 0;
+ do {
+ pos = textLine->findSelected(pos);
+ newPos = textLine->findUnselected(pos);
+ memset(&t[pos], 0, (newPos - pos)*sizeof(QChar));
+ pos = newPos;
+ } while (pos < tlen);
+ }
+
+ QString text(t, tlen);
+ if (sc.flags & KateView::sfWholeWords) {
+ // Until the end of the line...
+ while (col < tlen) {
+ // ...find the next match.
+ col = sc.search(text, col);
+ if (col != -1) {
+ // Is the match delimited correctly?
+ if (((col == 0) || (!m_highlight->isInWord(t[col]))) &&
+ ((col + sc.matchedLength == tlen) || (!m_highlight->isInWord(t[col + sc.matchedLength])))) {
+ goto found;
+ }
+ else {
+ // Start again from the next character.
+ col++;
+ }
+ }
+ else {
+ // No match.
+ break;
+ }
+ }
+ }
+ else {
+ // Non-whole-word search.
+ col = sc.search(text, col);
+ if (col != -1)
+ goto found;
+ }
+ col = 0;
+ line++;
+ }
+ } else {
+ // backward search
+ if (sc.flags & KateView::sfSelected) {
+ if (line > selectEnd) {
+ line = selectEnd;
+ col = -1;
+ }
+ searchEnd = selectStart;
+ } else searchEnd = 0;
+
+ while (line >= searchEnd) {
+ textLine = getTextLine(line);
+ tlen = textLine->length();
+ if (tlen > bufLen) {
+ delete t;
+ bufLen = (tlen + 255) & (~255);
+ t = new QChar[bufLen];
+ }
+ memcpy(t, textLine->getText(), tlen*sizeof(QChar));
+ if (sc.flags & KateView::sfSelected) {
+ pos = 0;
+ do {
+ pos = textLine->findSelected(pos);
+ newPos = textLine->findUnselected(pos);
+ memset(&t[pos], 0, (newPos - pos)*sizeof(QChar));
+ pos = newPos;
+ } while (pos < tlen);
+ }
+
+ if (col < 0 || col > tlen) col = tlen;
+
+ QString text(t, tlen);
+ if (sc.flags & KateView::sfWholeWords) {
+ // Until the beginning of the line...
+ while (col >= 0) {
+ // ...find the next match.
+ col = sc.search(text, col);
+ if (col != -1) {
+ // Is the match delimited correctly?
+ if (((col == 0) || (!m_highlight->isInWord(t[col]))) &&
+ ((col + sc.matchedLength == tlen) || (!m_highlight->isInWord(t[col + sc.matchedLength])))) {
+ goto found;
+ }
+ else {
+ // Start again from the previous character.
+ col--;
+ }
+ }
+ else {
+ // No match.
+ break;
+ }
+ }
+ }
+ else {
+ // Non-whole-word search.
+ col = sc.search(text, col);
+ if (col != -1)
+ goto found;
+ }
+ col = -1;
+ line--;
+ }
+ }
+ sc.flags |= KateView::sfWrapped;
+ return false;
+found:
+ if (sc.flags & KateView::sfWrapped) {
+ if ((line > sc.startCursor.y || (line == sc.startCursor.y && col >= sc.startCursor.x))
+ ^ ((sc.flags & KateView::sfBackward) != 0)) return false;
+ }
+ sc.cursor.x = col;
+ sc.cursor.y = line;
+ return true;
+}
+
+void KateDocument::tagLine(int line) {
+
+ if (tagStart > line) tagStart = line;
+ if (tagEnd < line) tagEnd = line;
+}
+
+void KateDocument::insLine(int line) {
+ KateView *view;
+
+ if (selectStart >= line) selectStart++;
+ if (selectEnd >= line) selectEnd++;
+ if (tagStart >= line) tagStart++;
+ if (tagEnd >= line) tagEnd++;
+
+ newDocGeometry = true;
+ for (view = views.first(); view != 0L; view = views.next() ) {
+ view->insLine(line);
+ }
+}
+
+void KateDocument::delLine(int line) {
+ KateView *view;
+
+ if (selectStart >= line && selectStart > 0) selectStart--;
+ if (selectEnd >= line) selectEnd--;
+ if (tagStart >= line && tagStart > 0) tagStart--;
+ if (tagEnd >= line) tagEnd--;
+
+ newDocGeometry = true;
+ for (view = views.first(); view != 0L; view = views.next() ) {
+ view->delLine(line);
+ }
+}
+
+void KateDocument::optimizeSelection() {
+ TextLine::Ptr textLine;
+
+ while (selectStart <= selectEnd) {
+ textLine = getTextLine(selectStart);
+ if (textLine->isSelected() || textLine->numSelected() > 0) break;
+ selectStart++;
+ }
+ while (selectEnd >= selectStart) {
+ textLine = getTextLine(selectEnd);
+ if (textLine->isSelected() || textLine->numSelected() > 0) break;
+ selectEnd--;
+ }
+ if (selectStart > selectEnd) {
+ selectStart = 0xffffff;
+ selectEnd = 0;
+ }
+}
+
+void KateDocument::doAction(KateAction *a) {
+
+ switch (a->action) {
+ case KateAction::replace:
+ doReplace(a);
+ break;
+ case KateAction::wordWrap:
+ doWordWrap(a);
+ break;
+ case KateAction::wordUnWrap:
+ doWordUnWrap(a);
+ break;
+ case KateAction::newLine:
+ doNewLine(a);
+ break;
+ case KateAction::delLine:
+ doDelLine(a);
+ break;
+ case KateAction::insLine:
+ doInsLine(a);
+ break;
+ case KateAction::killLine:
+ doKillLine(a);
+ break;
+/* case KateAction::doubleLine:
+ break;
+ case KateAction::removeLine:
+ break;*/
+ }
+}
+
+void KateDocument::doReplace(KateAction *a) {
+ TextLine::Ptr textLine;
+ int l;
+
+ //exchange current text with stored text in KateAction *a
+
+ textLine = getTextLine(a->cursor.y);
+ l = textLine->length() - a->cursor.x;
+ if (l > a->len) l = a->len;
+
+ QString oldText(&textLine->getText()[a->cursor.x], (l < 0) ? 0 : l);
+ textLine->replace(a->cursor.x, a->len, a->text.unicode(), a->text.length());
+
+ a->len = a->text.length();
+ a->text = oldText;
+
+ buffer->changeLine(a->cursor.y);
+
+ tagLine(a->cursor.y);
+}
+
+void KateDocument::doWordWrap(KateAction *a) {
+ TextLine::Ptr textLine;
+
+ textLine = getTextLine(a->cursor.y - 1);
+ a->len = textLine->length() - a->cursor.x;
+ textLine->wrap(getTextLine(a->cursor.y),a->len);
+
+ buffer->changeLine(a->cursor.y - 1);
+ buffer->changeLine(a->cursor.y);
+
+ tagLine(a->cursor.y - 1);
+ tagLine(a->cursor.y);
+ if (selectEnd == a->cursor.y - 1) selectEnd++;
+
+ a->action = KateAction::wordUnWrap;
+}
+
+void KateDocument::doWordUnWrap(KateAction *a) {
+ TextLine::Ptr textLine;
+
+ textLine = getTextLine(a->cursor.y - 1);
+// textLine->setLength(a->len);
+ textLine->unWrap(a->len, getTextLine(a->cursor.y),a->cursor.x);
+
+ buffer->changeLine(a->cursor.y - 1);
+ buffer->changeLine(a->cursor.y);
+
+ tagLine(a->cursor.y - 1);
+ tagLine(a->cursor.y);
+
+ a->action = KateAction::wordWrap;
+}
+
+void KateDocument::doNewLine(KateAction *a) {
+ TextLine::Ptr textLine, newLine;
+
+ textLine = getTextLine(a->cursor.y);
+ newLine = new TextLine(textLine->getRawAttr(), textLine->getContext());
+ textLine->wrap(newLine,a->cursor.x);
+
+ buffer->insertLine(a->cursor.y + 1, newLine);
+ buffer->changeLine(a->cursor.y);
+
+ insLine(a->cursor.y + 1);
+ tagLine(a->cursor.y);
+ tagLine(a->cursor.y + 1);
+ if (selectEnd == a->cursor.y) selectEnd++;//addSelection(a->cursor.y + 1);
+
+ a->action = KateAction::delLine;
+}
+
+void KateDocument::doDelLine(KateAction *a) {
+ TextLine::Ptr textLine, nextLine;
+
+ textLine = getTextLine(a->cursor.y);
+ nextLine = getTextLine(a->cursor.y+1);
+// textLine->setLength(a->cursor.x);
+ textLine->unWrap(a->cursor.x, nextLine,nextLine->length());
+ textLine->setContext(nextLine->getContext());
+ if (longestLine == nextLine) longestLine = 0L;
+
+ buffer->changeLine(a->cursor.y);
+ buffer->removeLine(a->cursor.y+1);
+
+ tagLine(a->cursor.y);
+ delLine(a->cursor.y + 1);
+
+ a->action = KateAction::newLine;
+}
+
+void KateDocument::doInsLine(KateAction *a) {
+
+ buffer->insertLine(a->cursor.y, new TextLine());
+
+ insLine(a->cursor.y);
+
+ a->action = KateAction::killLine;
+}
+
+void KateDocument::doKillLine(KateAction *a) {
+ TextLine::Ptr textLine = getTextLine(a->cursor.y);
+ if (longestLine == textLine) longestLine = 0L;
+
+ buffer->removeLine(a->cursor.y);
+
+ delLine(a->cursor.y);
+ tagLine(a->cursor.y);
+
+ a->action = KateAction::insLine;
+}
+
+void KateDocument::newUndo() {
+ KTextEditor::View *view;
+ int state;
+
+ state = 0;
+ if (currentUndo > 0) state |= 1;
+ if (currentUndo < (int) undoList.count()) state |= 2;
+ undoState = state;
+ for (view = m_views.first(); view != 0L; view = m_views.next() ) {
+ emit static_cast<KateView *>( view )->newUndo();
+ }
+}
+
+void KateDocument::recordStart(VConfig &c, int newUndoType) {
+ recordStart(c.view, c.cursor, c.flags, newUndoType);
+}
+
+void KateDocument::recordStart(KateView *, PointStruc &cursor, int flags,
+ int newUndoType, bool keepModal, bool mergeUndo) {
+
+ KateActionGroup *g;
+
+// if (newUndoType == KateActionGroup::ugNone) {
+ // only a bug would cause this
+//why should someone do this? we can't prevent all programming errors :) (jochen whilhelmy)
+// debug("KateDocument::recordStart() called with no undo group type!");
+// return;
+// }
+
+ if (!keepModal) setPseudoModal(0L);
+
+ //i optimized the group undo stuff a bit (jochen wilhelmy)
+ // recordReset() is not needed any more
+ g = undoList.getLast();
+ if (g != 0L && ((undoCount < 1024 && flags & KateView::cfGroupUndo
+ && g->end.x == cursor.x && g->end.y == cursor.y) || mergeUndo)) {
+
+ //undo grouping : same actions are put into one undo step
+ //precondition : new action starts where old stops or mergeUndo flag
+ if (g->undoType == newUndoType
+ || (g->undoType == KateActionGroup::ugInsChar
+ && newUndoType == KateActionGroup::ugInsLine)
+ || (g->undoType == KateActionGroup::ugDelChar
+ && newUndoType == KateActionGroup::ugDelLine)) {
+
+ undoCount++;
+ if (g->undoType != newUndoType) undoCount = 0xffffff;
+ return;
+ }
+ }
+ undoCount = 0;
+/*
+ if (undoView != view) {
+ // always kill the current undo group if the editing view changes
+ recordReset();
+ undoType = newUndoType;
+ } else if (newUndoType == undoType) {
+printf("bla!!!\n");
+ // same as current type, keep using it
+ return;
+ } else if ( (undoType == KateActionGroup::ugInsChar && newUndoType == KateActionGroup::ugInsLine) ||
+ (undoType == KateActionGroup::ugDelChar && newUndoType == KateActionGroup::ugDelLine) ) {
+ // some type combinations can run together...
+ undoType += 1000;
+ return;
+ } else {
+ recordReset();
+ undoType = newUndoType;
+ }
+
+ undoView = view;
+*/
+ while ((int) undoList.count() > currentUndo) undoList.removeLast();
+ while ((int) undoList.count() > undoSteps) {
+ undoList.removeFirst();
+ currentUndo--;
+ }
+
+ g = new KateActionGroup(cursor, newUndoType);
+ undoList.append(g);
+// currentUndo++;
+
+ tagEnd = 0;
+ tagStart = 0xffffff;
+}
+
+void KateDocument::recordAction(KateAction::Action action, PointStruc &cursor) {
+ KateAction *a;
+
+ a = new KateAction(action, cursor);
+ doAction(a);
+ undoList.getLast()->insertAction(a);
+}
+
+void KateDocument::recordInsert(VConfig &c, const QString &text) {
+ recordReplace(c, 0, text);
+}
+
+void KateDocument::recordReplace(VConfig &c, int len, const QString &text) {
+ if (c.cursor.x > 0 && !(c.flags & KateView::cfSpaceIndent)) {
+ TextLine::Ptr textLine = getTextLine(c.cursor.y);
+ if (textLine->length() == 0) {
+ QString s = tabString(c.cursor.x, tabChars);
+ int len = s.length();
+ s += text;
+ c.cursor.x = 0;
+ recordReplace(c.cursor, len, s);
+ c.cursor.x = len;
+ return;
+ }
+ }
+ recordReplace(c.cursor, len, text);
+}
+
+void KateDocument::recordInsert(PointStruc &cursor, const QString &text) {
+ recordReplace(cursor, 0, text);
+}
+
+void KateDocument::recordDelete(PointStruc &cursor, int len) {
+ recordReplace(cursor, len, QString::null);
+}
+
+void KateDocument::recordReplace(PointStruc &cursor, int len, const QString &text) {
+ KateAction *a;
+ TextLine::Ptr textLine;
+ int l;
+
+ if (len == 0 && text.isEmpty()) return;
+
+ //try to append to last replace action
+ a = undoList.getLast()->action;
+ if (a == 0L || a->action != KateAction::replace
+ || a->cursor.x + a->len != cursor.x || a->cursor.y != cursor.y) {
+
+//if (a != 0L) printf("new %d %d\n", a->cursor.x + a->len, cursor.x);
+ a = new KateAction(KateAction::replace, cursor);
+ undoList.getLast()->insertAction(a);
+ }
+
+ //replace
+ textLine = getTextLine(cursor.y);
+ l = textLine->length() - cursor.x;
+ if (l > len) l = len;
+ a->text.insert(a->text.length(), &textLine->getText()[cursor.x], (l < 0) ? 0 : l);
+ textLine->replace(cursor.x, len, text.unicode(), text.length());
+ a->len += text.length();
+
+ buffer->changeLine(a->cursor.y);
+ updateMaxLength(textLine);
+ tagLine(a->cursor.y);
+}
+
+void KateDocument::recordEnd(VConfig &c) {
+ recordEnd(c.view, c.cursor, c.flags);
+}
+
+void KateDocument::recordEnd(KateView *view, PointStruc &cursor, int flags) {
+ KateActionGroup *g;
+
+ // clear selection if option "persistent selections" is off
+// if (!(flags & cfPersistent)) deselectAll();
+
+ g = undoList.getLast();
+ if (g->action == 0L) {
+ // no action has been done: remove empty undo record
+ undoList.removeLast();
+ return;
+ }
+ // store end cursor position for redo
+ g->end = cursor;
+ currentUndo = undoList.count();
+
+ if (tagStart <= tagEnd) {
+ optimizeSelection();
+ updateLines(tagStart, tagEnd, flags, cursor.y);
+ setModified(true);
+ }
+
+ view->updateCursor(cursor, flags);
+
+// newUndo();
+/*
+ undoCount++;
+ // we limit the number of individual undo operations for sanity - is 1K reasonable?
+ // this is also where we handle non-group undo preference
+ // if the undo type is singlular, we always finish it now
+ if ( undoType == KateActionGroup::ugPaste ||
+ undoType == KateActionGroup::ugDelBlock ||
+ undoType > 1000 ||
+ undoCount > 1024 || !(flags & cfGroupUndo) ) {
+printf("recordend %d %d\n", undoType, undoCount);
+ recordReset();
+ }
+*/
+
+ // this should keep the flood of signals down a little...
+ if (undoCount == 0) newUndo();
+ emit textChanged();
+}
+/*
+void KateDocument::recordReset()
+{
+ if (pseudoModal)
+ return;
+
+ // forces the next call of recordStart() to begin a new undo group
+ // not used in normal editing, but used by markFound(), etc.
+ undoType = KateActionGroup::ugNone;
+ undoCount = 0;
+ undoView = NULL;
+ undoReported = false;
+printf("recordreset\n");
+}
+*/
+
+/*
+void KateDocument::recordDel(PointStruc &cursor, TextLine::Ptr &textLine, int l) {
+ int len;
+
+ len = textLine->length() - cursor.x;
+ if (len > l) len = l;
+ if (len > 0) {
+ insertUndo(new KateAction(KateAction::replace,cursor,&textLine->getText()[cursor.x],len));
+ }
+}
+*/
+
+
+void KateDocument::doActionGroup(KateActionGroup *g, int flags, bool undo) {
+ KateAction *a, *next;
+
+ setPseudoModal(0L);
+ if (!(flags & KateView::cfPersistent)) deselectAll();
+ tagEnd = 0;
+ tagStart = 0xffffff;
+
+ a = g->action;
+ g->action = 0L;
+ while (a) {
+ doAction(a);
+ next = a->next;
+ g->insertAction(a);
+ a = next;
+ }
+ optimizeSelection();
+ if (tagStart <= tagEnd) updateLines(tagStart, tagEnd, flags);
+
+ // the undo/redo functions set undo to true, all others should leave it
+ // alone (default)
+ if (!undo) {
+ setModified(true);
+ newUndo();
+ }
+}
+
+int KateDocument::nextUndoType()
+{
+ KateActionGroup *g;
+
+ if (currentUndo <= 0) return KateActionGroup::ugNone;
+ g = undoList.at(currentUndo - 1);
+ return g->undoType;
+}
+
+int KateDocument::nextRedoType()
+{
+ KateActionGroup *g;
+
+ if (currentUndo >= (int) undoList.count()) return KateActionGroup::ugNone;
+ g = undoList.at(currentUndo);
+// if (!g) return KateActionGroup::ugNone;
+ return g->undoType;
+}
+
+void KateDocument::undoTypeList(QValueList<int> &lst)
+{
+ lst.clear();
+ for (int i = currentUndo-1; i>=0 ;i--)
+ lst.append(undoList.at(i)->undoType);
+}
+
+void KateDocument::redoTypeList(QValueList<int> &lst)
+{
+ lst.clear();
+ for (int i = currentUndo+1; i<(int)undoList.count(); i++)
+ lst.append(undoList.at(i)->undoType);
+}
+
+void KateDocument::undo(VConfig &c, int count) {
+ KateActionGroup *g = 0L;
+ int num;
+ bool needUpdate = false; // don't update the cursor until completely done
+
+ if (count <= 0) return;
+
+ for (num = 0 ; num < count ; num++) {
+ if (currentUndo <= 0) break;
+ currentUndo--;
+ g = undoList.at(currentUndo);
+ doActionGroup(g, c.flags, true); // do not setModified() or newUndo()
+ needUpdate = true;
+
+// if (num == 0) recordReset();
+ }
+
+ if (needUpdate) {
+ // since we told doActionGroup() not to do this stuff, we need to do it now
+ c.view->updateCursor(g->start);
+ setModified(true);
+ newUndo();
+ }
+}
+
+void KateDocument::redo(VConfig &c, int count) {
+ KateActionGroup *g = 0L;
+ int num;
+ bool needUpdate = false; // don't update the cursor until completely done
+
+ if (count <= 0) return;
+
+ for (num = 0 ; num < count ; num++) {
+ if (currentUndo+1 > (int)undoList.count()) break;
+ g = undoList.at(currentUndo);
+ currentUndo++;
+ doActionGroup(g, c.flags, true); // do not setModified() or newUndo()
+ needUpdate = true;
+
+// if (num == 0) recordReset();
+ }
+
+ if (needUpdate) {
+ // since we told doActionGroup() not to do this stuff, we need to do it now
+ c.view->updateCursor(g->end);
+ setModified(true);
+ newUndo();
+ }
+}
+
+void KateDocument::clearRedo() {
+ // disable redos
+ // this was added as an assist to the spell checker
+ bool deleted = false;
+
+ while ((int) undoList.count() > currentUndo) {
+ deleted = true;
+ undoList.removeLast();
+ }
+
+ if (deleted) newUndo();
+}
+
+void KateDocument::setUndoSteps(int steps) {
+ if (steps < 5) steps = 5;
+ undoSteps = steps;
+}
+
+void KateDocument::setPseudoModal(QWidget *w) {
+// QWidget *old = pseudoModal;
+
+ // (glenebob)
+ // this is a temporary hack to make the spell checker work a little
+ // better - as kspell progresses, this sort of thing should become
+ // obsolete or worked around more cleanly
+ // this is relied upon *only* by the spell-check code
+ if (pseudoModal && pseudoModal != (QWidget*)1L)
+ delete pseudoModal;
+
+// pseudoModal = 0L;
+// if (old || w) recordReset();
+
+ pseudoModal = w;
+}
+
+
+void KateDocument::newBracketMark(PointStruc &cursor, BracketMark &bm)
+{
+ TextLine::Ptr textLine;
+ int x, line, count, attr;
+ QChar bracket, opposite, ch;
+ Attribute *a;
+
+ bm.eXPos = -1; //mark bracked mark as invalid
+ x = cursor.x -1; // -1 to look at left side of cursor
+ if (x < 0) return;
+ line = cursor.y; //current line
+ count = 0; //bracket counter for nested brackets
+
+ textLine = getTextLine(line);
+ if (!textLine) return;
+
+ bracket = textLine->getChar(x);
+ attr = textLine->getAttr(x);
+
+ if (bracket == '(' || bracket == '[' || bracket == '{')
+ {
+ //get opposite bracket
+ opposite = ')';
+ if (bracket == '[') opposite = ']';
+ if (bracket == '{') opposite = '}';
+ //get attribute of bracket (opposite bracket must have the same attribute)
+ x++;
+ while (line - cursor.y < 40) {
+ //go to next line on end of line
+ while (x >= (int) textLine->length()) {
+ line++;
+ if (line > lastLine()) return;
+ textLine = getTextLine(line);
+ x = 0;
+ }
+ if (textLine->getAttr(x) == attr) {
+ //try to find opposite bracked
+ ch = textLine->getChar(x);
+ if (ch == bracket) count++; //same bracket : increase counter
+ if (ch == opposite) {
+ count--;
+ if (count < 0) goto found;
+ }
+ }
+ x++;
+ }
+ }
+ else if (bracket == ')' || bracket == ']' || bracket == '}')
+ {
+ opposite = '(';
+ if (bracket == ']') opposite = '[';
+ if (bracket == '}') opposite = '{';
+ x--;
+ while (cursor.y - line < 20) {
+
+ while (x < 0) {
+ line--;
+ if (line < 0) return;
+ textLine = getTextLine(line);
+ x = textLine->length() -1;
+ }
+ if (textLine->getAttr(x) == attr) {
+ ch = textLine->getChar(x);
+ if (ch == bracket) count++;
+ if (ch == opposite) {
+ count--;
+ if (count < 0) goto found;
+ }
+ }
+ x--;
+ }
+ }
+ return;
+
+found:
+ //cursor position of opposite bracket
+ bm.cursor.x = x;
+ bm.cursor.y = line;
+ //x position (start and end) of related bracket
+ bm.sXPos = textWidth(textLine, x);
+ a = &m_attribs[attr];
+
+ if (a->bold && a->italic)
+ bm.eXPos = bm.sXPos + myFontMetricsBI.width(bracket);
+ else if (a->bold)
+ bm.eXPos = bm.sXPos + myFontMetricsBold.width(bracket);
+ else if (a->italic)
+ bm.eXPos = bm.sXPos + myFontMetricsItalic.width(bracket);
+ else
+ bm.eXPos = bm.sXPos + myFontMetrics.width(bracket);
+}
+
+void KateDocument::clipboardChanged() { //slot
+//#if defined(_WS_X11_)
+ if (m_singleSelection) {
+ disconnect(QApplication::clipboard(), SIGNAL(dataChanged()),
+ this, SLOT(clipboardChanged()));
+ deselectAll();
+ updateViews();
+ }
+//#endif
+}
+
+#if 0
+void KateDocument::guiActivateEvent( KParts::GUIActivateEvent *ev )
+{
+ KParts::ReadWritePart::guiActivateEvent( ev );
+ if ( ev->activated() )
+ emit selectionChanged();
+}
+#endif
+
+void KateDocument::setDocName (QString docName)
+{
+ myDocName = docName;
+ emit nameChanged (this);
+}
+
+void KateDocument::setMTime()
+{
+ if (fileInfo && !fileInfo->fileName().isEmpty()) {
+ fileInfo->refresh();
+ mTime = fileInfo->lastModified();
+ }
+}
+
+void KateDocument::isModOnHD(bool forceReload)
+{
+ if (fileInfo && !fileInfo->fileName().isEmpty()) {
+ fileInfo->refresh();
+ if (fileInfo->lastModified() > mTime) {
+ if ( forceReload ||
+ (KMessageBox::warningContinueCancel(0,
+ (i18n("The file %1 has changed on disk.\nDo you want to reload it?\n\nIf you cancel you will lose these changes next time you save this file")).arg(m_url),
+ i18n("File has changed on Disk"),
+ i18n("Yes") ) == KMessageBox::Continue)
+ )
+ reloadFile();
+ else
+ setMTime();
+ }
+ }
+}
+
+void KateDocument::reloadFile()
+{
+#warning fixme
+#if 0
+ if (fileInfo && !fileInfo->fileName().isEmpty()) {
+ KateDocument::openFile();
+ setMTime();
+ }
+#endif
+}
+
+void KateDocument::slotModChanged()
+{
+ emit modStateChanged (this);
+}
+
+QList<Kate::Mark> KateDocument::marks ()
+{
+ QList<Kate::Mark> list;
+ TextLine::Ptr line;
+
+ for (int i=0; i < numLines(); i++)
+ {
+ line = getTextLine(i);
+ if (line->mark() != 0)
+ {
+ Kate::Mark *mark=new Kate::Mark;
+ mark->line = i;
+ mark->type = line->mark();
+ list.append (mark);
+ }
+ }
+
+ return list;
+}
+
+void KateDocument::flush ()
+{
+ if (isReadOnly())
+ return;
+
+ m_url = QString::null;
+ fileInfo->setFile (QString());
+ setMTime();
+
+ clear();
+ updateViews();
+
+ emit fileNameChanged ();
+}
+
+void KateDocument::open (const QString &name)
+{
+ openURL (name);
+}
+
+void KateDocument::wrapText (uint col)
+{
+ int line = 0;
+ int z = 0;
+
+ while(true)
+ {
+ TextLine::Ptr l = getTextLine(line);
+
+ if (l->length() > col)
+ {
+ TextLine::Ptr tl = new TextLine();
+ buffer->insertLine(line+1,tl);
+ const QChar *text = l->getText();
+
+ for (z=col; z>0; z--)
+ {
+ if (z < 1) break;
+ if (text[z].isSpace()) break;
+ }
+
+ if (z < 1) z=col;
+
+ l->wrap (tl, z);
+ }
+
+ line++;
+ if (line >= numLines()) break;
+ };
+
+ newDocGeometry=true;
+ updateLines();
+ updateViews();
+}
+
+void KateDocument::setWordWrap (bool on)
+{
+ if (on != myWordWrap && on)
+ wrapText (myWordWrapAt);
+
+ myWordWrap = on;
+}
+
+void KateDocument::setWordWrapAt (uint col)
+{
+ if (myWordWrapAt != col && myWordWrap)
+ wrapText (myWordWrapAt);
+
+ myWordWrapAt = col;
+}
+
+void KateDocument::applyWordWrap ()
+{
+ wrapText (myWordWrapAt);
+}
diff --git a/noncore/apps/tinykate/libkate/document/katedocument.h b/noncore/apps/tinykate/libkate/document/katedocument.h
new file mode 100644
index 0000000..220d188
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katedocument.h
@@ -0,0 +1,569 @@
+/***************************************************************************
+ katedocument.h - description
+ -------------------
+ begin : Mon Jan 15 2001
+ copyright : (C) 2001 by Christoph "Crossfire" Cullmann
+ (C) 2002 by Joseph Wenninger
+ email : crossfire@babylon2k.de
+ jowenn@kde.org
+
+***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+/*
+ Copyright (C) 1998, 1999 Jochen Wilhelmy
+ digisnap@cs.tu-berlin.de
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef kate_document_h
+#define kate_document_h
+
+
+#include <qobject.h>
+#include <qlist.h>
+#include <qcolor.h>
+#include <qfont.h>
+#include <qfontmetrics.h>
+#include <qdatetime.h>
+#include <qfileinfo.h>
+
+#include "../view/kateview.h"
+#include "katehighlight.h"
+#include "katebuffer.h"
+#include "katetextline.h"
+
+
+#include <qptrdict.h>
+
+class KateCmd;
+
+class CachedFontMetrics : public QFontMetrics {
+private:
+ short *warray[256];
+public:
+ CachedFontMetrics(const QFont& f) : QFontMetrics(f) {
+ for (int i=0; i<256; i++) warray[i]=0;
+ }
+ ~CachedFontMetrics() {
+ for (int i=0; i<256; i++)
+ if (warray[i]) delete[] warray[i];
+ }
+ int width(QChar c) {
+ uchar cell=c.cell();
+ uchar row=c.row();
+ short *wa=warray[row];
+ if (!wa) {
+ // qDebug("create row: %d",row);
+ wa=warray[row]=new short[256];
+ for (int i=0; i<256; i++) wa[i]=-1;
+ }
+ if (wa[cell]<0) wa[cell]=(short) QFontMetrics::width(c);
+ return (int)wa[cell];
+ }
+ int width(QString s) { return QFontMetrics::width(s); }
+};
+
+class Attribute {
+ public:
+ Attribute() { ; };
+
+ QColor col;
+ QColor selCol;
+ bool bold;
+ bool italic;
+};
+
+class KateAction {
+ public:
+ enum Action {replace, wordWrap, wordUnWrap, newLine, delLine,
+ insLine, killLine};//, doubleLine, removeLine};
+
+ KateAction(Action, PointStruc &cursor, int len = 0,
+ const QString &text = QString::null);
+
+ Action action;
+ PointStruc cursor;
+ int len;
+ QString text;
+ KateAction *next;
+};
+
+class KateActionGroup {
+ public:
+ // the undo group types
+ enum { ugNone, //
+ ugPaste, // paste
+ ugDelBlock, // delete/replace selected text
+ ugIndent, // indent
+ ugUnindent, // unindent
+ ugComment, // comment
+ ugUncomment, // uncomment
+ ugReplace, // text search/replace
+ ugSpell, // spell check
+ ugInsChar, // char type/deleting
+ ugDelChar, // '' ''
+ ugInsLine, // line insert/delete
+ ugDelLine // '' ''
+ };
+
+ KateActionGroup(PointStruc &aStart, int type = ugNone);
+ ~KateActionGroup();
+ void insertAction(KateAction *);
+
+ static const char * typeName(int type);
+
+ PointStruc start;
+ PointStruc end;
+ KateAction *action;
+ int undoType;
+};
+
+/**
+ The text document. It contains the textlines, controls the
+ document changing operations and does undo/redo. WARNING: do not change
+ the text contents directly in methods where this is not explicitly
+ permitted. All changes have to be made with some basic operations,
+ which are recorded by the undo/redo system.
+ @see TextLine
+ @author Jochen Wilhelmy
+*/
+class KateDocument: public Kate::Document
+{
+ Q_OBJECT
+ friend class KateViewInternal;
+ friend class KateView;
+ friend class KateIconBorder;
+
+ public:
+ KateDocument(bool bSingleViewMode=false, bool bBrowserView=false, QWidget *parentWidget = 0, const char *widgetName = 0, QObject * = 0, const char * = 0);
+ ~KateDocument();
+
+ protected:
+ QFont myFont, myFontBold, myFontItalic, myFontBI;
+ CachedFontMetrics myFontMetrics, myFontMetricsBold, myFontMetricsItalic, myFontMetricsBI;
+
+ public:
+ void setFont (QFont font);
+ QFont getFont () { return myFont; };
+ CachedFontMetrics getFontMetrics () { return myFontMetrics; };
+
+ virtual bool saveFile();
+
+ virtual KTextEditor::View *createView( QWidget *parent, const char *name );
+ virtual QString textLine( int line ) const;
+
+ virtual void insertLine( const QString &s, int line = -1 );
+
+ void insert_Line(const QString& s,int line=-1, bool update=true);
+ void remove_Line(int line,bool update=true);
+ void replaceLine(const QString& s,int line=-1);
+ virtual void insertAt( const QString &s, int line, int col, bool mark = FALSE );
+ virtual void removeLine( int line );
+ virtual int length() const;
+
+ virtual void setSelection( int row_from, int col_from, int row_to, int col_t );
+ virtual bool hasSelection() const;
+ virtual QString selection() const;
+
+ // only to make part work, don't change it !
+ bool m_bSingleViewMode;
+
+// public interface
+ /**
+ * gets the number of lines
+ */
+ virtual int numLines() const;
+
+ /**
+ * gets the last line number (numLines() -1)
+ */
+ int lastLine() const {return numLines()-1;}
+
+ /**
+ gets the given line
+ @return the TextLine object at the given line
+ @see TextLine
+ */
+ TextLine::Ptr getTextLine(int line) const;
+
+ /**
+ get the length in pixels of the given line
+ */
+ int textLength(int line);
+
+ void setTabWidth(int);
+ int tabWidth() {return tabChars;}
+ void setReadOnly(bool);
+ bool isReadOnly() const;
+ void setNewDoc( bool );
+ bool isNewDoc() const;
+ virtual void setReadWrite( bool ){};
+ virtual bool isReadWrite() const {return true;}
+ virtual void setModified(bool);
+ virtual bool isModified() const;
+ void setSingleSelection(bool ss) {m_singleSelection = ss;}
+ bool singleSelection() {return m_singleSelection;}
+
+ void readConfig();
+ void writeConfig();
+ void readSessionConfig(KConfig *);
+ void writeSessionConfig(KConfig *);
+
+ bool hasBrowserExtension() const { return m_bBrowserView; }
+
+ protected:
+ bool m_bBrowserView;
+
+ signals:
+ void selectionChanged();
+ void highlightChanged();
+ void modifiedChanged ();
+ void preHighlightChanged(long);
+
+ // search stuff
+ protected:
+ static QStringList searchForList;
+ static QStringList replaceWithList;
+ static uint uniqueID;
+
+ // highlight stuff
+ public:
+ Highlight *highlight() {return m_highlight;}
+ int highlightNum() {return hlManager->findHl(m_highlight);}
+ int numAttribs() {return m_numAttribs;}
+ Attribute *attribs() {return m_attribs;}
+ void setDontChangeHlOnSave();
+
+ protected:
+ void setHighlight(int n);
+ void makeAttribs();
+ void updateFontData();
+
+ protected slots:
+ void hlChanged();
+
+// view interaction
+ public:
+ virtual void addView(KTextEditor::View *);
+ virtual void removeView(KTextEditor::View *);
+ bool ownedView(KateView *);
+ bool isLastView(int numViews);
+
+ int getTextLineCount() {return numLines();}
+
+ int textWidth(const TextLine::Ptr &, int cursorX);
+ int textWidth(PointStruc &cursor);
+ int textWidth(bool wrapCursor, PointStruc &cursor, int xPos);
+ int textPos(const TextLine::Ptr &, int xPos);
+// int textPos(TextLine::Ptr &, int xPos, int &newXPos);
+ int textWidth();
+ int textHeight();
+
+ void insert(VConfig &, const QString &);
+ void insertFile(VConfig &, QIODevice &);
+
+ int currentColumn(PointStruc &cursor);
+ bool insertChars(VConfig &, const QString &chars);
+ void newLine(VConfig &);
+ void killLine(VConfig &);
+ void backspace(VConfig &);
+ void del(VConfig &);
+ void clear();
+ void cut(VConfig &);
+ void copy(int flags);
+ void paste(VConfig &);
+
+ void toggleRect(int, int, int, int);
+ void selectTo(VConfig &c, PointStruc &cursor, int cXPos);
+ void selectAll();
+ void deselectAll();
+ void invertSelection();
+ void selectWord(PointStruc &cursor, int flags);
+ void selectLength(PointStruc &cursor, int length, int flags);
+
+ void indent(VConfig &c) {doIndent(c, 1);}
+ void unIndent(VConfig &c) {doIndent(c, -1);}
+ void cleanIndent(VConfig &c) {doIndent(c, 0);}
+ // called by indent/unIndent/cleanIndent
+ // just does some setup and then calls optimizeLeadingSpace()
+ void doIndent(VConfig &, int change);
+ // optimize leading whitespace on a single line - see kwdoc.cpp for full description
+ void optimizeLeadingSpace(int line, int flags, int change);
+
+ void comment(VConfig &c) {doComment(c, 1);}
+ void unComment(VConfig &c) {doComment(c, -1);}
+ void doComment(VConfig &, int change);
+
+ virtual QString text() const;
+ QString getWord(PointStruc &cursor);
+
+ public slots:
+ virtual void setText(const QString &);
+
+ public:
+ long needPreHighlight(long till);
+ bool hasMarkedText() {return (selectEnd >= selectStart);}
+ QString markedText(int flags);
+ void delMarkedText(VConfig &/*, bool undo = true*/);
+
+ void tagLineRange(int line, int x1, int x2);
+ void tagLines(int start, int end);
+ void tagAll();
+ void updateLines(int startLine = 0, int endLine = 0xffffff, int flags = 0, int cursorY = -1);
+ void updateMaxLength(TextLine::Ptr &);
+ void updateViews(KateView *exclude = 0L);
+
+ QColor &cursorCol(int x, int y);
+ void paintTextLine(QPainter &, int line, int xStart, int xEnd, bool showTabs);
+ void paintTextLine(QPainter &, int line, int y, int xStart, int xEnd, bool showTabs);
+
+ bool doSearch(SConfig &s, const QString &searchFor);
+
+// internal
+ void tagLine(int line);
+ void insLine(int line);
+ void delLine(int line);
+ void optimizeSelection();
+
+ void doAction(KateAction *);
+ void doReplace(KateAction *);
+ void doWordWrap(KateAction *);
+ void doWordUnWrap(KateAction *);
+ void doNewLine(KateAction *);
+ void doDelLine(KateAction *);
+ void doInsLine(KateAction *);
+ void doKillLine(KateAction *);
+ void newUndo();
+
+ void recordStart(VConfig &, int newUndoType);
+ void recordStart(KateView *, PointStruc &, int flags, int newUndoType, bool keepModal = false, bool mergeUndo = false);
+ void recordAction(KateAction::Action, PointStruc &);
+ void recordInsert(VConfig &, const QString &text);
+ void recordReplace(VConfig &, int len, const QString &text);
+ void recordInsert(PointStruc &, const QString &text);
+ void recordDelete(PointStruc &, int len);
+ void recordReplace(PointStruc &, int len, const QString &text);
+ void recordEnd(VConfig &);
+ void recordEnd(KateView *, PointStruc &, int flags);
+ void doActionGroup(KateActionGroup *, int flags, bool undo = false);
+
+ int nextUndoType();
+ int nextRedoType();
+ void undoTypeList(QValueList<int> &lst);
+ void redoTypeList(QValueList<int> &lst);
+ void undo(VConfig &, int count = 1);
+ void redo(VConfig &, int count = 1);
+ void clearRedo();
+ void setUndoSteps(int steps);
+
+ void setPseudoModal(QWidget *);
+
+ void newBracketMark(PointStruc &, BracketMark &);
+
+
+ protected slots:
+ void clipboardChanged();
+ void slotBufferChanged();
+ void slotBufferHighlight(long,long);
+ void doPreHighlight();
+
+ private slots:
+ void slotViewDestroyed();
+
+// member variables
+ protected:
+ long PreHighlightedTill;
+ long RequestPreHighlightTill;
+ KWBuffer *buffer;
+ QColor colors[2];
+ HlManager *hlManager;
+ Highlight *m_highlight;
+ int m_numAttribs;
+ static const int maxAttribs;
+ Attribute *m_attribs;
+
+ int eolMode;
+
+ int tabChars;
+ int m_tabWidth;
+ int fontHeight;
+ int fontAscent;
+
+ QList<KateView> views;
+ bool newDocGeometry;
+
+ TextLine::Ptr longestLine;
+ float maxLength;
+
+ PointStruc select;
+ PointStruc anchor;
+ int aXPos;
+ int selectStart;
+ int selectEnd;
+ bool oldMarkState;
+ bool m_singleSelection; // false: windows-like, true: X11-like
+
+ bool readOnly;
+ bool newDoc; // True if the file is a new document (used to determine whether
+ // to check for overwriting files on save)
+ bool modified;
+
+ bool myWordWrap;
+ uint myWordWrapAt;
+
+ QList<KateActionGroup> undoList;
+ int currentUndo;
+ int undoState;
+ int undoSteps;
+ int tagStart;
+ int tagEnd;
+ int undoCount; //counts merged undo steps
+
+ QWidget *pseudoModal; //the replace prompt is pseudo modal
+
+ public:
+ /** Tjecks if the file on disk is newer than document contents.
+ If forceReload is true, the document is reloaded without asking the user,
+ otherwise [default] the user is asked what to do. */
+ void isModOnHD(bool forceReload=false);
+
+ uint docID () {return myDocID;};
+ QString docName () {return myDocName;};
+
+ void setDocName (QString docName);
+
+ public slots:
+ /** Reloads the current document from disk if possible */
+ void reloadFile();
+
+ private slots:
+ void slotModChanged ();
+
+ private:
+ /** updates mTime to reflect file on fs.
+ called from constructor and from saveFile. */
+ void setMTime();
+ uint myDocID;
+ QFileInfo* fileInfo;
+ QDateTime mTime;
+ QString myDocName;
+
+ QString m_url;
+ QString m_file;
+ void openURL(const QString &filename);
+ private:
+ KateCmd *myCmd;
+
+ public:
+ KateCmd *cmd () { return myCmd; };
+
+ private:
+ QString myEncoding;
+
+ public:
+ void setEncoding (QString e) { myEncoding = e; };
+ QString encoding() { return myEncoding; };
+
+ void setWordWrap (bool on);
+ bool wordWrap () { return myWordWrap; };
+
+ void setWordWrapAt (uint col);
+ uint wordWrapAt () { return myWordWrapAt; };
+
+ signals:
+ void modStateChanged (KateDocument *doc);
+ void nameChanged (KateDocument *doc);
+
+ public:
+ QList<Kate::Mark> marks ();
+
+ public slots:
+ // clear buffer/filename - update the views
+ void flush ();
+
+ signals:
+ /**
+ The file has been saved (perhaps the name has changed). The main window
+ can use this to change its caption
+ */
+ void fileNameChanged ();
+
+ public:
+ //end of line settings
+ enum Eol_settings {eolUnix=0,eolDos=1,eolMacintosh=2};
+
+ // for the DCOP interface
+ public:
+ void open (const QString &name=0);
+
+ public:
+ // wrap the text of the document at the column col
+ void wrapText (uint col);
+
+ public slots:
+ void applyWordWrap ();
+
+ private:
+
+ class KateDocPrivate
+ {
+ public:
+ bool hlSetByUser;
+ };
+
+
+// BCI: Add a real d-pointer in the next BIC release
+static QPtrDict<KateDocPrivate>* d_ptr;
+static void cleanup_d_ptr()
+ {
+ delete d_ptr;
+ }
+
+KateDocPrivate* d( const KateDocument* foo )
+ {
+ if ( !d_ptr ) {
+ d_ptr = new QPtrDict<KateDocPrivate>;
+ //qAddPostRoutine( cleanup_d_ptr );
+ }
+ KateDocPrivate* ret = d_ptr->find( (void*) foo );
+ if ( ! ret ) {
+ ret = new KateDocPrivate;
+ d_ptr->replace( (void*) foo, ret );
+ }
+ return ret;
+ }
+
+void delete_d( const KateDocument* foo )
+ {
+ if ( d_ptr )
+ d_ptr->remove( (void*) foo );
+ }
+
+};
+
+#endif
+
+
diff --git a/noncore/apps/tinykate/libkate/document/katedocumentIface.h b/noncore/apps/tinykate/libkate/document/katedocumentIface.h
new file mode 100644
index 0000000..51c7506
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katedocumentIface.h
@@ -0,0 +1,32 @@
+/***************************************************************************
+ katedocumentIface.h - description
+ -------------------
+ copyright : (C) 2001 by The Kate Team
+ (C) 2002 by Joseph Wenninger
+ email : kwrite-devel@kde.org
+ jowenn@kde.org
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef _KATEDOCUMENT_IFACE_H_
+#define _KATEDOCUMENT_IFACE_H_
+
+#include <dcopobject.h>
+
+class KateDocumentDCOPIface : virtual public DCOPObject
+{
+ K_DCOP
+
+ k_dcop:
+ virtual void open (const QString &name=0)=0;
+};
+#endif
+
diff --git a/noncore/apps/tinykate/libkate/document/katehighlight.cpp b/noncore/apps/tinykate/libkate/document/katehighlight.cpp
new file mode 100644
index 0000000..797968b
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katehighlight.cpp
@@ -0,0 +1,1459 @@
+/*
+ Copyright (C) 1998, 1999 Jochen Wilhelmy
+ digisnap@cs.tu-berlin.de
+ (C) 2002, 2001 The Kate Team <kwrite-devel@kde.org>
+ (C) 2002 Joseph Wenninger <jowenn@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <string.h>
+
+#include <qtextstream.h>
+#include <qpe/config.h>
+#include <kglobal.h>
+//#include <kinstance.h>
+//#include <kmimemagic.h>
+#include <klocale.h>
+//#include <kregexp.h>
+#include <kglobalsettings.h>
+#include <kdebug.h>
+#include <kstddirs.h>
+
+#include "katehighlight.h"
+
+
+#include "katetextline.h"
+#include "katedocument.h"
+#include "katesyntaxdocument.h"
+
+
+HlManager *HlManager::s_pSelf = 0;
+
+enum Item_styles { dsNormal,dsKeyword,dsDataType,dsDecVal,dsBaseN,dsFloat,dsChar,dsString,dsComment,dsOthers};
+
+static bool trueBool = true;
+static QString stdDeliminator = QString ("!%&()*+,-./:;<=>?[]^{|}~ \t\\");
+
+int getDefStyleNum(QString name)
+{
+ if (name=="dsNormal") return dsNormal;
+ if (name=="dsKeyword") return dsKeyword;
+ if (name=="dsDataType") return dsDataType;
+ if (name=="dsDecVal") return dsDecVal;
+ if (name=="dsBaseN") return dsBaseN;
+ if (name=="dsFloat") return dsFloat;
+ if (name=="dsChar") return dsChar;
+ if (name=="dsString") return dsString;
+ if (name=="dsComment") return dsComment;
+ if (name=="dsOthers") return dsOthers;
+
+ return dsNormal;
+}
+
+bool ustrchr(const QChar *s, uint len, QChar c)
+{
+ for (int z=0; z < len; z++)
+ {
+ if (*s == c) return true;
+ s++;
+ }
+
+ return false;
+}
+
+HlItem::HlItem(int attribute, int context)
+ : attr(attribute), ctx(context) {subItems=0;
+}
+
+HlItem::~HlItem()
+{
+ //kdDebug(13010)<<"In hlItem::~HlItem()"<<endl;
+ if (subItems!=0) {subItems->setAutoDelete(true); subItems->clear(); delete subItems;}
+}
+
+bool HlItem::startEnable(QChar c)
+{
+ return true;
+}
+
+HlCharDetect::HlCharDetect(int attribute, int context, QChar c)
+ : HlItem(attribute,context), sChar(c) {
+}
+
+const QChar *HlCharDetect::checkHgl(const QChar *str, int len, bool) {
+ if (*str == sChar) return str + 1;
+ return 0L;
+}
+
+Hl2CharDetect::Hl2CharDetect(int attribute, int context, QChar ch1, QChar ch2)
+ : HlItem(attribute,context) {
+ sChar1 = ch1;
+ sChar2 = ch2;
+}
+
+const QChar *Hl2CharDetect::checkHgl(const QChar *str, int len, bool) {
+ if (str[0] == sChar1 && str[1] == sChar2) return str + 2;
+ return 0L;
+}
+
+HlStringDetect::HlStringDetect(int attribute, int context, const QString &s, bool inSensitive)
+ : HlItem(attribute, context), str(inSensitive ? s.upper():s), _inSensitive(inSensitive) {
+}
+
+HlStringDetect::~HlStringDetect() {
+}
+
+const QChar *HlStringDetect::checkHgl(const QChar *s, int len, bool) {
+ if (!_inSensitive) {if (memcmp(s, str.unicode(), str.length()*sizeof(QChar)) == 0) return s + str.length();}
+ else
+ {
+ QString tmp=QString(s,str.length()).upper();
+ if (tmp==str) return s+str.length();
+ }
+ return 0L;
+}
+
+
+HlRangeDetect::HlRangeDetect(int attribute, int context, QChar ch1, QChar ch2)
+ : HlItem(attribute,context) {
+ sChar1 = ch1;
+ sChar2 = ch2;
+}
+
+const QChar *HlRangeDetect::checkHgl(const QChar *s, int len, bool) {
+ if (*s == sChar1)
+ {
+ do
+ {
+ s++;
+ len--;
+ if (len == 0) return 0L;
+ }
+ while (*s != sChar2);
+
+ return s + 1;
+ }
+ return 0L;
+}
+
+HlKeyword::HlKeyword (int attribute, int context,bool casesensitive, const QChar *deliminator, uint deliLen)
+ : HlItem(attribute,context), dict (113, casesensitive)
+{
+ deliminatorChars = deliminator;
+ deliminatorLen = deliLen;
+ _caseSensitive=casesensitive;
+}
+
+HlKeyword::~HlKeyword() {
+}
+
+bool HlKeyword::startEnable(QChar c)
+{
+ return ustrchr(deliminatorChars, deliminatorLen, c);
+}
+
+// If we use a dictionary for lookup we don't really need
+// an item as such we are using the key to lookup
+void HlKeyword::addWord(const QString &word)
+{
+ words.append(word);
+ dict.insert(word,&trueBool);
+}
+
+void HlKeyword::addList(const QStringList& list)
+{
+
+ words+=list;
+ for(uint i=0;i<list.count();i++) dict.insert(list[i], &trueBool);
+}
+
+const QChar *HlKeyword::checkHgl(const QChar *s, int len, bool b)
+{
+ if (len == 0) return 0L;
+
+ const QChar *s2 = s;
+
+ while ( (len > 0) && (!ustrchr(deliminatorChars, deliminatorLen, *s2)) )
+ {
+ s2++;
+ len--;
+ }
+
+ if (s2 == s) return 0L;
+
+ QString lookup = QString(s,s2-s);
+
+ if ( dict.find(lookup) ) return s2;
+ return 0L;
+}
+
+HlInt::HlInt(int attribute, int context)
+ : HlItem(attribute,context) {
+}
+
+const QChar *HlInt::checkHgl(const QChar *str, int len, bool) {
+ const QChar *s,*s1;
+
+ s = str;
+ while (s->isDigit()) s++;
+ if (s > str)
+ {
+ if (subItems)
+ {
+ for (HlItem *it=subItems->first();it;it=subItems->next())
+ {
+ s1=it->checkHgl(s, len, false);
+ if (s1) return s1;
+ }
+ }
+ return s;
+ }
+ return 0L;
+}
+
+HlFloat::HlFloat(int attribute, int context)
+ : HlItem(attribute,context) {
+}
+
+const QChar *HlFloat::checkHgl(const QChar *s, int len, bool) {
+ bool b, p;
+ const QChar *s1;
+
+ b = false;
+ while (s->isDigit()){
+ s++;
+ b = true;
+ }
+ if (p = (*s == '.')) {
+ s++;
+ while (s->isDigit()) {
+ s++;
+ b = true;
+ }
+ }
+ if (!b) return 0L;
+ if ((*s&0xdf) == 'E') s++;
+ else
+ if (!p) return 0L;
+ else
+ {
+ if (subItems)
+ {
+ for (HlItem *it=subItems->first();it;it=subItems->next())
+ {
+ s1=it->checkHgl(s, len, false);
+ if (s1) return s1;
+ }
+ }
+ return s;
+ }
+ if ((*s == '-')||(*s =='+')) s++;
+ b = false;
+ while (s->isDigit()) {
+ s++;
+ b = true;
+ }
+ if (b)
+ {
+ if (subItems)
+ {
+ for (HlItem *it=subItems->first();it;it=subItems->next())
+ {
+ s1=it->checkHgl(s, len, false);
+ if (s1) return s1;
+ }
+ }
+ return s;
+ }
+ else return 0L;
+}
+
+
+HlCInt::HlCInt(int attribute, int context)
+ : HlInt(attribute,context) {
+}
+
+const QChar *HlCInt::checkHgl(const QChar *s, int len, bool lineStart) {
+
+// if (*s == '0') s++; else s = HlInt::checkHgl(s);
+ s = HlInt::checkHgl(s, len, lineStart);
+ if (s != 0L) {
+ int l = 0;
+ int u = 0;
+ const QChar *str;
+
+ do {
+ str = s;
+ if ((*s&0xdf) == 'L' ) {
+ l++;
+ if (l > 2) return 0L;
+ s++;
+ }
+ if ((*s&0xdf) == 'U' ){
+ u++;
+ if (u > 1) return 0L;
+ s++;
+ }
+ } while (s != str);
+ }
+ return s;
+}
+
+HlCOct::HlCOct(int attribute, int context)
+ : HlItem(attribute,context) {
+}
+
+const QChar *HlCOct::checkHgl(const QChar *str, int len, bool) {
+ const QChar *s;
+
+ if (*str == '0') {
+ str++;
+ s = str;
+ while (*s >= '0' && *s <= '7') s++;
+ if (s > str) {
+ if ((*s&0xdf) == 'L' || (*s&0xdf) == 'U' ) s++;
+ return s;
+ }
+ }
+ return 0L;
+}
+
+HlCHex::HlCHex(int attribute, int context)
+ : HlItem(attribute,context) {
+}
+
+const QChar *HlCHex::checkHgl(const QChar *str, int len, bool) {
+ const QChar *s=str;
+#if 0
+ int i;
+ for (i=0;(*s)!='\0';s++,i++);
+ QString line(str,i);
+ QRegExp3 rx("0[xX][a-fA-F\\d]+[UuLl]?"); // this matches but is also matching parenthesis
+ int pos=rx.search(line,0);
+ if(pos > -1) return str+rx.matchedLength();
+ else
+ return 0L;
+
+#else
+ if (str[0] == '0' && ((str[1]&0xdf) == 'X' )) {
+ str += 2;
+ s = str;
+ while (s->isDigit() || ((*s&0xdf) >= 'A' && (*s&0xdf) <= 'F') /*|| (*s >= 'a' && *s <= 'f')*/) s++;
+ if (s > str) {
+ if ((*s&0xdf) == 'L' || (*s&0xdf) == 'U' ) s++;
+ return s;
+ }
+ }
+ return 0L;
+#endif
+}
+
+HlCFloat::HlCFloat(int attribute, int context)
+ : HlFloat(attribute,context) {
+}
+
+const QChar *HlCFloat::checkHgl(const QChar *s, int len, bool lineStart) {
+
+ s = HlFloat::checkHgl(s, len, lineStart);
+ if (s && ((*s&0xdf) == 'F' )) s++;
+ return s;
+}
+
+HlAnyChar::HlAnyChar(int attribute, int context, const QChar* charList, uint len)
+ : HlItem(attribute, context) {
+ _charList=charList;
+ _charListLen=len;
+}
+
+const QChar *HlAnyChar::checkHgl(const QChar *s, int len, bool)
+{
+ if (ustrchr(_charList, _charListLen, *s)) return s +1;
+ return 0L;
+}
+
+HlRegExpr::HlRegExpr(int attribute, int context,QString regexp)
+ : HlItem(attribute, context) {
+
+ handlesLinestart=regexp.startsWith("^");
+ if(!handlesLinestart) regexp.prepend("^");
+ Expr=new QRegExp3(regexp);
+}
+
+const QChar *HlRegExpr::checkHgl(const QChar *s, int len, bool lineStart)
+{
+ if ((!lineStart) && handlesLinestart) return 0;
+
+ QString line(s,len);
+ int pos = Expr->search( line, 0 );
+ if (pos==-1) return 0L;
+ else
+ return (s+Expr->matchedLength());
+};
+
+
+HlLineContinue::HlLineContinue(int attribute, int context)
+ : HlItem(attribute,context) {
+}
+
+const QChar *HlLineContinue::checkHgl(const QChar *s, int len, bool) {
+
+ if ((s[0].latin1() == '\\') && (len == 1))
+ {
+ return s + 1;
+ }
+ return 0L;
+}
+
+
+HlCStringChar::HlCStringChar(int attribute, int context)
+ : HlItem(attribute,context) {
+}
+
+//checks for hex and oct (for example \x1b or \033)
+const QChar *checkCharHexOct(const QChar *str) {
+ const QChar *s;
+ s=str;
+ int n;
+ if (*s == 'x') {
+ n = 0;
+ do {
+ s++;
+ n *= 16;
+ if (s->isDigit()) n += *s - '0';
+ else if ((*s&0xdf) >= 'A' && (*s&0xdf) <= 'F') n += (*s&0xdf) - 'A' + 10;
+// else if (*s >= 'a' && *s <= 'f') n += *s - 'a' + 10;
+ else break;
+ if (n >= 256) return 0L;
+ } while (true);
+ if (s - str == 1) return 0L;
+ } else {
+ if (!(*s >= '0' && *s <= '7')) return 0L;
+ n = *s - '0';
+ do {
+ s++;
+ n *= 8;
+ if (*s >= '0' && *s <= '7') n += *s - '0'; else break;
+ if (n >= 256) return s;
+ } while (s - str < 3);
+ }
+ return s;
+}
+// checks for C escaped chars \n and escaped hex/octal chars
+const QChar *checkEscapedChar(const QChar *s, int len) {
+ int i;
+ if (s[0] == '\\' && (len > 1) ) {
+ s++;
+ switch(*s){
+ case 'a': // checks for control chars
+ case 'b': // we want to fall through
+ case 'e':
+ case 'f':
+
+ case 'n':
+ case 'r':
+ case 't':
+ case 'v':
+ case '\'':
+ case '\"':
+ case '?' : // added ? ANSI C classifies this as an escaped char
+ case '\\': s++;
+ break;
+ case 'x': // if it's like \xff
+ s++; // eat the x
+ // these for loops can probably be
+ // replaced with something else but
+ // for right now they work
+ // check for hexdigits
+ for(i=0;i<2 &&(*s >= '0' && *s <= '9' || (*s&0xdf) >= 'A' && (*s&0xdf) <= 'F');i++,s++);
+ if(i==0) return 0L; // takes care of case '\x'
+ break;
+
+ case '0': case '1': case '2': case '3' :
+ case '4': case '5': case '6': case '7' :
+ for(i=0;i < 3 &&(*s >='0'&& *s<='7');i++,s++);
+ break;
+ default: return 0L;
+ }
+ return s;
+ }
+ return 0L;
+}
+
+const QChar *HlCStringChar::checkHgl(const QChar *str, int len, bool) {
+ return checkEscapedChar(str, len);
+}
+
+
+HlCChar::HlCChar(int attribute, int context)
+ : HlItem(attribute,context) {
+}
+
+const QChar *HlCChar::checkHgl(const QChar *str, int len, bool) {
+ const QChar *s;
+
+ if ((len > 1) && (str[0] == '\'') && (str[1] != '\''))
+ {
+ s = checkEscapedChar(&str[1], len); //try to match escaped char
+ if (!s) s = &str[2]; //match single non-escaped char
+ if (*s == '\'') return s + 1;
+ }
+ return 0L;
+}
+
+
+//--------
+ItemStyle::ItemStyle() : selCol(Qt::white), bold(false), italic(false) {
+}
+
+ItemStyle::ItemStyle(const QColor &col, const QColor &selCol,
+ bool bold, bool italic)
+ : col(col), selCol(selCol), bold(bold), italic(italic) {
+}
+
+ItemData::ItemData(const QString name, int defStyleNum)
+ : name(name), defStyleNum(defStyleNum), defStyle(true) {
+}
+
+ItemData::ItemData(const QString name, int defStyleNum,
+ const QColor &col, const QColor &selCol, bool bold, bool italic)
+ : ItemStyle(col,selCol,bold,italic), name(name), defStyleNum(defStyleNum),
+ defStyle(false) {
+}
+
+HlData::HlData(const QString &wildcards, const QString &mimetypes, const QString &identifier)
+ : wildcards(wildcards), mimetypes(mimetypes), identifier(identifier) {
+
+//JW itemDataList.setAutoDelete(true);
+}
+
+HlContext::HlContext(int attribute, int lineEndContext, int _lineBeginContext)
+ : attr(attribute), ctx(lineEndContext),lineBeginContext(_lineBeginContext) {
+ items.setAutoDelete(true);
+}
+
+Hl2CharDetect::Hl2CharDetect(int attribute, int context, const QChar *s)
+ : HlItem(attribute,context) {
+ sChar1 = s[0];
+ sChar2 = s[1];
+}
+
+Highlight::Highlight(syntaxModeListItem *def) : refCount(0)
+{
+ noHl = false;
+
+ if (def == 0)
+ {
+ noHl = true;
+ iName = I18N_NOOP("Normal");
+ iSection = "";
+ }
+ else
+ {
+ iName = def->name;
+ iSection = def->section;
+ iWildcards = def->extension;
+ iMimetypes = def->mimetype;
+ identifier = def->identifier;
+ }
+ deliminator = stdDeliminator;
+ deliminatorChars = deliminator.unicode();
+ deliminatorLen = deliminator.length();
+}
+
+Highlight::~Highlight()
+{
+}
+
+int Highlight::doHighlight(int ctxNum, TextLine *textLine)
+{
+ if (noHl)
+ {
+ textLine->setAttribs(0,0,textLine->length());
+ textLine->setAttr(0);
+ return 0;
+ }
+
+ HlContext *context;
+ const QChar *s2;
+ HlItem *item;
+
+ context = contextList[ctxNum];
+ if (context->lineBeginContext!=-1)
+ {
+ ctxNum=context->lineBeginContext;
+ context=contextList[ctxNum];
+ }
+
+ QChar lastChar = ' ';
+
+ // first char
+ const QChar *str = textLine->getText();
+
+ // non space char - index of that char
+ const QChar *s1 = textLine->firstNonSpace();
+ uint z = textLine->firstChar();
+
+ // length of textline
+ uint len = textLine->length();
+
+ bool found = false;
+ while (z < len)
+ {
+ found = false;
+
+ for (item = context->items.first(); item != 0L; item = context->items.next())
+ {
+ if (item->startEnable(lastChar))
+ {
+ s2 = item->checkHgl(s1, len-z, z==0);
+ if (s2 > s1)
+ {
+ qDebug("An item has been detected");
+ textLine->setAttribs(item->attr,s1 - str,s2 - str);
+ ctxNum = item->ctx;
+ context = contextList[ctxNum];
+ z = z + s2 - s1 - 1;
+ s1 = s2 - 1;
+ found = true;
+ break;
+ }
+ }
+ }
+
+ // nothing found: set attribute of one char
+ if (!found)
+ textLine->setAttribs(context->attr,s1 - str,s1 - str + 1);
+
+ lastChar = *s1;
+ s1++;
+ z++;
+ }
+
+ //set "end of line"-properties
+ textLine->setAttr(context->attr);
+
+ //return new context
+ return context->ctx;
+}
+
+KConfig *Highlight::getKConfig() {
+ KConfig *config;
+ config=KGlobal::config();
+ config->setGroup(iName + QString(" Highlight"));
+ return config;
+}
+
+QString Highlight::getWildcards() {
+ KConfig *config;
+
+ config = getKConfig();
+
+ //if wildcards not yet in config, then use iWildCards as default
+ return config->readEntry("Wildcards", iWildcards);
+}
+
+
+QString Highlight::getMimetypes() {
+ KConfig *config;
+
+ config = getKConfig();
+
+ return config->readEntry("Mimetypes", iMimetypes);
+}
+
+
+HlData *Highlight::getData() {
+ KConfig *config;
+ HlData *hlData;
+
+ config = getKConfig();
+
+// iWildcards = config->readEntry("Wildcards");
+// iMimetypes = config->readEntry("Mimetypes");
+// hlData = new HlData(iWildcards,iMimetypes);
+ hlData = new HlData(
+ config->readEntry("Wildcards", iWildcards),
+ config->readEntry("Mimetypes", iMimetypes),
+ config->readEntry("Identifier", identifier));
+ getItemDataList(hlData->itemDataList, config);
+ return hlData;
+}
+
+void Highlight::setData(HlData *hlData) {
+ KConfig *config;
+
+ config = getKConfig();
+
+// iWildcards = hlData->wildcards;
+// iMimetypes = hlData->mimetypes;
+
+ config->writeEntry("Wildcards",hlData->wildcards);
+ config->writeEntry("Mimetypes",hlData->mimetypes);
+
+ setItemDataList(hlData->itemDataList,config);
+}
+
+void Highlight::getItemDataList(ItemDataList &list) {
+ KConfig *config;
+
+ config = getKConfig();
+ getItemDataList(list, config);
+}
+
+void Highlight::getItemDataList(ItemDataList &list, KConfig *config) {
+ ItemData *p;
+ QString s;
+ QRgb col, selCol;
+
+ list.clear();
+//JW list.setAutoDelete(true);
+ createItemData(list);
+
+ for (p = list.first(); p != 0L; p = list.next()) {
+ s = config->readEntry(p->name);
+ if (!s.isEmpty()) {
+ sscanf(s.latin1(),"%d,%X,%X,%d,%d", &p->defStyle,&col,&selCol,&p->bold,&p->italic);
+ p->col.setRgb(col);
+ p->selCol.setRgb(selCol);
+ }
+ }
+}
+
+/*******************************************************************************************
+ Highlight - setItemDataList
+ saves the ItemData / attribute / style definitions to the apps configfile.
+ Especially needed for user overridden values.
+
+ * input: ItemDataList &list :reference to the list, whose
+ * items should be saved
+ * KConfig *config :Pointer KDE configuration
+ * class, which should be used
+ * as storage
+ *************
+ * output: none
+ *************
+ * return value: none
+*******************************************************************************************/
+
+void Highlight::setItemDataList(ItemDataList &list, KConfig *config) {
+ ItemData *p;
+ QString s;
+
+ for (p = list.first(); p != 0L; p = list.next()) {
+ s.sprintf("%d,%X,%X,%d,%d",
+ p->defStyle,p->col.rgb(),p->selCol.rgb(),p->bold,p->italic);
+ config->writeEntry(p->name,s);
+ }
+}
+
+
+/*******************************************************************************************
+ Highlight - use
+ Increase the usage count and trigger initialization if needed
+
+ * input: none
+ *************
+ * output: none
+ *************
+ * return value: none
+*******************************************************************************************/
+
+void Highlight::use()
+{
+ if (refCount == 0) init();
+ refCount++;
+}
+
+
+/*******************************************************************************************
+ Highlight - release
+ Decrease the usage count and trigger a cleanup if needed
+
+ * input: none
+ *************
+ * output: none
+ *************
+ * return value: none
+*******************************************************************************************/
+
+void Highlight::release()
+{
+ refCount--;
+ if (refCount == 0) done();
+}
+
+/*******************************************************************************************
+ Highlight - init
+ If it's the first time a particular highlighting is used create the needed contextlist
+
+ * input: none
+ *************
+ * output: none
+ *************
+ * return value: none
+*******************************************************************************************/
+
+void Highlight::init()
+{
+ if (noHl)
+ return;
+
+ for (int z = 0; z < nContexts; z++) contextList[z] = 0L;
+ makeContextList();
+}
+
+
+/*******************************************************************************************
+ Highlight - done
+ If the there is no document using the highlighting style free the complete context
+ structure.
+
+ * input: none
+ *************
+ * output: none
+ *************
+ * return value: none
+*******************************************************************************************/
+
+void Highlight::done()
+{
+ if (noHl)
+ return;
+
+ for (int z = 0; z < nContexts; z++) delete contextList[z];
+}
+
+
+/*******************************************************************************************
+ Highlight - createItemData
+ This function reads the itemData entries from the config file, which specifies the
+ default attribute styles for matched items/contexts.
+
+ * input: none
+ *************
+ * output: ItemDataList &list :A reference to the internal
+ list containing the parsed
+ default config
+ *************
+ * return value: none
+*******************************************************************************************/
+
+void Highlight::createItemData(ItemDataList &list)
+{
+ qDebug("Highlight::createItemData");
+
+ // If no highlighting is selected we need only one default.
+ if (noHl)
+ {
+ list.append(new ItemData(I18N_NOOP("Normal Text"), dsNormal));
+ return;
+ }
+
+ QString color;
+ QString selColor;
+ QString bold;
+ QString italic;
+
+ // If the internal list isn't already available read the config file
+ if (internalIDList.count()==0)
+ {
+ //if all references to the list are destried the contents will also be deleted
+ internalIDList.setAutoDelete(true);
+ syntaxContextData *data;
+
+ qDebug("Trying to read itemData section");
+
+ //Tell the syntax document class which file we want to parse and which data group
+ HlManager::self()->syntax->setIdentifier(identifier);
+ data=HlManager::self()->syntax->getGroupInfo("highlighting","itemData");
+ //begin with the real parsing
+ while (HlManager::self()->syntax->nextGroup(data))
+ {
+ qDebug("Setting up one itemData element");
+ // read all attributes
+ color=HlManager::self()->syntax->groupData(data,QString("color"));
+ selColor=HlManager::self()->syntax->groupData(data,QString("selColor"));
+ bold=HlManager::self()->syntax->groupData(data,QString("bold"));
+ italic=HlManager::self()->syntax->groupData(data,QString("italic"));
+ //check if the user overrides something
+ if ( (!color.isEmpty()) && (!selColor.isEmpty()) && (!bold.isEmpty()) && (!italic.isEmpty()))
+ {
+ //create a user defined style
+ internalIDList.append(new ItemData(
+ HlManager::self()->syntax->groupData(data,QString("name")).simplifyWhiteSpace(),
+ getDefStyleNum(HlManager::self()->syntax->groupData(data,QString("defStyleNum"))),
+ QColor(color),QColor(selColor),(bold=="true") || (bold=="1"), (italic=="true") || (italic=="1")
+ ));
+ }
+ else
+ {
+ //assign a default style
+ internalIDList.append(new ItemData(
+ HlManager::self()->syntax->groupData(data,QString("name")).simplifyWhiteSpace(),
+ getDefStyleNum(HlManager::self()->syntax->groupData(data,QString("defStyleNum")))));
+
+ }
+ }
+ //clean up
+ if (data) HlManager::self()->syntax->freeGroupInfo(data);
+ }
+
+ //set the ouput reference
+ list=internalIDList;
+}
+
+
+/*******************************************************************************************
+ Highlight - lookupAttrName
+ This function is a helper for makeContextList and createHlItem. It looks the given
+ attribute name in the itemData list up and returns it's index
+
+ * input: QString &name :the attribute name to lookup
+ * ItemDataList &iDl :the list containing all
+ * available attributes
+ *************
+ * output: none
+ *************
+ * return value: int :The index of the attribute
+ * or 0
+*******************************************************************************************/
+
+int Highlight::lookupAttrName(const QString& name, ItemDataList &iDl)
+{
+ for (int i=0;i<iDl.count();i++)
+ {
+ if (iDl.at(i)->name==name) return i;
+ }
+ kdDebug(13010)<<"Couldn't resolve itemDataName"<<endl;
+ return 0;
+}
+
+
+/*******************************************************************************************
+ Highlight - createHlItem
+ This function is a helper for makeContextList. It parses the xml file for
+ information, how single or multi line comments are marked
+
+ * input: syntaxContextData *data : Data about the item read from
+ * the xml file
+ * ItemDataList &iDl : List of all available itemData
+ * entries. Needed for attribute
+ * name->index translation
+ *************
+ * output: none
+ *************
+ * return value: HlItem * : Pointer to the newly created item
+ * object
+*******************************************************************************************/
+
+HlItem *Highlight::createHlItem(syntaxContextData *data, ItemDataList &iDl)
+{
+ // No highlighting -> exit
+ if (noHl)
+ return 0;
+
+ // get the (tagname) itemd type
+ QString dataname=HlManager::self()->syntax->groupItemData(data,QString(""));
+
+ // BEGIN - Translation of the attribute parameter
+ QString tmpAttr=HlManager::self()->syntax->groupItemData(data,QString("attribute")).simplifyWhiteSpace();
+ int attr;
+ if (QString("%1").arg(tmpAttr.toInt())==tmpAttr)
+ attr=tmpAttr.toInt();
+ else
+ attr=lookupAttrName(tmpAttr,iDl);
+ // END - Translation of the attribute parameter
+
+ // Info about context switch
+ int context=((HlManager::self()->syntax->groupItemData(data,QString("context"))).toInt());
+
+ // Get the char parameter (eg DetectChar)
+ char chr;
+ if (! HlManager::self()->syntax->groupItemData(data,QString("char")).isEmpty())
+ chr= (HlManager::self()->syntax->groupItemData(data,QString("char")).latin1())[0];
+ else
+ chr=0;
+
+ // Get the String parameter (eg. StringDetect)
+ QString stringdata=HlManager::self()->syntax->groupItemData(data,QString("String"));
+
+ // Get a second char parameter (char1) (eg Detect2Chars)
+ char chr1;
+ if (! HlManager::self()->syntax->groupItemData(data,QString("char1")).isEmpty())
+ chr1= (HlManager::self()->syntax->groupItemData(data,QString("char1")).latin1())[0];
+ else
+ chr1=0;
+
+ // Will be removed eventuall. Atm used for StringDetect
+ bool insensitive=(HlManager::self()->syntax->groupItemData(data,QString("insensitive"))==QString("TRUE"));
+
+
+ //Create the item corresponding to it's type and set it's parameters
+ if (dataname=="keyword")
+ {
+ HlKeyword *keyword=new HlKeyword(attr,context,casesensitive,
+ deliminatorChars, deliminatorLen);
+
+ //Get the entries for the keyword lookup list
+ keyword->addList(HlManager::self()->syntax->finddata("highlighting",stringdata));
+ return keyword;
+ } else
+ if (dataname=="Float") return (new HlFloat(attr,context)); else
+ if (dataname=="Int") return(new HlInt(attr,context)); else
+ if (dataname=="DetectChar") return(new HlCharDetect(attr,context,chr)); else
+ if (dataname=="Detect2Chars") return(new Hl2CharDetect(attr,context,chr,chr1)); else
+ if (dataname=="RangeDetect") return(new HlRangeDetect(attr,context, chr, chr1)); else
+ if (dataname=="LineContinue") return(new HlLineContinue(attr,context)); else
+ if (dataname=="StringDetect") return(new HlStringDetect(attr,context,stringdata,insensitive)); else
+ if (dataname=="AnyChar") return(new HlAnyChar(attr,context,stringdata.unicode(), stringdata.length())); else
+ if (dataname=="RegExpr") return(new HlRegExpr(attr,context,stringdata)); else
+ if(dataname=="HlCChar") return ( new HlCChar(attr,context));else
+ if(dataname=="HlCHex") return (new HlCHex(attr,context));else
+ if(dataname=="HlCOct") return (new HlCOct(attr,context)); else
+ if(dataname=="HlCStringChar") return (new HlCStringChar(attr,context)); else
+
+ {
+ // oops, unknown type. Perhaps a spelling error in the xml file
+ return 0;
+ }
+
+
+}
+
+
+/*******************************************************************************************
+ Highlight - isInWord
+
+ * input: Qchar c Character to investigate
+ *************
+ * output: none
+ *************
+ * return value: returns true, if c is no deliminator
+*******************************************************************************************/
+
+bool Highlight::isInWord(QChar c)
+{
+ return !ustrchr(deliminatorChars, deliminatorLen, c);
+}
+
+
+
+/*******************************************************************************************
+ Highlight - readCommentConfig
+ This function is a helper for makeContextList. It parses the xml file for
+ information, how single or multi line comments are marked
+
+ * input: none
+ *************
+ * output: none
+ *************
+ * return value: none
+*******************************************************************************************/
+
+void Highlight::readCommentConfig()
+{
+
+ cslStart = "";
+ HlManager::self()->syntax->setIdentifier(identifier);
+
+ syntaxContextData *data=HlManager::self()->syntax->getGroupInfo("general","comment");
+ if (data)
+ {
+// kdDebug(13010)<<"COMMENT DATA FOUND"<<endl;
+ while (HlManager::self()->syntax->nextGroup(data))
+ {
+
+ if (HlManager::self()->syntax->groupData(data,"name")=="singleLine")
+ cslStart=HlManager::self()->syntax->groupData(data,"start");
+ if (HlManager::self()->syntax->groupData(data,"name")=="multiLine")
+ {
+ cmlStart=HlManager::self()->syntax->groupData(data,"start");
+ cmlEnd=HlManager::self()->syntax->groupData(data,"end");
+ }
+ }
+ HlManager::self()->syntax->freeGroupInfo(data);
+ }
+
+}
+
+/*******************************************************************************************
+ Highlight - readGlobalKeyWordConfig
+ This function is a helper for makeContextList. It parses the xml file for
+ information, if keywords should be treated case(in)sensitive and creates the keyword
+ delimiter list. Which is the default list, without any given weak deliminiators
+
+ * input: none
+ *************
+ * output: none
+ *************
+ * return value: none
+*******************************************************************************************/
+
+
+void Highlight::readGlobalKeywordConfig()
+{
+ // Tell the syntax document class which file we want to parse
+ HlManager::self()->syntax->setIdentifier(identifier);
+
+ // Get the keywords config entry
+ syntaxContextData * data=HlManager::self()->syntax->getConfig("general","keywords");
+ if (data)
+ {
+ kdDebug(13010)<<"Found global keyword config"<<endl;
+
+ if (HlManager::self()->syntax->groupItemData(data,QString("casesensitive"))!="0")
+ casesensitive=true; else {casesensitive=false; kdDebug(13010)<<"Turning on case insensitiveness"<<endl;}
+ //get the weak deliminators
+ weakDeliminator=(!HlManager::self()->syntax->groupItemData(data,QString("weakDeliminator")));
+
+ // remove any weakDelimitars (if any) from the default list and store this list.
+ int f;
+ for (int s=0; s < weakDeliminator.length(); s++)
+ {
+ f = 0;
+ f = deliminator.find (weakDeliminator[s]);
+
+ if (f > -1)
+ deliminator.remove (f, 1);
+ }
+
+ deliminatorChars = deliminator.unicode();
+ deliminatorLen = deliminator.length();
+
+ HlManager::self()->syntax->freeGroupInfo(data);
+ }
+ else
+ {
+ //Default values
+ casesensitive=true;
+ weakDeliminator=QString("");
+ }
+
+}
+
+/*******************************************************************************************
+ Highlight - makeContextList
+ That's the most important initialization function for each highlighting. It's called
+ each time a document gets a highlighting style assigned. parses the xml file and
+ creates a corresponding internal structure
+
+ * input: none
+ *************
+ * output: none
+ *************
+ * return value: none
+*******************************************************************************************/
+
+
+void Highlight::makeContextList()
+{
+ if (noHl)
+ return;
+
+ HlKeyword *keyword=0, *dataType=0;
+ syntaxContextData *data, *datasub;
+ HlItem *c;
+
+ readCommentConfig();
+ readGlobalKeywordConfig();
+
+ // Let the syntax document class know, which file we'd like to parse
+ HlManager::self()->syntax->setIdentifier(identifier);
+
+ // This list is needed for the translation of the attribute parameter, if the itemData name is given instead of the index
+ ItemDataList iDl;
+ createItemData(iDl);
+
+ //start the real work
+ data=HlManager::self()->syntax->getGroupInfo("highlighting","context");
+ int i=0;
+ if (data)
+ {
+ while (HlManager::self()->syntax->nextGroup(data))
+ {
+
+ // BEGIN - Translation of the attribute parameter
+ QString tmpAttr=HlManager::self()->syntax->groupData(data,QString("attribute")).simplifyWhiteSpace();
+ int attr;
+ if (QString("%1").arg(tmpAttr.toInt())==tmpAttr)
+ attr=tmpAttr.toInt();
+ else
+ attr=lookupAttrName(tmpAttr,iDl);
+ // END - Translation of the attribute parameter
+
+ contextList[i]=new HlContext(
+ attr,
+ (HlManager::self()->syntax->groupData(data,QString("lineEndContext"))).toInt(),
+ (HlManager::self()->syntax->groupData(data,QString("lineBeginContext"))).isEmpty()?-1:
+ (HlManager::self()->syntax->groupData(data,QString("lineBeginContext"))).toInt());
+
+
+ //Let's create all items for the context
+ while (HlManager::self()->syntax->nextItem(data))
+ {
+// kdDebug(13010)<< "In make Contextlist: Item:"<<endl;
+ c=createHlItem(data,iDl);
+ if (c)
+ {
+ contextList[i]->items.append(c);
+
+ // Not supported completely atm and only one level. Subitems.(all have to be matched to at once)
+ datasub=HlManager::self()->syntax->getSubItems(data);
+ bool tmpbool;
+ if (tmpbool=HlManager::self()->syntax->nextItem(datasub))
+ {
+ c->subItems=new QList<HlItem>;
+ for (;tmpbool;tmpbool=HlManager::self()->syntax->nextItem(datasub))
+ c->subItems->append(createHlItem(datasub,iDl));
+ }
+ HlManager::self()->syntax->freeGroupInfo(datasub);
+ // end of sublevel
+ }
+// kdDebug(13010)<<"Last line in loop"<<endl;
+ }
+ i++;
+ }
+ }
+
+ HlManager::self()->syntax->freeGroupInfo(data);
+
+
+}
+
+HlManager::HlManager() : QObject(0L)
+{
+ syntax = new SyntaxDocument();
+ SyntaxModeList modeList = syntax->modeList();
+
+ hlList.setAutoDelete(true);
+ hlList.append(new Highlight(0));
+
+ uint i=0;
+ while (i < modeList.count())
+ {
+ hlList.append(new Highlight(modeList.at(i)));
+ i++;
+ }
+}
+
+HlManager::~HlManager() {
+ if(syntax) delete syntax;
+}
+
+HlManager *HlManager::self()
+{
+ if ( !s_pSelf )
+ s_pSelf = new HlManager;
+ return s_pSelf;
+}
+
+Highlight *HlManager::getHl(int n) {
+ if (n < 0 || n >= (int) hlList.count()) n = 0;
+ return hlList.at(n);
+}
+
+int HlManager::defaultHl() {
+ KConfig *config;
+ config = KGlobal::config();
+ config->setGroup("General Options");
+
+#warning fixme return nameFind(config->readEntry("Highlight"));
+
+}
+
+
+int HlManager::nameFind(const QString &name) {
+ int z;
+
+ for (z = hlList.count() - 1; z > 0; z--) {
+ if (hlList.at(z)->iName == name) break;
+ }
+ return z;
+}
+
+int HlManager::wildcardFind(const QString &fileName) {
+ Highlight *highlight;
+ int p1, p2;
+ QString w;
+ for (highlight = hlList.first(); highlight != 0L; highlight = hlList.next()) {
+ p1 = 0;
+ w = highlight->getWildcards();
+ while (p1 < (int) w.length()) {
+ p2 = w.find(';',p1);
+ if (p2 == -1) p2 = w.length();
+ if (p1 < p2) {
+ QRegExp regExp(w.mid(p1,p2 - p1),true,true);
+ if (regExp.match(fileName) == 0) return hlList.at();
+ }
+ p1 = p2 + 1;
+ }
+ }
+ return -1;
+}
+
+
+int HlManager::makeAttribs(Highlight *highlight, Attribute *a, int maxAttribs) {
+ ItemStyleList defaultStyleList;
+ ItemStyle *defaultStyle;
+ ItemDataList itemDataList;
+ ItemData *itemData;
+ int nAttribs, z;
+
+ qDebug("HlManager::makeAttribs");
+
+ defaultStyleList.setAutoDelete(true);
+ getDefaults(defaultStyleList);
+
+// itemDataList.setAutoDelete(true);
+ highlight->getItemDataList(itemDataList);
+ nAttribs = itemDataList.count();
+ for (z = 0; z < nAttribs; z++) {
+ qDebug("HlManager::makeAttribs: createing one attribute definition");
+ itemData = itemDataList.at(z);
+ if (itemData->defStyle) {
+ // default style
+ defaultStyle = defaultStyleList.at(itemData->defStyleNum);
+ a[z].col = defaultStyle->col;
+ a[z].selCol = defaultStyle->selCol;
+ a[z].bold = defaultStyle->bold;
+ a[z].italic = defaultStyle->italic;
+ } else {
+ // custom style
+ a[z].col = itemData->col;
+ a[z].selCol = itemData->selCol;
+ a[z].bold = itemData->bold;
+ a[z].italic = itemData->italic;
+ }
+ }
+
+ for (; z < maxAttribs; z++) {
+ a[z].col = black;
+ a[z].selCol = black;
+ a[z].bold = defaultStyle->bold;
+ a[z].italic = defaultStyle->italic;
+ }
+ return nAttribs;
+}
+
+int HlManager::defaultStyles() {
+ return 10;
+}
+
+QString HlManager::defaultStyleName(int n)
+{
+ static QStringList names;
+
+ if (names.isEmpty())
+ {
+ names << i18n("Normal");
+ names << i18n("Keyword");
+ names << i18n("Data Type");
+ names << i18n("Decimal/Value");
+ names << i18n("Base-N Integer");
+ names << i18n("Floating Point");
+ names << i18n("Character");
+ names << i18n("String");
+ names << i18n("Comment");
+ names << i18n("Others");
+ }
+
+ return names[n];
+}
+
+void HlManager::getDefaults(ItemStyleList &list) {
+ KConfig *config;
+ int z;
+ ItemStyle *i;
+ QString s;
+ QRgb col, selCol;
+
+ list.setAutoDelete(true);
+ //ItemStyle(color, selected color, bold, italic)
+ list.append(new ItemStyle(black,white,false,false)); //normal
+ list.append(new ItemStyle(black,white,true,false)); //keyword
+ list.append(new ItemStyle(darkRed,white,false,false)); //datatype
+ list.append(new ItemStyle(blue,cyan,false,false)); //decimal/value
+ list.append(new ItemStyle(darkCyan,cyan,false,false)); //base n
+ list.append(new ItemStyle(darkMagenta,cyan,false,false));//float
+ list.append(new ItemStyle(magenta,magenta,false,false)); //char
+ list.append(new ItemStyle(red,red,false,false)); //string
+ list.append(new ItemStyle(darkGray,gray,false,true)); //comment
+ list.append(new ItemStyle(darkGreen,green,false,false)); //others
+
+#warning fixme
+/*
+ config = KateFactory::instance()->config();
+ config->setGroup("Default Item Styles");
+ for (z = 0; z < defaultStyles(); z++) {
+ i = list.at(z);
+ s = config->readEntry(defaultStyleName(z));
+ if (!s.isEmpty()) {
+ sscanf(s.latin1(),"%X,%X,%d,%d",&col,&selCol,&i->bold,&i->italic);
+ i->col.setRgb(col);
+ i->selCol.setRgb(selCol);
+ }
+ }
+*/
+}
+
+void HlManager::setDefaults(ItemStyleList &list) {
+ KConfig *config;
+ int z;
+ ItemStyle *i;
+ char s[64];
+#warning fixme
+/*
+ config = KateFactory::instance()->config();
+ config->setGroup("Default Item Styles");
+ for (z = 0; z < defaultStyles(); z++) {
+ i = list.at(z);
+ sprintf(s,"%X,%X,%d,%d",i->col.rgb(),i->selCol.rgb(),i->bold, i->italic);
+ config->writeEntry(defaultStyleName(z),s);
+ }
+*/
+ emit changed();
+}
+
+
+int HlManager::highlights() {
+ return (int) hlList.count();
+}
+
+QString HlManager::hlName(int n) {
+ return hlList.at(n)->iName;
+}
+
+QString HlManager::hlSection(int n) {
+ return hlList.at(n)->iSection;
+}
+
+void HlManager::getHlDataList(HlDataList &list) {
+ int z;
+
+ for (z = 0; z < (int) hlList.count(); z++) {
+ list.append(hlList.at(z)->getData());
+ }
+}
+
+void HlManager::setHlDataList(HlDataList &list) {
+ int z;
+
+ for (z = 0; z < (int) hlList.count(); z++) {
+ hlList.at(z)->setData(list.at(z));
+ }
+ //notify documents about changes in highlight configuration
+ emit changed();
+}
diff --git a/noncore/apps/tinykate/libkate/document/katehighlight.h b/noncore/apps/tinykate/libkate/document/katehighlight.h
new file mode 100644
index 0000000..1baddcc
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katehighlight.h
@@ -0,0 +1,349 @@
+/*
+ Copyright (C) 1998, 1999 Jochen Wilhelmy
+ digisnap@cs.tu-berlin.de
+ (C) 2002, 2001 The Kate Team <kwrite-devel@kde.org>
+ (C) 2002 Joseph Wenninger <jowenn@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _HIGHLIGHT_H_
+#define _HIGHLIGHT_H_
+
+#include <qlist.h>
+#include <qdialog.h>
+
+#include <kcolorbtn.h>
+#include <qstrvec.h>
+#include <qdict.h>
+#include <qregexp.h>
+#include "../qt3back/qregexp3.h"
+#include <kdebug.h>
+
+class SyntaxDocument;
+struct syntaxModeListItem;
+struct syntaxContextData;
+
+class QCheckBox;
+class QComboBox;
+class QLineEdit;
+
+class TextLine;
+class Attribute;
+
+class HlItem {
+ public:
+ HlItem(int attribute, int context);
+ virtual ~HlItem();
+ virtual bool startEnable(QChar);
+ virtual const QChar *checkHgl(const QChar *, int len, bool) = 0;
+ QList<HlItem> *subItems;
+ int attr;
+ int ctx;
+};
+
+class HlCharDetect : public HlItem {
+ public:
+ HlCharDetect(int attribute, int context, QChar);
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+ protected:
+ QChar sChar;
+};
+
+class Hl2CharDetect : public HlItem {
+ public:
+ Hl2CharDetect(int attribute, int context, QChar ch1, QChar ch2);
+ Hl2CharDetect(int attribute, int context, const QChar *ch);
+
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+ protected:
+ QChar sChar1;
+ QChar sChar2;
+};
+
+class HlStringDetect : public HlItem {
+ public:
+ HlStringDetect(int attribute, int context, const QString &, bool inSensitive=false);
+ virtual ~HlStringDetect();
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+ protected:
+ const QString str;
+ bool _inSensitive;
+};
+
+class HlRangeDetect : public HlItem {
+ public:
+ HlRangeDetect(int attribute, int context, QChar ch1, QChar ch2);
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+ protected:
+ QChar sChar1;
+ QChar sChar2;
+};
+
+class HlKeyword : public HlItem
+{
+ public:
+ HlKeyword(int attribute, int context,bool casesensitive, const QChar *deliminator, uint deliLen);
+ virtual ~HlKeyword();
+
+ virtual void addWord(const QString &);
+ virtual void addList(const QStringList &);
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+ QStringList getList() { return words;};
+ virtual bool startEnable(QChar c);
+
+ protected:
+ QStringList words;
+ QDict<bool> dict;
+ bool _caseSensitive;
+ const QChar *deliminatorChars;
+ uint deliminatorLen;
+};
+
+class HlPHex : public HlItem {
+ public:
+ HlPHex(int attribute,int context);
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+};
+class HlInt : public HlItem {
+ public:
+ HlInt(int attribute, int context);
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+};
+
+class HlFloat : public HlItem {
+ public:
+ HlFloat(int attribute, int context);
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+};
+
+class HlCInt : public HlInt {
+ public:
+ HlCInt(int attribute, int context);
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+};
+
+class HlCOct : public HlItem {
+ public:
+ HlCOct(int attribute, int context);
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+};
+
+class HlCHex : public HlItem {
+ public:
+ HlCHex(int attribute, int context);
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+};
+
+class HlCFloat : public HlFloat {
+ public:
+ HlCFloat(int attribute, int context);
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+};
+
+class HlLineContinue : public HlItem {
+ public:
+ HlLineContinue(int attribute, int context);
+ virtual bool endEnable(QChar c) {return c == '\0';}
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+};
+
+class HlCStringChar : public HlItem {
+ public:
+ HlCStringChar(int attribute, int context);
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+};
+
+class HlCChar : public HlItem {
+ public:
+ HlCChar(int attribute, int context);
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+};
+
+class HlAnyChar : public HlItem {
+ public:
+ HlAnyChar(int attribute, int context, const QChar* charList, uint len);
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+ const QChar* _charList;
+ uint _charListLen;
+};
+
+class HlRegExpr : public HlItem {
+ public:
+ HlRegExpr(int attribute, int context,QString expr);
+ ~HlRegExpr(){delete Expr;};
+ virtual const QChar *checkHgl(const QChar *, int len, bool);
+ QRegExp3 *Expr;
+ bool handlesLinestart;
+};
+
+//--------
+
+
+//Item Style: color, selected color, bold, italic
+class ItemStyle {
+ public:
+ ItemStyle();
+// ItemStyle(const ItemStyle &);
+ ItemStyle(const QColor &, const QColor &, bool bold, bool italic);
+ ItemStyle(ItemStyle *its){col=its->col;selCol=its->selCol; bold=its->bold; italic=its->italic;}
+// void setData(const ItemStyle &);
+ QColor col;
+ QColor selCol;
+ int bold; //boolean value
+ int italic; //boolean value
+};
+
+typedef QList<ItemStyle> ItemStyleList;
+
+//Item Properties: name, Item Style, Item Font
+class ItemData : public ItemStyle {
+ public:
+ ItemData(const QString name, int defStyleNum);
+ ItemData(const QString name, int defStyleNum,
+ const QColor&, const QColor&, bool bold, bool italic);
+ ItemData(ItemData
+*itd):ItemStyle((ItemStyle*)itd),name(itd->name),defStyleNum(itd->defStyleNum),defStyle(itd->defStyle){;}
+ const QString name;
+ int defStyleNum;
+ int defStyle; //boolean value
+};
+
+typedef QList<ItemData> ItemDataList;
+
+class HlData {
+ public:
+ HlData(const QString &wildcards, const QString &mimetypes,const QString &identifier);
+ ItemDataList itemDataList;
+ QString wildcards;
+ QString mimetypes;
+ QString identifier;
+};
+
+typedef QList<HlData> HlDataList;
+
+class HlManager;
+class KConfig;
+
+//context
+class HlContext {
+ public:
+ HlContext(int attribute, int lineEndContext,int _lineBeginContext);
+ QList<HlItem> items;
+ int attr;
+ int ctx;
+ int lineBeginContext;
+};
+
+class Highlight
+{
+ friend class HlManager;
+
+ public:
+ Highlight(syntaxModeListItem *def);
+ ~Highlight();
+
+ int doHighlight(int ctxNum, TextLine *);
+
+ KConfig *getKConfig();
+ QString getWildcards();
+ QString getMimetypes();
+ HlData *getData();
+ void setData(HlData *);
+ void getItemDataList(ItemDataList &);
+ void getItemDataList(ItemDataList &, KConfig *);
+ void setItemDataList(ItemDataList &, KConfig *);
+ QString name() {return iName;}
+ QString section() {return iSection;}
+ void use();
+ void release();
+ bool isInWord(QChar c);
+
+ QString getCommentStart() {return cmlStart;};
+ QString getCommentEnd() {return cmlEnd;};
+ QString getCommentSingleLineStart() { return cslStart;};
+
+ protected:
+ void init();
+ void done();
+ void makeContextList ();
+ void createItemData (ItemDataList &list);
+ void readGlobalKeywordConfig();
+ void readCommentConfig();
+ HlItem *createHlItem(struct syntaxContextData *data, ItemDataList &iDl);
+ int lookupAttrName(const QString& name, ItemDataList &iDl);
+ ItemDataList internalIDList;
+ static const int nContexts = 32;
+ HlContext *contextList[nContexts];
+
+ bool noHl;
+ bool casesensitive;
+ QString weakDeliminator;
+ QString deliminator;
+ const QChar *deliminatorChars;
+ uint deliminatorLen;
+ QString cmlStart;
+ QString cmlEnd;
+ QString cslStart;
+ QString iName;
+ QString iSection;
+ QString iWildcards;
+ QString iMimetypes;
+ QString identifier;
+ int refCount;
+};
+
+class HlManager : public QObject {
+ Q_OBJECT
+ public:
+ HlManager();
+ ~HlManager();
+
+ static HlManager *self();
+
+ Highlight *getHl(int n);
+ int defaultHl();
+ int nameFind(const QString &name);
+
+ int wildcardFind(const QString &fileName);
+ int findHl(Highlight *h) {return hlList.find(h);}
+
+ int makeAttribs(Highlight *, Attribute *, int maxAttribs);
+
+ int defaultStyles();
+ QString defaultStyleName(int n);
+ void getDefaults(ItemStyleList &);
+ void setDefaults(ItemStyleList &);
+
+ int highlights();
+ QString hlName(int n);
+ QString hlSection(int n);
+ void getHlDataList(HlDataList &);
+ void setHlDataList(HlDataList &);
+
+ SyntaxDocument *syntax;
+
+ signals:
+ void changed();
+ protected:
+ QList<Highlight> hlList;
+ static HlManager *s_pSelf;
+};
+
+
+
+
+#endif //_HIGHLIGHT_H_
diff --git a/noncore/apps/tinykate/libkate/document/katesyntaxdocument.cpp b/noncore/apps/tinykate/libkate/document/katesyntaxdocument.cpp
new file mode 100644
index 0000000..c51221b
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katesyntaxdocument.cpp
@@ -0,0 +1,306 @@
+/***************************************************************************
+ katesyntaxdocument.cpp - description
+ -------------------
+ begin : Sat 31 March 2001
+ copyright : (C) 2001,2002 by Joseph Wenninger
+ email : jowenn@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "katesyntaxdocument.h"
+#include <qfile.h>
+#include <kdebug.h>
+#include <kstddirs.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <qstringlist.h>
+#include <kconfig.h>
+#include <kglobal.h>
+
+
+
+SyntaxDocument::SyntaxDocument()
+{
+ m_root=0;
+ currentFile="";
+ setupModeList();
+}
+
+void SyntaxDocument::setIdentifier(const QString& identifier)
+{
+#warning FIXME delete m_root;
+ m_root=Opie::XMLElement::load(identifier);
+ if (!m_root) KMessageBox::error( 0L, i18n("Can't open %1").arg(identifier) );
+
+}
+
+SyntaxDocument::~SyntaxDocument()
+{
+}
+
+void SyntaxDocument::setupModeList(bool force)
+{
+
+ if (myModeList.count() > 0) return;
+
+ KConfig *config=KGlobal::config();
+ KStandardDirs *dirs = KGlobal::dirs();
+
+ QStringList list=dirs->findAllResources("data","kate/syntax/*.xml",false,true);
+
+ for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ QString Group="Highlighting_Cache"+*it;
+
+ if ((config->hasGroup(Group)) && (!force))
+ {
+ config->setGroup(Group);
+ syntaxModeListItem *mli=new syntaxModeListItem;
+ mli->name = config->readEntry("name","");
+ mli->section = config->readEntry("section","");
+ mli->mimetype = config->readEntry("mimetype","");
+ mli->extension = config->readEntry("extension","");
+ mli->identifier = *it;
+ myModeList.append(mli);
+ }
+ else
+ {
+ qDebug("Found a description file:"+(*it));
+ setIdentifier(*it);
+ Opie::XMLElement *e=m_root;
+ if (e)
+ {
+ e=e->firstChild();
+ qDebug(e->tagName());
+ if (e->tagName()=="language")
+ {
+ syntaxModeListItem *mli=new syntaxModeListItem;
+ mli->name = e->attribute("name");
+ mli->section = e->attribute("section");
+ mli->mimetype = e->attribute("mimetype");
+ mli->extension = e->attribute("extensions");
+ qDebug(QString("valid description for: %1/%2").arg(mli->section).arg(mli->name));
+ if (mli->section.isEmpty())
+ mli->section=i18n("Other");
+
+ mli->identifier = *it;
+#warning fixme
+/*
+ config->setGroup(Group);
+ config->writeEntry("name",mli->name);
+ config->writeEntry("section",mli->section);
+ config->writeEntry("mimetype",mli->mimetype);
+ config->writeEntry("extension",mli->extension);
+*/
+ myModeList.append(mli);
+ }
+ }
+ }
+ }
+// }
+
+// config->sync();
+}
+
+SyntaxModeList SyntaxDocument::modeList()
+{
+ return myModeList;
+}
+
+bool SyntaxDocument::nextGroup( syntaxContextData* data)
+{
+ if(!data) return false;
+
+ if (!data->currentGroup)
+ data->currentGroup=data->parent->firstChild();
+ else
+ data->currentGroup=data->currentGroup->nextChild();
+
+ data->item=0;
+
+ if (!data->currentGroup)
+ return false;
+ else
+ return true;
+}
+
+bool SyntaxDocument::nextItem( syntaxContextData* data)
+{
+ if(!data) return false;
+
+ if (!data->item)
+ data->item=data->currentGroup->firstChild();
+ else
+ data->item=data->item->nextChild();
+
+ if (!data->item)
+ return false;
+ else
+ return true;
+}
+
+QString SyntaxDocument::groupItemData( syntaxContextData* data,QString name)
+{
+ if(!data)
+ return QString::null;
+
+ if ( (data->item) && (name.isEmpty()))
+ return data->item->tagName();
+
+ if (data->item)
+ return data->item->attribute(name);
+ else
+ return QString();
+}
+
+QString SyntaxDocument::groupData( syntaxContextData* data,QString name)
+{
+ if(!data)
+ return QString::null;
+
+ if (data->currentGroup)
+ return data->currentGroup->attribute(name);
+ else
+ return QString();
+}
+
+void SyntaxDocument::freeGroupInfo( syntaxContextData* data)
+{
+ if (data)
+ delete data;
+}
+
+syntaxContextData* SyntaxDocument::getSubItems(syntaxContextData* data)
+{
+ syntaxContextData *retval=new syntaxContextData;
+ retval->parent=0;
+ retval->currentGroup=0;
+ retval->item=0;
+ if (data != 0)
+ {
+ retval->parent=data->currentGroup;
+ retval->currentGroup=data->item;
+ retval->item=0;
+ }
+
+ return retval;
+}
+
+syntaxContextData* SyntaxDocument::getConfig(const QString& mainGroupName, const QString &Config)
+{
+ Opie::XMLElement *e = m_root->firstChild()->firstChild();
+
+ while (e)
+ {
+ kdDebug(13010)<<"in SyntaxDocument::getGroupInfo (outer loop) " <<endl;
+
+ if (e->tagName().compare(mainGroupName)==0 )
+ {
+ Opie::XMLElement *e1=e->firstChild();
+
+ while (e1)
+ {
+ kdDebug(13010)<<"in SyntaxDocument::getGroupInfo (inner loop) " <<endl;
+
+ if (e1->tagName()==Config)
+ {
+ syntaxContextData *data=new ( syntaxContextData);
+ data->currentGroup=0;
+ data->parent=0;
+ data->item=e1;
+ return data;
+ }
+
+ e1=e1->nextChild();
+ }
+
+ kdDebug(13010) << "WARNING :returning null 3"<< endl;
+ return 0;
+ }
+
+ e=e->nextChild();
+ }
+
+ kdDebug(13010) << "WARNING :returning null 4" << endl;
+ return 0;
+}
+
+
+
+syntaxContextData* SyntaxDocument::getGroupInfo(const QString& mainGroupName, const QString &group)
+{
+
+ Opie::XMLElement *e=m_root->firstChild()->firstChild();
+
+ while (e)
+ {
+ kdDebug(13010)<<"in SyntaxDocument::getGroupInfo (outer loop) " <<endl;
+
+ if (e->tagName().compare(mainGroupName)==0 )
+ {
+ Opie::XMLElement *e1=e->firstChild();
+
+ while (e1)
+ {
+ kdDebug(13010)<<"in SyntaxDocument::getGroupInfo (inner loop) " <<endl;
+ if (e1->tagName()==group+"s")
+ {
+ syntaxContextData *data=new ( syntaxContextData);
+ data->parent=e1;
+ data->currentGroup=0;
+ data->item=0;
+ return data;
+ }
+
+ e1=e1->nextChild();
+ }
+
+ kdDebug(13010) << "WARNING : getGroupInfo returning null :1 " << endl;
+ return 0;
+ }
+
+ e=e->nextChild();
+ }
+
+ kdDebug(13010) << "WARNING : getGroupInfo returning null :2" << endl;
+ return 0;
+}
+
+
+QStringList& SyntaxDocument::finddata(const QString& mainGroup,const QString& type,bool clearList)
+{
+ Opie::XMLElement *e = m_root->firstChild();
+ if (clearList)
+ m_data.clear();
+
+ for(e=e->firstChild(); e; e=e->nextChild())
+ {
+ if (e->tagName()==mainGroup)
+ {
+ for (Opie::XMLElement *e1=e->firstChild();e1;e1=e1->nextChild())
+ {
+ if (e1->tagName()!="list") continue;
+
+ if (e1->attribute("name")==type)
+ {
+ for (Opie::XMLElement *e2=e1->firstChild();e2;e2=e2->nextChild())
+ qDebug("FOUND A LIST ENTRY("+e2->tagName()+"):"+e2->value());
+ m_data+="TEST";//e2->value().stripWhiteSpace();
+
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ return m_data;
+}
diff --git a/noncore/apps/tinykate/libkate/document/katesyntaxdocument.h b/noncore/apps/tinykate/libkate/document/katesyntaxdocument.h
new file mode 100644
index 0000000..5c5c5a4
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katesyntaxdocument.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ katesyntaxdocument.h - description
+ -------------------
+ begin : Sat 31 March 2001
+ copyright : (C) 2001,2002 by Joseph Wenninger
+ email : jowenn@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SYNTAXDOCUMENT_H
+#define SYNTAXDOCUMENT_H
+
+#include <opie/xmltree.h>
+#include <qlist.h>
+#include <qstringlist.h>
+
+
+class syntaxModeListItem
+{
+ public:
+ QString name;
+ QString section;
+ QString mimetype;
+ QString extension;
+ QString identifier;
+};
+
+class syntaxContextData
+{
+ public:
+ Opie::XMLElement *parent;
+ Opie::XMLElement *currentGroup;
+ Opie::XMLElement *item;
+};
+
+typedef QList<syntaxModeListItem> SyntaxModeList;
+
+class SyntaxDocument
+{
+ public:
+ SyntaxDocument();
+ ~SyntaxDocument();
+
+ QStringList& finddata(const QString& mainGroup,const QString& type,bool clearList=true);
+ SyntaxModeList modeList();
+
+ syntaxContextData* getGroupInfo(const QString& langName, const QString &group);
+ void freeGroupInfo(syntaxContextData* data);
+ syntaxContextData* getConfig(const QString& mainGroupName, const QString &Config);
+ bool nextItem(syntaxContextData* data);
+ bool nextGroup(syntaxContextData* data);
+ syntaxContextData* getSubItems(syntaxContextData* data);
+ QString groupItemData(syntaxContextData* data,QString name);
+ QString groupData(syntaxContextData* data,QString name);
+ void setIdentifier(const QString& identifier);
+
+ private:
+ Opie::XMLElement *m_root;
+ void setupModeList(bool force=false);
+ QString currentFile;
+ SyntaxModeList myModeList;
+ QStringList m_data;
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/document/katetextline.cpp b/noncore/apps/tinykate/libkate/document/katetextline.cpp
new file mode 100644
index 0000000..f44cc1c
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katetextline.cpp
@@ -0,0 +1,289 @@
+/*
+ Copyright (C) 1998, 1999 Jochen Wilhelmy
+ digisnap@cs.tu-berlin.de
+ (C) 2002, 2001 The Kate Team <kwrite-devel@kde.org>
+ (C) 2002 Joseph Wenninger <jowenn@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "katetextline.h"
+#include <kdebug.h>
+
+TextLine::TextLine(uchar attribute, int context)
+ : text(0L), attributes(0L), attr(attribute), ctx(context), myMark (0)
+{
+}
+
+TextLine::~TextLine()
+{
+}
+
+
+void TextLine::replace(uint pos, uint delLen, const QChar *insText, uint insLen, uchar *insAttribs)
+{
+ uint oldLen = text.length();
+
+ text.remove (pos, delLen);
+ text.insert (pos, insText, insLen);
+
+ if (oldLen<text.length()) attributes.resize (text.length());
+
+ if (text.length() == 0)
+ {
+ attributes.resize (0);
+ return;
+ }
+
+ if (pos >= oldLen)
+ {
+ for (uint t=oldLen; t < attributes.size(); t++)
+ {
+ attributes[t]=0;
+ }
+ }
+
+ int newAtStuff = insLen-delLen;
+ for (uint m=pos+delLen; m < attributes.size(); m++)
+ {
+ if (m+newAtStuff >= attributes.size()) break;
+ if (m >= attributes.size()) break;
+
+ attributes[m+newAtStuff]=attributes[m];
+ }
+
+ if (insAttribs == 0L)
+ {
+ for (uint m3=pos; m3 < pos+insLen; m3++)
+ {
+ if (m3 < attributes.size()) attributes[m3]=0;
+ }
+ }
+ else
+ {
+ for (uint m2=pos; m2 < pos+insLen; m2++)
+ {
+ if (m2 < attributes.size()) attributes[m2]=insAttribs[m2-pos];
+ }
+ }
+
+ if (oldLen>text.length()) attributes.resize (text.length());
+}
+
+void TextLine::wrap(TextLine::Ptr nextLine, uint pos)
+{
+ int l = text.length() - pos;
+
+ if (l > 0)
+ {
+ nextLine->replace(0, 0, &text.unicode()[pos], l, &attributes[pos]);
+ attr = attributes[pos];
+ truncate(pos);
+ }
+}
+
+void TextLine::unWrap(uint pos, TextLine::Ptr nextLine, uint len) {
+
+ replace(pos, 0, nextLine->text.unicode(), len, nextLine->attributes.data());
+ attr = nextLine->getRawAttr(len);
+ nextLine->replace(0, len, 0L, 0);
+}
+
+int TextLine::firstChar() const {
+ uint z = 0;
+
+ while (z < text.length() && text[z].isSpace()) z++;
+
+ if (z < text.length())
+ return z;
+ else
+ return -1;
+}
+
+int TextLine::lastChar() const {
+ uint z = text.length();
+
+ while (z > 0 && text[z - 1].isSpace()) z--;
+ return z;
+}
+
+void TextLine::removeSpaces() {
+
+ while (text.length() > 0 && text[text.length() - 1].isSpace()) text.truncate (text.length()-1);
+}
+
+QChar TextLine::getChar(uint pos) const {
+ if (pos < text.length()) return text.constref(pos);
+ return ' ';
+}
+const QChar *TextLine::firstNonSpace()
+{
+ const QChar *ptr=getText();
+ int first=firstChar();
+ return (first > -1) ? ptr+first : ptr;
+}
+
+bool TextLine::startingWith(QString& match)
+{
+ return text.startsWith (match);
+}
+
+bool TextLine::endingWith(QString& match) {
+
+ int matchLen = match.length();
+
+ // Get the last chars of the textline
+ QString lastChars = text.right(matchLen);
+
+ return (lastChars == match);
+}
+
+int TextLine::cursorX(uint pos, uint tabChars) const {
+ int l, x, z;
+
+ l = (pos < text.length()) ? pos : text.length();
+ x = 0;
+ for (z = 0; z < l; z++) {
+ if (text[z] == '\t') x += tabChars - (x % tabChars); else x++;
+ }
+ x += pos - l;
+ return x;
+}
+
+void TextLine::setAttribs(uchar attribute, uint start, uint end) {
+ uint z;
+
+ if (end > text.length()) end = text.length();
+ for (z = start; z < end; z++) attributes[z] = (attributes[z] & taSelected) | attribute;
+}
+
+void TextLine::setAttr(uchar attribute) {
+ attr = (attr & taSelected) | attribute;
+}
+
+uchar TextLine::getAttr(uint pos) const {
+ if (pos < text.length()) return attributes[pos] & taAttrMask;
+ return attr & taAttrMask;
+}
+
+uchar TextLine::getAttr() const {
+ return attr & taAttrMask;
+}
+
+uchar TextLine::getRawAttr(uint pos) const {
+ if (pos < text.length()) return attributes[pos];
+ return (attr & taSelected) ? attr : attr | 256;
+}
+
+uchar TextLine::getRawAttr() const {
+ return attr;
+}
+
+void TextLine::setContext(int context) {
+ ctx = context;
+}
+
+int TextLine::getContext() const {
+ return ctx;
+}
+
+
+void TextLine::select(bool sel, uint start, uint end) {
+ uint z;
+
+ if (end > text.length()) end = text.length();
+ if (sel) {
+ for (z = start; z < end; z++) attributes[z] |= taSelected;
+ } else {
+ for (z = start; z < end; z++) attributes[z] &= ~taSelected;
+ }
+}
+
+void TextLine::selectEol(bool sel, uint pos) {
+ uint z;
+
+ if (sel) {
+ for (z = pos; z < text.length(); z++) attributes[z] |= taSelected;
+ attr |= taSelected;
+ } else {
+ for (z = pos; z < text.length(); z++) attributes[z] &= ~taSelected;
+ attr &= ~taSelected;
+ }
+}
+
+
+void TextLine::toggleSelect(uint start, uint end) {
+ uint z;
+
+ if (end > text.length()) end = text.length();
+ for (z = start; z < end; z++) attributes[z] = attributes[z] ^ taSelected;
+}
+
+
+void TextLine::toggleSelectEol(uint pos) {
+ uint z;
+
+ for (z = pos; z < text.length(); z++) attributes[z] = attributes[z] ^ taSelected;
+ attr = attr ^ taSelected;
+}
+
+
+int TextLine::numSelected() const {
+ uint z, n;
+
+ n = 0;
+ for (z = 0; z < text.length(); z++) if (attributes[z] & taSelected) n++;
+ return n;
+}
+
+bool TextLine::isSelected(uint pos) const {
+ if (pos < text.length()) return (attributes[pos] & taSelected);
+ return (attr & taSelected);
+}
+
+bool TextLine::isSelected() const {
+ return (attr & taSelected);
+}
+
+int TextLine::findSelected(uint pos) const {
+ while (pos < text.length() && attributes[pos] & taSelected) pos++;
+ return pos;
+}
+
+int TextLine::findUnselected(uint pos) const {
+ while (pos < text.length() && !(attributes[pos] & taSelected)) pos++;
+ return pos;
+}
+
+int TextLine::findRevSelected(uint pos) const {
+ while (pos > 0 && attributes[pos - 1] & taSelected) pos--;
+ return pos;
+}
+
+int TextLine::findRevUnselected(uint pos) const {
+ while (pos > 0 && !(attributes[pos - 1] & taSelected)) pos--;
+ return pos;
+}
+
+void TextLine::addMark (uint m)
+{
+ myMark = myMark | m;
+}
+
+void TextLine::delMark (uint m)
+{
+ myMark = myMark & ~m;
+}
diff --git a/noncore/apps/tinykate/libkate/document/katetextline.h b/noncore/apps/tinykate/libkate/document/katetextline.h
new file mode 100644
index 0000000..c2968cc
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katetextline.h
@@ -0,0 +1,359 @@
+/*
+ Copyright (C) 1998, 1999 Jochen Wilhelmy
+ digisnap@cs.tu-berlin.de
+ (C) 2002, 2001 The Kate Team <kwrite-devel@kde.org>
+ (C) 2002 Joseph Wenninger <jowenn@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _KWTEXTLINE_H_
+#define _KWTEXTLINE_H_
+
+#include <stdlib.h>
+
+#include <qstring.h>
+#include <qarray.h>
+#include <qvaluelist.h>
+
+#include <ksharedptr.h>
+
+/**
+ FastValueList: QValueList, but with a faster at() like QList
+ FVPrivate is needed so that "const" functions can change the
+ current position
+*/
+template<class T>
+class FVPrivate
+{
+public:
+ int curpos;
+ typedef QValueListConstIterator<T> Iterator;
+ Iterator curit;
+
+ FVPrivate() { curpos=-1; };
+};
+
+template<class T>
+class FastValueList : public QValueList<T>
+{
+public:
+ typedef QValueListIterator<T> Iterator;
+ typedef QValueListConstIterator<T> ConstIterator;
+protected:
+ FVPrivate<T> *fvp;
+
+ Iterator fastat( uint i ) {
+ uint num=count();
+ if (i>=num) {return end();}
+ if (fvp->curpos<0) { fvp->curpos=0; fvp->curit=begin(); }
+ uint curpos=(uint) fvp->curpos;
+ Iterator curit(fvp->curit.node);
+ if (curpos==i) return curit;
+
+ int diff=i-curpos;
+ bool forward;
+ if (diff<0) diff=-diff;
+ if (((uint)diff < i) && ((uint)diff < num-i)) { // start from current node
+ forward=i > (uint)curpos;
+ } else if (i < num - i) { // start from first node
+ curit=begin(); diff=i; forward=TRUE;
+ } else { // start from last node
+ curit=fromLast(); diff=num - i - 1;
+ if (diff<0) diff=0;
+ forward=FALSE;
+ }
+ if (forward) {
+ while(diff--) curit++;
+ } else {
+ while(diff--) curit--;
+ }
+ fvp->curpos=i; fvp->curit=curit;
+ return curit;
+ }
+ ConstIterator fastat( uint i ) const {
+ uint num=count();
+ if (i>=num) {return end();}
+ if (fvp->curpos<0) { fvp->curpos=0; fvp->curit=begin(); }
+ uint curpos=(uint) fvp->curpos;
+ ConstIterator curit=fvp->curit;
+ if (curpos==i) return curit;
+
+ int diff=i-curpos;
+ bool forward;
+ if (diff<0) diff=-diff;
+ if (((uint)diff < i) && ((uint)diff < num-i)) { // start from current node
+ forward=i > (uint)curpos;
+ } else if (i < num - i) { // start from first node
+ curit=begin(); diff=i; forward=TRUE;
+ } else { // start from last node
+ curit=fromLast(); diff=num - i - 1;
+ if (diff<0) diff=0;
+ forward=FALSE;
+ }
+ if (forward) {
+ while(diff--) curit++;
+ } else {
+ while(diff--) curit--;
+ }
+ fvp->curpos=i; fvp->curit=curit;
+ return curit;
+ }
+
+public:
+ FastValueList() : QValueList<T>()
+ { fvp=new FVPrivate<T>(); }
+ FastValueList(const FastValueList<T>& l) : QValueList<T>(l)
+ { fvp=new FVPrivate<T>(); }
+ ~FastValueList() { delete fvp; }
+
+ Iterator insert( Iterator it, const T& x ) {
+ fvp->curpos=-1; return QValueList<T>::insert(it, x);
+ }
+
+ Iterator append( const T& x ) {
+ fvp->curpos=-1; return QValueList<T>::append( x );
+ }
+ Iterator prepend( const T& x ) {
+ fvp->curpos=-1; return QValueList<T>::prepend( x );
+ }
+
+ Iterator remove( Iterator it ) {
+ fvp->curpos=-1; return QValueList<T>::remove( it );
+ }
+ void remove( const T& x ) {
+ fvp->curpos=-1; QValueList<T>::remove( x );
+ }
+
+ T& operator[] ( uint i ) { detach(); return fastat(i); }
+ const T& operator[] ( uint i ) const { return *fastat(i); }
+ Iterator at( uint i ) { detach(); return fastat(i); }
+ ConstIterator at( uint i ) const { return ConstIterator( fastat(i) ); }
+};
+
+
+/**
+ The TextLine represents a line of text. A text line that contains the
+ text, an attribute for each character, an attribute for the free space
+ behind the last character and a context number for the syntax highlight.
+ The attribute stores the index to a table that contains fonts and colors
+ and also if a character is selected.
+*/
+class TextLine : public KShared
+{
+ friend class KWBuffer;
+ friend class KWBufBlock;
+
+public:
+ typedef KSharedPtr<TextLine> Ptr;
+ typedef FastValueList<Ptr> List;
+
+public:
+ /**
+ Creates an empty text line with given attribute and syntax highlight
+ context
+ */
+ TextLine(uchar attribute = 0, int context = 0);
+ ~TextLine();
+
+ /**
+ Returns the length
+ */
+ uint length() const {return text.length();}
+ /**
+ Universal text manipulation method. It can be used to insert, delete
+ or replace text.
+ */
+ void replace(uint pos, uint delLen, const QChar *insText, uint insLen, uchar *insAttribs = 0L);
+
+ /**
+ Appends a string of length l to the textline
+ */
+ void append(const QChar *s, uint l) {replace(text.length(), 0, s, l);}
+ /**
+ Wraps the text from the given position to the end to the next line
+ */
+ void wrap(TextLine::Ptr nextLine, uint pos);
+ /**
+ Wraps the text of given length from the beginning of the next line to
+ this line at the given position
+ */
+ void unWrap(uint pos, TextLine::Ptr nextLine, uint len);
+ /**
+ Truncates the textline to the new length
+ */
+ void truncate(uint newLen) { text.truncate(newLen); attributes.resize(text.length()); }
+ /**
+ Returns the position of the first character which is not a white space
+ */
+ int firstChar() const;
+ /**
+ Returns the position of the last character which is not a white space
+ */
+ int lastChar() const;
+ /**
+ Removes trailing spaces
+ */
+ void removeSpaces();
+ /**
+ Gets the char at the given position
+ */
+ QChar getChar(uint pos) const;
+ /**
+ Gets the text. WARNING: it is not null terminated
+ */
+ const QChar *getText() const {return text.unicode();};
+ /**
+ Gets a C-like null terminated string
+ */
+ const QString getString() { return text; };
+
+ /*
+ Gets a null terminated pointer to first non space char
+ */
+ const QChar *firstNonSpace();
+ /**
+ Returns the x position of the cursor at the given position, which
+ depends on the number of tab characters
+ */
+ int cursorX(uint pos, uint tabChars) const;
+ /**
+ Is the line starting with the given string
+ */
+ bool startingWith(QString& match);
+ /**
+ Is the line ending with the given string
+ */
+ bool endingWith(QString& match);
+
+ /**
+ Sets the attributes from start to end -1
+ */
+ void setAttribs(uchar attribute, uint start, uint end);
+ /**
+ Sets the attribute for the free space behind the last character
+ */
+ void setAttr(uchar attribute);
+ /**
+ Gets the attribute at the given position
+ */
+ uchar getAttr(uint pos) const;
+ /**
+ Gets the attribute for the free space behind the last character
+ */
+ uchar getAttr() const;
+ /**
+ Gets the attribute, including the select state, at the given position
+ */
+ uchar getRawAttr(uint pos) const;
+ /**
+ Gets the attribute, including the select state, for the free space
+ behind the last character
+ */
+ uchar getRawAttr() const;
+
+ /**
+ Sets the syntax highlight context number
+ */
+ void setContext(int context);
+ /**
+ Gets the syntax highlight context number
+ */
+ int getContext() const;
+
+ /**
+ Sets the select state from start to end -1
+ */
+ void select(bool sel, uint start, uint end);
+ /**
+ Sets the select state from the given position to the end, including
+ the free space behind the last character
+ */
+ void selectEol(bool sel, uint pos);
+ /**
+ Toggles the select state from start to end -1
+ */
+ void toggleSelect(uint start, uint end);
+ /**
+ Toggles the select state from the given position to the end, including
+ the free space behind the last character
+ */
+ void toggleSelectEol(uint pos);
+ /**
+ Returns the number of selected characters
+ */
+ int numSelected() const;
+ /**
+ Returns if the character at the given position is selected
+ */
+ bool isSelected(uint pos) const;
+ /**
+ Returns true if the free space behind the last character is selected
+ */
+ bool isSelected() const;
+ /**
+ Finds the next selected character, starting at the given position
+ */
+ int findSelected(uint pos) const;
+ /**
+ Finds the next unselected character, starting at the given position
+ */
+ int findUnselected(uint pos) const;
+ /**
+ Finds the previous selected character, starting at the given position
+ */
+ int findRevSelected(uint pos) const;
+ /**
+ Finds the previous unselected character, starting at the given position
+ */
+ int findRevUnselected(uint pos) const;
+
+ void clearMark () { myMark = 0; };
+ void addMark ( uint m );
+ void delMark ( uint m );
+ uint mark() { return myMark; };
+
+ uchar *getAttribs() { return attributes.data(); }
+
+ protected:
+ /**
+ The text
+ */
+ QString text;
+ /**
+ The attributes
+ */
+ QArray<uchar> attributes;
+ /**
+ The attribute of the free space behind the end
+ */
+ uchar attr;
+ /**
+ The syntax highlight context
+ */
+ int ctx;
+ /**
+ The marks of the current line
+ */
+ uint myMark;
+};
+
+//text attribute constants
+const int taSelected = 0x40;
+const int taAttrMask = ~taSelected & 0xFF;
+
+#endif //KWTEXTLINE_H
+
diff --git a/noncore/apps/tinykate/libkate/interfaces/document.h b/noncore/apps/tinykate/libkate/interfaces/document.h
new file mode 100644
index 0000000..cbfd1b3
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/interfaces/document.h
@@ -0,0 +1,103 @@
+/***************************************************************************
+ document.h - description
+ -------------------
+ begin : Mon Jan 15 2001
+ copyright : (C) 2001 by Christoph "Crossfire" Cullmann
+ (C) 2002 by Joseph Wenninger
+ email : crossfire@babylon2k.de
+ jowenn@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ ***************************************************************************/
+
+#ifndef _KATE_DOCUMENT_INCLUDE_
+#define _KATE_DOCUMENT_INCLUDE_
+
+#include <ktexteditor.h>
+
+class KConfig;
+
+namespace Kate
+{
+
+/** internal class for document bookmarks. */
+class Mark
+{
+ public:
+ uint line;
+ uint type;
+};
+
+/** This interface provedes access to the Kate Document class.
+*/
+class Document : public KTextEditor::Document
+{
+ Q_OBJECT
+
+ public:
+ Document ();
+ virtual ~Document ();
+
+ public:
+ /** Read document config.
+ */
+ virtual void readConfig () { ; };
+ /** Save document config.
+ */
+ virtual void writeConfig () { ; };
+
+ /** Read document session config.
+ */
+ virtual void readSessionConfig (KConfig *) { ; };
+ /** Save document session config.
+ */
+ virtual void writeSessionConfig (KConfig *) { ; };
+
+ /** Returns the document ID.
+ */
+ virtual uint docID () { return 0L; };
+
+ /** Defines possible mark types. A line can have marks of different types.
+ */
+ enum marks
+ {
+ Bookmark = 1,
+ Breakpoint = 2,
+ markType0 = 4,
+ markType1 = 8,
+ markType2 = 16,
+ markType3 = 32,
+ markType4 = 64,
+ markType5 = 128,
+ markType6 = 256,
+ markType7 = 512,
+ markType8 = 1024
+ };
+
+ /** A list of all marks in a document. Use binary comparing to find marks of a specific type.
+ */
+ virtual QList<Mark> marks () { QList<Mark> l; return l; };
+
+ public slots:
+ // clear buffer/filename - update the views
+ virtual void flush () { ; };
+};
+
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/interfaces/interfaces.cpp b/noncore/apps/tinykate/libkate/interfaces/interfaces.cpp
new file mode 100644
index 0000000..4fdd252
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/interfaces/interfaces.cpp
@@ -0,0 +1,51 @@
+/***************************************************************************
+ interfaces.cpp - description
+ -------------------
+ begin : Mon Jan 15 2001
+ copyright : (C) 2001 by Christoph "Crossfire" Cullmann
+ (C) 2002 by Joseph Wenninger
+ email : crossfire@babylon2k.de
+ jowenn@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ ***************************************************************************/
+
+#include "document.h"
+
+#include "view.h"
+
+namespace Kate
+{
+
+Document::Document () : KTextEditor::Document (0L, 0L)
+{
+}
+
+Document::~Document ()
+{
+}
+
+View::View ( KTextEditor::Document *doc, QWidget *parent, const char *name ) : KTextEditor::View (doc, parent, name)
+{
+}
+
+View::~View ()
+{
+}
+
+};
diff --git a/noncore/apps/tinykate/libkate/interfaces/view.h b/noncore/apps/tinykate/libkate/interfaces/view.h
new file mode 100644
index 0000000..5b24bb5
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/interfaces/view.h
@@ -0,0 +1,160 @@
+/***************************************************************************
+ view.h - description
+ -------------------
+ begin : Mon Jan 15 2001
+ copyright : (C) 2001 by Christoph "Crossfire" Cullmann
+ (C) 2002 by Joseph Wenninger
+ email : crossfire@babylon2k.de
+ jowenn@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ ***************************************************************************/
+
+#ifndef _KATE_VIEW_INCLUDE_
+#define _KATE_VIEW_INCLUDE_
+
+#include <ktexteditor.h>
+
+class KConfig;
+
+namespace Kate
+{
+
+class Document;
+class Mark;
+
+/** This interface provides access to the view.
+*/
+class View : public KTextEditor::View
+{
+ Q_OBJECT
+
+ public:
+ View ( KTextEditor::Document *doc, QWidget *parent, const char *name = 0 );
+ virtual ~View ();
+
+ /** Returns a pointer to the document of the view.
+ */
+ virtual Document *getDoc () { return 0L; };
+
+ /** Returns the marked text in the view.
+ */
+ virtual QString markedText () { return 0L; };
+
+ public slots:
+ /** popup a config dialog for the editor part.
+ */
+ virtual void configDialog () { ; };
+
+ // Highlighting slots
+ virtual void setHl (int) { ; };
+ virtual int getHl () { return 0; };
+ virtual int getHlCount () { return 0; };
+ virtual QString getHlName (int) { return 0L; };
+ virtual QString getHlSection (int) { return 0L; };
+
+ // undo/redo stuff
+ virtual void undo () { ; };
+ virtual void redo () { ; };
+ virtual void undoHistory() { ; };
+
+ public:
+ // read/save config of the view
+ virtual void readConfig () { ; };
+ virtual void writeConfig () { ; };
+
+ // read/save sessionconfig of the view
+ virtual void readSessionConfig (KConfig *) { ; };
+ virtual void writeSessionConfig (KConfig *) { ; };
+
+ public slots:
+ // some simply key commands
+ virtual void keyReturn () { ; };
+ virtual void keyDelete () { ; };
+ virtual void backspace () { ; };
+ virtual void killLine () { ; };
+
+ // move cursor in the view
+ virtual void cursorLeft () { ; };
+ virtual void shiftCursorLeft () { ; };
+ virtual void cursorRight () { ; };
+ virtual void shiftCursorRight () { ; };
+ virtual void wordLeft () { ; };
+ virtual void shiftWordLeft () { ; };
+ virtual void wordRight () { ; };
+ virtual void shiftWordRight () { ; };
+ virtual void home () { ; };
+ virtual void shiftHome () { ; };
+ virtual void end () { ; };
+ virtual void shiftEnd () { ; };
+ virtual void up () { ; };
+ virtual void shiftUp () { ; };
+ virtual void down () { ; };
+ virtual void shiftDown () { ; };
+ virtual void scrollUp () { ; };
+ virtual void scrollDown () { ; };
+ virtual void topOfView () { ; };
+ virtual void bottomOfView () { ; };
+ virtual void pageUp () { ; };
+ virtual void shiftPageUp () { ; };
+ virtual void pageDown () { ; };
+ virtual void shiftPageDown () { ; };
+ virtual void top () { ; };
+ virtual void shiftTop () { ; };
+ virtual void bottom () { ; };
+ virtual void shiftBottom () { ; };
+
+ public slots:
+ // edit command popup window
+ virtual void slotEditCommand () { ; };
+
+ // icon border enable/disable
+ virtual void setIconBorder (bool) { ; };
+ virtual void toggleIconBorder () { ; };
+
+ // goto mark
+ virtual void gotoMark (Mark *) { ; };
+
+ // toggle current line bookmark or clear all bookmarks
+ virtual void toggleBookmark () { ; };
+ virtual void clearBookmarks () { ; };
+
+ public:
+ // is iconborder visible ?
+ virtual bool iconBorder() { return false; };
+
+ public slots:
+ /**
+ Flushes the document of the text widget. The user is given
+ a chance to save the current document if the current document has
+ been modified.
+ */
+ virtual void flush () { ; };
+
+ public:
+ /**
+ Returns true if the current document can be
+ discarded. If the document is modified, the user is asked if he wants
+ to save it. On "cancel" the function returns false.
+ */
+ virtual bool canDiscard() { return false; };
+};
+
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/ktexteditor/ktexteditor.cpp b/noncore/apps/tinykate/libkate/ktexteditor/ktexteditor.cpp
new file mode 100644
index 0000000..6b4d86d
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/ktexteditor/ktexteditor.cpp
@@ -0,0 +1,140 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
+ Copyright (C) 2002 Joseph Wenninger <jowenn@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+
+#include "ktexteditor.h"
+
+using namespace KTextEditor;
+
+class View::ViewPrivate
+{
+public:
+ ViewPrivate()
+ {
+ }
+ ~ViewPrivate()
+ {
+ }
+
+ Document *m_doc;
+ bool m_bContextPopup;
+};
+
+View::View( Document *doc, QWidget *parent, const char *name )
+: QWidget( parent, name )
+{
+ d = new ViewPrivate;
+ d->m_doc = doc;
+ d->m_bContextPopup = true;
+}
+
+View::~View()
+{
+ delete d;
+}
+
+Document *View::document() const
+{
+ return d->m_doc;
+}
+
+void View::insertText( const QString &text, bool mark )
+{
+ int line, col;
+ getCursorPosition( &line, &col );
+ document()->insertAt( text, line, col, mark );
+}
+
+void View::setInternalContextMenuEnabled( bool b )
+{
+ d->m_bContextPopup = b;
+}
+
+bool View::internalContextMenuEnabled() const
+{
+ return d->m_bContextPopup;
+}
+
+class Document::DocumentPrivate
+{
+public:
+ DocumentPrivate()
+ {
+ }
+ ~DocumentPrivate()
+ {
+ }
+
+};
+
+Document::Document( QObject *parent, const char *name )
+ : QObject(parent,name)
+{
+ d = new DocumentPrivate;
+}
+
+Document::~Document()
+{
+ //one never knows...
+ QListIterator<View> it( m_views );
+
+ for (; it.current(); ++it )
+ disconnect( it.current(), SIGNAL( destroyed() ),
+ this, SLOT( slotViewDestroyed() ) );
+
+ delete d;
+}
+
+QList<View> Document::views() const
+{
+ return m_views;
+}
+
+void Document::addView( View *view )
+{
+ if ( !view )
+ return;
+
+ if ( m_views.findRef( view ) != -1 )
+ return;
+
+ m_views.append( view );
+ connect( view, SIGNAL( destroyed() ),
+ this, SLOT( slotViewDestroyed() ) );
+}
+
+void Document::removeView( View *view )
+{
+ if ( !view )
+ return;
+
+ disconnect( view, SIGNAL( destroyed() ),
+ this, SLOT( slotViewDestroyed() ) );
+
+ m_views.removeRef( view );
+}
+
+void Document::slotViewDestroyed()
+{
+ const View *view = static_cast<const View *>( sender() );
+ m_views.removeRef( view );
+}
+
+
diff --git a/noncore/apps/tinykate/libkate/ktexteditor/ktexteditor.h b/noncore/apps/tinykate/libkate/ktexteditor/ktexteditor.h
new file mode 100644
index 0000000..595b5d3
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/ktexteditor/ktexteditor.h
@@ -0,0 +1,239 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
+ Copyright (C) 2002 Joseph Wenninger <jowenn@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __ktexteditor_h__
+#define __ktexteditor_h__
+
+#include <qwidget.h>
+#include <qlist.h>
+
+/**
+ * This is the kparts interface classes for text editors.
+ * The text editors use the Document/View model that allows multiple views into
+ * one file (Document)
+ *
+ * Line numbers passed via this interface must begin at line number zero (0).
+ *
+ * TODO: See documentation at http://??????? for information on how to use kparts in
+ * general. A simple (but sufficient) implementation is shown below.
+ *
+ * <pre>
+ * QHBoxLayout *layout = new QHBoxLayout(this);
+ * QSplitter *fixme = new QSplitter(this);
+ *
+ * KTrader::OfferList offers = KTrader::self()->query( "KTextEditor/Document" );
+ * assert( offers.count() >= 1 );
+ * KService::Ptr service = *offers.begin();
+ * KLibFactory *factory = KLibLoader::self()->factory( service->library() );
+ * assert( factory );
+ * m_part = static_cast<KTextEditor::Document *>(
+ * factory->create( this, 0, "KTextEditor::Document" ) );
+ * assert( m_part );
+ * m_part->createView( fixme, 0 );
+ * layout->addWidget(fixme);
+ * m_part->setText( "" );
+ * </pre>
+ *
+ * You may also be able to use a dynamic_cast for the document part above
+ * (depending on compliation of the library used)
+ *
+ */
+
+namespace KTextEditor
+{
+
+class Document;
+
+/**
+ * The View class encapsulates a single view into the document.
+ */
+
+class View : public QWidget
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Create a new view to the given document. The document must be non-null.
+ */
+ View( Document *doc, QWidget *parent, const char *name = 0 );
+ virtual ~View();
+
+ /**
+ * Acessor to the parent Document.
+ */
+ virtual Document *document() const; // XXX fix when renaming KXMLGUIClient::document
+
+ virtual void setCursorPosition( int line, int col, bool mark = false ) = 0;
+ virtual void getCursorPosition( int *line, int *col ) = 0;
+
+ /**
+ * Inserts text at the current cursor position into the document
+ */
+ virtual void insertText( const QString &text, bool mark = false );
+
+ /**
+ * Overwrite mode is where the char under the cursor is replaced with the
+ * char typed by the user
+ */
+ virtual bool isOverwriteMode() const = 0;
+
+ /**
+ * You should reimplement this method.
+ * If the internal popupmenu property is enabled, then the implementation
+ * is free to handle/use/implement/show a context popupmenu ( see also
+ * KContextMenuManager class in kdeui ). If disabled, then the
+ * implementation should emit the @ref contextPopupMenu signal.
+ */
+ virtual void setInternalContextMenuEnabled( bool b );
+ virtual bool internalContextMenuEnabled() const;
+
+public slots:
+ virtual void setOverwriteMode( bool b ) = 0;
+
+signals:
+ /**
+ * Connect here when you want to implement a custom popup menu.
+ */
+ void contextPopupMenu( const QPoint &p );
+
+ /**
+ * Connect here if you want to track the scrolling within the editor. This
+ * allows you to add specialised borders that displays extra data about
+ * particular lines such as breakpoints etc.
+ */
+ void scrollValueChanged( int value );
+
+private:
+ class ViewPrivate;
+ ViewPrivate *d;
+};
+
+class Document : public QObject
+{
+ Q_OBJECT
+public:
+ Document( QObject *parent = 0, const char *name = 0 );
+ virtual ~Document();
+
+ /**
+ * Create a view that will display the document data. You can create as many
+ * views as you like. When the user modifies data in one view then all other
+ * views will be updated as well.
+ */
+ virtual View *createView( QWidget *parent, const char *name = 0 ) = 0;
+
+ /*
+ * Accessor to the list of views.
+ */
+ virtual QList<View> views() const;
+
+ /**
+ * @return All the text from the requested line.
+ */
+ virtual QString textLine( int line ) const = 0;
+
+ virtual void setSelection( int row_from, int col_from, int row_to, int col_t ) = 0;
+ virtual bool hasSelection() const = 0;
+ virtual QString selection() const = 0;
+
+ /**
+ * @return The current number of lines in the document
+ */
+ virtual int numLines() const = 0;
+
+ /**
+ * Insert line(s) at the given line number. If the line number is -1
+ * (the default) then the line is added to end of the document
+ */
+ virtual void insertLine( const QString &s, int line = -1 ) = 0;
+
+ /**
+ * Add the line(s) into the document at the given line and column.
+ */
+ virtual void insertAt( const QString &s, int line, int col, bool mark = FALSE ) = 0;
+
+ virtual void removeLine( int line ) = 0;
+
+ /**
+ * @return the complete document as a single QString
+ */
+ virtual QString text() const = 0;
+
+ /**
+ * @return the number of characters in the document
+ */
+ virtual int length() const = 0;
+
+public slots:
+ /**
+ * Set the given text into the view.
+ * Warning: This will overwrite any data currently held in this view.
+ */
+ virtual void setText( const QString &t ) = 0;
+
+signals:
+
+ /**
+ * When the user changes the text then this signal is emitted
+ * TODO: - explain why and what type of change trigger this?
+ */
+ void textChanged();
+
+ /**
+ */
+ void deleted( int startLine, int endLine );
+
+ /**
+ */
+ void inserted( int startLine, int endLine );
+
+protected:
+ /**
+ * Call this method in your document implementation whenever you created a new
+ * view.
+ * (like in @ref createView )
+ */
+ virtual void addView( View *view );
+
+ /**
+ * Call this method in your document implementation whenever you delete a view.
+ */
+ virtual void removeView( View *view );
+
+ QList<View> m_views;
+
+private slots:
+
+ /**
+ * The view emits a destroyed() signal which is connected to this slot
+ * and removed from our internal list. Note: The view* is obtained from
+ * the QObject::sender() method.
+ */
+ void slotViewDestroyed();
+
+private:
+ class DocumentPrivate;
+ DocumentPrivate *d;
+};
+
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/libkate.pro b/noncore/apps/tinykate/libkate/libkate.pro
new file mode 100644
index 0000000..a504abf
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/libkate.pro
@@ -0,0 +1,90 @@
+TEMPLATE = lib
+CONFIG = qt warn_on release
+DESTDIR = $(OPIEDIR)/bin
+HEADERS = microkde/kapplication.h \
+ microkde/kconfig.h \
+ microkde/kdebug.h \
+ microkde/kdialog.h \
+ microkde/kdialogbase.h \
+ microkde/kfiledialog.h \
+ microkde/kglobal.h \
+ microkde/kiconloader.h \
+ microkde/klineedit.h \
+ microkde/klocale.h \
+ microkde/kmessagebox.h \
+ microkde/kprinter.h \
+ microkde/krestrictedline.h \
+ microkde/kseparator.h \
+ microkde/ksimpleconfig.h \
+ microkde/kstandarddirs.h \
+ microkde/ktempfile.h \
+ microkde/kunload.h \
+ microkde/kurlrequester.h \
+ microkde/kfontdialog.h \
+ microkde/krun.h \
+ microkde/knumvalidator.h \
+ microkde/kstaticdeleter.h \
+ microkde/klistview.h \
+ microkde/kglobalsettings.h \
+ microkde/kcolorbtn.h \
+ \
+ \
+ qt3back/qregexp3.h \
+ kde/ksharedptr.h \
+ document/katebuffer.h document/katedialogs.h \
+ document/katetextline.h \
+ document/katecmd.h \
+ document/katehighlight.h \
+ document/katecmds.h document/katedocument.h \
+ document/katesyntaxdocument.h \
+ view/kateundohistory.h \
+ view/kateview.h \
+ view/kateviewdialog.h \
+ interfaces/view.h \
+ interfaces/document.h \
+ ktexteditor/ktexteditor.h
+
+SOURCES = microkde/kapplication.cpp \
+ microkde/kdialogbase.cpp \
+ microkde/kconfig.cpp \
+ microkde/klocale.cpp \
+ microkde/kmessagebox.cpp \
+ microkde/kprocess.cpp \
+ microkde/kstandarddirs.cpp \
+ microkde/ktempfile.cpp \
+ microkde/kurlrequester.cpp \
+ microkde/kcolordialog.cpp \
+ microkde/kfontdialog.cpp \
+ microkde/krun.cpp \
+ microkde/knumvalidator.cpp \
+ microkde/kglobal.cpp \
+ microkde/kglobalsettings.cpp \
+ microkde/kcolorbtn.cpp \
+ \
+ \
+ qt3back/qregexp3.cpp \
+ ktexteditor/ktexteditor.cpp \
+ document/katebuffer.cpp document/katedialogs.cpp \
+ document/katehighlight.cpp \
+ document/katecmd.cpp \
+ document/katesyntaxdocument.cpp document/katecmds.cpp \
+ document/katedocument.cpp document/katetextline.cpp \
+ view/kateundohistory.cpp \
+ view/kateview.cpp \
+ view/kateviewdialog.cpp \
+ interfaces/interfaces.cpp
+
+INTERFACES =
+INCLUDEPATH += $(OPIEDIR)/include $(OPIEDIR)/noncore/apps/tinykate/libkate/microkde \
+ $(OPIEDIR)/noncore/apps/tinykate/libkate/document \
+ $(OPIEDIR)/noncore/apps/tinykate/libkate/view \
+ $(OPIEDIR)/noncore/apps/tinykate/libkate/interfaces \
+ $(OPIEDIR)/noncore/apps/tinykate/libkate/ktexteditor \
+ $(OPIEDIR)/noncore/apps/tinykate/libkate/qt3back
+DEPENDPATH += $(OPIEDIR)/include
+LIBS += -lqpe -lopie
+TARGET = tinykate
+
+INCLUDEPATH += $(OPIEDIR)/include
+DESTDIR = $(QTDIR)/lib$(PROJMAK)
+
diff --git a/noncore/apps/tinykate/libkate/microkde/kaction.h b/noncore/apps/tinykate/libkate/microkde/kaction.h
new file mode 100644
index 0000000..622330e
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kaction.h
@@ -0,0 +1,8 @@
+#ifndef MINIKDE_KACTION_H
+#define MINIKDE_KACTION_H
+
+#include <qaction.h>
+
+#define KAction QAction
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kapplication.cpp b/noncore/apps/tinykate/libkate/microkde/kapplication.cpp
new file mode 100644
index 0000000..60ed579
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kapplication.cpp
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+
+#include "kapplication.h"
+
+int KApplication::random()
+{
+ return rand();
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/kapplication.h b/noncore/apps/tinykate/libkate/microkde/kapplication.h
new file mode 100644
index 0000000..99fb4f0
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kapplication.h
@@ -0,0 +1,11 @@
+#ifndef MINIKDE_KAPPLICATION_H
+#define MINIKDE_KAPPLICATION_H
+
+class KApplication
+{
+ public:
+ static int random();
+ static int cursorFlashTime() { return 1000; }
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kcolorbtn.cpp b/noncore/apps/tinykate/libkate/microkde/kcolorbtn.cpp
new file mode 100644
index 0000000..5d21f15
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kcolorbtn.cpp
@@ -0,0 +1,84 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 1997 Martin Jones (mjones@kde.org)
+ Copyright (C) 1999 Cristian Tibirna (ctibirna@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <qdialog.h>
+#include <qpainter.h>
+#include <qdrawutil.h>
+#include <qapplication.h>
+#include <kglobalsettings.h>
+#include "kcolordialog.h"
+#include "kcolorbtn.h"
+
+KColorButton::KColorButton( QWidget *parent, const char *name )
+ : QPushButton( parent, name ), dragFlag(false)
+{
+ // 2000-10-15 (putzer): fixes broken keyboard usage
+ connect (this, SIGNAL(clicked()), this, SLOT(chooseColor()));
+}
+
+KColorButton::KColorButton( const QColor &c, QWidget *parent,
+ const char *name )
+ : QPushButton( parent, name ), col(c), dragFlag(false)
+{
+
+ // 2000-10-15 (putzer): fixes broken keyboard usage
+ connect (this, SIGNAL(clicked()), this, SLOT(chooseColor()));
+}
+
+void KColorButton::setColor( const QColor &c )
+{
+ col = c;
+ repaint( false );
+}
+
+void KColorButton::drawButtonLabel( QPainter *painter )
+{
+ QRect r = QApplication::style().buttonRect( 0, 0, width(), height() );
+ int l = r.x();
+ int t = r.y();
+ int w = r.width();
+ int h = r.height();
+ int b = 5;
+
+ QColor lnCol = colorGroup().text();
+ QColor fillCol = isEnabled() ? col : backgroundColor();
+
+ if ( isDown() ) {
+ qDrawPlainRect( painter, l+b+1, t+b+1, w-b*2, h-b*2, lnCol, 1, 0 );
+ b++;
+ painter->fillRect( l+b+1, t+b+1, w-b*2, h-b*2, fillCol );
+ } else {
+ qDrawPlainRect( painter, l+b, t+b, w-b*2, h-b*2, lnCol, 1, 0 );
+ b++;
+ painter->fillRect( l+b, t+b, w-b*2, h-b*2, fillCol );
+ }
+}
+
+void KColorButton::chooseColor()
+{
+ if( KColorDialog::getColor( col) == QDialog::Rejected )
+ {
+ return;
+ }
+
+ repaint( false );
+ emit changed( col );
+}
+
diff --git a/noncore/apps/tinykate/libkate/microkde/kcolorbtn.h b/noncore/apps/tinykate/libkate/microkde/kcolorbtn.h
new file mode 100644
index 0000000..b79d5e8
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kcolorbtn.h
@@ -0,0 +1,92 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 1997 Martin Jones (mjones@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __COLBTN_H__
+#define __COLBTN_H__
+
+#include <qpushbutton.h>
+
+/**
+* This widget can be used to display or allow user selection of a colour.
+*
+* @see KColorDialog
+*
+* @short A pushbutton to display or allow user selection of a colour.
+* @version $Id$
+*/
+class KColorButton : public QPushButton
+{
+ Q_OBJECT
+ Q_PROPERTY( QColor color READ color WRITE setColor )
+
+public:
+ /**
+ * Constructor. Create a KColorButton.
+ */
+ KColorButton( QWidget *parent, const char *name = 0L );
+ /**
+ * Constructor. Create a KColorButton.
+ * @param c The initial colour of the button.
+ */
+ KColorButton( const QColor &c, QWidget *parent, const char *name = 0L );
+ /**
+ * Destructor.
+ */
+ virtual ~KColorButton() {}
+
+ /**
+ * The current colour.
+ * @return The current colour.
+ */
+ QColor color() const
+ { return col; }
+ /**
+ * Set the current colour.
+ *
+ * @param c The colour to set.
+ */
+ void setColor( const QColor &c );
+
+signals:
+ /**
+ * This signal will be emitted when the colour of the widget
+ * is changed, either with @ref #setColor() or via user selection.
+ */
+ void changed( const QColor &newColor );
+
+protected slots:
+ void chooseColor();
+
+protected:
+ /**
+ * @reimplemented
+ */
+ virtual void drawButtonLabel( QPainter *p );
+
+private:
+ QColor col;
+ QPoint mPos;
+ bool dragFlag;
+
+ class KColorButtonPrivate;
+ KColorButtonPrivate *d;
+};
+
+#endif
+
diff --git a/noncore/apps/tinykate/libkate/microkde/kcolorbutton.h b/noncore/apps/tinykate/libkate/microkde/kcolorbutton.h
new file mode 100644
index 0000000..b446eca
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kcolorbutton.h
@@ -0,0 +1,4 @@
+#ifndef K_COLOR_BUTTON_H
+#define K_COLOR_BUTTON_H
+#include <kcolorbtn.h>
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kcolordialog.cpp b/noncore/apps/tinykate/libkate/microkde/kcolordialog.cpp
new file mode 100644
index 0000000..3aee42a
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kcolordialog.cpp
@@ -0,0 +1,6 @@
+#include "kcolordialog.h"
+
+int KColorDialog::getColor( const QColor & )
+{
+ return 0;
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/kcolordialog.h b/noncore/apps/tinykate/libkate/microkde/kcolordialog.h
new file mode 100644
index 0000000..0f831cd
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kcolordialog.h
@@ -0,0 +1,14 @@
+#ifndef MINIKDE_KCOLORDIALOG_H
+#define MINIKDE_KCOLORDIALOG_H
+
+#include <qcolor.h>
+
+class KColorDialog
+{
+ public:
+ enum { Accepted };
+
+ static int getColor( const QColor & );
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kconfig.cpp b/noncore/apps/tinykate/libkate/microkde/kconfig.cpp
new file mode 100644
index 0000000..d88bda0
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kconfig.cpp
@@ -0,0 +1,181 @@
+#include <qfile.h>
+#include <qtextstream.h>
+
+#include "kdebug.h"
+
+#include "kconfig.h"
+
+QString KConfig::mGroup = "";
+//QString KConfig::mGroup = "General";
+
+KConfig::KConfig( const QString &fileName )
+ : mFileName( fileName ), mDirty( false )
+{
+ kdDebug() << "KConfig::KConfig(): '" << fileName << "'" << endl;
+
+ load();
+}
+
+
+KConfig::~KConfig()
+{
+ sync();
+}
+
+void KConfig::setGroup( const QString &group )
+{
+ return;
+
+// kdDebug() << "KConfig::setGroup(): '" << group << "'" << endl;
+
+ mGroup = group;
+
+ if ( mGroup.right( 1 ) != "/" ) mGroup += "/";
+}
+
+
+QValueList<int> KConfig::readIntListEntry( const QString & )
+{
+ QValueList<int> l;
+ return l;
+}
+
+int KConfig::readNumEntry( const QString &, int def )
+{
+ return def;
+}
+
+QString KConfig::readEntry( const QString &key, const QString &def )
+{
+ QMap<QString,QString>::ConstIterator it = mStringMap.find( mGroup + key );
+
+ if ( it == mStringMap.end() ) {
+ return def;
+ }
+
+ return *it;
+}
+
+QStringList KConfig::readListEntry( const QString & )
+{
+ return QStringList();
+}
+
+bool KConfig::readBoolEntry( const QString &key, bool def )
+{
+ QMap<QString,bool>::ConstIterator it = mBoolMap.find( mGroup + key );
+
+ if ( it == mBoolMap.end() ) {
+ return def;
+ }
+
+ return *it;
+}
+
+QColor KConfig::readColorEntry( const QString &, QColor *def )
+{
+ if ( def ) return *def;
+ return QColor();
+}
+
+QFont KConfig::readFontEntry( const QString &, QFont *def )
+{
+ if ( def ) return *def;
+ return QFont();
+}
+
+
+void KConfig::writeEntry( const QString &, QValueList<int> )
+{
+}
+
+void KConfig::writeEntry( const QString &, int )
+{
+}
+
+void KConfig::writeEntry( const QString &key, const QString &value )
+{
+ mStringMap.insert( mGroup + key, value );
+
+ mDirty = true;
+}
+
+void KConfig::writeEntry( const QString &, const QStringList & )
+{
+}
+
+void KConfig::writeEntry( const QString &key, bool value)
+{
+ mBoolMap.insert( mGroup + key, value );
+
+ mDirty = true;
+}
+
+void KConfig::writeEntry( const QString &, const QColor & )
+{
+}
+
+void KConfig::writeEntry( const QString &, const QFont & )
+{
+}
+
+void KConfig::load()
+{
+ mBoolMap.clear();
+ mStringMap.clear();
+
+ QFile f( mFileName );
+ if ( !f.open( IO_ReadOnly ) ) {
+ kdDebug() << "KConfig::load(): Can't open file '" << mFileName << "'"
+ << endl;
+ return;
+ }
+
+
+ QTextStream t( &f );
+
+ QString line = t.readLine();
+
+ while ( !line.isNull() ) {
+ QStringList tokens = QStringList::split( ",", line );
+ if ( tokens[0] == "bool" ) {
+ bool value = false;
+ if ( tokens[2] == "1" ) value = true;
+
+ mBoolMap.insert( tokens[1], value );
+ } else if ( tokens[0] == "QString" ) {
+ QString value = tokens[2];
+ mStringMap.insert( tokens[1], value );
+ }
+
+ line = t.readLine();
+ }
+}
+
+void KConfig::sync()
+{
+ if ( !mDirty ) return;
+
+ QFile f( mFileName );
+ if ( !f.open( IO_WriteOnly ) ) {
+ kdDebug() << "KConfig::sync(): Can't open file '" << mFileName << "'"
+ << endl;
+ return;
+ }
+
+ QTextStream t( &f );
+
+ QMap<QString,bool>::ConstIterator itBool;
+ for( itBool = mBoolMap.begin(); itBool != mBoolMap.end(); ++itBool ) {
+ t << "bool," << itBool.key() << "," << (*itBool ) << endl;
+ }
+
+ QMap<QString,QString>::ConstIterator itString;
+ for( itString = mStringMap.begin(); itString != mStringMap.end(); ++itString ) {
+ t << "QString," << itString.key() << "," << (*itString ) << endl;
+ }
+
+ f.close();
+
+ mDirty = false;
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/kconfig.h b/noncore/apps/tinykate/libkate/microkde/kconfig.h
new file mode 100644
index 0000000..8bd768a
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kconfig.h
@@ -0,0 +1,51 @@
+#ifndef MINIKDE_KCONFIG_H
+#define MINIKDE_KCONFIG_H
+
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qvaluelist.h>
+#include <qcolor.h>
+#include <qfont.h>
+#include <qmap.h>
+
+class KConfig
+{
+ public:
+ KConfig( const QString & );
+ ~KConfig();
+
+ void setGroup( const QString & );
+
+ bool hasGroup( const QString &) {return false;}
+
+ QValueList<int> readIntListEntry( const QString & );
+ int readNumEntry( const QString &, int def=0 );
+ QString readEntry( const QString &, const QString &def=QString::null );
+ QStringList readListEntry( const QString & );
+ bool readBoolEntry( const QString &, bool def=false );
+ QColor readColorEntry( const QString &, QColor * );
+ QFont readFontEntry( const QString &, QFont * );
+
+ void writeEntry( const QString &, QValueList<int> );
+ void writeEntry( const QString &, int );
+ void writeEntry( const QString &, const QString & );
+ void writeEntry( const QString &, const QStringList & );
+ void writeEntry( const QString &, bool );
+ void writeEntry( const QString &, const QColor & );
+ void writeEntry( const QString &, const QFont & );
+
+ void load();
+ void sync();
+
+ private:
+ static QString mGroup;
+
+ QString mFileName;
+
+ QMap<QString,bool> mBoolMap;
+ QMap<QString,QString> mStringMap;
+
+ bool mDirty;
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kdatepicker.cpp b/noncore/apps/tinykate/libkate/microkde/kdatepicker.cpp
new file mode 100644
index 0000000..2cdd609
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kdatepicker.cpp
@@ -0,0 +1,405 @@
+/* -*- C++ -*-
+ This file is part of the KDE libraries
+ Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org)
+ (C) 1998-2001 Mirko Boehm (mirko@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "kdatepicker.h"
+#include <kglobal.h>
+#include <kapplication.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <qframe.h>
+#include <qpainter.h>
+#include <qdialog.h>
+#include <qtoolbutton.h>
+#include <qfont.h>
+#include <qlineedit.h>
+#include <qvalidator.h>
+#include <kdebug.h>
+#include <knotifyclient.h>
+#include "kdatetbl.h"
+#include "kdatepicker.moc"
+
+
+KDatePicker::KDatePicker(QWidget *parent, QDate dt, const char *name)
+ : QFrame(parent,name),
+ yearForward(new QToolButton(this)),
+ yearBackward(new QToolButton(this)),
+ monthForward(new QToolButton(this)),
+ monthBackward(new QToolButton(this)),
+ selectMonth(new QToolButton(this)),
+ selectYear(new QToolButton(this)),
+ line(new QLineEdit(this)),
+ val(new KDateValidator(this)),
+ table(new KDateTable(this)),
+ fontsize(10)
+{
+ // -----
+ setFontSize(10);
+ line->setValidator(val);
+ yearForward->setPixmap(BarIcon(QString::fromLatin1("2rightarrow")));
+ yearBackward->setPixmap(BarIcon(QString::fromLatin1("2leftarrow")));
+ monthForward->setPixmap(BarIcon(QString::fromLatin1("1rightarrow")));
+ monthBackward->setPixmap(BarIcon(QString::fromLatin1("1leftarrow")));
+ setDate(dt); // set button texts
+ connect(table, SIGNAL(dateChanged(QDate)), SLOT(dateChangedSlot(QDate)));
+ connect(table, SIGNAL(tableClicked()), SLOT(tableClickedSlot()));
+ connect(monthForward, SIGNAL(clicked()), SLOT(monthForwardClicked()));
+ connect(monthBackward, SIGNAL(clicked()), SLOT(monthBackwardClicked()));
+ connect(yearForward, SIGNAL(clicked()), SLOT(yearForwardClicked()));
+ connect(yearBackward, SIGNAL(clicked()), SLOT(yearBackwardClicked()));
+ connect(selectMonth, SIGNAL(clicked()), SLOT(selectMonthClicked()));
+ connect(selectYear, SIGNAL(clicked()), SLOT(selectYearClicked()));
+ connect(line, SIGNAL(returnPressed()), SLOT(lineEnterPressed()));
+}
+
+KDatePicker::~KDatePicker()
+{
+}
+
+void
+KDatePicker::resizeEvent(QResizeEvent*)
+{
+ QWidget *buttons[] = {
+ yearBackward,
+ monthBackward,
+ selectMonth,
+ selectYear,
+ monthForward,
+ yearForward };
+ const int NoOfButtons=sizeof(buttons)/sizeof(buttons[0]);
+ QSize sizes[NoOfButtons];
+ int buttonHeight=0;
+ int count;
+ int w;
+ int x=0;
+ // ----- calculate button row height:
+ for(count=0; count<NoOfButtons; ++count) {
+ sizes[count]=buttons[count]->sizeHint();
+ buttonHeight=QMAX(buttonHeight, sizes[count].height());
+ }
+ // ----- calculate size of the month button:
+ w=0;
+ for(count=0; count<NoOfButtons; ++count) {
+ if(buttons[count]!=selectMonth)
+ {
+ w+=sizes[count].width();
+ } else {
+ x=count;
+ }
+ }
+ sizes[x].setWidth(width()-w); // stretch the month button
+ // ----- place the buttons:
+ x=0;
+ for(count=0; count<NoOfButtons; ++count)
+ {
+ w=sizes[count].width();
+ buttons[count]->setGeometry(x, 0, w, buttonHeight);
+ x+=w;
+ }
+ // ----- place the line edit for direct input:
+ sizes[0]=line->sizeHint();
+ line->setGeometry(0, height()-sizes[0].height(), width(), sizes[0].height());
+ // ----- adjust the table:
+ table->setGeometry(0, buttonHeight, width(),
+ height()-buttonHeight-sizes[0].height());
+}
+
+void
+KDatePicker::dateChangedSlot(QDate date)
+{
+ kdDebug() << "KDatePicker::dateChangedSlot: date changed (" << date.year() << "/" << date.month() << "/" << date.day() << ")." << endl;
+ line->setText(KGlobal::locale()->formatDate(date, true));
+ emit(dateChanged(date));
+}
+
+void
+KDatePicker::tableClickedSlot()
+{
+ kdDebug() << "KDatePicker::tableClickedSlot: table clicked." << endl;
+ emit(dateSelected(table->getDate()));
+ emit(tableClicked());
+}
+
+const QDate&
+KDatePicker::getDate() const
+{
+ return table->getDate();
+}
+
+const QDate &
+KDatePicker::date() const
+{
+ return table->getDate();
+}
+
+bool
+KDatePicker::setDate(const QDate& date)
+{
+ if(date.isValid()) {
+ QString temp;
+ // -----
+ table->setDate(date);
+ selectMonth->setText(KGlobal::locale()->monthName(date.month(), false));
+ temp.setNum(date.year());
+ selectYear->setText(temp);
+ line->setText(KGlobal::locale()->formatDate(date, true));
+ return true;
+ } else {
+ kdDebug() << "KDatePicker::setDate: refusing to set invalid date." << endl;
+ return false;
+ }
+}
+
+void
+KDatePicker::monthForwardClicked()
+{
+ QDate temp=table->getDate();
+ int day=temp.day();
+ // -----
+ if(temp.month()==12) {
+ temp.setYMD(temp.year()+1, 1, 1);
+ } else {
+ temp.setYMD(temp.year(), temp.month()+1, 1);
+ }
+ if(temp.daysInMonth()<day) {
+ temp.setYMD(temp.year(), temp.month(), temp.daysInMonth());
+ } else {
+ temp.setYMD(temp.year(), temp.month(), day);
+ }
+ // assert(temp.isValid());
+ setDate(temp);
+}
+
+void
+KDatePicker::monthBackwardClicked()
+{
+ QDate temp=table->getDate();
+ int day=temp.day();
+ // -----
+ if(temp.month()==1)
+ {
+ temp.setYMD(temp.year()-1, 12, 1);
+ } else {
+ temp.setYMD(temp.year(), temp.month()-1, 1);
+ }
+ if(temp.daysInMonth()<day)
+ {
+ temp.setYMD(temp.year(), temp.month(), temp.daysInMonth());
+ } else {
+ temp.setYMD(temp.year(), temp.month(), day);
+ }
+ // assert(temp.isValid());
+ setDate(temp);
+}
+
+void
+KDatePicker::yearForwardClicked()
+{
+ QDate temp=table->getDate();
+ int day=temp.day();
+ // -----
+ temp.setYMD(temp.year()+1, temp.month(), 1);
+ if(temp.daysInMonth()<day)
+ {
+ temp.setYMD(temp.year(), temp.month(), temp.daysInMonth());
+ } else {
+ temp.setYMD(temp.year(), temp.month(), day);
+ }
+ // assert(temp.isValid());
+ setDate(temp);
+}
+
+void
+KDatePicker::yearBackwardClicked()
+{
+ QDate temp=table->getDate();
+ int day=temp.day();
+ // -----
+ temp.setYMD(temp.year()-1, temp.month(), 1);
+ if(temp.daysInMonth()<day)
+ {
+ temp.setYMD(temp.year(), temp.month(), temp.daysInMonth());
+ } else {
+ temp.setYMD(temp.year(), temp.month(), day);
+ }
+ // assert(temp.isValid());
+ setDate(temp);
+}
+
+void
+KDatePicker::selectMonthClicked()
+{
+ int month;
+ KPopupFrame* popup = new KPopupFrame(this);
+ KDateInternalMonthPicker* picker = new KDateInternalMonthPicker(fontsize, popup);
+ // -----
+ picker->resize(picker->sizeHint());
+ popup->setMainWidget(picker);
+ picker->setFocus();
+ connect(picker, SIGNAL(closeMe(int)), popup, SLOT(close(int)));
+ if(popup->exec(selectMonth->mapToGlobal(QPoint(0, selectMonth->height()))))
+ {
+ QDate date;
+ int day;
+ // -----
+ month=picker->getResult();
+ date=table->getDate();
+ day=date.day();
+ // ----- construct a valid date in this month:
+ date.setYMD(date.year(), month, 1);
+ date.setYMD(date.year(), month, QMIN(day, date.daysInMonth()));
+ // ----- set this month
+ setDate(date);
+ } else {
+ KNotifyClient::beep();
+ }
+ delete popup;
+}
+
+void
+KDatePicker::selectYearClicked()
+{
+ int year;
+ KPopupFrame* popup = new KPopupFrame(this);
+ KDateInternalYearSelector* picker = new KDateInternalYearSelector(fontsize, popup);
+ // -----
+ picker->resize(picker->sizeHint());
+ popup->setMainWidget(picker);
+ connect(picker, SIGNAL(closeMe(int)), popup, SLOT(close(int)));
+ picker->setFocus();
+ if(popup->exec(selectYear->mapToGlobal(QPoint(0, selectMonth->height()))))
+ {
+ QDate date;
+ int day;
+ // -----
+ year=picker->getYear();
+ date=table->getDate();
+ day=date.day();
+ // ----- construct a valid date in this month:
+ date.setYMD(year, date.month(), 1);
+ date.setYMD(year, date.month(), QMIN(day, date.daysInMonth()));
+ // ----- set this month
+ setDate(date);
+ } else {
+ KNotifyClient::beep();
+ }
+ delete popup;
+}
+
+void
+KDatePicker::setEnabled(bool enable)
+{
+ QWidget *widgets[]= {
+ yearForward, yearBackward, monthForward, monthBackward,
+ selectMonth, selectYear,
+ line, table };
+ const int Size=sizeof(widgets)/sizeof(widgets[0]);
+ int count;
+ // -----
+ for(count=0; count<Size; ++count)
+ {
+ widgets[count]->setEnabled(enable);
+ }
+}
+
+void
+KDatePicker::lineEnterPressed()
+{
+ QDate temp;
+ // -----
+ if(val->date(line->text(), temp)==QValidator::Acceptable)
+ {
+ kdDebug() << "KDatePicker::lineEnterPressed: valid date entered." << endl;
+ emit(dateEntered(temp));
+ setDate(temp);
+ } else {
+ KNotifyClient::beep();
+ kdDebug() << "KDatePicker::lineEnterPressed: invalid date entered." << endl;
+ }
+}
+
+QSize
+KDatePicker::sizeHint() const
+{
+ QSize tableSize=table->sizeHint();
+ QWidget *buttons[]={
+ yearBackward,
+ monthBackward,
+ selectMonth,
+ selectYear,
+ monthForward,
+ yearForward };
+ const int NoOfButtons=sizeof(buttons)/sizeof(buttons[0]);
+ QSize sizes[NoOfButtons];
+ int cx=0, cy=0, count;
+ // ----- store the size hints:
+ for(count=0; count<NoOfButtons; ++count)
+ {
+ sizes[count]=buttons[count]->sizeHint();
+ if(buttons[count]==selectMonth)
+ {
+ cx+=maxMonthRect.width();
+ } else {
+ cx+=sizes[count].width();
+ }
+ cy=QMAX(sizes[count].height(), cy);
+ }
+ // ----- calculate width hint:
+ cx=QMAX(cx, tableSize.width()); // line edit ignored
+ // ----- calculate height hint:
+ cy+=tableSize.height()+line->sizeHint().height();
+ return QSize(cx, cy);
+}
+
+void
+KDatePicker::setFontSize(int s)
+{
+ QWidget *buttons[]= {
+ // yearBackward,
+ // monthBackward,
+ selectMonth,
+ selectYear,
+ // monthForward,
+ // yearForward
+ };
+ const int NoOfButtons=sizeof(buttons)/sizeof(buttons[0]);
+ int count;
+ QFont font;
+ QRect r;
+ // -----
+ fontsize=s;
+ for(count=0; count<NoOfButtons; ++count)
+ {
+ font=buttons[count]->font();
+ font.setPointSize(s);
+ buttons[count]->setFont(font);
+ }
+ QFontMetrics metrics(selectMonth->fontMetrics());
+ for(int i=1; i <= 12; ++i)
+ { // maxMonthRect is used by sizeHint()
+ r=metrics.boundingRect(KGlobal::locale()->monthName(i, false));
+ maxMonthRect.setWidth(QMAX(r.width(), maxMonthRect.width()));
+ maxMonthRect.setHeight(QMAX(r.height(), maxMonthRect.height()));
+ }
+ table->setFontSize(s);
+}
+
+void KDatePicker::virtual_hook( int id, void* data )
+{ /*BASE::virtual_hook( id, data );*/ }
+
diff --git a/noncore/apps/tinykate/libkate/microkde/kdatepicker.h b/noncore/apps/tinykate/libkate/microkde/kdatepicker.h
new file mode 100644
index 0000000..8fe8d66
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kdatepicker.h
@@ -0,0 +1,177 @@
+/* -*- C++ -*-
+ This file is part of the KDE libraries
+ Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org)
+ (C) 1998-2001 Mirko Boehm (mirko@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+#ifndef MICROKDE_KDATEPICKER_H
+#define MICROKDE_KDATEPICKER_H
+#include <qdatetime.h>
+#include <qframe.h>
+
+class QLineEdit;
+class QToolButton;
+class KDateValidator;
+class KDateTable;
+
+/**
+ * Provides a widget for calendar date input.
+ *
+ * Different from the
+ * previous versions, it now emits two types of signals, either
+ * @ref dateSelected() or @ref dateEntered() (see documentation for both
+ * signals).
+ *
+ * A line edit has been added in the newer versions to allow the user
+ * to select a date directly by entering numbers like 19990101
+ * or 990101.
+ *
+ * @image kdatepicker.png KDatePicker
+ *
+ * @version $Id$
+ * @author Tim Gilman, Mirko Boehm
+ *
+ * @short A date selection widget.
+ **/
+class KDatePicker: public QFrame
+{
+ Q_OBJECT
+public:
+ /** The usual constructor. The given date will be displayed
+ * initially.
+ **/
+ KDatePicker(QWidget *parent=0,
+ QDate=QDate::currentDate(),
+ const char *name=0);
+ /**
+ * The destructor.
+ **/
+ virtual ~KDatePicker();
+
+ /** The size hint for date pickers. The size hint recommends the
+ * minimum size of the widget so that all elements may be placed
+ * without clipping. This sometimes looks ugly, so when using the
+ * size hint, try adding 28 to each of the reported numbers of
+ * pixels.
+ **/
+ QSize sizeHint() const;
+
+ /**
+ * Sets the date.
+ *
+ * @returns @p false and does not change anything
+ * if the date given is invalid.
+ **/
+ bool setDate(const QDate&);
+
+ /**
+ * Returns the selected date.
+ * @deprecated
+ **/
+ const QDate& getDate() const;
+
+ /**
+ * @returns the selected date.
+ */
+ const QDate &date() const;
+
+ /**
+ * Enables or disables the widget.
+ **/
+ void setEnabled(bool);
+
+ /**
+ * Sets the font size of the widgets elements.
+ **/
+ void setFontSize(int);
+ /**
+ * Returns the font size of the widget elements.
+ */
+ int fontSize() const
+ { return fontsize; }
+
+protected:
+ /// the resize event
+ void resizeEvent(QResizeEvent*);
+ /// the year forward button
+ QToolButton *yearForward;
+ /// the year backward button
+ QToolButton *yearBackward;
+ /// the month forward button
+ QToolButton *monthForward;
+ /// the month backward button
+ QToolButton *monthBackward;
+ /// the button for selecting the month directly
+ QToolButton *selectMonth;
+ /// the button for selecting the year directly
+ QToolButton *selectYear;
+ /// the line edit to enter the date directly
+ QLineEdit *line;
+ /// the validator for the line edit:
+ KDateValidator *val;
+ /// the date table
+ KDateTable *table;
+ /// the size calculated during resize events
+ // QSize sizehint;
+ /// the widest month string in pixels:
+ QSize maxMonthRect;
+protected slots:
+ void dateChangedSlot(QDate);
+ void tableClickedSlot();
+ void monthForwardClicked();
+ void monthBackwardClicked();
+ void yearForwardClicked();
+ void yearBackwardClicked();
+ void selectMonthClicked();
+ void selectYearClicked();
+ void lineEnterPressed();
+signals:
+ /** This signal is emitted each time the selected date is changed.
+ * Usually, this does not mean that the date has been entered,
+ * since the date also changes, for example, when another month is
+ * selected.
+ * @see dateSelected
+ */
+ void dateChanged(QDate);
+ /** This signal is emitted each time a day has been selected by
+ * clicking on the table (hitting a day in the current month). It
+ * has the same meaning as dateSelected() in older versions of
+ * KDatePicker.
+ */
+ void dateSelected(QDate);
+ /** This signal is emitted when enter is pressed and a VALID date
+ * has been entered before into the line edit. Connect to both
+ * dateEntered() and dateSelected() to receive all events where the
+ * user really enters a date.
+ */
+ void dateEntered(QDate);
+ /** This signal is emitted when the day has been selected by
+ * clicking on it in the table.
+ */
+ void tableClicked();
+
+private:
+ /// the font size for the widget
+ int fontsize;
+
+protected:
+ virtual void virtual_hook( int id, void* data );
+private:
+ class KDatePickerPrivate;
+ KDatePickerPrivate *d;
+};
+
+#endif // KDATEPICKER_H
diff --git a/noncore/apps/tinykate/libkate/microkde/kdatetbl.cpp b/noncore/apps/tinykate/libkate/microkde/kdatetbl.cpp
new file mode 100644
index 0000000..c56991d
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kdatetbl.cpp
@@ -0,0 +1,718 @@
+/* -*- C++ -*-
+ This file is part of the KDE libraries
+ Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org)
+ (C) 1998-2001 Mirko Boehm (mirko@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/////////////////// KDateTable widget class //////////////////////
+//
+// Copyright (C) 1997 Tim D. Gilman
+// (C) 1998-2001 Mirko Boehm
+// Written using Qt (http://www.troll.no) for the
+// KDE project (http://www.kde.org)
+//
+// This is a support class for the KDatePicker class. It just
+// draws the calender table without titles, but could theoretically
+// be used as a standalone.
+//
+// When a date is selected by the user, it emits a signal:
+// dateSelected(QDate)
+
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <kapplication.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <knotifyclient.h>
+#include "kdatetbl.h"
+#include <qdatetime.h>
+#include <qstring.h>
+#include <qpen.h>
+#include <qpainter.h>
+#include <qdialog.h>
+#include <assert.h>
+#include <qapplication.h>
+
+KDateValidator::KDateValidator(QWidget* parent, const char* name)
+ : QValidator(parent, name)
+{
+}
+
+QValidator::State
+KDateValidator::validate(QString& text, int&) const
+{
+ QDate temp;
+ // ----- everything is tested in date():
+ return date(text, temp);
+}
+
+QValidator::State
+KDateValidator::date(const QString& text, QDate& d) const
+{
+ QDate tmp = KGlobal::locale()->readDate(text);
+ if (!tmp.isNull())
+ {
+ d = tmp;
+ return Acceptable;
+ } else
+ return Valid;
+}
+
+void
+KDateValidator::fixup( QString& ) const
+{
+
+}
+
+KDateTable::KDateTable(QWidget *parent, QDate date_, const char* name, WFlags f)
+ : QGridView(parent, name, f)
+{
+ setFontSize(10);
+ if(!date_.isValid())
+ {
+ kdDebug() << "KDateTable ctor: WARNING: Given date is invalid, using current date." << endl;
+ date_=QDate::currentDate();
+ }
+ setFocusPolicy( QWidget::StrongFocus );
+ setNumRows(7); // 6 weeks max + headline
+ setNumCols(7); // 7 days a week
+ setHScrollBarMode(AlwaysOff);
+ setVScrollBarMode(AlwaysOff);
+#if 0
+ viewport()->setEraseColor(lightGray);
+#endif
+ setDate(date_); // this initializes firstday, numdays, numDaysPrevMonth
+}
+
+void
+KDateTable::paintCell(QPainter *painter, int row, int col)
+{
+ QRect rect;
+ QString text;
+ QPen pen;
+ int w=cellWidth();
+ int h=cellHeight();
+ int pos;
+ QBrush brushBlue(blue);
+ QBrush brushLightblue(lightGray);
+ QFont font=KGlobalSettings::generalFont();
+ // -----
+ font.setPointSize(fontsize);
+ if(row==0)
+ { // we are drawing the headline
+ font.setBold(true);
+ painter->setFont(font);
+ bool normalday = true;
+ QString daystr;
+ if (KGlobal::locale()->weekStartsMonday())
+ {
+ daystr = KGlobal::locale()->weekDayName(col+1, true);
+ if (col == 5 || col == 6)
+ normalday = false;
+ } else {
+ daystr = KGlobal::locale()->weekDayName(col==0? 7 : col, true);
+ if (col == 0 || col == 6)
+ normalday = false;
+ }
+ if (!normalday)
+ {
+ painter->setPen(lightGray);
+ painter->setBrush(brushLightblue);
+ painter->drawRect(0, 0, w, h);
+ painter->setPen(blue);
+ } else {
+ painter->setPen(blue);
+ painter->setBrush(brushBlue);
+ painter->drawRect(0, 0, w, h);
+ painter->setPen(white);
+ }
+ painter->drawText(0, 0, w, h-1, AlignCenter,
+ daystr, -1, &rect);
+ painter->setPen(black);
+ painter->moveTo(0, h-1);
+ painter->lineTo(w-1, h-1);
+ // ----- draw the weekday:
+ } else {
+ painter->setFont(font);
+ pos=7*(row-1)+col;
+ if (KGlobal::locale()->weekStartsMonday())
+ pos++;
+ if(pos<firstday || (firstday+numdays<=pos))
+ { // we are either
+ // ° painting a day of the previous month or
+ // ° painting a day of the following month
+ if(pos<firstday)
+ { // previous month
+ text.setNum(numDaysPrevMonth+pos-firstday+1);
+ } else { // following month
+ text.setNum(pos-firstday-numdays+1);
+ }
+ painter->setPen(gray);
+ } else { // paint a day of the current month
+ text.setNum(pos-firstday+1);
+ painter->setPen(black);
+ }
+
+ pen=painter->pen();
+ if(firstday+date.day()-1==pos)
+ {
+ if(hasFocus())
+ { // draw the currently selected date
+ painter->setPen(red);
+ painter->setBrush(darkRed);
+ pen=white;
+ } else {
+ painter->setPen(darkGray);
+ painter->setBrush(darkGray);
+ pen=white;
+ }
+ } else {
+ painter->setBrush(lightGray);
+ painter->setPen(lightGray);
+ }
+ painter->drawRect(0, 0, w, h);
+ painter->setPen(pen);
+ painter->drawText(0, 0, w, h, AlignCenter, text, -1, &rect);
+ }
+ if(rect.width()>maxCell.width()) maxCell.setWidth(rect.width());
+ if(rect.height()>maxCell.height()) maxCell.setHeight(rect.height());
+}
+
+void
+KDateTable::keyPressEvent( QKeyEvent *e )
+{
+ if ( e->key() == Qt::Key_Prior ) {
+ if ( date.month() == 1 ) {
+ KNotifyClient::beep();
+ return;
+ }
+ int day = date.day();
+ if ( day > 27 )
+ while ( !QDate::isValid( date.year(), date.month()-1, day ) )
+ day--;
+ setDate(QDate(date.year(), date.month()-1, day));
+ return;
+ }
+ if ( e->key() == Qt::Key_Next ) {
+ if ( date.month() == 12 ) {
+ KNotifyClient::beep();
+ return;
+ }
+ int day = date.day();
+ if ( day > 27 )
+ while ( !QDate::isValid( date.year(), date.month()+1, day ) )
+ day--;
+ setDate(QDate(date.year(), date.month()+1, day));
+ return;
+ }
+
+ int dayoff = KGlobal::locale()->weekStartsMonday() ? 1 : 0;
+
+ int temp=firstday+date.day()-dayoff;
+ int pos = temp;
+
+ if ( e->key() == Qt::Key_Up ) {
+ pos -= 7;
+ }
+ if ( e->key() == Qt::Key_Down ) {
+ pos += 7;
+ }
+ if ( e->key() == Qt::Key_Left ) {
+ pos--;
+ }
+ if ( e->key() == Qt::Key_Right ) {
+ pos++;
+ }
+
+ if(pos+dayoff<=firstday)
+ { // this day is in the previous month
+ KNotifyClient::beep();
+ return;
+ }
+ if(firstday+numdays<pos+dayoff)
+ { // this date is in the next month
+ KNotifyClient::beep(i18n( "Month not long enough" ));
+ return;
+ }
+
+ if ( pos == temp )
+ return;
+
+ setDate(QDate(date.year(), date.month(), pos-firstday+dayoff));
+ updateCell(temp/7+1, temp%7); // Update the previously selected cell
+ updateCell(pos/7+1, pos%7); // Update the selected cell
+ assert(QDate(date.year(), date.month(), pos-firstday+dayoff).isValid());
+}
+
+void
+KDateTable::viewportResizeEvent(QResizeEvent * e)
+{
+ QGridView::viewportResizeEvent(e);
+
+ setCellWidth(viewport()->width()/7);
+ setCellHeight(viewport()->height()/7);
+}
+
+void
+KDateTable::setFontSize(int size)
+{
+ int count;
+ QFontMetrics metrics(fontMetrics());
+ QRect rect;
+ // ----- store rectangles:
+ fontsize=size;
+ // ----- find largest day name:
+ maxCell.setWidth(0);
+ maxCell.setHeight(0);
+ for(count=0; count<7; ++count)
+ {
+ rect=metrics.boundingRect(KGlobal::locale()->weekDayName(count+1, true));
+ maxCell.setWidth(QMAX(maxCell.width(), rect.width()));
+ maxCell.setHeight(QMAX(maxCell.height(), rect.height()));
+ }
+ // ----- compare with a real wide number and add some space:
+ rect=metrics.boundingRect(QString::fromLatin1("88"));
+ maxCell.setWidth(QMAX(maxCell.width()+2, rect.width()));
+ maxCell.setHeight(QMAX(maxCell.height()+4, rect.height()));
+}
+
+void
+KDateTable::contentsMousePressEvent(QMouseEvent *e)
+{
+ if(e->type()!=QEvent::MouseButtonPress)
+ { // the KDatePicker only reacts on mouse press events:
+ return;
+ }
+ if(!isEnabled())
+ {
+ KNotifyClient::beep();
+ return;
+ }
+
+ int dayoff = KGlobal::locale()->weekStartsMonday() ? 1 : 0;
+ // -----
+ int row, col, pos, temp;
+ QPoint mouseCoord;
+ // -----
+ mouseCoord = e->pos();
+ row=rowAt(mouseCoord.y());
+ col=columnAt(mouseCoord.x());
+ if(row<0 || col<0)
+ { // the user clicked on the frame of the table
+ return;
+ }
+ pos=7*(row-1)+col+1;
+ if(pos+dayoff<=firstday)
+ { // this day is in the previous month
+ KNotifyClient::beep();
+ return;
+ }
+ if(firstday+numdays<pos+dayoff)
+ { // this date is in the next month
+ KNotifyClient::beep();
+ return;
+ }
+ temp=firstday+date.day()-dayoff-1;
+ setDate(QDate(date.year(), date.month(), pos-firstday+dayoff));
+ updateCell(temp/7+1, temp%7); // Update the previously selected cell
+ updateCell(row, col); // Update the selected cell
+ // assert(QDate(date.year(), date.month(), pos-firstday+dayoff).isValid());
+ emit(tableClicked());
+}
+
+bool
+KDateTable::setDate(const QDate& date_)
+{
+ bool changed=false;
+ QDate temp;
+ // -----
+ if(!date_.isValid())
+ {
+ kdDebug() << "KDateTable::setDate: refusing to set invalid date." << endl;
+ return false;
+ }
+ if(date!=date_)
+ {
+ date=date_;
+ changed=true;
+ }
+ temp.setYMD(date.year(), date.month(), 1);
+ firstday=temp.dayOfWeek();
+ if(firstday==1) firstday=8;
+ numdays=date.daysInMonth();
+ if(date.month()==1)
+ { // set to december of previous year
+ temp.setYMD(date.year()-1, 12, 1);
+ } else { // set to previous month
+ temp.setYMD(date.year(), date.month()-1, 1);
+ }
+ numDaysPrevMonth=temp.daysInMonth();
+ if(changed)
+ {
+ repaintContents(false);
+ }
+ emit(dateChanged(date));
+ return true;
+}
+
+const QDate&
+KDateTable::getDate() const
+{
+ return date;
+}
+
+void KDateTable::focusInEvent( QFocusEvent *e )
+{
+ repaintContents(false);
+ QGridView::focusInEvent( e );
+}
+
+void KDateTable::focusOutEvent( QFocusEvent *e )
+{
+ repaintContents(false);
+ QGridView::focusOutEvent( e );
+}
+
+QSize
+KDateTable::sizeHint() const
+{
+ if(maxCell.height()>0 && maxCell.width()>0)
+ {
+ return QSize(maxCell.width()*numCols()+2*frameWidth(),
+ (maxCell.height()+2)*numRows()+2*frameWidth());
+ } else {
+ kdDebug() << "KDateTable::sizeHint: obscure failure - " << endl;
+ return QSize(-1, -1);
+ }
+}
+
+KDateInternalMonthPicker::KDateInternalMonthPicker
+(int fontsize, QWidget* parent, const char* name)
+ : QGridView(parent, name),
+ result(0) // invalid
+{
+ QRect rect;
+ QFont font;
+ // -----
+ activeCol = -1;
+ activeRow = -1;
+ font=KGlobalSettings::generalFont();
+ font.setPointSize(fontsize);
+ setFont(font);
+ setHScrollBarMode(AlwaysOff);
+ setVScrollBarMode(AlwaysOff);
+ setFrameStyle(QFrame::NoFrame);
+ setNumRows(4);
+ setNumCols(3);
+ // enable to find drawing failures:
+ // setTableFlags(Tbl_clipCellPainting);
+#if 0
+ viewport()->setEraseColor(lightGray); // for consistency with the datepicker
+#endif
+ // ----- find the preferred size
+ // (this is slow, possibly, but unfortunatly it is needed here):
+ QFontMetrics metrics(font);
+ for(int i=1; i <= 12; ++i)
+ {
+ rect=metrics.boundingRect(KGlobal::locale()->monthName(i, false));
+ if(max.width()<rect.width()) max.setWidth(rect.width());
+ if(max.height()<rect.height()) max.setHeight(rect.height());
+ }
+
+}
+
+QSize
+KDateInternalMonthPicker::sizeHint() const
+{
+ return QSize((max.width()+6)*numCols()+2*frameWidth(),
+ (max.height()+6)*numRows()+2*frameWidth());
+}
+
+int
+KDateInternalMonthPicker::getResult() const
+{
+ return result;
+}
+
+void
+KDateInternalMonthPicker::setupPainter(QPainter *p)
+{
+ p->setPen(black);
+}
+
+void
+KDateInternalMonthPicker::viewportResizeEvent(QResizeEvent*)
+{
+ setCellWidth(width()/3);
+ setCellHeight(height()/4);
+}
+
+void
+KDateInternalMonthPicker::paintCell(QPainter* painter, int row, int col)
+{
+ int index;
+ QString text;
+ // ----- find the number of the cell:
+ index=3*row+col+1;
+ text=KGlobal::locale()->monthName(index, false);
+ painter->drawText(0, 0, cellWidth(), cellHeight(), AlignCenter, text);
+ if ( activeCol == col && activeRow == row )
+ painter->drawRect( 0, 0, cellWidth(), cellHeight() );
+}
+
+void
+KDateInternalMonthPicker::contentsMousePressEvent(QMouseEvent *e)
+{
+ if(!isEnabled() || e->button() != LeftButton)
+ {
+ KNotifyClient::beep();
+ return;
+ }
+ // -----
+ int row, col;
+ QPoint mouseCoord;
+ // -----
+ mouseCoord = e->pos();
+ row=rowAt(mouseCoord.y());
+ col=columnAt(mouseCoord.x());
+
+ if(row<0 || col<0)
+ { // the user clicked on the frame of the table
+ activeCol = -1;
+ activeRow = -1;
+ } else {
+ activeCol = col;
+ activeRow = row;
+ updateCell( row, col /*, false */ );
+ }
+}
+
+void
+KDateInternalMonthPicker::contentsMouseMoveEvent(QMouseEvent *e)
+{
+ if (e->state() & LeftButton)
+ {
+ int row, col;
+ QPoint mouseCoord;
+ // -----
+ mouseCoord = e->pos();
+ row=rowAt(mouseCoord.y());
+ col=columnAt(mouseCoord.x());
+ int tmpRow = -1, tmpCol = -1;
+ if(row<0 || col<0)
+ { // the user clicked on the frame of the table
+ if ( activeCol > -1 )
+ {
+ tmpRow = activeRow;
+ tmpCol = activeCol;
+ }
+ activeCol = -1;
+ activeRow = -1;
+ } else {
+ bool differentCell = (activeRow != row || activeCol != col);
+ if ( activeCol > -1 && differentCell)
+ {
+ tmpRow = activeRow;
+ tmpCol = activeCol;
+ }
+ if ( differentCell)
+ {
+ activeRow = row;
+ activeCol = col;
+ updateCell( row, col /*, false */ ); // mark the new active cell
+ }
+ }
+ if ( tmpRow > -1 ) // repaint the former active cell
+ updateCell( tmpRow, tmpCol /*, true */ );
+ }
+}
+
+void
+KDateInternalMonthPicker::contentsMouseReleaseEvent(QMouseEvent *e)
+{
+ if(!isEnabled())
+ {
+ return;
+ }
+ // -----
+ int row, col, pos;
+ QPoint mouseCoord;
+ // -----
+ mouseCoord = e->pos();
+ row=rowAt(mouseCoord.y());
+ col=columnAt(mouseCoord.x());
+ if(row<0 || col<0)
+ { // the user clicked on the frame of the table
+ emit(closeMe(0));
+ }
+ pos=3*row+col+1;
+ result=pos;
+ emit(closeMe(1));
+}
+
+
+
+KDateInternalYearSelector::KDateInternalYearSelector
+(int fontsize, QWidget* parent, const char* name)
+ : QLineEdit(parent, name),
+ val(new QIntValidator(this)),
+ result(0)
+{
+ QFont font;
+ // -----
+ font=KGlobalSettings::generalFont();
+ font.setPointSize(fontsize);
+ setFont(font);
+#if 0
+ setFrameStyle(QFrame::NoFrame);
+#endif
+ // we have to respect the limits of QDate here, I fear:
+ val->setRange(0, 8000);
+ setValidator(val);
+ connect(this, SIGNAL(returnPressed()), SLOT(yearEnteredSlot()));
+}
+
+void
+KDateInternalYearSelector::yearEnteredSlot()
+{
+ bool ok;
+ int year;
+ QDate date;
+ // ----- check if this is a valid year:
+ year=text().toInt(&ok);
+ if(!ok)
+ {
+ KNotifyClient::beep();
+ return;
+ }
+ date.setYMD(year, 1, 1);
+ if(!date.isValid())
+ {
+ KNotifyClient::beep();
+ return;
+ }
+ result=year;
+ emit(closeMe(1));
+}
+
+int
+KDateInternalYearSelector::getYear()
+{
+ return result;
+}
+
+void
+KDateInternalYearSelector::setYear(int year)
+{
+ QString temp;
+ // -----
+ temp.setNum(year);
+ setText(temp);
+}
+
+KPopupFrame::KPopupFrame(QWidget* parent, const char* name)
+ : QFrame(parent, name, WType_Popup),
+ result(0), // rejected
+ main(0)
+{
+ setFrameStyle(QFrame::Box|QFrame::Raised);
+ setMidLineWidth(2);
+}
+
+void
+KPopupFrame::keyPressEvent(QKeyEvent* e)
+{
+ if(e->key()==Key_Escape)
+ {
+ result=0; // rejected
+ qApp->exit_loop();
+ }
+}
+
+void
+KPopupFrame::close(int r)
+{
+ result=r;
+ qApp->exit_loop();
+}
+
+void
+KPopupFrame::setMainWidget(QWidget* m)
+{
+ main=m;
+ if(main!=0)
+ {
+ resize(main->width()+2*frameWidth(), main->height()+2*frameWidth());
+ }
+}
+
+void
+KPopupFrame::resizeEvent(QResizeEvent*)
+{
+ if(main!=0)
+ {
+ main->setGeometry(frameWidth(), frameWidth(),
+ width()-2*frameWidth(), height()-2*frameWidth());
+ }
+}
+
+void
+KPopupFrame::popup(const QPoint &pos)
+{
+ // Make sure the whole popup is visible.
+ QRect d = QApplication::desktop()->frameGeometry();
+ int x = pos.x();
+ int y = pos.y();
+ int w = width();
+ int h = height();
+ if (x+w > d.x()+d.width())
+ x = d.width() - w;
+ if (y+h > d.y()+d.height())
+ y = d.height() - h;
+ if (x < d.x())
+ x = 0;
+ if (y < d.y())
+ y = 0;
+
+ // Pop the thingy up.
+ move(x, y);
+ show();
+}
+
+int
+KPopupFrame::exec(QPoint pos)
+{
+ popup(pos);
+ repaint();
+ qApp->enter_loop();
+ hide();
+ return result;
+}
+
+int
+KPopupFrame::exec(int x, int y)
+{
+ return exec(QPoint(x, y));
+}
+
+void KPopupFrame::virtual_hook( int, void* )
+{ /*BASE::virtual_hook( id, data );*/ }
+
+void KDateTable::virtual_hook( int, void* )
+{ /*BASE::virtual_hook( id, data );*/ }
+
+#include "kdatetbl.moc"
diff --git a/noncore/apps/tinykate/libkate/microkde/kdatetbl.h b/noncore/apps/tinykate/libkate/microkde/kdatetbl.h
new file mode 100644
index 0000000..df7b7ef
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kdatetbl.h
@@ -0,0 +1,308 @@
+/* -*- C++ -*-
+ This file is part of the KDE libraries
+ Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org)
+ (C) 1998-2001 Mirko Boehm (mirko@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+#ifndef KDATETBL_H
+#define KDATETBL_H
+
+#include <qvalidator.h>
+#include <qgridview.h>
+#include <qlineedit.h>
+#include <qdatetime.h>
+
+/**
+* A table containing month names. It is used to pick a month directly.
+* @internal
+* @version $Id$
+* @author Tim Gilman, Mirko Boehm
+*/
+class KDateInternalMonthPicker : public QGridView
+{
+ Q_OBJECT
+protected:
+ /**
+ * Store the month that has been clicked [1..12].
+ */
+ int result;
+ /**
+ * the cell under mouse cursor when LBM is pressed
+ */
+ short int activeCol;
+ short int activeRow;
+ /**
+ * Contains the largest rectangle needed by the month names.
+ */
+ QRect max;
+signals:
+ /**
+ * This is send from the mouse click event handler.
+ */
+ void closeMe(int);
+public:
+ /**
+ * The constructor.
+ */
+ KDateInternalMonthPicker(int fontsize, QWidget* parent, const char* name=0);
+ /**
+ * The size hint.
+ */
+ QSize sizeHint() const;
+ /**
+ * Return the result. 0 means no selection (reject()), 1..12 are the
+ * months.
+ */
+ int getResult() const;
+protected:
+ /**
+ * Set up the painter.
+ */
+ void setupPainter(QPainter *p);
+ /**
+ * The resize event.
+ */
+ void viewportResizeEvent(QResizeEvent*);
+ /**
+ * Paint a cell. This simply draws the month names in it.
+ */
+ virtual void paintCell(QPainter* painter, int row, int col);
+ /**
+ * Catch mouse click and move events to paint a rectangle around the item.
+ */
+ void contentsMousePressEvent(QMouseEvent *e);
+ void contentsMouseMoveEvent(QMouseEvent *e);
+ /**
+ * Emit monthSelected(int) when a cell has been released.
+ */
+ void contentsMouseReleaseEvent(QMouseEvent *e);
+
+private:
+ class KDateInternalMonthPrivate;
+ KDateInternalMonthPrivate *d;
+};
+
+/** Year selection widget.
+* @internal
+* @version $Id$
+* @author Tim Gilman, Mirko Boehm
+*/
+class KDateInternalYearSelector : public QLineEdit
+{
+ Q_OBJECT
+protected:
+ QIntValidator *val;
+ int result;
+public slots:
+ void yearEnteredSlot();
+signals:
+ void closeMe(int);
+public:
+ KDateInternalYearSelector(int fontsize,
+ QWidget* parent=0,
+ const char* name=0);
+ int getYear();
+ void setYear(int year);
+
+private:
+ class KDateInternalYearPrivate;
+ KDateInternalYearPrivate *d;
+};
+
+/**
+ * Frame with popup menu behaviour.
+ * @author Tim Gilman, Mirko Boehm
+ * @version $Id$
+ */
+class KPopupFrame : public QFrame
+{
+ Q_OBJECT
+protected:
+ /**
+ * The result. It is returned from exec() when the popup window closes.
+ */
+ int result;
+ /**
+ * Catch key press events.
+ */
+ void keyPressEvent(QKeyEvent* e);
+ /**
+ * The only subwidget that uses the whole dialog window.
+ */
+ QWidget *main;
+public slots:
+ /**
+ * Close the popup window. This is called from the main widget, usually.
+ * @p r is the result returned from exec().
+ */
+ void close(int r);
+public:
+ /**
+ * The contructor. Creates a dialog without buttons.
+ */
+ KPopupFrame(QWidget* parent=0, const char* name=0);
+ /**
+ * Set the main widget. You cannot set the main widget from the constructor,
+ * since it must be a child of the frame itselfes.
+ * Be careful: the size is set to the main widgets size. It is up to you to
+ * set the main widgets correct size before setting it as the main
+ * widget.
+ */
+ void setMainWidget(QWidget* m);
+ /**
+ * The resize event. Simply resizes the main widget to the whole
+ * widgets client size.
+ */
+ void resizeEvent(QResizeEvent*);
+ /**
+ * Open the popup window at position pos.
+ */
+ void popup(const QPoint &pos);
+ /**
+ * Execute the popup window.
+ */
+ int exec(QPoint p);
+ /**
+ * Dito.
+ */
+ int exec(int x, int y);
+
+private:
+
+ virtual bool close(bool alsoDelete) { return QFrame::close(alsoDelete); }
+protected:
+ virtual void virtual_hook( int id, void* data );
+private:
+ class KPopupFramePrivate;
+ KPopupFramePrivate *d;
+};
+
+/**
+* Validates user-entered dates.
+*/
+class KDateValidator : public QValidator
+{
+public:
+ KDateValidator(QWidget* parent=0, const char* name=0);
+ virtual State validate(QString&, int&) const;
+ virtual void fixup ( QString & input ) const;
+ State date(const QString&, QDate&) const;
+};
+
+/**
+ * Date selection table.
+ * This is a support class for the KDatePicker class. It just
+ * draws the calender table without titles, but could theoretically
+ * be used as a standalone.
+ *
+ * When a date is selected by the user, it emits a signal:
+ * dateSelected(QDate)
+ *
+ * @internal
+ * @version $Id$
+ * @author Tim Gilman, Mirko Boehm
+ */
+class KDateTable : public QGridView
+{
+ Q_OBJECT
+public:
+ /**
+ * The constructor.
+ */
+ KDateTable(QWidget *parent=0,
+ QDate date=QDate::currentDate(),
+ const char* name=0, WFlags f=0);
+ /**
+ * Returns a recommended size for the widget.
+ * To save some time, the size of the largest used cell content is
+ * calculated in each paintCell() call, since all calculations have
+ * to be done there anyway. The size is stored in maxCell. The
+ * sizeHint() simply returns a multiple of maxCell.
+ */
+ virtual QSize sizeHint() const;
+ /**
+ * Set the font size of the date table.
+ */
+ void setFontSize(int size);
+ /**
+ * Select and display this date.
+ */
+ bool setDate(const QDate&);
+ const QDate& getDate() const;
+
+
+protected:
+ /**
+ * Paint a cell.
+ */
+ virtual void paintCell(QPainter*, int, int);
+ /**
+ * Handle the resize events.
+ */
+ virtual void viewportResizeEvent(QResizeEvent *);
+ /**
+ * React on mouse clicks that select a date.
+ */
+ virtual void contentsMousePressEvent(QMouseEvent *);
+ virtual void keyPressEvent( QKeyEvent *e );
+ virtual void focusInEvent( QFocusEvent *e );
+ virtual void focusOutEvent( QFocusEvent *e );
+ /**
+ * The font size of the displayed text.
+ */
+ int fontsize;
+ /**
+ * The currently selected date.
+ */
+ QDate date;
+ /**
+ * The day of the first day in the month [1..7].
+ */
+ int firstday;
+ /**
+ * The number of days in the current month.
+ */
+ int numdays;
+ /**
+ * The number of days in the previous month.
+ */
+ int numDaysPrevMonth;
+ /**
+ * unused
+ */
+ bool unused_hasSelection;
+ /**
+ * Save the size of the largest used cell content.
+ */
+ QRect maxCell;
+signals:
+ /**
+ * The selected date changed.
+ */
+ void dateChanged(QDate);
+ /**
+ * A date has been selected by clicking on the table.
+ */
+ void tableClicked();
+
+protected:
+ virtual void virtual_hook( int id, void* data );
+private:
+ class KDateTablePrivate;
+ KDateTablePrivate *d;
+};
+
+#endif // KDATETBL_H
diff --git a/noncore/apps/tinykate/libkate/microkde/kdebug.h b/noncore/apps/tinykate/libkate/microkde/kdebug.h
new file mode 100644
index 0000000..9042644
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kdebug.h
@@ -0,0 +1,112 @@
+#ifndef MINIKDE_KDEBUG_H
+#define MINIKDE_KDEBUG_H
+
+#include <stdio.h>
+
+#include <qstring.h>
+
+class kdbgstream;
+typedef kdbgstream & (*KDBGFUNC)(kdbgstream &); // manipulator function
+
+class kdbgstream {
+ public:
+ kdbgstream(unsigned int _area, unsigned int _level, bool _print = true) :
+ area(_area), level(_level), print(_print) { }
+ kdbgstream(const char * initialString, unsigned int _area, unsigned int _level, bool _print = true) :
+ output(QString::fromLatin1(initialString)), area(_area), level(_level), print(_print) { }
+ ~kdbgstream()
+ {
+ if (!output.isEmpty()) {
+ fprintf(stderr,"ASSERT: debug output not ended with \\n\n");
+ *this << "\n";
+ }
+ }
+ kdbgstream &operator<<(bool i) {
+ if (!print) return *this;
+ output += QString::fromLatin1(i ? "true" : "false");
+ return *this;
+ }
+ kdbgstream &operator<<(short i) {
+ if (!print) return *this;
+ QString tmp; tmp.setNum(i); output += tmp;
+ return *this;
+ }
+ kdbgstream &operator<<(unsigned short i) {
+ if (!print) return *this;
+ QString tmp; tmp.setNum(i); output += tmp;
+ return *this;
+ }
+ kdbgstream &operator<<(char i) {
+ if (!print) return *this;
+ QString tmp; tmp.setNum(int(i)); output += tmp;
+ return *this;
+ }
+ kdbgstream &operator<<(unsigned char i) {
+ if (!print) return *this;
+ QString tmp; tmp.setNum(static_cast<unsigned int>(i)); output += tmp;
+ return *this;
+ }
+
+ kdbgstream &operator<<(int i) {
+ if (!print) return *this;
+ QString tmp; tmp.setNum(i); output += tmp;
+ return *this;
+ }
+ kdbgstream &operator<<(unsigned int i) {
+ if (!print) return *this;
+ QString tmp; tmp.setNum(i); output += tmp;
+ return *this;
+ }
+ kdbgstream &operator<<(long i) {
+ if (!print) return *this;
+ QString tmp; tmp.setNum(i); output += tmp;
+ return *this;
+ }
+ kdbgstream &operator<<(unsigned long i) {
+ if (!print) return *this;
+ QString tmp; tmp.setNum(i); output += tmp;
+ return *this;
+ }
+ kdbgstream &operator<<(const QString& string) {
+ if (!print) return *this;
+ output += string;
+ if (output.at(output.length() -1 ) == '\n')
+ flush();
+ return *this;
+ }
+ kdbgstream &operator<<(const char *string) {
+ if (!print) return *this;
+ output += QString::fromUtf8(string);
+ if (output.at(output.length() - 1) == '\n')
+ flush();
+ return *this;
+ }
+ kdbgstream &operator<<(const QCString& string) {
+ *this << string.data();
+ return *this;
+ }
+ kdbgstream& operator<<(KDBGFUNC f) {
+ if (!print) return *this;
+ return (*f)(*this);
+ }
+ kdbgstream& operator<<(double d) {
+ QString tmp; tmp.setNum(d); output += tmp;
+ return *this;
+ }
+ void flush() {
+ if (output.isEmpty() || !print)
+ return;
+ printf("%s",output.latin1());
+ output = QString::null;
+ }
+ private:
+ QString output;
+ unsigned int area, level;
+ bool print;
+};
+
+inline kdbgstream &endl( kdbgstream &s) { s << "\n"; return s; }
+
+inline kdbgstream kdDebug(int area = 0) { return kdbgstream(area, 0); }
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kdialog.h b/noncore/apps/tinykate/libkate/microkde/kdialog.h
new file mode 100644
index 0000000..56f6bb0
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kdialog.h
@@ -0,0 +1,16 @@
+#ifndef MINIKDE_KDIALOG_H
+#define MINIKDE_KDIALOG_H
+
+#include <qdialog.h>
+
+class KDialog : public QDialog
+{
+ public:
+ KDialog( QWidget *parent=0, const char *name=0, bool modal=true ) :
+ QDialog( parent, name, modal ) {}
+
+ static int spacingHint() { return 3; }
+ static int marginHint() { return 3; }
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kdialogbase.cpp b/noncore/apps/tinykate/libkate/microkde/kdialogbase.cpp
new file mode 100644
index 0000000..8caefe0
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kdialogbase.cpp
@@ -0,0 +1,214 @@
+#include <qtabwidget.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qframe.h>
+
+#include "klocale.h"
+#include "kdebug.h"
+
+#include "kdialogbase.h"
+
+KDialogBase::KDialogBase()
+{
+}
+
+KDialogBase::KDialogBase( QWidget *parent, const char *name, bool modal,
+ const QString &caption,
+ int buttonMask, ButtonCode defaultButton,
+ bool separator,
+ const QString &user1,
+ const QString &user2,
+ const QString &user3) :
+ KDialog( parent, name, modal )
+{
+ init( caption, buttonMask, user1 );
+}
+
+KDialogBase::KDialogBase( int dialogFace, const QString &caption,
+ int buttonMask, ButtonCode defaultButton,
+ QWidget *parent, const char *name, bool modal,
+ bool separator,
+ const QString &user1,
+ const QString &user2,
+ const QString &user3) :
+ KDialog( parent, name, modal )
+{
+ init( caption, buttonMask, user1 );
+}
+
+KDialogBase::~KDialogBase()
+{
+}
+
+void KDialogBase::init( const QString &caption, int buttonMask,
+ const QString &user1 )
+{
+ mMainWidget = 0;
+ mTabWidget = 0;
+ mPlainPage = 0;
+ mTopLayout = 0;
+
+ if ( !caption.isEmpty() ) {
+ setCaption( caption );
+ }
+
+ if ( buttonMask & User1 ) {
+ mUser1Button = new QPushButton( user1, this );
+ connect( mUser1Button, SIGNAL( clicked() ), SLOT( slotUser1() ) );
+ } else {
+ mUser1Button = 0;
+ }
+
+ if ( buttonMask & Ok ) {
+ mOkButton = new QPushButton( i18n("Ok"), this );
+ connect( mOkButton, SIGNAL( clicked() ), SLOT( slotOk() ) );
+ } else {
+ mOkButton = 0;
+ }
+
+ if ( buttonMask & Apply ) {
+ mApplyButton = new QPushButton( i18n("Apply"), this );
+ connect( mApplyButton, SIGNAL( clicked() ), SLOT( slotApply() ) );
+ } else {
+ mApplyButton = 0;
+ }
+
+ if ( buttonMask & Cancel ) {
+ mCancelButton = new QPushButton( i18n("Cancel"), this );
+ connect( mCancelButton, SIGNAL( clicked() ), SLOT( slotCancel() ) );
+ } else {
+ mCancelButton = 0;
+ }
+
+ if ( buttonMask & Close ) {
+ mCloseButton = new QPushButton( i18n("Close"), this );
+ connect( mCloseButton, SIGNAL( clicked() ), SLOT( slotClose() ) );
+ } else {
+ mCloseButton = 0;
+ }
+}
+
+QTabWidget *KDialogBase::tabWidget()
+{
+ if ( !mTabWidget ) {
+ mTabWidget = new QTabWidget( this );
+ setMainWidget( mTabWidget );
+ }
+ return mTabWidget;
+}
+
+void KDialogBase::initLayout()
+{
+ delete mTopLayout;
+ mTopLayout = new QVBoxLayout( this );
+ mTopLayout->setMargin( marginHint() );
+ mTopLayout->setSpacing( spacingHint() );
+
+ mTopLayout->addWidget( mMainWidget );
+
+ QBoxLayout *buttonLayout = new QHBoxLayout;
+ mTopLayout->addLayout( buttonLayout );
+
+ if ( mUser1Button ) buttonLayout->addWidget( mUser1Button );
+ if ( mOkButton ) buttonLayout->addWidget( mOkButton );
+ if ( mApplyButton ) buttonLayout->addWidget( mApplyButton );
+ if ( mCancelButton ) buttonLayout->addWidget( mCancelButton );
+ if ( mCloseButton ) buttonLayout->addWidget( mCloseButton );
+}
+
+QFrame *KDialogBase::addPage( const QString &name )
+{
+// kdDebug() << "KDialogBase::addPage(): " << name << endl;
+
+ QFrame *frame = new QFrame( tabWidget() );
+ tabWidget()->addTab( frame, name );
+ return frame;
+}
+
+QFrame *KDialogBase::addPage( const QString &name, int, const QPixmap & )
+{
+ return addPage( name );
+}
+
+
+void KDialogBase::setMainWidget( QWidget *widget )
+{
+ kdDebug() << "KDialogBase::setMainWidget()" << endl;
+
+ mMainWidget = widget;
+ initLayout();
+}
+
+
+void KDialogBase::enableButton( ButtonCode id, bool state )
+{
+ QPushButton *button = 0;
+ switch ( id ) {
+ case Ok:
+ button = mOkButton;
+ break;
+ case Apply:
+ button = mApplyButton;
+ break;
+ default:
+ break;
+ }
+ if ( button ) {
+ button->setEnabled( state );
+ }
+}
+
+void KDialogBase::enableButtonOK( bool state )
+{
+ enableButton( Ok, state );
+}
+
+void KDialogBase::enableButtonApply( bool state )
+{
+ enableButton( Apply, state );
+}
+
+
+int KDialogBase::pageIndex( QWidget *widget ) const
+{
+ return 0;
+}
+
+
+bool KDialogBase::showPage( int index )
+{
+ return false;
+}
+
+QFrame *KDialogBase::plainPage()
+{
+ if ( !mPlainPage ) {
+ mPlainPage = new QFrame( this );
+ setMainWidget( mPlainPage );
+ }
+ return mPlainPage;
+}
+
+void KDialogBase::slotOk()
+{
+ accept();
+}
+
+void KDialogBase::slotApply()
+{
+}
+
+void KDialogBase::slotCancel()
+{
+ reject();
+}
+
+void KDialogBase::slotClose()
+{
+ accept();
+}
+
+void KDialogBase::slotUser1()
+{
+ emit user1Clicked();
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/kdialogbase.h b/noncore/apps/tinykate/libkate/microkde/kdialogbase.h
new file mode 100644
index 0000000..dfb85d2
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kdialogbase.h
@@ -0,0 +1,105 @@
+#ifndef MINIKDE_KDIALOGBASE_H
+#define MINIKDE_KDIALOGBASE_H
+
+#include <qframe.h>
+
+#include "kdialog.h"
+
+class QPushButton;
+class QLayout;
+class QTabWidget;
+class QBoxLayout;
+
+class KDialogBase : public KDialog
+{
+ Q_OBJECT
+ public:
+ enum ButtonCode
+ {
+ Help = 0x00000001,
+ Default = 0x00000002,
+ Ok = 0x00000004,
+ Apply = 0x00000008,
+ Try = 0x00000010,
+ Cancel = 0x00000020,
+ Close = 0x00000040,
+ User1 = 0x00000080,
+ User2 = 0x00000100,
+ User3 = 0x00000200,
+ No = 0x00000080,
+ Yes = 0x00000100,
+ Details = 0x00000400,
+ Filler = 0x40000000,
+ Stretch = 0x80000000
+ };
+
+ enum DialogType
+ {
+ TreeList,
+ Tabbed,
+ Plain,
+ Swallow,
+ IconList
+ };
+
+ KDialogBase();
+ KDialogBase( QWidget *parent=0, const char *name=0, bool modal=true,
+ const QString &caption=QString::null,
+ int buttonMask=Ok|Apply|Cancel, ButtonCode defaultButton=Ok,
+ bool separator=false,
+ const QString &user1=QString::null,
+ const QString &user2=QString::null,
+ const QString &user3=QString::null);
+ KDialogBase( int dialogFace, const QString &caption,
+ int buttonMask, ButtonCode defaultButton,
+ QWidget *parent=0, const char *name=0, bool modal=true,
+ bool separator=false,
+ const QString &user1=QString::null,
+ const QString &user2=QString::null,
+ const QString &user3=QString::null);
+ virtual ~KDialogBase();
+
+ QFrame *addPage( const QString & );
+ QFrame *addPage( const QString &, int, const QPixmap & );
+
+ void setMainWidget( QWidget *widget );
+
+ void enableButton( ButtonCode id, bool state );
+ void enableButtonOK( bool state );
+ void enableButtonApply( bool state );
+
+ int pageIndex( QWidget *widget ) const;
+
+ bool showPage( int index );
+
+ QFrame *plainPage();
+
+ signals:
+ void user1Clicked();
+
+ protected slots:
+ virtual void slotOk();
+ virtual void slotApply();
+ virtual void slotCancel();
+ virtual void slotClose();
+ virtual void slotUser1();
+
+ private:
+ QTabWidget *tabWidget();
+ void init( const QString &caption, int buttonMask,
+ const QString &user1=QString::null );
+ void initLayout();
+
+ QWidget *mMainWidget;
+ QTabWidget *mTabWidget;
+ QFrame *mPlainPage;
+ QBoxLayout *mTopLayout;
+
+ QPushButton *mUser1Button;
+ QPushButton *mCloseButton;
+ QPushButton *mOkButton;
+ QPushButton *mApplyButton;
+ QPushButton *mCancelButton;
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kemailsettings.cpp b/noncore/apps/tinykate/libkate/microkde/kemailsettings.cpp
new file mode 100644
index 0000000..9a9ad84
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kemailsettings.cpp
@@ -0,0 +1,6 @@
+#include "kemailsettings.h"
+
+QString KEMailSettings::getSetting(KEMailSettings::Setting s)
+{
+ return QString::null;
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/kemailsettings.h b/noncore/apps/tinykate/libkate/microkde/kemailsettings.h
new file mode 100644
index 0000000..cf43f17
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kemailsettings.h
@@ -0,0 +1,32 @@
+#ifndef MINIKDE_KEMAILSETTINGS_H
+#define MINIKDE_KEMAILSETTINGS_H
+
+#include <qstring.h>
+
+class KEMailSettings
+{
+ public:
+ enum Setting {
+ ClientProgram,
+ ClientTerminal,
+ RealName,
+ EmailAddress,
+ ReplyToAddress,
+ Organization,
+ OutServer,
+ OutServerLogin,
+ OutServerPass,
+ OutServerType,
+ OutServerCommand,
+ OutServerTLS,
+ InServer,
+ InServerLogin,
+ InServerPass,
+ InServerType,
+ InServerMBXType,
+ InServerTLS
+ };
+ QString getSetting(KEMailSettings::Setting s);
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kfiledialog.h b/noncore/apps/tinykate/libkate/microkde/kfiledialog.h
new file mode 100644
index 0000000..61781f0
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kfiledialog.h
@@ -0,0 +1,21 @@
+#ifndef MICROKDE_KFILEDIALOG_H
+#define MICROKDE_KFILEDIALOG_H
+
+class KFileDialog
+{
+ public:
+
+ static QString getSaveFileName( const QString &,
+ const QString &, QWidget * )
+ {
+ return QString::null;
+ }
+
+ static QString getOpenFileName( const QString &,
+ const QString &, QWidget * )
+ {
+ return QString::null;
+ }
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kfontdialog.cpp b/noncore/apps/tinykate/libkate/microkde/kfontdialog.cpp
new file mode 100644
index 0000000..d199936
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kfontdialog.cpp
@@ -0,0 +1,6 @@
+#include "kfontdialog.h"
+
+int KFontDialog::getFont( const QFont & )
+{
+ return 0;
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/kfontdialog.h b/noncore/apps/tinykate/libkate/microkde/kfontdialog.h
new file mode 100644
index 0000000..a4bf23d
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kfontdialog.h
@@ -0,0 +1,14 @@
+#ifndef MINIKDE_KFONTDIALOG_H
+#define MINIKDE_KFONTDIALOG_H
+
+#include <qfont.h>
+
+class KFontDialog
+{
+ public:
+ enum { Accepted };
+
+ static int getFont( const QFont & );
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kglobal.cpp b/noncore/apps/tinykate/libkate/microkde/kglobal.cpp
new file mode 100644
index 0000000..572768d
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kglobal.cpp
@@ -0,0 +1,49 @@
+#include "kglobal.h"
+
+KLocale *KGlobal::mLocale = 0;
+KConfig *KGlobal::mConfig = 0;
+KIconLoader *KGlobal::mIconLoader = 0;
+KStandardDirs *KGlobal::mDirs = 0;
+
+QString KGlobal::mAppName = "godot";
+
+KLocale *KGlobal::locale()
+{
+ if ( !mLocale ) {
+ mLocale = new KLocale();
+ }
+
+ return mLocale;
+}
+
+KConfig *KGlobal::config()
+{
+ if ( !mConfig ) {
+ mConfig = new KConfig( KStandardDirs::appDir() + mAppName + "rc" );
+ }
+
+ return mConfig;
+}
+
+KIconLoader *KGlobal::iconLoader()
+{
+ if ( !mIconLoader ) {
+ mIconLoader = new KIconLoader();
+ }
+
+ return mIconLoader;
+}
+
+KStandardDirs *KGlobal::dirs()
+{
+ if ( !mDirs ) {
+ mDirs = new KStandardDirs();
+ }
+
+ return mDirs;
+}
+
+void KGlobal::setAppName( const QString &appName )
+{
+ mAppName = appName;
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/kglobal.h b/noncore/apps/tinykate/libkate/microkde/kglobal.h
new file mode 100644
index 0000000..8985bd4
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kglobal.h
@@ -0,0 +1,27 @@
+#ifndef MINIKDE_KGLOBAL_H
+#define MINIKDE_KGLOBAL_H
+
+#include "klocale.h"
+#include "kiconloader.h"
+#include "kstandarddirs.h"
+#include "kconfig.h"
+
+class KGlobal {
+ public:
+ static KLocale *locale();
+ static KConfig *config();
+ static KIconLoader *iconLoader();
+ static KStandardDirs *dirs();
+
+ static void setAppName( const QString & );
+
+ private:
+ static KLocale *mLocale;
+ static KConfig *mConfig;
+ static KIconLoader *mIconLoader;
+ static KStandardDirs *mDirs;
+
+ static QString mAppName;
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kglobalsettings.cpp b/noncore/apps/tinykate/libkate/microkde/kglobalsettings.cpp
new file mode 100644
index 0000000..cb5fe4c
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kglobalsettings.cpp
@@ -0,0 +1,17 @@
+#include "kglobalsettings.h"
+
+QFont KGlobalSettings::generalFont()
+{
+ return QFont("fixed",12);
+}
+
+QColor KGlobalSettings::baseColor()
+{
+ return Qt::white;
+}
+
+QColor KGlobalSettings::highlightColor()
+{
+ return Qt::blue;
+}
+
diff --git a/noncore/apps/tinykate/libkate/microkde/kglobalsettings.h b/noncore/apps/tinykate/libkate/microkde/kglobalsettings.h
new file mode 100644
index 0000000..34cdb49
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kglobalsettings.h
@@ -0,0 +1,15 @@
+#ifndef MICROKDE_KGLOBALSETTINGS_H
+#define MICROKDE_KGLOBALSETTINGS_H
+
+#include <qfont.h>
+#include <qcolor.h>
+
+class KGlobalSettings
+{
+ public:
+ static QFont generalFont();
+ static QColor baseColor();
+ static QColor highlightColor();
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kiconloader.cpp b/noncore/apps/tinykate/libkate/microkde/kiconloader.cpp
new file mode 100644
index 0000000..83a2cad
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kiconloader.cpp
@@ -0,0 +1,33 @@
+#include <qpe/resource.h>
+
+#include "kiconloader.h"
+
+QPixmap KIconLoader::loadIcon( const QString &name, int )
+{
+ return Resource::loadPixmap( "kate/" + name );
+}
+
+QString KIconLoader::iconPath( const QString &, int )
+{
+ return QString::null;
+}
+
+QPixmap BarIcon( const QString &name )
+{
+ return Resource::loadPixmap( "kate/" + name );
+}
+
+QPixmap DesktopIcon( const QString &name, int )
+{
+ return Resource::loadPixmap( "kate/" + name );
+}
+
+QPixmap SmallIcon( const QString &name )
+{
+ return Resource::loadPixmap( "kate/" + name );
+}
+
+QPixmap SmallIconSet( const QString &name )
+{
+ return Resource::loadPixmap( "kate/" + name );
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/kiconloader.h b/noncore/apps/tinykate/libkate/microkde/kiconloader.h
new file mode 100644
index 0000000..c4f642e
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kiconloader.h
@@ -0,0 +1,31 @@
+#ifndef MINIKDE_KICONLOADER_H
+#define MINIKDE_KICONLOADER_H
+
+#include <qpixmap.h>
+#include <qstring.h>
+
+class KIcon
+{
+ public:
+ enum Group { NoGroup=-1, Desktop=0, Toolbar, MainToolbar, Small,
+ Panel, LastGroup, User };
+ enum StdSizes { SizeSmall=16, SizeMedium=32, SizeLarge=48 };
+};
+
+class KIconLoader
+{
+ public:
+ QPixmap loadIcon( const QString &name, int );
+
+ QString iconPath( const QString &, int );
+};
+
+QPixmap BarIcon(const QString& name);
+
+QPixmap DesktopIcon(const QString& name, int);
+
+QPixmap SmallIcon(const QString& name);
+
+QPixmap SmallIconSet( const QString &name );
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/klineedit.h b/noncore/apps/tinykate/libkate/microkde/klineedit.h
new file mode 100644
index 0000000..26956ad
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/klineedit.h
@@ -0,0 +1,13 @@
+#ifndef MINIKDE_KLINEEDIT_H
+#define MINIKDE_KLINEEDIT_H
+
+#include <qlineedit.h>
+
+class KLineEdit : public QLineEdit
+{
+ public:
+ KLineEdit( QWidget *parent=0, const char *name=0 ) :
+ QLineEdit( parent, name ) {}
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/klineeditdlg.h b/noncore/apps/tinykate/libkate/microkde/klineeditdlg.h
new file mode 100644
index 0000000..4136054
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/klineeditdlg.h
@@ -0,0 +1,8 @@
+#ifndef _mykdelineeditdlg_h_
+#define _mykdelineeditdlg_h_
+
+#include <qinputdialog.h>
+
+#define KLineEditDlg QInputDialog
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/klistview.h b/noncore/apps/tinykate/libkate/microkde/klistview.h
new file mode 100644
index 0000000..008acbc
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/klistview.h
@@ -0,0 +1,24 @@
+#ifndef MICROKDE_KLISTVIEW_H
+#define MICROKDE_KLISTVIEW_H
+
+#include <qlistview.h>
+#include <qpoint.h>
+#include <qstring.h>
+
+class KConfig;
+
+class KListView : public QListView
+{
+ Q_OBJECT
+ public:
+ KListView( QWidget *parent=0, const char *name=0 )
+ : QListView( parent, name ) {}
+
+ void saveLayout( KConfig *, const QString & ) {}
+ void restoreLayout( KConfig *, const QString & ) {}
+
+ signals:
+ void doubleClicked( QListViewItem *, QPoint, int );
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/klocale.cpp b/noncore/apps/tinykate/libkate/microkde/klocale.cpp
new file mode 100644
index 0000000..dfdb97a
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/klocale.cpp
@@ -0,0 +1,530 @@
+#include <qregexp.h>
+
+#include "kdebug.h"
+
+#include "klocale.h"
+
+QString i18n(const char *text)
+{
+ return QString( text );
+}
+
+QString i18n(const char *,const char *text)
+{
+ return QString( text );
+}
+
+inline void put_it_in( QChar *buffer, uint& index, const QString &s )
+{
+ for ( uint l = 0; l < s.length(); l++ )
+ buffer[index++] = s.at( l );
+}
+
+inline void put_it_in( QChar *buffer, uint& index, int number )
+{
+ buffer[index++] = number / 10 + '0';
+ buffer[index++] = number % 10 + '0';
+}
+
+static int readInt(const QString &str, uint &pos)
+{
+ if (!str.at(pos).isDigit()) return -1;
+ int result = 0;
+ for (; str.length() > pos && str.at(pos).isDigit(); pos++)
+ {
+ result *= 10;
+ result += str.at(pos).digitValue();
+ }
+
+ return result;
+}
+
+QString KLocale::formatTime(const QTime &pTime, bool includeSecs) const
+{
+ const QString rst = timeFormat();
+
+ // only "pm/am" here can grow, the rest shrinks, but
+ // I'm rather safe than sorry
+ QChar *buffer = new QChar[rst.length() * 3 / 2 + 30];
+
+ uint index = 0;
+ bool escape = false;
+ int number = 0;
+
+ for ( uint format_index = 0; format_index < rst.length(); format_index++ )
+ {
+ if ( !escape )
+ {
+ if ( rst.at( format_index ).unicode() == '%' )
+ escape = true;
+ else
+ buffer[index++] = rst.at( format_index );
+ }
+ else
+ {
+ switch ( rst.at( format_index ).unicode() )
+ {
+ case '%':
+ buffer[index++] = '%';
+ break;
+ case 'H':
+ put_it_in( buffer, index, pTime.hour() );
+ break;
+ case 'I':
+ put_it_in( buffer, index, ( pTime.hour() + 11) % 12 + 1 );
+ break;
+ case 'M':
+ put_it_in( buffer, index, pTime.minute() );
+ break;
+ case 'S':
+ if (includeSecs)
+ put_it_in( buffer, index, pTime.second() );
+ else
+ {
+ // we remove the seperator sign before the seconds and
+ // assume that works everywhere
+ --index;
+ break;
+ }
+ break;
+ case 'k':
+ number = pTime.hour();
+ case 'l':
+ // to share the code
+ if ( rst.at( format_index ).unicode() == 'l' )
+ number = (pTime.hour() + 11) % 12 + 1;
+ if ( number / 10 )
+ buffer[index++] = number / 10 + '0';
+ buffer[index++] = number % 10 + '0';
+ break;
+ case 'p':
+ {
+ QString s;
+ if ( pTime.hour() >= 12 )
+ put_it_in( buffer, index, i18n("pm") );
+ else
+ put_it_in( buffer, index, i18n("am") );
+ break;
+ }
+ default:
+ buffer[index++] = rst.at( format_index );
+ break;
+ }
+ escape = false;
+ }
+ }
+ QString ret( buffer, index );
+ delete [] buffer;
+ return ret;
+}
+
+QString KLocale::formatDate(const QDate &pDate, bool shortFormat) const
+{
+ const QString rst = shortFormat?dateFormatShort():dateFormat();
+
+ // I'm rather safe than sorry
+ QChar *buffer = new QChar[rst.length() * 3 / 2 + 50];
+
+ unsigned int index = 0;
+ bool escape = false;
+ int number = 0;
+
+ for ( uint format_index = 0; format_index < rst.length(); ++format_index )
+ {
+ if ( !escape )
+ {
+ if ( rst.at( format_index ).unicode() == '%' )
+ escape = true;
+ else
+ buffer[index++] = rst.at( format_index );
+ }
+ else
+ {
+ switch ( rst.at( format_index ).unicode() )
+ {
+ case '%':
+ buffer[index++] = '%';
+ break;
+ case 'Y':
+ put_it_in( buffer, index, pDate.year() / 100 );
+ case 'y':
+ put_it_in( buffer, index, pDate.year() % 100 );
+ break;
+ case 'n':
+ number = pDate.month();
+ case 'e':
+ // to share the code
+ if ( rst.at( format_index ).unicode() == 'e' )
+ number = pDate.day();
+ if ( number / 10 )
+ buffer[index++] = number / 10 + '0';
+ buffer[index++] = number % 10 + '0';
+ break;
+ case 'm':
+ put_it_in( buffer, index, pDate.month() );
+ break;
+ case 'b':
+ put_it_in( buffer, index, monthName(pDate.month(), true) );
+ break;
+ case 'B':
+ put_it_in( buffer, index, monthName(pDate.month(), false) );
+ break;
+ case 'd':
+ put_it_in( buffer, index, pDate.day() );
+ break;
+ case 'a':
+ put_it_in( buffer, index, weekDayName(pDate.dayOfWeek(), true) );
+ break;
+ case 'A':
+ put_it_in( buffer, index, weekDayName(pDate.dayOfWeek(), false) );
+ break;
+ default:
+ buffer[index++] = rst.at( format_index );
+ break;
+ }
+ escape = false;
+ }
+ }
+ QString ret( buffer, index );
+ delete [] buffer;
+ return ret;
+}
+
+QString KLocale::formatDateTime(const QDateTime &pDateTime,
+ bool shortFormat,
+ bool includeSeconds) const
+{
+ return i18n("concatenation of dates and time", "%1 %2")
+ .arg( formatDate( pDateTime.date(), shortFormat ) )
+ .arg( formatTime( pDateTime.time(), includeSeconds ) );
+}
+
+QString KLocale::formatDateTime(const QDateTime &pDateTime) const
+{
+ return formatDateTime(pDateTime, true);
+}
+
+QDate KLocale::readDate(const QString &intstr, bool* ok) const
+{
+ QDate date;
+ date = readDate(intstr, true, ok);
+ if (date.isValid()) return date;
+ return readDate(intstr, false, ok);
+}
+
+QDate KLocale::readDate(const QString &intstr, bool shortFormat, bool* ok) const
+{
+ QString fmt = (shortFormat ? dateFormatShort() : dateFormat()).simplifyWhiteSpace();
+ return readDate( intstr, fmt, ok );
+}
+
+QDate KLocale::readDate(const QString &intstr, const QString &fmt, bool* ok) const
+{
+ //kdDebug(173) << "KLocale::readDate intstr=" << intstr << " fmt=" << fmt << endl;
+ QString str = intstr.simplifyWhiteSpace().lower();
+ int day = -1, month = -1;
+ // allow the year to be omitted if not in the format
+ int year = QDate::currentDate().year();
+ uint strpos = 0;
+ uint fmtpos = 0;
+
+ while (fmt.length() > fmtpos || str.length() > strpos)
+ {
+ if ( !(fmt.length() > fmtpos && str.length() > strpos) )
+ goto error;
+
+ QChar c = fmt.at(fmtpos++);
+
+ if (c != '%') {
+ if (c.isSpace())
+ strpos++;
+ else if (c != str.at(strpos++))
+ goto error;
+ continue;
+ }
+
+ // remove space at the begining
+ if (str.length() > strpos && str.at(strpos).isSpace())
+ strpos++;
+
+ c = fmt.at(fmtpos++);
+ switch (c)
+ {
+ case 'a':
+ case 'A':
+ // this will just be ignored
+ { // Cristian Tache: porting to Win: Block added because of "j" redefinition
+ for (int j = 1; j < 8; j++) {
+ QString s = weekDayName(j, c == 'a').lower();
+ int len = s.length();
+ if (str.mid(strpos, len) == s)
+ strpos += len;
+ }
+ break;
+ }
+ case 'b':
+ case 'B':
+ { // Cristian Tache: porting to Win: Block added because of "j" redefinition
+ for (int j = 1; j < 13; j++) {
+ QString s = monthName(j, c == 'b').lower();
+ int len = s.length();
+ if (str.mid(strpos, len) == s) {
+ month = j;
+ strpos += len;
+ }
+ }
+ break;
+ }
+ case 'd':
+ case 'e':
+ day = readInt(str, strpos);
+ if (day < 1 || day > 31)
+ goto error;
+
+ break;
+
+ case 'n':
+ case 'm':
+ month = readInt(str, strpos);
+ if (month < 1 || month > 12)
+ goto error;
+
+ break;
+
+ case 'Y':
+ case 'y':
+ year = readInt(str, strpos);
+ if (year < 0)
+ goto error;
+ // Qt treats a year in the range 0-100 as 1900-1999.
+ // It is nicer for the user if we treat 0-68 as 2000-2068
+ if (year < 69)
+ year += 2000;
+ else if (c == 'y')
+ year += 1900;
+
+ break;
+ }
+ }
+ //kdDebug(173) << "KLocale::readDate day=" << day << " month=" << month << " year=" << year << endl;
+ if ( year != -1 && month != -1 && day != -1 )
+ {
+ if (ok) *ok = true;
+ return QDate(year, month, day);
+ }
+ error:
+ if (ok) *ok = false;
+ return QDate(); // invalid date
+}
+
+QTime KLocale::readTime(const QString &intstr, bool *ok) const
+{
+ QTime _time;
+ _time = readTime(intstr, true, ok);
+ if (_time.isValid()) return _time;
+ return readTime(intstr, false, ok);
+}
+
+QTime KLocale::readTime(const QString &intstr, bool seconds, bool *ok) const
+{
+ QString str = intstr.simplifyWhiteSpace().lower();
+ QString Format = timeFormat().simplifyWhiteSpace();
+ if (!seconds)
+ Format.replace(QRegExp(QString::fromLatin1(".%S")), QString::null);
+
+ int hour = -1, minute = -1, second = seconds ? -1 : 0; // don't require seconds
+ bool g_12h = false;
+ bool pm = false;
+ uint strpos = 0;
+ uint Formatpos = 0;
+
+ while (Format.length() > Formatpos || str.length() > strpos)
+ {
+ if ( !(Format.length() > Formatpos && str.length() > strpos) ) goto error;
+
+ QChar c = Format.at(Formatpos++);
+
+ if (c != '%')
+ {
+ if (c.isSpace())
+ strpos++;
+ else if (c != str.at(strpos++))
+ goto error;
+ continue;
+ }
+
+ // remove space at the begining
+ if (str.length() > strpos && str.at(strpos).isSpace())
+ strpos++;
+
+ c = Format.at(Formatpos++);
+ switch (c)
+ {
+ case 'p':
+ {
+ QString s;
+ s = i18n("pm").lower();
+ int len = s.length();
+ if (str.mid(strpos, len) == s)
+ {
+ pm = true;
+ strpos += len;
+ }
+ else
+ {
+ s = i18n("am").lower();
+ len = s.length();
+ if (str.mid(strpos, len) == s) {
+ pm = false;
+ strpos += len;
+ }
+ else
+ goto error;
+ }
+ }
+ break;
+
+ case 'k':
+ case 'H':
+ g_12h = false;
+ hour = readInt(str, strpos);
+ if (hour < 0 || hour > 23)
+ goto error;
+
+ break;
+
+ case 'l':
+ case 'I':
+ g_12h = true;
+ hour = readInt(str, strpos);
+ if (hour < 1 || hour > 12)
+ goto error;
+
+ break;
+
+ case 'M':
+ minute = readInt(str, strpos);
+ if (minute < 0 || minute > 59)
+ goto error;
+
+ break;
+
+ case 'S':
+ second = readInt(str, strpos);
+ if (second < 0 || second > 59)
+ goto error;
+
+ break;
+ }
+ }
+ if (g_12h)
+ {
+ hour %= 12;
+ if (pm) hour += 12;
+ }
+
+ if (ok) *ok = true;
+ return QTime(hour, minute, second);
+
+ error:
+ if (ok) *ok = false;
+ return QTime(-1, -1, -1); // return invalid date if it didn't work
+ // This will be removed in the near future, since it gives a warning on stderr.
+ // The presence of the bool* (since KDE-3.0) removes the need for an invalid QTime.
+}
+
+bool KLocale::use12Clock() const
+{
+ return false;
+}
+
+bool KLocale::weekStartsMonday() const
+{
+ return true;
+}
+
+QString KLocale::weekDayName(int i,bool shortName) const
+{
+ if ( shortName )
+ switch ( i )
+ {
+ case 1: return i18n("Monday", "Mon");
+ case 2: return i18n("Tuesday", "Tue");
+ case 3: return i18n("Wednesday", "Wed");
+ case 4: return i18n("Thursday", "Thu");
+ case 5: return i18n("Friday", "Fri");
+ case 6: return i18n("Saturday", "Sat");
+ case 7: return i18n("Sunday", "Sun");
+ }
+ else
+ switch ( i )
+ {
+ case 1: return i18n("Monday");
+ case 2: return i18n("Tuesday");
+ case 3: return i18n("Wednesday");
+ case 4: return i18n("Thursday");
+ case 5: return i18n("Friday");
+ case 6: return i18n("Saturday");
+ case 7: return i18n("Sunday");
+ }
+
+ return QString::null;
+}
+
+QString KLocale::monthName(int i,bool shortName) const
+{
+ if ( shortName )
+ switch ( i )
+ {
+ case 1: return i18n("January", "Jan");
+ case 2: return i18n("February", "Feb");
+ case 3: return i18n("March", "Mar");
+ case 4: return i18n("April", "Apr");
+ case 5: return i18n("May short", "May");
+ case 6: return i18n("June", "Jun");
+ case 7: return i18n("July", "Jul");
+ case 8: return i18n("August", "Aug");
+ case 9: return i18n("September", "Sep");
+ case 10: return i18n("October", "Oct");
+ case 11: return i18n("November", "Nov");
+ case 12: return i18n("December", "Dec");
+ }
+ else
+ switch (i)
+ {
+ case 1: return i18n("January");
+ case 2: return i18n("February");
+ case 3: return i18n("March");
+ case 4: return i18n("April");
+ case 5: return i18n("May long", "May");
+ case 6: return i18n("June");
+ case 7: return i18n("July");
+ case 8: return i18n("August");
+ case 9: return i18n("September");
+ case 10: return i18n("October");
+ case 11: return i18n("November");
+ case 12: return i18n("December");
+ }
+
+ return QString::null;
+}
+
+QString KLocale::country() const
+{
+ return QString::null;
+}
+
+QString KLocale::dateFormat() const
+{
+ return "%A %d %B %Y";
+}
+
+QString KLocale::dateFormatShort() const
+{
+ return "%d.%m.%Y";
+}
+
+QString KLocale::timeFormat() const
+{
+ return "%H:%M:%S";
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/klocale.h b/noncore/apps/tinykate/libkate/microkde/klocale.h
new file mode 100644
index 0000000..cff200b
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/klocale.h
@@ -0,0 +1,53 @@
+#ifndef MINIKDE_KLOCALE_H
+#define MINIKDE_KLOCALE_H
+
+#include <qstring.h>
+#include <qdatetime.h>
+
+
+#define I18N_NOOP(x) x
+
+
+QString i18n(const char *text);
+QString i18n(const char *hint, const char *text);
+
+// Qt3's uic generates i18n( "msg", "comment" ) calls which conflict
+// with our i18n method. we use uic -tr tr2i18n to redirect
+// to the right i18n() function
+inline QString tr2i18n(const char* message, const char* =0) {
+ return i18n( message);
+}
+
+class KLocale
+{
+ public:
+
+ QString formatDate(const QDate &pDate, bool shortFormat = false) const;
+ QString formatTime(const QTime &pTime, bool includeSecs = false) const;
+ QString formatDateTime(const QDateTime &pDateTime) const;
+ QString formatDateTime(const QDateTime &pDateTime,
+ bool shortFormat,
+ bool includeSecs = false) const;
+
+ QDate readDate(const QString &str, bool* ok = 0) const;
+ QDate readDate( const QString &intstr, const QString &fmt, bool* ok = 0) const;
+ QTime readTime(const QString &str, bool* ok = 0) const;
+
+ bool use12Clock() const;
+ bool weekStartsMonday() const;
+
+ QString weekDayName(int,bool=false) const;
+ QString monthName(int,bool=false) const;
+
+ QString country() const;
+
+ QString dateFormat() const;
+ QString dateFormatShort() const;
+ QString timeFormat() const;
+
+ private:
+ QTime readTime(const QString &str, bool seconds, bool *ok) const;
+ QDate readDate(const QString &str, bool shortFormat, bool *ok) const;
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kmessagebox.cpp b/noncore/apps/tinykate/libkate/microkde/kmessagebox.cpp
new file mode 100644
index 0000000..fd305cd
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kmessagebox.cpp
@@ -0,0 +1,90 @@
+#include "kmessagebox.h"
+#include "klocale.h"
+
+#include <qmessagebox.h>
+
+void KMessageBox::sorry( QWidget *parent,
+ const QString &text,
+ const QString &caption, bool )
+{
+ QString cap = caption;
+
+ if (cap.isEmpty()) {
+ cap = i18n("Sorry");
+ }
+
+ QMessageBox::warning( parent, cap, text );
+}
+
+int KMessageBox::warningYesNoCancel(QWidget *parent, const QString &text)
+{
+ int result = QMessageBox::warning(parent,i18n("Warning"),text,QMessageBox::Yes,
+ QMessageBox::No, QMessageBox::Cancel);
+ switch (result) {
+ case QMessageBox::Yes: return Yes;
+ case QMessageBox::No: return No;
+ case QMessageBox::Cancel: return Cancel;
+ }
+}
+
+int KMessageBox::questionYesNo(QWidget *parent,
+ const QString &text,
+ const QString &textYes,
+ const QString &textNo,
+ bool notify=true )
+{
+ int result =QMessageBox::warning(parent,i18n("Question"),text,textYes,textNo);
+ if ( result == 0 ) return KMessageBox::Yes;
+ return KMessageBox::No;
+}
+
+
+
+
+int KMessageBox::warningContinueCancel( QWidget *parent,
+ const QString &text,
+ const QString &caption,
+ const QString &buttonContinue,
+ const QString &dontAskAgainName,
+ bool notify )
+{
+ QString cap = caption;
+
+ if (cap.isEmpty()) {
+ cap = i18n("Warning");
+ }
+
+ int result = QMessageBox::warning( parent, cap, text, i18n("Ok"),
+ i18n("Cancel") );
+
+ if ( result == 0 ) return KMessageBox::Continue;
+ return KMessageBox::Cancel;
+}
+
+void KMessageBox::error( QWidget *parent,
+ const QString &text,
+ const QString &caption, bool notify )
+{
+ QString cap = caption;
+
+ if (cap.isEmpty()) {
+ cap = i18n("Error");
+ }
+
+ QMessageBox::critical( parent, cap, text );
+}
+
+void KMessageBox::information( QWidget *parent,
+ const QString &text,
+ const QString &caption,
+ const QString &,
+ bool )
+{
+ QString cap = caption;
+
+ if (cap.isEmpty()) {
+ cap = i18n("Information");
+ }
+
+ QMessageBox::information( parent, cap, text );
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/kmessagebox.h b/noncore/apps/tinykate/libkate/microkde/kmessagebox.h
new file mode 100644
index 0000000..d7c971f
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kmessagebox.h
@@ -0,0 +1,46 @@
+#ifndef MINIKDE_KMESSAGEBOX_H
+#define MINIKDE_KMESSAGEBOX_H
+
+#include <qstring.h>
+
+class QWidget;
+
+class KMessageBox
+{
+ public:
+ enum { Ok = 1, Cancel = 2, Yes = 3, No = 4, Continue = 5 };
+
+ static void sorry(QWidget *parent,
+ const QString &text,
+ const QString &caption = QString::null, bool notify=true);
+
+ static int warningContinueCancel(QWidget *parent,
+ const QString &text,
+ const QString &caption = QString::null,
+ const QString &buttonContinue = QString::null,
+ const QString &dontAskAgainName = QString::null,
+ bool notify=true );
+
+
+ static int questionYesNo(QWidget *parent,
+ const QString &text,
+ const QString &textYes,
+ const QString &textNo,
+ bool notify=true );
+
+ static int warningYesNoCancel(QWidget *parent, const QString &text);
+
+
+ static void error(QWidget *parent,
+ const QString &text,
+ const QString &caption = QString::null, bool notify=true);
+
+ static void information(QWidget *parent,
+ const QString &text,
+ const QString &caption = QString::null,
+ const QString &dontShowAgainName = QString::null,
+ bool notify=true);
+};
+
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/knotifyclient.h b/noncore/apps/tinykate/libkate/microkde/knotifyclient.h
new file mode 100644
index 0000000..118026a
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/knotifyclient.h
@@ -0,0 +1,14 @@
+#ifndef MINIKDE_KNOTIFYCLIENT_H
+#define MINIKDE_KNOTIFYCLIENT_H
+
+#include <qstring.h>
+
+class KNotifyClient
+{
+ public:
+
+ static void beep() {}
+ static void beep( const QString & ) {}
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/knumvalidator.cpp b/noncore/apps/tinykate/libkate/microkde/knumvalidator.cpp
new file mode 100644
index 0000000..67e632f
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/knumvalidator.cpp
@@ -0,0 +1,8 @@
+#include <qlineedit.h>
+
+#include "knumvalidator.h"
+
+KIntValidator::KIntValidator( int a, int b, QLineEdit *c )
+ : QIntValidator( a, b, c )
+{
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/knumvalidator.h b/noncore/apps/tinykate/libkate/microkde/knumvalidator.h
new file mode 100644
index 0000000..92eda01
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/knumvalidator.h
@@ -0,0 +1,14 @@
+#ifndef MINIKDE_KNUMVALIDATOR_H
+#define MINIKDE_KNUMVALIDATOR_H
+
+#include <qvalidator.h>
+
+class QLineEdit;
+
+class KIntValidator : public QIntValidator
+{
+ public:
+ KIntValidator( int, int, QLineEdit * );
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kpopupmenu.h b/noncore/apps/tinykate/libkate/microkde/kpopupmenu.h
new file mode 100644
index 0000000..fb35943
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kpopupmenu.h
@@ -0,0 +1,8 @@
+#ifndef _MYKPOPUPMENU_H_
+#define _MYKPOPUPMENU_H_
+
+#include <qpopupmenu.h>
+
+#define KPopupMenu QPopupMenu
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kprinter.h b/noncore/apps/tinykate/libkate/microkde/kprinter.h
new file mode 100644
index 0000000..b99d689
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kprinter.h
@@ -0,0 +1,8 @@
+#ifndef MINIKDE_KPRINTER_H
+#define MINIKDE_KPRINTER_H
+
+#include <qprinter.h>
+
+#define KPrinter QPrinter
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kprocess.cpp b/noncore/apps/tinykate/libkate/microkde/kprocess.cpp
new file mode 100644
index 0000000..62033e9
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kprocess.cpp
@@ -0,0 +1,15 @@
+#include "kprocess.h"
+
+void KProcess::clearArguments()
+{
+}
+
+KProcess & KProcess::operator<<( const QString & )
+{
+ return *this;
+}
+
+bool KProcess::start()
+{
+ return false;
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/kprocess.h b/noncore/apps/tinykate/libkate/microkde/kprocess.h
new file mode 100644
index 0000000..96dce54
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kprocess.h
@@ -0,0 +1,16 @@
+#ifndef MINIKDE_KPROCESS_H
+#define MINIKDE_KPROCESS_H
+
+#include <qobject.h>
+
+class KProcess : public QObject
+{
+ public:
+ void clearArguments();
+
+ KProcess & operator<<( const QString & );
+
+ bool start();
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/krestrictedline.h b/noncore/apps/tinykate/libkate/microkde/krestrictedline.h
new file mode 100644
index 0000000..200546c
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/krestrictedline.h
@@ -0,0 +1,13 @@
+#ifndef MINIKDE_KRESTRICTEDLINE_H
+#define MINIKDE_KRESTRICTEDLINE_H
+
+#include "klineedit.h"
+
+class KRestrictedLine : public KLineEdit
+{
+ public:
+ KRestrictedLine( QWidget *parent, const char *, const QString & ) :
+ KLineEdit( parent ) {}
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/krun.cpp b/noncore/apps/tinykate/libkate/microkde/krun.cpp
new file mode 100644
index 0000000..a170add
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/krun.cpp
@@ -0,0 +1,6 @@
+#include "krun.h"
+
+bool KRun::runCommand(const QString &, const QString &, const QString &)
+{
+ return false;
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/krun.h b/noncore/apps/tinykate/libkate/microkde/krun.h
new file mode 100644
index 0000000..1b63cb7
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/krun.h
@@ -0,0 +1,13 @@
+#ifndef MINIKDE_KRUN_H
+#define MINIKDE_KRUN_H
+
+#include <qstring.h>
+
+class KRun
+{
+ public:
+ static bool runCommand(const QString &a, const QString &b=QString::null,
+ const QString &c=QString::null);
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kseparator.h b/noncore/apps/tinykate/libkate/microkde/kseparator.h
new file mode 100644
index 0000000..9fc0b51
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kseparator.h
@@ -0,0 +1,8 @@
+#ifndef MINIKDE_KSEPARATOR_H
+#define MINIKDE_KSEPARATOR_H
+
+class KSeparator
+{
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/ksharedptr.h b/noncore/apps/tinykate/libkate/microkde/ksharedptr.h
new file mode 100644
index 0000000..55ed2e9
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/ksharedptr.h
@@ -0,0 +1,142 @@
+/* This file is part of the KDE libraries
+ Copyright (c) 1999 Waldo Bastian <bastian@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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+#ifndef KSharedPTR_H
+#define KSharedPTR_H
+
+/**
+ * Reference counting for shared objects. If you derive your object
+ * from this class, then you may use it in conjunction with
+ * @ref KSharedPtr to control the lifetime of your object.
+ *
+ * Specifically, all classes that derive from KShared have an internal
+ * counter keeping track of how many other objects have a reference to
+ * their object. If used with @ref KSharedPtr, then your object will
+ * not be deleted until all references to the object have been
+ * released.
+ *
+ * You should probably not ever use any of the methods in this class
+ * directly -- let the @ref KSharedPtr take care of that. Just derive
+ * your class from KShared and forget about it.
+ *
+ * @author Waldo Bastian <bastian@kde.org>
+ * @version $Id$
+ */
+class KShared {
+public:
+ /**
+ * Standard constructor. This will initialize the reference count
+ * on this object to 0
+ */
+ KShared() : count(0) { }
+
+ /**
+ * Copy constructor. This will @em not actually copy the objects
+ * but it will initialize the reference count on this object to 0
+ */
+ KShared( const KShared & ) : count(0) { }
+
+ /**
+ * Overloaded assignment operator
+ */
+ KShared &operator=(const KShared & ) { return *this; }
+
+ /**
+ * Increases the reference count by one
+ */
+ void _KShared_ref() { count++; }
+
+ /**
+ * Releases a reference (decreases the reference count by one). If
+ * the count goes to 0, this object will delete itself
+ */
+ void _KShared_unref() { if (!--count) delete this; }
+
+ /**
+ * Return the current number of references held
+ *
+ * @return Number of references
+ */
+ int _KShared_count() { return count; }
+
+protected:
+ virtual ~KShared() { }
+ int count; // ### KDE 3.0: rename to something like _KShared_count
+ // or make private
+};
+
+/**
+ * Can be used to control the lifetime of an object that has derived
+ * @ref KShared. As long a someone holds a KSharedPtr on some KShared
+ * object it won't become deleted but is deleted once its reference
+ * count is 0. This struct emulates C++ pointers perfectly. So just
+ * use it like a simple C++ pointer.
+ *
+ * KShared and KSharedPtr are preferred over QShared / QSharedPtr
+ * since they are more safe.
+ *
+ * @author Waldo Bastian <bastian@kde.org>
+ * @version $Id$
+ */
+template< class T >
+struct KSharedPtr
+{
+public:
+ KSharedPtr()
+ : ptr(0) { }
+ KSharedPtr( T* t )
+ : ptr(t) { if ( ptr ) ptr->_KShared_ref(); }
+ KSharedPtr( const KSharedPtr& p )
+ : ptr(p.ptr) { if ( ptr ) ptr->_KShared_ref(); }
+
+ ~KSharedPtr() { if ( ptr ) ptr->_KShared_unref(); }
+
+ KSharedPtr<T>& operator= ( const KSharedPtr<T>& p ) {
+ if ( ptr == p.ptr ) return *this;
+ if ( ptr ) ptr->_KShared_unref();
+ ptr = p.ptr;
+ if ( ptr ) ptr->_KShared_ref();
+ return *this;
+ }
+ KSharedPtr<T>& operator= ( T* p ) {
+ if ( ptr == p ) return *this;
+ if ( ptr ) ptr->_KShared_unref();
+ ptr = p;
+ if ( ptr ) ptr->_KShared_ref();
+ return *this;
+ }
+ bool operator== ( const KSharedPtr<T>& p ) const { return ( ptr == p.ptr ); }
+ bool operator!= ( const KSharedPtr<T>& p ) const { return ( ptr != p.ptr ); }
+ bool operator== ( const T* p ) const { return ( ptr == p ); }
+ bool operator!= ( const T* p ) const { return ( ptr != p ); }
+ bool operator!() const { return ( ptr == 0 ); }
+ operator T*() const { return ptr; }
+
+ T* data() { return ptr; }
+ const T* data() const { return ptr; }
+
+ const T& operator*() const { return *ptr; }
+ T& operator*() { return *ptr; }
+ const T* operator->() const { return ptr; }
+ T* operator->() { return ptr; }
+
+ int count() const { return ptr->_KShared_count(); } // for debugging purposes
+private:
+ T* ptr;
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/ksimpleconfig.h b/noncore/apps/tinykate/libkate/microkde/ksimpleconfig.h
new file mode 100644
index 0000000..1efd982
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/ksimpleconfig.h
@@ -0,0 +1,12 @@
+#ifndef MINIKDE_KSIMPLECONFIG_H
+#define MINIKDE_KSIMPLECONFIG_H
+
+#include "kconfig.h"
+
+class KSimpleConfig : public KConfig
+{
+ public:
+ KSimpleConfig( const QString &file ) : KConfig( file ) {}
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kstandarddirs.cpp b/noncore/apps/tinykate/libkate/microkde/kstandarddirs.cpp
new file mode 100644
index 0000000..befa667
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kstandarddirs.cpp
@@ -0,0 +1,39 @@
+#include "kdebug.h"
+
+#include "kstandarddirs.h"
+
+QString KStandardDirs::mAppDir = QString::null;
+
+QString locate( const char *type, const QString& filename )
+{
+ QString path = KStandardDirs::appDir() + type + "_" + filename;
+
+ kdDebug() << "locate: '" << path << "'" << endl;
+
+ return path;
+}
+
+QString locateLocal( const char *type, const QString& filename )
+{
+ return locate( type, filename );
+}
+
+QStringList KStandardDirs::findAllResources( const QString &, const QString &, bool, bool)
+{
+ QStringList list;
+ list.append("/cpp.xml");
+ return list;
+// return QStringList();
+}
+
+QString KStandardDirs::findResourceDir( const QString &, const QString & )
+{
+ return QString::null;
+}
+
+void KStandardDirs::setAppDir( const QString &appDir )
+{
+ mAppDir = appDir;
+
+ if ( mAppDir.right( 1 ) != "/" ) mAppDir += "/";
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/kstandarddirs.h b/noncore/apps/tinykate/libkate/microkde/kstandarddirs.h
new file mode 100644
index 0000000..fa5e460
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kstandarddirs.h
@@ -0,0 +1,23 @@
+#ifndef MINIKDE_KSTANDARDDIRS_H
+#define MINIKDE_KSTANDARDDIRS_H
+
+#include <qstring.h>
+#include <qstringlist.h>
+
+QString locate( const char *type, const QString& filename );
+QString locateLocal( const char *type, const QString& filename );
+
+class KStandardDirs
+{
+ public:
+ QStringList findAllResources( const QString &, const QString &, bool, bool);
+ QString findResourceDir( const QString &, const QString & );
+
+ static void setAppDir( const QString & );
+ static QString appDir() { return mAppDir; }
+
+ private:
+ static QString mAppDir;
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kstaticdeleter.h b/noncore/apps/tinykate/libkate/microkde/kstaticdeleter.h
new file mode 100644
index 0000000..190f3e4
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kstaticdeleter.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the KDE Libraries
+ * Copyright (C) 2000 Stephan Kulow <coolo@kde.org>
+ * 2001 KDE Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _KSTATIC_DELETER_H_
+#define _KSTATIC_DELETER_H_
+
+template<class type>
+class KStaticDeleter
+{
+ public:
+ KStaticDeleter() {};
+ type *setObject( type *obj, bool isArray = false) { return obj; }
+ virtual ~KStaticDeleter() {};
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kstddirs.h b/noncore/apps/tinykate/libkate/microkde/kstddirs.h
new file mode 100644
index 0000000..fa5e460
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kstddirs.h
@@ -0,0 +1,23 @@
+#ifndef MINIKDE_KSTANDARDDIRS_H
+#define MINIKDE_KSTANDARDDIRS_H
+
+#include <qstring.h>
+#include <qstringlist.h>
+
+QString locate( const char *type, const QString& filename );
+QString locateLocal( const char *type, const QString& filename );
+
+class KStandardDirs
+{
+ public:
+ QStringList findAllResources( const QString &, const QString &, bool, bool);
+ QString findResourceDir( const QString &, const QString & );
+
+ static void setAppDir( const QString & );
+ static QString appDir() { return mAppDir; }
+
+ private:
+ static QString mAppDir;
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/ktempfile.cpp b/noncore/apps/tinykate/libkate/microkde/ktempfile.cpp
new file mode 100644
index 0000000..b9166bd
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/ktempfile.cpp
@@ -0,0 +1,25 @@
+#include <qtextstream.h>
+
+#include "ktempfile.h"
+
+KTempFile::KTempFile()
+{
+}
+
+KTempFile::KTempFile( const QString &filename, const QString &extension )
+{
+}
+
+void KTempFile::setAutoDelete( bool )
+{
+}
+
+QString KTempFile::name()
+{
+ return QString::null;
+}
+
+QTextStream *KTempFile::textStream()
+{
+ return 0;
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/ktempfile.h b/noncore/apps/tinykate/libkate/microkde/ktempfile.h
new file mode 100644
index 0000000..20dfa82
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/ktempfile.h
@@ -0,0 +1,20 @@
+#ifndef MINIKDE_KTEMPFILE_H
+#define MINIKDE_KTEMPFILE_H
+
+#include <qstring.h>
+
+class QTextStream;
+
+class KTempFile
+{
+ public:
+ KTempFile();
+ KTempFile( const QString &filename, const QString &extension );
+
+ void setAutoDelete( bool );
+ QString name();
+
+ QTextStream *textStream();
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kunload.h b/noncore/apps/tinykate/libkate/microkde/kunload.h
new file mode 100644
index 0000000..1c3d00f
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kunload.h
@@ -0,0 +1,6 @@
+#ifndef MINIKDE_KUNLOAD_H
+#define MINIKDE_KUNLOAD_H
+
+#define _UNLOAD(p)
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/microkde/kurlrequester.cpp b/noncore/apps/tinykate/libkate/microkde/kurlrequester.cpp
new file mode 100644
index 0000000..29d173b
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kurlrequester.cpp
@@ -0,0 +1,14 @@
+#include "klineedit.h"
+
+#include "kurlrequester.h"
+
+KURLRequester::KURLRequester( QWidget *parent ) :
+ QWidget( parent )
+{
+ mLineEdit = new KLineEdit( parent );
+}
+
+KLineEdit *KURLRequester::lineEdit()
+{
+ return mLineEdit;
+}
diff --git a/noncore/apps/tinykate/libkate/microkde/kurlrequester.h b/noncore/apps/tinykate/libkate/microkde/kurlrequester.h
new file mode 100644
index 0000000..8b39196
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kurlrequester.h
@@ -0,0 +1,17 @@
+#ifndef MINIKDE_KURLREQUESTER_H
+#define MINIKDE_KURLREQUESTER_H
+
+class KLineEdit;
+
+class KURLRequester : public QWidget
+{
+ public:
+ KURLRequester( QWidget *parent );
+
+ KLineEdit *lineEdit();
+
+ private:
+ KLineEdit *mLineEdit;
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/qt3back/README b/noncore/apps/tinykate/libkate/qt3back/README
new file mode 100644
index 0000000..e329aee
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/qt3back/README
@@ -0,0 +1,12 @@
+This is a backport I got from Scott Manson, I just added an additional #ifndef QT_NO_COMPAT in the .cpp file around a match
+function
+
+*************************
+ This is ___NOT___ the original version from Trolltech, so don't blame them if something is wrong.
+*************************
+
+Use it at your own risk, neither Trolltech, Scott Manson nor I take any responsibility, if it damages your system or causes
+unexpected behaviour or causes loss of data
+
+Joseph Wenninger
+<jowenn@kde.org>
diff --git a/noncore/apps/tinykate/libkate/qt3back/qregexp3.cpp b/noncore/apps/tinykate/libkate/qt3back/qregexp3.cpp
new file mode 100644
index 0000000..a2c680f
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/qt3back/qregexp3.cpp
@@ -0,0 +1,3767 @@
+/****************************************************************************
+** $Id$
+**
+** Implementation of QRegExp class
+**
+** Created : 950126
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#if QT_VERSION >=300
+#error QRegExp3 is now in QT 3 use QRegExp instead
+#endif
+
+#include "qarray.h"
+#include "qbitarray.h"
+#include "qcache.h"
+#include "qintdict.h"
+#include "qmap.h"
+#if QT_VERSION < 300
+#include "./qregexp3.h"
+#else
+#include "qregexp.h"
+#endif
+#include "qstring.h"
+#include "qtl.h"
+#include "qvector.h"
+
+#include <limits.h>
+
+/*
+ WARNING! Be sure to read qregexp.tex before modifying this file.
+*/
+
+/*!
+ \class QRegExp3 qregexp.h
+
+ \brief The QRegExp class provides pattern matching using regular expressions.
+
+ \ingroup tools
+ \ingroup misc
+ \ingroup shared
+
+
+ Regular expressions, "regexps", provide a way to find patterns
+ within text. This is useful in many contexts, for example:
+
+ <ol>
+ <li>\e Validation. A regexp can be used to check whether a piece of
+ text meets some criteria, e.g. is an integer or contains no
+ whitespace.
+ <li>\e Searching. Regexps provide a much more powerful means of
+ searching text than simple string matching does. For example we can
+ create a regexp which says "find one of the words 'mail', 'letter'
+ or 'correspondence' but not any of the words 'email', 'mailman'
+ 'mailer', 'letterbox' etc."
+ <li><em>Search and Replace.</em> A regexp can be used to replace a
+ pattern with a piece of text, for example replace all occurrences of
+ '&' with '\&amp;' except where the '&' is already followed by
+ 'amp;'.
+ <li><em>String Splitting.</em> A regexp can be used to identify
+ where a string should be split into its component fields, e.g.
+ splitting tab delimited strings.
+ </ol>
+
+ We present a very brief introduction to regexps, a description of
+ Qt's regexp language, some code examples, and finally the function
+ documentation. QRegExp is modelled on Perl's regexp engine and fully
+ supports Unicode. QRegExp may also be used in the weaker 'wildcard'
+ (globbing) mode which works in a similar way to command shells. A
+ good text on regexps is <i>Mastering Regular Expressions: Powerful
+ Techniques for Perl and Other Tools</i> by Jeffrey E. Friedl, ISBN
+ 1565922573.
+
+ Experienced regexp users may prefer to skip the introduction and
+ go directly to the relevant information:
+
+ <ul>
+ <li><a href="#characters-and-abbreviations-for-sets-of-characters">
+ Characters and Abbreviations for Sets of Characters</a>
+ <li><a href="#sets-of-characters">Sets of Characters</a>
+ <li><a href="#quantifiers">Quantifiers</a>
+ <li><a href="#capturing-text">Capturing Text</a>
+ <li><a href="#assertions">Assertions</a>
+ <li><a href="#wildcard-matching">Wildcard Matching (globbing)</a>
+ <li><a href="#perl-users">Notes for Perl Users</a>
+ <li><a href="#code-examples">Code Examples</a>
+ <li><a href="#member-function-documentation">Member Function Documentation</a>
+ </ul>
+
+ <b>Introduction</b>
+
+ Regexps are built up from expressions, quantifiers and assertions.
+ The simplest form of expression is simply a character, e.g. <b>x</b>
+ or <b>5</b>. An expression can also be a set of characters. For
+ example, <b>[ABCD]</b>, will match an <b>A</b> or a <b>B</b> or a
+ <b>C</b> or a <b>D</b>. As a shorthand we could write this as
+ <b>[A-D]</b>. If we want to match any of the captital letters in the
+ English alphabet we can write <b>[A-Z]</b>. A quantifier tells the
+ regexp engine how many occurrences of the expression we want, e.g.
+ <b>x{1,1}</b> means match an <b>x</b> which occurs at least once and
+ at most once. We'll look at assertions and more complex expressions
+ later. Note that regexps cannot be used to check for balanced
+ brackets or tags (unless you know the maximum level of nesting).
+
+
+ We'll start by writing a regexp to match integers in the range 0 to
+ 99. We will require at least one digit so we will start with
+ <b>[0-9]{1,1}</b> which means match a digit exactly once. This
+ regexp alone will match integers in the range 0 to 9. To match one
+ or two digits we can increase the maximum number of occurrences so
+ the regexp becomes <b>[0-9]{1,2}</b> meaning match a digit at least
+ once and at most twice. However, this regexp as it stands will not
+ match correctly. This regexp will match one or two digits \e within
+ a string. To ensure that we match against the whole string we must
+ use the anchor assertions. We need <b>^</b> (caret) which when it is
+ the first character in the regexp means that the regexp must match
+ from the beginning of the string. And we also need <b>$</b> (dollar)
+ which when it is the last character in the regexp means that the
+ regexp must match until the end of the string. So now our regexp is
+ <b>^[0-9]{1,2}$</b>. Note that assertions do not match any
+ characters.
+
+ If you've seen regexps elsewhere they may have looked different from
+ the one above. This is because some sets of characters and some
+ quantifiers are so common that they have special symbols to
+ represent them. <b>[0-9]</b> can be replaced with the symbol
+ <b>\d</b>. The quantifier to match exactly one occurrence,
+ <b>{1,1}</b>, can be replaced with the expression itself. This means
+ that <b>x{1,1}</b> is exactly the same as <b>x</b> alone. So our 0
+ to 99 matcher could be written: <b>^\d{1,2}$</b>, although most
+ people would write it <b>^\d\d?$</b>. The <b>?</b> is the same as
+ the quantifier <b>{0,1}</b>, i.e. a minimum of no occurrences a
+ maximum of one occurrence. This is used to make an expression
+ optional. The regexp <b>^\d\d?$</b> means "from the beginning of the
+ string match one digit followed by zero or one digits and then the
+ end of the string".
+
+ Our second example is matching the words 'mail', 'letter' or
+ 'correspondence' but without matching 'email', 'mailman', 'mailer',
+ 'letterbox' etc. We'll start by just matching 'mail'. In full the
+ regexp is, <b>m{1,1}a{1,1}i{1,1}l{1,1}</b>, but since an expression
+ itself is automatically quantified by <b>{1,1}</b> we can simply
+ write this as <b>mail</b>; an 'm' followed by an 'a' followed by an
+ 'i' followed by an 'l'. The symbol '|' (bar) is used for \e
+ alternation, so our regexp now becomes
+ <b>mail|letter|correspondence</b> which means match 'mail' \e or
+ 'letter' \e or 'correspondence'. Whilst this regexp will find the
+ words we want it will also find words we don't want such as 'email'.
+ We will start by putting our regexp in parenthesis
+ <b>(mail|letter|correspondence)</b>. Parenthesis have two effects,
+ firstly they group expressions together and secondly they identify
+ parts of the regexp that we wish to <a href="#capturing-text">capture</a>.
+ Our regexp still matches any of the three words but now they are
+ grouped together as a unit. This is useful for building up more
+ complex regexps. It is also useful because it allows us to examine
+ which of the words actually matched. We need to use another
+ assertion, this time <b>\b</b> "word boundary":
+ <b>\b(mail|letter|correspondence)\b</b>. This regexp means "match a
+ word boundary followed by the expression in parenthesis followed by
+ another word boundary". The <b>\b</b> assertion matches at a \e
+ position in the regexp not a \e character in the regexp. A word
+ boundary is any non-word character such as a space a newline or the
+ beginning or end of the string.
+
+ For our third example we want to replace ampersands with the HTML
+ entity '\&amp;'. The regexp to match is simple: <b>\&</b>, i.e.
+ match one ampersand. Unfortunately this will mess up our text if
+ some of the ampersands have already been turned into HTML entities.
+ So what we really want to say is replace an ampersand providing it
+ is not followed by 'amp;'. For this we need the negative lookahead
+ assertion and our regexp becomes: <b>\&(?!amp;)</b>. The negative
+ lookahead assertion is introduced with '(?!' and finishes at the
+ ')'. It means that the text it contains, 'amp;' in our example, must
+ \e not follow the expression that preceeds it.
+
+ Regexps provide a rich language that can be used in a variety of
+ ways. For example suppose we want to count all the occurrences of
+ 'Eric' and 'Eirik' in a string. Two valid regexps to match these are
+ <b>\\</b><b>b(Eric|Eirik)</b><b>\\</b><b>b</b> and
+ <b>\\</b><b>bEi?ri[ck]</b><b>\\</b><b>b</b>. We need the word boundary
+ '\b' so we don't get 'Ericsson' etc. The second regexp actually
+ matches more than we want, 'Eric', 'Erik', 'Eiric' and 'Eirik'.
+
+ We will implement some the examples above in the
+ <a href="#code-examples">code examples</a> section.
+
+ <a name="characters-and-abbreviations-for-sets-of-characters">
+ <b>Characters and Abbreviations for Sets of Characters</b></a>
+
+ <ul>
+
+ <li><b>c</b> Any character represents itself unless it has a special regexp
+ meaning. Thus <b>c</b> matches the character \e c.
+
+ <li><b>\\</b><b>c</b> A character that follows a backslash matches the
+ character itself except where mentioned below. For example if you
+ wished to match a literal caret at the beginning of a string you
+ would write <b>\^</b>.
+
+ <li><b>\\</b><b>a</b> This matches the ASCII bell character (BEL, 0x07).
+ <li><b>\\</b><b>f</b> This matches the ASCII form feed character (FF, 0x0C).
+ <li><b>\\</b><b>n</b> This matches the ASCII line feed character (LF, 0x0A), (Unix newline).
+ <li><b>\\</b><b>r</b> This matches the ASCII carriage return character (CR, 0x0D).
+ <li><b>\\</b><b>t</b> This matches the ASCII horizontal tab character (HT, 0x09).
+ <li><b>\\</b><b>v</b> This matches the ASCII vertical tab character (VT, 0x0B).
+ <li><b>\\</b><b>xhhhh</b> This matches the Unicode character corresponding
+ to the hexadecimal number hhhh (between 0x0000 and 0xFFFF). \0ooo
+ (i.e., \zero ooo) matches the ASCII/Latin-1 character corresponding
+ to the octal number ooo (between 0 and 0377).
+ <li><b>. (dot)</b> This matches any character (including newline).
+ <li><b>\\</b><b>d</b> This matches a digit (see QChar::isDigit()).
+ <li><b>\\</b><b>D</b> This matches a non-digit.
+ <li><b>\\</b><b>s</b> This matches a whitespace (see QChar::isSpace()).
+ <li><b>\\</b><b>S</b> This matches a non-whitespace.
+ <li><b>\\</b><b>w</b> This matches a word character (see QChar::isLetterOrNumber()).
+ <li><b>\\</b><b>W</b> This matches a non-word character.
+ <li><b>\\</b><b>n</b> The n<sup>th</sup>
+ <a href="#capturing-text">backreference</a>, e.g. \1, \2, etc.
+ </ul>
+
+ <em>Note that the C++ compiler transforms backslashes in strings so
+ to include a <b>\\</b> in a regexp you will need to enter it twice,
+ i.e. <b>\\</b><b>\\</b>.</em>
+
+ <a name="sets-of-characters"><b>Sets of Characters</b></a>
+
+ Square brackets are used to match any character in the set of
+ characters contained within the square brackets. All the character
+ set abbreviations described above can be used within square
+ brackets. Apart from the character set abbreviations and the
+ following two exceptions no characters have special meanings in
+ square brackets.
+
+ <ul>
+
+ <li><b>^</b> The caret negates the character set if it occurs as the
+ first character, i.e. immediately after the opening square bracket.
+ For example, <b>[abc]</b> matches 'a' or 'b' or 'c', but
+ <b>[^abc]</b> matches anything \e except 'a' or 'b' or 'c'.
+
+ <li><b>-</b> The dash is used to indicate a range of characters, for
+ example <b>[W-Z]</b> matches 'W' or 'X' or 'Y' or 'Z'.
+
+ </ul>
+
+ Using the predefined character set abbreviations is more portable
+ than using character ranges across platforms and languages. For
+ example, <b>[0-9]</b> matches a digit in Western alphabets but
+ <b>\d</b> matches a digit in \e any alphabet.
+
+ Note that in most regexp literature sets of characters are called
+ "character classes".
+
+ <a name="quantifiers"><b>Quantifiers</b></a>
+
+ By default an expression is automatically quantified by
+ <b>{1,1}</b>, i.e. it should occur exactly once. In the following
+ list <b><i>E</i></b> stands for any expression. An expression is a
+ character or an abbreviation for a set of characters or a set of
+ characters in square brackets or any parenthesised expression.
+
+ <ul>
+
+ <li><b><i>E</i>?</b> Matches zero or one occurrence of <i>E</i>.
+ This quantifier means "the previous expression is optional" since it
+ will match whether or not the expression occurs in the string.
+ It is the same as <b><i>E</i>{0,1}</b>. For example <b>dents?</b>
+ will match 'dent' and 'dents'.
+
+ <li><b><i>E</i>+</b> Matches one or more occurrences of <i>E</i>.
+ This is the same as <b><i>E</i>{1,MAXINT}</b>. For example,
+ <b>0+</b> will match '0', '00', '000', etc.
+
+ <li><b><i>E</i>*</b> Matches zero or more occurrences of <i>E</i>.
+ This is the same as <b><i>E</i>{0,MAXINT}</b>. The <b>*</b>
+ quantifier is often used by a mistake. Since it matches \e zero or
+ more occurrences it will match no occurrences at all. For example if
+ we want to match strings that end in whitespace and use the regexp
+ <b>\s*$</b> we would get a match on every string. This is because we
+ have said find zero or more whitespace followed by the end of string,
+ so even strings that don't end in whitespace will match. The regexp
+ we want in this case is <b>\s+$</b> to match strings that have at
+ least one whitespace at the end.
+
+ <li><b><i>E</i>{n}</b> Matches exactly \e n occurrences of the
+ expression. This is the same as repeating the expression \e n times.
+ For example, <b>x{5}</b> is the same as <b>xxxxx</b>. It is also the
+ same as <b><i>E</i>{n,n}</b>, e.g. <b>x{5,5}</b>.
+
+ <li><b><i>E</i>{n,}</b> Matches at least \e n occurrences of the
+ expression. This is the same as <b><i>E</i>{n,MAXINT}</b>.
+
+ <li><b><i>E</i>{,m}</b> Matches at most \e m occurrences of the
+ expression. This is the same as <b><i>E</i>{0,m}</b>.
+
+ <li><b><i>E</i>{n,m}</b> Matches at least \e n occurrences of the
+ expression and at most \e m occurrences of the expression.
+
+ </ul>
+
+ (MAXINT is implementation dependent but will not be smaller than
+ 16384.)
+
+ If we wish to apply a quantifier to more than just the preceeding
+ character we can use parenthesis to group characters together in an
+ expression. For example, <b>tag+</b> matches a 't' followed by an
+ 'a' followed by at least one 'g', whereas <b>(tag)+</b> matches at
+ least one occurrence of 'tag'.
+
+ Note that quantifiers are "greedy", they will match as much text as
+ they can. For example, <b>0+</b> will match as many zeros as it can
+ from the first zero it finds, e.g. '2.<u>000</u>5'. Quantifiers can
+ be made non-greedy, see setMinimal().
+
+ <a name="capturing-text"><b>Capturing Text</b></a>
+
+ Parenthesis allow us to group elements together so that we can
+ quantify and capture them. For example if we have the expression
+ <b>mail|letter|correspondence</b> that matches a string we know that
+ \e one of the words matched but not which one. Using parenthesis
+ allows us to "capture" whatever is matched within their bounds, so
+ if we used <b>(mail|letter|correspondence)</b> and matched this
+ regexp against the string "I sent you some email" we can use the
+ cap() or capturedTexts() functions to extract the matched
+ characters, in this case 'mail'.
+
+ We can use captured text within the regexp itself. To refer to the
+ captured text we use \e backreferences which are indexed from 1 the
+ same as for cap(). For example we could search for duplicate words
+ in a string using <b>\b(\w+)\W+\1\b</b> which means match a word
+ boundary followed by one or more word characters followed by one or
+ more non-word characters followed by the same text as the first
+ parenthesised expression followed by a word boundary.
+
+ If we want to use parenthesis purely for grouping and not for
+ capturing we use the non-capturing syntax, e.g.
+ <b>(?:green|blue)</b>. Non-capturing parenthesis begin '(?:' and end
+ ')'. In this example we match either 'green' or 'blue' but we do not
+ capture the match so we can only know whether or not we matched but
+ not which color we actually found. Using non-capturing parenthesis
+ is more efficient than using capturing parenthesis since the regexp
+ engine has to do less book-keeping.
+
+ Both capturing and non-capturing parenthesis may be nested.
+
+ <a name="assertions"><b>Assertions</b></a>
+
+ Assertions make some statement about the text at the point where
+ they occur in the regexp but they do not match any characters.
+ In the following list <b><i>E</i></b> stands for any expression.
+
+ <ul>
+ <li><b>^</b> If the caret is the first character in the regexp
+ (apart from opening parenthesis) it signifies the beginning of the
+ string. It has no special meaning elsewhere (except as the first
+ character of a set of characters in square brackets). For example,
+ <b>^#include</b> will only match strings which \e begin with the
+ characters '#include'.
+
+ <li><b>$</b> If the dollar is the last character in the regexp
+ (apart from closing parenthesis) it signifies the end of the string.
+ It has no special meaning elsewhere. For example, <b>\d\s*$</b>
+ will match strings which end with a digit optionally followed by
+ whitespace.
+
+ <li><b>\\</b><b>b</b> A word boundary. For example the regexp
+ <b>\\</b><b>bOK</b>\\</b><b>b</b> means match immediately after a
+ word boundary (e.g. start of string or whitespace) the letter 'O'
+ then the letter 'K' immediately before another word boundary (e.g.
+ end of string or whitespace). But note that the assertion does not
+ actually match any whitespace so if we write
+ <b>(</b><b>\\</b><b>bOK</b>\\</b><b>b)</b> and we have a match it
+ will only contain 'OK' even if the string is "Its <u>OK</u> now".
+
+ <li><b>\\</b><b>B</b> A non-word boundary. This assertion is true
+ wherever <b>\\</b><b>b</b> is false. For example if we searched for
+ <b>\\</b><b>Bon</b>\\</b><b>B</b> in "Left on" the match would fail
+ (space and end of string aren't non-word boundaries), but it would
+ match in "t<u>on</u>ne".
+
+ <li><b>(?=<i>E</i>)</b> Positive lookahead. This assertion is true
+ if the expression matches at this point in the regex. This assertion
+ does not match any characters. For example,
+ <b>^#define\s+(\w+)(?=MAX)</b> will match strings which begin with
+ '#define' followed by at least one whitespace followed by at least
+ one word character followed by 'MAX'. The first set of parenthesis
+ will capture the word character(s) matched. This regexp will not
+ match '#define DEBUG' but will match '#define <u>INT</u>MAX
+ 32767'.
+
+ <li><b>(?!<i>E</i>)</b> Negative lookahead. This assertion is true
+ if the expression does not match at this point in the regex. This
+ assertion does not match any characters. For example,
+ <b>^#define\s+(\w+)\s*$</b> will match strings which begin with
+ '#define' followed by at least one whitespace followed by at least
+ one word character optionally followed by whitespace. This regexp
+ will match define's that exist but have no value, i.e. it will not
+ match '#define INTMAX 32767' but it will match '#define <u>DEBUG</u>'.
+
+ </ul>
+
+ <a name="wildcard-matching"><b>Wildcard Matching (globbing)</b></a>
+
+ Most command shells such as \e bash or \e cmd support "file
+ globbing", the ability to identify a group of files by using
+ wildcards. Wildcard matching is much simpler than full regexps and
+ has only four features:
+
+ <ul>
+
+ <li><b>c</b> Any character represents itself apart from those
+ mentioned below. Thus <b>c</b> matches the character \e c.
+
+ <li><b>?</b> This matches any single character. It is the same as
+ <b>.</b> in full regexps.
+
+ <li><b>*</b> This matches zero or more of any characters. It is the
+ same as <b>.*</b> in full regexps.
+
+ <li><b>[...]</b> Sets of characters can be represented in square
+ brackets the same as for full regexps.
+
+ <!-- JASMIN: Are the character classes, \w, etc supported in
+ wildcards? -->
+
+ </ul>
+
+ For example if we are in wildcard mode and have strings which
+ contain filenames we could identify HTML files with <b>*.html</b>.
+ This will match zero or more characters followed by a dot followed
+ by 'h', 't', 'm' and 'l'.
+
+ <a name="perl-users"><b>Notes for Perl Users</b></a>
+
+ Most of the character class abbreviations supported by Perl are
+ supported by QRegExp, see
+ <a href="#characters-and-abbreviations-for-sets-of-characters">
+ characters and abbreviations for sets of characters</a>.
+
+ QRegExp's quantifiers are the same as Perl's greedy quantifiers.
+ Non-greedy matching cannot be applied to individual quantifiers, but
+ can be applied to all the quantifiers in the pattern. For example,
+ to match the Perl regex <b>ro+?m</b> requires:
+ \code
+ QRegExp rx( "ro+m" );
+ rx.setMinimal( TRUE );
+ \endcode
+
+ The equivalent of Perl's <tt>/i</tt> option is
+ setCaseSensitive(FALSE).
+
+ Perl's <tt>/g</tt> option can be emulated using a
+ <a href="#cap_in_a_loop">loop</a>.
+
+ In QRegExp <b>.</b> matches any character, therefore all QRegExp
+ regexps have the equivalent of Perl's <tt>/s</tt> option. QRegExp
+ does not have an equivalent to Perl's <tt>/m</tt> option, but this
+ can be emulated in various ways for example by splitting the input
+ into lines or by looping with a regexp that searches for newlines.
+
+ Because QRegExp is string oriented there are no \A, \Z or \z
+ assertions. The \G assertion is not supported but can be emulated in
+ a loop.
+
+ Perl's $& is cap(0) or capturedTexts()[0]. There are no QRegExp
+ equivalents for $`, $' or $+. $1, $2 etc correspond to
+ cap(1) or capturedTexts()[1], cap(2) or capturedTexts()[2], etc.
+
+ To substitute a pattern use QString::replace().
+
+ Perl's extended <tt>/x</tt> syntax is not supported, nor are regexp
+ comments (?#comment) or directives, e.g. (?i).
+
+ Both zero-width positive and zero-width negative lookahead
+ assertions (?=pattern) and (?!pattern) are supported with the same
+ syntax as Perl. Perl's lookbehind assertions, "independent"
+ subexpressions and conditional expressions are not supported.
+
+ Non-capturing parenthesis are also supported, with the same
+ (?:pattern) syntax.
+
+ See QStringList::split() and QStringList::join() for equivalents to
+ Perl's split and join functions.
+
+ Note: because C++ transforms \\'s they must be written \e twice in
+ code, e.g. <b>\\</b><b>b</b> must be written <b>\\</b><b>\\</b><b>b</b>.
+
+ <a name="code-examples"><b>Code Examples</b></a>
+
+ \code
+ QRegExp rx( "^\\d\\d?$" ); // Match integers 0 to 99
+ rx.search( "123" ); // Returns -1 (no match)
+ rx.search( "-6" ); // Returns -1 (no match)
+ rx.search( "6" ); // Returns 0 (matched as position 0)
+ \endcode
+
+ The third string matches '<u>6</u>'. This is a simple validation
+ regexp for integers in the range 0 to 99.
+
+ \code
+ QRegExp rx( "^\\S+$" ); // Match strings which have no whitespace
+ rx.search( "Hello world" ); // Returns -1 (no match)
+ rx.search( "This_is-OK" ); // Returns 0 (matched at position 0)
+ \endcode
+
+ The second string matches '<u>This_is-OK</u>'. We've used the
+ character set abbreviation '\S' (non-whitespace) and the anchors to
+ match strings which contain no whitespace.
+
+ In the following example we match strings containing 'mail' or
+ 'letter' or 'correspondence' but only match whole words i.e. not
+ 'email'
+
+ \code
+ QRegExp rx( "\\b(mail|letter|correspondence)\\b" );
+ rx.search( "I sent you an email" ); // Returns -1 (no match)
+ rx.search( "Please write the letter" ); // Returns 17 (matched at position 17)
+ \endcode
+
+ The second string matches "Please write the <u>letter</u>". The word
+ 'letter' is also captured (because of the parenthesis). We can see
+ what text we've captured like this:
+
+ \code
+ QString captured = rx.cap( 1 ); // captured contains "letter"
+ \endcode
+
+ This will capture the text from the first set of capturing
+ parenthesis (counting capturing left parenthesis from left to
+ right). The parenthesis are counted from 1 since cap( 0 ) is the
+ whole matched regexp (equivalent to '&' in most regexp engines).
+
+ \code
+ QRegExp rx( "&(?!amp;)" ); // Match ampersands but not &amp;
+ QString line1 = "This & that";
+ line1.replace( rx, "&amp;" );
+ // line1 == "This &amp; that"
+ QString line2 = "His &amp; hers & theirs";
+ line2.replace( rx, "&amp;" );
+ // line2 == "His &amp; hers &amp; theirs"
+ \endcode
+
+ Here we've passed the QRegExp to QString's replace() function to
+ replace the matched text with new text.
+
+ \code
+ QString str = "One Eric another Eirik, and an Ericsson. How many Eiriks, Eric?";
+ QRegExp rx( "\\b(Eric|Eirik)\\b" ); // Match Eric or Eirik
+ int pos = 0; // Where we are in the string
+ int count = 0; // How many Eric and Eirik's we've counted
+ while ( pos >= 0 ) {
+ pos = rx.search( str, pos );
+ if ( pos >= 0 ) {
+ pos++; // Move along in str
+ count++; // Count our Eric or Eirik
+ }
+ }
+ \endcode
+
+ We've used the search() function to repeatedly match the regexp in
+ the string. Note that instead of moving forward by one character at
+ a time <tt>pos++</tt> we could have written <tt>pos +=
+ rx.matchedLength()</tt> to skip over the already matched string. The
+ count will equal 3, matching 'One <u>Eric</u> another <u>Eirik</u>,
+ and an Ericsson. How many Eiriks, <u>Eric</u>?'; it doesn't match
+ 'Ericsson' or 'Eiriks' because they are not bounded by non-word
+ boundaries.
+
+ One common use of regexps is to split lines of delimited data into
+ their component fields.
+
+ \code
+ str = "Trolltech AS\twww.trolltech.com\tNorway";
+ QString company, web, country;
+ rx.setPattern( "^([^\t]+)\t([^\t]+)\t([^\t]+)$" );
+ if ( rx.search( str ) != -1 ) {
+ company = rx.cap( 1 );
+ web = rx.cap( 2 );
+ country = rx.cap( 3 );
+ }
+ \endcode
+
+ In this example our input lines have the format company name, web
+ address and country. Unfortunately the regexp is rather long and not
+ very versatile -- the code will break if we add any more fields. A
+ simpler and better solution is to look for the separator, '\t' in
+ this case, and take the surrounding text. The QStringList split()
+ function can take a separator string or regexp as an argument and
+ split a string accordingly.
+
+ \code
+ QStringList field = QStringList::split( "\t", str );
+ \endcode
+
+ Here field[0] is the company, field[1] the web address and so on.
+
+ To immitate the matching of a shell we can use wildcard mode.
+
+ \code
+ QRegExp rx( "*.html" ); // Invalid regexp: * doesn't quantify anything
+ rx.setWildcard( TRUE ); // Now its a valid wildcard regexp
+ rx.search( "index.html" ); // Returns 0 (matched at position 0)
+ rx.search( "default.htm" ); // Returns -1 (no match)
+ rx.search( "readme.txt" ); // Returns -1 (no match)
+ \endcode
+
+ Wildcard matching can be convenient because of its simplicity, but
+ any wildcard regex can be defined using full regexps, e.g.
+ <b>.*\.html$</b>. Notice that we can't match both \c .html and \c
+ .htm files with a wildcard unless we use <b>*.htm*</b> which will
+ also match 'test.html.bak'. A full regexp gives us the precision we
+ need, <b>.*\.html?$</b>.
+
+ QRegExp can match case insensitively using setCaseSensitive(), and
+ can use non-greedy matching, see setMinimal(). By default QRegExp
+ uses full regexps but this can be changed with setWildcard().
+ Searching can be forward with search() or backward with searchRev().
+ Captured text can be accessed using capturedTexts() which returns a
+ string list of all captured strings, or using cap() which returns
+ the captured string for the given index. The pos() function takes a
+ match index and returns the position in the string where the match
+ was made (or -1 if there was no match).
+
+ \sa QRegExpValidator QString QStringList
+
+ <a name="member-function-documentation"/>
+*/
+
+static const int NumBadChars = 128;
+#define BadChar( ch ) ( (ch).cell() % NumBadChars )
+
+static const int NoOccurrence = INT_MAX;
+static const int EmptyCapture = INT_MAX;
+static const int InftyLen = INT_MAX;
+static const int InftyRep = 1000;
+static const int EOS = -1;
+
+#ifndef QT_NO_REGEXP_OPTIM
+static int engCount = 0;
+static QArray<int> *noOccurrences = 0;
+static QArray<int> *firstOccurrenceAtZero = 0;
+#endif
+
+/*
+ Merges two QArrays of ints and puts the result into the first one.
+*/
+static void mergeInto( QArray<int> *a, const QArray<int>& b )
+{
+ int asize = a->size();
+ int bsize = b.size();
+ if ( asize == 0 ) {
+ *a = b.copy();
+#ifndef QT_NO_REGEXP_OPTIM
+ } else if ( bsize == 1 && (*a)[asize - 1] < b[0] ) {
+ a->resize( asize + 1 );
+ (*a)[asize] = b[0];
+#endif
+ } else if ( bsize >= 1 ) {
+ int csize = asize + bsize;
+ QArray<int> c( csize );
+ int i = 0, j = 0, k = 0;
+ while ( i < asize ) {
+ if ( j < bsize ) {
+ if ( (*a)[i] == b[j] ) {
+ i++;
+ csize--;
+ } else if ( (*a)[i] < b[j] ) {
+ c[k++] = (*a)[i++];
+ } else {
+ c[k++] = b[j++];
+ }
+ } else {
+ memcpy( c.data() + k, (*a).data() + i,
+ (asize - i) * sizeof(int) );
+ break;
+ }
+ }
+ c.resize( csize );
+ if ( j < bsize )
+ memcpy( c.data() + k, b.data() + j, (bsize - j) * sizeof(int) );
+ *a = c;
+ }
+}
+
+/*
+ Merges two disjoint QMaps of (int, int) pairs and puts the result into the
+ first one.
+*/
+static void mergeInto( QMap<int, int> *a, const QMap<int, int>& b )
+{
+ QMap<int, int>::ConstIterator it;
+ for ( it = b.begin(); it != b.end(); ++it )
+ a->insert( it.key(), *it );
+}
+
+/*
+ Returns the value associated to key k in QMap m of (int, int) pairs, or 0 if
+ no such value is explicitly present.
+*/
+static int at( const QMap<int, int>& m, int k )
+{
+ QMap<int, int>::ConstIterator it = m.find( k );
+ if ( it == m.end() )
+ return 0;
+ else
+ return *it;
+}
+
+#ifndef QT_NO_REGEXP_WILDCARD
+/*
+ Translates a wildcard pattern to an equivalent regular expression pattern
+ (e.g., *.cpp to .*\.cpp).
+*/
+static QString wc2rx( const QString& wc )
+{
+ int wclen = wc.length();
+ QString rx = QString::fromLatin1( "" );
+ int i = 0;
+ while ( i < wclen ) {
+ QChar c = wc[i++];
+ switch ( c.unicode() ) {
+ case '*':
+ rx += QString::fromLatin1( ".*" );
+ break;
+ case '?':
+ rx += QChar( '.' );
+ break;
+ case '$':
+ case '(':
+ case ')':
+ case '+':
+ case '.':
+ case '\\':
+ case '^':
+ case '{':
+ case '|':
+ case '}':
+ rx += QChar( '\\' );
+ rx += c;
+ break;
+ case '[':
+ rx += c;
+ if ( wc[i] == QChar('^') )
+ rx += wc[i++];
+ if ( i < wclen ) {
+ if ( rx[i] == ']' )
+ rx += wc[i++];
+ while ( i < wclen && wc[i] != QChar(']') ) {
+ if ( wc[i] == '\\' )
+ rx += QChar( '\\' );
+ rx += wc[i++];
+ }
+ }
+ break;
+ default:
+ rx += c;
+ }
+ }
+ return rx;
+}
+#endif
+
+/*
+ The class QRegExpEngine encapsulates a modified nondeterministic finite
+ automaton (NFA).
+*/
+class QRegExpEngine : public QShared
+{
+public:
+#ifndef QT_NO_REGEXP_CCLASS
+ /*
+ The class CharClass represents a set of characters, such as can be found
+ in regular expressions (e.g., [a-z] denotes the set {a, b, ..., z}).
+ */
+ class CharClass
+ {
+ public:
+ CharClass();
+ CharClass( const CharClass& cc ) { operator=( cc ); }
+
+ CharClass& operator=( const CharClass& cc );
+
+ void clear();
+ bool negative() const { return n; }
+ void setNegative( bool negative );
+ void addCategories( int cats );
+ void addRange( ushort from, ushort to );
+ void addSingleton( ushort ch ) { addRange( ch, ch ); }
+
+ bool in( QChar ch ) const;
+#ifndef QT_NO_REGEXP_OPTIM
+ const QArray<int>& firstOccurrence() const { return occ1; }
+#endif
+
+#if defined(QT_DEBUG)
+ void dump() const;
+#endif
+
+ private:
+ /*
+ The struct Range represents a range of characters (e.g., [0-9] denotes
+ range 48 to 57).
+ */
+ struct Range
+ {
+ ushort from; // 48
+ ushort to; // 57
+ };
+
+ int c; // character classes
+ QArray<Range> r; // character ranges
+ bool n; // negative?
+#ifndef QT_NO_REGEXP_OPTIM
+ QArray<int> occ1; // first-occurrence array
+#endif
+ };
+#else
+ struct CharClass
+ {
+ int x; // dummy
+
+#ifndef QT_NO_REGEXP_OPTIM
+ const QArray<int>& firstOccurrence() const {
+ return *firstOccurrenceAtZero;
+ }
+#endif
+ };
+#endif
+
+ QRegExpEngine( bool caseSensitive ) { setup( caseSensitive ); }
+ QRegExpEngine( const QString& rx, bool caseSensitive );
+#ifndef QT_NO_REGEXP_OPTIM
+ ~QRegExpEngine();
+#endif
+
+ bool isValid() const { return valid; }
+ bool caseSensitive() const { return cs; }
+ int numCaptures() const { return realncap; }
+ QArray<int> match( const QString& str, int pos, bool minimal,
+ bool oneTest );
+ int matchedLength() const { return mmMatchedLen; }
+
+ int createState( QChar ch );
+ int createState( const CharClass& cc );
+#ifndef QT_NO_REGEXP_BACKREF
+ int createState( int bref );
+#endif
+
+ void addCatTransitions( const QArray<int>& from, const QArray<int>& to );
+#ifndef QT_NO_REGEXP_CAPTURE
+ void addPlusTransitions( const QArray<int>& from, const QArray<int>& to,
+ int atom );
+#endif
+
+#ifndef QT_NO_REGEXP_ANCHOR_ALT
+ int anchorAlternation( int a, int b );
+ int anchorConcatenation( int a, int b );
+#else
+ int anchorAlternation( int a, int b ) { return a & b; }
+ int anchorConcatenation( int a, int b ) { return a | b; }
+#endif
+ void addAnchors( int from, int to, int a );
+
+#ifndef QT_NO_REGEXP_OPTIM
+ void setupGoodStringHeuristic( int earlyStart, int lateStart,
+ const QString& str );
+ void setupBadCharHeuristic( int minLen, const QArray<int>& firstOcc );
+ void heuristicallyChooseHeuristic();
+#endif
+
+#if defined(QT_DEBUG)
+ void dump() const;
+#endif
+
+private:
+ enum { CharClassBit = 0x10000, BackRefBit = 0x20000 };
+
+ /*
+ The struct State represents one state in a modified NFA. The input
+ characters matched are stored in the state instead of on the transitions,
+ something possible for an automaton constructed from a regular expression.
+ */
+ struct State
+ {
+#ifndef QT_NO_REGEXP_CAPTURE
+ int atom; // which atom does this state belong to?
+#endif
+ int match; // what does it match? (see CharClassBit and BackRefBit)
+ QArray<int> outs; // out-transitions
+ QMap<int, int> *reenter; // atoms reentered when transiting out
+ QMap<int, int> *anchors; // anchors met when transiting out
+
+#ifndef QT_NO_REGEXP_CAPTURE
+ State( int a, int m )
+ : atom( a ), match( m ), reenter( 0 ), anchors( 0 ) { }
+#else
+ State( int m )
+ : match( m ), reenter( 0 ), anchors( 0 ) { }
+#endif
+ ~State() { delete reenter; delete anchors; }
+ };
+
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ /*
+ The struct Lookahead represents a lookahead a la Perl (e.g., (?=foo) and
+ (?!bar)).
+ */
+ struct Lookahead
+ {
+ QRegExpEngine *eng; // NFA representing the embedded regular expression
+ bool neg; // negative lookahead?
+
+ Lookahead( QRegExpEngine *eng0, bool neg0 )
+ : eng( eng0 ), neg( neg0 ) { }
+ ~Lookahead() { delete eng; }
+ };
+#endif
+
+#ifndef QT_NO_REGEXP_CAPTURE
+ /*
+ The struct Atom represents one node in the hierarchy of regular expression
+ atoms.
+ */
+ struct Atom
+ {
+ int parent; // index of parent in array of atoms
+ int capture; // index of capture, from 1 to ncap
+ };
+#endif
+
+#ifndef QT_NO_REGEXP_ANCHOR_ALT
+ /*
+ The struct AnchorAlternation represents a pair of anchors with OR
+ semantics.
+ */
+ struct AnchorAlternation
+ {
+ int a; // this anchor...
+ int b; // ...or this one
+ };
+#endif
+
+ enum { InitialState = 0, FinalState = 1 };
+ void setup( bool caseSensitive );
+ int setupState( int match );
+
+ /*
+ Let's hope that 13 lookaheads and 14 back-references are enough.
+ */
+ enum { MaxLookaheads = 13, MaxBackRefs = 14 };
+ enum { Anchor_Dollar = 0x00000001, Anchor_Caret = 0x00000002,
+ Anchor_Word = 0x00000004, Anchor_NonWord = 0x00000008,
+ Anchor_FirstLookahead = 0x00000010,
+ Anchor_BackRef1Empty = Anchor_FirstLookahead << MaxLookaheads,
+ Anchor_BackRef0Empty = Anchor_BackRef1Empty >> 1,
+ Anchor_Alternation = Anchor_BackRef1Empty << MaxBackRefs,
+
+ Anchor_LookaheadMask = ( Anchor_FirstLookahead - 1 ) ^
+ ( (Anchor_FirstLookahead << MaxLookaheads) - 1 ) };
+#ifndef QT_NO_REGEXP_CAPTURE
+ int startAtom( bool capture );
+ void finishAtom( int atom ) { cf = f[atom].parent; }
+#endif
+
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ int addLookahead( QRegExpEngine *eng, bool negative );
+#endif
+
+#ifndef QT_NO_REGEXP_CAPTURE
+ bool isBetterCapture( const int *begin1, const int *end1, const int *begin2,
+ const int *end2 );
+#endif
+ bool testAnchor( int i, int a, const int *capBegin );
+
+#ifndef QT_NO_REGEXP_OPTIM
+ bool goodStringMatch();
+ bool badCharMatch();
+#else
+ bool bruteMatch();
+#endif
+ bool matchHere();
+
+ QVector<State> s; // array of states
+ int ns; // number of states
+#ifndef QT_NO_REGEXP_CAPTURE
+ QArray<Atom> f; // atom hierarchy
+ int nf; // number of atoms
+ int cf; // current atom
+#endif
+ int realncap; // number of captures, seen from the outside
+ int ncap; // number of captures, seen from the inside
+#ifndef QT_NO_REGEXP_CCLASS
+ QVector<CharClass> cl; // array of character classes
+#endif
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ QVector<Lookahead> ahead; // array of lookaheads
+#endif
+#ifndef QT_NO_REGEXP_ANCHOR_ALT
+ QArray<AnchorAlternation> aa; // array of (a, b) pairs of anchors
+#endif
+#ifndef QT_NO_REGEXP_OPTIM
+ bool caretAnchored; // does the regexp start with ^?
+#endif
+ bool valid; // is the regular expression valid?
+ bool cs; // case sensitive?
+#ifndef QT_NO_REGEXP_BACKREF
+ int nbrefs; // number of back-references
+#endif
+
+#ifndef QT_NO_REGEXP_OPTIM
+ bool useGoodStringHeuristic; // use goodStringMatch? otherwise badCharMatch
+
+ int goodEarlyStart; // the index where goodStr can first occur in a match
+ int goodLateStart; // the index where goodStr can last occur in a match
+ QString goodStr; // the string that any match has to contain
+
+ int minl; // the minimum length of a match
+ QArray<int> occ1; // first-occurrence array
+#endif
+
+ /*
+ The class Box is an abstraction for a regular expression fragment. It can
+ also be seen as one node in the syntax tree of a regular expression with
+ synthetized attributes.
+
+ It's interface is ugly for performance reasons.
+ */
+ class Box
+ {
+ public:
+ Box( QRegExpEngine *engine );
+ Box( const Box& b ) { operator=( b ); }
+
+ Box& operator=( const Box& b );
+
+ void clear() { operator=(Box(eng)); }
+ void set( QChar ch );
+ void set( const CharClass& cc );
+#ifndef QT_NO_REGEXP_BACKREF
+ void set( int bref );
+#endif
+
+ void cat( const Box& b );
+ void orx( const Box& b );
+ void plus( int atom );
+ void opt();
+ void catAnchor( int a );
+#ifndef QT_NO_REGEXP_OPTIM
+ void setupHeuristics();
+#endif
+
+#if defined(QT_DEBUG)
+ void dump() const;
+#endif
+
+ private:
+ void addAnchorsToEngine( const Box& to ) const;
+
+ QRegExpEngine *eng; // the automaton under construction
+ QArray<int> ls; // the left states (firstpos)
+ QArray<int> rs; // the right states (lastpos)
+ QMap<int, int> lanchors; // the left anchors
+ QMap<int, int> ranchors; // the right anchors
+ int skipanchors; // the anchors to match if the box is skipped
+
+#ifndef QT_NO_REGEXP_OPTIM
+ int earlyStart; // the index where str can first occur
+ int lateStart; // the index where str can last occur
+ QString str; // a string that has to occur in any match
+ QString leftStr; // a string occurring at the left of this box
+ QString rightStr; // a string occurring at the right of this box
+ int maxl; // the maximum length of this box (possibly InftyLen)
+#endif
+
+ int minl; // the minimum length of this box
+#ifndef QT_NO_REGEXP_OPTIM
+ QArray<int> occ1; // first-occurrence array
+#endif
+ };
+ friend class Box;
+
+ /*
+ This is the lexical analyzer for regular expressions.
+ */
+ enum { Tok_Eos, Tok_Dollar, Tok_LeftParen, Tok_MagicLeftParen,
+ Tok_PosLookahead, Tok_NegLookahead, Tok_RightParen, Tok_CharClass,
+ Tok_Caret, Tok_Quantifier, Tok_Bar, Tok_Word, Tok_NonWord,
+ Tok_Char = 0x10000, Tok_BackRef = 0x20000 };
+ int getChar();
+ int getEscape();
+#ifndef QT_NO_REGEXP_INTERVAL
+ int getRep( int def );
+#endif
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ void skipChars( int n );
+#endif
+ void startTokenizer( const QChar *rx, int len );
+ int getToken();
+
+ const QChar *yyIn; // a pointer to the input regular expression pattern
+ int yyPos0; // the position of yyTok in the input pattern
+ int yyPos; // the position of the next character to read
+ int yyLen; // the length of yyIn
+ int yyCh; // the last character read
+ CharClass *yyCharClass; // attribute for Tok_CharClass tokens
+ int yyMinRep; // attribute for Tok_Quantifier
+ int yyMaxRep; // ditto
+ bool yyError; // syntax error or overflow during parsing?
+
+ /*
+ This is the syntactic analyzer for regular expressions.
+ */
+ int parse( const QChar *rx, int len );
+ void parseAtom( Box *box );
+ void parseFactor( Box *box );
+ void parseTerm( Box *box );
+ void parseExpression( Box *box );
+
+ int yyTok; // the last token read
+ bool yyMayCapture; // set this to FALSE to disable capturing
+
+ /*
+ This is the engine state during matching.
+ */
+ const QString *mmStr; // a pointer to the input QString
+ const QChar *mmIn; // a pointer to the input string data
+ int mmPos; // the current position in the string
+ int mmLen; // the length of the input string
+ bool mmMinimal; // minimal matching?
+ QArray<int> mmCaptured; // an array of pairs (start, len)
+ QArray<int> mmCapturedNoMatch; // an array of pairs (-1, -1)
+ QArray<int> mmBigArray; // big QArray<int> array
+ int *mmInNextStack; // is state is mmNextStack?
+ int *mmCurStack; // stack of current states
+ int *mmNextStack; // stack of next states
+ int *mmCurCapBegin; // start of current states' captures
+ int *mmNextCapBegin; // start of next states' captures
+ int *mmCurCapEnd; // end of current states' captures
+ int *mmNextCapEnd; // end of next states' captures
+ int *mmTempCapBegin; // start of temporary captures
+ int *mmTempCapEnd; // end of temporary captures
+ int *mmCapBegin; // start of captures for a next state
+ int *mmCapEnd; // end of captures for a next state
+ int *mmSlideTab; // bump-along slide table for bad-character heuristic
+ int mmSlideTabSize; // size of slide table
+#ifndef QT_NO_REGEXP_BACKREF
+ QIntDict<int> mmSleeping; // dictionary of back-reference sleepers
+#endif
+ int mmMatchedLen; // length of match or of matched string for partial match
+};
+
+QRegExpEngine::QRegExpEngine( const QString& rx, bool caseSensitive )
+#ifndef QT_NO_REGEXP_BACKREF
+ : mmSleeping( 101 )
+#endif
+{
+ setup( caseSensitive );
+ valid = ( parse(rx.unicode(), rx.length()) == (int) rx.length() );
+}
+
+#ifndef QT_NO_REGEXP_OPTIM
+QRegExpEngine::~QRegExpEngine()
+{
+ if ( --engCount == 0 ) {
+ delete noOccurrences;
+ noOccurrences = 0;
+ delete firstOccurrenceAtZero;
+ firstOccurrenceAtZero = 0;
+ }
+}
+#endif
+
+/*
+ Tries to match in str and returns an array of (begin, length) pairs for
+ captured text. If there is no match, all pairs are (-1, -1).
+*/
+QArray<int> QRegExpEngine::match( const QString& str, int pos, bool minimal,
+ bool oneTest )
+{
+ mmStr = &str;
+ mmIn = str.unicode();
+ if ( mmIn == 0 )
+ mmIn = &QChar::null;
+ mmPos = pos;
+ mmLen = str.length();
+ mmMinimal = minimal;
+ mmMatchedLen = 0;
+
+ bool matched = FALSE;
+ if ( valid && mmPos >= 0 && mmPos <= mmLen ) {
+#ifndef QT_NO_REGEXP_OPTIM
+ if ( mmPos <= mmLen - minl ) {
+ if ( caretAnchored || oneTest )
+ matched = matchHere();
+ else if ( useGoodStringHeuristic )
+ matched = goodStringMatch();
+ else
+ matched = badCharMatch();
+ }
+#else
+ matched = oneTest ? matchHere() : bruteMatch();
+#endif
+ }
+
+ if ( matched ) {
+ mmCaptured.detach();
+ mmCaptured[0] = mmPos;
+ mmCaptured[1] = mmMatchedLen;
+ for ( int j = 0; j < realncap; j++ ) {
+ int len = mmCapEnd[j] - mmCapBegin[j];
+ mmCaptured[2 + 2 * j] = len > 0 ? mmPos + mmCapBegin[j] : 0;
+ mmCaptured[2 + 2 * j + 1] = len;
+ }
+ return mmCaptured;
+ } else {
+ return mmCapturedNoMatch;
+ }
+}
+
+/*
+ The three following functions add one state to the automaton and return the
+ number of the state.
+*/
+
+int QRegExpEngine::createState( QChar ch )
+{
+ return setupState( ch.unicode() );
+}
+
+int QRegExpEngine::createState( const CharClass& cc )
+{
+#ifndef QT_NO_REGEXP_CCLASS
+ int n = cl.size();
+ cl.resize( n + 1 );
+ cl.insert( n, new CharClass(cc) );
+ return setupState( CharClassBit | n );
+#else
+ Q_UNUSED( cc );
+ return setupState( CharClassBit );
+#endif
+}
+
+#ifndef QT_NO_REGEXP_BACKREF
+int QRegExpEngine::createState( int bref )
+{
+ if ( bref > nbrefs ) {
+ nbrefs = bref;
+ if ( nbrefs > MaxBackRefs ) {
+ yyError = TRUE;
+ return 0;
+ }
+ }
+ return setupState( BackRefBit | bref );
+}
+#endif
+
+/*
+ The two following functions add a transition between all pairs of states
+ (i, j) where i is fond in from, and j is found in to.
+
+ Cat-transitions are distinguished from plus-transitions for capturing.
+*/
+
+void QRegExpEngine::addCatTransitions( const QArray<int>& from,
+ const QArray<int>& to )
+{
+ for ( int i = 0; i < (int) from.size(); i++ ) {
+ State *st = s[from[i]];
+ mergeInto( &st->outs, to );
+ }
+}
+
+#ifndef QT_NO_REGEXP_CAPTURE
+void QRegExpEngine::addPlusTransitions( const QArray<int>& from,
+ const QArray<int>& to, int atom )
+{
+ for ( int i = 0; i < (int) from.size(); i++ ) {
+ State *st = s[from[i]];
+ QArray<int> oldOuts = st->outs.copy();
+ mergeInto( &st->outs, to );
+ if ( f[atom].capture >= 0 ) {
+ if ( st->reenter == 0 )
+ st->reenter = new QMap<int, int>;
+ for ( int j = 0; j < (int) to.size(); j++ ) {
+ if ( !st->reenter->contains(to[j]) &&
+ oldOuts.bsearch(to[j]) < 0 )
+ st->reenter->insert( to[j], atom );
+ }
+ }
+ }
+}
+#endif
+
+#ifndef QT_NO_REGEXP_ANCHOR_ALT
+/*
+ Returns an anchor that means a OR b.
+*/
+int QRegExpEngine::anchorAlternation( int a, int b )
+{
+ if ( ((a & b) == a || (a & b) == b) && ((a | b) & Anchor_Alternation) == 0 )
+ return a & b;
+
+ int n = aa.size();
+ aa.resize( n + 1 );
+ aa[n].a = a;
+ aa[n].b = b;
+ return Anchor_Alternation | n;
+}
+
+/*
+ Returns an anchor that means a AND b.
+*/
+int QRegExpEngine::anchorConcatenation( int a, int b )
+{
+ if ( ((a | b) & Anchor_Alternation) == 0 )
+ return a | b;
+ if ( (b & Anchor_Alternation) != 0 )
+ qSwap( a, b );
+ int aprime = anchorConcatenation( aa[a ^ Anchor_Alternation].a, b );
+ int bprime = anchorConcatenation( aa[a ^ Anchor_Alternation].b, b );
+ return anchorAlternation( aprime, bprime );
+}
+#endif
+
+/*
+ Adds anchor a on a transition caracterised by its from state and its to state.
+*/
+void QRegExpEngine::addAnchors( int from, int to, int a )
+{
+ State *st = s[from];
+ if ( st->anchors == 0 )
+ st->anchors = new QMap<int, int>;
+ if ( st->anchors->contains(to) )
+ a = anchorAlternation( (*st->anchors)[to], a );
+ st->anchors->insert( to, a );
+}
+
+#ifndef QT_NO_REGEXP_OPTIM
+/*
+ The two following functions provide the engine with the information needed by
+ its matching heuristics.
+*/
+
+void QRegExpEngine::setupGoodStringHeuristic( int earlyStart, int lateStart,
+ const QString& str )
+{
+ goodEarlyStart = earlyStart;
+ goodLateStart = lateStart;
+ goodStr = cs ? str : str.lower();
+}
+
+void QRegExpEngine::setupBadCharHeuristic( int minLen,
+ const QArray<int>& firstOcc )
+{
+ minl = minLen;
+ occ1 = cs ? firstOcc : *firstOccurrenceAtZero;
+}
+
+/*
+ This function chooses between the good-string and the bad-character
+ heuristics. It computes two scores and chooses the heuristic with the highest
+ score.
+
+ Here are some common-sense constraints on the scores that should be respected
+ if the formulas are ever modified: (1) If goodStr is empty, the good-string
+ heuristic scores 0. (2) If the search is case insensitive, the good-string
+ heuristic should be used, unless it scores 0. (Case insensitivity
+ turns all entries of occ1 to 0.) (3) If (goodLateStart - goodEarlyStart) is
+ big, the good-string heuristic should score less.
+*/
+void QRegExpEngine::heuristicallyChooseHeuristic()
+{
+ int i;
+
+ if ( minl == 0 )
+ return;
+
+ /*
+ Magic formula: The good string has to constitute a good proportion of the
+ minimum-length string, and appear at a more-or-less known index.
+ */
+ int goodStringScore = ( 64 * goodStr.length() / minl ) -
+ ( goodLateStart - goodEarlyStart );
+
+ /*
+ Less magic formula: We pick a couple of characters at random, and check
+ whether they are good or bad.
+ */
+ int badCharScore = 0;
+ int step = QMAX( 1, NumBadChars / 32 );
+ for ( i = 1; i < NumBadChars; i += step ) {
+ if ( occ1[i] == NoOccurrence )
+ badCharScore += minl;
+ else
+ badCharScore += occ1[i];
+ }
+ badCharScore /= minl;
+
+ useGoodStringHeuristic = ( goodStringScore > badCharScore );
+}
+#endif
+
+#if defined(QT_DEBUG)
+void QRegExpEngine::dump() const
+{
+ int i, j;
+ qDebug( "Case %ssensitive engine", cs ? "" : "in" );
+ qDebug( " States" );
+ for ( i = 0; i < ns; i++ ) {
+ qDebug( " %d%s", i,
+ i == InitialState ? " (initial)" :
+ i == FinalState ? " (final)" : "" );
+#ifndef QT_NO_REGEXP_CAPTURE
+ qDebug( " in atom %d", s[i]->atom );
+#endif
+ int m = s[i]->match;
+ if ( (m & CharClassBit) != 0 ) {
+ qDebug( " match character class %d", m ^ CharClassBit );
+#ifndef QT_NO_REGEXP_CCLASS
+ cl[m ^ CharClassBit]->dump();
+#else
+ qDebug( " negative character class" );
+#endif
+ } else if ( (m & BackRefBit) != 0 ) {
+ qDebug( " match back-reference %d", m ^ BackRefBit );
+ } else if ( m >= 0x20 && m <= 0x7e ) {
+ qDebug( " match 0x%.4x (%c)", m, m );
+ } else {
+ qDebug( " match 0x%.4x", m );
+ }
+ for ( j = 0; j < (int) s[i]->outs.size(); j++ ) {
+ int next = s[i]->outs[j];
+ qDebug( " -> %d", next );
+ if ( s[i]->reenter != 0 && s[i]->reenter->contains(next) )
+ qDebug( " [reenter %d]", (*s[i]->reenter)[next] );
+ if ( s[i]->anchors != 0 && at(*s[i]->anchors, next) != 0 )
+ qDebug( " [anchors 0x%.8x]", (*s[i]->anchors)[next] );
+ }
+ }
+#ifndef QT_NO_REGEXP_CAPTURE
+ if ( nf > 0 ) {
+ qDebug( " Atom Parent Capture" );
+ for ( i = 0; i < nf; i++ )
+ qDebug( " %6d %6d %6d", i, f[i].parent, f[i].capture );
+ }
+#endif
+#ifndef QT_NO_REGEXP_ANCHOR_ALT
+ for ( i = 0; i < (int) aa.size(); i++ )
+ qDebug( " Anchor alternation 0x%.8x: 0x%.8x 0x%.9x", i, aa[i].a,
+ aa[i].b );
+#endif
+}
+#endif
+
+void QRegExpEngine::setup( bool caseSensitive )
+{
+#ifndef QT_NO_REGEXP_OPTIM
+ if ( engCount++ == 0 ) {
+ noOccurrences = new QArray<int>( NumBadChars );
+ firstOccurrenceAtZero = new QArray<int>( NumBadChars );
+ noOccurrences->fill( NoOccurrence );
+ firstOccurrenceAtZero->fill( 0 );
+ }
+#endif
+ s.setAutoDelete( TRUE );
+ s.resize( 32 );
+ ns = 0;
+#ifndef QT_NO_REGEXP_CAPTURE
+ f.resize( 32 );
+ nf = 0;
+ cf = -1;
+#endif
+ realncap = 0;
+ ncap = 0;
+#ifndef QT_NO_REGEXP_CCLASS
+ cl.setAutoDelete( TRUE );
+#endif
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ ahead.setAutoDelete( TRUE );
+#endif
+#ifndef QT_NO_REGEXP_OPTIM
+ caretAnchored = TRUE;
+#endif
+ valid = FALSE;
+ cs = caseSensitive;
+#ifndef QT_NO_REGEXP_BACKREF
+ nbrefs = 0;
+#endif
+#ifndef QT_NO_REGEXP_OPTIM
+ useGoodStringHeuristic = FALSE;
+ minl = 0;
+ occ1 = *firstOccurrenceAtZero;
+#endif
+ mmCapturedNoMatch.fill( -1, 2 );
+}
+
+int QRegExpEngine::setupState( int match )
+{
+ if ( (ns & (ns + 1)) == 0 && ns + 1 >= (int) s.size() )
+ s.resize( (ns + 1) << 1 );
+#ifndef QT_NO_REGEXP_CAPTURE
+ s.insert( ns, new State(cf, match) );
+#else
+ s.insert( ns, new State(match) );
+#endif
+ return ns++;
+}
+
+#ifndef QT_NO_REGEXP_CAPTURE
+/*
+ Functions startAtom() and finishAtom() should be called to delimit atoms.
+ When a state is created, it is assigned to the current atom. The information
+ is later used for capturing.
+*/
+int QRegExpEngine::startAtom( bool capture )
+{
+ if ( (nf & (nf + 1)) == 0 && nf + 1 >= (int) f.size() )
+ f.resize( (nf + 1) << 1 );
+ f[nf].parent = cf;
+ cf = nf++;
+ f[cf].capture = capture ? ncap++ : -1;
+ return cf;
+}
+#endif
+
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+/*
+ Creates a lookahead anchor.
+*/
+int QRegExpEngine::addLookahead( QRegExpEngine *eng, bool negative )
+{
+ int n = ahead.size();
+ if ( n == MaxLookaheads ) {
+ yyError = TRUE;
+ return 0;
+ }
+ ahead.resize( n + 1 );
+ ahead.insert( n, new Lookahead(eng, negative) );
+ return Anchor_FirstLookahead << n;
+}
+#endif
+
+#ifndef QT_NO_REGEXP_CAPTURE
+/*
+ We want the longest leftmost captures.
+*/
+bool QRegExpEngine::isBetterCapture( const int *begin1, const int *end1,
+ const int *begin2, const int *end2 )
+{
+ for ( int i = 0; i < ncap; i++ ) {
+ int delta = begin2[i] - begin1[i]; // it has to start early...
+ if ( delta == 0 )
+ delta = end1[i] - end2[i]; // ...and end late (like a party)
+
+ if ( delta != 0 )
+ return delta > 0;
+ }
+ return FALSE;
+}
+#endif
+
+/*
+ Returns TRUE if anchor a matches at position mmPos + i in the input string,
+ otherwise FALSE.
+*/
+bool QRegExpEngine::testAnchor( int i, int a, const int *capBegin )
+{
+ int j;
+
+#ifndef QT_NO_REGEXP_ANCHOR_ALT
+ if ( (a & Anchor_Alternation) != 0 ) {
+ return testAnchor( i, aa[a ^ Anchor_Alternation].a, capBegin ) ||
+ testAnchor( i, aa[a ^ Anchor_Alternation].b, capBegin );
+ }
+#endif
+
+ if ( (a & Anchor_Caret) != 0 ) {
+ if ( mmPos + i != 0 )
+ return FALSE;
+ }
+ if ( (a & Anchor_Dollar) != 0 ) {
+ if ( mmPos + i != mmLen )
+ return FALSE;
+ }
+#ifndef QT_NO_REGEXP_ESCAPE
+ if ( (a & (Anchor_Word | Anchor_NonWord)) != 0 ) {
+ bool before = FALSE, after = FALSE;
+ if ( mmPos + i != 0 )
+ before = mmIn[mmPos + i - 1].isLetterOrNumber();
+ if ( mmPos + i != mmLen )
+ after = mmIn[mmPos + i].isLetterOrNumber();
+ if ( (a & Anchor_Word) != 0 && (before == after) )
+ return FALSE;
+ if ( (a & Anchor_NonWord) != 0 && (before != after) )
+ return FALSE;
+ }
+#endif
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ bool catchx = TRUE;
+
+ if ( (a & Anchor_LookaheadMask) != 0 ) {
+ QConstString cstr = QConstString( (QChar *) mmIn + mmPos + i,
+ mmLen - mmPos - i );
+ for ( j = 0; j < (int) ahead.size(); j++ ) {
+ if ( (a & (Anchor_FirstLookahead << j)) != 0 ) {
+ catchx = ( ahead[j]->eng->match(cstr.string(), 0, TRUE,
+ TRUE)[0] == 0 );
+ if ( catchx == ahead[j]->neg )
+ return FALSE;
+ }
+ }
+ }
+#endif
+#ifndef QT_NO_REGEXP_CAPTURE
+#ifndef QT_NO_REGEXP_BACKREF
+ for ( j = 0; j < nbrefs; j++ ) {
+ if ( (a & (Anchor_BackRef1Empty << j)) != 0 ) {
+ if ( capBegin[j] != EmptyCapture )
+ return FALSE;
+ }
+ }
+#endif
+#endif
+ return TRUE;
+}
+
+#ifndef QT_NO_REGEXP_OPTIM
+/*
+ The three following functions are what Jeffrey Friedl would call transmissions
+ (or bump-alongs). Using one or the other should make no difference, except
+ in performance.
+*/
+
+bool QRegExpEngine::goodStringMatch()
+{
+ int k = mmPos + goodEarlyStart;
+
+ while ( (k = mmStr->find(goodStr, k, cs)) != -1 ) {
+ int from = k - goodLateStart;
+ int to = k - goodEarlyStart;
+ if ( from > mmPos )
+ mmPos = from;
+
+ while ( mmPos <= to ) {
+ if ( matchHere() )
+ return TRUE;
+ mmPos++;
+ }
+ k++;
+ }
+ return FALSE;
+}
+
+bool QRegExpEngine::badCharMatch()
+{
+ int slideHead = 0;
+ int slideNext = 0;
+ int i;
+ int lastPos = mmLen - minl;
+ memset( mmSlideTab, 0, mmSlideTabSize * sizeof(int) );
+
+ /*
+ Set up the slide table, used for the bad-character heuristic, using
+ the table of first occurrence of each character.
+ */
+ for ( i = 0; i < minl; i++ ) {
+ int sk = occ1[BadChar(mmIn[mmPos + i])];
+ if ( sk == NoOccurrence )
+ sk = i + 1;
+ if ( sk > 0 ) {
+ int k = i + 1 - sk;
+ if ( k < 0 ) {
+ sk = i + 1;
+ k = 0;
+ }
+ if ( sk > mmSlideTab[k] )
+ mmSlideTab[k] = sk;
+ }
+ }
+
+ if ( mmPos > lastPos )
+ return FALSE;
+
+ while ( TRUE ) {
+ if ( ++slideNext >= mmSlideTabSize )
+ slideNext = 0;
+ if ( mmSlideTab[slideHead] > 0 ) {
+ if ( mmSlideTab[slideHead] - 1 > mmSlideTab[slideNext] )
+ mmSlideTab[slideNext] = mmSlideTab[slideHead] - 1;
+ mmSlideTab[slideHead] = 0;
+ } else {
+ if ( matchHere() )
+ return TRUE;
+ }
+
+ if ( mmPos == lastPos )
+ break;
+
+ /*
+ Update the slide table. This code has much in common with the
+ initialization code.
+ */
+ int sk = occ1[BadChar(mmIn[mmPos + minl])];
+ if ( sk == NoOccurrence ) {
+ mmSlideTab[slideNext] = minl;
+ } else if ( sk > 0 ) {
+ int k = slideNext + minl - sk;
+ if ( k >= mmSlideTabSize )
+ k -= mmSlideTabSize;
+ if ( sk > mmSlideTab[k] )
+ mmSlideTab[k] = sk;
+ }
+ slideHead = slideNext;
+ mmPos++;
+ }
+ return FALSE;
+}
+#else
+bool QRegExpEngine::bruteMatch()
+{
+ while ( mmPos <= mmLen ) {
+ if ( matchHere() )
+ return TRUE;
+ mmPos++;
+ }
+ return FALSE;
+}
+#endif
+
+/*
+ Here's the core of the engine. It tries to do a match here and now.
+*/
+bool QRegExpEngine::matchHere()
+{
+ int ncur = 1, nnext = 0;
+ int i = 0, j, k, m;
+ bool match = FALSE;
+
+ mmMatchedLen = -1;
+ mmCurStack[0] = InitialState;
+
+#ifndef QT_NO_REGEXP_CAPTURE
+ if ( ncap > 0 ) {
+ for ( j = 0; j < ncap; j++ ) {
+ mmCurCapBegin[j] = EmptyCapture;
+ mmCurCapEnd[j] = EmptyCapture;
+ }
+ }
+#endif
+
+#ifndef QT_NO_REGEXP_BACKREF
+ int *zzZ = 0;
+
+ while ( (ncur > 0 || mmSleeping.count() > 0) && i <= mmLen - mmPos &&
+ !match )
+#else
+ while ( ncur > 0 && i <= mmLen - mmPos && !match )
+#endif
+ {
+ int ch = ( i < mmLen - mmPos ) ? mmIn[mmPos + i].unicode() : 0;
+ for ( j = 0; j < ncur; j++ ) {
+ int cur = mmCurStack[j];
+ State *scur = s[cur];
+ QArray<int>& outs = scur->outs;
+ for ( k = 0; k < (int) outs.size(); k++ ) {
+ int next = outs[k];
+ State *snext = s[next];
+ bool in = TRUE;
+#ifndef QT_NO_REGEXP_BACKREF
+ int needSomeSleep = 0;
+#endif
+
+ /*
+ First, check if the anchors are anchored properly.
+ */
+ if ( scur->anchors != 0 ) {
+ int a = at( *scur->anchors, next );
+ if ( a != 0 && !testAnchor(i, a, mmCurCapBegin + j * ncap) )
+ in = FALSE;
+ }
+ /*
+ If indeed they are, check if the input character is correct
+ for this transition.
+ */
+ if ( in ) {
+ m = snext->match;
+ if ( (m & (CharClassBit | BackRefBit)) == 0 ) {
+ if ( cs )
+ in = ( m == ch );
+ else
+ in = ( QChar(m).lower() == QChar(ch).lower() );
+ } else if ( next == FinalState ) {
+ mmMatchedLen = i;
+ match = mmMinimal;
+ in = TRUE;
+ } else if ( (m & CharClassBit) != 0 ) {
+#ifndef QT_NO_REGEXP_CCLASS
+ const CharClass *cc = cl[m ^ CharClassBit];
+ if ( cs )
+ in = cc->in( ch );
+ else if ( cc->negative() )
+ in = cc->in( QChar(ch).lower() ) &&
+ cc->in( QChar(ch).upper() );
+ else
+ in = cc->in( QChar(ch).lower() ) ||
+ cc->in( QChar(ch).upper() );
+#endif
+#ifndef QT_NO_REGEXP_BACKREF
+ } else { /* ( (m & BackRefBit) != 0 ) */
+ int bref = m ^ BackRefBit;
+ int ell = j * ncap + ( bref - 1 );
+
+ in = bref <= ncap && mmCurCapBegin[ell] != EmptyCapture;
+ if ( in ) {
+ if ( cs )
+ in = ( mmIn[mmPos + mmCurCapBegin[ell]]
+ == QChar(ch) );
+ else
+ in = ( mmIn[mmPos + mmCurCapBegin[ell]].lower()
+ == QChar(ch).lower() );
+ }
+
+ if ( in ) {
+ int delta;
+ if ( mmCurCapEnd[ell] == EmptyCapture )
+ delta = i - mmCurCapBegin[ell];
+ else
+ delta = mmCurCapEnd[ell] - mmCurCapBegin[ell];
+
+ in = ( delta <= mmLen - mmPos );
+ if ( in && delta > 1 ) {
+ int n;
+ if ( cs ) {
+ for ( n = 1; n < delta; n++ ) {
+ if ( mmIn[mmPos +
+ mmCurCapBegin[ell] + n] !=
+ mmIn[mmPos + i + n] )
+ break;
+ }
+ } else {
+ for ( n = 1; n < delta; n++ ) {
+ QChar a = mmIn[mmPos +
+ mmCurCapBegin[ell] + n];
+ QChar b = mmIn[mmPos + i + n];
+ if ( a.lower() != b.lower() )
+ break;
+ }
+ }
+ in = ( n == delta );
+ if ( in )
+ needSomeSleep = delta - 1;
+ }
+ }
+#endif
+ }
+ }
+
+ /*
+ All is right. We must now update our data structures.
+ */
+ if ( in ) {
+#ifndef QT_NO_REGEXP_CAPTURE
+ int *capBegin, *capEnd;
+#endif
+ /*
+ If the next state was not encountered yet, all is fine.
+ */
+ if ( (m = mmInNextStack[next]) == -1 ) {
+ m = nnext++;
+ mmNextStack[m] = next;
+ mmInNextStack[next] = m;
+#ifndef QT_NO_REGEXP_CAPTURE
+ capBegin = mmNextCapBegin + m * ncap;
+ capEnd = mmNextCapEnd + m * ncap;
+
+ /*
+ Otherwise, we'll first maintain captures in temporary
+ arrays, and decide at the end whether it's best to keep
+ the previous capture zones or the new ones.
+ */
+ } else {
+ capBegin = mmTempCapBegin;
+ capEnd = mmTempCapEnd;
+#endif
+ }
+
+#ifndef QT_NO_REGEXP_CAPTURE
+ /*
+ Updating the capture zones is much of a task.
+ */
+ if ( ncap > 0 ) {
+ memcpy( capBegin, mmCurCapBegin + j * ncap,
+ ncap * sizeof(int) );
+ memcpy( capEnd, mmCurCapEnd + j * ncap,
+ ncap * sizeof(int) );
+ int c = scur->atom, n = snext->atom;
+ int p = -1, q = -1;
+ int cap;
+
+ /*
+ Lemma 1. For any x in the range [0..nf), we have
+ f[x].parent < x.
+
+ Proof. By looking at startAtom(), it is clear that
+ cf < nf holds all the time, and thus that
+ f[nf].parent < nf.
+ */
+
+ /*
+ If we are reentering an atom, we empty all capture
+ zones inside it.
+ */
+ if ( scur->reenter != 0 &&
+ (q = at(*scur->reenter, next)) != 0 ) {
+ QBitArray b;
+ b.fill( FALSE, nf );
+ b.setBit( q, TRUE );
+ for ( int ell = q + 1; ell < nf; ell++ ) {
+ if ( b.testBit(f[ell].parent) ) {
+ b.setBit( ell, TRUE );
+ cap = f[ell].capture;
+ if ( cap >= 0 ) {
+ capBegin[cap] = EmptyCapture;
+ capEnd[cap] = EmptyCapture;
+ }
+ }
+ }
+ p = f[q].parent;
+
+ /*
+ Otherwise, close the capture zones we are leaving.
+ We are leaving f[c].capture, f[f[c].parent].capture,
+ f[f[f[c].parent].parent].capture, ..., until
+ f[x].capture, with x such that f[x].parent is the
+ youngest common ancestor for c and n.
+
+ We go up along c's and n's ancestry until we find x.
+ */
+ } else {
+ p = c;
+ q = n;
+ while ( p != q ) {
+ if ( p > q ) {
+ cap = f[p].capture;
+ if ( cap >= 0 ) {
+ if ( capBegin[cap] == i ) {
+ capBegin[cap] = EmptyCapture;
+ capEnd[cap] = EmptyCapture;
+ } else {
+ capEnd[cap] = i;
+ }
+ }
+ p = f[p].parent;
+ } else {
+ q = f[q].parent;
+ }
+ }
+ }
+
+ /*
+ In any case, we now open the capture zones we are
+ entering. We work upwards from n until we reach p
+ (the parent of the atom we reenter or the youngest
+ common ancestor).
+ */
+ while ( n > p ) {
+ cap = f[n].capture;
+ if ( cap >= 0 ) {
+ capBegin[cap] = i;
+ capEnd[cap] = EmptyCapture;
+ }
+ n = f[n].parent;
+ }
+ /*
+ If the next state was already in mmNextStack, we must
+ choose carefully which capture zones we want to keep.
+ */
+ if ( capBegin == mmTempCapBegin &&
+ isBetterCapture(capBegin, capEnd,
+ mmNextCapBegin + m * ncap,
+ mmNextCapEnd + m * ncap) ) {
+ memcpy( mmNextCapBegin + m * ncap, capBegin,
+ ncap * sizeof(int) );
+ memcpy( mmNextCapEnd + m * ncap, capEnd,
+ ncap * sizeof(int) );
+ }
+ }
+#ifndef QT_NO_REGEXP_BACKREF
+ /*
+ We are done with updating the capture zones. It's now
+ time to put the next state to sleep, if it needs to, and
+ to remove it from mmNextStack.
+ */
+ if ( needSomeSleep > 0 ) {
+ zzZ = new int[1 + 2 * ncap];
+ zzZ[0] = next;
+ if ( ncap > 0 ) {
+ memcpy( zzZ + 1, capBegin, ncap * sizeof(int) );
+ memcpy( zzZ + 1 + ncap, capEnd,
+ ncap * sizeof(int) );
+ }
+ mmInNextStack[mmNextStack[--nnext]] = -1;
+ mmSleeping.insert( i + needSomeSleep, zzZ );
+ }
+#endif
+#endif
+ }
+ }
+ }
+#ifndef QT_NO_REGEXP_CAPTURE
+ /*
+ If we reached the final state, hurray! Copy the captured zone.
+ */
+ if ( ncap > 0 && (m = mmInNextStack[FinalState]) != -1 ) {
+ memcpy( mmCapBegin, mmNextCapBegin + m * ncap, ncap * sizeof(int) );
+ memcpy( mmCapEnd, mmNextCapEnd + m * ncap, ncap * sizeof(int) );
+ }
+#ifndef QT_NO_REGEXP_BACKREF
+ /*
+ It's time to wake up the sleepers.
+ */
+ if ( mmSleeping.count() > 0 ) {
+ while ( (zzZ = mmSleeping.take(i)) != 0 ) {
+ int next = zzZ[0];
+ int *capBegin = zzZ + 1;
+ int *capEnd = zzZ + 1 + ncap;
+ bool copyOver = TRUE;
+
+ if ( (m = mmInNextStack[zzZ[0]]) == -1 ) {
+ m = nnext++;
+ mmNextStack[m] = next;
+ mmInNextStack[next] = m;
+ } else {
+ copyOver = isBetterCapture( mmNextCapBegin + m * ncap,
+ mmNextCapEnd + m * ncap,
+ capBegin, capEnd );
+ }
+ if ( copyOver ) {
+ memcpy( mmNextCapBegin + m * ncap, capBegin,
+ ncap * sizeof(int) );
+ memcpy( mmNextCapEnd + m * ncap, capEnd,
+ ncap * sizeof(int) );
+ }
+ delete[] zzZ;
+ }
+ }
+#endif
+#endif
+ for ( j = 0; j < nnext; j++ )
+ mmInNextStack[mmNextStack[j]] = -1;
+
+ qSwap( mmCurStack, mmNextStack );
+#ifndef QT_NO_REGEXP_CAPTURE
+ qSwap( mmCurCapBegin, mmNextCapBegin );
+ qSwap( mmCurCapEnd, mmNextCapEnd );
+#endif
+ ncur = nnext;
+ nnext = 0;
+ i++;
+ }
+
+#ifndef QT_NO_REGEXP_BACKREF
+ /*
+ If minimal matching is enabled, we might have some sleepers left.
+ */
+ while ( !mmSleeping.isEmpty() ) {
+ zzZ = mmSleeping.take( *QIntDictIterator<int>(mmSleeping) );
+ delete[] zzZ;
+ }
+#endif
+
+ match = ( mmMatchedLen >= 0 );
+ if ( !match )
+ mmMatchedLen = i - 1;
+ return match;
+}
+
+#ifndef QT_NO_REGEXP_CCLASS
+
+QRegExpEngine::CharClass::CharClass()
+ : c( 0 ), n( FALSE )
+#ifndef QT_NO_REGEXP_OPTIM
+ , occ1( *noOccurrences )
+#endif
+{
+}
+
+QRegExpEngine::CharClass& QRegExpEngine::CharClass::operator=(
+ const CharClass& cc )
+{
+ c = cc.c;
+ r = cc.r.copy();
+ n = cc.n;
+#ifndef QT_NO_REGEXP_OPTIM
+ occ1 = cc.occ1;
+#endif
+ return *this;
+}
+
+void QRegExpEngine::CharClass::clear()
+{
+ c = 0;
+ r.resize( 0 );
+ n = FALSE;
+}
+
+void QRegExpEngine::CharClass::setNegative( bool negative )
+{
+ n = negative;
+#ifndef QT_NO_REGEXP_OPTIM
+ occ1 = *firstOccurrenceAtZero;
+#endif
+}
+
+void QRegExpEngine::CharClass::addCategories( int cats )
+{
+ c |= cats;
+#ifndef QT_NO_REGEXP_OPTIM
+ occ1 = *firstOccurrenceAtZero;
+#endif
+}
+
+void QRegExpEngine::CharClass::addRange( ushort from, ushort to )
+{
+ if ( from > to )
+ qSwap( from, to );
+ int n = r.size();
+ r.resize( n + 1 );
+ r[n].from = from;
+ r[n].to = to;
+
+#ifndef QT_NO_REGEXP_OPTIM
+ int i;
+
+ if ( to - from < NumBadChars ) {
+ occ1.detach();
+ if ( from % NumBadChars <= to % NumBadChars ) {
+ for ( i = from % NumBadChars; i <= to % NumBadChars; i++ )
+ occ1[i] = 0;
+ } else {
+ for ( i = 0; i <= to % NumBadChars; i++ )
+ occ1[i] = 0;
+ for ( i = from % NumBadChars; i < NumBadChars; i++ )
+ occ1[i] = 0;
+ }
+ } else {
+ occ1 = *firstOccurrenceAtZero;
+ }
+#endif
+}
+
+bool QRegExpEngine::CharClass::in( QChar ch ) const
+{
+#ifndef QT_NO_REGEXP_OPTIM
+ if ( occ1[BadChar(ch)] == NoOccurrence )
+ return n;
+#endif
+
+ if ( c != 0 && (c & (1 << (int) ch.category())) != 0 )
+ return !n;
+ for ( int i = 0; i < (int) r.size(); i++ ) {
+ if ( ch.unicode() >= r[i].from && ch.unicode() <= r[i].to )
+ return !n;
+ }
+ return n;
+}
+
+#if defined(QT_DEBUG)
+void QRegExpEngine::CharClass::dump() const
+{
+ int i;
+ qDebug( " %stive character class", n ? "nega" : "posi" );
+#ifndef QT_NO_REGEXP_CCLASS
+ if ( c != 0 )
+ qDebug( " categories 0x%.8x", c );
+#endif
+ for ( i = 0; i < (int) r.size(); i++ )
+ qDebug( " 0x%.4x through 0x%.4x", r[i].from, r[i].to );
+}
+#endif
+#endif
+
+QRegExpEngine::Box::Box( QRegExpEngine *engine )
+ : eng( engine ), skipanchors( 0 )
+#ifndef QT_NO_REGEXP_OPTIM
+ , earlyStart( 0 ), lateStart( 0 ), maxl( 0 ), occ1( *noOccurrences )
+#endif
+{
+ minl = 0;
+}
+
+QRegExpEngine::Box& QRegExpEngine::Box::operator=( const Box& b )
+{
+ eng = b.eng;
+ ls = b.ls;
+ rs = b.rs;
+ lanchors = b.lanchors;
+ ranchors = b.ranchors;
+ skipanchors = b.skipanchors;
+#ifndef QT_NO_REGEXP_OPTIM
+ earlyStart = b.earlyStart;
+ lateStart = b.lateStart;
+ str = b.str;
+ leftStr = b.leftStr;
+ rightStr = b.rightStr;
+ maxl = b.maxl;
+ occ1 = b.occ1;
+#endif
+ minl = b.minl;
+ return *this;
+}
+
+void QRegExpEngine::Box::set( QChar ch )
+{
+ ls.resize( 1 );
+ ls[0] = eng->createState( ch );
+ rs = ls;
+ rs.detach();
+#ifndef QT_NO_REGEXP_OPTIM
+ str = ch;
+ leftStr = ch;
+ rightStr = ch;
+ maxl = 1;
+ occ1.detach();
+ occ1[BadChar(ch)] = 0;
+#endif
+ minl = 1;
+}
+
+void QRegExpEngine::Box::set( const CharClass& cc )
+{
+ ls.resize( 1 );
+ ls[0] = eng->createState( cc );
+ rs = ls;
+ rs.detach();
+#ifndef QT_NO_REGEXP_OPTIM
+ maxl = 1;
+ occ1 = cc.firstOccurrence();
+#endif
+ minl = 1;
+}
+
+#ifndef QT_NO_REGEXP_BACKREF
+void QRegExpEngine::Box::set( int bref )
+{
+ ls.resize( 1 );
+ ls[0] = eng->createState( bref );
+ rs = ls;
+ rs.detach();
+ if ( bref >= 1 && bref <= MaxBackRefs )
+ skipanchors = Anchor_BackRef0Empty << bref;
+#ifndef QT_NO_REGEXP_OPTIM
+ maxl = InftyLen;
+#endif
+ minl = 0;
+}
+#endif
+
+void QRegExpEngine::Box::cat( const Box& b )
+{
+ eng->addCatTransitions( rs, b.ls );
+ addAnchorsToEngine( b );
+ if ( minl == 0 ) {
+ mergeInto( &lanchors, b.lanchors );
+ if ( skipanchors != 0 ) {
+ for ( int i = 0; i < (int) b.ls.size(); i++ ) {
+ int a = eng->anchorConcatenation( at(lanchors, b.ls[i]),
+ skipanchors );
+ lanchors.insert( b.ls[i], a );
+ }
+ }
+ mergeInto( &ls, b.ls );
+ }
+ if ( b.minl == 0 ) {
+ mergeInto( &ranchors, b.ranchors );
+ if ( b.skipanchors != 0 ) {
+ for ( int i = 0; i < (int) rs.size(); i++ ) {
+ int a = eng->anchorConcatenation( at(ranchors, rs[i]),
+ b.skipanchors );
+ ranchors.insert( rs[i], a );
+ }
+ }
+ mergeInto( &rs, b.rs );
+ } else {
+ ranchors = b.ranchors;
+ rs = b.rs;
+ }
+
+#ifndef QT_NO_REGEXP_OPTIM
+ if ( maxl != InftyLen ) {
+ if ( rightStr.length() + b.leftStr.length() >
+ QMAX(str.length(), b.str.length()) ) {
+ earlyStart = minl - rightStr.length();
+ lateStart = maxl - rightStr.length();
+ str = rightStr + b.leftStr;
+ } else if ( b.str.length() > str.length() ) {
+ earlyStart = minl + b.earlyStart;
+ lateStart = maxl + b.lateStart;
+ str = b.str;
+ }
+ }
+
+ if ( (int) leftStr.length() == maxl )
+ leftStr += b.leftStr;
+ if ( (int) b.rightStr.length() == b.maxl )
+ rightStr += b.rightStr;
+ else
+ rightStr = b.rightStr;
+
+ if ( maxl == InftyLen || b.maxl == InftyLen )
+ maxl = InftyLen;
+ else
+ maxl += b.maxl;
+
+ occ1.detach();
+ for ( int i = 0; i < NumBadChars; i++ ) {
+ if ( b.occ1[i] != NoOccurrence && minl + b.occ1[i] < occ1[i] )
+ occ1[i] = minl + b.occ1[i];
+ }
+#endif
+
+ minl += b.minl;
+ if ( minl == 0 )
+ skipanchors = eng->anchorConcatenation( skipanchors, b.skipanchors );
+ else
+ skipanchors = 0;
+}
+
+void QRegExpEngine::Box::orx( const Box& b )
+{
+ mergeInto( &ls, b.ls );
+ mergeInto( &lanchors, b.lanchors );
+ mergeInto( &rs, b.rs );
+ mergeInto( &ranchors, b.ranchors );
+ skipanchors = eng->anchorAlternation( skipanchors, b.skipanchors );
+
+#ifndef QT_NO_REGEXP_OPTIM
+ occ1.detach();
+ for ( int i = 0; i < NumBadChars; i++ ) {
+ if ( occ1[i] > b.occ1[i] )
+ occ1[i] = b.occ1[i];
+ }
+ earlyStart = 0;
+ lateStart = 0;
+ str = QString::null;
+ leftStr = QString::null;
+ rightStr = QString::null;
+ if ( b.maxl > maxl )
+ maxl = b.maxl;
+#endif
+ if ( b.minl < minl )
+ minl = b.minl;
+}
+
+void QRegExpEngine::Box::plus( int atom )
+{
+#ifndef QT_NO_REGEXP_CAPTURE
+ eng->addPlusTransitions( rs, ls, atom );
+#else
+ Q_UNUSED( atom );
+ eng->addCatTransitions( rs, ls );
+#endif
+ addAnchorsToEngine( *this );
+#ifndef QT_NO_REGEXP_OPTIM
+ maxl = InftyLen;
+#endif
+}
+
+void QRegExpEngine::Box::opt()
+{
+#ifndef QT_NO_REGEXP_OPTIM
+ earlyStart = 0;
+ lateStart = 0;
+ str = QString::null;
+ leftStr = QString::null;
+ rightStr = QString::null;
+#endif
+ skipanchors = 0;
+ minl = 0;
+}
+
+void QRegExpEngine::Box::catAnchor( int a )
+{
+ if ( a != 0 ) {
+ for ( int i = 0; i < (int) rs.size(); i++ ) {
+ a = eng->anchorConcatenation( at(ranchors, rs[i]), a );
+ ranchors.insert( rs[i], a );
+ }
+ if ( minl == 0 )
+ skipanchors = eng->anchorConcatenation( skipanchors, a );
+ }
+}
+
+#ifndef QT_NO_REGEXP_OPTIM
+void QRegExpEngine::Box::setupHeuristics()
+{
+ eng->setupGoodStringHeuristic( earlyStart, lateStart, str );
+
+ /*
+ A regular expression such as 112|1 has occ1['2'] = 2 and minl = 1 at this
+ point. An entry of occ1 has to be at most minl or infinity for the rest
+ of the algorithm to go well.
+
+ We waited until here before normalizing these cases (instead of doing it
+ in Box::orx()) because sometimes things improve by themselves; consider
+ (112|1)34.
+ */
+ for ( int i = 0; i < NumBadChars; i++ ) {
+ if ( occ1[i] != NoOccurrence && occ1[i] >= minl )
+ occ1[i] = minl;
+ }
+ eng->setupBadCharHeuristic( minl, occ1 );
+
+ eng->heuristicallyChooseHeuristic();
+}
+#endif
+
+#if defined(QT_DEBUG)
+void QRegExpEngine::Box::dump() const
+{
+ int i;
+ qDebug( "Box of at least %d character%s", minl, minl == 1 ? "" : "s" );
+ qDebug( " Left states:" );
+ for ( i = 0; i < (int) ls.size(); i++ ) {
+ if ( at(lanchors, ls[i]) == 0 )
+ qDebug( " %d", ls[i] );
+ else
+ qDebug( " %d [anchors 0x%.8x]", ls[i], lanchors[ls[i]] );
+ }
+ qDebug( " Right states:" );
+ for ( i = 0; i < (int) rs.size(); i++ ) {
+ if ( at(ranchors, ls[i]) == 0 )
+ qDebug( " %d", rs[i] );
+ else
+ qDebug( " %d [anchors 0x%.8x]", rs[i], ranchors[rs[i]] );
+ }
+ qDebug( " Skip anchors: 0x%.8x", skipanchors );
+}
+#endif
+
+void QRegExpEngine::Box::addAnchorsToEngine( const Box& to ) const
+{
+ for ( int i = 0; i < (int) to.ls.size(); i++ ) {
+ for ( int j = 0; j < (int) rs.size(); j++ ) {
+ int a = eng->anchorConcatenation( at(ranchors, rs[j]),
+ at(to.lanchors, to.ls[i]) );
+ eng->addAnchors( rs[j], to.ls[i], a );
+ }
+ }
+}
+
+int QRegExpEngine::getChar()
+{
+ return ( yyPos == yyLen ) ? EOS : yyIn[yyPos++].unicode();
+}
+
+int QRegExpEngine::getEscape()
+{
+#ifndef QT_NO_REGEXP_ESCAPE
+ const char tab[] = "afnrtv"; // no b, as \b means word boundary
+ const char backTab[] = "\a\f\n\r\t\v";
+ ushort low;
+ int i;
+#endif
+ ushort val;
+ int prevCh = yyCh;
+
+ if ( prevCh == EOS ) {
+ yyError = TRUE;
+ return Tok_Char | '\\';
+ }
+ yyCh = getChar();
+#ifndef QT_NO_REGEXP_ESCAPE
+ if ( (prevCh & ~0xff) == 0 ) {
+ const char *p = strchr( tab, prevCh );
+ if ( p != 0 )
+ return Tok_Char | backTab[p - tab];
+ }
+#endif
+
+ switch ( prevCh ) {
+#ifndef QT_NO_REGEXP_ESCAPE
+ case '0':
+ val = 0;
+ for ( i = 0; i < 3; i++ ) {
+ if ( yyCh >= '0' && yyCh <= '7' )
+ val = ( val << 3 ) | ( yyCh - '0' );
+ else
+ break;
+ yyCh = getChar();
+ }
+ if ( (val & ~0377) != 0 )
+ yyError = TRUE;
+ return Tok_Char | val;
+#endif
+#ifndef QT_NO_REGEXP_ESCAPE
+ case 'B':
+ return Tok_NonWord;
+#endif
+#ifndef QT_NO_REGEXP_CCLASS
+ case 'D':
+ // see QChar::isDigit()
+ yyCharClass->addCategories( 0x7fffffef );
+ return Tok_CharClass;
+ case 'S':
+ // see QChar::isSpace()
+ yyCharClass->addCategories( 0x7ffff87f );
+ yyCharClass->addRange( 0x0000, 0x0008 );
+ yyCharClass->addRange( 0x000e, 0x001f );
+ yyCharClass->addRange( 0x007f, 0x009f );
+ return Tok_CharClass;
+ case 'W':
+ // see QChar::isLetterOrNumber()
+ yyCharClass->addCategories( 0x7ff07f8f );
+ return Tok_CharClass;
+#endif
+#ifndef QT_NO_REGEXP_ESCAPE
+ case 'b':
+ return Tok_Word;
+#endif
+#ifndef QT_NO_REGEXP_CCLASS
+ case 'd':
+ // see QChar::isDigit()
+ yyCharClass->addCategories( 0x00000010 );
+ return Tok_CharClass;
+ case 's':
+ // see QChar::isSpace()
+ yyCharClass->addCategories( 0x00000380 );
+ yyCharClass->addRange( 0x0009, 0x000d );
+ return Tok_CharClass;
+ case 'w':
+ // see QChar::isLetterOrNumber()
+ yyCharClass->addCategories( 0x000f8070 );
+ return Tok_CharClass;
+#endif
+#ifndef QT_NO_REGEXP_ESCAPE
+ case 'x':
+ val = 0;
+ for ( i = 0; i < 4; i++ ) {
+ low = QChar( yyCh ).lower();
+ if ( low >= '0' && low <= '9' )
+ val = ( val << 4 ) | ( low - '0' );
+ else if ( low >= 'a' && low <= 'f' )
+ val = ( val << 4 ) | ( low - 'a' + 10 );
+ else
+ break;
+ yyCh = getChar();
+ }
+ return Tok_Char | val;
+#endif
+ default:
+ if ( prevCh >= '1' && prevCh <= '9' ) {
+#ifndef QT_NO_REGEXP_BACKREF
+ val = prevCh - '0';
+ while ( yyCh >= '0' && yyCh <= '9' ) {
+ val = ( val *= 10 ) | ( yyCh - '0' );
+ yyCh = getChar();
+ }
+ return Tok_BackRef | val;
+#else
+ yyError = TRUE;
+#endif
+ }
+ return Tok_Char | prevCh;
+ }
+}
+
+#ifndef QT_NO_REGEXP_INTERVAL
+int QRegExpEngine::getRep( int def )
+{
+ if ( yyCh >= '0' && yyCh <= '9' ) {
+ int rep = 0;
+ do {
+ rep = 10 * rep + yyCh - '0';
+ if ( rep >= InftyRep ) {
+ yyError = TRUE;
+ rep = def;
+ }
+ yyCh = getChar();
+ } while ( yyCh >= '0' && yyCh <= '9' );
+ return rep;
+ } else {
+ return def;
+ }
+}
+#endif
+
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+void QRegExpEngine::skipChars( int n )
+{
+ if ( n > 0 ) {
+ yyPos += n - 1;
+ yyCh = getChar();
+ }
+}
+#endif
+
+void QRegExpEngine::startTokenizer( const QChar *rx, int len )
+{
+ yyIn = rx;
+ yyPos0 = 0;
+ yyPos = 0;
+ yyLen = len;
+ yyCh = getChar();
+ yyCharClass = new CharClass;
+ yyMinRep = 0;
+ yyMaxRep = 0;
+ yyError = FALSE;
+}
+
+int QRegExpEngine::getToken()
+{
+#ifndef QT_NO_REGEXP_CCLASS
+ ushort pendingCh = 0;
+ bool charPending;
+ bool rangePending;
+ int tok;
+#endif
+ int prevCh = yyCh;
+
+ yyPos0 = yyPos - 1;
+#ifndef QT_NO_REGEXP_CCLASS
+ yyCharClass->clear();
+#endif
+ yyMinRep = 0;
+ yyMaxRep = 0;
+ yyCh = getChar();
+ switch ( prevCh ) {
+ case EOS:
+ yyPos0 = yyPos;
+ return Tok_Eos;
+ case '$':
+ return Tok_Dollar;
+ case '(':
+ if ( yyCh == '?' ) {
+ prevCh = getChar();
+ yyCh = getChar();
+ switch ( prevCh ) {
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ case '!':
+ return Tok_NegLookahead;
+ case '=':
+ return Tok_PosLookahead;
+#endif
+ case ':':
+ return Tok_MagicLeftParen;
+ default:
+ yyError = TRUE;
+ return Tok_MagicLeftParen;
+ }
+ } else {
+ return Tok_LeftParen;
+ }
+ case ')':
+ return Tok_RightParen;
+ case '*':
+ yyMinRep = 0;
+ yyMaxRep = InftyRep;
+ return Tok_Quantifier;
+ case '+':
+ yyMinRep = 1;
+ yyMaxRep = InftyRep;
+ return Tok_Quantifier;
+ case '.':
+#ifndef QT_NO_REGEXP_CCLASS
+ yyCharClass->setNegative( TRUE );
+#endif
+ return Tok_CharClass;
+ case '?':
+ yyMinRep = 0;
+ yyMaxRep = 1;
+ return Tok_Quantifier;
+ case '[':
+#ifndef QT_NO_REGEXP_CCLASS
+ if ( yyCh == '^' ) {
+ yyCharClass->setNegative( TRUE );
+ yyCh = getChar();
+ }
+ charPending = FALSE;
+ rangePending = FALSE;
+ do {
+ if ( yyCh == '-' && charPending && !rangePending ) {
+ rangePending = TRUE;
+ yyCh = getChar();
+ } else {
+ if ( charPending && !rangePending ) {
+ yyCharClass->addSingleton( pendingCh );
+ charPending = FALSE;
+ }
+ if ( yyCh == '\\' ) {
+ yyCh = getChar();
+ tok = getEscape();
+ if ( tok == Tok_Word )
+ tok = '\b';
+ } else {
+ tok = Tok_Char | yyCh;
+ yyCh = getChar();
+ }
+ if ( tok == Tok_CharClass ) {
+ if ( rangePending ) {
+ yyCharClass->addSingleton( '-' );
+ yyCharClass->addSingleton( pendingCh );
+ charPending = FALSE;
+ rangePending = FALSE;
+ }
+ } else if ( (tok & Tok_Char) != 0 ) {
+ if ( rangePending ) {
+ yyCharClass->addRange( pendingCh, tok ^ Tok_Char );
+ charPending = FALSE;
+ rangePending = FALSE;
+ } else {
+ pendingCh = tok ^ Tok_Char;
+ charPending = TRUE;
+ }
+ } else {
+ yyError = TRUE;
+ }
+ }
+ } while ( yyCh != ']' && yyCh != EOS );
+ if ( rangePending )
+ yyCharClass->addSingleton( '-' );
+ if ( charPending )
+ yyCharClass->addSingleton( pendingCh );
+ if ( yyCh == EOS )
+ yyError = TRUE;
+ else
+ yyCh = getChar();
+ return Tok_CharClass;
+#else
+ yyError = TRUE;
+ return Tok_Char | '[';
+#endif
+ case '\\':
+ return getEscape();
+ case ']':
+ yyError = TRUE;
+ return Tok_Char | ']';
+ case '^':
+ return Tok_Caret;
+#ifndef QT_NO_REGEXP_INTERVAL
+ case '{':
+ yyMinRep = getRep( 0 );
+ yyMaxRep = yyMinRep;
+ if ( yyCh == ',' ) {
+ yyCh = getChar();
+ yyMaxRep = getRep( InftyRep );
+ }
+ if ( yyMaxRep < yyMinRep )
+ qSwap( yyMinRep, yyMaxRep );
+ if ( yyCh != '}' )
+ yyError = TRUE;
+ yyCh = getChar();
+ return Tok_Quantifier;
+#else
+ yyError = TRUE;
+ return Tok_Char | '{';
+#endif
+ case '|':
+ return Tok_Bar;
+ case '}':
+ yyError = TRUE;
+ return Tok_Char | '}';
+ default:
+ return Tok_Char | prevCh;
+ }
+}
+
+int QRegExpEngine::parse( const QChar *pattern, int len )
+{
+ valid = TRUE;
+ startTokenizer( pattern, len );
+ yyTok = getToken();
+#ifndef QT_NO_REGEXP_CAPTURE
+ yyMayCapture = TRUE;
+#else
+ yyMayCapture = FALSE;
+#endif
+
+#ifndef QT_NO_REGEXP_CAPTURE
+ int atom = startAtom( FALSE );
+#endif
+ CharClass anything;
+ Box box( this ); // create InitialState
+ box.set( anything );
+ Box rightBox( this ); // create FinalState
+ rightBox.set( anything );
+
+ Box middleBox( this );
+ parseExpression( &middleBox );
+#ifndef QT_NO_REGEXP_CAPTURE
+ finishAtom( atom );
+#endif
+#ifndef QT_NO_REGEXP_OPTIM
+ middleBox.setupHeuristics();
+#endif
+ box.cat( middleBox );
+ box.cat( rightBox );
+ delete yyCharClass;
+ yyCharClass = 0;
+
+ realncap = ncap;
+#ifndef QT_NO_REGEXP_BACKREF
+ if ( nbrefs > ncap )
+ ncap = nbrefs;
+#endif
+
+ mmCaptured.resize( 2 + 2 * realncap );
+ mmCapturedNoMatch.fill( -1, 2 + 2 * realncap );
+
+ /*
+ We use one QArray<int> for all the big data used a lot in matchHere() and
+ friends.
+ */
+#ifndef QT_NO_REGEXP_OPTIM
+ mmSlideTabSize = QMAX( minl + 1, 16 );
+#else
+ mmSlideTabSize = 0;
+#endif
+ mmBigArray.resize( (3 + 4 * ncap) * ns + 4 * ncap + mmSlideTabSize );
+
+ mmInNextStack = mmBigArray.data();
+ memset( mmInNextStack, -1, ns * sizeof(int) );
+ mmCurStack = mmInNextStack + ns;
+ mmNextStack = mmInNextStack + 2 * ns;
+
+ mmCurCapBegin = mmInNextStack + 3 * ns;
+ mmNextCapBegin = mmCurCapBegin + ncap * ns;
+ mmCurCapEnd = mmCurCapBegin + 2 * ncap * ns;
+ mmNextCapEnd = mmCurCapBegin + 3 * ncap * ns;
+
+ mmTempCapBegin = mmCurCapBegin + 4 * ncap * ns;
+ mmTempCapEnd = mmTempCapBegin + ncap;
+ mmCapBegin = mmTempCapBegin + 2 * ncap;
+ mmCapEnd = mmTempCapBegin + 3 * ncap;
+
+ mmSlideTab = mmTempCapBegin + 4 * ncap;
+
+ if ( yyError )
+ return -1;
+
+#ifndef QT_NO_REGEXP_OPTIM
+ State *sinit = s[InitialState];
+ caretAnchored = ( sinit->anchors != 0 );
+ if ( caretAnchored ) {
+ QMap<int, int>& anchors = *sinit->anchors;
+ QMap<int, int>::ConstIterator a;
+ for ( a = anchors.begin(); a != anchors.end(); ++a ) {
+#ifndef QT_NO_REGEXP_ANCHOR_ALT
+ if ( (*a & Anchor_Alternation) != 0 )
+ break;
+#endif
+ if ( (*a & Anchor_Caret) == 0 ) {
+ caretAnchored = FALSE;
+ break;
+ }
+ }
+ }
+#endif
+ return yyPos0;
+}
+
+void QRegExpEngine::parseAtom( Box *box )
+{
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ QRegExpEngine *eng = 0;
+ bool neg;
+ int len;
+#endif
+
+ switch ( yyTok ) {
+ case Tok_Dollar:
+ box->catAnchor( Anchor_Dollar );
+ break;
+ case Tok_Caret:
+ box->catAnchor( Anchor_Caret );
+ break;
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ case Tok_PosLookahead:
+ case Tok_NegLookahead:
+ neg = ( yyTok == Tok_NegLookahead );
+ eng = new QRegExpEngine( cs );
+ len = eng->parse( yyIn + yyPos - 1, yyLen - yyPos + 1 );
+ if ( len >= 0 )
+ skipChars( len );
+ else
+ yyError = TRUE;
+ box->catAnchor( addLookahead(eng, neg) );
+ yyTok = getToken();
+ if ( yyTok != Tok_RightParen )
+ yyError = TRUE;
+ break;
+#endif
+#ifndef QT_NO_REGEXP_ESCAPE
+ case Tok_Word:
+ box->catAnchor( Anchor_Word );
+ break;
+ case Tok_NonWord:
+ box->catAnchor( Anchor_NonWord );
+ break;
+#endif
+ case Tok_LeftParen:
+ case Tok_MagicLeftParen:
+ yyTok = getToken();
+ parseExpression( box );
+ if ( yyTok != Tok_RightParen )
+ yyError = TRUE;
+ break;
+ case Tok_CharClass:
+ box->set( *yyCharClass );
+ break;
+ default:
+ if ( (yyTok & Tok_Char) != 0 )
+ box->set( QChar(yyTok ^ Tok_Char) );
+#ifndef QT_NO_REGEXP_BACKREF
+ else if ( (yyTok & Tok_BackRef) != 0 )
+ box->set( yyTok ^ Tok_BackRef );
+#endif
+ else
+ yyError = TRUE;
+ }
+ yyTok = getToken();
+}
+
+void QRegExpEngine::parseFactor( Box *box )
+{
+#ifndef QT_NO_REGEXP_CAPTURE
+ int atom = startAtom( yyMayCapture && yyTok == Tok_LeftParen );
+#else
+ static const int atom = 0;
+#endif
+
+#ifndef QT_NO_REGEXP_INTERVAL
+#define YYREDO() \
+ yyIn = in, yyPos0 = pos0, yyPos = pos, yyLen = len, yyCh = ch, \
+ *yyCharClass = charClass, yyMinRep = 0, yyMaxRep = 0, yyTok = tok
+
+ const QChar *in = yyIn;
+ int pos0 = yyPos0;
+ int pos = yyPos;
+ int len = yyLen;
+ int ch = yyCh;
+ CharClass charClass;
+ if ( yyTok == Tok_CharClass )
+ charClass = *yyCharClass;
+ int tok = yyTok;
+ bool mayCapture = yyMayCapture;
+#endif
+
+ parseAtom( box );
+#ifndef QT_NO_REGEXP_CAPTURE
+ finishAtom( atom );
+#endif
+
+ if ( yyTok == Tok_Quantifier ) {
+ if ( yyMaxRep == InftyRep ) {
+ box->plus( atom );
+#ifndef QT_NO_REGEXP_INTERVAL
+ } else if ( yyMaxRep == 0 ) {
+ box->clear();
+#endif
+ }
+ if ( yyMinRep == 0 )
+ box->opt();
+
+#ifndef QT_NO_REGEXP_INTERVAL
+ yyMayCapture = FALSE;
+ int alpha = ( yyMinRep == 0 ) ? 0 : yyMinRep - 1;
+ int beta = ( yyMaxRep == InftyRep ) ? 0 : yyMaxRep - ( alpha + 1 );
+
+ Box rightBox( this );
+ int i;
+
+ for ( i = 0; i < beta; i++ ) {
+ YYREDO();
+ Box leftBox( this );
+ parseAtom( &leftBox );
+ leftBox.cat( rightBox );
+ leftBox.opt();
+ rightBox = leftBox;
+ }
+ for ( i = 0; i < alpha; i++ ) {
+ YYREDO();
+ Box leftBox( this );
+ parseAtom( &leftBox );
+ leftBox.cat( rightBox );
+ rightBox = leftBox;
+ }
+ rightBox.cat( *box );
+ *box = rightBox;
+#endif
+ yyTok = getToken();
+#ifndef QT_NO_REGEXP_INTERVAL
+ yyMayCapture = mayCapture;
+#endif
+ }
+#undef YYREDO
+}
+
+void QRegExpEngine::parseTerm( Box *box )
+{
+#ifndef QT_NO_REGEXP_OPTIM
+ if ( yyTok != Tok_Eos && yyTok != Tok_RightParen && yyTok != Tok_Bar )
+ parseFactor( box );
+#endif
+ while ( yyTok != Tok_Eos && yyTok != Tok_RightParen && yyTok != Tok_Bar ) {
+ Box rightBox( this );
+ parseFactor( &rightBox );
+ box->cat( rightBox );
+ }
+}
+
+void QRegExpEngine::parseExpression( Box *box )
+{
+ parseTerm( box );
+ while ( yyTok == Tok_Bar ) {
+ Box rightBox( this );
+ yyTok = getToken();
+ parseTerm( &rightBox );
+ box->orx( rightBox );
+ }
+}
+
+/*
+ The class QRegExpPrivate contains the private data of a regular expression
+ other than the automaton. It makes it possible for many QRegExp objects to
+ use the same QRegExpEngine object with different QRegExpPrivate objects.
+*/
+struct QRegExpPrivate
+{
+ QString pattern; // regular-expression or wildcard pattern
+ QString rxpattern; // regular-expression pattern
+#ifndef QT_NO_REGEXP_WILDCARD
+ bool wc; // wildcard mode?
+#endif
+ bool min; // minimal matching? (instead of maximal)
+#ifndef QT_NO_REGEXP_CAPTURE
+ QString t; // last string passed to QRegExp::search() or searchRev()
+ QStringList capturedCache; // what QRegExp::capturedTexts() returned last
+#endif
+ QArray<int> captured; // what QRegExpEngine::search() returned last
+
+ QRegExpPrivate() { captured.fill( -1, 2 ); }
+};
+
+#ifndef QT_NO_REGEXP_OPTIM
+static QCache<QRegExpEngine> *engineCache = 0;
+#endif
+
+static QRegExpEngine *newEngine( const QString& pattern, bool caseSensitive )
+{
+#ifndef QT_NO_REGEXP_OPTIM
+ if ( engineCache != 0 ) {
+ QRegExpEngine *eng = engineCache->take( pattern );
+ if ( eng == 0 || eng->caseSensitive() != caseSensitive ) {
+ delete eng;
+ } else {
+ eng->ref();
+ return eng;
+ }
+ }
+#endif
+ return new QRegExpEngine( pattern, caseSensitive );
+}
+
+static void derefEngine( QRegExpEngine *eng, const QString& pattern )
+{
+ if ( eng != 0 && eng->deref() ) {
+#ifndef QT_NO_REGEXP_OPTIM
+ if ( engineCache == 0 ) {
+ engineCache = new QCache<QRegExpEngine>;
+ engineCache->setAutoDelete( TRUE );
+ }
+ if ( !pattern.isNull() &&
+ engineCache->insert(pattern, eng, 4 + pattern.length() / 4) )
+ return;
+#else
+ Q_UNUSED( pattern );
+#endif
+ delete eng;
+ }
+}
+
+/*!
+ Constructs an empty regexp.
+
+ \sa isValid()
+*/
+QRegExp3::QRegExp3()
+{
+ eng = new QRegExpEngine( TRUE );
+ priv = new QRegExpPrivate;
+ priv->pattern = QString::null;
+#ifndef QT_NO_REGEXP_WILDCARD
+ priv->wc = FALSE;
+#endif
+ priv->min = FALSE;
+ compile( TRUE );
+}
+
+/*!
+ Constructs a regular expression object for the given \a pattern
+ string. The pattern must be given using wildcard notation if \a
+ wildcard is TRUE (default is FALSE). The pattern is case sensitive,
+ unless \a caseSensitive is FALSE. Matching is greedy (maximal), but
+ can be changed by calling setMinimal().
+
+ \sa setPattern() setCaseSensitive() setWildcard() setMinimal()
+*/
+QRegExp3::QRegExp3( const QString& pattern, bool caseSensitive, bool wildcard )
+{
+ eng = 0;
+ priv = new QRegExpPrivate;
+ priv->pattern = pattern;
+#ifndef QT_NO_REGEXP_WILDCARD
+ priv->wc = wildcard;
+#endif
+ priv->min = FALSE;
+ compile( caseSensitive );
+}
+
+/*!
+ Constructs a regular expression as a copy of \a rx.
+
+ \sa operator=()
+*/
+QRegExp3::QRegExp3( const QRegExp3& rx )
+{
+ eng = 0;
+ priv = new QRegExpPrivate;
+ operator=( rx );
+}
+
+/*!
+ Destroys the regular expression and cleans up its internal data.
+*/
+QRegExp3::~QRegExp3()
+{
+ derefEngine( eng, priv->rxpattern );
+ delete priv;
+}
+
+/*!
+ Copies the regular expression \a rx and returns a reference to the copy.
+ The case sensitivity, wildcard and minimal matching options are copied as
+ well.
+*/
+QRegExp3& QRegExp3::operator=( const QRegExp3& rx )
+{
+ rx.eng->ref();
+ derefEngine( eng, priv->rxpattern );
+ eng = rx.eng;
+ priv->pattern = rx.priv->pattern;
+ priv->rxpattern = rx.priv->rxpattern;
+#ifndef QT_NO_REGEXP_WILDCARD
+ priv->wc = rx.priv->wc;
+#endif
+ priv->min = rx.priv->min;
+#ifndef QT_NO_REGEXP_CAPTURE
+ priv->t = rx.priv->t;
+ priv->capturedCache = rx.priv->capturedCache;
+#endif
+ priv->captured = rx.priv->captured;
+ return *this;
+}
+
+/*!
+ Returns TRUE if this regular expression is equal to \a rx, otherwise
+ returns FALSE.
+
+ Two QRegExp3 objects are equal if they have the same pattern strings
+ and the same settings for case sensitivity, wildcard and minimal
+ matching.
+*/
+bool QRegExp3::operator==( const QRegExp3& rx ) const
+{
+ return priv->pattern == rx.priv->pattern &&
+ eng->caseSensitive() == rx.eng->caseSensitive() &&
+#ifndef QT_NO_REGEXP_WILDCARD
+ priv->wc == rx.priv->wc &&
+#endif
+ priv->min == rx.priv->min;
+}
+
+/*! \fn bool QRegExp3::operator!=( const QRegExp& rx ) const
+
+ Returns TRUE if this regular expression is not equal to \a rx, otherwise
+ FALSE.
+
+ \sa operator==()
+*/
+
+/*!
+ Returns TRUE if the pattern string is empty, otherwise FALSE.
+
+ If you call match() with an empty pattern on an empty string it will
+ return TRUE otherwise it returns FALSE since match() operates over the
+ whole string. If you call search() with an empty pattern on \e any
+ string it will return the start position (0 by default) since it will
+ match at the start position, because the empty pattern matches the
+ 'emptiness' at the start of the string, and the length of the match
+ returned by matchedLength() will be 0.
+
+ See QString::isEmpty().
+*/
+
+bool QRegExp3::isEmpty() const
+{
+ return priv->pattern.isEmpty();
+}
+
+/*!
+ Returns TRUE if the regular expression is valid, or FALSE if it's invalid. An
+ invalid regular expression never matches.
+
+ The pattern <b>[a-z</b> is an example of an invalid pattern, since it lacks
+ a closing square bracket.
+
+ Note that the validity of a regexp may also depend on the setting of
+ the wildcard flag, for example <b>*.html</b> is a valid wildcard
+ regexp but an invalid full regexp.
+*/
+bool QRegExp3::isValid() const
+{
+ return eng->isValid();
+}
+
+/*!
+ Returns the pattern string of the regular expression. The pattern has either
+ regular expression syntax or wildcard syntax, depending on wildcard().
+
+ \sa setPattern()
+*/
+QString QRegExp3::pattern() const
+{
+ return priv->pattern;
+}
+
+/*!
+ Sets the pattern string to \a pattern and returns a reference to this regular
+ expression. The case sensitivity, wildcard and minimal matching options are
+ not changed.
+
+ \sa pattern()
+*/
+void QRegExp3::setPattern( const QString& pattern )
+{
+ if ( priv->pattern != pattern ) {
+ priv->pattern = pattern;
+ compile( caseSensitive() );
+ }
+}
+
+/*!
+ Returns TRUE if case sensitivity is enabled, otherwise FALSE. The default is
+ TRUE.
+
+ \sa setCaseSensitive()
+*/
+bool QRegExp3::caseSensitive() const
+{
+ return eng->caseSensitive();
+}
+
+/*!
+ Sets case sensitive matching to \a sensitive.
+
+ If \a sensitive is TRUE, <b>\\</b><b>.txt$</b> matches
+ <tt>readme.txt</tt> but not <tt>README.TXT</tt>.
+
+ \sa caseSensitive()
+*/
+void QRegExp3::setCaseSensitive( bool sensitive )
+{
+ if ( sensitive != eng->caseSensitive() )
+ compile( sensitive );
+}
+
+#ifndef QT_NO_REGEXP_WILDCARD
+/*!
+ Returns TRUE if wildcard mode is enabled, otherwise FALSE. The default is
+ FALSE.
+
+ \sa setWildcard()
+*/
+bool QRegExp3::wildcard() const
+{
+ return priv->wc;
+}
+
+/*! Sets the wildcard mode for the regular expression. The default is FALSE.
+
+ Setting \a wildcard to TRUE enables simple shell-like wildcard
+ matching.
+ (See <a href="#wildcard-matching">wildcard matching (globbing)</a>.)
+
+ For example, <b>r*.txt</b> matches the string <tt>readme.txt</tt> in wildcard
+ mode, but does not match <tt>readme</tt>.
+
+ \sa wildcard()
+*/
+void QRegExp3::setWildcard( bool wildcard )
+{
+ if ( wildcard != priv->wc ) {
+ priv->wc = wildcard;
+ compile( caseSensitive() );
+ }
+}
+#endif
+
+/*! Returns TRUE if minimal (non-greedy) matching is enabled, otherwise
+ returns FALSE.
+
+ \sa setMinimal()
+*/
+bool QRegExp3::minimal() const
+{
+ return priv->min;
+}
+
+/*!
+ Enables or disables minimal matching. If \a minimal is FALSE, matching is
+ greedy (maximal) which is the default.
+
+ For example, suppose we have the input string "We must be \<b>bold\</b>,
+ very \<b>bold\</b>!" and the pattern <b>\<b>.*\</b></b>. With
+ the default greedy (maximal) matching, the match is
+ "We must be <u>\<b>bold\</b>, very \<b>bold\</b></u>!". But with
+ minimal (non-greedy) matching the first match is:
+ "We must be <u>\<b>bold\</b></u>, very \<b>bold\</b>!" and the
+ second match is
+ "We must be \<b>bold\</b>, very <u>\<b>bold\</b></u>!".
+ In practice we might use the pattern <b>\<b>[^\<]+\</b></b>,
+ although this will still fail for nested tags.
+
+ \sa minimal()
+*/
+void QRegExp3::setMinimal( bool minimal )
+{
+ priv->min = minimal;
+}
+
+/*!
+ Returns TRUE if \a str is matched exactly by this regular expression
+ otherwise it returns FALSE. You can determine how much of the string was
+ matched by calling matchedLength().
+
+ For a given regexp string, R, <tt>match("R")</tt> is the equivalent
+ of <tt>search("^R$")</tt> since match() effectively encloses the
+ regexp in the start of string and end of string anchors.
+
+ For example, if the regular expression is <b>blue</b>, then match()
+ returns TRUE only for input <tt>blue</tt>. For inputs
+ <tt>bluebell</tt>, <tt>blutak</tt> and <tt>lightblue</tt>, match()
+ returns FALSE and matchedLength() will return 4, 3 and 0 respectively.
+
+ \sa search() searchRev() QRegExpValidator
+*/
+bool QRegExp3::exactMatch( const QString& str )
+{
+#ifndef QT_NO_REGEXP_CAPTURE
+ priv->t = str;
+ priv->capturedCache.clear();
+#endif
+
+ priv->captured = eng->match( str, 0, priv->min, TRUE );
+ if ( priv->captured[1] == (int) str.length() ) {
+ return TRUE;
+ } else {
+ priv->captured.detach();
+ priv->captured[0] = 0;
+ priv->captured[1] = eng->matchedLength();
+ return FALSE;
+ }
+}
+
+/*! \overload
+
+ This version does not set matchedLength(), capturedTexts() and friends.
+*/
+bool QRegExp3::exactMatch( const QString& str ) const
+{
+ return eng->match(str, 0, priv->min, TRUE)[0] == 0 &&
+ eng->matchedLength() == (int) str.length();
+}
+
+/*! \obsolete
+
+ Attempts to match in \a str, starting from position \a index. Returns the
+ position of the match, or -1 if there was no match.
+
+ The length of the match is stored in \a *len, unless \a len is a null pointer.
+
+ If \a indexIsStart is TRUE (the default), the position \a index in the string
+ will match the start of string anchor, <b>^</b>, in the regexp, if present.
+ Otherwise, position 0 in \a str will match.
+
+ Use search() and matchedLength() instead of this function.
+
+ If you really need the \a indexIsStart functionality, try this:
+
+ \code
+ QRegExp3 rx( "some pattern" );
+ int pos = rx.search( str.mid( index ) );
+ if ( pos != -1 )
+ pos += index;
+ int len = rx.matchedLength();
+ \endcode
+*/
+#ifndef QT_NO_COMPAT
+int QRegExp3::match( const QString& str, int index, int *len,
+ bool indexIsStart )
+{
+ int pos;
+ if ( indexIsStart ) {
+ pos = search( str.mid(index) );
+ if ( pos >= 0 ) {
+ pos += index;
+ if ( len != 0 )
+ *len = matchedLength();
+ } else {
+ if ( len != 0 )
+ *len = 0;
+ }
+ } else {
+ pos = search( str, index );
+ if ( len != 0 )
+ *len = matchedLength();
+ }
+ return pos;
+}
+#endif
+
+/*!
+ Attempts to find a match in \a str from position \a start (0 by default). If
+ \a start is -1, the search starts at the last character; if -2, at the next to
+ last character; etc.
+
+ Returns the position of the first match, or -1 if there was no match.
+
+ You might prefer to use QString::find(), QString::contains() or even
+ QStringList::grep(). To replace matches use QString::replace().
+
+ Example:
+ \code
+ QString str = "offsets: 1.23 .50 71.00 6.00";
+ QRegExp3 rx( "\\d*\\.\\d+" ); // very simple floating point matching
+ int count = 0;
+ int pos = 0;
+ while ( pos >= 0 ) {
+ pos = rx.search( str, pos );
+ count++;
+ }
+ // pos will be 9, 14, 18 and finally 24; count will end up as 4.
+ \endcode
+
+ \sa searchRev() match() matchedLength() capturedTexts()
+*/
+// QChar versions
+
+#ifdef QCHAR_SUPPORT
+const QString makeString(const QChar *str)
+{
+// A sentinel value checked in case the QChar *ptr is never null terminated
+ const uint MAXLENGTH=65535;
+
+ const QChar *s=str;
+ uint i=0;
+ while(i < MAXLENGTH && *s != QChar::null) { i++;s++ ;}
+ return QString(str,i);
+
+}
+int QRegExp3::search(const QChar *str,int start)
+{
+ return search(makeString(str),start);
+}
+int QRegExp3::search(const QChar *str,int start) const
+{
+ return search(makeString(str),start);
+}
+int QRegExp3::searchRev(const QChar *str,int start)
+{
+ return searchRev(makeString(str),start);
+}
+int QRegExp3::searchRev(const QChar *str,int start) const
+{
+ return searchRev(makeString(str),start);
+}
+bool QRegExp3::exactMatch(const QChar *str)
+{
+ return exactMatch(makeString(str));
+}
+bool QRegExp3::exactMatch(const QChar *str) const
+{
+ return exactMatch(makeString(str));
+}
+#endif // QCHAR_SUPPORT
+
+int QRegExp3::search( const QString& str, int start )
+{
+ if ( start < 0 )
+ start += str.length();
+#ifndef QT_NO_REGEXP_CAPTURE
+ priv->t = str;
+ priv->capturedCache.clear();
+#endif
+ priv->captured = eng->match( str, start, priv->min, FALSE );
+ return priv->captured[0];
+}
+
+/*! \overload
+
+ This version does not set matchedLength(), capturedTexts() and friends.
+*/
+int QRegExp3::search( const QString& str, int start ) const
+{
+ if ( start < 0 )
+ start += str.length();
+ return eng->match( str, start, priv->min, FALSE )[0];
+}
+
+/*!
+ Attempts to find a match backwards in \a str from position \a start. If
+ \a start is -1 (the default), the search starts at the last character; if -2,
+ at the next to last character; etc.
+
+ Returns the position of the first match, or -1 if there was no match.
+
+ You might prefer to use QString::findRev().
+
+ \sa search() matchedLength() capturedTexts()
+*/
+int QRegExp3::searchRev( const QString& str, int start )
+{
+ if ( start < 0 )
+ start += str.length();
+#ifndef QT_NO_REGEXP_CAPTURE
+ priv->t = str;
+ priv->capturedCache.clear();
+#endif
+ if ( start < 0 || start > (int) str.length() ) {
+ priv->captured.detach();
+ priv->captured.fill( -1 );
+ return -1;
+ }
+
+ while ( start >= 0 ) {
+ priv->captured = eng->match( str, start, priv->min, TRUE );
+ if ( priv->captured[0] == start )
+ return start;
+ start--;
+ }
+ return -1;
+}
+
+/*! \overload
+
+ This version does not set matchedLength(), capturedText() and friends.
+*/
+int QRegExp3::searchRev( const QString& str, int start ) const
+{
+ if ( start < 0 )
+ start += str.length();
+ if ( start < 0 || start > (int) str.length() )
+ return -1;
+
+ while ( start >= 0 ) {
+ if ( eng->match(str, start, priv->min, TRUE)[0] == start )
+ return start;
+ start--;
+ }
+ return -1;
+}
+
+/*!
+ Returns the length of the last matched string, or -1 if there was no match.
+
+ \sa match() search()
+*/
+int QRegExp3::matchedLength()
+{
+ return priv->captured[1];
+}
+
+#ifndef QT_NO_REGEXP_CAPTURE
+/*!
+ Returns a list of the captured text strings.
+
+ The first string in the list is the entire matched string. Each
+ subsequent list element contains a string that matched a
+ (capturing) subexpression of the regexp.
+
+ For example:
+ \code
+ QRegExp3 rx( "(\\d+)(\\s*)(cm|inch(es)?)" );
+ int pos = rx.search( "Length: 36 inches" );
+ QStringList list = rx.capturedTexts();
+ // list is now ( "36 inches", "36", " ", "inches", "es" ).
+ \endcode
+
+ The above example also captures elements
+ that may be present but which we have no interest in. This problem
+ can be solved by using non-capturing parenthesis:
+
+ \code
+ QRegExp3 rx( "(\\d+)(?:\\s*)(cm|inch(?:es)?)" );
+ int pos = rx.search( "Length: 36 inches" );
+ QStringList list = rx.capturedTexts();
+ // list is now ( "36 inches", "36", "inches" ).
+ \endcode
+
+ Some regexps can match an indeterminate number of times. For example
+ if the input string is "Offsets: 12 14 99 231 7" and the regexp,
+ <tt>rx</tt>, is <b>(</b><b>\\</b><b>d+)+</b>, we would hope to get a
+ list of all the numbers matched. However, after calling
+ <tt>rx.search(str)</tt>, capturedTexts() will return the list ( "12",
+ "12" ), i.e. the entire match was "12" and the first subexpression
+ matched was "12". The correct approach is to use cap() in a
+ <a href="#cap_in_a_loop">loop</a>.
+
+ The order of elements in the string list is as follows. The first
+ element is the entire matching string. Each subsequent element
+ corresponds to the next capturing open left parenthesis. Thus
+ capturedTexts()[1] is the text of the first capturing parenthesis,
+ capturedTexts()[2] is the text of the second and so on (corresponding
+ to $1, $2 etc. in some other regexp languages).
+
+ \sa cap() pos()
+*/
+QStringList QRegExp3::capturedTexts()
+{
+ if ( priv->capturedCache.isEmpty() ) {
+ for ( int i = 0; i < (int) priv->captured.size(); i += 2 ) {
+ QString m;
+ if ( priv->captured[i + 1] == 0 )
+ m = QString::fromLatin1( "" );
+ else if ( priv->captured[i] >= 0 )
+ m = priv->t.mid( priv->captured[i],
+ priv->captured[i + 1] );
+ priv->capturedCache.append( m );
+ }
+ priv->t = QString::null;
+ }
+ return priv->capturedCache;
+}
+
+/*! Returns the text captured by the \a nth subexpression. The entire match
+ has index 0 and the parenthesised subexpressions have indices starting
+ from 1 (excluding non-capturing parenthesis).
+
+ \code
+ QRegExp3 rxlen( "(\\d+)(?:\\s*)(cm|inch)" );
+ int pos = rxlen.search( "Length: 189cm" );
+ if ( pos > -1 ) {
+ QString value = rxlen.cap( 1 ); // "189"
+ QString unit = rxlen.cap( 2 ); // "cm"
+ // ...
+ }
+ \endcode
+
+ <a name="cap_in_a_loop">
+ Some patterns may lead to a number of matches which cannot be
+ determined in advance, for example:</a>
+
+ \code
+ QRegExp3 rx( "(\\d+)" );
+ str = "Offsets: 12 14 99 231 7";
+ QStringList list;
+ pos = 0;
+ while ( pos >= 0 ) {
+ pos = rx.search( str, pos );
+ if ( pos > -1 ) {
+ list += rx.cap( 1 );
+ pos += rx.matchedLength();
+ }
+ }
+ // list contains: ( "12", "14", "99", "231", "7" ).
+ \endcode
+
+ The order of elements matched by cap() is as follows. The first
+ element, cap( 0 ), is the entire matching string. Each subsequent
+ element corresponds to the next capturing open left parenthesis. Thus
+ cap( 1 ) is the text of the first capturing parenthesis, cap( 2 ) is
+ the text of the second and so on.
+
+ \sa search() pos() capturedTexts()
+*/
+QString QRegExp3::cap( int nth )
+{
+ if ( nth < 0 || nth >= (int) priv->captured.size() / 2 )
+ return QString::null;
+ else
+ return capturedTexts()[nth];
+}
+
+/*! Returns the position of the \a nth captured text in the
+ searched string. If \a nth is 0 (the default), pos() returns the
+ position of the whole match.
+
+ Example:
+ \code
+ QRegExp3 rx( "/([a-z]+)/([a-z]+)" );
+ rx.search( "Output /dev/null" ); // Returns 7 (position of /dev/null)
+ rx.pos( 0 ); // Returns 7 (position of /dev/null)
+ rx.pos( 1 ); // Returns 8 (position of dev)
+ rx.pos( 2 ); // Returns 12 (position of null)
+ \endcode
+
+ Note that pos() returns -1 for zero-length matches. (For example, if
+ cap(4) would return an empty string, pos(4) returns -1.) This is due
+ to an implementation tradeoff.
+
+ \sa capturedTexts() cap()
+*/
+int QRegExp3::pos( int nth )
+{
+ if ( nth < 0 || nth >= (int) priv->captured.size() / 2 )
+ return -1;
+ else
+ return priv->captured[2 * nth];
+}
+#endif
+
+void QRegExp3::compile( bool caseSensitive )
+{
+ derefEngine( eng, priv->rxpattern );
+#ifndef QT_NO_REGEXP_WILDCARD
+ if ( priv->wc )
+ priv->rxpattern = wc2rx( priv->pattern );
+ else
+#endif
+ priv->rxpattern = priv->pattern.isNull() ? QString::fromLatin1( "" )
+ : priv->pattern;
+ eng = newEngine( priv->rxpattern, caseSensitive );
+#ifndef QT_NO_REGEXP_CAPTURE
+ priv->t = QString::null;
+ priv->capturedCache.clear();
+#endif
+ priv->captured.detach();
+ priv->captured.fill( -1, 2 + 2 * eng->numCaptures() );
+}
diff --git a/noncore/apps/tinykate/libkate/qt3back/qregexp3.h b/noncore/apps/tinykate/libkate/qt3back/qregexp3.h
new file mode 100644
index 0000000..5b75131
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/qt3back/qregexp3.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+** $Id$
+**
+** Definition of QRegExp class
+**
+** Created : 950126
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QREGEXP3_H
+#define QREGEXP3_H
+#ifndef QT_H
+#include "qstringlist.h"
+#endif // QT_H
+
+
+#if QT_VERSION >=300
+#include <qregexp.h>
+#else
+class QRegExpEngine;
+struct QRegExpPrivate;
+
+class Q_EXPORT QRegExp3
+{
+public:
+ QRegExp3();
+ QRegExp3( const QString& pattern, bool caseSensitive = TRUE,
+ bool wildcard = FALSE );
+ QRegExp3( const QRegExp3& rx );
+ ~QRegExp3();
+ QRegExp3& operator=( const QRegExp3& rx );
+
+ bool operator==( const QRegExp3& rx ) const;
+ bool operator!=( const QRegExp3& rx ) const { return !operator==( rx ); }
+
+ bool isEmpty() const;
+ bool isValid() const;
+ QString pattern() const;
+ void setPattern( const QString& pattern );
+ bool caseSensitive() const;
+ void setCaseSensitive( bool sensitive );
+#ifndef QT_NO_REGEXP_WILDCARD
+ bool wildcard() const;
+ void setWildcard( bool wildcard );
+#endif
+ bool minimal() const;
+ void setMinimal( bool minimal );
+
+ bool exactMatch( const QString& str );
+ bool exactMatch( const QString& str ) const;
+#ifndef QT_NO_COMPAT
+ int match( const QString& str, int index, int *len = 0,
+ bool indexIsStart = TRUE );
+#endif
+ int search( const QString& str, int start = 0 );
+ int search( const QString& str, int start = 0 ) const;
+// QChar versions
+#ifdef QCHAR_SUPPORT
+ int search(const QChar *str,int start=0);
+ int search(const QChar *str,int start=0) const;
+ int searchRev(const QChar *str,int start=-1);
+ int searchRev(const QChar *str,int start=-1) const ;
+ bool exactMatch(const QChar *str);
+ bool exactMatch(const QChar *str) const;
+// end QChar versions
+#endif
+ int searchRev( const QString& str, int start = -1 );
+ int searchRev( const QString& str, int start = -1 ) const;
+ int matchedLength();
+#ifndef QT_NO_REGEXP_CAPTURE
+ QStringList capturedTexts();
+ QString cap( int nth = 0 );
+ int pos( int nth = 0 );
+#endif
+
+private:
+ void compile( bool caseSensitive );
+
+ QRegExpEngine *eng;
+ QRegExpPrivate *priv;
+};
+#endif // QT_VERSION >= 300
+#endif // QREGEXP_H
diff --git a/noncore/apps/tinykate/libkate/view/kateundohistory.cpp b/noncore/apps/tinykate/libkate/view/kateundohistory.cpp
new file mode 100644
index 0000000..b7b9b56
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/view/kateundohistory.cpp
@@ -0,0 +1,271 @@
+/*
+ Copyright (C) 1999 Glen Parker <glenebob@nwlink.com>
+ Copyright (C) 2002 Joseph Wenninger <jowenn@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ --------------------------------------------------------------------
+
+ This implements a dialog used to display and control undo/redo history.
+ It uses a specialized QListBox subclass to provide a selection mechanism
+ that must:
+ 1) always have the first item selected, and
+ 2) maintain a contiguous multiple selection
+*/
+
+#include <stdio.h>
+
+#include <qwidget.h>
+#include <qdialog.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qlistbox.h>
+#include <qpushbutton.h>
+
+#include <klocale.h>
+
+#include "kateview.h"
+
+#include "kateundohistory.h"
+
+/////////////////////////////////////////////////////////////////////
+// UndoHistory implementation
+//
+UndoHistory::UndoHistory(KateView *kWrite, QWidget *parent, const char *name, bool modal, WFlags f)
+ : QDialog(parent, name, modal, f)
+{
+ this->kWrite = kWrite;
+
+ QPushButton *btn;
+ QLabel *lbl;
+ QHBoxLayout *hLayout;
+ QVBoxLayout *vLayout;
+
+ hLayout = new QHBoxLayout(this, 5, 4);
+
+ vLayout = new QVBoxLayout(hLayout);
+ lbl = new QLabel(i18n("Undo List"), this);
+ lbUndo = new UndoListBox(this);
+ vLayout->addWidget(lbl);
+ vLayout->addWidget(lbUndo);
+
+ vLayout = new QVBoxLayout(hLayout);
+ lbl = new QLabel(i18n("Redo List"), this);
+ lbRedo = new UndoListBox(this);
+ vLayout->addWidget(lbl);
+ vLayout->addWidget(lbRedo);
+
+ lbUndo->setMinimumSize(QSize(150,140));
+ lbRedo->setMinimumSize(QSize(150,140));
+
+ connect(lbUndo, SIGNAL(sigSelected(int)), this, SLOT(slotUndoSelChanged(int)));
+ connect(lbRedo, SIGNAL(sigSelected(int)), this, SLOT(slotRedoSelChanged(int)));
+
+ vLayout = new QVBoxLayout(hLayout);
+
+ btnUndo = new QPushButton(this);
+ btnUndo->setText(i18n("&Undo"));
+ btnUndo->setEnabled(false);
+ btnUndo->setFixedSize(btnUndo->sizeHint());
+ connect(btnUndo, SIGNAL(clicked()), this, SLOT(slotUndo()));
+
+ vLayout->addWidget(btnUndo, 0);
+
+ btnRedo = new QPushButton(this);
+ btnRedo->setText(i18n("&Redo"));
+ btnRedo->setEnabled(false);
+ btnRedo->setFixedSize(btnRedo->sizeHint());
+ connect(btnRedo, SIGNAL(clicked()), this, SLOT(slotRedo()));
+
+ vLayout->addWidget(btnRedo, 0);
+
+ btn = new QPushButton(this);
+ btn->setText(i18n("&Close"));
+ btn->setFixedSize(btn->sizeHint());
+ connect(btn, SIGNAL(clicked()), this, SLOT(close()));
+
+ vLayout->addWidget(btn, 0, AlignBottom);
+
+ newUndo();
+}
+
+UndoHistory::~UndoHistory()
+{}
+
+void UndoHistory::newUndo()
+{
+ QValueList<int> undoList;
+ QValueList<int>::Iterator it;
+
+ // we don't want a signal storm...
+ disconnect(lbUndo, SIGNAL(sigSelected(int)), this, SLOT(slotUndoSelChanged(int)));
+ disconnect(lbRedo, SIGNAL(sigSelected(int)), this, SLOT(slotRedoSelChanged(int)));
+
+ kWrite->undoTypeList(undoList);
+
+ lbUndo->clear();
+
+ for (it = undoList.begin() ; it != undoList.end() ; it++) {
+ lbUndo->insertItem(i18n(kWrite->undoTypeName(*it)));
+ }
+
+ kWrite->redoTypeList(undoList);
+
+ lbRedo->clear();
+ for (it = undoList.begin() ; it != undoList.end() ; it++) {
+ lbRedo->insertItem(i18n(kWrite->undoTypeName(*it)));
+ }
+
+ connect(lbUndo, SIGNAL(sigSelected(int)), this, SLOT(slotUndoSelChanged(int)));
+ connect(lbRedo, SIGNAL(sigSelected(int)), this, SLOT(slotRedoSelChanged(int)));
+
+ slotUndoSelChanged(lbUndo->selCount());
+ slotRedoSelChanged(lbRedo->selCount());
+}
+
+void UndoHistory::slotUndo()
+{
+ int selCount = lbUndo->selCount();
+ emit undo(selCount);
+ lbRedo->setSelCount(selCount);
+}
+void UndoHistory::slotRedo()
+{
+ int selCount = lbRedo->selCount();
+ emit redo(selCount);
+ lbUndo->setSelCount(selCount);
+}
+
+void UndoHistory::slotUndoSelChanged(int cnt)
+{
+ btnUndo->setEnabled(cnt > 0);
+}
+
+void UndoHistory::slotRedoSelChanged(int cnt)
+{
+ btnRedo->setEnabled(cnt > 0);
+}
+
+/////////////////////////////////////////////////////////////////////
+// UndoListBox implementation
+//
+UndoListBox::UndoListBox(QWidget *parent, const char *name, WFlags f)
+ : QListBox(parent, name, f)
+{
+ _selCount = 0;
+ setSelectionMode(Extended);
+ connect(this, SIGNAL(highlighted(int)), this, SLOT(_slotSelectionChanged()));
+ connect(this, SIGNAL(selectionChanged()), this, SLOT(_slotSelectionChanged()));
+}
+
+UndoListBox::~UndoListBox()
+{}
+
+void UndoListBox::insertItem (const QString &text, int index)
+{
+ bool sig = false;
+
+ if (count() == 0)
+ sig = true;
+ else if (index > -1)
+ sig = (isSelected(index));
+
+ QListBox::insertItem(text, index);
+
+ if (sig)
+ _slotSelectionChanged();
+}
+
+void UndoListBox::removeItem (int index)
+{
+ bool sig;
+
+ if (count() == 1)
+ sig = true;
+ else if (index == -1)
+ sig = (isSelected(count() - 1));
+ else
+ sig = (isSelected(index));
+
+ QListBox::removeItem(index);
+
+ if (sig)
+ _slotSelectionChanged();
+}
+
+void UndoListBox::clear()
+{
+ bool sig = (count() > 0);
+
+ QListBox::clear();
+
+ if (sig)
+ _slotSelectionChanged();
+}
+
+int UndoListBox::selCount()
+{
+ return _selCount;
+}
+
+void UndoListBox::setSelCount(int count)
+{
+ if (count == _selCount)
+ return;
+
+ if (count < 1 || count > (int)this->count())
+ return;
+
+ setCurrentItem(count - 1);
+}
+
+// make sure the first item is selected, and that there are no holes
+void UndoListBox::_slotSelectionChanged()
+{
+ int count = this->count();
+
+ if (! count) {
+ if (_selCount != 0) {
+ _selCount = 0;
+ emit sigSelected(_selCount);
+ }
+ return;
+ }
+
+ if (currentItem() < 0)
+ setCurrentItem(0);
+
+ int i;
+ int currItem = currentItem();
+ int max = (currItem+1 > _selCount ? currItem+1 : _selCount);
+
+ for (i = 0 ; i < max ; i++) {
+ if (i > currItem) {
+ if (isSelected(i)) {
+ setSelected(i, false);
+ }
+ } else {
+ if (! isSelected(i)) {
+ setSelected(i, true);
+ }
+ }
+ }
+
+ if (_selCount != currItem + 1) {
+ _selCount = currItem + 1;
+ emit sigSelected(_selCount);
+ }
+}
diff --git a/noncore/apps/tinykate/libkate/view/kateundohistory.h b/noncore/apps/tinykate/libkate/view/kateundohistory.h
new file mode 100644
index 0000000..eb91af9
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/view/kateundohistory.h
@@ -0,0 +1,114 @@
+/*
+ Copyright (C) 1999 Glen Parker <glenebob@nwlink.com>
+ Copyright (C) 2002 Joseph Wenninger <jowenn@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 as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ --------------------------------------------------------------------
+
+ This implements a dialog used to display and control undo/redo history.
+ It uses a specialized QListBox subclass to provide a selection mechanism
+ that will:
+ 1) always have the first item selected, and
+ 2) maintain a contiguous multiple selection
+*/
+
+#ifndef __undohistory_h_
+#define __undohistory_h_
+
+#include <qdialog.h>
+#include <qlistbox.h>
+
+#include "kateview.h"
+
+class UndoListBox;
+
+// the dialog class that provides the interface to the user
+class UndoHistory : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ /**
+ Constructed just like a regular QDialog
+ */
+ UndoHistory(KateView*, QWidget *parent=0, const char *name=0, bool modal=FALSE, WFlags f=0);
+ virtual ~UndoHistory();
+
+ public slots:
+ /**
+ This should be called whenever a change occurs in the undo/redo list.
+ Causes the dialog to update its interface.
+ */
+ void newUndo();
+
+ signals:
+ /**
+ Emitted when the user hits the Undo button. Specifies the number of
+ operations to undo.
+ */
+ void undo(int);
+ /**
+ Emitted when the user hits the Redo button. Specifies the number of
+ undone operations to redo.
+ */
+ void redo(int);
+
+ protected:
+ KateView *kWrite;
+
+ UndoListBox *lbUndo,
+ *lbRedo;
+ QPushButton *btnUndo,
+ *btnRedo;
+
+ protected slots:
+ void slotUndo();
+ void slotRedo();
+ void slotUndoSelChanged(int);
+ void slotRedoSelChanged(int);
+
+};
+
+// listbox class used to provide contiguous, 0-based selection
+// this is used internally
+class UndoListBox : public QListBox
+{
+ Q_OBJECT
+
+ public:
+ UndoListBox(QWidget * parent=0, const char * name=0, WFlags f=0);
+ virtual ~UndoListBox();
+
+ int selCount();
+ void setSelCount(int count);
+
+ void insertItem (const QString &text, int index = -1);
+ void removeItem (int index);
+ void clear();
+
+ protected:
+ int _selCount;
+
+ signals:
+ void sigSelected(int);
+
+ protected slots:
+ void _slotSelectionChanged();
+
+};
+
+#endif
diff --git a/noncore/apps/tinykate/libkate/view/kateview.cpp b/noncore/apps/tinykate/libkate/view/kateview.cpp
new file mode 100644
index 0000000..8f3a25e
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/view/kateview.cpp
@@ -0,0 +1,2923 @@
+/***************************************************************************
+ kateview.cpp - description
+ -------------------
+ begin : Mon Jan 15 2001
+ copyright : (C) 2001 by Christoph "Crossfire" Cullmann
+ (C) 2002 by Joseph Wenninger
+ email : crossfire@babylon2k.de
+ jowenn@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+/*
+ Copyright (C) 1998, 1999 Jochen Wilhelmy
+ digisnap@cs.tu-berlin.de
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+
+
+#include "kateview.h"
+
+#include "../document/katedocument.h"
+#include "../document/katecmd.h"
+#include "../document/katehighlight.h"
+#include "kateviewdialog.h"
+#include "../document/katedialogs.h"
+
+#include <qfocusdata.h>
+#include <kdebug.h>
+#include <kapplication.h>
+#include <qscrollbar.h>
+#include <qiodevice.h>
+#include <qpopupmenu.h>
+#include <kpopupmenu.h>
+#include <qkeycode.h>
+#include <qintdict.h>
+#include <kconfig.h>
+#include <qfont.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qfileinfo.h>
+#include <qfile.h>
+#include <qevent.h>
+#include <qdir.h>
+#include <qvbox.h>
+#include <qprintdialog.h>
+#include <qpaintdevicemetrics.h>
+#include <qiodevice.h>
+#include <qbuffer.h>
+#include <qfocusdata.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <qregexp.h>
+#include <kdialogbase.h>
+#include <klineeditdlg.h>
+#include <qapplication.h>
+#include <kfiledialog.h>
+#include <kiconloader.h>
+#include "../document/katetextline.h"
+#include "kateviewdialog.h"
+#include "kateundohistory.h"
+#include <qlayout.h>
+
+KateViewInternal::KateViewInternal(KateView *view, KateDocument *doc) : QWidget(view)
+{
+ waitForPreHighlight=-1;
+ myView = view;
+ myDoc = doc;
+
+ iconBorderWidth = 16;
+ iconBorderHeight = 800;
+
+ QWidget::setCursor(ibeamCursor);
+ setBackgroundMode(NoBackground);
+
+ setFocusPolicy(StrongFocus);
+
+ xScroll = new QScrollBar(QScrollBar::Horizontal,myView);
+ yScroll = new QScrollBar(QScrollBar::Vertical,myView);
+ connect(xScroll,SIGNAL(valueChanged(int)),SLOT(changeXPos(int)));
+ connect(yScroll,SIGNAL(valueChanged(int)),SLOT(changeYPos(int)));
+ connect(yScroll,SIGNAL(valueChanged(int)),myView,SIGNAL(scrollValueChanged(int)));
+ connect( doc, SIGNAL (preHighlightChanged(long)),this,SLOT(slotPreHighlightUpdate(long)));
+
+ xPos = 0;
+ yPos = 0;
+
+ scrollTimer = 0;
+
+ cursor.x = 0;
+ cursor.y = 0;
+ cursorOn = false;
+ cursorTimer = 0;
+ cXPos = 0;
+ cOldXPos = 0;
+
+ startLine = 0;
+ endLine = -1;
+
+ exposeCursor = false;
+ updateState = 0;
+ numLines = 0;
+ lineRanges = 0L;
+ newXPos = -1;
+ newYPos = -1;
+
+ drawBuffer = new QPixmap ();
+ drawBuffer->setOptimization (QPixmap::BestOptim);
+
+ bm.sXPos = 0;
+ bm.eXPos = -1;
+
+}
+
+
+KateViewInternal::~KateViewInternal()
+{
+ delete [] lineRanges;
+ delete drawBuffer;
+}
+
+
+void KateViewInternal::slotPreHighlightUpdate(long line)
+{
+ //kdDebug()<<QString("slotPreHighlightUpdate - Wait for: %1, line: %2").arg(waitForPreHighlight).arg(line)<<endl;
+ if (waitForPreHighlight!=-1)
+ {
+ if (line>=waitForPreHighlight)
+ {
+ waitForPreHighlight=-1;
+ repaint();
+ }
+ }
+}
+
+void KateViewInternal::doCursorCommand(VConfig &c, int cmdNum) {
+
+ switch (cmdNum) {
+ case KateView::cmLeft:
+ cursorLeft(c);
+ break;
+ case KateView::cmRight:
+ cursorRight(c);
+ break;
+ case KateView::cmWordLeft:
+ wordLeft(c);
+ break;
+ case KateView::cmWordRight:
+ wordRight(c);
+ break;
+ case KateView::cmHome:
+ home(c);
+ break;
+ case KateView::cmEnd:
+ end(c);
+ break;
+ case KateView::cmUp:
+ cursorUp(c);
+ break;
+ case KateView::cmDown:
+ cursorDown(c);
+ break;
+ case KateView::cmScrollUp:
+ scrollUp(c);
+ break;
+ case KateView::cmScrollDown:
+ scrollDown(c);
+ break;
+ case KateView::cmTopOfView:
+ topOfView(c);
+ break;
+ case KateView::cmBottomOfView:
+ bottomOfView(c);
+ break;
+ case KateView::cmPageUp:
+ pageUp(c);
+ break;
+ case KateView::cmPageDown:
+ pageDown(c);
+ break;
+ case KateView::cmTop:
+ top_home(c);
+ break;
+ case KateView::cmBottom:
+ bottom_end(c);
+ break;
+ }
+}
+
+void KateViewInternal::doEditCommand(VConfig &c, int cmdNum) {
+
+ switch (cmdNum) {
+ case KateView::cmCopy:
+ myDoc->copy(c.flags);
+ return;
+ case KateView::cmSelectAll:
+ myDoc->selectAll();
+ return;
+ case KateView::cmDeselectAll:
+ myDoc->deselectAll();
+ return;
+ case KateView::cmInvertSelection:
+ myDoc->invertSelection();
+ return;
+ }
+ if (myView->isReadOnly()) return;
+ switch (cmdNum) {
+ case KateView::cmReturn:
+ if (c.flags & KateView::cfDelOnInput) myDoc->delMarkedText(c);
+ myDoc->newLine(c);
+ //emit returnPressed();
+ //e->ignore();
+ return;
+ case KateView::cmDelete:
+ if ((c.flags & KateView::cfDelOnInput) && myDoc->hasMarkedText())
+ myDoc->delMarkedText(c);
+ else myDoc->del(c);
+ return;
+ case KateView::cmBackspace:
+ if ((c.flags & KateView::cfDelOnInput) && myDoc->hasMarkedText())
+ myDoc->delMarkedText(c);
+ else myDoc->backspace(c);
+ return;
+ case KateView::cmKillLine:
+ myDoc->killLine(c);
+ return;
+ case KateView::cmCut:
+ myDoc->cut(c);
+ return;
+ case KateView::cmPaste:
+ if (c.flags & KateView::cfDelOnInput) myDoc->delMarkedText(c);
+ myDoc->paste(c);
+ return;
+ case KateView::cmUndo:
+ myDoc->undo(c);
+ return;
+ case KateView::cmRedo:
+ myDoc->redo(c);
+ return;
+ case KateView::cmIndent:
+ myDoc->indent(c);
+ return;
+ case KateView::cmUnindent:
+ myDoc->unIndent(c);
+ return;
+ case KateView::cmCleanIndent:
+ myDoc->cleanIndent(c);
+ return;
+ case KateView::cmComment:
+ myDoc->comment(c);
+ return;
+ case KateView::cmUncomment:
+ myDoc->unComment(c);
+ return;
+ }
+}
+
+void KateViewInternal::cursorLeft(VConfig &c) {
+
+ cursor.x--;
+ if (c.flags & KateView::cfWrapCursor && cursor.x < 0 && cursor.y > 0) {
+ cursor.y--;
+ cursor.x = myDoc->textLength(cursor.y);
+ }
+ cOldXPos = cXPos = myDoc->textWidth(cursor);
+ changeState(c);
+}
+
+void KateViewInternal::cursorRight(VConfig &c) {
+
+ if (c.flags & KateView::cfWrapCursor) {
+ if (cursor.x >= myDoc->textLength(cursor.y)) {
+ if (cursor.y == myDoc->lastLine()) return;
+ cursor.y++;
+ cursor.x = -1;
+ }
+ }
+ cursor.x++;
+ cOldXPos = cXPos = myDoc->textWidth(cursor);
+ changeState(c);
+}
+
+void KateViewInternal::wordLeft(VConfig &c) {
+ Highlight *highlight;
+
+ highlight = myDoc->highlight();
+ TextLine::Ptr textLine = myDoc->getTextLine(cursor.y);
+
+ if (cursor.x > 0) {
+ do {
+ cursor.x--;
+ } while (cursor.x > 0 && !highlight->isInWord(textLine->getChar(cursor.x)));
+ while (cursor.x > 0 && highlight->isInWord(textLine->getChar(cursor.x -1)))
+ cursor.x--;
+ } else {
+ if (cursor.y > 0) {
+ cursor.y--;
+ textLine = myDoc->getTextLine(cursor.y);
+ cursor.x = textLine->length();
+ }
+ }
+
+ cOldXPos = cXPos = myDoc->textWidth(cursor);
+ changeState(c);
+}
+
+void KateViewInternal::wordRight(VConfig &c) {
+ Highlight *highlight;
+ int len;
+
+ highlight = myDoc->highlight();
+ TextLine::Ptr textLine = myDoc->getTextLine(cursor.y);
+ len = textLine->length();
+
+ if (cursor.x < len) {
+ do {
+ cursor.x++;
+ } while (cursor.x < len && highlight->isInWord(textLine->getChar(cursor.x)));
+ while (cursor.x < len && !highlight->isInWord(textLine->getChar(cursor.x)))
+ cursor.x++;
+ } else {
+ if (cursor.y < myDoc->lastLine()) {
+ cursor.y++;
+ textLine = myDoc->getTextLine(cursor.y);
+ cursor.x = 0;
+ }
+ }
+
+ cOldXPos = cXPos = myDoc->textWidth(cursor);
+ changeState(c);
+}
+
+void KateViewInternal::home(VConfig &c) {
+ int lc;
+
+ lc = (c.flags & KateView::cfSmartHome) ? myDoc->getTextLine(cursor.y)->firstChar() : 0;
+ if (lc <= 0 || cursor.x == lc) {
+ cursor.x = 0;
+ cOldXPos = cXPos = 0;
+ } else {
+ cursor.x = lc;
+ cOldXPos = cXPos = myDoc->textWidth(cursor);
+ }
+
+ changeState(c);
+}
+
+void KateViewInternal::end(VConfig &c) {
+ cursor.x = myDoc->textLength(cursor.y);
+ cOldXPos = cXPos = myDoc->textWidth(cursor);
+ changeState(c);
+}
+
+
+void KateViewInternal::cursorUp(VConfig &c) {
+
+ cursor.y--;
+ cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor,cursor,cOldXPos);
+ changeState(c);
+}
+
+
+void KateViewInternal::cursorDown(VConfig &c) {
+ int x;
+
+ if (cursor.y == myDoc->lastLine()) {
+ x = myDoc->textLength(cursor.y);
+ if (cursor.x >= x) return;
+ cursor.x = x;
+ cXPos = myDoc->textWidth(cursor);
+ } else {
+ cursor.y++;
+ cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor, cursor, cOldXPos);
+ }
+ changeState(c);
+}
+
+void KateViewInternal::scrollUp(VConfig &c) {
+
+ if (! yPos) return;
+
+ newYPos = yPos - myDoc->fontHeight;
+ if (cursor.y == (yPos + height())/myDoc->fontHeight -1) {
+ cursor.y--;
+ cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor,cursor,cOldXPos);
+
+ changeState(c);
+ }
+}
+
+void KateViewInternal::scrollDown(VConfig &c) {
+
+ if (endLine >= myDoc->lastLine()) return;
+
+ newYPos = yPos + myDoc->fontHeight;
+ if (cursor.y == (yPos + myDoc->fontHeight -1)/myDoc->fontHeight) {
+ cursor.y++;
+ cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor,cursor,cOldXPos);
+ changeState(c);
+ }
+}
+
+void KateViewInternal::topOfView(VConfig &c) {
+
+ cursor.y = (yPos + myDoc->fontHeight -1)/myDoc->fontHeight;
+ cursor.x = 0;
+ cOldXPos = cXPos = 0;
+ changeState(c);
+}
+
+void KateViewInternal::bottomOfView(VConfig &c) {
+
+ cursor.y = (yPos + height())/myDoc->fontHeight -1;
+ if (cursor.y < 0) cursor.y = 0;
+ if (cursor.y > myDoc->lastLine()) cursor.y = myDoc->lastLine();
+ cursor.x = 0;
+ cOldXPos = cXPos = 0;
+ changeState(c);
+}
+
+void KateViewInternal::pageUp(VConfig &c) {
+ int lines = (endLine - startLine - 1);
+
+ if (lines <= 0) lines = 1;
+
+ if (!(c.flags & KateView::cfPageUDMovesCursor) && yPos > 0) {
+ newYPos = yPos - lines * myDoc->fontHeight;
+ if (newYPos < 0) newYPos = 0;
+ }
+ cursor.y -= lines;
+ cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor, cursor, cOldXPos);
+ changeState(c);
+// cursorPageUp(c);
+}
+
+void KateViewInternal::pageDown(VConfig &c) {
+
+ int lines = (endLine - startLine - 1);
+
+ if (!(c.flags & KateView::cfPageUDMovesCursor) && endLine < myDoc->lastLine()) {
+ if (lines < myDoc->lastLine() - endLine)
+ newYPos = yPos + lines * myDoc->fontHeight;
+ else
+ newYPos = yPos + (myDoc->lastLine() - endLine) * myDoc->fontHeight;
+ }
+ cursor.y += lines;
+ cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor,cursor,cOldXPos);
+ changeState(c);
+// cursorPageDown(c);
+}
+
+// go to the top, same X position
+void KateViewInternal::top(VConfig &c) {
+
+// cursor.x = 0;
+ cursor.y = 0;
+ cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor,cursor,cOldXPos);
+// cOldXPos = cXPos = 0;
+ changeState(c);
+}
+
+// go to the bottom, same X position
+void KateViewInternal::bottom(VConfig &c) {
+
+// cursor.x = 0;
+ cursor.y = myDoc->lastLine();
+ cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor,cursor,cOldXPos);
+// cOldXPos = cXPos = 0;
+ changeState(c);
+}
+
+// go to the top left corner
+void KateViewInternal::top_home(VConfig &c)
+{
+ cursor.y = 0;
+ cursor.x = 0;
+ cOldXPos = cXPos = 0;
+ changeState(c);
+}
+
+// go to the bottom right corner
+void KateViewInternal::bottom_end(VConfig &c) {
+
+ cursor.y = myDoc->lastLine();
+ cursor.x = myDoc->textLength(cursor.y);
+ cOldXPos = cXPos = myDoc->textWidth(cursor);
+ changeState(c);
+}
+
+
+void KateViewInternal::changeXPos(int p) {
+ int dx;
+
+ dx = xPos - p;
+ xPos = p;
+ if (QABS(dx) < width()) scroll(dx, 0); else update();
+}
+
+void KateViewInternal::changeYPos(int p) {
+ int dy;
+
+ dy = yPos - p;
+ yPos = p;
+ clearDirtyCache(height());
+
+ if (QABS(dy) < height())
+ {
+ scroll(0, dy);
+ leftBorder->scroll(0, dy);
+ }
+ else
+ update();
+}
+
+
+void KateViewInternal::getVConfig(VConfig &c) {
+
+ c.view = myView;
+ c.cursor = cursor;
+ c.cXPos = cXPos;
+ c.flags = myView->configFlags;
+}
+
+void KateViewInternal::changeState(VConfig &c) {
+ /*
+ * we need to be sure to kill the selection on an attempted cursor
+ * movement even if the cursor doesn't physically move,
+ * but we need to be careful not to do some other things in this case,
+ * like we don't want to expose the cursor
+ */
+
+// if (cursor.x == c.cursor.x && cursor.y == c.cursor.y) return;
+ bool nullMove = (cursor.x == c.cursor.x && cursor.y == c.cursor.y);
+
+// if (cursor.y != c.cursor.y || c.flags & KateView::cfMark) myDoc->recordReset();
+
+ if (! nullMove) {
+
+ exposeCursor = true;
+
+ // mark old position of cursor as dirty
+ if (cursorOn) {
+ tagLines(c.cursor.y, c.cursor.y, c.cXPos -2, c.cXPos +3);
+ cursorOn = false;
+ }
+
+ // mark old bracket mark position as dirty
+ if (bm.sXPos < bm.eXPos) {
+ tagLines(bm.cursor.y, bm.cursor.y, bm.sXPos, bm.eXPos);
+ }
+ // make new bracket mark
+ myDoc->newBracketMark(cursor, bm);
+
+ // remove trailing spaces when leaving a line
+ if (c.flags & KateView::cfRemoveSpaces && cursor.y != c.cursor.y) {
+ TextLine::Ptr textLine = myDoc->getTextLine(c.cursor.y);
+ int newLen = textLine->lastChar();
+ if (newLen != textLine->length()) {
+ textLine->truncate(newLen);
+ // if some spaces are removed, tag the line as dirty
+ myDoc->tagLines(c.cursor.y, c.cursor.y);
+ }
+ }
+ }
+
+ if (c.flags & KateView::cfMark) {
+ if (! nullMove)
+ myDoc->selectTo(c, cursor, cXPos);
+ } else {
+ if (!(c.flags & KateView::cfPersistent))
+ myDoc->deselectAll();
+ }
+}
+
+void KateViewInternal::insLine(int line) {
+
+ if (line <= cursor.y) {
+ cursor.y++;
+ }
+ if (line < startLine) {
+ startLine++;
+ endLine++;
+ yPos += myDoc->fontHeight;
+ } else if (line <= endLine) {
+ tagAll();
+ }
+}
+
+void KateViewInternal::delLine(int line) {
+
+ if (line <= cursor.y && cursor.y > 0) {
+ cursor.y--;
+ }
+ if (line < startLine) {
+ startLine--;
+ endLine--;
+ yPos -= myDoc->fontHeight;
+ } else if (line <= endLine) {
+ tagAll();
+ }
+}
+
+void KateViewInternal::updateCursor() {
+ cOldXPos = cXPos = myDoc->textWidth(cursor);
+}
+
+
+void KateViewInternal::updateCursor(PointStruc &newCursor) {
+ updateCursor(newCursor, myView->config());
+}
+
+void KateViewInternal::updateCursor(PointStruc &newCursor, int flags) {
+
+ if (!(flags & KateView::cfPersistent)) myDoc->deselectAll();
+
+ exposeCursor = true;
+ if (cursorOn) {
+ tagLines(cursor.y, cursor.y, cXPos -2, cXPos +3);
+ cursorOn = false;
+ }
+
+ if (bm.sXPos < bm.eXPos) {
+ tagLines(bm.cursor.y, bm.cursor.y, bm.sXPos, bm.eXPos);
+ }
+ myDoc->newBracketMark(newCursor, bm);
+
+ cursor = newCursor;
+ cOldXPos = cXPos = myDoc->textWidth(cursor);
+}
+
+// init the line dirty cache
+void KateViewInternal::clearDirtyCache(int height) {
+ int lines, z;
+
+ // calc start and end line of visible part
+ startLine = yPos/myDoc->fontHeight;
+ endLine = (yPos + height -1)/myDoc->fontHeight;
+
+ updateState = 0;
+
+ lines = endLine - startLine +1;
+ if (lines > numLines) { // resize the dirty cache
+ numLines = lines*2;
+ delete [] lineRanges;
+ lineRanges = new LineRange[numLines];
+ }
+
+ for (z = 0; z < lines; z++) { // clear all lines
+ lineRanges[z].start = 0xffffff;
+ lineRanges[z].end = -2;
+ }
+ newXPos = newYPos = -1;
+}
+
+void KateViewInternal::tagLines(int start, int end, int x1, int x2) {
+ LineRange *r;
+ int z;
+
+ start -= startLine;
+ if (start < 0) start = 0;
+ end -= startLine;
+ if (end > endLine - startLine) end = endLine - startLine;
+
+ if (x1 <= 0) x1 = -2;
+ if (x1 < xPos-2) x1 = xPos-2;
+ if (x2 > width() + xPos-2) x2 = width() + xPos-2;
+ if (x1 >= x2) return;
+
+ r = &lineRanges[start];
+ for (z = start; z <= end; z++) {
+ if (x1 < r->start) r->start = x1;
+ if (x2 > r->end) r->end = x2;
+ r++;
+ updateState |= 1;
+ }
+}
+
+void KateViewInternal::tagAll() {
+ updateState = 3;
+}
+
+void KateViewInternal::setPos(int x, int y) {
+ newXPos = x;
+ newYPos = y;
+}
+
+void KateViewInternal::center() {
+ newXPos = 0;
+ newYPos = cursor.y*myDoc->fontHeight - height()/2;
+ if (newYPos < 0) newYPos = 0;
+}
+
+void KateViewInternal::updateView(int flags) {
+ int fontHeight;
+ int oldXPos, oldYPos;
+ int w, h;
+ int z;
+ bool b;
+ int xMax, yMax;
+ int cYPos;
+ int cXPosMin, cXPosMax, cYPosMin, cYPosMax;
+ int dx, dy;
+ int pageScroll;
+ int scrollbarWidth = style().scrollBarExtent().width();
+
+//debug("upView %d %d %d %d %d", exposeCursor, updateState, flags, newXPos, newYPos);
+ if (exposeCursor || flags & KateView::ufDocGeometry) {
+ emit myView->newCurPos();
+ } else {
+ if (updateState == 0 && newXPos < 0 && newYPos < 0) return;
+ }
+
+ if (cursorTimer) {
+ killTimer(cursorTimer);
+ cursorTimer = startTimer(KApplication::cursorFlashTime() / 2);
+ cursorOn = true;
+ }
+
+ oldXPos = xPos;
+ oldYPos = yPos;
+/* if (flags & ufPos) {
+ xPos = newXPos;
+ yPos = newYPos;
+ exposeCursor = true;
+ }*/
+ if (newXPos >= 0) xPos = newXPos;
+ if (newYPos >= 0) yPos = newYPos;
+
+ fontHeight = myDoc->fontHeight;
+ cYPos = cursor.y*fontHeight;
+
+ z = 0;
+ do {
+ w = myView->width() - 4;
+ h = myView->height() - 4;
+
+ xMax = myDoc->textWidth() - w;
+ b = (xPos > 0 || xMax > 0);
+ if (b) h -= scrollbarWidth;
+ yMax = myDoc->textHeight() - h;
+ if (yPos > 0 || yMax > 0) {
+ w -= scrollbarWidth;
+ xMax += scrollbarWidth;
+ if (!b && xMax > 0) {
+ h -= scrollbarWidth;
+ yMax += scrollbarWidth;
+ }
+ }
+
+ if (!exposeCursor) break;
+// if (flags & KateView::ufNoScroll) break;
+/*
+ if (flags & KateView::ufCenter) {
+ cXPosMin = xPos + w/3;
+ cXPosMax = xPos + (w*2)/3;
+ cYPosMin = yPos + h/3;
+ cYPosMax = yPos + ((h - fontHeight)*2)/3;
+ } else {*/
+ cXPosMin = xPos + 4;
+ cXPosMax = xPos + w - 8;
+ cYPosMin = yPos;
+ cYPosMax = yPos + (h - fontHeight);
+// }
+
+ if (cXPos < cXPosMin) {
+ xPos -= cXPosMin - cXPos;
+ }
+ if (xPos < 0) xPos = 0;
+ if (cXPos > cXPosMax) {
+ xPos += cXPos - cXPosMax;
+ }
+ if (cYPos < cYPosMin) {
+ yPos -= cYPosMin - cYPos;
+ }
+ if (yPos < 0) yPos = 0;
+ if (cYPos > cYPosMax) {
+ yPos += cYPos - cYPosMax;
+ }
+
+ z++;
+ } while (z < 2);
+
+ if (xMax < xPos) xMax = xPos;
+ if (yMax < yPos) yMax = yPos;
+
+ if (xMax > 0) {
+ pageScroll = w - (w % fontHeight) - fontHeight;
+ if (pageScroll <= 0)
+ pageScroll = fontHeight;
+
+ xScroll->blockSignals(true);
+ xScroll->setGeometry(2,h + 2,w,scrollbarWidth);
+ xScroll->setRange(0,xMax);
+ xScroll->setValue(xPos);
+ xScroll->setSteps(fontHeight,pageScroll);
+ xScroll->blockSignals(false);
+ xScroll->show();
+ } else xScroll->hide();
+
+ if (yMax > 0) {
+ pageScroll = h - (h % fontHeight) - fontHeight;
+ if (pageScroll <= 0)
+ pageScroll = fontHeight;
+
+ yScroll->blockSignals(true);
+ yScroll->setGeometry(w + 2,2,scrollbarWidth,h);
+ yScroll->setRange(0,yMax);
+ yScroll->setValue(yPos);
+ yScroll->setSteps(fontHeight,pageScroll);
+ yScroll->blockSignals(false);
+ yScroll->show();
+ } else yScroll->hide();
+
+ if (w != width() || h != height()) {
+ clearDirtyCache(h);
+ resize(w,h);
+ } else {
+ dx = oldXPos - xPos;
+ dy = oldYPos - yPos;
+
+ b = updateState == 3;
+ if (flags & KateView::ufUpdateOnScroll) {
+ b |= dx || dy;
+ } else {
+ b |= QABS(dx)*3 > w*2 || QABS(dy)*3 > h*2;
+ }
+
+ if (b) {
+ clearDirtyCache(h);
+ update();
+ } else {
+ if (dy)
+ leftBorder->scroll(0, dy);
+ if (updateState > 0) paintTextLines(oldXPos, oldYPos);
+ clearDirtyCache(h);
+
+ if (dx || dy) {
+ scroll(dx,dy);
+// kapp->syncX();
+// scroll2(dx - dx/2,dy - dy/2);
+// } else {
+ }
+ if (cursorOn) paintCursor();
+ if (bm.eXPos > bm.sXPos) paintBracketMark();
+ }
+ }
+ exposeCursor = false;
+// updateState = 0;
+}
+
+
+void KateViewInternal::paintTextLines(int xPos, int yPos) {
+// int xStart, xEnd;
+ int line;//, z;
+ int h;
+ LineRange *r;
+
+ if (!drawBuffer) return;
+ if (drawBuffer->isNull()) return;
+
+ QPainter paint;
+ paint.begin(drawBuffer);
+
+ h = myDoc->fontHeight;
+ r = lineRanges;
+ for (line = startLine; line <= endLine; line++) {
+ if (r->start < r->end) {
+//debug("painttextline %d %d %d", line, r->start, r->end);
+ myDoc->paintTextLine(paint, line, r->start, r->end, myView->configFlags & KateView::cfShowTabs);
+ bitBlt(this, r->start - (xPos-2), line*h - yPos, drawBuffer, 0, 0,
+ r->end - r->start, h);
+ leftBorder->paintLine(line);
+ }
+ r++;
+ }
+
+ paint.end();
+}
+
+void KateViewInternal::paintCursor() {
+ int h, y, x;
+ static int cx = 0, cy = 0, ch = 0;
+
+ h = myDoc->fontHeight;
+ y = h*cursor.y - yPos;
+ x = cXPos - (xPos-2);
+
+ if(myDoc->myFont != font()) setFont(myDoc->myFont);
+ if(cx != x || cy != y || ch != h){
+ cx = x;
+ cy = y;
+ ch = h;
+ setMicroFocusHint(cx, cy, 0, ch - 2);
+ }
+
+ QPainter paint;
+ if (cursorOn) {
+ paint.begin(this);
+ paint.setClipping(false);
+ paint.setPen(myDoc->cursorCol(cursor.x,cursor.y));
+
+ h += y - 1;
+ paint.drawLine(x, y, x, h);
+
+ paint.end();
+ } else { if (drawBuffer && !drawBuffer->isNull()) {
+ paint.begin(drawBuffer);
+ myDoc->paintTextLine(paint, cursor.y, cXPos - 2, cXPos + 3, myView->configFlags & KateView::cfShowTabs);
+ bitBlt(this,x - 2,y, drawBuffer, 0, 0, 5, h);
+ paint.end(); }
+ }
+
+}
+
+void KateViewInternal::paintBracketMark() {
+ int y;
+
+ y = myDoc->fontHeight*(bm.cursor.y +1) - yPos -1;
+
+ QPainter paint;
+ paint.begin(this);
+ paint.setPen(myDoc->cursorCol(bm.cursor.x, bm.cursor.y));
+
+ paint.drawLine(bm.sXPos - (xPos-2), y, bm.eXPos - (xPos-2) -1, y);
+ paint.end();
+}
+
+void KateViewInternal::placeCursor(int x, int y, int flags) {
+ VConfig c;
+
+ getVConfig(c);
+ c.flags |= flags;
+ cursor.y = (yPos + y)/myDoc->fontHeight;
+ cXPos = cOldXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor, cursor,xPos-2 + x);
+ changeState(c);
+}
+
+// given physical coordinates, report whether the text there is selected
+bool KateViewInternal::isTargetSelected(int x, int y) {
+
+ y = (yPos + y) / myDoc->fontHeight;
+
+ TextLine::Ptr line = myDoc->getTextLine(y);
+ if (!line)
+ return false;
+
+ x = myDoc->textPos(line, x);
+
+ return line->isSelected(x);
+}
+
+void KateViewInternal::focusInEvent(QFocusEvent *) {
+// debug("got focus %d",cursorTimer);
+
+ if (!cursorTimer) {
+ cursorTimer = startTimer(KApplication::cursorFlashTime() / 2);
+ cursorOn = true;
+ paintCursor();
+ }
+}
+
+void KateViewInternal::focusOutEvent(QFocusEvent *) {
+// debug("lost focus %d", cursorTimer);
+
+ if (cursorTimer) {
+ killTimer(cursorTimer);
+ cursorTimer = 0;
+ }
+
+ if (cursorOn) {
+ cursorOn = false;
+ paintCursor();
+ }
+}
+
+void KateViewInternal::keyPressEvent(QKeyEvent *e) {
+ VConfig c;
+// int ascii;
+
+/* if (e->state() & AltButton) {
+ e->ignore();
+ return;
+ }*/
+// debug("ascii %i, key %i, state %i",e->ascii(), e->key(), e->state());
+
+ getVConfig(c);
+// ascii = e->ascii();
+
+ if (!myView->isReadOnly()) {
+ if (c.flags & KateView::cfTabIndents && myDoc->hasMarkedText()) {
+ if (e->key() == Qt::Key_Tab) {
+ myDoc->indent(c);
+ myDoc->updateViews();
+ return;
+ }
+ if (e->key() == Qt::Key_Backtab) {
+ myDoc->unIndent(c);
+ myDoc->updateViews();
+ return;
+ }
+ }
+ if ( !(e->state() & ControlButton ) && myDoc->insertChars(c, e->text())) {
+ myDoc->updateViews();
+ e->accept();
+ return;
+ }
+ }
+ e->ignore();
+}
+
+void KateViewInternal::mousePressEvent(QMouseEvent *e) {
+
+ if (e->button() == LeftButton) {
+
+ int flags;
+
+ flags = 0;
+ if (e->state() & ShiftButton) {
+ flags |= KateView::cfMark;
+ if (e->state() & ControlButton) flags |= KateView::cfMark | KateView::cfKeepSelection;
+ }
+ placeCursor(e->x(), e->y(), flags);
+ scrollX = 0;
+ scrollY = 0;
+ if (!scrollTimer) scrollTimer = startTimer(50);
+ myDoc->updateViews();
+ }
+ if (e->button() == MidButton) {
+ placeCursor(e->x(), e->y());
+ if (! myView->isReadOnly())
+ myView->paste();
+ }
+ if (myView->rmbMenu && e->button() == RightButton) {
+ myView->rmbMenu->popup(mapToGlobal(e->pos()));
+ }
+ myView->mousePressEvent(e); // this doesn't do anything, does it?
+ // it does :-), we need this for KDevelop, so please don't uncomment it again -Sandy
+}
+
+void KateViewInternal::mouseDoubleClickEvent(QMouseEvent *e) {
+
+ if (e->button() == LeftButton) {
+ VConfig c;
+ getVConfig(c);
+ myDoc->selectWord(c.cursor, c.flags);
+ myDoc->updateViews();
+ }
+}
+
+void KateViewInternal::mouseReleaseEvent(QMouseEvent *e) {
+
+ if (e->button() == LeftButton) {
+ if (myView->config() & KateView::cfMouseAutoCopy) myView->copy();
+ killTimer(scrollTimer);
+ scrollTimer = 0;
+ }
+}
+
+void KateViewInternal::mouseMoveEvent(QMouseEvent *e) {
+
+ if (e->state() & LeftButton) {
+ int flags;
+ int d;
+ int x = e->x(),
+ y = e->y();
+
+ mouseX = e->x();
+ mouseY = e->y();
+ scrollX = 0;
+ scrollY = 0;
+ d = myDoc->fontHeight;
+ if (mouseX < 0) {
+ mouseX = 0;
+ scrollX = -d;
+ }
+ if (mouseX > width()) {
+ mouseX = width();
+ scrollX = d;
+ }
+ if (mouseY < 0) {
+ mouseY = 0;
+ scrollY = -d;
+ }
+ if (mouseY > height()) {
+ mouseY = height();
+ scrollY = d;
+ }
+//debug("modifiers %d", ((KGuiCmdApp *) kapp)->getModifiers());
+ flags = KateView::cfMark;
+ if (e->state() & ControlButton) flags |= KateView::cfKeepSelection;
+ placeCursor(mouseX, mouseY, flags);
+ myDoc->updateViews(/*ufNoScroll*/);
+ }
+}
+
+
+
+void KateViewInternal::wheelEvent( QWheelEvent *e )
+{
+ if( yScroll->isVisible() == true )
+ {
+ QApplication::sendEvent( yScroll, e );
+ }
+}
+
+
+
+void KateViewInternal::paintEvent(QPaintEvent *e) {
+ int xStart, xEnd;
+ int h;
+ int line, y, yEnd;
+
+ QRect updateR = e->rect();
+
+ if (!drawBuffer) return;
+ if (drawBuffer->isNull()) return;
+
+ QPainter paint;
+ paint.begin(drawBuffer);
+
+ xStart = xPos-2 + updateR.x();
+ xEnd = xStart + updateR.width();
+
+ h = myDoc->fontHeight;
+ line = (yPos + updateR.y()) / h;
+ y = line*h - yPos;
+ yEnd = updateR.y() + updateR.height();
+ waitForPreHighlight=myDoc->needPreHighlight(waitForPreHighlight=line+((long)(yEnd-y)/h)+5);
+
+ while (y < yEnd)
+ {
+ TextLine *textLine;
+ int ctxNum = 0;
+ myDoc->paintTextLine(paint, line, xStart, xEnd, myView->configFlags & KateView::cfShowTabs);
+ bitBlt(this, updateR.x(), y, drawBuffer, 0, 0, updateR.width(), h);
+ leftBorder->paintLine(line);
+ line++;
+ y += h;
+ }
+ paint.end();
+
+ if (cursorOn) paintCursor();
+ if (bm.eXPos > bm.sXPos) paintBracketMark();
+}
+
+void KateViewInternal::resizeEvent(QResizeEvent *)
+{
+ drawBuffer->resize (width(), myDoc->fontHeight);
+ leftBorder->resize(iconBorderWidth, height());
+}
+
+void KateViewInternal::timerEvent(QTimerEvent *e) {
+ if (e->timerId() == cursorTimer) {
+ cursorOn = !cursorOn;
+ paintCursor();
+ }
+ if (e->timerId() == scrollTimer && (scrollX | scrollY)) {
+ xScroll->setValue(xPos + scrollX);
+ yScroll->setValue(yPos + scrollY);
+
+ placeCursor(mouseX, mouseY, KateView::cfMark);
+ myDoc->updateViews(/*ufNoScroll*/);
+ }
+}
+
+uint KateView::uniqueID = 0;
+
+KateView::KateView(KateDocument *doc, QWidget *parent, const char * name) : Kate::View (doc, parent, name)
+{
+
+ myViewID = uniqueID;
+ uniqueID++;
+
+ active = false;
+ myIconBorder = false;
+
+ myDoc = doc;
+ myViewInternal = new KateViewInternal (this,doc);
+ myViewInternal->move(2, 2);
+ myViewInternal->leftBorder = new KateIconBorder(this, myViewInternal);
+ myViewInternal->leftBorder->setGeometry(2, 2, myViewInternal->iconBorderWidth, myViewInternal->iconBorderHeight);
+ myViewInternal->leftBorder->hide();
+
+ doc->addView( this );
+
+
+ // some defaults
+ configFlags = KateView::cfAutoIndent | KateView::cfBackspaceIndents
+ | KateView::cfTabIndents | KateView::cfKeepIndentProfile
+ | KateView::cfRemoveSpaces
+ | KateView::cfDelOnInput | KateView::cfMouseAutoCopy | KateView::cfWrapCursor
+ | KateView::cfGroupUndo | KateView::cfShowTabs | KateView::cfSmartHome;
+
+ searchFlags = 0;
+ replacePrompt = 0L;
+ rmbMenu = 0L;
+
+
+ setFocusProxy( myViewInternal );
+ myViewInternal->setFocus();
+ resize(parent->width() -4, parent->height() -4);
+
+
+ myViewInternal->installEventFilter( this );
+
+ //setupActions();
+
+ connect( this, SIGNAL( newStatus() ), this, SLOT( slotUpdate() ) );
+ connect( this, SIGNAL( newUndo() ), this, SLOT( slotNewUndo() ) );
+ connect( doc, SIGNAL( fileNameChanged() ), this, SLOT( slotFileStatusChanged() ) );
+ connect( doc, SIGNAL( highlightChanged() ), this, SLOT( slotHighlightChanged() ) );
+
+ readConfig();
+// setHighlight->setCurrentItem(getHl());
+ slotUpdate();
+}
+
+KateView::~KateView()
+{
+
+ if (myDoc && !myDoc->m_bSingleViewMode)
+ myDoc->removeView( this );
+
+ delete myViewInternal;
+
+}
+
+#if 0
+void KateView::setupActions()
+{
+#if 0
+ KStdAction::close( this, SLOT(flush()), actionCollection(), "file_close" );
+
+ KStdAction::save(this, SLOT(save()), actionCollection());
+
+ // setup edit menu
+ editUndo = KStdAction::undo(this, SLOT(undo()), actionCollection());
+ editRedo = KStdAction::redo(this, SLOT(redo()), actionCollection());
+ editUndoHist = new KAction(i18n("Undo/Redo &History..."), 0, this, SLOT(undoHistory()),
+ actionCollection(), "edit_undoHistory");
+ KStdAction::cut(this, SLOT(cut()), actionCollection());
+ KStdAction::copy(this, SLOT(copy()), actionCollection());
+ KStdAction::paste(this, SLOT(paste()), actionCollection());
+
+ if ( myDoc->hasBrowserExtension() )
+ {
+ KStdAction::saveAs(this, SLOT(saveAs()), myDoc->actionCollection());
+ KStdAction::find(this, SLOT(find()), myDoc->actionCollection(), "find");
+ KStdAction::findNext(this, SLOT(findAgain()), myDoc->actionCollection(), "find_again");
+ KStdAction::findPrev(this, SLOT(findPrev()), myDoc->actionCollection(), "find_prev");
+ KStdAction::gotoLine(this, SLOT(gotoLine()), myDoc->actionCollection(), "goto_line" );
+ new KAction(i18n("&Configure Editor..."), 0, this, SLOT(configDialog()),myDoc->actionCollection(), "set_confdlg");
+ setHighlight = new KSelectAction(i18n("&Highlight Mode"), 0, myDoc->actionCollection(), "set_highlight");
+ KStdAction::selectAll(this, SLOT(selectAll()), myDoc->actionCollection(), "select_all");
+ new KAction(i18n("&Deselect All"), 0, this, SLOT(deselectAll()),
+ myDoc->actionCollection(), "unselect_all");
+ new KAction(i18n("Invert &Selection"), 0, this, SLOT(invertSelection()),
+ myDoc->actionCollection(), "invert_select");
+
+ new KAction(i18n("Increase Font Sizes"), "viewmag+", 0, this, SLOT(slotIncFontSizes()),
+ myDoc->actionCollection(), "incFontSizes");
+ new KAction(i18n("Decrease Font Sizes"), "viewmag-", 0, this, SLOT(slotDecFontSizes()),
+ myDoc->actionCollection(), "decFontSizes");
+ }
+ else
+ {
+ KStdAction::saveAs(this, SLOT(saveAs()), actionCollection());
+ KStdAction::find(this, SLOT(find()), actionCollection());
+ KStdAction::findNext(this, SLOT(findAgain()), actionCollection());
+ KStdAction::findPrev(this, SLOT(findPrev()), actionCollection(), "edit_find_prev");
+ KStdAction::gotoLine(this, SLOT(gotoLine()), actionCollection());
+ new KAction(i18n("&Configure Editor..."), 0, this, SLOT(configDialog()),actionCollection(), "set_confdlg");
+ setHighlight = new KSelectAction(i18n("&Highlight Mode"), 0, actionCollection(), "set_highlight");
+ KStdAction::selectAll(this, SLOT(selectAll()), actionCollection());
+ new KAction(i18n("&Deselect All"), 0, this, SLOT(deselectAll()),
+ actionCollection(), "edit_deselectAll");
+ new KAction(i18n("Invert &Selection"), 0, this, SLOT(invertSelection()),
+ actionCollection(), "edit_invertSelection");
+
+ new KAction(i18n("Increase Font Sizes"), "viewmag+", 0, this, SLOT(slotIncFontSizes()),
+ actionCollection(), "incFontSizes");
+ new KAction(i18n("Decrease Font Sizes"), "viewmag-", 0, this, SLOT(slotDecFontSizes()),
+ actionCollection(), "decFontSizes");
+ }
+
+ new KAction(i18n("Apply Word Wrap"), 0, myDoc, SLOT(applyWordWrap()), actionCollection(), "edit_apply_wordwrap");
+
+ KStdAction::replace(this, SLOT(replace()), actionCollection());
+
+ new KAction(i18n("Editing Co&mmand"), Qt::CTRL+Qt::Key_M, this, SLOT(slotEditCommand()),
+ actionCollection(), "edit_cmd");
+
+ // setup bookmark menu
+ bookmarkToggle = new KAction(i18n("Toggle &Bookmark"), Qt::CTRL+Qt::Key_B, this, SLOT(toggleBookmark()), actionCollection(), "edit_bookmarkToggle");
+ bookmarkClear = new KAction(i18n("Clear Bookmarks"), 0, this, SLOT(clearBookmarks()), actionCollection(), "edit_bookmarksClear");
+
+ // connect settings menu aboutToshow
+ bookmarkMenu = new KActionMenu(i18n("&Bookmarks"), actionCollection(), "bookmarks");
+ connect(bookmarkMenu->popupMenu(), SIGNAL(aboutToShow()), this, SLOT(bookmarkMenuAboutToShow()));
+
+ new KToggleAction(i18n("Show &IconBorder"), Key_F6, this, SLOT(toggleIconBorder()), actionCollection(), "view_border");
+
+ // setup Tools menu
+ KStdAction::spelling(this, SLOT(spellcheck()), actionCollection());
+ new KAction(i18n("&Indent"), "indent", Qt::CTRL+Qt::Key_I, this, SLOT(indent()),
+ actionCollection(), "tools_indent");
+ new KAction(i18n("&Unindent"), "unindent", Qt::CTRL+Qt::Key_U, this, SLOT(unIndent()),
+ actionCollection(), "tools_unindent");
+ new KAction(i18n("&Clean Indentation"), 0, this, SLOT(cleanIndent()),
+ actionCollection(), "tools_cleanIndent");
+ new KAction(i18n("C&omment"), CTRL+Qt::Key_NumberSign, this, SLOT(comment()),
+ actionCollection(), "tools_comment");
+ new KAction(i18n("Unco&mment"), CTRL+SHIFT+Qt::Key_NumberSign, this, SLOT(uncomment()),
+ actionCollection(), "tools_uncomment");
+
+ setVerticalSelection = new KToggleAction(i18n("&Vertical Selection"), Key_F4, this, SLOT(toggleVertical()),
+ actionCollection(), "set_verticalSelect");
+
+ connect(setHighlight, SIGNAL(activated(int)), this, SLOT(setHl(int)));
+ QStringList list;
+ for (int z = 0; z < HlManager::self()->highlights(); z++)
+ list.append(HlManager::self()->hlName(z));
+ setHighlight->setItems(list);
+
+ setEndOfLine = new KSelectAction(i18n("&End Of Line"), 0, actionCollection(), "set_eol");
+ connect(setEndOfLine, SIGNAL(activated(int)), this, SLOT(setEol(int)));
+ list.clear();
+ list.append("&Unix");
+ list.append("&Windows/Dos");
+ list.append("&Macintosh");
+ setEndOfLine->setItems(list);
+#endif
+}
+#endif
+
+void KateView::slotUpdate()
+{
+ int cfg = config();
+
+#warning fixme setVerticalSelection->setChecked(cfg & KateView::cfVerticalSelect);
+
+ slotNewUndo();
+}
+void KateView::slotFileStatusChanged()
+{
+ int eol = getEol();
+ eol = eol>=1 ? eol : 0;
+
+#warning fixme setEndOfLine->setCurrentItem(eol);
+}
+void KateView::slotNewUndo()
+{
+#if 0
+ int state = undoState();
+
+ editUndoHist->setEnabled(state & 1 || state & 2);
+
+ QString t = i18n("Und&o"); // it would be nicer to fetch the original string
+ if (state & 1) {
+ editUndo->setEnabled(true);
+ t += ' ';
+ t += i18n(undoTypeName(nextUndoType()));
+ } else {
+ editUndo->setEnabled(false);
+ }
+ editUndo->setText(t);
+
+ t = i18n("Re&do"); // it would be nicer to fetch the original string
+ if (state & 2) {
+ editRedo->setEnabled(true);
+ t += ' ';
+ t += i18n(undoTypeName(nextRedoType()));
+ } else {
+ editRedo->setEnabled(false);
+ }
+ editRedo->setText(t);
+#endif
+}
+
+void KateView::slotHighlightChanged()
+{
+// setHighlight->setCurrentItem(getHl());
+}
+
+
+void KateView::keyPressEvent( QKeyEvent *ev )
+{
+ switch ( ev->key() )
+ {
+ case Key_Left:
+ if ( ev->state() & ShiftButton )
+ {
+ if ( ev->state() & ControlButton )
+ shiftWordLeft();
+ else
+ shiftCursorLeft();
+ }
+ else if ( ev->state() & ControlButton )
+ wordLeft();
+ else
+ cursorLeft();
+ break;
+ case Key_Right:
+ if ( ev->state() & ShiftButton )
+ {
+ if ( ev->state() & ControlButton )
+ shiftWordRight();
+ else
+ shiftCursorRight();
+ }
+ else if ( ev->state() & ControlButton )
+ wordRight();
+ else
+ cursorRight();
+ break;
+ case Key_Home:
+ if ( ev->state() & ShiftButton )
+ {
+ if ( ev->state() & ControlButton )
+ shiftTop();
+ else
+ shiftHome();
+ }
+ else if ( ev->state() & ControlButton )
+ top();
+ else
+ home();
+ break;
+ case Key_End:
+ if ( ev->state() & ShiftButton )
+ {
+ if ( ev->state() & ControlButton )
+ shiftBottom();
+ else
+ shiftEnd();
+ }
+ else if ( ev->state() & ControlButton )
+ bottom();
+ else
+ end();
+ break;
+ case Key_Up:
+ if ( ev->state() & ShiftButton )
+ shiftUp();
+ else if ( ev->state() & ControlButton )
+ scrollUp();
+ else
+ up();
+ break;
+ case Key_Down:
+ if ( ev->state() & ShiftButton )
+ shiftDown();
+ else if ( ev->state() & ControlButton )
+ scrollDown();
+ else
+ down();
+ break;
+ case Key_PageUp:
+ if ( ev->state() & ShiftButton )
+ shiftPageUp();
+ else if ( ev->state() & ControlButton )
+ topOfView();
+ else
+ pageUp();
+ break;
+ case Key_PageDown:
+ if ( ev->state() & ShiftButton )
+ shiftPageDown();
+ else if ( ev->state() & ControlButton )
+ bottomOfView();
+ else
+ pageDown();
+ break;
+ case Key_Return:
+ case Key_Enter:
+ keyReturn();
+ break;
+ case Key_Delete:
+ if ( ev->state() & ControlButton )
+ {
+ VConfig c;
+ shiftWordRight();
+ myViewInternal->getVConfig(c);
+ myDoc->delMarkedText(c);
+ myViewInternal->update();
+ }
+ else keyDelete();
+ break;
+ case Key_Backspace:
+ if ( ev->state() & ControlButton )
+ {
+ VConfig c;
+ shiftWordLeft();
+ myViewInternal->getVConfig(c);
+ myDoc->delMarkedText(c);
+ myViewInternal->update();
+ }
+ else backspace();
+ break;
+ case Key_Insert:
+ toggleInsert();
+ break;
+ case Key_K:
+ if ( ev->state() & ControlButton )
+ {
+ killLine();
+ break;
+ }
+ default:
+ KTextEditor::View::keyPressEvent( ev );
+ return;
+ break;
+ }
+ ev->accept();
+}
+
+
+void KateView::setCursorPosition( int line, int col, bool /*mark*/ )
+{
+ setCursorPositionInternal( line, col );
+}
+
+void KateView::getCursorPosition( int *line, int *col )
+{
+ if ( line )
+ *line = currentLine();
+
+ if ( col )
+ *col = currentColumn();
+}
+
+
+int KateView::currentLine() {
+ return myViewInternal->cursor.y;
+}
+
+int KateView::currentColumn() {
+ return myDoc->currentColumn(myViewInternal->cursor);
+}
+
+int KateView::currentCharNum() {
+ return myViewInternal->cursor.x;
+}
+
+void KateView::setCursorPositionInternal(int line, int col) {
+ PointStruc cursor;
+
+ cursor.x = col;
+ cursor.y = line;
+ myViewInternal->updateCursor(cursor);
+ myViewInternal->center();
+// myViewInternal->updateView(ufPos, 0, line*myDoc->fontHeight - height()/2);
+// myDoc->updateViews(myViewInternal); //uptade all other views except this one
+ myDoc->updateViews();
+}
+
+int KateView::config() {
+ int flags;
+
+ flags = configFlags;
+ if (myDoc->singleSelection()) flags |= KateView::cfSingleSelection;
+ return flags;
+}
+
+void KateView::setConfig(int flags) {
+ bool updateView;
+
+ // cfSingleSelection is a doc-property
+ myDoc->setSingleSelection(flags & KateView::cfSingleSelection);
+ flags &= ~KateView::cfSingleSelection;
+
+ if (flags != configFlags) {
+ // update the view if visibility of tabs has changed
+ updateView = (flags ^ configFlags) & KateView::cfShowTabs;
+ configFlags = flags;
+ emit newStatus();
+ if (updateView) myViewInternal->update();
+ }
+}
+
+int KateView::tabWidth() {
+ return myDoc->tabChars;
+}
+
+void KateView::setTabWidth(int w) {
+ myDoc->setTabWidth(w);
+ myDoc->updateViews();
+}
+
+void KateView::setEncoding (QString e) {
+ myDoc->setEncoding (e);
+ myDoc->updateViews();
+}
+
+int KateView::undoSteps() {
+ return myDoc->undoSteps;
+}
+
+void KateView::setUndoSteps(int s) {
+ myDoc->setUndoSteps(s);
+}
+
+bool KateView::isReadOnly() {
+ return myDoc->readOnly;
+}
+
+bool KateView::isModified() {
+ return myDoc->modified;
+}
+
+void KateView::setReadOnly(bool m) {
+ myDoc->setReadOnly(m);
+}
+
+void KateView::setModified(bool m) {
+ myDoc->setModified(m);
+}
+
+bool KateView::isLastView() {
+ return myDoc->isLastView(1);
+}
+
+KateDocument *KateView::doc() {
+ return myDoc;
+}
+
+int KateView::undoState() {
+ if (isReadOnly())
+ return 0;
+ else
+ return myDoc->undoState;
+}
+
+int KateView::nextUndoType() {
+ return myDoc->nextUndoType();
+}
+
+int KateView::nextRedoType() {
+ return myDoc->nextRedoType();
+}
+
+void KateView::undoTypeList(QValueList<int> &lst)
+{
+ myDoc->undoTypeList(lst);
+}
+
+void KateView::redoTypeList(QValueList<int> &lst)
+{
+ myDoc->redoTypeList(lst);
+}
+
+const char * KateView::undoTypeName(int type) {
+ return KateActionGroup::typeName(type);
+}
+
+QColor* KateView::getColors()
+{
+ return myDoc->colors;
+}
+
+void KateView::applyColors()
+{
+ myDoc->tagAll();
+ myDoc->updateViews();
+}
+
+bool KateView::isOverwriteMode() const
+{
+ return ( configFlags & KateView::cfOvr );
+}
+
+void KateView::setOverwriteMode( bool b )
+{
+ if ( isOverwriteMode() && !b )
+ setConfig( configFlags ^ KateView::cfOvr );
+ else
+ setConfig( configFlags | KateView::cfOvr );
+}
+
+void KateView::toggleInsert() {
+ setConfig(configFlags ^ KateView::cfOvr);
+}
+
+void KateView::toggleVertical()
+{
+ setConfig(configFlags ^ KateView::cfVerticalSelect);
+}
+
+
+int KateView::numLines() {
+ return myDoc->numLines();
+}
+
+QString KateView::text() {
+ return myDoc->text();
+}
+
+QString KateView::currentTextLine() {
+ TextLine::Ptr textLine = myDoc->getTextLine(myViewInternal->cursor.y);
+ return QString(textLine->getText(), textLine->length());
+}
+
+QString KateView::textLine(int num) {
+ TextLine::Ptr textLine = myDoc->getTextLine(num);
+ return QString(textLine->getText(), textLine->length());
+}
+
+QString KateView::currentWord() {
+ return myDoc->getWord(myViewInternal->cursor);
+}
+
+QString KateView::word(int x, int y) {
+ PointStruc cursor;
+ cursor.y = (myViewInternal->yPos + y)/myDoc->fontHeight;
+ if (cursor.y < 0 || cursor.y > myDoc->lastLine()) return QString();
+ cursor.x = myDoc->textPos(myDoc->getTextLine(cursor.y), myViewInternal->xPos-2 + x);
+ return myDoc->getWord(cursor);
+}
+
+void KateView::setText(const QString &s) {
+ myDoc->setText(s);
+ myDoc->updateViews();
+}
+
+void KateView::insertText(const QString &s, bool /*mark*/) {
+ VConfig c;
+ myViewInternal->getVConfig(c);
+ myDoc->insert(c, s);
+ myDoc->updateViews();
+}
+
+bool KateView::hasMarkedText() {
+ return myDoc->hasMarkedText();
+}
+
+QString KateView::markedText() {
+ return myDoc->markedText(configFlags);
+}
+
+bool KateView::canDiscard() {
+ int query;
+
+ if (isModified()) {
+ query = KMessageBox::warningYesNoCancel(this,
+ i18n("The current Document has been modified.\nWould you like to save it?"));
+ switch (query) {
+ case KMessageBox::Yes: //yes
+ if (save() == CANCEL) return false;
+ if (isModified()) {
+ query = KMessageBox::warningContinueCancel(this,
+ i18n("Could not save the document.\nDiscard it and continue?"),
+ QString::null, i18n("&Discard"));
+ if (query == KMessageBox::Cancel) return false;
+ }
+ break;
+ case KMessageBox::Cancel: //cancel
+ return false;
+ }
+ }
+ return true;
+}
+
+void KateView::flush()
+{
+ if (canDiscard()) myDoc->flush();
+}
+
+KateView::fileResult KateView::save() {
+ int query = KMessageBox::Yes;
+ if (isModified()) {
+ return saveAs();
+ }
+ return OK;
+}
+
+KateView::fileResult KateView::saveAs() {
+ return OK;
+}
+
+void KateView::doCursorCommand(int cmdNum) {
+ VConfig c;
+ myViewInternal->getVConfig(c);
+ if (cmdNum & selectFlag) c.flags |= KateView::cfMark;
+ if (cmdNum & multiSelectFlag) c.flags |= KateView::cfMark | KateView::cfKeepSelection;
+ cmdNum &= ~(selectFlag | multiSelectFlag);
+ myViewInternal->doCursorCommand(c, cmdNum);
+ myDoc->updateViews();
+}
+
+void KateView::doEditCommand(int cmdNum) {
+ VConfig c;
+ myViewInternal->getVConfig(c);
+ myViewInternal->doEditCommand(c, cmdNum);
+ myDoc->updateViews();
+}
+
+void KateView::undoMultiple(int count) {
+ if (isReadOnly())
+ return;
+
+ VConfig c;
+ myViewInternal->getVConfig(c);
+ myDoc->undo(c, count);
+ myDoc->updateViews();
+}
+
+void KateView::redoMultiple(int count) {
+ if (isReadOnly())
+ return;
+
+ VConfig c;
+ myViewInternal->getVConfig(c);
+ myDoc->redo(c, count);
+ myDoc->updateViews();
+}
+
+void KateView::undoHistory()
+{
+ UndoHistory *undoH;
+
+ undoH = new UndoHistory(this, this, "UndoHistory", true);
+
+ undoH->setCaption(i18n("Undo/Redo History"));
+
+ connect(this,SIGNAL(newUndo()),undoH,SLOT(newUndo()));
+ connect(undoH,SIGNAL(undo(int)),this,SLOT(undoMultiple(int)));
+ connect(undoH,SIGNAL(redo(int)),this,SLOT(redoMultiple(int)));
+
+ undoH->exec();
+
+ delete undoH;
+}
+
+static void kwview_addToStrList(QStringList &list, const QString &str) {
+ if (list.count() > 0) {
+ if (list.first() == str) return;
+ QStringList::Iterator it;
+ it = list.find(str);
+ if (*it != 0L) list.remove(it);
+ if (list.count() >= 16) list.remove(list.fromLast());
+ }
+ list.prepend(str);
+}
+
+void KateView::find() {
+ SearchDialog *searchDialog;
+
+ if (!myDoc->hasMarkedText()) searchFlags &= ~KateView::sfSelected;
+
+ searchDialog = new SearchDialog(this, myDoc->searchForList, myDoc->replaceWithList,
+ searchFlags & ~KateView::sfReplace);
+
+ // If the user has marked some text we use that otherwise
+ // use the word under the cursor.
+ QString str;
+ if (myDoc->hasMarkedText())
+ str = markedText();
+
+ if (str.isEmpty())
+ str = currentWord();
+
+ if (!str.isEmpty())
+ {
+ str.replace(QRegExp("^\n"), "");
+ int pos=str.find("\n");
+ if (pos>-1)
+ str=str.left(pos);
+ searchDialog->setSearchText( str );
+ }
+
+ myViewInternal->focusOutEvent(0L);// QT bug ?
+ if (searchDialog->exec() == QDialog::Accepted) {
+ kwview_addToStrList(myDoc->searchForList, searchDialog->getSearchFor());
+ searchFlags = searchDialog->getFlags() | (searchFlags & KateView::sfPrompt);
+ initSearch(s, searchFlags);
+ findAgain(s);
+ }
+ delete searchDialog;
+}
+
+void KateView::replace() {
+ SearchDialog *searchDialog;
+
+ if (isReadOnly()) return;
+
+ if (!myDoc->hasMarkedText()) searchFlags &= ~KateView::sfSelected;
+ searchDialog = new SearchDialog(this, myDoc->searchForList, myDoc->replaceWithList,
+ searchFlags | KateView::sfReplace);
+
+ // If the user has marked some text we use that otherwise
+ // use the word under the cursor.
+ QString str;
+ if (myDoc->hasMarkedText())
+ str = markedText();
+
+ if (str.isEmpty())
+ str = currentWord();
+
+ if (!str.isEmpty())
+ {
+ str.replace(QRegExp("^\n"), "");
+ int pos=str.find("\n");
+ if (pos>-1)
+ str=str.left(pos);
+ searchDialog->setSearchText( str );
+ }
+
+ myViewInternal->focusOutEvent(0L);// QT bug ?
+ if (searchDialog->exec() == QDialog::Accepted) {
+// myDoc->recordReset();
+ kwview_addToStrList(myDoc->searchForList, searchDialog->getSearchFor());
+ kwview_addToStrList(myDoc->replaceWithList, searchDialog->getReplaceWith());
+ searchFlags = searchDialog->getFlags();
+ initSearch(s, searchFlags);
+ replaceAgain();
+ }
+ delete searchDialog;
+}
+
+void KateView::gotoLine() {
+ GotoLineDialog *dlg;
+ PointStruc cursor;
+
+ dlg = new GotoLineDialog(this, myViewInternal->cursor.y + 1, myDoc->numLines());
+// dlg = new GotoLineDialog(myViewInternal->cursor.y + 1, this);
+
+ if (dlg->exec() == QDialog::Accepted) {
+// myDoc->recordReset();
+ cursor.x = 0;
+ cursor.y = dlg->getLine() - 1;
+ myDoc->needPreHighlight(cursor.y);
+ myViewInternal->updateCursor(cursor);
+ myViewInternal->center();
+ myViewInternal->updateView(KateView::ufUpdateOnScroll);
+ myDoc->updateViews(this); //uptade all other views except this one
+ }
+ delete dlg;
+}
+
+
+void KateView::initSearch(SConfig &s, int flags) {
+
+ s.flags = flags;
+ s.setPattern(myDoc->searchForList.first());
+
+ if (!(s.flags & KateView::sfFromBeginning)) {
+ // If we are continuing a backward search, make sure we do not get stuck
+ // at an existing match.
+ s.cursor = myViewInternal->cursor;
+ TextLine::Ptr textLine = myDoc->getTextLine(s.cursor.y);
+ QString const txt(textLine->getText(),textLine->length());
+ const QString searchFor= myDoc->searchForList.first();
+ int pos = s.cursor.x-searchFor.length()-1;
+ if ( pos < 0 ) pos = 0;
+ pos= txt.find(searchFor, pos, s.flags & KateView::sfCaseSensitive);
+ if ( s.flags & KateView::sfBackward )
+ {
+ if ( pos <= s.cursor.x ) s.cursor.x= pos-1;
+ }
+ else
+ if ( pos == s.cursor.x ) s.cursor.x++;
+ } else {
+ if (!(s.flags & KateView::sfBackward)) {
+ s.cursor.x = 0;
+ s.cursor.y = 0;
+ } else {
+ s.cursor.x = -1;
+ s.cursor.y = myDoc->lastLine();
+ }
+ s.flags |= KateView::sfFinished;
+ }
+ if (!(s.flags & KateView::sfBackward)) {
+ if (!(s.cursor.x || s.cursor.y))
+ s.flags |= KateView::sfFinished;
+ }
+ s.startCursor = s.cursor;
+}
+
+void KateView::continueSearch(SConfig &s) {
+
+ if (!(s.flags & KateView::sfBackward)) {
+ s.cursor.x = 0;
+ s.cursor.y = 0;
+ } else {
+ s.cursor.x = -1;
+ s.cursor.y = myDoc->lastLine();
+ }
+ s.flags |= KateView::sfFinished;
+ s.flags &= ~KateView::sfAgain;
+}
+
+void KateView::findAgain(SConfig &s) {
+ int query;
+ PointStruc cursor;
+ QString str;
+
+ QString searchFor = myDoc->searchForList.first();
+
+ if( searchFor.isEmpty() ) {
+ find();
+ return;
+ }
+
+ do {
+ query = KMessageBox::Cancel;
+ if (myDoc->doSearch(s,searchFor)) {
+ cursor = s.cursor;
+ if (!(s.flags & KateView::sfBackward))
+ s.cursor.x += s.matchedLength;
+ myViewInternal->updateCursor(s.cursor); //does deselectAll()
+ exposeFound(cursor,s.matchedLength,(s.flags & KateView::sfAgain) ? 0 : KateView::ufUpdateOnScroll,false);
+ } else {
+ if (!(s.flags & KateView::sfFinished)) {
+ // ask for continue
+ if (!(s.flags & KateView::sfBackward)) {
+ // forward search
+ str = i18n("End of document reached.\n"
+ "Continue from the beginning?");
+ query = KMessageBox::warningContinueCancel(this,
+ str, i18n("Find"), i18n("Continue"));
+ } else {
+ // backward search
+ str = i18n("Beginning of document reached.\n"
+ "Continue from the end?");
+ query = KMessageBox::warningContinueCancel(this,
+ str, i18n("Find"), i18n("Continue"));
+ }
+ continueSearch(s);
+ } else {
+ // wrapped
+ KMessageBox::sorry(this,
+ i18n("Search string '%1' not found!").arg(searchFor),
+ i18n("Find"));
+ }
+ }
+ } while (query == KMessageBox::Continue);
+}
+
+void KateView::replaceAgain() {
+ if (isReadOnly())
+ return;
+
+ replaces = 0;
+ if (s.flags & KateView::sfPrompt) {
+ doReplaceAction(-1);
+ } else {
+ doReplaceAction(KateView::srAll);
+ }
+}
+
+void KateView::doReplaceAction(int result, bool found) {
+ int rlen;
+ PointStruc cursor;
+ bool started;
+
+ QString searchFor = myDoc->searchForList.first();
+ QString replaceWith = myDoc->replaceWithList.first();
+ rlen = replaceWith.length();
+
+ switch (result) {
+ case KateView::srYes: //yes
+ myDoc->recordStart(this, s.cursor, configFlags,
+ KateActionGroup::ugReplace, true);
+ myDoc->recordReplace(s.cursor, s.matchedLength, replaceWith);
+ replaces++;
+ if (s.cursor.y == s.startCursor.y && s.cursor.x < s.startCursor.x)
+ s.startCursor.x += rlen - s.matchedLength;
+ if (!(s.flags & KateView::sfBackward)) s.cursor.x += rlen;
+ myDoc->recordEnd(this, s.cursor, configFlags | KateView::cfPersistent);
+ break;
+ case KateView::srNo: //no
+ if (!(s.flags & KateView::sfBackward)) s.cursor.x += s.matchedLength;
+ break;
+ case KateView::srAll: //replace all
+ deleteReplacePrompt();
+ do {
+ started = false;
+ while (found || myDoc->doSearch(s,searchFor)) {
+ if (!started) {
+ found = false;
+ myDoc->recordStart(this, s.cursor, configFlags,
+ KateActionGroup::ugReplace);
+ started = true;
+ }
+ myDoc->recordReplace(s.cursor, s.matchedLength, replaceWith);
+ replaces++;
+ if (s.cursor.y == s.startCursor.y && s.cursor.x < s.startCursor.x)
+ s.startCursor.x += rlen - s.matchedLength;
+ if (!(s.flags & KateView::sfBackward)) s.cursor.x += rlen;
+ }
+ if (started) myDoc->recordEnd(this, s.cursor,
+ configFlags | KateView::cfPersistent);
+ } while (!askReplaceEnd());
+ return;
+ case KateView::srCancel: //cancel
+ deleteReplacePrompt();
+ return;
+ default:
+ replacePrompt = 0L;
+ }
+
+ do {
+ if (myDoc->doSearch(s,searchFor)) {
+ //text found: highlight it, show replace prompt if needed and exit
+ cursor = s.cursor;
+ if (!(s.flags & KateView::sfBackward)) cursor.x += s.matchedLength;
+ myViewInternal->updateCursor(cursor); //does deselectAll()
+ exposeFound(s.cursor,s.matchedLength,(s.flags & KateView::sfAgain) ? 0 : KateView::ufUpdateOnScroll,true);
+ if (replacePrompt == 0L) {
+ replacePrompt = new ReplacePrompt(this);
+ myDoc->setPseudoModal(replacePrompt);//disable();
+ connect(replacePrompt,SIGNAL(clicked()),this,SLOT(replaceSlot()));
+ replacePrompt->show(); //this is not modal
+ }
+ return; //exit if text found
+ }
+ //nothing found: repeat until user cancels "repeat from beginning" dialog
+ } while (!askReplaceEnd());
+ deleteReplacePrompt();
+}
+
+void KateView::exposeFound(PointStruc &cursor, int slen, int flags, bool replace) {
+ int x1, x2, y1, y2, xPos, yPos;
+
+ VConfig c;
+ myViewInternal->getVConfig(c);
+ myDoc->selectLength(cursor,slen,c.flags);
+
+ TextLine::Ptr textLine = myDoc->getTextLine(cursor.y);
+ x1 = myDoc->textWidth(textLine,cursor.x) -10;
+ x2 = myDoc->textWidth(textLine,cursor.x + slen) +20;
+ y1 = myDoc->fontHeight*cursor.y -10;
+ y2 = y1 + myDoc->fontHeight +30;
+
+ xPos = myViewInternal->xPos;
+ yPos = myViewInternal->yPos;
+
+ if (x1 < 0) x1 = 0;
+ if (replace) y2 += 90;
+
+ if (x1 < xPos || x2 > xPos + myViewInternal->width()) {
+ xPos = x2 - myViewInternal->width();
+ }
+ if (y1 < yPos || y2 > yPos + myViewInternal->height()) {
+ xPos = x2 - myViewInternal->width();
+ yPos = myDoc->fontHeight*cursor.y - height()/3;
+ }
+ myViewInternal->setPos(xPos, yPos);
+ myViewInternal->updateView(flags);// | ufPos,xPos,yPos);
+ myDoc->updateViews(this);
+}
+
+void KateView::deleteReplacePrompt() {
+ myDoc->setPseudoModal(0L);
+}
+
+bool KateView::askReplaceEnd() {
+ QString str;
+ int query;
+
+ myDoc->updateViews();
+ if (s.flags & KateView::sfFinished) {
+ // replace finished
+ str = i18n("%1 replacement(s) made").arg(replaces);
+ KMessageBox::information(this, str, i18n("Replace"));
+ return true;
+ }
+
+ // ask for continue
+ if (!(s.flags & KateView::sfBackward)) {
+ // forward search
+ str = i18n("%1 replacement(s) made.\n"
+ "End of document reached.\n"
+ "Continue from the beginning?").arg(replaces);
+ query = KMessageBox::questionYesNo(this, str, i18n("Replace"),
+ i18n("Continue"), i18n("Stop"));
+ } else {
+ // backward search
+ str = i18n("%1 replacement(s) made.\n"
+ "Beginning of document reached.\n"
+ "Continue from the end?").arg(replaces);
+ query = KMessageBox::questionYesNo(this, str, i18n("Replace"),
+ i18n("Continue"), i18n("Stop"));
+ }
+ replaces = 0;
+ continueSearch(s);
+ return (query == KMessageBox::No);
+}
+
+void KateView::replaceSlot() {
+ doReplaceAction(replacePrompt->result(),true);
+}
+
+void KateView::installPopup(QPopupMenu *rmb_Menu)
+{
+ rmbMenu = rmb_Menu;
+}
+
+void KateView::readConfig()
+{
+ KConfig *config = KGlobal::config();
+ config->setGroup("Kate View");
+
+ searchFlags = config->readNumEntry("SearchFlags", KateView::sfPrompt);
+ configFlags = config->readNumEntry("ConfigFlags", configFlags) & ~KateView::cfMark;
+
+ config->sync();
+}
+
+void KateView::writeConfig()
+{
+ KConfig *config = KGlobal::config();
+ config->setGroup("Kate View");
+
+ config->writeEntry("SearchFlags",searchFlags);
+ config->writeEntry("ConfigFlags",configFlags);
+
+ config->sync();
+}
+
+void KateView::readSessionConfig(KConfig *config)
+{
+ PointStruc cursor;
+
+ myViewInternal->xPos = config->readNumEntry("XPos");
+ myViewInternal->yPos = config->readNumEntry("YPos");
+ cursor.x = config->readNumEntry("CursorX");
+ cursor.y = config->readNumEntry("CursorY");
+ myViewInternal->updateCursor(cursor);
+ myIconBorder = config->readBoolEntry("IconBorder on");
+ setIconBorder(myIconBorder);
+}
+
+void KateView::writeSessionConfig(KConfig *config)
+{
+ config->writeEntry("XPos",myViewInternal->xPos);
+ config->writeEntry("YPos",myViewInternal->yPos);
+ config->writeEntry("CursorX",myViewInternal->cursor.x);
+ config->writeEntry("CursorY",myViewInternal->cursor.y);
+ config->writeEntry("IconBorder on", myIconBorder);
+}
+
+void KateView::configDialog()
+{
+
+#warning fixme
+
+#if 1
+ KDialogBase *kd = new KDialogBase(KDialogBase::IconList,
+ i18n("Configure Editor"),
+ KDialogBase::Ok | KDialogBase::Cancel |
+ KDialogBase::Help ,
+ KDialogBase::Ok, this, "tabdialog");
+
+ // color options
+ QFrame *page=kd->addPage(i18n("Colors"));
+ (new QVBoxLayout(page))->setAutoAdd(true);
+ ColorConfig *colorConfig = new ColorConfig(page);
+ QColor* colors = getColors();
+ colorConfig->setColors(colors);
+
+ page = kd->addPage(i18n("Fonts"));
+ (new QVBoxLayout(page))->setAutoAdd(true);
+
+ FontConfig *fontConfig = new FontConfig(page);
+ fontConfig->setFont (myDoc->getFont());
+
+ // indent options
+ page=kd->addPage(i18n("Indent"));
+ (new QVBoxLayout(page))->setAutoAdd(true);
+
+ IndentConfigTab *indentConfig = new IndentConfigTab(page, this);
+
+ // select options
+ page=kd->addPage(i18n("Select"));
+ (new QVBoxLayout(page))->setAutoAdd(true);
+
+ SelectConfigTab *selectConfig = new SelectConfigTab(page, this);
+
+ // edit options
+ page=kd->addPage(i18n("Edit"));
+ (new QVBoxLayout(page))->setAutoAdd(true);
+
+ EditConfigTab *editConfig = new EditConfigTab(page, this);
+
+
+
+ HighlightDialogPage *hlPage;
+ HlManager *hlManager;
+ HlDataList hlDataList;
+ ItemStyleList defaultStyleList;
+
+ hlManager = HlManager::self();
+
+ defaultStyleList.setAutoDelete(true);
+ hlManager->getDefaults(defaultStyleList);
+
+ hlDataList.setAutoDelete(true);
+ //this gets the data from the KConfig object
+ hlManager->getHlDataList(hlDataList);
+
+ page=kd->addPage(i18n("Highlighting"));
+ (new QVBoxLayout(page))->setAutoAdd(true);
+
+ hlPage = new HighlightDialogPage(hlManager, &defaultStyleList, &hlDataList, 0, page);
+
+ if (kd->exec()) {
+ // color options
+ colorConfig->getColors(colors);
+ myDoc->setFont (fontConfig->getFont());
+
+ applyColors();
+ // indent options
+ indentConfig->getData(this);
+ // select options
+ selectConfig->getData(this);
+ // edit options
+ editConfig->getData(this);
+ // spell checker
+ hlManager->setHlDataList(hlDataList);
+ hlManager->setDefaults(defaultStyleList);
+ hlPage->saveData();
+ }
+
+ delete kd;
+
+#endif
+}
+
+int KateView::getHl() {
+ return myDoc->highlightNum();
+}
+
+void KateView::setDontChangeHlOnSave()
+{
+ myDoc->setDontChangeHlOnSave();
+}
+
+void KateView::setHl(int n) {
+ myDoc->setHighlight(n);
+ myDoc->setDontChangeHlOnSave();
+ myDoc->updateViews();
+}
+
+int KateView::getEol() {
+ return myDoc->eolMode;
+}
+
+void KateView::setEol(int eol) {
+ if (isReadOnly())
+ return;
+
+ myDoc->eolMode = eol;
+ myDoc->setModified(true);
+}
+
+
+
+void KateView::paintEvent(QPaintEvent *e) {
+ int x, y;
+
+ QRect updateR = e->rect(); // update rectangle
+// debug("Update rect = ( %i, %i, %i, %i )",
+// updateR.x(),updateR.y(), updateR.width(), updateR.height() );
+
+ int ux1 = updateR.x();
+ int uy1 = updateR.y();
+ int ux2 = ux1 + updateR.width();
+ int uy2 = uy1 + updateR.height();
+
+ QPainter paint;
+ paint.begin(this);
+
+ QColorGroup g = colorGroup();
+ x = width();
+ y = height();
+
+ paint.setPen(g.dark());
+ if (uy1 <= 0) paint.drawLine(0,0,x-2,0);
+ if (ux1 <= 0) paint.drawLine(0,1,0,y-2);
+
+ paint.setPen(black);
+ if (uy1 <= 1) paint.drawLine(1,1,x-3,1);
+ if (ux1 <= 1) paint.drawLine(1,2,1,y-3);
+
+ paint.setPen(g.midlight());
+ if (uy2 >= y-1) paint.drawLine(1,y-2,x-3,y-2);
+ if (ux2 >= x-1) paint.drawLine(x-2,1,x-2,y-2);
+
+ paint.setPen(g.light());
+ if (uy2 >= y) paint.drawLine(0,y-1,x-2,y-1);
+ if (ux2 >= x) paint.drawLine(x-1,0,x-1,y-1);
+
+ x -= 2 + 16;
+ y -= 2 + 16;
+ if (ux2 > x && uy2 > y) {
+ paint.fillRect(x,y,16,16,g.background());
+ }
+ paint.end();
+}
+
+void KateView::resizeEvent(QResizeEvent *) {
+
+// debug("Resize %d, %d",e->size().width(),e->size().height());
+
+//myViewInternal->resize(width() -20, height() -20);
+ myViewInternal->tagAll();
+ myViewInternal->updateView(0/*ufNoScroll*/);
+}
+
+
+// Applies a new pattern to the search context.
+void SConfig::setPattern(QString &newPattern) {
+ bool regExp = (flags & KateView::sfRegularExpression);
+
+ m_pattern = newPattern;
+ if (regExp) {
+ m_regExp.setCaseSensitive(flags & KateView::sfCaseSensitive);
+ m_regExp.setPattern(m_pattern);
+ }
+}
+
+// Applies the search context to the given string, and returns whether a match was found. If one is,
+// the length of the string matched is also returned.
+int SConfig::search(QString &text, int index) {
+ bool regExp = (flags & KateView::sfRegularExpression);
+ bool caseSensitive = (flags & KateView::sfCaseSensitive);
+
+ if (flags & KateView::sfBackward) {
+ if (regExp) {
+ index = text.findRev(m_regExp, index);
+ }
+ else {
+ index = text.findRev(m_pattern, index, caseSensitive);
+ }
+ }
+ else {
+ if (regExp) {
+ index = text.find(m_regExp, index);
+ }
+ else {
+ index = text.find(m_pattern, index, caseSensitive);
+ }
+ }
+
+ // Work out the matched length.
+ if (index != -1)
+ {
+ if (regExp) {
+ m_regExp.match(text, index, &matchedLength, false);
+ }
+ else {
+ matchedLength = m_pattern.length();
+ }
+ }
+ return index;
+}
+
+void KateView::setActive (bool b)
+{
+ active = b;
+}
+
+bool KateView::isActive ()
+{
+ return active;
+}
+
+void KateView::setFocus ()
+{
+ QWidget::setFocus ();
+
+ emit gotFocus (this);
+}
+
+bool KateView::eventFilter (QObject *object, QEvent *event)
+{
+
+ if ( (event->type() == QEvent::FocusIn) )
+ emit gotFocus (this);
+
+ if ( (event->type() == QEvent::KeyPress) )
+ {
+ QKeyEvent * ke=(QKeyEvent *)event;
+
+ if ((ke->key()==Qt::Key_Tab) || (ke->key()==Qt::Key_BackTab))
+ {
+ myViewInternal->keyPressEvent(ke);
+ return true;
+ }
+ }
+ return QWidget::eventFilter (object, event);
+}
+
+void KateView::findAgain (bool back)
+{
+ bool b= (searchFlags & sfBackward) > 0;
+ initSearch(s, (searchFlags & ((b==back)?~sfBackward:~0) & ~sfFromBeginning) // clear flag for forward searching
+ | sfPrompt | sfAgain | ((b!=back)?sfBackward:0) );
+ if (s.flags & sfReplace)
+ replaceAgain();
+ else
+ KateView::findAgain(s);
+}
+
+void KateView::slotEditCommand ()
+{
+#warning fixme
+/*
+ bool ok;
+ QString cmd = KLineEditDlg::getText("Editing Command", "", &ok, this);
+
+ if (ok)
+ myDoc->cmd()->execCmd (cmd, this);*/
+}
+
+void KateView::setIconBorder (bool enable)
+{
+ myIconBorder = enable;
+
+ if (myIconBorder)
+ {
+ myViewInternal->move(myViewInternal->iconBorderWidth+2, 2);
+ myViewInternal->leftBorder->show();
+ }
+ else
+ {
+ myViewInternal->leftBorder->hide();
+ myViewInternal->move(2, 2);
+ }
+}
+
+void KateView::toggleIconBorder ()
+{
+ setIconBorder (!myIconBorder);
+}
+
+void KateView::gotoMark (Kate::Mark *mark)
+{
+ PointStruc cursor;
+
+ cursor.x = 0;
+ cursor.y = mark->line;
+ myDoc->needPreHighlight(cursor.y);
+ myViewInternal->updateCursor(cursor);
+ myViewInternal->center();
+ myViewInternal->updateView(KateView::ufUpdateOnScroll);
+ myDoc->updateViews(this);
+}
+
+void KateView::toggleBookmark ()
+{
+ TextLine::Ptr line = myDoc->getTextLine (currentLine());
+
+ if (line->mark()&KateDocument::Bookmark)
+ line->delMark(KateDocument::Bookmark);
+ else
+ line->addMark(KateDocument::Bookmark);
+
+ myDoc->tagLines (currentLine(), currentLine());
+ myDoc->updateViews();
+}
+
+void KateView::clearBookmarks()
+{
+ QList<Kate::Mark> list = myDoc->marks();
+ for (int i=0; (uint) i < list.count(); i++)
+ {
+ if (list.at(i)->type&KateDocument::Bookmark)
+ {
+ myDoc->getTextLine(list.at(i)->line)->delMark(KateDocument::Bookmark);
+ myDoc->tagLines(list.at(i)->line, list.at(i)->line);
+ }
+ }
+
+ myDoc->updateViews();
+}
+
+void KateView::bookmarkMenuAboutToShow()
+{
+#warning fixme
+#if 0
+ bookmarkMenu->popupMenu()->clear ();
+ bookmarkToggle->plug (bookmarkMenu->popupMenu());
+ bookmarkClear->plug (bookmarkMenu->popupMenu());
+ bookmarkMenu->popupMenu()->insertSeparator ();
+
+ list = myDoc->marks();
+ for (int i=0; (uint) i < list.count(); i++)
+ {
+ if (list.at(i)->type&KateDocument::Bookmark)
+ {
+ QString bText = textLine(list.at(i)->line);
+ bText.truncate(32);
+ bText.append ("...");
+ bookmarkMenu->popupMenu()->insertItem ( QString("%1 - \"%2\"").arg(list.at(i)->line).arg(bText), this, SLOT (gotoBookmark(int)), 0, i );
+ }
+ }
+#endif
+}
+
+void KateView::gotoBookmark (int n)
+{
+ gotoMark (list.at(n));
+}
+
+int KateView::getHlCount ()
+{
+ return HlManager::self()->highlights();
+}
+
+QString KateView::getHlName (int z)
+{
+ return HlManager::self()->hlName(z);
+}
+
+QString KateView::getHlSection (int z)
+{
+ return HlManager::self()->hlSection (z);
+}
+
+void KateView::slotIncFontSizes ()
+{
+ QFont font = myDoc->getFont();
+ font.setPointSize (font.pointSize()+2);
+ myDoc->setFont (font);
+}
+
+void KateView::slotDecFontSizes ()
+{
+ QFont font = myDoc->getFont();
+ font.setPointSize (font.pointSize()-2);
+ myDoc->setFont (font);
+}
+
+const char*bookmark_xpm[]={
+"12 16 4 1",
+"b c #808080",
+"a c #000080",
+"# c #0000ff",
+". c None",
+"............",
+"............",
+"........###.",
+".......#...a",
+"......#.##.a",
+".....#.#..aa",
+"....#.#...a.",
+"...#.#.a.a..",
+"..#.#.a.a...",
+".#.#.a.a....",
+"#.#.a.a.....",
+"#.#a.a...bbb",
+"#...a..bbb..",
+".aaa.bbb....",
+"............",
+"............"};
+
+const char* breakpoint_xpm[]={
+"11 16 6 1",
+"c c #c6c6c6",
+". c None",
+"# c #000000",
+"d c #840000",
+"a c #ffffff",
+"b c #ff0000",
+"...........",
+"...........",
+"...#####...",
+"..#aaaaa#..",
+".#abbbbbb#.",
+"#abbbbbbbb#",
+"#abcacacbd#",
+"#abbbbbbbb#",
+"#abcacacbd#",
+"#abbbbbbbb#",
+".#bbbbbbb#.",
+"..#bdbdb#..",
+"...#####...",
+"...........",
+"...........",
+"..........."};
+
+const char*breakpoint_bl_xpm[]={
+"11 16 7 1",
+"a c #c0c0ff",
+"# c #000000",
+"c c #0000c0",
+"e c #0000ff",
+"b c #dcdcdc",
+"d c #ffffff",
+". c None",
+"...........",
+"...........",
+"...#####...",
+"..#ababa#..",
+".#bcccccc#.",
+"#acccccccc#",
+"#bcadadace#",
+"#acccccccc#",
+"#bcadadace#",
+"#acccccccc#",
+".#ccccccc#.",
+"..#cecec#..",
+"...#####...",
+"...........",
+"...........",
+"..........."};
+
+const char*breakpoint_gr_xpm[]={
+"11 16 6 1",
+"c c #c6c6c6",
+"d c #2c2c2c",
+"# c #000000",
+". c None",
+"a c #ffffff",
+"b c #555555",
+"...........",
+"...........",
+"...#####...",
+"..#aaaaa#..",
+".#abbbbbb#.",
+"#abbbbbbbb#",
+"#abcacacbd#",
+"#abbbbbbbb#",
+"#abcacacbd#",
+"#abbbbbbbb#",
+".#bbbbbbb#.",
+"..#bdbdb#..",
+"...#####...",
+"...........",
+"...........",
+"..........."};
+
+const char*ddd_xpm[]={
+"11 16 4 1",
+"a c #00ff00",
+"b c #000000",
+". c None",
+"# c #00c000",
+"...........",
+"...........",
+"...........",
+"#a.........",
+"#aaa.......",
+"#aaaaa.....",
+"#aaaaaaa...",
+"#aaaaaaaaa.",
+"#aaaaaaa#b.",
+"#aaaaa#b...",
+"#aaa#b.....",
+"#a#b.......",
+"#b.........",
+"...........",
+"...........",
+"..........."};
+
+
+
+KateIconBorder::KateIconBorder(KateView *view, KateViewInternal *internalView)
+ : QWidget(view), myView(view), myInternalView(internalView)
+{
+ lmbSetsBreakpoints = true;
+}
+
+KateIconBorder::~KateIconBorder()
+{
+}
+
+void KateIconBorder::paintLine(int i)
+{
+ if (!myView->myIconBorder) return;
+
+ QPainter p(this);
+
+ int fontHeight = myView->doc()->fontHeight;
+ int y = i*fontHeight - myInternalView->yPos;
+ p.fillRect(0, y, myInternalView->iconBorderWidth-2, fontHeight, colorGroup().background());
+ p.setPen(white);
+ p.drawLine(myInternalView->iconBorderWidth-2, y, myInternalView->iconBorderWidth-2, y + fontHeight);
+ p.setPen(QColor(colorGroup().background()).dark());
+ p.drawLine(myInternalView->iconBorderWidth-1, y, myInternalView->iconBorderWidth-1, y + fontHeight);
+
+ TextLine *line = myView->doc()->getTextLine(i);
+ if (!line)
+ return;
+
+ if (line->mark()&KateDocument::Bookmark)
+ p.drawPixmap(2, y, QPixmap(bookmark_xpm)); /*
+ if (line && (line->breakpointId() != -1)) {
+ if (!line->breakpointEnabled())
+ p.drawPixmap(2, y, QPixmap(breakpoint_gr_xpm));
+ else if (line->breakpointPending())
+ p.drawPixmap(2, y, QPixmap(breakpoint_bl_xpm));
+ else
+ p.drawPixmap(2, y, QPixmap(breakpoint_xpm));
+ }
+ if (line->isExecutionPoint())
+ p.drawPixmap(2, y, QPixmap(ddd_xpm)); */
+}
+
+
+void KateIconBorder::paintEvent(QPaintEvent* e)
+{
+ if (!myView->myIconBorder) return;
+
+ int lineStart = 0;
+ int lineEnd = 0;
+
+ QRect updateR = e->rect();
+
+ KateDocument *doc = myView->doc();
+ int h = doc->fontHeight;
+ int yPos = myInternalView->yPos;
+ if (h) {
+ lineStart = (yPos + updateR.y()) / h;
+ lineEnd = QMAX((yPos + updateR.y() + updateR.height()) / h, (int)doc->numLines());
+ }
+
+ for(int i = lineStart; i <= lineEnd; ++i)
+ paintLine(i);
+}
+
+
+void KateIconBorder::mousePressEvent(QMouseEvent* e)
+{
+ myInternalView->placeCursor( 0, e->y(), 0 );
+
+ KateDocument *doc = myView->doc();
+ int cursorOnLine = (e->y() + myInternalView->yPos) / doc->fontHeight;
+ TextLine *line = doc->getTextLine(cursorOnLine);
+
+ switch (e->button()) {
+ case LeftButton:
+ if (!line)
+ break;
+ else
+ {
+ if (line->mark()&KateDocument::Bookmark)
+ line->delMark (KateDocument::Bookmark);
+ else
+ line->addMark (KateDocument::Bookmark);
+
+ doc->tagLines(cursorOnLine, cursorOnLine);
+ doc->updateViews();
+ }
+ break;
+ /* case RightButton:
+ {
+ if (!line)
+ break;
+ KPopupMenu popup;
+ popup.setCheckable(true);
+ popup.insertTitle(i18n("Breakpoints/Bookmarks"));
+ int idToggleBookmark = popup.insertItem(i18n("Toggle bookmark"));
+ popup.insertSeparator();
+ int idToggleBreakpoint = popup.insertItem(i18n("Toggle breakpoint"));
+ int idEditBreakpoint = popup.insertItem(i18n("Edit breakpoint"));
+ int idEnableBreakpoint = popup.insertItem(i18n("Disable breakpoint"));
+ popup.insertSeparator();
+ popup.insertSeparator();
+ int idLmbSetsBreakpoints = popup.insertItem(i18n("LMB sets breakpoints"));
+ int idLmbSetsBookmarks = popup.insertItem(i18n("LMB sets bookmarks"));
+
+ popup.setItemChecked(idLmbSetsBreakpoints, lmbSetsBreakpoints);
+ popup.setItemChecked(idLmbSetsBookmarks, !lmbSetsBreakpoints);
+
+ if (line->breakpointId() == -1) {
+ popup.setItemEnabled(idEditBreakpoint, false);
+ popup.setItemEnabled(idEnableBreakpoint, false);
+ popup.changeItem(idEnableBreakpoint, i18n("Enable breakpoint"));
+ }
+ int res = popup.exec(mapToGlobal(e->pos()));
+ if (res == idToggleBookmark) {
+ line->toggleBookmark();
+ doc->tagLines(cursorOnLine, cursorOnLine);
+ doc->updateViews();
+ } else if (res == idToggleBreakpoint)
+ emit myView->toggledBreakpoint(cursorOnLine);
+ else if (res == idEditBreakpoint)
+ emit myView->editedBreakpoint(cursorOnLine);
+ else if (res == idEnableBreakpoint)
+ emit myView->toggledBreakpointEnabled(cursorOnLine+1);
+ else if (res == idLmbSetsBreakpoints || res == idLmbSetsBookmarks)
+ lmbSetsBreakpoints = !lmbSetsBreakpoints;
+ break;
+ }
+ case MidButton:
+ line->toggleBookmark();
+ doc->tagLines(cursorOnLine, cursorOnLine);
+ doc->updateViews();
+ break; */
+ default:
+ break;
+ }
+}
+
+
+
diff --git a/noncore/apps/tinykate/libkate/view/kateview.h b/noncore/apps/tinykate/libkate/view/kateview.h
new file mode 100644
index 0000000..2e78a3a
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/view/kateview.h
@@ -0,0 +1,865 @@
+/***************************************************************************
+ kateview.h - description
+ -------------------
+ begin : Mon Jan 15 2001
+ copyright : (C) 2001 by Christoph "Crossfire" Cullmann
+ (C) 2002 by Joseph Wenninger
+ email : crossfire@babylon2k.de
+ jowenn@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+/*
+ Copyright (C) 1998, 1999 Jochen Wilhelmy
+ digisnap@cs.tu-berlin.de
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef kate_view_h
+#define kate_view_h
+
+#include "../interfaces/view.h"
+#include "../interfaces/document.h"
+
+#include <qlist.h>
+#include <qstring.h>
+#include <qdialog.h>
+
+
+class KateDocument;
+class Highlight;
+
+/*
+//dialog results
+const int srYes = QDialog::Accepted;
+const int srNo = 10;
+const int srAll = 11;
+const int srCancel = QDialog::Rejected;
+*/
+// --- config flags ---
+// indent
+
+enum Select_flags {
+ selectFlag = 0x100000,
+ multiSelectFlag = 0x200000
+};
+//state commands
+enum State_commands {
+ cmToggleInsert = 1,
+ cmToggleVertical = 2
+};
+
+class KateViewInternal;
+class KateView;
+
+struct PointStruc {
+ int x;
+ int y;
+};
+
+struct VConfig {
+ KateView *view;
+ PointStruc cursor;
+ int cXPos;
+ int flags;
+};
+
+struct SConfig {
+ PointStruc cursor;
+ PointStruc startCursor;
+ int flags;
+
+ // Set the pattern to be used for searching.
+ void setPattern(QString &newPattern);
+
+ // Search the given string.
+ int search(QString &text, int index);
+
+ // The length of the last match found using pattern or regExp.
+ int matchedLength;
+
+private:
+ QString m_pattern;
+
+ // The regular expression corresponding to pattern. Only guaranteed valid if
+ // flags has sfRegularExpression set.
+ QRegExp m_regExp;
+};
+
+struct LineRange {
+ int start;
+ int end;
+};
+
+struct BracketMark {
+ PointStruc cursor;
+ int sXPos;
+ int eXPos;
+};
+
+
+class KateIconBorder : public QWidget
+{
+public:
+ KateIconBorder(KateView *view, class KateViewInternal *internalView);
+ ~KateIconBorder();
+
+ void paintLine(int i);
+
+protected:
+ void paintEvent(QPaintEvent* e);
+ void mousePressEvent(QMouseEvent* e);
+
+private:
+
+ KateView *myView;
+ class KateViewInternal *myInternalView;
+ bool lmbSetsBreakpoints;
+};
+
+class KateViewInternal : public QWidget {
+ Q_OBJECT
+ friend class KateDocument;
+ friend class KateView;
+ friend class KateIconBorder;
+
+ private:
+ long waitForPreHighlight;
+ int iconBorderWidth;
+ int iconBorderHeight;
+
+ protected slots:
+ void slotPreHighlightUpdate(long line);
+
+ public:
+ KateViewInternal(KateView *view, KateDocument *doc);
+ ~KateViewInternal();
+
+ virtual void doCursorCommand(VConfig &, int cmdNum);
+ virtual void doEditCommand(VConfig &, int cmdNum);
+
+ void cursorLeft(VConfig &);
+ void cursorRight(VConfig &);
+ void wordLeft(VConfig &);
+ void wordRight(VConfig &);
+ void home(VConfig &);
+ void end(VConfig &);
+ void cursorUp(VConfig &);
+ void cursorDown(VConfig &);
+ void scrollUp(VConfig &);
+ void scrollDown(VConfig &);
+ void topOfView(VConfig &);
+ void bottomOfView(VConfig &);
+ void pageUp(VConfig &);
+ void pageDown(VConfig &);
+ void cursorPageUp(VConfig &);
+ void cursorPageDown(VConfig &);
+ void top(VConfig &);
+ void bottom(VConfig &);
+ void top_home(VConfig &c);
+ void bottom_end(VConfig &c);
+
+ protected slots:
+ void changeXPos(int);
+ void changeYPos(int);
+
+ protected:
+ void getVConfig(VConfig &);
+ void changeState(VConfig &);
+ void insLine(int line);
+ void delLine(int line);
+ void updateCursor();
+ void updateCursor(PointStruc &newCursor);
+ void updateCursor(PointStruc &newCursor, int flags);
+ void clearDirtyCache(int height);
+ void tagLines(int start, int end, int x1, int x2);
+ void tagAll();
+ void setPos(int x, int y);
+ void center();
+
+ void updateView(int flags);
+
+ void paintTextLines(int xPos, int yPos);
+ void paintCursor();
+ void paintBracketMark();
+
+ void placeCursor(int x, int y, int flags = 0);
+ bool isTargetSelected(int x, int y);
+
+// void doDrag();
+
+ virtual void focusInEvent(QFocusEvent *);
+ virtual void focusOutEvent(QFocusEvent *);
+ virtual void keyPressEvent(QKeyEvent *e);
+ virtual void mousePressEvent(QMouseEvent *);
+ virtual void mouseDoubleClickEvent(QMouseEvent *);
+ virtual void mouseReleaseEvent(QMouseEvent *);
+ virtual void mouseMoveEvent(QMouseEvent *);
+ virtual void wheelEvent( QWheelEvent *e );
+ virtual void paintEvent(QPaintEvent *);
+ virtual void resizeEvent(QResizeEvent *);
+ virtual void timerEvent(QTimerEvent *);
+
+
+ KateView *myView;
+ KateDocument *myDoc;
+ QScrollBar *xScroll;
+ QScrollBar *yScroll;
+ KateIconBorder *leftBorder;
+
+ int xPos;
+ int yPos;
+
+ int mouseX;
+ int mouseY;
+ int scrollX;
+ int scrollY;
+ int scrollTimer;
+
+ PointStruc cursor;
+ bool cursorOn;
+ int cursorTimer;
+ int cXPos;
+ int cOldXPos;
+
+ int startLine;
+ int endLine;
+
+ bool exposeCursor;
+ int updateState;
+ int numLines;
+ LineRange *lineRanges;
+ int newXPos;
+ int newYPos;
+
+ QPixmap *drawBuffer;
+
+ BracketMark bm;
+
+};
+
+/**
+ The KateView text editor widget. It has many options, document/view
+ architecture and syntax highlight.
+ @author Jochen Wilhelmy
+*/
+
+class KateView : public Kate::View
+{
+ Q_OBJECT
+ friend class KateViewInternal;
+ friend class KateDocument;
+ friend class KateIconBorder;
+
+ public:
+ KateView(KateDocument *doc=0L, QWidget *parent = 0L, const char * name = 0);
+ ~KateView();
+
+ virtual void setCursorPosition( int line, int col, bool mark = false );
+ virtual void getCursorPosition( int *line, int *col );
+
+ virtual bool isOverwriteMode() const;
+ virtual void setOverwriteMode( bool b );
+
+//status and config functions
+ /**
+ Returns the current line number, that is the line the cursor is on.
+ For the first line it returns 0. Signal newCurPos() is emitted on
+ cursor position changes.
+ */
+ int currentLine();
+ /**
+ Returns the current column number. It handles tab's correctly.
+ For the first column it returns 0.
+ */
+ int currentColumn();
+ /**
+ Returns the number of the character, that the cursor is on (cursor x)
+ */
+ int currentCharNum();
+ /**
+ Sets the current cursor position
+ */
+ void setCursorPositionInternal(int line, int col);
+ /**
+ Returns the config flags. See the cfXXX constants in the .h file.
+ */
+ int config();// {return configFlags;}
+ /**
+ Sets the config flags
+ */
+ void setConfig(int);
+
+ int tabWidth();
+ void setTabWidth(int);
+ void setEncoding (QString e);
+ int undoSteps();
+ void setUndoSteps(int);
+
+ // bool isOverwriteMode();
+ /**
+ Returns true if the document is in read only mode.
+ */
+ bool isReadOnly();
+ /**
+ Returns true if the document has been modified.
+ */
+ bool isModified();
+ /**
+ Sets the read-only flag of the document
+ */
+ void setReadOnly(bool);
+ /**
+ Sets the modification status of the document
+ */
+ void setModified(bool m = true);
+ /**
+ Returns true if this editor is the only owner of its document
+ */
+ bool isLastView();
+ /**
+ Returns the document object
+ */
+ KateDocument *doc();
+
+ /*
+ Bit 0 : undo possible, Bit 1 : redo possible.
+ Used to enable/disable undo/redo menu items and toolbar buttons
+ */
+ int undoState();
+ /**
+ Returns the type of the next undo group.
+ */
+ int nextUndoType();
+ /**
+ Returns the type of the next redo group.
+ */
+ int nextRedoType();
+ /**
+ Returns a list of all available undo types, in undo order.
+ */
+ void undoTypeList(QValueList<int> &lst);
+ /**
+ Returns a list of all available redo types, in redo order.
+ */
+ void redoTypeList(QValueList<int> &lst);
+ /**
+ Returns a short text description of the given undo type,
+ which is obtained with nextUndoType(), nextRedoType(), undoTypeList(), and redoTypeList(),
+ suitable for display in a menu entry. It is not translated;
+ use i18n() before displaying this string.
+ */
+ const char * undoTypeName(int undoType);
+
+ QColor* getColors();
+ void applyColors();
+
+
+ public slots:
+ void slotUpdate();
+ void slotFileStatusChanged();
+ void slotNewUndo();
+ void slotHighlightChanged();
+
+ public slots:
+ /**
+ Toggles Insert mode
+ */
+ void toggleInsert();
+ /**
+ Toggles "Vertical Selections" option
+ */
+ void toggleVertical();
+ signals:
+ /**
+ The cursor position has changed. Get the values with currentLine()
+ and currentColumn()
+ */
+ void newCurPos();
+ /**
+ Modified flag or config flags have changed
+ */
+ void newStatus();
+ /**
+ The undo/redo enable status has changed
+ */
+ void newUndo();
+ /**
+ The marked text state has changed. This can be used to enable/disable
+ cut and copy
+ */
+ void newMarkStatus();
+
+ // emitted when saving a remote URL with KIO::NetAccess. In that case we have to disable the UI.
+ void enableUI( bool enable );
+
+ protected:
+ virtual void keyPressEvent( QKeyEvent *ev );
+
+ int configFlags;
+
+ /*
+ * Check if the given URL already exists. Currently used by both save() and saveAs()
+ *
+ * Asks the user for permission and returns the message box result and defaults to
+ * KMessageBox::Yes in case of doubt
+ */
+
+//text access
+ public:
+ /**
+ Gets the number of text lines;
+ */
+ int numLines();
+ /**
+ Gets the complete document content as string
+ */
+ QString text();
+ /**
+ Gets the text line where the cursor is on
+ */
+ QString currentTextLine();
+ /**
+ Gets a text line
+ */
+ QString textLine(int num);
+ /**
+ Gets the word where the cursor is on
+ */
+ QString currentWord();
+ /**
+ Gets the word at position x, y. Can be used to find
+ the word under the mouse cursor
+ */
+ QString word(int x, int y);
+ /**
+ Discard old text without warning and set new text
+ */
+ void setText(const QString &);
+ /**
+ Insert text at the current cursor position. If length is a positive
+ number, it restricts the number of inserted characters
+ */
+ virtual void insertText(const QString &, bool mark = false);
+ /**
+ Queries if there is marked text
+ */
+ bool hasMarkedText();
+ /**
+ Gets the marked text as string
+ */
+ QString markedText();
+
+ public:
+ enum fileResult { OK, CANCEL, RETRY, ERROR };
+
+ /**
+ Returns true if the current document can be
+ discarded. If the document is modified, the user is asked if he wants
+ to save it. On "cancel" the function returns false.
+ */
+ bool canDiscard();
+
+ public slots:
+ /**
+ Flushes the document of the text widget. The user is given
+ a chance to save the current document if the current document has
+ been modified.
+ */
+ void flush ();
+ /**
+ Saves the file if necessary under the current file name. If the current file
+ name is Untitled, as it is after a call to newFile(), this routing will
+ call saveAs().
+ */
+ fileResult save();
+ /**
+ Allows the user to save the file under a new name. This starts the
+ automatic highlight selection.
+ */
+ fileResult saveAs();
+ /**
+ Moves the marked text into the clipboard
+ */
+ void cut() {doEditCommand(KateView::cmCut);}
+ /**
+ Copies the marked text into the clipboard
+ */
+ void copy() {doEditCommand(KateView::cmCopy);}
+ /**
+ Inserts text from the clipboard at the actual cursor position
+ */
+ void paste() {doEditCommand(KateView::cmPaste);}
+ /**
+ Undoes the last operation. The number of undo steps is configurable
+ */
+ void undo() {doEditCommand(KateView::cmUndo);}
+ /**
+ Repeats an operation which has been undone before.
+ */
+ void redo() {doEditCommand(KateView::cmRedo);}
+ /**
+ Undoes <count> operations.
+ Called by slot undo().
+ */
+ void undoMultiple(int count);
+ /**
+ Repeats <count> operation which have been undone before.
+ Called by slot redo().
+ */
+ void redoMultiple(int count);
+ /**
+ Displays the undo history dialog
+ */
+ void undoHistory();
+ /**
+ Moves the current line or the selection one position to the right
+ */
+ void indent() {doEditCommand(KateView::cmIndent);};
+ /**
+ Moves the current line or the selection one position to the left
+ */
+ void unIndent() {doEditCommand(KateView::cmUnindent);};
+ /**
+ Optimizes the selected indentation, replacing tabs and spaces as needed
+ */
+ void cleanIndent() {doEditCommand(KateView::cmCleanIndent);};
+ /**
+ Selects all text
+ */
+ void selectAll() {doEditCommand(KateView::cmSelectAll);}
+ /**
+ Deselects all text
+ */
+ void deselectAll() {doEditCommand(KateView::cmDeselectAll);}
+ /**
+ Inverts the current selection
+ */
+ void invertSelection() {doEditCommand(KateView::cmInvertSelection);}
+ /**
+ comments out current line
+ */
+ void comment() {doEditCommand(KateView::cmComment);};
+ /**
+ removes comment signs in the current line
+ */
+ void uncomment() {doEditCommand(KateView::cmUncomment);};
+
+ void keyReturn() {doEditCommand(KateView::cmReturn);};
+ void keyDelete() {doEditCommand(KateView::cmDelete);};
+ void backspace() {doEditCommand(KateView::cmBackspace);};
+ void killLine() {doEditCommand(KateView::cmKillLine);};
+
+// cursor commands...
+
+ void cursorLeft() {doCursorCommand(KateView::cmLeft);};
+ void shiftCursorLeft() {doCursorCommand(KateView::cmLeft | selectFlag);};
+ void cursorRight() {doCursorCommand(KateView::cmRight);}
+ void shiftCursorRight() {doCursorCommand(KateView::cmRight | selectFlag);}
+ void wordLeft() {doCursorCommand(KateView::cmWordLeft);};
+ void shiftWordLeft() {doCursorCommand(KateView::cmWordLeft | selectFlag);};
+ void wordRight() {doCursorCommand(KateView::cmWordRight);};
+ void shiftWordRight() {doCursorCommand(KateView::cmWordRight | selectFlag);};
+ void home() {doCursorCommand(KateView::cmHome);};
+ void shiftHome() {doCursorCommand(KateView::cmHome | selectFlag);};
+ void end() {doCursorCommand(KateView::cmEnd);};
+ void shiftEnd() {doCursorCommand(KateView::cmEnd | selectFlag);};
+ void up() {doCursorCommand(KateView::cmUp);};
+ void shiftUp() {doCursorCommand(KateView::cmUp | selectFlag);};
+ void down() {doCursorCommand(KateView::cmDown);};
+ void shiftDown() {doCursorCommand(KateView::cmDown | selectFlag);};
+ void scrollUp() {doCursorCommand(KateView::cmScrollUp);};
+ void scrollDown() {doCursorCommand(KateView::cmScrollDown);};
+ void topOfView() {doCursorCommand(KateView::cmTopOfView);};
+ void bottomOfView() {doCursorCommand(KateView::cmBottomOfView);};
+ void pageUp() {doCursorCommand(KateView::cmPageUp);};
+ void shiftPageUp() {doCursorCommand(KateView::cmPageUp | selectFlag);};
+ void pageDown() {doCursorCommand(KateView::cmPageDown);};
+ void shiftPageDown() {doCursorCommand(KateView::cmPageDown | selectFlag);};
+ void top() {doCursorCommand(KateView::cmTop);};
+ void shiftTop() {doCursorCommand(KateView::cmTop | selectFlag);};
+ void bottom() {doCursorCommand(KateView::cmBottom);};
+ void shiftBottom() {doCursorCommand(KateView::cmBottom | selectFlag);};
+
+//search/replace functions
+ public slots:
+ /**
+ Presents a search dialog to the user
+ */
+ void find();
+ /**
+ Presents a replace dialog to the user
+ */
+ void replace();
+
+ /**
+ Presents a "Goto Line" dialog to the user
+ */
+ void gotoLine();
+ protected:
+ void initSearch(SConfig &, int flags);
+ void continueSearch(SConfig &);
+ void findAgain(SConfig &);
+ void replaceAgain();
+ void doReplaceAction(int result, bool found = false);
+ void exposeFound(PointStruc &cursor, int slen, int flags, bool replace);
+ void deleteReplacePrompt();
+ bool askReplaceEnd();
+ protected slots:
+ void replaceSlot();
+ protected:
+ int searchFlags;
+ int replaces;
+ SConfig s;
+ QDialog *replacePrompt;
+
+//right mouse button popup menu & bookmark menu
+ public:
+ /**
+ Install a Popup Menu. The Popup Menu will be activated on
+ a right mouse button press event.
+ */
+ void installPopup(QPopupMenu *rmb_Menu);
+
+ protected:
+ QPopupMenu *rmbMenu;
+
+ signals:
+ void bookAddChanged(bool enabled);
+ void bookClearChanged(bool enabled);
+
+//config file / session management functions
+ public:
+ /**
+ Reads config entries
+ */
+ void readConfig();
+ /**
+ Writes config entries i
+ */
+ void writeConfig();
+ /**
+ Reads session config out of the KConfig object. This also includes
+ the actual cursor position and the bookmarks.
+ */
+ void readSessionConfig(KConfig *);
+ /**
+ Writes session config into the KConfig object
+ */
+ void writeSessionConfig(KConfig *);
+
+
+ public:
+ void setDontChangeHlOnSave();
+
+
+ // syntax highlight
+ public slots:
+ /**
+ Presents the setup dialog to the user
+ */
+ void configDialog ();
+ /**
+ Gets the highlight number
+ */
+ int getHl();
+ /**
+ Sets the highlight number n
+ */
+ void setHl(int n);
+ /**
+ Get the end of line mode (Unix, Macintosh or Dos)
+ */
+ int getEol();
+ /**
+ Set the end of line mode (Unix, Macintosh or Dos)
+ */
+ void setEol(int);
+
+//internal
+ protected:
+ virtual void paintEvent(QPaintEvent *);
+ virtual void resizeEvent(QResizeEvent *);
+
+ void doCursorCommand(int cmdNum);
+ void doEditCommand(int cmdNum);
+
+ KateViewInternal *myViewInternal;
+ KateDocument *myDoc;
+
+
+ // some kwriteview stuff
+ protected:
+ void insLine(int line) { myViewInternal->insLine(line); };
+ void delLine(int line) { myViewInternal->delLine(line); };
+ void updateCursor() { myViewInternal->updateCursor(); };
+ void updateCursor(PointStruc &newCursor) { myViewInternal->updateCursor(newCursor); };
+ void updateCursor(PointStruc &newCursor, int flags) { myViewInternal->updateCursor(newCursor, flags); };
+
+ void clearDirtyCache(int height) { myViewInternal->clearDirtyCache(height); };
+ void tagLines(int start, int end, int x1, int x2) { myViewInternal->tagLines(start, end, x1, x2); };
+ void tagAll() { myViewInternal->tagAll(); };
+ void setPos(int x, int y) { myViewInternal->setPos(x, y); };
+ void center() { myViewInternal->center(); };
+
+ void updateView(int flags) { myViewInternal->updateView(flags); };
+
+
+
+ public:
+ enum Config_flags {
+ cfAutoIndent= 0x1,
+ cfBackspaceIndents= 0x2,
+ cfWordWrap= 0x4,
+ cfReplaceTabs= 0x8,
+ cfRemoveSpaces = 0x10,
+ cfWrapCursor= 0x20,
+ cfAutoBrackets= 0x40,
+ cfPersistent= 0x80,
+ cfKeepSelection= 0x100,
+ cfVerticalSelect= 0x200,
+ cfDelOnInput= 0x400,
+ cfXorSelect= 0x800,
+ cfOvr= 0x1000,
+ cfMark= 0x2000,
+ cfGroupUndo= 0x4000,
+ cfKeepIndentProfile= 0x8000,
+ cfKeepExtraSpaces= 0x10000,
+ cfMouseAutoCopy= 0x20000,
+ cfSingleSelection= 0x40000,
+ cfTabIndents= 0x80000,
+ cfPageUDMovesCursor= 0x100000,
+ cfShowTabs= 0x200000,
+ cfSpaceIndent= 0x400000,
+ cfSmartHome = 0x800000};
+
+ enum Dialog_results {
+ srYes=QDialog::Accepted,
+ srNo=10,
+ srAll,
+ srCancel=QDialog::Rejected};
+
+//search flags
+ enum Search_flags {
+ sfCaseSensitive=1,
+ sfWholeWords=2,
+ sfFromBeginning=4,
+ sfBackward=8,
+ sfSelected=16,
+ sfPrompt=32,
+ sfReplace=64,
+ sfAgain=128,
+ sfWrapped=256,
+ sfFinished=512,
+ sfRegularExpression=1024};
+
+//update flags
+ enum Update_flags {
+ ufDocGeometry=1,
+ ufUpdateOnScroll=2,
+ ufPos=4};
+
+//load flags
+ enum Load_flags {
+ lfInsert=1,
+ lfNewFile=2,
+ lfNoAutoHl=4};
+
+//cursor movement commands
+ enum Cursor_commands
+ { cmLeft,cmRight,cmWordLeft,cmWordRight,
+ cmHome,cmEnd,cmUp,cmDown,
+ cmScrollUp,cmScrollDown,cmTopOfView,cmBottomOfView,
+ cmPageUp,cmPageDown,cmCursorPageUp,cmCursorPageDown,
+ cmTop,cmBottom};
+//edit commands
+ enum Edit_commands {
+ cmReturn=1,cmDelete,cmBackspace,cmKillLine,cmUndo,
+ cmRedo,cmCut,cmCopy,cmPaste,cmIndent,cmUnindent,cmCleanIndent,
+ cmSelectAll,cmDeselectAll,cmInvertSelection,cmComment,
+ cmUncomment};
+//find commands
+ enum Find_commands { cmFind=1,cmReplace,cmFindAgain,cmGotoLine};
+
+ public:
+ void setActive (bool b);
+ bool isActive ();
+
+ private:
+ bool active;
+ bool myIconBorder;
+ QList<Kate::Mark> list;
+
+ public slots:
+ virtual void setFocus ();
+ void findAgain(bool back=false);
+ void findAgain () { findAgain(false); };
+ void findPrev () { findAgain(true); };
+
+ protected:
+ bool eventFilter(QObject* o, QEvent* e);
+
+ signals:
+ void gotFocus (KateView *);
+
+ public slots:
+ void slotEditCommand ();
+ void setIconBorder (bool enable);
+ void toggleIconBorder ();
+ void gotoMark (Kate::Mark *mark);
+ void toggleBookmark ();
+ void clearBookmarks ();
+
+ public:
+ bool iconBorder() { return myIconBorder; } ;
+
+ private slots:
+ void bookmarkMenuAboutToShow();
+ void gotoBookmark (int n);
+
+ public:
+ Kate::Document *getDoc ()
+ { return (Kate::Document*) myDoc; };
+
+ public slots:
+ int getHlCount ();
+ QString getHlName (int);
+ QString getHlSection (int);
+
+ void slotIncFontSizes ();
+ void slotDecFontSizes ();
+
+ protected:
+ uint myViewID;
+ static uint uniqueID;
+};
+
+#endif
+
+
+
+
+
+
diff --git a/noncore/apps/tinykate/libkate/view/kateviewdialog.cpp b/noncore/apps/tinykate/libkate/view/kateviewdialog.cpp
new file mode 100644
index 0000000..a311042
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/view/kateviewdialog.cpp
@@ -0,0 +1,556 @@
+/***************************************************************************
+ kateviewdialog.cpp - description
+ -------------------
+ copyright : (C) 2001 by The Kate Team
+ (C) 2002 by Joseph Wenninger
+ email : kwrite-devel@kde.org
+ jowenn@kde.org
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+// Dialogs
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <qgrid.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlistbox.h>
+#include <qspinbox.h>
+#include <qcombobox.h>
+#include <qgroupbox.h>
+#include <qlineedit.h>
+#include <qcheckbox.h>
+#include <qcollection.h>
+#include <qpushbutton.h>
+#include <qobjectlist.h>
+#include <qradiobutton.h>
+#include <qwhatsthis.h>
+#include <qstringlist.h>
+#include <klocale.h>
+#include <kcolorbtn.h>
+#include <qcombobox.h>
+#include <kglobal.h>
+#include <qvbox.h>
+#include <qspinbox.h>
+#include <kfontdialog.h>
+
+#include "../document/katedocument.h"
+#include "kateviewdialog.h"
+
+SearchDialog::SearchDialog( QWidget *parent, QStringList &searchFor, QStringList &replaceWith, int flags )
+ : KDialogBase( parent, 0L, true, i18n( "Find Text" ), Ok | Cancel, Ok )
+ , m_replace( 0L )
+{
+ QWidget *page = new QWidget( this );
+ setMainWidget( page );
+
+ QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
+
+ m_search = new QComboBox( true, page );
+ m_search->insertStringList( searchFor );
+ m_search->setMinimumWidth( m_search->sizeHint().width() );
+ m_search->lineEdit()->selectAll();
+ QLabel *label = new QLabel( m_search, i18n( "&Text To Find:" ), page );
+ m_optRegExp = new QCheckBox( i18n( "Regular Expression" ), page );
+ topLayout->addWidget( label );
+ topLayout->addWidget( m_search );
+ topLayout->addWidget( m_optRegExp );
+
+ if( flags & KateView::sfReplace )
+ {
+ // make it a replace dialog
+ setCaption( i18n( "Replace Text" ) );
+ m_replace = new QComboBox( true, page );
+ m_replace->insertStringList( replaceWith );
+ m_replace->setMinimumWidth( m_search->sizeHint().width() );
+ label = new QLabel( m_replace, i18n( "&Replace With:" ), page );
+ //m_optPlaceholders = new QCheckBox( i18n( "&Use Placeholders" ), page );
+ topLayout->addWidget( label );
+ topLayout->addWidget( m_replace );
+ //topLayout->addWidget( m_optPlaceholders );
+ }
+
+ QGroupBox *group = new QGroupBox( i18n( "Options" ), page );
+ topLayout->addWidget( group, 10 );
+
+ QGridLayout *gbox = new QGridLayout( group, 5, 2, spacingHint() );
+ gbox->addRowSpacing( 0, fontMetrics().lineSpacing() );
+ gbox->setRowStretch( 4, 10 );
+
+ m_opt1 = new QCheckBox( i18n( "C&ase Sensitive" ), group );
+ gbox->addWidget( m_opt1, 1, 0 );
+
+ m_opt2 = new QCheckBox(i18n("&Whole Words Only" ), group );
+ gbox->addWidget( m_opt2, 2, 0 );
+
+ m_opt3 = new QCheckBox(i18n("&From Beginning" ), group );
+ gbox->addWidget( m_opt3, 3, 0 );
+
+ m_opt4 = new QCheckBox(i18n("Find &Backwards" ), group );
+ gbox->addWidget( m_opt4, 1, 1 );
+
+ m_opt5 = new QCheckBox(i18n("&Selected Text" ), group );
+ gbox->addWidget( m_opt5, 2, 1 );
+
+ m_opt1->setChecked( flags & KateView::sfCaseSensitive );
+ m_opt2->setChecked( flags & KateView::sfWholeWords );
+ m_opt3->setChecked( flags & KateView::sfFromBeginning );
+ m_optRegExp->setChecked( flags & KateView::sfRegularExpression );
+ m_opt4->setChecked( flags & KateView::sfBackward );
+ m_opt5->setChecked( flags & KateView::sfSelected );
+
+ if( m_replace )
+ {
+ m_opt6 = new QCheckBox( i18n( "&Prompt On Replace" ), group );
+ m_opt6->setChecked( flags & KateView::sfPrompt );
+ gbox->addWidget( m_opt6, 3, 1 );
+ }
+
+ m_search->setFocus();
+}
+
+QString SearchDialog::getSearchFor()
+{
+ return m_search->currentText();
+}
+
+QString SearchDialog::getReplaceWith()
+{
+ return m_replace->currentText();
+}
+
+int SearchDialog::getFlags()
+{
+ int flags = 0;
+
+ if( m_opt1->isChecked() ) flags |= KateView::sfCaseSensitive;
+ if( m_opt2->isChecked() ) flags |= KateView::sfWholeWords;
+ if( m_opt3->isChecked() ) flags |= KateView::sfFromBeginning;
+ if( m_opt4->isChecked() ) flags |= KateView::sfBackward;
+ if( m_opt5->isChecked() ) flags |= KateView::sfSelected;
+ if( m_optRegExp->isChecked() ) flags |= KateView::sfRegularExpression;
+ if( m_replace )
+ {
+ if( m_opt6->isChecked() )
+ flags |= KateView::sfPrompt;
+
+ flags |= KateView::sfReplace;
+ }
+
+ return flags;
+}
+
+void SearchDialog::slotOk()
+{
+ if ( !m_search->currentText().isEmpty() )
+ {
+ if ( !m_optRegExp->isChecked() )
+ {
+ accept();
+ }
+ else
+ {
+ // Check for a valid regular expression.
+
+ QRegExp regExp( m_search->currentText() );
+
+ if ( regExp.isValid() )
+ accept();
+ }
+ }
+}
+
+void SearchDialog::setSearchText( const QString &searchstr )
+ {
+ m_search->insertItem( searchstr, 0 );
+ m_search->setCurrentItem( 0 );
+ m_search->lineEdit()->selectAll();
+ }
+
+// this dialog is not modal
+ReplacePrompt::ReplacePrompt( QWidget *parent )
+ : KDialogBase(parent, 0L, false, i18n( "Replace Text" ),
+ User3 | User2 | User1 | Close, User3, true,
+ i18n("&All"), i18n("&No"), i18n("&Yes")) {
+
+ QWidget *page = new QWidget(this);
+ setMainWidget(page);
+
+ QBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
+ QLabel *label = new QLabel(i18n("Replace this occurence?"),page);
+ topLayout->addWidget(label );
+}
+
+void ReplacePrompt::slotUser1( void ) { // All
+ done(KateView::srAll);
+}
+
+void ReplacePrompt::slotUser2( void ) { // No
+ done(KateView::srNo);
+}
+
+void ReplacePrompt::slotUser3( void ) { // Yes
+ accept();
+}
+
+void ReplacePrompt::done(int r) {
+ setResult(r);
+ emit clicked();
+}
+
+void ReplacePrompt::closeEvent(QCloseEvent *) {
+ reject();
+}
+
+GotoLineDialog::GotoLineDialog(QWidget *parent, int line, int max)
+ : KDialogBase(parent, 0L, true, i18n("Goto Line"), Ok | Cancel, Ok) {
+
+ QWidget *page = new QWidget(this);
+ setMainWidget(page);
+
+ QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
+ e1 = new QSpinBox(page);
+ e1->setMinValue(1);
+ e1->setMaxValue(max);
+ e1->setValue((int)line);
+
+ QLabel *label = new QLabel( e1,i18n("&Goto Line:"), page );
+ topLayout->addWidget(label);
+ topLayout->addWidget(e1);
+ topLayout->addSpacing(spacingHint()); // A little bit extra space
+ topLayout->addStretch(10);
+ e1->setFocus();
+}
+
+int GotoLineDialog::getLine() {
+ return e1->value();
+}
+
+const int IndentConfigTab::flags[] = {KateView::cfAutoIndent, KateView::cfSpaceIndent,
+ KateView::cfBackspaceIndents,KateView::cfTabIndents, KateView::cfKeepIndentProfile, KateView::cfKeepExtraSpaces};
+
+IndentConfigTab::IndentConfigTab(QWidget *parent, KateView *view)
+ : QWidget(parent, 0L)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this, 0, KDialog::spacingHint() );
+ int configFlags = view->config();
+
+ opt[0] = new QCheckBox(i18n("&Auto Indent"), this);
+ layout->addWidget(opt[0], 0, AlignLeft);
+ opt[0]->setChecked(configFlags & flags[0]);
+
+ opt[1] = new QCheckBox(i18n("Indent With &Spaces"), this);
+ layout->addWidget(opt[1], 0, AlignLeft);
+ opt[1]->setChecked(configFlags & flags[1]);
+
+ opt[2] = new QCheckBox(i18n("&Backspace Key Indents"), this);
+ layout->addWidget(opt[2], 0, AlignLeft);
+ opt[2]->setChecked(configFlags & flags[2]);
+
+ opt[3] = new QCheckBox(i18n("&Tab Key Indents"), this);
+ layout->addWidget(opt[3], 0, AlignLeft);
+ opt[3]->setChecked(configFlags & flags[3]);
+
+ opt[4] = new QCheckBox(i18n("Keep Indent &Profile"), this);
+ layout->addWidget(opt[4], 0, AlignLeft);
+// opt[4]->setChecked(configFlags & flags[4]);
+ opt[4]->setChecked(true);
+ opt[4]->hide();
+
+ opt[5] = new QCheckBox(i18n("&Keep Extra Spaces"), this);
+ layout->addWidget(opt[5], 0, AlignLeft);
+ opt[5]->setChecked(configFlags & flags[5]);
+
+ layout->addStretch();
+
+ // What is this? help
+ QWhatsThis::add(opt[0], i18n("When <b>Auto indent</b> is on, KateView will indent new lines to equal the indent on the previous line.<p>If the previous line is blank, the nearest line above with text is used"));
+ QWhatsThis::add(opt[1], i18n("Check this if you want to indent with spaces rather than tabs.<br>A Tab will be converted to <u>Tab-width</u> as set in the <b>edit</b> options"));
+ QWhatsThis::add(opt[2], i18n("This allows the <b>backspace</b> key to be used to indent."));
+ QWhatsThis::add(opt[3], i18n("This allows the <b>tab</b> key to be used to indent."));
+ QWhatsThis::add(opt[4], i18n("This retains current indentation settings for future documents."));
+ QWhatsThis::add(opt[5], i18n("Indentations of more than the selected number of spaces will not be shortened."));
+}
+
+void IndentConfigTab::getData(KateView *view) {
+ int configFlags, z;
+
+ configFlags = view->config();
+ for (z = 0; z < numFlags; z++) {
+ configFlags &= ~flags[z];
+ if (opt[z]->isChecked()) configFlags |= flags[z];
+ }
+ view->setConfig(configFlags);
+}
+
+const int SelectConfigTab::flags[] = {KateView::cfPersistent, KateView::cfDelOnInput,
+ KateView::cfMouseAutoCopy, KateView::cfSingleSelection, KateView::cfVerticalSelect, KateView::cfXorSelect};
+
+SelectConfigTab::SelectConfigTab(QWidget *parent, KateView *view)
+ : QWidget(parent, 0L)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this, 0, KDialog::spacingHint() );
+ int configFlags = view->config();
+
+ opt[0] = new QCheckBox(i18n("&Persistent Selections"), this);
+ layout->addWidget(opt[0], 0, AlignLeft);
+ opt[0]->setChecked(configFlags & flags[0]);
+
+ opt[1] = new QCheckBox(i18n("&Overwrite Selections"), this);
+ layout->addWidget(opt[1], 0, AlignLeft);
+ opt[1]->setChecked(configFlags & flags[1]);
+
+ opt[2] = new QCheckBox(i18n("Mouse &Autocopy"), this);
+ layout->addWidget(opt[2], 0, AlignLeft);
+ opt[2]->setChecked(configFlags & flags[2]);
+
+ opt[3] = new QCheckBox(i18n("&X11-like Single Selection"), this);
+ layout->addWidget(opt[3], 0, AlignLeft);
+ opt[3]->setChecked(configFlags & flags[3]);
+
+ opt[4] = new QCheckBox(i18n("&Vertical Selections"), this);
+ layout->addWidget(opt[4], 0, AlignLeft);
+ opt[4]->setChecked(configFlags & flags[4]);
+
+ opt[5] = new QCheckBox(i18n("&Toggle Old"), this);
+ layout->addWidget(opt[5], 0, AlignLeft);
+ opt[5]->setChecked(configFlags & flags[5]);
+
+ layout->addStretch();
+
+ // What is this? help
+ QWhatsThis::add(opt[0], i18n("Enabling this prevents key input or cursor movement by way of the arrow keys from causing the elimination of text selection.<p><b>Note:</b> If the Overwrite Selections option is activated then any typed character input or paste operation will replace the selected text."));
+ QWhatsThis::add(opt[1], i18n("When this is on, any keyed character input or paste operation will replace the selected text."));
+ QWhatsThis::add(opt[2], i18n("When this is on, any text selected with the mouse will be automatically copied to the clipboard."));
+ QWhatsThis::add(opt[3], i18n("Not implemented yet."));
+ QWhatsThis::add(opt[4], i18n("Enabling this allows you to make vertical selections."));
+ QWhatsThis::add(opt[5], i18n("Not yet implemented."));
+}
+
+void SelectConfigTab::getData(KateView *view) {
+ int configFlags, z;
+
+ configFlags = view->config();
+ for (z = 0; z < numFlags; z++) {
+ configFlags &= ~flags[z]; // clear flag
+ if (opt[z]->isChecked()) configFlags |= flags[z]; // set flag if checked
+ }
+ view->setConfig(configFlags);
+}
+
+const int EditConfigTab::flags[] = {KateView::cfWordWrap, KateView::cfReplaceTabs, KateView::cfRemoveSpaces,
+ KateView::cfAutoBrackets, KateView::cfGroupUndo, KateView::cfShowTabs, KateView::cfSmartHome,
+ KateView::cfPageUDMovesCursor, KateView::cfWrapCursor};
+
+EditConfigTab::EditConfigTab(QWidget *parent, KateView *view)
+ : QWidget(parent, 0L) {
+
+ QHBoxLayout *mainLayout;
+ QVBoxLayout *cbLayout, *leLayout;
+ int configFlags;
+
+ mainLayout = new QHBoxLayout(this, 0, KDialog::spacingHint() );
+
+ // checkboxes
+ cbLayout = new QVBoxLayout( mainLayout );
+ configFlags = view->config();
+
+ opt[0] = new QCheckBox(i18n("&Word wrap"), this);
+ cbLayout->addWidget(opt[0], 0, AlignLeft);
+ opt[0]->setChecked(view->doc()->wordWrap());
+
+ opt[1] = new QCheckBox(i18n("Replace &tabs with spaces"), this);
+ cbLayout->addWidget(opt[1], 0, AlignLeft);
+ opt[1]->setChecked(configFlags & flags[1]);
+
+ opt[2] = new QCheckBox(i18n("&Remove trailing spaces"), this);
+ cbLayout->addWidget(opt[2], 0, AlignLeft);
+ opt[2]->setChecked(configFlags & flags[2]);
+
+ opt[3] = new QCheckBox(i18n("&Auto brackets"), this);
+ cbLayout->addWidget(opt[3], 0, AlignLeft);
+ opt[3]->setChecked(configFlags & flags[3]);
+
+ opt[4] = new QCheckBox(i18n("Group &undos"), this);
+ cbLayout->addWidget(opt[4], 0, AlignLeft);
+ opt[4]->setChecked(configFlags & flags[4]);
+
+ opt[5] = new QCheckBox(i18n("&Show tabs"), this);
+ cbLayout->addWidget(opt[5], 0, AlignLeft);
+ opt[5]->setChecked(configFlags & flags[5]);
+
+ opt[6] = new QCheckBox(i18n("Smart &home"), this);
+ cbLayout->addWidget(opt[6], 0, AlignLeft);
+ opt[6]->setChecked(configFlags & flags[6]);
+
+ opt[7] = new QCheckBox(i18n("&Page up/down moves cursor"), this);
+ cbLayout->addWidget(opt[7], 0, AlignLeft);
+ opt[7]->setChecked(configFlags & flags[7]);
+
+ opt[8] = new QCheckBox(i18n("Wrap &cursor"), this);
+ cbLayout->addWidget(opt[8], 0, AlignLeft);
+ opt[8]->setChecked(configFlags & flags[8]);
+
+ cbLayout->addStretch();
+
+ // edit lines
+ leLayout = new QVBoxLayout();
+ mainLayout->addLayout(leLayout,10);
+
+ e1 = new QSpinBox(this);
+ e1->setMinValue(20);
+ e1->setMaxValue( 200);
+ e1->setValue((int)(view->doc()->wordWrapAt()));
+#warning fixme e1->setLabel(i18n("Wrap Words At:"));
+
+ e2 = new QSpinBox(this);
+ e2->setMinValue(1);
+ e2->setMaxValue(16);
+ e2->setValue((int)view->tabWidth());
+
+#warning fixme e2->setLabel(i18n("Tab/Indent Width:"));
+
+ e3 = new QSpinBox(this);
+ e3->setMinValue(5);
+ e3->setMaxValue( 30000);
+#warning fixme e3->setLabel(i18n("Undo steps:"));
+ e3->setValue((int)view->undoSteps());
+
+ leLayout->addWidget(e1, 0, AlignLeft);
+ leLayout->addWidget(e2, 0, AlignLeft);
+ leLayout->addWidget(e3, 0, AlignLeft);
+
+
+ QVBox *box = new QVBox (this);
+ leLayout->addWidget (box, 0, AlignLeft);
+
+ new QLabel (i18n("Encoding:"), box);
+
+ encoding = new QComboBox(box);
+#warning fixme
+#if 0
+ encoding->insertStringList (KGlobal::charsets()->availableEncodingNames());
+ encoding->setCurrentItem (KGlobal::charsets()->availableEncodingNames().findIndex(view->doc()->encoding()));
+#endif
+ leLayout->addStretch();
+
+ // What is this? help
+ QWhatsThis::add(opt[0], i18n("Word wrap is a feature that causes the editor to automatically start a new line of text and move (wrap) the cursor to the beginning of that new line. KateView will automatically start a new line of text when the current line reaches the length specified by the Wrap Words At: option.<p><b>NOTE:<b> Word Wrap will not change existing lines or wrap them for easy reading as in some applications."));
+ QWhatsThis::add(e1, i18n("If the Word Wrap option is selected this entry determines the length (in characters) at which the editor will automatically start a new line."));
+ QWhatsThis::add(opt[1], i18n("KateView will replace any tabs with the number of spaces indicated in the Tab Width: entry."));
+ QWhatsThis::add(e2, i18n("If the Replace Tabs By Spaces option is selected this entry determines the number of spaces with which the editor will automatically replace tabs."));
+ QWhatsThis::add(opt[2], i18n("KateView will automatically eliminate extra spaces at the ends of lines of text."));
+ QWhatsThis::add(opt[3], i18n("When the user types a left bracket ([,(, or {) KateView automatically enters the right bracket (}, ), or ]) to the right of the cursor."));
+ QWhatsThis::add(opt[4], i18n("Checking this will cause sequences of similar actions to be undone at once."));
+ QWhatsThis::add(opt[5], i18n("The editor will display a symbol to indicate the presence of a tab in the text."));
+ QWhatsThis::add(opt[6], i18n("Not yet implemented."));
+ QWhatsThis::add(opt[7], i18n("If this is selected, the insertion cursor will be moved to the first/last line when pressing the page up/down buttons.<p>If not selected, it will remain at it's relative position in the visible text."));
+ QWhatsThis::add(e3, i18n("Sets the number of undo/redo steps to record. More steps uses more memory."));
+ QWhatsThis::add(opt[8], i18n("When on, moving the insertion cursor using the <b>Left</b> and <b>Right</b> keys will go on to previous/next line at beginning/end of the line, similar to most editors.<p>When off, the insertion cursor cannot be moved left of the line start, but it can be moved off the line end, which can be very handy for programmers."));
+}
+
+void EditConfigTab::getData(KateView *view)
+{
+ int configFlags, z;
+
+ configFlags = view->config();
+ for (z = 1; z < numFlags; z++) {
+ configFlags &= ~flags[z];
+ if (opt[z]->isChecked()) configFlags |= flags[z];
+ }
+ view->setConfig(configFlags);
+
+ view->setEncoding (encoding->currentText());
+ view->doc()->setWordWrapAt(e1->value());
+ view->doc()->setWordWrap (opt[0]->isChecked());
+ view->setTabWidth(e2->value());
+ view->setUndoSteps(e3->value());
+}
+
+ColorConfig::ColorConfig( QWidget *parent, char *name )
+ : QWidget( parent, name )
+{
+ QGridLayout *glay = new QGridLayout( this, 6, 2, 0, KDialog::spacingHint());
+ glay->setColStretch(1,1);
+ glay->setRowStretch(5,1);
+
+ QLabel *label;
+
+ label = new QLabel( i18n("Background:"), this);
+ label->setAlignment( AlignRight|AlignVCenter );
+ m_back = new KColorButton( this );
+ glay->addWidget( label, 0, 0 );
+ glay->addWidget( m_back, 0, 1 );
+
+ label = new QLabel( i18n("Selected:"), this);
+ label->setAlignment( AlignRight|AlignVCenter );
+ m_selected = new KColorButton( this );
+ glay->addWidget( label, 2, 0 );
+ glay->addWidget( m_selected, 2, 1 );
+
+ // QWhatsThis help
+ QWhatsThis::add(m_back, i18n("Sets the background color of the editing area"));
+ QWhatsThis::add(m_selected, i18n("Sets the background color of the selection. To set the text color for selected text, use the &quot;<b>Configure Highlighting</b>&quot; dialog."));
+}
+
+
+ColorConfig::~ColorConfig()
+{
+}
+
+void ColorConfig::setColors(QColor *colors)
+{
+ m_back->setColor( colors[0] );
+ m_selected->setColor( colors[1] );
+}
+
+void ColorConfig::getColors(QColor *colors)
+{
+ colors[0] = m_back->color();
+ colors[1] = m_selected->color();
+}
+
+FontConfig::FontConfig( QWidget *parent, char *name )
+ : QWidget( parent, name )
+{
+ // sizemanagment
+ QGridLayout *grid = new QGridLayout( this, 1, 1 );
+#if 0
+ m_fontchooser = new KFontChooser ( this );
+ m_fontchooser->enableColumn(KFontChooser::StyleList, false);
+ grid->addWidget( m_fontchooser, 0, 0);
+
+ connect (m_fontchooser, SIGNAL (fontSelected( const QFont & )), this, SLOT (slotFontSelected( const QFont & )));
+#endif
+}
+
+FontConfig::~FontConfig()
+{
+}
+
+void FontConfig::setFont ( const QFont &font )
+{
+#if 0
+ m_fontchooser->setFont (font);
+ myFont = font;
+#endif
+}
+
+void FontConfig::slotFontSelected( const QFont &font )
+{
+ myFont = font;
+}
+
+
+
+
diff --git a/noncore/apps/tinykate/libkate/view/kateviewdialog.h b/noncore/apps/tinykate/libkate/view/kateviewdialog.h
new file mode 100644
index 0000000..60f30bd
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/view/kateviewdialog.h
@@ -0,0 +1,194 @@
+/***************************************************************************
+ kateviewdialog.h - description
+ -------------------
+ copyright : (C) 2001 by The Kate Team
+ (C) 2002 by Joseph Wenninger
+ email : kwrite-devel@kde.org
+ jowenn@kde.org
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+// Dialogs
+
+#ifndef _KWDIALOG_H_
+#define _KWDIALOG_H_
+
+
+class QCheckBox;
+class QLineEdit;
+class QPushButton;
+class QRadioButton;
+class QSpinBox;
+class KColorButton;
+class QComboBox;
+
+#include <kdialogbase.h>
+#include "kateview.h"
+
+class SearchDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ SearchDialog( QWidget *parent, QStringList &searchFor, QStringList &replaceWith, int flags );
+ QString getSearchFor();
+ QString getReplaceWith();
+ int getFlags();
+ void setSearchText( const QString &searchstr );
+
+ protected slots:
+ void slotOk();
+
+ protected:
+ QComboBox *m_search;
+ QComboBox *m_replace;
+ QCheckBox *m_opt1;
+ QCheckBox *m_opt2;
+ QCheckBox *m_opt3;
+ QCheckBox *m_optRegExp;
+ QCheckBox *m_opt4;
+ QCheckBox *m_opt5;
+ QCheckBox *m_opt6;
+};
+
+class ReplacePrompt : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+
+ ReplacePrompt(QWidget *parent);
+
+ signals:
+
+ void clicked();
+
+ protected slots:
+
+ void slotUser1( void ); // All
+ void slotUser2( void ); // No
+ void slotUser3( void ); // Yes
+ virtual void done(int);
+
+ protected:
+
+ void closeEvent(QCloseEvent *);
+};
+
+class GotoLineDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+
+ GotoLineDialog(QWidget *parent, int line, int max);
+ int getLine();
+
+ protected:
+
+ QSpinBox *e1;
+ QPushButton *btnOK;
+};
+
+class IndentConfigTab : public QWidget
+{
+ Q_OBJECT
+
+ public:
+
+ IndentConfigTab(QWidget *parent, KateView *);
+ void getData(KateView *);
+
+ protected:
+
+ static const int numFlags = 6;
+ static const int flags[numFlags];
+ QCheckBox *opt[numFlags];
+};
+
+class SelectConfigTab : public QWidget
+{
+ Q_OBJECT
+
+ public:
+
+ SelectConfigTab(QWidget *parent, KateView *);
+ void getData(KateView *);
+
+ protected:
+
+ static const int numFlags = 6;
+ static const int flags[numFlags];
+ QCheckBox *opt[numFlags];
+};
+
+class EditConfigTab : public QWidget
+{
+ Q_OBJECT
+
+ public:
+
+ EditConfigTab(QWidget *parent, KateView *);
+ void getData(KateView *);
+
+ protected:
+
+ static const int numFlags = 9;
+ static const int flags[numFlags];
+ QCheckBox *opt[numFlags];
+ QComboBox *encoding;
+
+
+ QSpinBox *e1;
+ QSpinBox *e2;
+ QSpinBox *e3;
+};
+
+class ColorConfig : public QWidget
+{
+ Q_OBJECT
+
+public:
+
+ ColorConfig( QWidget *parent = 0, char *name = 0 );
+ ~ColorConfig();
+
+ void setColors( QColor * );
+ void getColors( QColor * );
+
+private:
+
+ KColorButton *m_back;
+ KColorButton *m_selected;
+};
+
+class FontConfig : public QWidget
+{
+ Q_OBJECT
+
+public:
+
+ FontConfig( QWidget *parent = 0, char *name = 0 );
+ ~FontConfig();
+
+ void setFont ( const QFont &font );
+ QFont getFont ( ) { return myFont; };
+
+ private:
+// class KFontChooser *m_fontchooser;
+ QFont myFont;
+
+ private slots:
+ void slotFontSelected( const QFont &font );
+};
+
+
+#endif //_KWDIALOG_H_
diff --git a/noncore/apps/tinykate/main.cpp b/noncore/apps/tinykate/main.cpp
new file mode 100644
index 0000000..e92df69
--- a/dev/null
+++ b/noncore/apps/tinykate/main.cpp
@@ -0,0 +1,29 @@
+/***************************************************************************
+ main.cpp
+ -------------------
+ begin : November 2002
+ copyright : (C) 2002 by Joseph Wenninger <jowenn@kde.org>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * ONLY VERSION 2 OF THE LICENSE IS APPLICABLE *
+ * *
+ ***************************************************************************/
+#include <qpe/qpeapplication.h>
+#include <qmainwindow.h>
+#include "tinykate.h"
+
+
+int main( int argc, char ** argv )
+{
+ QPEApplication a( argc, argv );
+
+ TinyKate *m = new TinyKate();
+ a.setMainWidget( m );
+ m->showMaximized();
+ return a.exec();
+}
diff --git a/noncore/apps/tinykate/pics/edit-redo.xpm b/noncore/apps/tinykate/pics/edit-redo.xpm
new file mode 100644
index 0000000..7557ac5
--- a/dev/null
+++ b/noncore/apps/tinykate/pics/edit-redo.xpm
@@ -0,0 +1,90 @@
+/* XPM */
+static char * edit_redo_xpm[] = {
+"18 17 70 1",
+" c None",
+". c #1E472E",
+"+ c #234E33",
+"@ c #1B4029",
+"# c #1B422A",
+"$ c #AFBEBA",
+"% c #DBEADF",
+"& c #C1CECC",
+"* c #214A30",
+"= c #224B31",
+"- c #163321",
+"; c #BFD0C8",
+"> c #90BD9F",
+", c #227D37",
+"' c #C0D1C9",
+") c #245135",
+"! c #153220",
+"~ c #BDCEC7",
+"{ c #2F9645",
+"] c #3BB057",
+"^ c #43BA5C",
+"/ c #224B30",
+"( c #173A23",
+"_ c #143120",
+": c #38774E",
+"< c #1E4335",
+"[ c #0B281E",
+"} c #143D29",
+"| c #3FAF57",
+"1 c #42B75B",
+"2 c #7BA08A",
+"3 c #0F2417",
+"4 c #081914",
+"5 c #050E0D",
+"6 c #123926",
+"7 c #36A34D",
+"8 c #9DC6AA",
+"9 c #88AB9C",
+"0 c #C2DBCA",
+"a c #040B06",
+"b c #0A1F18",
+"c c #0D3525",
+"d c #2A8F3D",
+"e c #CFE0D4",
+"f c #0A1910",
+"g c #0D2419",
+"h c #030C0B",
+"i c #041714",
+"j c #259039",
+"k c #3E9951",
+"l c #B2D1BC",
+"m c #03090A",
+"n c #071112",
+"o c #55AE72",
+"p c #5AB975",
+"q c #5AA77B",
+"r c #468166",
+"s c #000001",
+"t c #10211F",
+"u c #03080A",
+"v c #010003",
+"w c #020005",
+"x c #000000",
+"y c #14311F",
+"z c #050B0C",
+"A c #162D26",
+"B c #050D0E",
+"C c #142724",
+"D c #090F10",
+"E c #050A0C",
+" ",
+" ",
+" ..+ ",
+" @#$%&*= ",
+" -;>,,,%'* ) ",
+" !~,,{]^,,%/ )( ",
+" _,:<[[}|1,%*)2( ",
+"3,)4 567,890( ",
+"a,b c7,de( ",
+"fgh i,jkl( ",
+" mn 4,opqr( ",
+" stu vvvwvvxy ",
+" zA5 ",
+" BCD ",
+" sEs ",
+" ",
+" "};
diff --git a/noncore/apps/tinykate/pics/edit-undo.xpm b/noncore/apps/tinykate/pics/edit-undo.xpm
new file mode 100644
index 0000000..17a1f30
--- a/dev/null
+++ b/noncore/apps/tinykate/pics/edit-undo.xpm
@@ -0,0 +1,90 @@
+/* XPM */
+static char * edit_undo_xpm[] = {
+"18 17 70 1",
+" c None",
+". c #234E33",
+"+ c #1E472E",
+"@ c #224B31",
+"# c #214A30",
+"$ c #C1CECC",
+"% c #DBEADF",
+"& c #AFBEBA",
+"* c #1B422A",
+"= c #1B4029",
+"- c #245135",
+"; c #C0D1C9",
+"> c #227D37",
+", c #90BD9F",
+"' c #BFD0C8",
+") c #163321",
+"! c #173A23",
+"~ c #224B30",
+"{ c #43BA5C",
+"] c #3BB057",
+"^ c #2F9645",
+"/ c #BDCEC7",
+"( c #153220",
+"_ c #7BA08A",
+": c #42B75B",
+"< c #3FAF57",
+"[ c #143D29",
+"} c #0B281E",
+"| c #1E4335",
+"1 c #38774E",
+"2 c #143120",
+"3 c #C2DBCA",
+"4 c #88AB9C",
+"5 c #9DC6AA",
+"6 c #36A34D",
+"7 c #123926",
+"8 c #050E0D",
+"9 c #081914",
+"0 c #0F2417",
+"a c #CFE0D4",
+"b c #2A8F3D",
+"c c #0D3525",
+"d c #0A1F18",
+"e c #040B06",
+"f c #B2D1BC",
+"g c #3E9951",
+"h c #259039",
+"i c #041714",
+"j c #030C0B",
+"k c #0D2419",
+"l c #0A1910",
+"m c #468166",
+"n c #5AA77B",
+"o c #5AB975",
+"p c #55AE72",
+"q c #071112",
+"r c #03090A",
+"s c #14311F",
+"t c #000000",
+"u c #010003",
+"v c #020005",
+"w c #03080A",
+"x c #10211F",
+"y c #000001",
+"z c #162D26",
+"A c #050B0C",
+"B c #090F10",
+"C c #142724",
+"D c #050D0E",
+"E c #050A0C",
+" ",
+" ",
+" .++ ",
+" @#$%&*= ",
+"- #;%>>>,') ",
+"!- ~%>>{]^>>/( ",
+"!_-#%>:<[}}|1>2 ",
+"!345>678 9->0 ",
+"!ab>6c d>e ",
+"!fgh>i jkl ",
+"!mnop>9 qr ",
+"stuuvuuu wxy ",
+" 8zA ",
+" BCD ",
+" yEy ",
+" ",
+" "};
diff --git a/noncore/apps/tinykate/pics/file-new.xpm b/noncore/apps/tinykate/pics/file-new.xpm
new file mode 100644
index 0000000..ec8dd63
--- a/dev/null
+++ b/noncore/apps/tinykate/pics/file-new.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static const char * file_new_xpm[] = {
+"16 16 5 1",
+" c None",
+". c #808080",
+"+ c #FFFFFF",
+"@ c #C0C0C0",
+"# c #000000",
+" .......... ",
+" .++++++++@. ",
+" .++++++++@+. ",
+" .++++++++#### ",
+" .++++++++++@# ",
+" .++++++++++@# ",
+" .++++++++++@# ",
+" .++++++++++@# ",
+" .++++++++++@# ",
+" .++++++++++@# ",
+" .++++++++++@# ",
+" .++++++++++@# ",
+" .++++++++++@# ",
+" .++++++++++@# ",
+" .@@@@@@@@@@@# ",
+" ############# "};
diff --git a/noncore/apps/tinykate/pics/file-open.xpm b/noncore/apps/tinykate/pics/file-open.xpm
new file mode 100644
index 0000000..8449d5b
--- a/dev/null
+++ b/noncore/apps/tinykate/pics/file-open.xpm
@@ -0,0 +1,25 @@
+/* XPM */
+static const char * file_open_xpm[] = {
+"16 16 6 1",
+" c None",
+". c #808080",
+"+ c #FFFFFF",
+"@ c #C0C0C0",
+"# c #FFFF00",
+"$ c #000000",
+" ",
+" ..... ",
+" .+++++. ",
+" .+@#@#@+...... ",
+" .+#@#@#@+++++.$",
+" .+@#@#@#@#@#@.$",
+".............#.$",
+".++++++++++.$@.$",
+".+@#@#@#@#@#$..$",
+" .+@#@#@#@#@.$.$",
+" .+#@#@#@#@#@$.$",
+" .+#@#@#@#@#.$$",
+" ............$$",
+" $$$$$$$$$$$$$",
+" ",
+" "};
diff --git a/noncore/apps/tinykate/pics/file-save.xpm b/noncore/apps/tinykate/pics/file-save.xpm
new file mode 100644
index 0000000..039a174
--- a/dev/null
+++ b/noncore/apps/tinykate/pics/file-save.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static const char * file_save_xpm[] = {
+"16 16 5 1",
+" c None",
+". c #808080",
+"+ c #FFFFFF",
+"@ c #000000",
+"# c #0000FF",
+" ",
+" ........ ",
+" .++++++.@ ",
+" .+....+.+@ #",
+" .++++++.@@@ ##",
+" .+....++++@ ##@",
+" .+++++++++@##@ ",
+" .+.......+##@ ",
+" .++++++++##@ ",
+" .+......@#@ ",
+" .++++++@@@@ ",
+" .+....@@@+@ ",
+" .++++@++++@ ",
+" .+++++++++@ ",
+" @@@@@@@@@@@ ",
+" "};
diff --git a/noncore/apps/tinykate/tinykate.cpp b/noncore/apps/tinykate/tinykate.cpp
new file mode 100644
index 0000000..03c6e50
--- a/dev/null
+++ b/noncore/apps/tinykate/tinykate.cpp
@@ -0,0 +1,199 @@
+/***************************************************************************
+ tinykate.cpp
+ Tiny KATE mainwindow
+ -------------------
+ begin : November 2002
+ copyright : (C) 2002 by Joseph Wenninger <jowenn@kde.org>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * ONLY VERSION 2 OF THE LICENSE IS APPLICABLE *
+ * *
+ ***************************************************************************/
+#include <qwidget.h>
+#include <qaction.h>
+#include <qlayout.h>
+#include <qpe/qpetoolbar.h>
+#include <qpe/qpemenubar.h>
+#include <qpe/resource.h>
+#include <qpe/global.h>
+
+#include <opie/ofiledialog.h>
+
+#include "tinykate.h"
+#include "pics/file-new.xpm"
+#include "pics/file-open.xpm"
+#include "pics/file-save.xpm"
+#include "pics/edit-undo.xpm"
+#include "pics/edit-redo.xpm"
+
+#include <katedocument.h>
+#include <katehighlight.h>
+
+TinyKate::TinyKate( QWidget *parent, const char *name, WFlags f) :
+ QMainWindow( parent, name, f )
+{
+ currentView=0;
+ setCaption(tr("TinyKATE"));
+
+ setToolBarsMovable(FALSE);
+
+ QPEToolBar *bar = new QPEToolBar( this );
+ bar->setHorizontalStretchable( TRUE );
+ QPEMenuBar *mb = new QPEMenuBar( bar );
+ mb->setMargin( 0 );
+
+ tabwidget=new OTabWidget(this);
+ setCentralWidget(tabwidget);
+ connect(tabwidget,SIGNAL(currentChanged( QWidget *)),this,SLOT(slotCurrentChanged(QWidget *)));
+
+//FILE ACTIONS
+ QPopupMenu *popup = new QPopupMenu( this );
+
+ // Action for creating a new document
+ QAction *a = new QAction( tr( "New" ), QPixmap((const char**)file_new_xpm ), QString::null, 0, this, 0 );
+ a->addTo( popup );
+ connect(a, SIGNAL(activated()), this, SLOT(slotNew()));
+
+ // Action for opening an exisiting document
+ a = new QAction( tr( "Open" ), QPixmap((const char**)file_open_xpm), QString::null, 0, this, 0 );
+ a->addTo(popup);
+ connect(a, SIGNAL(activated()), this, SLOT(slotOpen()));
+
+
+ // Action for saving document
+ a = new QAction( tr( "Save" ), QPixmap((const char**)file_save_xpm), QString::null, 0, this, 0 );
+ a->addTo(popup);
+
+ // Action for saving document to a new name
+ a = new QAction( tr( "Save As" ), QPixmap((const char**)file_save_xpm), QString::null, 0, this, 0 );
+ a->addTo(popup);
+
+ // Action for closing the currently active document
+ a = new QAction( tr( "Close" ), QPixmap(), QString::null, 0, this, 0 );
+ a->addTo(popup);
+ connect(a, SIGNAL(activated()), this, SLOT(slotClose()));
+
+
+ mb->insertItem(tr("File"),popup);
+
+//EDIT ACTIONS
+
+ // Action for cutting text
+ editCut = new QAction( tr( "Cut" ), Resource::loadPixmap( "cut" ), QString::null, 0, this, 0 );
+ editCut->addTo( bar );
+
+ // Action for Copying text
+ editCopy = new QAction( tr( "Copy" ), Resource::loadPixmap( "copy" ), QString::null, 0, this, 0 );
+ editCopy->addTo( bar );
+
+ // Action for pasting text
+ editPaste = new QAction( tr( "Paste" ), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 );
+ editPaste->addTo( bar );
+
+
+ // Action for finding / replacing text
+ editFindReplace = new QAction( tr( "Find/Replace" ), Resource::loadPixmap("find"), QString::null, 0, this, 0 );
+ editFindReplace->addTo( bar );
+
+ // Action for undo
+ editUndo = new QAction( tr( "Undo" ), QPixmap((const char**)edit_undo_xpm), QString::null, 0, this, 0 );
+ editUndo->addTo( bar );
+
+ // Action for redo
+ editRedo = new QAction( tr( "Redo" ), QPixmap((const char**)edit_redo_xpm), QString::null, 0, this, 0 );
+ editRedo->addTo( bar );
+
+//VIEW ACITONS
+ popup = new QPopupMenu( this );
+
+ viewIncFontSizes = new QAction( tr( "Font +" ), QString::null, 0, this, 0 );
+ viewIncFontSizes->addTo( popup );
+
+ viewDecFontSizes = new QAction( tr( "Font -" ), QString::null, 0, this, 0 );
+ viewDecFontSizes->addTo( popup );
+
+ mb->insertItem(tr("View"),popup);
+
+
+
+ popup = new QPopupMenu( this );
+ mb->insertItem(tr("Utils"),popup);
+
+//Highlight management
+ hlmenu=new QPopupMenu(this);
+ HlManager *hlm=HlManager::self();
+ for (int i=0;i<hlm->highlights();i++)
+ {
+ hlmenu->insertItem(hlm->hlName(i),i);
+ }
+ popup->insertItem(tr("Highlighting"),hlmenu);
+
+
+ utilSettings = new QAction( tr( "Settings" ), QString::null, 0, this, 0 );
+ utilSettings->addTo( popup);
+
+}
+
+
+void TinyKate::slotOpen( )
+{
+ QString filename=OFileDialog::getOpenFileName(OFileSelector::EXTENDED_ALL);
+ if (!filename.isEmpty()) {
+ KateDocument *kd= new KateDocument(false, false, this,0,this);
+ KTextEditor::View *kv;
+ tabwidget->addTab(kv=kd->createView(tabwidget,"bLAH"),"BLAH","BLAH");
+ qDebug(filename);
+ kd->open(filename);
+ }
+}
+
+void TinyKate::slotCurrentChanged( QWidget * view)
+{
+ if (currentView) {
+ disconnect(editCopy,SIGNAL(activated()),currentView,SLOT(copy()));
+ disconnect(editCut,SIGNAL(activated()),currentView,SLOT(cut()));
+ disconnect(editPaste,SIGNAL(activated()),currentView,SLOT(paste()));
+ disconnect(editUndo,SIGNAL(activated()),currentView,SLOT(undo()));
+ disconnect(editRedo,SIGNAL(activated()),currentView,SLOT(redo()));
+ disconnect(viewIncFontSizes,SIGNAL(activated()), currentView,SLOT(slotIncFontSizes()));
+ disconnect(viewDecFontSizes,SIGNAL(activated()), currentView,SLOT(slotDecFontSizes()));
+ disconnect(hlmenu,SIGNAL(activated(int)), currentView,SLOT(setHl(int)));
+ disconnect(utilSettings,SIGNAL(activated()), currentView,SLOT(configDialog()));
+ }
+
+ currentView=(KTextEditor::View*)view;
+
+ connect(editCopy,SIGNAL(activated()),currentView,SLOT(copy()));
+ connect(editCut,SIGNAL(activated()),currentView,SLOT(cut()));
+ connect(editPaste,SIGNAL(activated()),currentView,SLOT(paste()));
+ connect(editUndo,SIGNAL(activated()),currentView,SLOT(undo()));
+ connect(editRedo,SIGNAL(activated()),currentView,SLOT(redo()));
+ connect(viewIncFontSizes,SIGNAL(activated()), currentView,SLOT(slotIncFontSizes()));
+ connect(viewDecFontSizes,SIGNAL(activated()), currentView,SLOT(slotDecFontSizes()));
+ connect(hlmenu,SIGNAL(activated(int)), currentView,SLOT(setHl(int)));
+ connect(utilSettings,SIGNAL(activated()), currentView,SLOT(configDialog()));
+
+}
+
+void TinyKate::slotNew( )
+{
+ KateDocument *kd= new KateDocument(false, false, this,0,this);
+ KTextEditor::View *kv;
+ tabwidget->addTab(kv=kd->createView(tabwidget,"BLAH"),"BLAH",tr("Unnamed %1").arg(0));
+
+}
+
+void TinyKate::slotClose( )
+{
+ if (currentView==0) return;
+ KTextEditor::View *dv=currentView;
+ currentView=0;
+ tabwidget->removePage(dv);
+ delete dv->document();
+}
+
diff --git a/noncore/apps/tinykate/tinykate.desktop b/noncore/apps/tinykate/tinykate.desktop
new file mode 100644
index 0000000..2230a6b
--- a/dev/null
+++ b/noncore/apps/tinykate/tinykate.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Type=Application
+Exec=tinykate
+Icon=tinykate_icon.xpm
+Name=TinyKATE
+Comment=Opie Advanced Texteditor
diff --git a/noncore/apps/tinykate/tinykate.h b/noncore/apps/tinykate/tinykate.h
new file mode 100644
index 0000000..6dda05d
--- a/dev/null
+++ b/noncore/apps/tinykate/tinykate.h
@@ -0,0 +1,62 @@
+/***************************************************************************
+ tinykate.h
+ Tiny KATE mainwindow
+ -------------------
+ begin : November 2002
+ copyright : (C) 2002 by Joseph Wenninger <jowenn@kde.org>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * ONLY VERSION 2 OF THE LICENSE IS APPLICABLE *
+ * *
+ ***************************************************************************/
+
+#ifndef __TINYKATE_H__
+#define __TINYKATE_H__
+
+
+#include <qmainwindow.h>
+#include <opie/otabwidget.h>
+#include <ktexteditor.h>
+
+class QAction;
+class QPopupMenu;
+
+class TinyKate : public QMainWindow
+{
+Q_OBJECT
+public:
+ TinyKate( QWidget *parent=0, const char *name=0, WFlags f = 0);
+
+public slots:
+ void slotOpen();
+
+protected slots:
+ void slotNew();
+ void slotClose();
+ void slotCurrentChanged(QWidget *);
+
+private:
+ OTabWidget *tabwidget;
+ KTextEditor::View *currentView;
+
+ QAction *editCopy;
+ QAction *editCut;
+ QAction *editPaste;
+ QAction *editUndo;
+ QAction *editRedo;
+ QAction *editFindReplace;
+ QAction *viewIncFontSizes;
+ QAction *viewDecFontSizes;
+ QAction *utilSettings;
+
+ QPopupMenu *hlmenu;
+
+};
+
+
+#endif // __TINYKATE_H__
diff --git a/noncore/apps/tinykate/tinykate.pro b/noncore/apps/tinykate/tinykate.pro
new file mode 100644
index 0000000..2079041
--- a/dev/null
+++ b/noncore/apps/tinykate/tinykate.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = $(OPIEDIR)/bin
+HEADERS = tinykate.h
+SOURCES = tinykate.cpp main.cpp
+INTERFACES =
+INCLUDEPATH += $(OPIEDIR)/include $(OPIEDIR)/noncore/apps/tinykate/libkate/microkde \
+ $(OPIEDIR)/noncore/apps/tinykate/libkate/document \
+ $(OPIEDIR)/noncore/apps/tinykate/libkate/view \
+ $(OPIEDIR)/noncore/apps/tinykate/libkate/interfaces \
+ $(OPIEDIR)/noncore/apps/tinykate/libkate/ktexteditor \
+ $(OPIEDIR)/noncore/apps/tinykate/libkate/qt3back
+
+DEPENDPATH += $(OPIEDIR)/include
+LIBS += -lqpe -ltinykate -lopie
+TARGET = tinykate
diff --git a/noncore/apps/tinykate/tinykate_icon.xpm b/noncore/apps/tinykate/tinykate_icon.xpm
new file mode 100644
index 0000000..e48e7c9
--- a/dev/null
+++ b/noncore/apps/tinykate/tinykate_icon.xpm
@@ -0,0 +1,20 @@
+/* XPM */
+static char *tinykate_xpm[] = {
+"14 14 3 1",
+" c None",
+". c #000000",
+"a c #FFFFFF",
+" ",
+" aaaaaaaaaaaa ",
+" a..........a ",
+" a..aaaaaa..a ",
+" a.a.aaaa.a.a ",
+" a.aa.aa.aa.a ",
+" a.aaa..aaa.a ",
+" a.aaa..aaa.a ",
+" a.aa.aa.aa.a ",
+" a.a.aaaa.a.a ",
+" a..aaaaaa..a ",
+" a..........a ",
+" aaaaaaaaaaaa ",
+" "};
diff --git a/pics/tinykate/tinykate.png b/pics/tinykate/tinykate.png
new file mode 100644
index 0000000..6644160
--- a/dev/null
+++ b/pics/tinykate/tinykate.png
Binary files differ