summaryrefslogtreecommitdiffstats
path: root/lib/util
diff options
context:
space:
mode:
Diffstat (limited to 'lib/util')
-rw-r--r--lib/util/Mainpage.dox10
-rw-r--r--lib/util/Makefile.am21
-rw-r--r--lib/util/blockingkprocess.cpp105
-rw-r--r--lib/util/blockingkprocess.h92
-rw-r--r--lib/util/configwidgetproxy.cpp105
-rw-r--r--lib/util/configwidgetproxy.h129
-rw-r--r--lib/util/domutil.cpp367
-rw-r--r--lib/util/domutil.h226
-rw-r--r--lib/util/execcommand.cpp101
-rw-r--r--lib/util/execcommand.h70
-rw-r--r--lib/util/filetemplate.cpp128
-rw-r--r--lib/util/filetemplate.h88
-rw-r--r--lib/util/kdeveditorutil.cpp89
-rw-r--r--lib/util/kdeveditorutil.h67
-rw-r--r--lib/util/kdevjobtimer.cpp39
-rw-r--r--lib/util/kdevjobtimer.h39
-rw-r--r--lib/util/kdevshellwidget.cpp125
-rw-r--r--lib/util/kdevshellwidget.h100
-rw-r--r--lib/util/kscriptactionmanager.cpp177
-rw-r--r--lib/util/kscriptactionmanager.h139
-rw-r--r--lib/util/rurl.cpp369
-rw-r--r--lib/util/rurl.h182
-rw-r--r--lib/util/settings.cpp63
-rw-r--r--lib/util/settings.h26
-rw-r--r--lib/util/urlutil.cpp319
-rw-r--r--lib/util/urlutil.h190
26 files changed, 3366 insertions, 0 deletions
diff --git a/lib/util/Mainpage.dox b/lib/util/Mainpage.dox
new file mode 100644
index 00000000..dad04de5
--- /dev/null
+++ b/lib/util/Mainpage.dox
@@ -0,0 +1,10 @@
+/**
+@mainpage The KDevelop Utility Library
+
+This library contains utility classes for the KDevelop architecture.
+
+<b>Link with</b>: -lkdevelop
+
+<b>Include path</b>: -I\$(kde_includes)/kdevelop/util
+*/
+
diff --git a/lib/util/Makefile.am b/lib/util/Makefile.am
new file mode 100644
index 00000000..c170787e
--- /dev/null
+++ b/lib/util/Makefile.am
@@ -0,0 +1,21 @@
+INCLUDES = -I$(top_srcdir)/lib/compat -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/sourceinfo $(all_includes)
+
+noinst_LTLIBRARIES = libkdevutil.la
+
+libkdevutil_la_SOURCES = blockingkprocess.cpp configwidgetproxy.cpp domutil.cpp \
+ execcommand.cpp filetemplate.cpp kdeveditorutil.cpp kdevjobtimer.cpp \
+ kdevshellwidget.cpp kscriptactionmanager.cpp rurl.cpp settings.cpp urlutil.cpp
+
+METASOURCES = AUTO
+
+kdevelopincludedir = $(includedir)/kdevelop/util
+kdevelopinclude_HEADERS = domutil.h execcommand.h filetemplate.h urlutil.h \
+ configwidgetproxy.h rurl.h kscriptactionmanager.h
+
+DOXYGEN_REFERENCES = dcop interfaces kdecore kdefx kdeui khtml kmdi kio kjs kparts kutils kdevextensions kdevinterfaces
+DOXYGEN_PROJECTNAME = KDevelop Utility Library
+DOXYGEN_DOCDIRPREFIX = kdev
+include ../../Doxyfile.am
+
+noinst_HEADERS = blockingkprocess.h kdeveditorutil.h kdevjobtimer.h \
+ kdevshellwidget.h settings.h
diff --git a/lib/util/blockingkprocess.cpp b/lib/util/blockingkprocess.cpp
new file mode 100644
index 00000000..f0d6e6c3
--- /dev/null
+++ b/lib/util/blockingkprocess.cpp
@@ -0,0 +1,105 @@
+/***************************************************************************
+* Copyright (C) 2006 by Andras Mantia *
+* amantia@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 "blockingkprocess.h"
+
+#include <qapplication.h>
+#include <qtimer.h>
+
+BlockingKProcess::BlockingKProcess(QObject *parent, const char *name)
+ : KProcess(parent, name)
+{
+ m_stdOut = "";
+ m_stdErr = "";
+ m_timeoutValue = 60;
+ m_timer = 0L;
+
+ connect(this, SIGNAL(receivedStdout(KProcess *, char *, int)),
+ this, SLOT(slotReceivedStdOut(KProcess *, char *, int)));
+ connect(this, SIGNAL(receivedStderr(KProcess *, char *, int)),
+ this, SLOT(slotReceivedStdErr(KProcess *, char *, int)));
+ connect(this, SIGNAL(processExited(KProcess *)),
+ this, SLOT(slotProcessExited(KProcess *)));
+}
+
+BlockingKProcess::BlockingKProcess()
+ : KProcess()
+{
+ m_stdOut = "";
+ m_stdErr = "";
+ m_timeoutValue = 60;
+ m_timer = 0L;
+ connect(this, SIGNAL(receivedStdout(KProcess *, char *, int)),
+ this, SLOT(slotReceivedStdOut(KProcess *, char *, int)));
+ connect(this, SIGNAL(receivedStderr(KProcess *, char *, int)),
+ this, SLOT(slotReceivedStdErr(KProcess *, char *, int)));
+ connect(this, SIGNAL(processExited(KProcess *)),
+ this, SLOT(slotProcessExited(KProcess *)));
+}
+
+
+BlockingKProcess::~BlockingKProcess()
+{
+}
+bool BlockingKProcess::start(RunMode runmode, Communication comm)
+{
+ if (KProcess::start(runmode, comm))
+ {
+ m_timeout = false;
+ m_timer = new QTimer();
+ connect(m_timer, SIGNAL(timeout()), this, SLOT(slotTimeOut()));
+ m_timer->start(m_timeoutValue*1000, true);
+ enter_loop();
+ delete m_timer;
+ m_timer = 0L;
+ return !m_timeout;
+ } else
+ return false;
+}
+
+
+void BlockingKProcess::slotReceivedStdOut(KProcess *, char *buffer, int buflen)
+{
+ m_stdOut += QString::fromLatin1(buffer, buflen);
+}
+
+void BlockingKProcess::slotReceivedStdErr(KProcess *, char *buffer, int buflen)
+{
+ m_stdErr += QString::fromLatin1(buffer, buflen);
+}
+
+void BlockingKProcess::slotProcessExited(KProcess *)
+{
+ qApp->exit_loop();
+}
+
+void BlockingKProcess::slotTimeOut()
+{
+ m_timeout = true;
+ kill();
+ qApp->exit_loop();
+}
+
+
+void qt_enter_modal( QWidget *widget );
+void qt_leave_modal( QWidget *widget );
+
+void BlockingKProcess::enter_loop()
+{
+ QWidget dummy(0,0,WType_Dialog | WShowModal);
+ dummy.setFocusPolicy( QWidget::NoFocus );
+ qt_enter_modal(&dummy);
+ qApp->enter_loop();
+ qt_leave_modal(&dummy);
+}
+
+
+#include "blockingkprocess.moc"
diff --git a/lib/util/blockingkprocess.h b/lib/util/blockingkprocess.h
new file mode 100644
index 00000000..c5c8f5d9
--- /dev/null
+++ b/lib/util/blockingkprocess.h
@@ -0,0 +1,92 @@
+
+/***************************************************************************
+* Copyright (C) 2006 by Andras Mantia *
+* amantia@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 BLOCKINGKPROCESS_H
+#define BLOCKINGKPROCESS_H
+
+#include <kprocess.h>
+
+/**
+ * Blocking version of KProcess, which stores the stdout.
+ * Differences between start(KProcess::Block, KProcess::StdOut) and this
+ * class are:
+ * - the GUI update is not blocked why the external process is running
+ * - in case of problems there is a timeout (defaults to 60 seconds), after which the
+ * process is terminated.
+ * - the stdout is caught - it the caller request it - and can be read by the caller
+ * @author Andras Mantia <amantia@kde.org>
+*/
+
+class QTimer;
+class BlockingKProcess : public KProcess
+{
+ Q_OBJECT
+
+public:
+ BlockingKProcess(QObject *parent, const char *name=0);
+ BlockingKProcess();
+
+ virtual ~BlockingKProcess();
+
+ /**
+ * Start the process. It waits until the process exits or the timeout is hit.
+ * @param runmode @see KProcess, use KProcess::NotifyOnExit to get proper behaviour,
+ * not KProcess::Block
+ * @param comm if Stdout is passed, it catches the output. For the rest @see KProcess
+ * @return true in case of success, false if there are problems to start the process
+ * or it was killed because of the timeout.
+ */
+ virtual bool start(RunMode runmode=NotifyOnExit, Communication comm=NoCommunication);
+
+ /**
+ * Get the output of the run process
+ * @return the output
+ */
+ QString stdOut() { return m_stdOut;}
+ /**
+ * Clear the internal stdout buffer. Useful in case the class is reused.
+ */
+ void clearStdOut() { m_stdOut = "";}
+ /**
+ * Get the error output of the run process
+ * @return the output
+ */
+ QString stdErr() { return m_stdErr;}
+ /**
+ * Clear the internal stderr buffer. Useful in case the class is reused.
+ */
+ void clearStdErr() { m_stdErr = "";}
+
+ /**
+ * Sets the timeout
+ * @param timeout seconds after which the process is considered hung and killed. 0 disables the timeout.
+ */
+ void setTimeOut(int timeout) { m_timeoutValue = timeout; }
+
+private slots:
+ void slotReceivedStdOut(KProcess *proc, char *buffer, int buflen);
+ void slotReceivedStdErr(KProcess *proc, char *buffer, int buflen);
+ void slotProcessExited(KProcess *proc);
+ void slotTimeOut();
+
+private:
+ void enter_loop();
+
+ QString m_stdOut;
+ QString m_stdErr;
+ bool m_timeout;
+ int m_timeoutValue;
+ QTimer *m_timer;
+};
+
+#endif
diff --git a/lib/util/configwidgetproxy.cpp b/lib/util/configwidgetproxy.cpp
new file mode 100644
index 00000000..128fa2ad
--- /dev/null
+++ b/lib/util/configwidgetproxy.cpp
@@ -0,0 +1,105 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Jens Dagerbo <jens.dagerbo@swipnet.se>
+
+ 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 <qstring.h>
+#include <qvbox.h>
+
+#include <kdebug.h>
+#include <kdialogbase.h>
+#include <kiconloader.h>
+
+#include <kdevcore.h>
+
+
+#include "configwidgetproxy.h"
+
+
+ConfigWidgetProxy::ConfigWidgetProxy( KDevCore * core )
+{
+ connect( core, SIGNAL(configWidget(KDialogBase*)), this, SLOT(slotConfigWidget( KDialogBase*)) );
+ connect( core, SIGNAL(projectConfigWidget(KDialogBase*)), this, SLOT(slotProjectConfigWidget( KDialogBase*)) );
+}
+
+ConfigWidgetProxy::~ConfigWidgetProxy()
+{}
+
+void ConfigWidgetProxy::createGlobalConfigPage( QString const & title, unsigned int pagenumber, QString const & icon )
+{
+ _globalTitleMap.insert( pagenumber, qMakePair( title, icon ) );
+}
+
+void ConfigWidgetProxy::createProjectConfigPage( QString const & title, unsigned int pagenumber, QString const & icon )
+{
+ _projectTitleMap.insert( pagenumber, qMakePair( title, icon ) );
+}
+
+void ConfigWidgetProxy::removeConfigPage( int pagenumber )
+{
+ _globalTitleMap.remove( pagenumber );
+ _projectTitleMap.remove( pagenumber );
+}
+
+void ConfigWidgetProxy::slotConfigWidget( KDialogBase * dlg )
+{
+ TitleMap::Iterator it = _globalTitleMap.begin();
+ while ( it != _globalTitleMap.end() )
+ {
+ _pageMap.insert( dlg->addVBoxPage( it.data().first, it.data().first, BarIcon( it.data().second, KIcon::SizeMedium ) ), it.key() );
+ ++it;
+ }
+
+ connect( dlg, SIGNAL(aboutToShowPage(QWidget*)), this, SLOT( slotAboutToShowPage(QWidget*)) );
+ connect( dlg, SIGNAL(destroyed()), this, SLOT(slotConfigWidgetDestroyed()) );
+}
+
+void ConfigWidgetProxy::slotProjectConfigWidget( KDialogBase * dlg )
+{
+ TitleMap::Iterator it = _projectTitleMap.begin();
+ while ( it != _projectTitleMap.end() )
+ {
+ _pageMap.insert( dlg->addVBoxPage( it.data().first, it.data().first, BarIcon( it.data().second, KIcon::SizeMedium ) ), it.key() );
+ ++it;
+ }
+
+ connect( dlg, SIGNAL(aboutToShowPage(QWidget*)), this, SLOT( slotAboutToShowPage(QWidget*)) );
+ connect( dlg, SIGNAL(destroyed()), this, SLOT(slotConfigWidgetDestroyed()) );
+}
+
+void ConfigWidgetProxy::slotConfigWidgetDestroyed( )
+{
+ _pageMap.clear();
+}
+
+void ConfigWidgetProxy::slotAboutToShowPage( QWidget * page )
+{
+ if ( !page ) return;
+
+ PageMap::Iterator it = _pageMap.find( page );
+ if ( it != _pageMap.end() )
+ {
+ emit insertConfigWidget( static_cast<KDialogBase*>(const_cast<QObject*>(sender())), page, it.data() );
+ _pageMap.remove( it );
+ }
+}
+
+#include "configwidgetproxy.moc"
+
+// kate: space-indent off; indent-width 4; replace-tabs off; tab-width 4;
diff --git a/lib/util/configwidgetproxy.h b/lib/util/configwidgetproxy.h
new file mode 100644
index 00000000..6380d002
--- /dev/null
+++ b/lib/util/configwidgetproxy.h
@@ -0,0 +1,129 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Jens Dagerbo <jens.dagerbo@swipnet.se>
+
+ 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 _CONFIGWIDGETPROXY_H
+#define _CONFIGWIDGETPROXY_H
+
+#include <qobject.h>
+#include <qstring.h>
+#include <qmap.h>
+
+class KDevCore;
+class KDialogBase;
+
+/**
+@file configwidgetproxy.h
+Configuration widget proxy class.
+*/
+
+/**
+This class can be used to implement demand-loading of config pages.
+In order to avoid the potentially heavy and unneccessary creation
+of a config page that might not be needed, this class can be used
+to delay the config page creation until the user explicitly asks
+for it.
+
+A typical case looks like this:
+@code
+#define GLOBALDOC_OPTIONS 1
+#define PROJECTDOC_OPTIONS 2
+
+_configProxy = new ConfigWidgetProxy( core() );
+_configProxy->createGlobalConfigPage( i18n("My Part"), GLOBALDOC_OPTIONS, info()->icon() );
+_configProxy->createProjectConfigPage( i18n("My Part"), PROJECTDOC_OPTIONS, info()->icon() );
+connect( _configProxy, SIGNAL(insertConfigWidget(const QObject*, QWidget*, unsigned int )),
+ this, SLOT(insertConfigWidget(const QObject*, QWidget*, unsigned int )) );
+
+...
+...
+
+void MyPart::insertConfigWidget( QObject const * dlg, QWidget * page, unsigned int pagenumber )
+{
+ if ( pagenumber == PROJECTDOC_OPTIONS ) {
+ MyPartGlobalSettings * w = new MyPartGlobalSettings( this, page );
+ connect( dlg, SIGNAL(okClicked()), w, SLOT(slotAccept()) );
+ } else if ( pagenumber == PROJECTDOC_OPTIONS ) {
+ MyPartProjectSettings * w = new MyPartProjectSettings( this, page );
+ connect( dlg, SIGNAL(okClicked()), w, SLOT(slotAccept()) );
+ }
+}
+@endcode
+
+Note that this replaces the functionality of typical KDevCore::configWidget() and
+KDevCore::projectConfigWidget() slots.
+*/
+class ConfigWidgetProxy : public QObject
+{
+Q_OBJECT
+
+public:
+ /**Constructor.
+ @param core An instance of KDevelop Core.*/
+ ConfigWidgetProxy( KDevCore * core );
+ virtual ~ConfigWidgetProxy();
+
+ /**
+ * Tells the proxy you want a page in the Global Settings.
+ * @param title The title of the config page, shown in the settings dialog.
+ * @param pagenumber A per-proxy unique identifier, used when responding to insertConfigWidget() signal.
+ * @param icon The name of the icon to use.
+ */
+ void createGlobalConfigPage( QString const & title, unsigned int pagenumber, QString const & icon = "kdevelop" );
+
+ /**
+ * Tells the proxy you want a page in the Project Settings.
+ * @param title The title of the config page, shown in the settings dialog.
+ * @param pagenumber A per-proxy unique identifier, used when responding to insertConfigWidget() signal.
+ * @param icon The name of the icon to use.
+ */
+ void createProjectConfigPage( QString const & title, unsigned int pagenumber, QString const & icon = "kdevelop" );
+
+ /**
+ * Removes a config page from the proxy. Next time the settings dialog opens, this page will not be available.
+ * @param pagenumber The identifier set in createGlobalConfigPage() or createProjectConfigPage().
+ */
+ void removeConfigPage( int pagenumber );
+
+signals:
+ /**
+ * The proxy emits this signal to notify the client that a specific config page has been requested.
+ * @param dlg The settings dialog. The client should connect to its okClicked() signal.
+ * @param page The setting page. The client should use this as parent to the config widget.
+ * @param pagenumber The identifier set in createGlobalConfigPage() or createProjectConfigPage(). Identifies the requested config page.
+ */
+ void insertConfigWidget( const KDialogBase * dlg, QWidget * page, unsigned int pagenumber );
+
+private slots:
+ void slotConfigWidget( KDialogBase * );
+ void slotProjectConfigWidget( KDialogBase * );
+ void slotConfigWidgetDestroyed();
+ void slotAboutToShowPage( QWidget * page );
+
+private:
+ typedef QMap<unsigned int, QPair<QString,QString> > TitleMap;
+ typedef QMap<QWidget*, int> PageMap;
+
+ TitleMap _globalTitleMap;
+ TitleMap _projectTitleMap;
+ PageMap _pageMap;
+};
+
+#endif
+
+// kate: space-indent off; indent-width 4; replace-tabs off; tab-width 4;
diff --git a/lib/util/domutil.cpp b/lib/util/domutil.cpp
new file mode 100644
index 00000000..b183717f
--- /dev/null
+++ b/lib/util/domutil.cpp
@@ -0,0 +1,367 @@
+/***************************************************************************
+ * Copyright (C) 2001-2002 by Bernd Gehrmann *
+ * bernd@kdevelop.org *
+ * default support: Eray Ozkural (exa) *
+ * additions: John Firebaugh <jfirebaugh@kde.org> *
+ * Jakob Simon-Gaarde <jakob@simon-gaarde.dk> *
+ * *
+ * 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 "domutil.h"
+
+#include <kdebug.h>
+#include <qstringlist.h>
+#include <qfile.h>
+
+
+void DomUtil::makeEmpty( QDomElement& e )
+{
+ while( !e.firstChild().isNull() )
+ e.removeChild( e.firstChild() );
+}
+
+QDomElement DomUtil::elementByPath(const QDomDocument &doc, const QString &path)
+{
+ QStringList l = QStringList::split('/', path);
+
+ QDomElement el;
+ if(&doc) el = doc.documentElement();
+ QStringList::ConstIterator it;
+ for (it = l.begin(); it != l.end(); ++it) {
+ el = el.namedItem(*it).toElement();
+ }
+
+ return el;
+}
+
+
+QString DomUtil::readEntry(const QDomDocument &doc, const QString &path, const QString &defaultEntry)
+{
+ QDomElement el = elementByPath(doc, path);
+ if (el.isNull())
+ return defaultEntry;
+ else
+ return el.firstChild().toText().data();
+}
+
+/// @todo consider whether it's okay to accept empty string == default value
+/// if not use the below type
+///typedef pair<bool,QString> EltInfo;
+
+QString DomUtil::readEntryAux(const QDomDocument &doc, const QString &path)
+{
+ QDomElement el = elementByPath(doc, path);
+ if (el.isNull())
+ return QString::null;
+ else
+ return el.firstChild().toText().data();
+}
+
+int DomUtil::readIntEntry(const QDomDocument &doc, const QString &path, int defaultEntry)
+{
+ QString entry = readEntryAux(doc, path);
+ if (entry.isNull())
+ return defaultEntry;
+ else
+ return entry.toInt();
+}
+
+
+bool DomUtil::readBoolEntry(const QDomDocument &doc, const QString &path, bool defaultEntry)
+{
+ QString entry = readEntryAux(doc, path);
+ if (entry.isNull())
+ return defaultEntry;
+ else
+ return entry == "TRUE" || entry == "true";
+}
+
+
+QStringList DomUtil::readListEntry(const QDomDocument &doc, const QString &path, const QString &tag)
+{
+ QStringList list;
+
+ QDomElement el = elementByPath(doc, path);
+ QDomElement subEl = el.firstChild().toElement();
+ while (!subEl.isNull()) {
+ if (subEl.tagName() == tag)
+ list << subEl.firstChild().toText().data();
+ subEl = subEl.nextSibling().toElement();
+ }
+
+ return list;
+}
+
+
+DomUtil::PairList DomUtil::readPairListEntry(const QDomDocument &doc, const QString &path, const QString &tag,
+ const QString &firstAttr, const QString &secondAttr)
+{
+ PairList list;
+
+ QDomElement el = elementByPath(doc, path);
+ QDomElement subEl = el.firstChild().toElement();
+ while (!subEl.isNull()) {
+ if (subEl.tagName() == tag) {
+ QString first = subEl.attribute(firstAttr);
+ QString second = subEl.attribute(secondAttr);
+ list << Pair(first, second);
+ }
+ subEl = subEl.nextSibling().toElement();
+ }
+
+ return list;
+}
+
+QMap<QString, QString> DomUtil::readMapEntry(const QDomDocument &doc, const QString& path)
+{
+ QMap<QString, QString> map;
+
+ QDomElement el = elementByPath(doc, path);
+ QDomElement subEl = el.firstChild().toElement();
+ while (!subEl.isNull()) {
+ map[subEl.tagName()] = subEl.firstChild().toText().data();
+ subEl = subEl.nextSibling().toElement();
+ }
+
+ return map;
+}
+
+QDomElement DomUtil::namedChildElement( QDomElement& el, const QString& name )
+{
+ QDomElement child = el.namedItem( name ).toElement();
+ if (child.isNull()) {
+ child = el.ownerDocument().createElement( name );
+ el.appendChild(child);
+ }
+ return child;
+}
+
+
+QDomElement DomUtil::createElementByPath(QDomDocument &doc, const QString &path)
+{
+ QStringList l = QStringList::split('/', path);
+
+ QDomElement el;
+ if(&doc) el = doc.documentElement();
+ QStringList::ConstIterator it;
+ for (it = l.begin(); it != l.end(); ++it)
+ el = DomUtil::namedChildElement( el, *it );
+
+ while (!el.firstChild().isNull())
+ el.removeChild(el.firstChild());
+
+ return el;
+}
+
+
+void DomUtil::writeEntry(QDomDocument &doc, const QString &path, const QString &value)
+{
+ QDomElement el = createElementByPath(doc, path);
+ el.appendChild(doc.createTextNode(value));
+}
+
+void DomUtil::writeMapEntry(QDomDocument &doc, const QString &path, const QMap<QString, QString> &map)
+{
+ QString basePath( path + "/" );
+ QMap<QString,QString>::ConstIterator it;
+ for (it = map.begin(); it != map.end(); ++it)
+ {
+ kdDebug( 9010 ) << "writing " << basePath << ";" << it.key() << ";" << it.data() << endl;
+ if( ! it.key().isEmpty() )
+ writeEntry(doc, basePath + it.key(), it.data() );
+ }
+}
+
+void DomUtil::writeIntEntry(QDomDocument &doc, const QString &path, int value)
+{
+ writeEntry(doc, path, QString::number(value));
+}
+
+
+void DomUtil::writeBoolEntry(QDomDocument &doc, const QString &path, bool value)
+{
+ writeEntry(doc, path, value? "true" : "false");
+}
+
+
+void DomUtil::writeListEntry(QDomDocument &doc, const QString &path, const QString &tag,
+ const QStringList &value)
+{
+ QDomElement el = createElementByPath(doc, path);
+
+ QStringList::ConstIterator it;
+ for (it = value.begin(); it != value.end(); ++it) {
+ QDomElement subEl = doc.createElement(tag);
+ subEl.appendChild(doc.createTextNode(*it));
+ el.appendChild(subEl);
+ }
+}
+
+
+void DomUtil::writePairListEntry(QDomDocument &doc, const QString &path, const QString &tag,
+ const QString &firstAttr, const QString &secondAttr,
+ const PairList &value)
+{
+ QDomElement el = createElementByPath(doc, path);
+
+ PairList::ConstIterator it;
+ for (it = value.begin(); it != value.end(); ++it) {
+ QDomElement subEl = doc.createElement(tag);
+ subEl.setAttribute(firstAttr, (*it).first);
+ subEl.setAttribute(secondAttr, (*it).second);
+ el.appendChild(subEl);
+ }
+}
+
+DomPath DomUtil::resolvPathStringExt(const QString pathstring)
+{
+ // parse path
+ unsigned int i;
+ QStringList pathParts = QStringList::split('/',pathstring);
+ DomPath dompath;
+ for (i=0; i<pathParts.count(); i++)
+ {
+ QStringList pathElemParts = QStringList::split('|',pathParts[i],TRUE);
+ DomPathElement dompathelem;
+ dompathelem.tagName = pathElemParts[0].simplifyWhiteSpace();
+ if (pathElemParts.count()>1)
+ {
+ // handle attributes
+ QStringList attrParts = QStringList::split(';',pathElemParts[1]);
+ for (unsigned int j=0; j<attrParts.count(); j++)
+ {
+ QStringList attribSet = QStringList::split('=',attrParts[j]);
+ if (attribSet.count()<2)
+ continue;
+ DomAttribute domattribute;
+ domattribute.name = attribSet[0].simplifyWhiteSpace();
+ domattribute.value = attribSet[1].simplifyWhiteSpace();
+ dompathelem.attribute.append(domattribute);
+ }
+ }
+ if (pathElemParts.count()>2)
+ dompathelem.matchNumber = pathElemParts[2].toInt();
+ else
+ dompathelem.matchNumber = 0; // or else the first
+ dompath.append(dompathelem);
+ }
+ return dompath;
+}
+
+
+#define rightchild !wrongchild
+
+QDomElement DomUtil::elementByPathExt(QDomDocument &doc, const QString &pathstring)
+{
+ DomPath dompath = resolvPathStringExt(pathstring);
+ QDomElement elem = doc.documentElement();
+ QDomNodeList children;
+ QDomElement nextElem = elem;
+ for (unsigned int j=0; j<dompath.count(); j++)
+ {
+ children = nextElem.childNodes();
+ DomPathElement dompathelement= dompath[j];
+ bool wrongchild = false;
+ int matchCount = 0;
+ for (unsigned int i=0; i<children.count(); i++)
+ {
+ wrongchild = false;
+ QDomElement child = children.item(i).toElement();
+ QString tag = child.tagName();
+ tag = dompathelement.tagName;
+ if (child.tagName() == dompathelement.tagName)
+ {
+ for (unsigned int k=0; k<dompathelement.attribute.count(); k++)
+ {
+ DomAttribute domattribute = dompathelement.attribute[k];
+ QDomAttr domattr = child.attributeNode(domattribute.name);
+ if (domattr.isNull() ||
+ domattr.value() != domattribute.value)
+ {
+ wrongchild = true;
+ break;
+ }
+ }
+ }
+ else
+ wrongchild=true;
+ if (rightchild)
+ {
+ if (dompathelement.matchNumber == matchCount++)
+ {
+ nextElem = child;
+ break;
+ }
+ }
+ }
+ if (wrongchild)
+ {
+ QDomElement nullDummy;
+ nullDummy.clear();
+ return nullDummy;
+ }
+ }
+ return nextElem;
+}
+
+
+bool DomUtil::openDOMFile(QDomDocument &doc, QString filename)
+{
+ QFile file( filename );
+ if ( !file.open( IO_ReadOnly ) )
+ return false;
+ if ( !doc.setContent( &file ) ) {
+ file.close();
+ return false;
+ }
+ file.close();
+ return true;
+}
+
+bool DomUtil::saveDOMFile(QDomDocument &doc, QString filename)
+{
+ QFile file( filename );
+ if ( !file.open( IO_ReadWrite | IO_Truncate ) )
+ return false;
+ QTextStream t( &file );
+ t << doc.toString();
+ file.close();
+ return true;
+}
+
+bool DomUtil::removeTextNodes(QDomDocument doc,QString pathExt)
+{
+ QDomElement elem = elementByPathExt(doc,pathExt);
+ if (elem.isNull())
+ return false;
+ QDomNodeList children = elem.childNodes();
+ for (unsigned int i=0;i<children.count();i++)
+ if (children.item(i).isText())
+ elem.removeChild(children.item(i));
+ return true;
+}
+
+
+bool DomUtil::appendText(QDomDocument doc, QString pathExt, QString text)
+{
+ QDomElement elem = elementByPathExt(doc,pathExt);
+ if (elem.isNull())
+ return false;
+ elem.appendChild(doc.createTextNode(text));
+ return true;
+}
+
+
+bool DomUtil::replaceText(QDomDocument doc, QString pathExt, QString text)
+{
+ if (removeTextNodes(doc,pathExt) &&
+ appendText(doc,pathExt,text))
+ return true;
+ else
+ return false;
+}
diff --git a/lib/util/domutil.h b/lib/util/domutil.h
new file mode 100644
index 00000000..a301ef00
--- /dev/null
+++ b/lib/util/domutil.h
@@ -0,0 +1,226 @@
+/***************************************************************************
+ * Copyright (C) 2001 by Bernd Gehrmann *
+ * bernd@kdevelop.org *
+ * jakob@simon-gaarde.dk *
+ * *
+ * 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 _DOMUTIL_H_
+#define _DOMUTIL_H_
+
+#include <qdom.h>
+#include <qpair.h>
+#include <qstringlist.h>
+#include <qvaluelist.h>
+#include <qmap.h>
+
+/**
+@file domutil.h
+Utility functions to operate on %DOM.
+*/
+
+struct DomAttribute
+{
+ QString name;
+ QString value;
+};
+
+struct DomPathElement
+{
+ QString tagName;
+ QValueList<DomAttribute> attribute;
+ int matchNumber; // for use when more than one element matches the path
+};
+
+typedef QValueList<DomPathElement> DomPath;
+
+/**
+ * Utility class for conveniently accessing data in a %DOM tree.
+ */
+class DomUtil
+{
+public:
+ typedef QPair<QString, QString> Pair;
+ typedef QValueList<Pair> PairList;
+ /**
+ * Remove all child elements from a given element.
+ */
+ static void makeEmpty( QDomElement& );
+ /**
+ * Reads a string entry.
+ */
+ static QString readEntry(const QDomDocument &doc, const QString &path, const QString &defaultEntry = QString::null);
+ /**
+ * Reads a number entry.
+ */
+ static int readIntEntry(const QDomDocument &doc, const QString &path, int defaultEntry = 0);
+ /**
+ * Reads a boolean entry. The strings "true" and "TRUE" are interpreted
+ * as true, all other as false.
+ */
+ static bool readBoolEntry(const QDomDocument &doc, const QString &path, bool defaultEntry = false);
+ /**
+ * Reads a list entry. See writeListEntry().
+ */
+ static QStringList readListEntry(const QDomDocument &doc, const QString &path, const QString &tag);
+ /**
+ * Reads a list of string pairs. See writePairListEntry().
+ */
+ static PairList readPairListEntry(const QDomDocument &doc, const QString &path, const QString &tag,
+ const QString &firstAttr, const QString &secondAttr);
+ /**
+ * Reads a string to string map. See writeMapEntry()
+ */
+ static QMap<QString, QString> readMapEntry(const QDomDocument &doc, const QString &path);
+ /**
+ * Retrieves an element by path, return null if any item along
+ * the path does not exist.
+ */
+ static QDomElement elementByPath( const QDomDocument& doc, const QString& path );
+ /**
+ * Retrieves an element by path, creating the necessary nodes.
+ */
+ static QDomElement createElementByPath( QDomDocument& doc, const QString& path );
+ /**
+ * Retrieves a child element, creating it if it does not exist.
+ * The return value is guaranteed to be non isNull()
+ */
+ static QDomElement namedChildElement( QDomElement& el, const QString& name );
+ /**
+ Writes a string entry. For example,
+ \verbatim
+ <code>
+ writeEntry(doc, "/general/special", "foo");
+ </code>
+ \endverbatim creates the %DOM fragment: \verbatim
+ <code>
+ <general><special>foo</special></general>
+ </code>
+ \endverbatim
+ */
+ static void writeEntry(QDomDocument &doc, const QString &path, const QString &value);
+ /**
+ * Writes a number entry.
+ */
+ static void writeIntEntry(QDomDocument &doc, const QString &path, int value);
+ /**
+ * Writes a boolean entry. Booleans are stored as "true", "false" resp.
+ */
+ static void writeBoolEntry(QDomDocument &doc, const QString &path, bool value);
+ /**
+ Writes a string list element. The list elements are separated by tag. For example,
+ \verbatim
+ <code>
+ QStringList l; l << "one" << "two";
+ writeListEntry(doc, "/general/special", "el", l);
+ </code>
+ \endverbatim creates the %DOM fragment: \verbatim
+ <code>
+ <general><special><el>one</el><el>two</el></special></general>
+ </code>
+ \endverbatim
+ */
+ static void writeListEntry(QDomDocument &doc, const QString &path, const QString &tag,
+ const QStringList &value);
+ /**
+ Writes a list of string pairs. The list elements are stored in the attributes
+ firstAttr and secondAttr of elements named tag. For example,
+ \verbatim
+ <code>
+ DomUtil::PairList l;
+ l << DomUtil::StringPair("one", "1");
+ l << DomUtil::StringPair("two", "2");
+ writePairListEntry(doc, "/general/special", "el", "first", "second", l);
+ </code>
+ \endverbatim creates the %DOM fragment: \verbatim
+ <code>
+ <general><special>
+ <el first="one" second="1"/>
+ <el first="two" second="2"/>
+ </special></general>
+ </code>
+ \endverbatim
+ */
+ static void writePairListEntry(QDomDocument &doc, const QString &path, const QString &tag,
+ const QString &firstAttr, const QString &secondAttr,
+ const PairList &value);
+ /**
+ * Writes a string to string map. This map is stored in a way, that it can be read with
+ * readMapEntry() and readEntry()
+ */
+ static void writeMapEntry(QDomDocument &doc, const QString& path, const QMap<QString,QString> &map);
+
+ /**
+ * Resolves an extended path
+ * Extended path format:
+ * pathpart: tag[|attr1=value[;attr2=value;..][|matchNumber]]
+ * where matchNumber is zero-based
+ * path: pathpart[/pathpart/..]
+ */
+ static DomPath resolvPathStringExt(const QString pathstring);
+
+ /**
+ Retrieve an element specified with extended path
+ examples:
+
+ - 1: "widget|class=QDialog/property|name=geometry"
+ or "widget|class=QDialog/property||1"
+ - 2: "widget/property|name=caption/string"
+ or "widget/property||2/string"
+ .
+ \verbatim
+ <widget class="QDialog">
+ <property name="name">
+ <cstring>KdevFormName</cstring>
+ </property>
+ <property name="geometry"> <-- 1. reaches this node
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>480</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>KdevFormCaption</string> <-- 2. reaches this node
+ </property>
+ </widget>
+ \endverbatim
+ */
+ static QDomElement elementByPathExt(QDomDocument &doc, const QString &pathstring);
+
+ /**
+ * Open file - filename - and set setContents of doc
+ */
+ static bool openDOMFile(QDomDocument &doc, QString filename);
+
+ /**
+ * Store contents of doc in file - filename. Existing file will be truncated!
+ */
+ static bool saveDOMFile(QDomDocument &doc, QString filename);
+
+ /**
+ * Remove all child text nodes of parent described in pathExt
+ */
+ static bool removeTextNodes(QDomDocument doc,QString pathExt);
+
+ /**
+ * Add child text node to parent described in pathExt
+ */
+ static bool appendText(QDomDocument doc, QString pathExt, QString text);
+
+ /**
+ * Replace all chilt text nodes of parent described in pathExt with one new.
+ */
+ static bool replaceText(QDomDocument doc, QString pathExt, QString text);
+
+private:
+ static QString readEntryAux(const QDomDocument &doc, const QString &path);
+};
+
+#endif
diff --git a/lib/util/execcommand.cpp b/lib/util/execcommand.cpp
new file mode 100644
index 00000000..73fc9320
--- /dev/null
+++ b/lib/util/execcommand.cpp
@@ -0,0 +1,101 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Harald Fernengel <harry@kdevelop.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 "execcommand.h"
+
+#include <kprocess.h>
+#include <kprogress.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+ExecCommand::ExecCommand( const QString& executable, const QStringList& args,
+ const QString& workingDir, const QStringList& env,
+ QObject* parent, const char* name ):
+ QObject( parent, name ), out( "" ) /* make sure out is not QString::null since that would mean "error" */
+
+{
+ progressDlg = 0;
+
+ proc = new KProcess();
+ proc->setWorkingDirectory( workingDir );
+ for ( QStringList::ConstIterator it = env.begin(); it != env.end(); ++it )
+ proc->setEnvironment( (*it).section( '=', 0, 0 ), (*it).section( '=', 1, 1 ) );
+ *proc << executable;
+ *proc << args;
+
+ connect( proc, SIGNAL(processExited(KProcess*)),
+ this, SLOT(processExited()) );
+ connect( proc, SIGNAL(receivedStdout(KProcess*,char*,int)),
+ this, SLOT(receivedStdout(KProcess*,char*,int)) );
+ connect( proc, SIGNAL(receivedStderr(KProcess*,char*,int)),
+ this, SLOT(receivedStderr(KProcess*,char*,int)) );
+
+ bool ok = proc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
+
+ if ( !ok ) {
+ KMessageBox::error( 0, i18n("Could not invoke \"%1\". Please make sure it is installed correctly").arg( executable ),
+ i18n("Error Invoking Command") );
+
+ emit finished( QString::null, QString::null );
+ deleteLater();
+
+ } else {
+ progressDlg = new KProgressDialog( 0, 0, i18n("Command running..."),
+ i18n("Please wait until the \"%1\" command finishes.").arg( executable ), false );
+ connect( progressDlg, SIGNAL(cancelClicked()),
+ this, SLOT(cancelClicked()) );
+ }
+}
+
+void ExecCommand::receivedStdout (KProcess*, char *buffer, int buflen)
+{
+ out += QString::fromUtf8( buffer, buflen );
+}
+
+void ExecCommand::receivedStderr (KProcess*, char *buffer, int buflen)
+{
+ err += QString::fromUtf8( buffer, buflen );
+}
+
+void ExecCommand::processExited()
+{
+ delete progressDlg;
+ progressDlg = 0;
+
+ emit finished( out, err );
+ deleteLater();
+}
+
+void ExecCommand::cancelClicked()
+{
+ delete progressDlg;
+ progressDlg = 0;
+ proc->kill();
+
+ emit finished( QString::null, QString::null );
+ deleteLater();
+}
+
+ExecCommand::~ExecCommand()
+{
+ delete proc;
+ delete progressDlg;
+}
+
+#include "execcommand.moc"
diff --git a/lib/util/execcommand.h b/lib/util/execcommand.h
new file mode 100644
index 00000000..b5545e0d
--- /dev/null
+++ b/lib/util/execcommand.h
@@ -0,0 +1,70 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Harald Fernengel <harry@kdevelop.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 _EXECCOMMAND_H_
+#define _EXECCOMMAND_H_
+
+#include <qobject.h>
+#include <qstringlist.h>
+
+class KProcess;
+class KProgressDialog;
+
+/**
+@file execcommand.h
+Command execution facilities.
+*/
+
+/**
+ * This class invokes a binary with the arguments passed in the constructor and
+ * emits the signal finished() with the output. It also displays
+ * a progress dialog with the possibility to cancel the command.
+ *
+ * If there was an error or the user pressed cancel, finished ()
+ * will emit a QString::null, otherwise QStrings containing the stdout/stderr.
+ *
+ * The object will delete itself after the finished signal has been emitted.
+ * Additional environment can be set in the QStringList env via QStrings with the format "foo=blah"
+ */
+class ExecCommand : public QObject
+{
+ Q_OBJECT
+public:
+ ExecCommand( const QString& executable, const QStringList& args,
+ const QString& workingDir = QString::null,
+ const QStringList& env = QStringList(), QObject* parent = 0, const char* name = 0 );
+ ~ExecCommand();
+
+signals:
+ void finished( const QString& output, const QString& errorOutput );
+
+private slots:
+ void receivedStdout (KProcess *, char *buffer, int buflen);
+ void receivedStderr (KProcess *, char *buffer, int buflen);
+ void processExited();
+ void cancelClicked();
+
+private:
+ KProcess* proc;
+ KProgressDialog* progressDlg;
+ QString out;
+ QString err;
+};
+
+#endif
diff --git a/lib/util/filetemplate.cpp b/lib/util/filetemplate.cpp
new file mode 100644
index 00000000..82221891
--- /dev/null
+++ b/lib/util/filetemplate.cpp
@@ -0,0 +1,128 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Sandy Meier <smeier@kdevelop.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 "filetemplate.h"
+
+#include <qdatetime.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+
+#include <kstandarddirs.h>
+
+#include "kdevplugin.h"
+#include "kdevproject.h"
+#include "domutil.h"
+
+
+bool FileTemplate::exists(KDevPlugin *part, const QString &name, Policy p)
+{
+ //QString fileName = (p == Default) ?
+ // (part->project()->projectDirectory() + "/templates/" + name) : name;
+
+ return QFile::exists( fullPathForName(part,name,p) );
+}
+
+QString FileTemplate::read(KDevPlugin *part, const QString &name, Policy p)
+{
+
+ //KDevProject *project = part->project();
+ //QString fileName = (p == Default) ? (project->projectDirectory() +
+// "/templates/" + name) : name;
+
+ return readFile(part, fullPathForName(part, name, p) );
+}
+
+QString FileTemplate::readFile(KDevPlugin *part, const QString &fileName)
+{
+ QDomDocument &dom = *part->projectDom();
+
+ QFile f(fileName);
+ if (!f.open(IO_ReadOnly))
+ return QString::null;
+ QTextStream stream(&f);
+ QString str = stream.read();
+
+ return makeSubstitutions( dom, str );
+}
+
+QString FileTemplate::makeSubstitutions( QDomDocument & dom, const QString & text )
+{
+ QString author = DomUtil::readEntry(dom, "/general/author");
+ QString email = DomUtil::readEntry(dom, "/general/email");
+ QString version = DomUtil::readEntry(dom, "/general/version");
+ QString appname = DomUtil::readEntry(dom, "/general/projectname");
+ QString date = QDate::currentDate().toString();
+ QString year = QString::number(QDate::currentDate().year());
+
+ QString str = text;
+ str.replace(QRegExp("\\$EMAIL\\$"),email);
+ str.replace(QRegExp("\\$AUTHOR\\$"),author);
+ str.replace(QRegExp("\\$VERSION\\$"),version);
+ str.replace(QRegExp("\\$DATE\\$"),date);
+ str.replace(QRegExp("\\$YEAR\\$"),year);
+ str.replace(QRegExp("\\$APPNAME\\$"),appname);
+ str.replace(QRegExp("\\$APPNAME\\$"),appname);
+ str.replace(QRegExp("\\$APPNAMEUC\\$"),appname.upper());
+ str.replace(QRegExp("\\$APPNAMELC\\$"),appname.lower());
+
+ return str;
+}
+
+
+bool FileTemplate::copy(KDevPlugin *part, const QString &name,
+ const QString &dest, Policy p)
+{
+ QString text = read(part, name, p);
+
+ QFile f(dest);
+ if (!f.open(IO_WriteOnly))
+ return false;
+
+ QFileInfo fi(f);
+ QString module = fi.baseName();
+ QString basefilename = fi.baseName(true);
+ text.replace(QRegExp("\\$MODULE\\$"),module);
+ text.replace(QRegExp("\\$FILENAME\\$"),basefilename);
+
+ QTextStream stream(&f);
+ stream << text;
+ f.close();
+
+ return true;
+}
+
+QString FileTemplate::fullPathForName(KDevPlugin *part, const QString &name,
+ Policy p) {
+ // if Policy is not default, full path is just the name
+ if (p!=Default) return name;
+
+ QString fileName;
+ // first try project-specific
+ if (part->project())
+ {
+ fileName = (part->project()->projectDirectory() + "/templates/" + name);
+ if (QFile::exists(fileName)) return fileName;
+ }
+
+ // next try global
+ QString globalName = ::locate("data", "kdevfilecreate/file-templates/" + name);
+ return globalName.isNull() ? fileName : globalName;
+}
diff --git a/lib/util/filetemplate.h b/lib/util/filetemplate.h
new file mode 100644
index 00000000..e126176d
--- /dev/null
+++ b/lib/util/filetemplate.h
@@ -0,0 +1,88 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Bernd Gehrmann <bernd@kdevelop.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 _FILETEMPLATE_H_
+#define _FILETEMPLATE_H_
+
+#include <qstring.h>
+
+class KDevPlugin;
+class QDomDocument;
+
+/**
+@file filetemplate.h
+FileTemplate class with utility methods to work with file templates.
+*/
+
+/**
+Utilities to work with file templates in the current project.
+*/
+class FileTemplate
+{
+public:
+
+ /**Policy of finding file templates.*/
+ typedef enum {
+ Default /**<Checks for templates in project and also for global filecreate templates.*/,
+ Custom /**<Checks for templates in custom directories. This usually means that
+ full paths are given for FileTemplate methods.*/
+ } Policy;
+
+ /**
+ * @return Whether a template with the given name
+ * exists in the current project. File templates
+ * are stored in the "templates" subdirectory of a project or in application shared dirs.
+ */
+ static bool exists(KDevPlugin *part, const QString &name, Policy p = Default);
+
+ /**
+ * Reads a template with the given name (e.g. "cpp")
+ * and makes variable substitutions (like $AUTHOR$ etc.)
+ * in it. The resulting string is returned.
+ */
+ static QString read(KDevPlugin *part, const QString &name, Policy p = Default);
+
+ /**
+ * Reads a template with the given URL
+ * and makes variable substitutions (like $AUTHOR$ etc.)
+ * in it. The resulting string is returned.
+ */
+ static QString readFile(KDevPlugin *part, const QString &fileName);
+
+ /**
+ * Makes variable substitutions on a text, based on a specified QDomDocument
+ * describing a KDevelop project file. The resulting string is returned.
+ */
+ static QString makeSubstitutions(QDomDocument &dom, const QString &text);
+
+ /**
+ * Copies a file template with the given name to the
+ * file with the name dest and - while copying -
+ * performs variable substitutions.
+ */
+ static bool copy(KDevPlugin *part, const QString &name,
+ const QString &dest, Policy p = Default);
+ /**
+ * Translates a template name into a full path, or suggests a full path
+ * for the template in the project directory if it doesn't exist.
+ */
+ static QString fullPathForName(KDevPlugin *part, const QString &name, Policy p = Default);
+};
+
+#endif
diff --git a/lib/util/kdeveditorutil.cpp b/lib/util/kdeveditorutil.cpp
new file mode 100644
index 00000000..fdf044d5
--- /dev/null
+++ b/lib/util/kdeveditorutil.cpp
@@ -0,0 +1,89 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Jens Dagerbo *
+ * jens.dagerbo@swipnet.se *
+ * *
+ * 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 "kdeveditorutil.h"
+
+#include <ktexteditor/document.h>
+#include <ktexteditor/view.h>
+#include <ktexteditor/viewcursorinterface.h>
+#include <ktexteditor/editinterface.h>
+#include <ktexteditor/selectioninterface.h>
+
+bool KDevEditorUtil::currentPositionReal( unsigned int * line, unsigned int * col, KTextEditor::Document * doc, KTextEditor::View * view )
+{
+ if ( !line || !col ) return false;
+
+ KTextEditor::EditInterface * editIface = dynamic_cast<KTextEditor::EditInterface*>( doc );
+ if ( !editIface ) return false;
+
+ view = view ? view : dynamic_cast<KTextEditor::View*>( doc->widget() );
+
+ KTextEditor::ViewCursorInterface * cursorIface = dynamic_cast<KTextEditor::ViewCursorInterface*>( view );
+ if ( !cursorIface ) return false;
+
+ cursorIface->cursorPositionReal( line, col );
+ return true;
+}
+
+QString KDevEditorUtil::currentLine( KTextEditor::Document * doc, KTextEditor::View * view )
+{
+ KTextEditor::EditInterface * editIface = dynamic_cast<KTextEditor::EditInterface*>( doc );
+ if ( !editIface ) return QString();
+
+ view = view ? view : dynamic_cast<KTextEditor::View*>( doc->widget() );
+
+ KTextEditor::ViewCursorInterface * cursorIface = dynamic_cast<KTextEditor::ViewCursorInterface*>( view );
+ if ( !cursorIface ) return QString();
+
+ uint line = 0;
+ uint col = 0;
+ cursorIface->cursorPositionReal(&line, &col);
+
+ return editIface->textLine(line);
+}
+
+QString KDevEditorUtil::currentWord( KTextEditor::Document * doc, KTextEditor::View * view )
+{
+ KTextEditor::EditInterface * editIface = dynamic_cast<KTextEditor::EditInterface*>( doc );
+ if ( !editIface ) return QString();
+
+ view = view ? view : dynamic_cast<KTextEditor::View*>( doc->widget() );
+
+ KTextEditor::ViewCursorInterface * cursorIface = dynamic_cast<KTextEditor::ViewCursorInterface*>( view );
+ if ( !cursorIface ) return QString();
+
+ uint line = 0;
+ uint col = 0;
+ cursorIface->cursorPositionReal(&line, &col);
+
+ QString linestr = editIface->textLine(line);
+
+ int startPos = QMAX( QMIN( (int)col, (int)linestr.length()-1 ), 0 );
+ int endPos = startPos;
+ startPos--;
+ while (startPos >= 0 && ( linestr[startPos].isLetterOrNumber() || linestr[startPos] == '_' || linestr[startPos] == '~') )
+ startPos--;
+ while (endPos < (int)linestr.length() && ( linestr[endPos].isLetterOrNumber() || linestr[endPos] == '_' ) )
+ endPos++;
+
+ return ( ( startPos == endPos ) ? QString::null : linestr.mid( startPos+1, endPos-startPos-1 ) );
+}
+
+
+QString KDevEditorUtil::currentSelection( KTextEditor::Document * doc )
+{
+ KTextEditor::SelectionInterface * selectIface = dynamic_cast<KTextEditor::SelectionInterface*>( doc );
+ return selectIface ? selectIface->selection() : QString();
+}
+
+
+// kate: space-indent off; indent-width 4; tab-width 4; show-tabs on;
+
diff --git a/lib/util/kdeveditorutil.h b/lib/util/kdeveditorutil.h
new file mode 100644
index 00000000..7b788fc3
--- /dev/null
+++ b/lib/util/kdeveditorutil.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Jens Dagerbo *
+ * jens.dagerbo@swipnet.se *
+ * *
+ * 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 KDEVEDITOR_H
+#define KDEVEDITOR_H
+
+namespace KTextEditor
+{
+class Document;
+class View;
+}
+
+#include <qstring.h>
+
+/**
+Class with some common utility operations not currently supported by KTE
+
+ @author Jens Dagerbo <jens.dagerbo@swipnet.se>
+*/
+class KDevEditorUtil
+{
+ KDevEditorUtil() {}
+public:
+
+ /**
+ *
+ * @param line
+ * @param col
+ * @param doc
+ * @param view
+ * @return
+ */
+ static bool currentPositionReal( unsigned int * line, unsigned int * col, KTextEditor::Document * doc, KTextEditor::View * view = 0 );
+
+ /**
+ *
+ * @param doc
+ * @param view
+ * @return
+ */
+ static QString currentLine( KTextEditor::Document * doc, KTextEditor::View * view = 0 );
+
+ /**
+ * Call to get the text under the cursor of the currently active view.
+ * @return the text under the cursor of the currently active view
+ */
+ static QString currentWord( KTextEditor::Document * doc, KTextEditor::View * view = 0 );
+
+ /**
+ * Call to get the selection in the currently active view
+ * @return the selection in the currently active view
+ */
+ static QString currentSelection( KTextEditor::Document * doc );
+};
+
+#endif
+
+
+// kate: space-indent off; indent-width 4; tab-width 4; show-tabs on;
diff --git a/lib/util/kdevjobtimer.cpp b/lib/util/kdevjobtimer.cpp
new file mode 100644
index 00000000..b7f9e2ae
--- /dev/null
+++ b/lib/util/kdevjobtimer.cpp
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Jens Dagerbo *
+ * jens.dagerbo@swipnet.se *
+ * *
+ * 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 "kdevjobtimer.h"
+
+KDevJobTimer::KDevJobTimer( void * payload, QObject *parent, const char *name)
+ : QTimer(parent, name)
+{
+ m_payload = payload;
+ connect( this, SIGNAL(timeout()), this, SLOT(slotTimeout()) );
+}
+
+KDevJobTimer::~KDevJobTimer()
+{
+}
+
+void KDevJobTimer::singleShot(int msec, QObject * receiver, const char * member, void * payload)
+{
+ KDevJobTimer * p = new KDevJobTimer( payload );
+ p->start( msec, true );
+ connect( p, SIGNAL(timeout(void*)), receiver, member );
+}
+
+void KDevJobTimer::slotTimeout()
+{
+ emit timeout( m_payload );
+ m_payload = 0;
+ deleteLater();
+}
+
+#include "kdevjobtimer.moc"
diff --git a/lib/util/kdevjobtimer.h b/lib/util/kdevjobtimer.h
new file mode 100644
index 00000000..972a654a
--- /dev/null
+++ b/lib/util/kdevjobtimer.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Jens Dagerbo *
+ * jens.dagerbo@swipnet.se *
+ * *
+ * 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 KDEVJOBTIMER_H
+#define KDEVJOBTIMER_H
+
+#include <qtimer.h>
+
+class KDevJobTimer : public QTimer
+{
+Q_OBJECT
+public:
+ static void singleShot( int msec, QObject * receiver, const char * member, void * payload );
+
+signals:
+ void timeout(void*);
+
+private:
+ KDevJobTimer( void * payload, QObject *parent = 0, const char *name = 0);
+ ~KDevJobTimer();
+
+private slots:
+ void slotTimeout();
+
+private:
+ void * m_payload;
+
+};
+
+
+#endif
diff --git a/lib/util/kdevshellwidget.cpp b/lib/util/kdevshellwidget.cpp
new file mode 100644
index 00000000..f9a61fea
--- /dev/null
+++ b/lib/util/kdevshellwidget.cpp
@@ -0,0 +1,125 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Jens Dagerbo *
+ * jens.dagerbo@swipnet.se *
+ * *
+ * 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 <qtimer.h>
+#include <qframe.h>
+
+#include <kdebug.h>
+#include <kparts/part.h>
+#include <klibloader.h>
+#include <kde_terminal_interface.h>
+#include <kprocess.h>
+
+#include "kdevshellwidget.h"
+
+KDevShellWidget::KDevShellWidget(QWidget *parent, const char *name)
+ : QVBox(parent, name), m_doAutoActivate( false ), m_isRunning( false )
+{
+}
+
+
+KDevShellWidget::~KDevShellWidget()
+{
+}
+
+void KDevShellWidget::setShell( const QString & shell, const QStrList & arguments )
+{
+ m_shellName = shell;
+ m_shellArguments = arguments;
+}
+
+void KDevShellWidget::activate( )
+{
+ KLibFactory *factory = KLibLoader::self()->factory("libkonsolepart");
+ if ( !factory ) return;
+
+ m_konsolePart = (KParts::ReadOnlyPart *) factory->create( this, "libkonsolepart", "KParts::ReadOnlyPart" );
+ if ( !m_konsolePart ) return;
+
+ connect( m_konsolePart, SIGNAL( processExited(KProcess *) ), this, SLOT( processExited(KProcess *) ) );
+ connect( m_konsolePart, SIGNAL( receivedData( const QString& ) ), this, SIGNAL( receivedData( const QString& ) ) );
+ connect( m_konsolePart, SIGNAL(destroyed()), this, SLOT(partDestroyed()) );
+
+ m_konsolePart->widget()->setFocusPolicy( QWidget::WheelFocus );
+ setFocusProxy( m_konsolePart->widget() );
+ m_konsolePart->widget()->setFocus();
+
+ if ( m_konsolePart->widget()->inherits("QFrame") )
+ ((QFrame*)m_konsolePart->widget())->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+
+ m_konsolePart->widget()->show();
+
+ TerminalInterface* ti = static_cast<TerminalInterface*>( m_konsolePart->qt_cast( "TerminalInterface" ) );
+ if( !ti ) return;
+
+ if ( !m_shellName.isEmpty() )
+ ti->startProgram( m_shellName, m_shellArguments );
+
+ m_isRunning = true;
+
+}
+
+void KDevShellWidget::partDestroyed( )
+{
+ if ( m_doAutoActivate )
+ {
+ activate();
+ }
+}
+
+void KDevShellWidget::processExited( KProcess * proc )
+{
+ m_isRunning = false;
+
+ if ( !proc ) return;
+
+ kdDebug(9000) << proc->args() << endl;
+
+ if ( proc->normalExit() )
+ emit shellExited( proc->exitStatus() );
+ else if ( proc->signalled() )
+ emit shellSignalled( proc->exitSignal() );
+}
+
+void KDevShellWidget::sendInput( const QString & text )
+{
+ if ( !m_konsolePart ) return;
+ TerminalInterface* ti = static_cast<TerminalInterface*>( m_konsolePart->qt_cast( "TerminalInterface" ) );
+ if( !ti ) return;
+
+ ti->sendInput( text );
+}
+
+bool KDevShellWidget::isRunning( )
+{
+ return m_isRunning;
+}
+
+void KDevShellWidget::setAutoReactivateOnClose( bool doAutoActivate )
+{
+ // to auto reactivate can be dangerous, do it like this to avoid
+ // reactivating with a non-working setting (the partDestroyed()
+ // slot will have ran before m_doAutoActivate is set)
+ if ( doAutoActivate )
+ QTimer::singleShot( 3000, this, SLOT(setAutoReactivateOnCloseDelayed()) );
+ else
+ m_doAutoActivate = false;
+}
+
+void KDevShellWidget::setAutoReactivateOnCloseDelayed( )
+{
+ m_doAutoActivate = true;
+}
+
+
+#include "kdevshellwidget.moc"
+
+// kate: space-indent off; indent-width 4; tab-width 4; show-tabs off;
diff --git a/lib/util/kdevshellwidget.h b/lib/util/kdevshellwidget.h
new file mode 100644
index 00000000..3f1500aa
--- /dev/null
+++ b/lib/util/kdevshellwidget.h
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Jens Dagerbo *
+ * jens.dagerbo@swipnet.se *
+ * *
+ * 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 KDEVSHELLWIDGET_H
+#define KDEVSHELLWIDGET_H
+
+#include <qstrlist.h>
+#include <qvbox.h>
+#include <qguardedptr.h>
+
+class KProcess;
+namespace KParts
+{
+ class ReadOnlyPart;
+}
+
+class KDevShellWidget : public QVBox
+{
+
+Q_OBJECT
+
+public:
+ KDevShellWidget(QWidget *parent = 0, const char *name = 0);
+ virtual ~KDevShellWidget();
+
+ /**
+ * Stores the shell name and arguments, that will be used in @ref activate()
+ * @param shell The shell name, for example 'irb' or '/bin/bash'
+ * @param arguments Any optional arguments
+ */
+ void setShell( const QString & shell, const QStrList & arguments = QStrList() );
+
+ /**
+ * Executes the previously set shell. If @ref setShell wasn't called before
+ * konsolepart will decide what to use.
+ */
+ void activate();
+
+ /**
+ * Should we auto launch the shell again if it was terminated?
+ * @param doAutoActivate
+ */
+ void setAutoReactivateOnClose( bool doAutoActivate );
+
+ /**
+ * Send text to the running shell
+ * @param text The text to send to the shell
+ */
+ void sendInput( const QString & text );
+
+ /**
+ * Call to check if the shell is currently running
+ * @return true if the shell is currently running
+ */
+ bool isRunning();
+
+signals:
+ /**
+ * This signal will be emmitted when the started shell exits normally
+ * @param exitcode The return code of the process
+ */
+ void shellExited( int exitcode );
+
+ /**
+ * This signal will be emitted when the started shell is terminated by a signal
+ * @param signalcode The signal the process was killed with
+ */
+ void shellSignalled( int signalcode );
+
+ /**
+ * This signal will be emitted when the process receives data
+ * @param text received data
+ */
+ void receivedData( const QString & );
+
+private slots:
+ void partDestroyed();
+ void processExited( KProcess * );
+ void setAutoReactivateOnCloseDelayed( );
+
+private:
+ QGuardedPtr<KParts::ReadOnlyPart> m_konsolePart;
+ QString m_shellName;
+ QStrList m_shellArguments;
+ bool m_doAutoActivate;
+ bool m_isRunning;
+};
+
+#endif
+
+// kate: space-indent off; indent-width 4; tab-width 4; show-tabs off;
diff --git a/lib/util/kscriptactionmanager.cpp b/lib/util/kscriptactionmanager.cpp
new file mode 100644
index 00000000..cf73e949
--- /dev/null
+++ b/lib/util/kscriptactionmanager.cpp
@@ -0,0 +1,177 @@
+/***************************************************************************
+* Copyright (C) 2004 by ian geiser *
+* geiseri@sourcextreme.com *
+* *
+* 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. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+***************************************************************************/
+#include "kscriptactionmanager.h"
+#include <kparts/part.h>
+#include <kparts/componentfactory.h>
+#include <kapplication.h>
+#include <kdesktopfile.h>
+#include <kstandarddirs.h>
+
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <scriptinterface.h>
+#include <kaction.h>
+#include <qfileinfo.h>
+#include <qtimer.h>
+
+KScriptAction::KScriptAction( const QString &scriptDesktopFile, QObject *interface, KActionCollection *ac )
+ : QObject(interface), KScriptClientInterface( )
+{
+ m_interface = 0L;
+ m_action = 0L;
+ m_isValid = false;
+ m_refs = 0;
+ // Read the desktop file
+ if(KDesktopFile::isDesktopFile(scriptDesktopFile))
+ {
+ KDesktopFile desktop(scriptDesktopFile, true);
+ QFileInfo scriptPath(scriptDesktopFile);
+
+ m_scriptFile = scriptPath.dirPath(true) + "/" + desktop.readEntry("X-KDE-ScriptName", "");
+ m_scriptName = desktop.readName();
+ m_scriptType = desktop.readType();
+ QString scriptTypeQuery = "([X-KDE-Script-Runner] == '" + m_scriptType + "')";
+ KTrader::OfferList offers = KTrader::self()->query( "KScriptRunner/KScriptRunner", scriptTypeQuery );
+ if ( !offers.isEmpty() )
+ {
+ m_action = new KAction(m_scriptName, KShortcut(), this, SLOT(activate()), ac, "script");
+ m_isValid = true;
+ m_timeout = new QTimer(this);
+ QString icon = desktop.readIcon();
+ m_action->setStatusText(desktop.readComment());
+ if( !icon.isEmpty() )
+ m_action->setIcon(icon);
+ m_action->setShortcutConfigurable(true);
+ connect( m_timeout, SIGNAL(timeout()), SLOT(cleanup()) );
+ }
+ }
+}
+
+KScriptAction::~KScriptAction()
+{
+ if( m_interface ) delete m_interface;
+ if( m_action ) delete m_action;
+}
+
+
+
+KAction * KScriptAction::action( )
+{
+ return m_action;
+}
+
+void KScriptAction::activate( )
+{
+ if( m_interface == 0L)
+ {
+ QString scriptTypeQuery = "([X-KDE-Script-Runner] == '" + m_scriptType + "')";
+ m_interface= KParts::ComponentFactory::createInstanceFromQuery<KScriptInterface>( "KScriptRunner/KScriptRunner", scriptTypeQuery, this );
+ if ( m_interface != 0L)
+ {
+ m_interface->ScriptClientInterface= this;
+ if( m_scriptMethod.isEmpty() )
+ m_interface->setScript(m_scriptFile);
+ else
+ m_interface->setScript(m_scriptFile, m_scriptMethod);
+ connect(this, SIGNAL(done(KScriptClientInterface::Result, const QVariant &)), this, SLOT(scriptFinished()));
+ }
+ else
+ {
+ KMessageBox::sorry(0, i18n("Unable to get KScript Runner for type \"%1\".").arg(m_scriptType), i18n("KScript Error"));
+ kdDebug() << "Query string: " << scriptTypeQuery << endl;
+ return;
+ }
+ }
+ m_interface->run(parent(), QVariant());
+ m_timeout->start(60000,FALSE); // after 1 minute unload
+ m_refs++;
+}
+
+void KScriptAction::cleanup()
+{
+ if( m_interface && m_refs == 0)
+ {
+ delete m_interface;
+ m_interface = 0L;
+ }
+}
+
+void KScriptAction::scriptFinished()
+{
+ m_refs--;
+}
+
+KScriptActionManager::KScriptActionManager( QObject *parent, KActionCollection * ac ) : QObject(parent), m_ac(ac)
+{
+ m_actions.setAutoDelete(true);
+}
+
+KScriptActionManager::~ KScriptActionManager( )
+{
+ m_actions.clear();
+}
+
+QPtrList< KAction > KScriptActionManager::scripts( QObject * interface , const QStringList &dirs) const
+{
+ m_actions.clear();
+ QPtrList<KAction> actions;
+ QStringList scripts;
+
+ scripts += KGlobal::dirs()->findAllResources("data",
+ QString(kapp->name())+"/scripts/*.desktop", false, true );
+
+ for( QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it)
+ {
+ scripts += KGlobal::dirs()->findAllResources("data",
+ (*it)+"/*.desktop", false, true );
+ }
+
+ for (QStringList::Iterator it = scripts.begin(); it != scripts.end(); ++it )
+ {
+ kdDebug() << "Loading " << *it << endl;
+ KScriptAction *script = new KScriptAction(*it, interface, m_ac);
+ if( script->isValid())
+ {
+ actions.append(script->action());
+ m_actions.append(script);
+ connect(script, SIGNAL(error( const QString&)), this,
+ SIGNAL(scriptError( const QString&)));
+ connect(script, SIGNAL(warning( const QString&)), this,
+ SIGNAL(scriptWarning( const QString&)));
+ connect(script, SIGNAL(output( const QString&)), this,
+ SIGNAL(scriptOutput( const QString&)));
+ connect(script, SIGNAL(progress( int )), this,
+ SIGNAL(scriptProgress(int)));
+ connect(script, SIGNAL(done( KScriptClientInterface::Result, const QVariant &)),this,
+ SIGNAL(scriptDone( KScriptClientInterface::Result, const QVariant &)));
+ }
+ else
+ delete script;
+ }
+ return actions;
+}
+
+bool KScriptAction::isValid( ) const
+{
+ return m_isValid;
+}
+
+#include "kscriptactionmanager.moc"
diff --git a/lib/util/kscriptactionmanager.h b/lib/util/kscriptactionmanager.h
new file mode 100644
index 00000000..234e4a3c
--- /dev/null
+++ b/lib/util/kscriptactionmanager.h
@@ -0,0 +1,139 @@
+/***************************************************************************
+* Copyright (C) 2004 by ian geiser *
+* geiseri@sourcextreme.com *
+* *
+* 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. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+***************************************************************************/
+#ifndef KScriptAction_H
+#define KScriptAction_H
+
+#include <scriptclientinterface.h>
+#include <qobject.h>
+#include <qptrlist.h>
+
+class KAction;
+class KActionCollection;
+class KScriptInterface;
+class KScriptActionManager;
+class QTimer;
+
+/**
+* Connects a KAction to a script runner.
+*
+* @author ian geiser geiseri@sourcextreme.com
+*/
+class KScriptAction : public QObject, public KScriptClientInterface {
+ Q_OBJECT
+public:
+
+ KScriptAction( const QString &scriptDesktopFile, QObject *interface, KActionCollection *ac );
+
+ virtual ~KScriptAction();
+
+ /**
+ * KAction for the current script
+ */
+ KAction *action();
+
+ /**
+ * Returns the validity of the current script.
+ */
+ bool isValid() const;
+
+signals:
+ // Reimplemented from KScript
+ void error ( const QString &msg );
+ void warning ( const QString &msg );
+ void output ( const QString &msg );
+ void progress ( int percent );
+ void done ( KScriptClientInterface::Result result, const QVariant &returned );
+
+signals:
+ void scriptError ( const QString &msg );
+ void scriptWarning ( const QString &msg );
+ void scriptOutput ( const QString &msg );
+ void scriptProgress ( int percent );
+ void scriptDone ( KScriptClientInterface::Result result, const QVariant &returned );
+
+private slots:
+ void activate();
+ void cleanup();
+ void scriptFinished();
+
+private:
+ KAction *m_action;
+ QString m_scriptName;
+ QString m_scriptType;
+ QString m_scriptFile;
+ QString m_scriptMethod;
+ KScriptInterface *m_interface;
+ bool m_isValid;
+ QTimer *m_timeout;
+ uint m_refs;
+};
+
+/**
+ * Provides an actionlist of scripts that are currently available.
+ * Scripts are not actually loaded until they are actually executed.
+ * @author ian geiser <geiseri@sourcextreme.com>
+ */
+class KScriptActionManager : public QObject {
+Q_OBJECT
+
+public:
+ /**
+ * Create a script manager that is attached to an action collection.
+ */
+ KScriptActionManager( QObject *parent, KActionCollection *ac );
+ ~KScriptActionManager();
+
+ /**
+ * Return all currently loaded scripts in a direcotry and attaches them
+ * to a QObject interface. If the dirs are empty the current applications
+ * scripts directory is used. The dirs are actual directories to search
+ * in the $KDEPATH/data/ direcories. So if you add "coolapp/data" then
+ * the manager will search in $KDEPATH/data/coolapp/data for all desktop
+ * files that are scripts.
+ */
+ QPtrList<KAction> scripts( QObject *interface, const QStringList &dirs = QStringList() ) const;
+
+signals:
+ /**
+ * Returns an error message from a script.
+ */
+ void scriptError ( const QString &msg );
+ /**
+ * Returns a warning message from a script.
+ */
+ void scriptWarning ( const QString &msg );
+ /**
+ * Returns a standard out message from a script.
+ */
+ void scriptOutput ( const QString &msg );
+ /**
+ * Returns the percentage complete of an operation in the script.
+ */
+ void scriptProgress ( int percent );
+ /**
+ * Notifies that the script has finished.
+ */
+ void scriptDone( KScriptClientInterface::Result result, const QVariant &returned );
+
+private:
+ mutable QPtrList<KScriptAction> m_actions;
+ KActionCollection *m_ac;
+};
+#endif
diff --git a/lib/util/rurl.cpp b/lib/util/rurl.cpp
new file mode 100644
index 00000000..1ec23434
--- /dev/null
+++ b/lib/util/rurl.cpp
@@ -0,0 +1,369 @@
+#include <qstringlist.h>
+
+#include "rurl.h"
+
+namespace Relative{
+
+
+//class Name
+
+Name::Name( const QString & rurl, const Type type )
+ :m_rurl(rurl), m_type(type)
+{
+ correct();
+}
+
+Name::Name( const char * rurl, const Type type )
+ :m_rurl(rurl), m_type(type)
+{
+ correct();
+}
+
+void Name::correct()
+{
+ cleanRURL();
+ if (m_rurl[0] == '/')
+ m_rurl = m_rurl.mid(1);
+ switch (m_type)
+ {
+ case File:
+ if (m_rurl.endsWith("/"))
+ m_rurl = m_rurl.mid(0, m_rurl.length()-1);
+ break;
+ case Directory:
+ if (!m_rurl.endsWith("/"))
+ m_rurl += "/";
+ break;
+ case Auto:
+ if (m_rurl.endsWith("/"))
+ m_type = Directory;
+ else
+ m_type = File;
+ break;
+ }
+}
+
+QString Name::correctName( const QString & rurl, const Type type )
+{
+ QString temp = rurl;
+ temp = Name::cleanName(temp);
+ if (temp[0] == '/')
+ temp = temp.mid(1);
+
+ switch (type)
+ {
+ case File:
+ if (temp.endsWith("/"))
+ temp = temp.mid(0, temp.length()-1);
+ break;
+ case Directory:
+ if (!temp.endsWith("/"))
+ temp += "/";
+ break;
+ }
+
+ return temp;
+}
+
+void Name::setRURL( const QString & rurl, const Type type )
+{
+ m_rurl = rurl;
+ m_type = type;
+ correct();
+}
+
+QString Name::rurl( ) const
+{
+ return m_rurl;
+}
+
+void Name::addPath( const QString & addendum )
+{
+ QString temp = correctName(addendum, Directory);
+ m_rurl = directory() + temp + fileName();
+}
+
+void Name::cleanRURL( )
+{
+ m_rurl = cleanName(m_rurl);
+}
+
+QString Name::cleanName( const QString & rurl )
+{
+ QString temp;
+ bool wasSlash = false;
+ for (unsigned int i = 0; i < rurl.length(); ++i)
+ {
+ if (wasSlash && (rurl[i] == '/'))
+ continue;
+
+ temp += rurl[i];
+ if (rurl[i] == '/')
+ wasSlash = true;
+ else if (wasSlash)
+ wasSlash = false;
+ }
+
+ return temp;
+}
+
+QString Name::extension( bool complete ) const
+{
+ if (m_type == File)
+ {
+ QString temp = fileName();
+ if (complete)
+ return temp.mid(temp.find('.')+1);
+ else
+ return temp.mid(temp.findRev('.')+1);
+ }
+ return QString::null;
+}
+
+QString Name::fileName( ) const
+{
+ if (m_type == File)
+ return m_rurl.section('/', -1);
+ return QString::null;
+}
+
+QString Name::directory( ) const
+{
+ if ( (m_type == File) && (m_rurl.findRev('/') == -1) )
+ return QString::null;
+
+ return m_rurl.mid(0, m_rurl.findRev('/')+1);
+}
+
+bool Name::isFile( ) const
+{
+ return m_type == File;
+}
+
+bool Name::isDirectory( ) const
+{
+ return m_type == Directory;
+}
+
+bool Name::operator ==( const Name & rname )
+{
+ return rname.rurl() == m_rurl;
+}
+
+bool Name::operator !=( const Name & rname )
+{
+ return rname.rurl() != m_rurl;
+}
+
+bool Name::isValid( ) const
+{
+ if (m_rurl.startsWith("/"))
+ return false;
+ if (m_rurl.contains("//"))
+ return false;
+ if ( (m_rurl.endsWith("/")) && (m_type == File) )
+ return false;
+ if ( (!m_rurl.endsWith("/")) && (m_type == Directory) )
+ return false;
+ if (m_type == Auto)
+ return false;
+
+ return true;
+}
+
+Name::Type Name::type( ) const
+{
+ return m_type;
+}
+
+void Name::setType( const Type type )
+{
+ m_type = type;
+}
+
+Name Name::relativeName( const QString &base, const QString &url )
+{
+ QString dirUrl = base;
+ QString fileUrl = url;
+
+ if (dirUrl.isEmpty() || (dirUrl == "/"))
+ return Name(fileUrl);
+
+ QStringList dir = QStringList::split("/", dirUrl, false);
+ QStringList file = QStringList::split("/", fileUrl, false);
+
+ QString resFileName = file.last();
+ if (url.endsWith("/"))
+ resFileName += "/";
+ file.remove(file.last());
+
+ uint i = 0;
+ while ( (i < dir.count()) && (i < (file.count())) && (dir[i] == file[i]) )
+ i++;
+
+ QString result_up;
+ QString result_down;
+ QString currDir;
+ QString currFile;
+ do
+ {
+ i >= dir.count() ? currDir = "" : currDir = dir[i];
+ i >= file.count() ? currFile = "" : currFile = file[i];
+// qWarning("i = %d, currDir = %s, currFile = %s", i, currDir.latin1(), currFile.latin1());
+ if (currDir.isEmpty() && currFile.isEmpty())
+ break;
+ else if (currDir.isEmpty())
+ result_down += file[i] + "/";
+ else if (currFile.isEmpty())
+ result_up += "../";
+ else
+ {
+ result_down += file[i] + "/";
+ result_up += "../";
+ }
+ i++;
+ }
+ while ( (!currDir.isEmpty()) || (!currFile.isEmpty()) );
+
+ return result_up + result_down + resFileName;
+}
+
+
+
+//class URL
+
+URL::URL( KURL base, KURL url, Type type )
+ :Name(Name::relativeName(base.path(), url.path()).rurl(), type), m_base(base)
+{
+}
+
+URL::URL( KURL base, QString url, bool isUrlRelative, Type type )
+ :Name(isUrlRelative ? url : Name::relativeName(base.path(), url).rurl(), type), m_base(base)
+{
+}
+
+void URL::setBase( const KURL & base )
+{
+ m_base = base;
+}
+
+void URL::setBase( const QString & base )
+{
+ KURL url;
+ url.setPath(base);
+ m_base = url;
+}
+
+KURL URL::base( ) const
+{
+ return m_base;
+}
+
+QString URL::basePath( ) const
+{
+ return m_base.path(1);
+}
+
+KURL URL::url( ) const
+{
+ KURL url = m_base;
+ url.addPath(rurl());
+ url.cleanPath();
+ return url;
+}
+
+QString URL::urlPath( ) const
+{
+ KURL url = m_base;
+ url.addPath(rurl());
+ int mod = 0;
+ if (type() == File)
+ mod = -1;
+ else if (type() == Directory)
+ mod = 1;
+ url.cleanPath();
+ return url.path(mod);
+}
+
+QString URL::urlDirectory( ) const
+{
+ KURL url = m_base;
+ url.addPath(rurl());
+ url.cleanPath();
+ return url.directory(false, false);
+}
+
+URL URL::relativeTo( KURL base )
+{
+ return URL(base, url(), type());
+}
+
+URL URL::relativeURL( KURL base, KURL url )
+{
+ return URL(base, url);
+}
+
+URL URL::relativeURL( KURL base, QString url, bool isUrlRelative )
+{
+ return URL(base, url, isUrlRelative);
+}
+
+bool Relative::URL::operator ==( const URL & url )
+{
+ return (m_base == url.base()) && (rurl() == url.rurl());
+}
+
+bool Relative::URL::operator !=( const URL & url )
+{
+ return (m_base != url.base()) || (rurl() != url.rurl());
+}
+
+
+
+// Directory class
+
+Directory::Directory( KURL base, KURL url )
+ :URL(base, url, Name::Directory)
+{
+}
+
+Directory::Directory( KURL base, QString url, bool isRelativeUrl )
+ :URL(base, url, isRelativeUrl, Name::Directory)
+{
+}
+
+void Directory::setRURL( QString rurl )
+{
+ URL::setRURL(rurl, Name::Directory);
+}
+
+void Directory::setRURL( QString rurl, Type type )
+{
+ URL::setRURL(rurl, type);
+}
+
+
+
+//File class
+
+File::File( KURL base, KURL url )
+ :URL(base, url, Name::File)
+{
+}
+
+File::File( KURL base, QString url, bool isRelativeUrl )
+ :URL(base, url, isRelativeUrl, Name::File)
+{
+}
+
+void File::setRURL( QString rurl, Type type )
+{
+ URL::setRURL(rurl, type);
+}
+
+void File::setRURL( QString rurl )
+{
+ URL::setRURL(rurl, Name::File);
+}
+
+}
diff --git a/lib/util/rurl.h b/lib/util/rurl.h
new file mode 100644
index 00000000..342b3e3d
--- /dev/null
+++ b/lib/util/rurl.h
@@ -0,0 +1,182 @@
+#ifndef RURL_H_LIB
+#define RURL_H_LIB
+
+#include <kurl.h>
+
+/**
+@file rurl.h
+Classes and functions to work with relative URLs.
+*/
+
+/**Classes and functions to work with relative URLs.*/
+namespace Relative
+{
+
+/**Relative name of a file or directory.*/
+class Name{
+public:
+ enum Type { File, Directory, Auto };
+
+ /**Constructor takes the relative name of a directory or file.
+ Leading slash in the name will be deleted.
+ If type is Auto names like:
+ name/name/ are directories
+ name/name are files.
+ Trailing slash will be deleted for files (type == File).*/
+ Name(const QString &rurl, const Type type = Auto);
+ Name(const char *rurl, const Type type = Auto);
+
+ /**Sets the relative name.*/
+ void setRURL(const QString &rurl, const Type type);
+ /**Gets the relative name in form
+ dir/dir/ -> directory
+ or
+ dir/dir/file -> file.*/
+ QString rurl() const;
+
+ /**Adds addendum to the directory path. This honors file names so
+ if RName represents /dir1/dir2/fname.ext
+ addPath(dir3) will change RName to /dir1/dir2/dir3/fname.ext*/
+ void addPath(const QString &addendum);
+ /**Removes "//" from the name.*/
+ void cleanRURL();
+
+ /**Returns the extension of a file or QString::null for directories.
+ If complete is true then returns extensions like "tar.gz".
+ Else returns "gz".*/
+ QString extension(bool complete = true) const;
+ /**Returns the name of the file without the path or QString::null
+ for directories.*/
+ QString fileName() const;
+ /**Returns the name of the directory or QString::null if there are no dirs in path.*/
+ QString directory() const;
+
+ /**Returns true if the type of RName is file.*/
+ bool isFile() const;
+ /**Returns true if the type of RName is directory.*/
+ bool isDirectory() const;
+ /**Checks if RName is valid.*/
+ bool isValid() const;
+
+ /**Returns a type of the relative name - file or directory.*/
+ Type type() const;
+ /**Sets a type of the relative name - file or directory.
+ If Auto is passed, nothing happens.*/
+ void setType(const Type type);
+
+ /**Creates and returns relative name between base and url. Base and url should be absolute.
+ Base is considered to be a directory.*/
+ static Name relativeName(const QString &base, const QString &url);
+ /**Cleans rurl by removing extra slashes.*/
+ static QString cleanName(const QString &rurl);
+ /**Corrects rurl according to the given type and returns corrected url.
+ Also cleans url (see @ref cleanRURL).*/
+ static QString correctName(const QString &rurl, const Type type = Auto);
+
+ bool operator == (const Name &rname);
+ bool operator != (const Name &rname);
+
+protected:
+ /**Corrects m_rurl and m_type according to the relative name storing policy,
+ i.e. removes leading slash, removes trailing slash for files, changes type
+ to be either File or Directory, but not Auto. Also cleans url (see @ref cleanRURL).*/
+ void correct();
+
+private:
+ QString m_rurl;
+ Type m_type;
+};
+
+/**Relative name of file or directory to some base location.*/
+class URL: public Name{
+public:
+ /**Evaluates the relative path between url and base and creates RURL object.
+ base should be an url to the directory or location, not a file.
+ The check is not performed. url should be the usual url. Only the
+ path of this url is taken into account when evaluating relative path.*/
+ URL(KURL base, KURL url, Type type = Auto);
+ /**Creates RURL object with given base and relative or full url (according to
+ the isUrlRelative value).*/
+ URL(KURL base, QString url, bool isUrlRelative, Type type = Auto);
+
+ /**Sets a new base for a RURL.*/
+ void setBase(const KURL &base);
+ /**Sets a new base for a RURL. Base is is considered to be a
+ directory and converted to KURL using KURL::setPath().*/
+ void setBase(const QString &base);
+ /**Returns RURL base.*/
+ KURL base() const;
+ /**Returns a path of a base KURL (using KURL::path()). Trailing slash is guaranteed.*/
+ QString basePath() const;
+
+ /**Returns a complete url to the RURL location. This is basically base + rurl.
+ This also resolves ".." components in path.
+ Directories always have trailing slash in KURL
+ (this means that if url() == "file:/test/dir/" then
+ url() != KURL("/test/dir") and
+ url() == KURL("/test/dir/").*/
+ KURL url() const;
+ /**Returns a path of a complete url to the location. The url is basically base + rurl.
+ This method only returns a path part of the KURL (using KURL::path()).
+ Trailing slash is guaranteed for directories and no trailing slash - for files.
+ This also resolves ".." components in path.*/
+ QString urlPath() const;
+ /**Returns a directory of a complete url to the location. The url is constructed as base + rurl.
+ Returns the same as urlPath() for directories.
+ This method uses KURL::directory to determine the directory.
+ Trailing slash is guaranteed.
+ This also resolves ".." components in path.*/
+ QString urlDirectory() const;
+
+ /**Returns a new URL that is relative to given base. Relative part is taken from
+ current URL object.*/
+ URL relativeTo(KURL base);
+
+ /**Returns a new relative URL constructed from base and given url.*/
+ static URL relativeURL(KURL base, KURL url);
+ /**Returns a new relative URL constructed from base and given url. url parameter
+ is either relative or full (depends on isUrlRelative value).*/
+ static URL relativeURL(KURL base, QString url, bool isUrlRelative);
+
+ bool operator == (const URL &url);
+ bool operator != (const URL &url);
+
+private:
+ KURL m_base;
+};
+
+/**Relative directory name.*/
+class Directory: public URL{
+public:
+ /**Works as URL::URL(KURL, KURL), only implies Name::Directory mode.*/
+ Directory(KURL base, KURL url);
+ /**Works as URL::URL(KURL, QString, bool), only implies Name::Directory mode.*/
+ Directory(KURL base, QString url, bool isRelativeUrl);
+
+ /**Works as URL::setRURL(QString), only implies Name::Directory mode.*/
+ void setRURL(QString rurl);
+
+private:
+ void setRURL(QString rurl, Type type);
+
+};
+
+/**Relative file name.*/
+class File: public URL{
+public:
+ /**Works as URL::URL(KURL, KURL), only implies Name::File mode.*/
+ File(KURL base, KURL url);
+ /**Works as URL::URL(KURL, KURL), only implies Name::File mode.*/
+ File(KURL base, QString url, bool isRelativeUrl);
+
+ /**Works as URL::setRURL(QString), only implies Name::File mode.*/
+ void setRURL(QString rurl);
+
+private:
+ void setRURL(QString rurl, Type type);
+
+};
+
+}
+
+#endif
diff --git a/lib/util/settings.cpp b/lib/util/settings.cpp
new file mode 100644
index 00000000..4e246e5b
--- /dev/null
+++ b/lib/util/settings.cpp
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Jens Dagerbo *
+ * jens.dagerbo@swipnet.se *
+ * *
+ * 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 <kconfig.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+
+#include "settings.h"
+
+QString Settings::terminalEmulatorName( KConfig & config )
+{
+ config.setGroup("TerminalEmulator");
+ bool useKDESetting = config.readBoolEntry( "UseKDESetting", true );
+ QString terminal;
+
+ if ( useKDESetting )
+ {
+ KConfigGroup confGroup( KGlobal::config(), QString::fromLatin1("General") );
+ terminal = confGroup.readEntry("TerminalApplication", QString::fromLatin1("konsole"));
+ }
+ else
+ {
+ terminal = config.readEntry( "TerminalApplication", QString::fromLatin1("konsole"));
+ }
+ return terminal;
+}
+
+QString Settings::profileByAttributes(const QString &language, const QStringList &keywords)
+{
+ KConfig config(locate("data", "kdevelop/profiles/projectprofiles"));
+ config.setGroup(language);
+
+ QStringList profileKeywords = QStringList::split("/", "Empty");
+ if (config.hasKey("Keywords"))
+ profileKeywords = config.readListEntry("Keywords");
+
+ int idx = 0;
+ for (QStringList::const_iterator it = profileKeywords.constBegin();
+ it != profileKeywords.constEnd(); ++it)
+ {
+ if (keywords.contains(*it))
+ {
+ idx = profileKeywords.findIndex(*it);
+ break;
+ }
+ }
+
+ QStringList profiles;
+ if (config.hasKey("Profiles"))
+ {
+ profiles = config.readListEntry("Profiles");
+ return profiles[idx];
+ }
+ return "KDevelop";
+}
diff --git a/lib/util/settings.h b/lib/util/settings.h
new file mode 100644
index 00000000..cd241cad
--- /dev/null
+++ b/lib/util/settings.h
@@ -0,0 +1,26 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Jens Dagerbo *
+ * jens.dagerbo@swipnet.se *
+ * *
+ * 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 SETTINGS_H
+#define SETTINGS_H
+
+class KConfig;
+
+/// Utility functions for settings
+class Settings
+{
+public:
+ static QString terminalEmulatorName( KConfig & config );
+ static QString profileByAttributes(const QString &language, const QStringList &keywords);
+
+};
+
+#endif
diff --git a/lib/util/urlutil.cpp b/lib/util/urlutil.cpp
new file mode 100644
index 00000000..942f1900
--- /dev/null
+++ b/lib/util/urlutil.cpp
@@ -0,0 +1,319 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Julian Rockey <linux@jrockey.com>
+ Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net>
+ Copyright (C) 2003 Mario Scalas <mario.scalas@libero.it>
+
+ 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 <qstringlist.h>
+
+#include <qdir.h>
+#include <qfileinfo.h>
+#include <kdebug.h>
+
+#include <unistd.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include "urlutil.h"
+
+#include <kdeversion.h>
+
+///////////////////////////////////////////////////////////////////////////////
+// Namespace URLUtil
+///////////////////////////////////////////////////////////////////////////////
+
+QString URLUtil::filename(const QString & name) {
+ int slashPos = name.findRev("/");
+ return slashPos<0 ? name : name.mid(slashPos+1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+QString URLUtil::directory(const QString & name) {
+ int slashPos = name.findRev("/");
+ return slashPos<0 ? QString("") : name.left(slashPos);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+QString URLUtil::getRelativePath(const QString& basepath, const QString& destpath)
+{
+ QString relpath = ".";
+ if (!QFile::exists(basepath) ||
+ !QFile::exists(destpath))
+ return "";
+ QStringList basedirs = QStringList::split(QString( QChar( QDir::separator() ) ),basepath);
+ QStringList destdirs = QStringList::split(QString( QChar( QDir::separator() ) ),destpath);
+
+ int maxCompare=0;
+ if (basedirs.count()>=destdirs.count())
+ maxCompare=destdirs.count();
+ else
+ maxCompare=basedirs.count();
+ int lastCommonDir=-1;
+ for (int i=0; i<maxCompare; i++)
+ {
+ if (basedirs[i] != destdirs[i])
+ break;
+ lastCommonDir=i;
+ }
+ for (uint i=0;i<basedirs.count()-(lastCommonDir+1); i++)
+ relpath += QString( QChar( QDir::separator() ) )+QString("..");
+ for (int i=0; i<lastCommonDir+1; i++)
+ destdirs.pop_front();
+ if (destdirs.count())
+ relpath += QString( QChar( QDir::separator() ) )+destdirs.join( QChar( QDir::separator() ) );
+ return QDir::cleanDirPath(relpath);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+QString URLUtil::relativePath(const KURL & parent, const KURL & child, uint slashPolicy) {
+ bool slashPrefix = slashPolicy & SLASH_PREFIX;
+ bool slashSuffix = slashPolicy & SLASH_SUFFIX;
+ if (parent.equals(child,true))
+ return slashPrefix ? QString("/") : QString("");
+
+ if (!parent.isParentOf(child)) return QString();
+ int a=slashPrefix ? -1 : 1;
+ int b=slashSuffix ? 1 : -1;
+ return child.path(b).mid(parent.path(a).length());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+QString URLUtil::relativePath(const QString & parent, const QString & child, uint slashPolicy) {
+ return relativePath(KURL(parent), KURL(child), slashPolicy);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+QString URLUtil::upDir(const QString & path, bool slashSuffix) {
+ int slashPos = path.findRev("/");
+ if (slashPos<1) return QString::null;
+ return path.mid(0,slashPos+ (slashSuffix ? 1 : 0) );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+KURL URLUtil::mergeURL(const KURL & source, const KURL & dest, const KURL & child) {
+
+ // if already a child of source, then fine
+ if (source.isParentOf(child) || source.equals(child,true)) return child;
+
+ // if not a child of dest, return blank URL (error)
+ if (!dest.isParentOf(child) && !dest.equals(child,true)) return KURL();
+
+ // if child is same as dest, return source
+ if (dest.equals(child,true)) return source;
+
+ // calculate
+ QString childUrlStr = child.url(-1);
+ QString destStemStr = dest.url(1);
+ QString sourceStemStr = source.url(1);
+ return KURL(sourceStemStr.append( childUrlStr.mid( destStemStr.length() ) ) );
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+QString URLUtil::getExtension(const QString & path) {
+ int dotPos = path.findRev('.');
+ if (dotPos<0) return QString("");
+ return path.mid(dotPos+1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+QString URLUtil::extractPathNameRelative(const KURL &baseDirUrl, const KURL &url )
+{
+ QString absBase = extractPathNameAbsolute( baseDirUrl ),
+ absRef = extractPathNameAbsolute( url );
+ int i = absRef.find( absBase, 0, true );
+
+ if (i == -1)
+ return QString();
+
+ if (absRef == absBase)
+ return QString( "." );
+ else
+ return absRef.replace( 0, absBase.length(), QString() );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+QString URLUtil::extractPathNameRelative(const QString &basePath, const KURL &url )
+{
+ KURL baseDirUrl = KURL::fromPathOrURL( basePath );
+ return extractPathNameRelative( baseDirUrl, url );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+QString URLUtil::extractPathNameRelative(const QString &basePath, const QString &absFilePath )
+{
+ KURL baseDirUrl = KURL::fromPathOrURL( basePath ),
+ fileUrl = KURL::fromPathOrURL( absFilePath );
+ return extractPathNameRelative( baseDirUrl, fileUrl );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+QString URLUtil::extractPathNameAbsolute( const KURL &url )
+{
+ if (isDirectory( url ))
+ return url.path( +1 ); // with trailing "/" if none is present
+ else
+ {
+ // Ok, this is an over-tight pre-condition on "url" since I hope nobody will never
+ // stress this function with absurd cases ... but who knows?
+ /*
+ QString path = url.path();
+ QFileInfo fi( path ); // Argh: QFileInfo is back ;))
+ return ( fi.exists()? path : QString() );
+ */
+ return url.path();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool URLUtil::isDirectory( const KURL &url )
+{
+ return isDirectory( url.path() );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool URLUtil::isDirectory( const QString &absFilePath )
+{
+ return QDir( absFilePath ).exists();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void URLUtil::dump( const KURL::List &urls, const QString &aMessage )
+{
+ if (!aMessage.isNull())
+ {
+ kdDebug(9000) << aMessage << endl;
+ }
+ kdDebug(9000) << " List has " << urls.count() << " elements." << endl;
+
+ for (size_t i = 0; i<urls.count(); ++i)
+ {
+ KURL url = urls[ i ];
+// kdDebug(9000) << " * Element = " << url.path() << endl;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+QStringList URLUtil::toRelativePaths( const QString &baseDir, const KURL::List &urls)
+{
+ QStringList paths;
+
+ for (size_t i=0; i<urls.count(); ++i)
+ {
+ paths << extractPathNameRelative( baseDir, urls[i] );
+ }
+
+ return paths;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+QString URLUtil::relativePathToFile( const QString & dirUrl, const QString & fileUrl )
+{
+ if (dirUrl.isEmpty() || (dirUrl == "/"))
+ return fileUrl;
+
+ QStringList dir = QStringList::split("/", dirUrl, false);
+ QStringList file = QStringList::split("/", fileUrl, false);
+
+ QString resFileName = file.last();
+ file.remove(file.last());
+
+ uint i = 0;
+ while ( (i < dir.count()) && (i < (file.count())) && (dir[i] == file[i]) )
+ i++;
+
+ QString result_up;
+ QString result_down;
+ QString currDir;
+ QString currFile;
+ do
+ {
+ i >= dir.count() ? currDir = "" : currDir = dir[i];
+ i >= file.count() ? currFile = "" : currFile = file[i];
+ //qWarning("i = %d, currDir = %s, currFile = %s", i, currDir.latin1(), currFile.latin1());
+ if (currDir.isEmpty() && currFile.isEmpty())
+ break;
+ else if (currDir.isEmpty())
+ result_down += file[i] + "/";
+ else if (currFile.isEmpty())
+ result_up += "../";
+ else
+ {
+ result_down += file[i] + "/";
+ result_up += "../";
+ }
+ i++;
+ }
+ while ( (!currDir.isEmpty()) || (!currFile.isEmpty()) );
+
+ return result_up + result_down + resFileName;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+//TODO: remove for KDE4
+QString URLUtil::canonicalPath( const QString & path )
+{
+ QDir dir(path);
+ return dir.canonicalPath();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+//written by "Dawit A." <adawit@kde.org>
+//borrowed from his patch to KShell
+QString URLUtil::envExpand ( const QString& str )
+{
+ uint len = str.length();
+
+ if (len > 1 && str[0] == '$')
+ {
+ int pos = str.find ('/');
+
+ if (pos < 0)
+ pos = len;
+
+ char* ret = getenv( QConstString(str.unicode()+1, pos-1).string().local8Bit().data() );
+
+ if (ret)
+ {
+ QString expandedStr ( QFile::decodeName( ret ) );
+ if (pos < (int)len)
+ expandedStr += str.mid(pos);
+ return expandedStr;
+ }
+ }
+
+ return str;
+}
+
diff --git a/lib/util/urlutil.h b/lib/util/urlutil.h
new file mode 100644
index 00000000..4f9ddbab
--- /dev/null
+++ b/lib/util/urlutil.h
@@ -0,0 +1,190 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Julian Rockey <linux@jrockey.com>
+ Copyright (C) 2003 Mario Scalas <mario.scalas@libero.it>
+
+ 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 _URLUTIL_H_
+#define _URLUTIL_H_
+
+#include <qstring.h>
+#include <qvaluelist.h>
+#include <kurl.h>
+
+/**
+@file urlutil.h
+Utility functions to operate on URLs.
+*/
+
+/**Utility functions to operate on URLs.*/
+namespace URLUtil
+{
+ /**Position of a slash in the URL.*/
+ enum SlashesPosition {
+ SLASH_PREFIX = 1 /**<URL has slash as a prefix.*/,
+ SLASH_SUFFIX = 2 /**<URL has slash as a suffix.*/
+ };
+
+ /**
+ * @return The filename part of a pathname (i.e. everything past the last slash).
+ * @param pathName The absolute path to a file.
+ */
+ QString filename(const QString & pathName);
+ /**
+ * @return The directory part of a path (i.e. everything up to but not including the last slash)
+ * @param pathName The absolute path to a directory.
+ */
+ QString directory(const QString & pathName);
+ /**
+ * @return The relative path between a parent and child URL, or blank if the specified
+ * child is not a child of parent.
+ * @param parent The parent URL.
+ * @param child The child URL.
+ * @param slashPolicy If parent and child are equal then the function returns "/" if
+ * slashPolicy contains SLASH_PREFIX and otherwise "".\n"/" is appended to a result
+ * if slashPolicy contains SLASH_SUFFIX.\n"/" is prepended to a result if
+ * slashPolicy contains SLASH_PREFIX.
+ */
+ QString relativePath(const KURL & parent, const KURL & child, uint slashPolicy = SLASH_PREFIX);
+ /**
+ * @return The relative path between a parent and child URL, or blank if the specified
+ * child is not a child of parent.
+ * @param parent The parent URL.
+ * @param child The child URL.
+ * @param slashPolicy If parent and child are equal then the function returns "/" if
+ * slashPolicy contains SLASH_PREFIX and otherwise "".\n"/" is appended to a result
+ * if slashPolicy contains SLASH_SUFFIX.\n"/" is prepended to a result if
+ * slashPolicy contains SLASH_PREFIX.
+ */
+ QString relativePath(const QString & parent, const QString & child, uint slashPolicy = SLASH_PREFIX);
+ /**
+ * @return The relative path between a base path and destination path or.
+ * @param base The base Path.
+ * @param dest The destination path.
+ */
+ QString getRelativePath( const QString& base, const QString& dest );
+ /**
+ * @param dirUrl An URL of a directory.
+ * @param fileUrl An URL of a file.
+ * @return The relative path between a directory and file. Should never return empty path.\n
+ * <pre>Example:
+ * dirUrl: /home/test/src
+ * fileUrl: /home/test/lib/mylib.cpp
+ * returns: ../lib/mylib.cpp</pre>
+ */
+ QString relativePathToFile( const QString & dirUrl, const QString & fileUrl );
+ /**
+ *@param path A path (absolute or relative).
+ *@param slashSuffix if true then "/" is appended to a path.
+ *@returns The path 'up one level' - the opposite of what filename returns.
+ */
+ QString upDir(const QString & path, bool slashSuffix = false);
+ /**
+ * 'Merges' URLs - changes a URL that starts with dest to start with source instead.\n
+ * <pre>Example:
+ * source is /home/me/
+ * dest is /home/you/
+ * child is /home/you/dir1/file1
+ * returns /home/me/dir1/fil1</pre>
+ * @param source An URL of a source.
+ * @param dest An URL of a destination.
+ * @param child An URL to change.
+ * @return The result of merge.
+ */
+ KURL mergeURL(const KURL & source, const KURL & dest, const KURL & child);
+ /**
+ * @return The file extension for a filename or path.
+ * @param path Absolute or relative path.
+ */
+ QString getExtension(const QString & path);
+
+ /**
+ * Given a base directory url in @p baseDirUrl and the url referring to the
+ * sub-directory or file, it will return the path relative to @p baseDirUrl.
+ * If baseDirUrl == url.path() then it will return ".".
+ * @code
+ * KURL baseUrl, dirUrl;
+ * baseUrl.setPath( "/home/mario/src/kdevelop/" );
+ * dirUrl.setPath( "/home/mario/src/kdevelop/parts/cvs/" );
+ * QString relPathName = extractDirPathRelative( baseUrl, url ); // == "parts/cvs/"
+ * QString absPathName = extractDirPathAbsolute( url ); // == "/home/mario/src/kdevelop/parts/cvs/"
+ * @endcode
+ * Note that if you pass a file name in @p url (instead of a directory) or the
+ * @p baseUrl is not contained in @p url then the function will return "" (void string).
+ *
+ * @param baseDirUrl Base directory URL.
+ * @param url Base directory URL.
+ * @return The relative path between @p url and @p baseDirUrl.
+ */
+ QString extractPathNameRelative(const KURL &baseDirUrl, const KURL &url );
+ /**Same as above. @p basePath is QString.*/
+ QString extractPathNameRelative(const QString &basePath, const KURL &url );
+ /**Same as above. Both @p basePath and @p absFilePath are QStrings.*/
+ QString extractPathNameRelative(const QString &basePath, const QString &absFilePath );
+
+ /**
+ * @param url The url to extract the absolute path from.
+ * @return The absolute path name referred in @p url.
+ * Look at @ref extractPathNameRelative documentation for an example.
+ */
+ QString extractPathNameAbsolute( const KURL &url );
+
+ /**
+ * @param baseDir Base directory for relative URLs.
+ * @param urls The list of urls to extract the relative paths from.
+ * @return A QStringList of relative (to @p baseDir) paths from a list of KURLs in @p urls.
+ */
+ QStringList toRelativePaths( const QString &baseDir, const KURL::List &urls);
+
+ /**
+ * @param url The absolute URL.
+ * @return true if @p url is a directory, false otherwise.
+ */
+ bool isDirectory( const KURL &url );
+ /**
+ * @param absFilePath The absolute path.
+ * @return true if @p url is a directory, false otherwise.
+ */
+ bool isDirectory( const QString &absFilePath );
+
+ /**
+ * Dumps the list of KURL @p urls on standard output, eventually printing @p aMessage if it
+ * is not null.
+ * @param urls URLs to dump.
+ * @param aMessage Message to be written onto a stdout.
+ */
+ void dump( const KURL::List &urls, const QString &aMessage = QString::null );
+
+ /**
+ * Same as QDir::canonicalPath in later versions of Qt. Earlier versions of Qt
+ * had this broken, so it's reproduced here.
+ * Deprecated, use QDir::canonicalPath instead.
+ */
+ QString canonicalPath( const QString & path );
+
+ /**
+ * Performs environment variable expansion on @p variable.
+ *
+ * @param variable The string with the environment variable to expand.
+ * @return The expanded environment variable value. if the variable
+ * cannot be expanded, @p variable itself is returned.
+ */
+ QString envExpand ( const QString &variable );
+
+}
+
+#endif