From e9ae80694875f869892f13f4fcaf1170a00dea41 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdewebdev@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- quanta/utility/Makefile.am | 20 + quanta/utility/myprocess.h | 36 + quanta/utility/newstuff.cpp | 144 ++++ quanta/utility/newstuff.h | 121 ++++ quanta/utility/qpevents.cpp | 403 +++++++++++ quanta/utility/qpevents.h | 90 +++ quanta/utility/quantabookmarks.cpp | 399 +++++++++++ quanta/utility/quantabookmarks.h | 99 +++ quanta/utility/quantacommon.cpp | 753 ++++++++++++++++++++ quanta/utility/quantacommon.h | 225 ++++++ quanta/utility/quantanetaccess.cpp | 268 ++++++++ quanta/utility/quantanetaccess.h | 86 +++ quanta/utility/resource.h | 59 ++ quanta/utility/tagaction.cpp | 1285 +++++++++++++++++++++++++++++++++++ quanta/utility/tagaction.h | 137 ++++ quanta/utility/tagactionmanager.cpp | 83 +++ quanta/utility/tagactionmanager.h | 74 ++ quanta/utility/tagactionset.cpp | 1172 ++++++++++++++++++++++++++++++++ quanta/utility/tagactionset.h | 161 +++++ quanta/utility/toolbartabwidget.cpp | 351 ++++++++++ quanta/utility/toolbartabwidget.h | 111 +++ quanta/utility/toolbarxmlgui.cpp | 27 + quanta/utility/toolbarxmlgui.h | 32 + 23 files changed, 6136 insertions(+) create mode 100644 quanta/utility/Makefile.am create mode 100644 quanta/utility/myprocess.h create mode 100644 quanta/utility/newstuff.cpp create mode 100644 quanta/utility/newstuff.h create mode 100644 quanta/utility/qpevents.cpp create mode 100644 quanta/utility/qpevents.h create mode 100644 quanta/utility/quantabookmarks.cpp create mode 100644 quanta/utility/quantabookmarks.h create mode 100644 quanta/utility/quantacommon.cpp create mode 100644 quanta/utility/quantacommon.h create mode 100644 quanta/utility/quantanetaccess.cpp create mode 100644 quanta/utility/quantanetaccess.h create mode 100644 quanta/utility/resource.h create mode 100644 quanta/utility/tagaction.cpp create mode 100644 quanta/utility/tagaction.h create mode 100644 quanta/utility/tagactionmanager.cpp create mode 100644 quanta/utility/tagactionmanager.h create mode 100644 quanta/utility/tagactionset.cpp create mode 100644 quanta/utility/tagactionset.h create mode 100644 quanta/utility/toolbartabwidget.cpp create mode 100644 quanta/utility/toolbartabwidget.h create mode 100644 quanta/utility/toolbarxmlgui.cpp create mode 100644 quanta/utility/toolbarxmlgui.h (limited to 'quanta/utility') diff --git a/quanta/utility/Makefile.am b/quanta/utility/Makefile.am new file mode 100644 index 00000000..56522430 --- /dev/null +++ b/quanta/utility/Makefile.am @@ -0,0 +1,20 @@ +noinst_LTLIBRARIES = libutility.la + +METASOURCES = AUTO + +libutility_la_SOURCES = quantacommon.cpp tagaction.cpp toolbartabwidget.cpp \ + toolbarxmlgui.cpp newstuff.cpp quantanetaccess.cpp qpevents.cpp quantabookmarks.cpp \ + tagactionmanager.cpp tagactionset.cpp + +AM_CPPFLAGS = -I$(top_srcdir)/quanta/src \ + -I$(top_srcdir)/quanta/parsers \ + -I$(top_srcdir)/quanta/messages \ + -I$(top_srcdir)/quanta/dialogs/tagdialogs \ + -I$(top_srcdir)/quanta/parts/kafka \ + -I$(top_srcdir)/quanta/project \ + -I$(top_srcdir)/lib \ + $(KNEWSTUFF_INCLUDES) \ + $(KMDI_INCLUDES) $(all_includes) + +libutility_la_LDFLAGS = $(all_libraries) +noinst_HEADERS = qpevents.h tagactionmanager.h tagactionset.h diff --git a/quanta/utility/myprocess.h b/quanta/utility/myprocess.h new file mode 100644 index 00000000..a495cdf9 --- /dev/null +++ b/quanta/utility/myprocess.h @@ -0,0 +1,36 @@ +/*************************************************************************** + myprocess.h + ------------------- + begin : Jun 25 2003 + copyright : (C) 2003 by Andras Mantia + ***************************************************************************/ + +/*************************************************************************** + * * + * 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; version 2 of the License. * + * * + ***************************************************************************/ + +#ifndef MYPROCESS_H +#define MYPROCESS_H + +#include + +class MyProcess:public KProcess +{ + Q_OBJECT + + public: + MyProcess(); + virtual ~MyProcess() {}; + + protected: + virtual int commSetupDoneC(); +}; + + + +#endif + diff --git a/quanta/utility/newstuff.cpp b/quanta/utility/newstuff.cpp new file mode 100644 index 00000000..f6cbf397 --- /dev/null +++ b/quanta/utility/newstuff.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + newstuff.cpp - description + ------------------- + begin : Tue Jun 22 12:19:55 2004 + copyright : (C) 2004 by Andras Mantia + ***************************************************************************/ + +/*************************************************************************** + * * + * 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; version 2 of the License. * + * * + ***************************************************************************/ + //qt includes +#include + +//kde includes +#include +#include +#include +#include +#include + +//app includes +#include "newstuff.h" +#include "dtds.h" +#include "resource.h" +#include "quantacommon.h" +#include "qextfileinfo.h" + +void QNewDTEPStuff::installResource() +{ + bool ok = true; + KTar tar(m_tarName, "application/x-gzip"); + if (tar.open(IO_ReadOnly)) + { + const KArchiveDirectory *directory = tar.directory(); + QString dtepDir =KGlobal::dirs()->saveLocation("data") + resourceDir + "dtep/"; + QString dtdName = (*directory->entries().at(0)); + if (dtdName.isEmpty()) + { + ok = false; + } else + { + directory->copyTo(dtepDir, true); + DTDs::ref()->slotLoadDTEP(dtepDir + dtdName, false); + } + tar.close(); + } else + ok = false; + if (!ok) + KMessageBox::error(parentWidget(), i18n("There was an error with the downloaded DTEP tarball file. Possible causes are damaged archive or invalid directory structure in the archive."), i18n("DTEP Installation Error")); +} + +QNewToolbarStuff::QNewToolbarStuff(const QString &type, QWidget *parentWidget) + :KNewStuffSecure(type, parentWidget) +{ + connect(this, SIGNAL(loadToolbarFile(const KURL&)), parentWidget, SLOT(slotLoadToolbarFile(const KURL&))); +} + + +void QNewToolbarStuff::installResource() +{ + KURL destURL = KURL::fromPathOrURL(KGlobal::dirs()->saveLocation("data") + resourceDir + "toolbars/" + QFileInfo(m_tarName).fileName()); + bool ok = true; + if (QuantaCommon::checkOverwrite(destURL, parentWidget())) + { + if (!QExtFileInfo::copy(KURL::fromPathOrURL(m_tarName), destURL, -1, true, false, parentWidget())) + ok = false; + else + { + if (KMessageBox::questionYesNo(parentWidget(), i18n("Do you want to load the newly downloaded toolbar?"), i18n("Load Toolbar"), i18n("Load"), KStdGuiItem::cancel()) == KMessageBox::Yes) + { + emit loadToolbarFile(destURL); + } + } + if (!ok) + KMessageBox::error(parentWidget(), i18n("There was an error with the downloaded toolbar tarball file. Possible causes are damaged archive or invalid directory structure in the archive."), i18n("Toolbar Installation Error")); + } +} + +QNewTemplateStuff::QNewTemplateStuff(const QString &type, QWidget *parentWidget) + :KNewStuffSecure(type, parentWidget) +{ + connect(this, SIGNAL(openFile(const KURL&)), parentWidget, SLOT(slotFileOpen(const KURL&))); +} + + +void QNewTemplateStuff::installResource() +{ + KURL destURL = KURL::fromPathOrURL(KGlobal::dirs()->saveLocation("data") + resourceDir + "templates/" + QFileInfo(m_tarName).fileName()); + bool ok = true; + if (QuantaCommon::checkOverwrite(destURL, parentWidget())) + { + if (!QExtFileInfo::copy(KURL::fromPathOrURL(m_tarName), destURL, -1, true, false, parentWidget())) + ok = false; + else + { + if (KMessageBox::questionYesNo(parentWidget(), i18n("Do you want to open the newly downloaded template?"), i18n("Open Template"), KStdGuiItem::open(), KStdGuiItem::cancel()) == KMessageBox::Yes) + { + emit openFile(destURL); + } + } + if (!ok) + KMessageBox::error(parentWidget(), i18n("There was an error with the downloaded template file."), i18n("Template Installation Error")); + } +} + +void QNewScriptStuff::installResource() +{ + bool ok = true; + KTar tar(m_tarName, "application/x-gzip"); + if (tar.open(IO_ReadOnly)) + { + const KArchiveDirectory *directory = tar.directory(); + QString scriptsDir =KGlobal::dirs()->saveLocation("data") + resourceDir + "scripts/"; + directory->copyTo(scriptsDir, true); + tar.close(); + } else + ok = false; + + if (!ok) + KMessageBox::error(parentWidget(), i18n("There was an error with the downloaded script tarball file. Possible causes are damaged archive or invalid directory structure in the archive."), i18n("Script Installation Error")); +} + +void QNewDocStuff::installResource() +{ + bool ok = true; + KTar tar(m_tarName, "application/x-gzip"); + if (tar.open(IO_ReadOnly)) + { + const KArchiveDirectory *directory = tar.directory(); + QString docDir =KGlobal::dirs()->saveLocation("data") + resourceDir + "doc/"; + directory->copyTo(docDir, true); + tar.close(); + } else + ok = false; + + if (!ok) + KMessageBox::error(parentWidget(), i18n("There was an error with the downloaded script tarball file. Possible causes are damaged archive or invalid directory structure in the archive."), i18n("Documentation Installation Error")); +} + +#include "newstuff.moc" diff --git a/quanta/utility/newstuff.h b/quanta/utility/newstuff.h new file mode 100644 index 00000000..dd2ad104 --- /dev/null +++ b/quanta/utility/newstuff.h @@ -0,0 +1,121 @@ +/*************************************************************************** + newstuff.h - description + ------------------- + begin : Tue Jun 22 12:19:55 2004 + copyright : (C) 2004 by Andras Mantia + ***************************************************************************/ + +/*************************************************************************** + * * + * 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; version 2 of the License. * + * * + ***************************************************************************/ + +#ifndef NEWSTUFF_H +#define NEWSTUFF_H + +//qt includes +#include + +//kde includes +#include +/** +Makes possible downloading and installing a DTEP resource files from a server. + +@author Andras Mantia +*/ + +class KURL; + +class QNewDTEPStuff: public KNewStuffSecure +{ + Q_OBJECT + +public: + QNewDTEPStuff(const QString &type, QWidget *parentWidget=0) + :KNewStuffSecure(type, parentWidget){}; + ~QNewDTEPStuff() {}; + +private: + virtual void installResource(); +}; + +/** +Makes possible downloading and installing a Toolbar resource files from a server. + +@author Andras Mantia +*/ +class QNewToolbarStuff: public KNewStuffSecure +{ + Q_OBJECT + +public: + QNewToolbarStuff(const QString &type, QWidget *parentWidget=0); + ~QNewToolbarStuff() {}; + +signals: + void loadToolbarFile(const KURL&); + +private: + virtual void installResource(); +}; + +/** +Makes possible downloading and installing a template resource files from a server. + +@author Andras Mantia +*/ +class QNewTemplateStuff: public KNewStuffSecure +{ + Q_OBJECT + +public: + QNewTemplateStuff(const QString &type, QWidget *parentWidget=0); + ~QNewTemplateStuff() {}; + +signals: + void openFile(const KURL&); + +private: + virtual void installResource(); +}; + +/** +Makes possible downloading and installing a script resource files from a server. + +@author Andras Mantia +*/ +class QNewScriptStuff: public KNewStuffSecure +{ + Q_OBJECT + +public: + QNewScriptStuff(const QString &type, QWidget *parentWidget=0) + :KNewStuffSecure(type, parentWidget){}; + ~QNewScriptStuff() {}; + +private: + virtual void installResource(); +}; + +/** +Makes possible downloading and installing a documentation resource files from a server. + +@author Andras Mantia + */ +class QNewDocStuff: public KNewStuffSecure +{ + Q_OBJECT + + public: + QNewDocStuff(const QString &type, QWidget *parentWidget=0) + :KNewStuffSecure(type, parentWidget){}; + ~QNewDocStuff() {}; + + private: + virtual void installResource(); +}; + +#endif diff --git a/quanta/utility/qpevents.cpp b/quanta/utility/qpevents.cpp new file mode 100644 index 00000000..bb0d5db4 --- /dev/null +++ b/quanta/utility/qpevents.cpp @@ -0,0 +1,403 @@ +/*************************************************************************** + qpevents.cpp - description + ------------------- + begin : Sun Jul 11 2004 + copyright : (C) 2004 Andras Mantia + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +//qt includes +#include +#include +#include + +//kde includes +#include +#include +#include +#include + +//app includes +#include "qpevents.h" +#include "document.h" +#include "project.h" +#include "qextfileinfo.h" +#include "viewmanager.h" +#include "resource.h" +#include "quanta.h" +#include "tagaction.h" + +//TODO: Better create a class for each internal event action +QPEvents::QPEvents(QObject *parent, const char *name) + : QObject(parent, name) +{ + m_eventNames["before_save"] = i18n("Before Document Save"); + m_eventNames["after_save"] = i18n("After Document Save"); + m_eventNames["after_open"] = i18n("After Document Open"); + m_eventNames["before_close"] = i18n("Before Document Close"); + m_eventNames["after_close"] = i18n("After Document Close"); + m_eventNames["after_project_open"] = i18n("After Project Open"); + m_eventNames["before_project_close"] = i18n("Before Project Close"); + m_eventNames["after_project_close"] = i18n("After Project Close"); + m_eventNames["upload_requested"] = i18n("Upload Requested"); + m_eventNames["before_upload"] = i18n("Before Document Upload"); + m_eventNames["after_upload"] = i18n("After Document Upload"); + m_eventNames["after_project_add"] = i18n("After Addition to Project"); + m_eventNames["after_project_remove"] = i18n("After Removal From Project"); + m_eventNames["after_commit"] = i18n("After Commit to CVS"); + m_eventNames["after_update"] = i18n("After Update From CVS"); + m_eventNames["after_file_move"] = i18n("After Moving File Inside Project"); + m_eventNames["quanta_start"] = i18n("Quanta Start"); + m_eventNames["quanta_exit"] = i18n("Quanta Exit"); +// m_eventNames["after_multiple_save"] = i18n("After saving more files at once (like Save All)"); + + m_actionNames["email"] = i18n("Send Email"); + m_actionNames["log"] = i18n("Log Event"); + m_actionNames["script"] = i18n("Script Action"); + m_actionNames["action"] = i18n("Non-Script Action"); +} + + +QPEvents::~QPEvents() +{ +} + +void QPEvents::slotEventHappened(const QString& name, const QString& argument1, const QString& argument2) +{ + if (!quantaApp || !Project::ref()->eventsEnabled()) + return; + EventActions *events = Project::ref()->events(); + if (!events) return; + if (events->contains(name)) + { + m_eventName = name; + QValueList evList = (*events)[name]; + for (QValueList::Iterator it = evList.begin(); it != evList.end(); ++it) + { + EventAction ev = *it; + if (ev.type == EventAction::Internal) + { + if (KMessageBox::warningContinueCancel(0L, i18n("An internal action (%1) associated with an event (%2) will be executed. Do you want to allow the execution of this action?").arg(ev.action).arg(name), i18n("Event Triggered"), i18n("Execute"), "Warn about internal actions") == KMessageBox::Cancel) + return; + } else + { + if (KMessageBox::warningContinueCancel(0L, i18n("An external action (%1) associated with an event (%2) will be executed. Do you want to allow the execution of this action?").arg(ev.action).arg(name), i18n("Event Triggered"), i18n("Execute"), "Warn about external actions") == KMessageBox::Cancel) + return; + } + KURL url = KURL::fromPathOrURL(argument1); + KURL url2 = KURL::fromPathOrURL(argument2); + if (url.isValid()) + { + bool inProject = Project::ref()->contains(url); + if (inProject) + { + if (name == "upload_requested") + { + ev.arguments << i18n("An upload was initiated"); + ev.arguments << url.path(); + handleEvent(ev); + } + } + if (inProject && url2.isValid()) + { + if (name == "before_upload") + { + ev.arguments << i18n("About to upload a document"); + ev.arguments << url.path(); + ev.arguments << url2.path(); + handleEvent(ev); + } else + if (name == "after_upload") + { + ev.arguments << i18n("Document uploaded"); + ev.arguments << url.path(); + ev.arguments << url2.path(); + handleEvent(ev); + } else + if (name == "after_file_move") + { + ev.arguments << i18n("Document moved"); + ev.arguments << url.path(); + ev.arguments << url2.path(); + handleEvent(ev); + } + } else + { + QString relativePath = QExtFileInfo::toRelative(url, Project::ref()->projectBaseURL()).path(); + if (inProject && name == "after_save") + { + ev.arguments << i18n("Document saved"); + ev.arguments << relativePath; + handleEvent(ev); + } else + if (inProject && name == "before_save") + { + ev.arguments << i18n("About to save a document"); + ev.arguments << relativePath; + handleEvent(ev); + } else + if (inProject && name == "after_open") + { + ev.arguments << i18n("Document opened"); + ev.arguments << relativePath; + handleEvent(ev); + } else + if (inProject && name == "after_close") + { + ev.arguments << i18n("Document closed"); + ev.arguments << relativePath; + handleEvent(ev); + } else + if (inProject && name == "before_close") + { + ev.arguments << i18n("About to close a document"); + ev.arguments << relativePath; + handleEvent(ev); + } else + if (name == "after_project_open") + { + ev.arguments << i18n("Project opened"); + ev.arguments << url.path(); + handleEvent(ev); + } else + if (name == "after_project_close") + { + ev.arguments << i18n("Project closed"); + ev.arguments << url.path(); + handleEvent(ev); + } else + if (name == "before_project_close") + { + ev.arguments << i18n("About to close the project"); + ev.arguments << url.path(); + handleEvent(ev); + } else + if (name == "after_project_add") + { + ev.arguments << i18n("Document added to project"); + ev.arguments << url.path(); + handleEvent(ev); + } else + if (name == "after_project_remove") + { + ev.arguments << i18n("Document removed from project"); + ev.arguments << url.path(); + handleEvent(ev); + } + } + } else + if (name == "after_commit") + { + ev.arguments << i18n("Document committed"); + ev.arguments << argument1; + handleEvent(ev); + } else + if (name == "after_update") + { + ev.arguments << i18n("Document updated"); + ev.arguments << argument1; + handleEvent(ev); + } else + if (name == "quanta_start") + { + ev.arguments << i18n("Quanta has been started"); + ev.arguments << argument1; + handleEvent(ev); + } else + if (name == "quanta_exit") + { + ev.arguments << i18n("Quanta is shutting down"); + ev.arguments << argument1; + handleEvent(ev); + } + } + } + if (!m_eventNames.contains(name)) + KMessageBox::sorry(0L, i18n("Unsupported event %1.").arg(name), i18n("Event Handling Error")); +} + +bool QPEvents::handleEvent(const EventAction& ev) +{ + if (ev.type == EventAction::Internal) + { + if (ev.action == "email") + { + QString receiver = ev.arguments[0]; + TeamMember member; + if (receiver == "teamleader") + member = Project::ref()->teamLeader(); + else if (receiver.startsWith("subprojectleader-")) + { + QString s = receiver.remove("subprojectleader-"); + member = Project::ref()->subprojectLeader(s); + SubProject subProject; + QValueList *subprojects = Project::ref()->subprojects(); + for (uint i = 0 ; i < subprojects->count(); i++) + { + if ((*subprojects)[i].name == s) + { + subProject = (*subprojects)[i]; + break; + } + } + if (!subProject.location.isEmpty() && !ev.arguments[2].startsWith(subProject.location)) + { + kdDebug(24000) << ev.arguments[2] << " is not part of the " << subProject.name << "subproject \"" << subProject.location << "\". " << endl; + return true; + } + } + else if (receiver.startsWith("taskleader-")) + member = Project::ref()->taskLeader(receiver.remove("taskleader-")); + + QString body; + for (uint i = 2; i < ev.arguments.count(); i++) + body += ev.arguments[i] + "\n"; + kapp->invokeMailer(member.name + "<" + member.email + ">", "", "", ev.arguments[1], body, "", QStringList(), ""); + + return true; + } + if (ev.action == "log") + { + QString logFile = ev.arguments[0]; + KURL url = KURL::fromPathOrURL(logFile); + if (url.isValid() && !url.isLocalFile()) + { + KMessageBox::sorry(0L, i18n("Logging to remote files is not supported.")); + return false; + } + if (!logFile.startsWith("/")) + { + url = Project::ref()->projectBaseURL(); + url.addPath(logFile); + if (!url.isLocalFile()) + { + KMessageBox::sorry(0L, i18n("Logging to files inside a remote project is not supported.")); + return false; + } + } + QFile file(url.path()); + bool result; + if (ev.arguments[2] == "create_new") + result = file.open(IO_WriteOnly); + else + result = file.open(IO_WriteOnly | IO_Append); + if (result) + { + QTextStream stream(&file); + stream.setEncoding(QTextStream::UnicodeUTF8); + //Note: the log text should not be translated. + QString s = QDateTime::currentDateTime().toString(Qt::ISODate) + ": "; + s.append( "Event : " + m_eventName + " : "); + s.append( "Action: " + ev.action + " : "); + if (ev.arguments[1] == "full") + { + s.append( "Arguments: "); + for (uint i = 1; i < ev.arguments.count(); i++) + s.append(ev.arguments[i] + " | "); + } + s[s.length() - 1] = '\n'; + stream << s; + file.close(); + } + if (!result) + { + KMessageBox::sorry(0L, i18n("Logging failed. Check that you have write access to %1.").arg(url.path())); + return false; + } + } else + KMessageBox::sorry(0L, i18n("Unsupported internal event action : %1.").arg(ev.action)); + } else + if (ev.type == EventAction::External) + { + //KMessageBox::sorry(0L, i18n("External event actions are not yet supported.")); + if (ev.action == "script" || ev.action =="action") + { + QString name = ev.arguments[0]; + KAction *action = quantaApp->actionCollection()->action(name); + TagAction *tagAction = dynamic_cast(action); + if (tagAction) + { + bool blocking = (ev.arguments[1] == "yes"); + EventAction event = ev; + event.arguments.remove(event.arguments.at(1)); + tagAction->addArguments(event.arguments); + tagAction->execute(blocking); + } + else + if (action) + { + action->activate(); + } else + KMessageBox::sorry(0L, i18n("The %1 script action was not found on your system.").arg(name), i18n("Action Execution Error")); + } else + KMessageBox::sorry(0L, i18n("Unsupported external event action.")); + } else + KMessageBox::sorry(0L, i18n("Unknown event type.")); + return false; +} + +QString QPEvents::fullEventName(const QString &name) +{ + if (m_eventNames.contains(name)) + return m_eventNames[name]; + else + return name; +} + +QString QPEvents::fullActionName(const QString& name) +{ + if (m_actionNames.contains(name)) + return m_actionNames[name]; + else + return name; +} + +QString QPEvents::eventName(const QString &fullName) +{ + for (QMap::ConstIterator it = m_eventNames.constBegin(); it != m_eventNames.constEnd(); ++it) + { + if (fullName == it.data()) + return it.key(); + } + return fullName; +} + +QString QPEvents::actionName(const QString &fullName) +{ + for (QMap::ConstIterator it = m_actionNames.constBegin(); it != m_actionNames.constEnd(); ++it) + { + if (fullName == it.data()) + return it.key(); + } + return fullName; +} + +QStringList QPEvents::eventNames() +{ + QStringList names; + for (QMap::ConstIterator it = m_eventNames.constBegin(); it != m_eventNames.constEnd(); ++it) + { + names << it.data(); + } + return names; +} + +QStringList QPEvents::actionNames() +{ + QStringList names; + for (QMap::ConstIterator it = m_actionNames.constBegin(); it != m_actionNames.constEnd(); ++it) + { + names << it.data(); + } + return names; +} + +#include "qpevents.moc" diff --git a/quanta/utility/qpevents.h b/quanta/utility/qpevents.h new file mode 100644 index 00000000..83f6d37b --- /dev/null +++ b/quanta/utility/qpevents.h @@ -0,0 +1,90 @@ +/*************************************************************************** + qpevents.h - description + ------------------- + begin : Sun Jul 11 2004 + copyright : (C) 2004 Andras Mantia + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 QPEVENTS_H +#define QPEVENTS_H + +#include + +/** +@author Andras Mantia +*/ + +/** Describes an event action. */ +struct EventAction { + /** Possible event types */ + enum Types { + Internal = 0, + External = 1 + }; + /** The type of the event. See @ref Types */ + uint type; + /** the name of the action to be executed. In case of external events + this is the name of the script, in case of internal events it can be one of the + following: "email" + */ + QString action; + /** The arguments for the event action. It is different for each action. + */ + QStringList arguments; +}; + +/** The configured events. The key is the event name, the data is the event description. +For example: events["before_save"] points to the event data that needs to be used +before a file is saved. Possible key names are: before_save, after_save, after_open, +after_project_open, after_project_save, before_upload, after_upload, after_project_add, +after_project_remove, after_commit +*/ +typedef QMap > EventActions; + +class QPEvents : public QObject +{ +Q_OBJECT +public: + static QPEvents* const ref(QObject *parent = 0L) + { + static QPEvents *m_ref; + if (!m_ref) m_ref = new QPEvents(parent); + return m_ref; + } + ~QPEvents(); + QString fullEventName(const QString &name); + QString fullActionName(const QString &name); + QString eventName(const QString &fullName); + QString actionName(const QString &fullName); + QStringList eventNames(); + QStringList actionNames(); + +public slots: + /** Called when an event has happened */ + void slotEventHappened(const QString& name, const QString& argument1, const QString& argument2); + +private: + QPEvents(QObject *parent = 0, const char *name = 0); + /** Calls the action associated with an event. Returns true if the call succeeded, false + otherwise. The call might fail if: + - the action type is unknown + - the script cannot be found + - the user canceled the execution + */ + bool handleEvent(const EventAction& ev); + + QMap m_eventNames; + QMap m_actionNames; + QString m_eventName; +}; + +#endif diff --git a/quanta/utility/quantabookmarks.cpp b/quanta/utility/quantabookmarks.cpp new file mode 100644 index 00000000..ebca5843 --- /dev/null +++ b/quanta/utility/quantabookmarks.cpp @@ -0,0 +1,399 @@ +/* This file is part of the KDE libraries + Copyright (C) 2002, 2003, 2004 Anders Lund + Copyright (C) 2002 John Firebaugh + Copyright (C) 2005 Andras Mantia + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "quantabookmarks.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "viewmanager.h" +#include "document.h" + +/** + Utility: selection sort + sort a QMemArray in ascending order. + max it the largest (zerobased) index to sort. + To sort the entire array: ssort( *array, array.size() -1 ); + This is only efficient if ran only once. +*/ +static void ssort( QMemArray &a, int max ) +{ + uint tmp, j, maxpos; + for ( uint h = max; h >= 1; h-- ) + { + maxpos = 0; + for ( j = 0; j <= h; j++ ) + maxpos = a[j] > a[maxpos] ? j : maxpos; + tmp = a[maxpos]; + a[maxpos] = a[h]; + a[h] = tmp; + } +} + +// TODO add a insort() or bubble_sort - more efficient for aboutToShow() ? + +QuantaBookmarks::QuantaBookmarks(ViewManager *parent,Sorting sort, bool onlyFromActualDocument ) + : QObject( parent, "bookmarks" ) + , m_sorting(sort) + , m_onlyFromActualDocument(onlyFromActualDocument) +{ + m_viewManager = parent; + _tries=0; + m_bookmarksMenu = 0L; + m_doc = 0L; +} + +QuantaBookmarks::~QuantaBookmarks() +{ +} + +void QuantaBookmarks::createActions( KActionCollection* ac ) +{ + m_bookmarksMenu = (new KActionMenu(i18n("&Bookmarks"), ac, "bookmarks"))->popupMenu(); + init(ac); +} + +void QuantaBookmarks::init(KActionCollection* ac) +{ + m_bookmarkToggle = new KToggleAction( + i18n("Set &Bookmark"), "bookmark", CTRL+Key_B, + this, SLOT(toggleBookmark()), + ac, "bookmarks_toggle" ); + m_bookmarkToggle->setWhatsThis(i18n("If a line has no bookmark then add one, otherwise remove it.")); + m_bookmarkToggle->setCheckedState( i18n("Clear &Bookmark") ); + + m_bookmarkClear = new KAction( + i18n("Clear &All Bookmarks"), 0, + this, SLOT(clearBookmarks()), + ac, "bookmarks_clear"); + m_bookmarkClear->setWhatsThis(i18n("Remove all bookmarks of the current document.")); + + m_goNext = new KAction( + i18n("Next Bookmark"), "next", ALT + Key_PageDown, + this, SLOT(goNext()), + ac, "bookmarks_next"); + m_goNext->setWhatsThis(i18n("Go to the next bookmark.")); + + m_goPrevious = new KAction( + i18n("Previous Bookmark"), "previous", ALT + Key_PageUp, + this, SLOT(goPrevious()), + ac, "bookmarks_previous"); + m_goPrevious->setWhatsThis(i18n("Go to the previous bookmark.")); + + //connect the aboutToShow() and aboutToHide() signals with + //the bookmarkMenuAboutToShow() and bookmarkMenuAboutToHide() slots + connect( m_bookmarksMenu, SIGNAL(aboutToShow()), this, SLOT(bookmarkMenuAboutToShow())); + connect( m_bookmarksMenu, SIGNAL(aboutToHide()), this, SLOT(bookmarkMenuAboutToHide()) ); + + marksChanged (); +} + +void QuantaBookmarks::setBookmarksMenu(QPopupMenu* bookmarksMenu) + +{ + m_bookmarksMenu = bookmarksMenu; + init(); +} + +void QuantaBookmarks::toggleBookmark () +{ + Document *doc = m_doc; + if (!doc) + doc = m_viewManager->activeDocument(); + if (doc && doc->markIf) + { + uint mark = doc->markIf->mark(doc->viewCursorIf->cursorLine()); + if( mark & KTextEditor::MarkInterface::markType01 ) + doc->markIf->removeMark(doc->viewCursorIf->cursorLine(), + KTextEditor::MarkInterface::markType01 ); + else + doc->markIf->addMark(doc->viewCursorIf->cursorLine(), + KTextEditor::MarkInterface::markType01 ); + } + marksChanged(); +} + +void QuantaBookmarks::clearBookmarks () +{ + Document *doc = m_viewManager->activeDocument(); + if (doc && doc->markIf) + { + QPtrList m = doc->markIf->marks(); + for (uint i=0; i < m.count(); i++) + doc->markIf->removeMark( m.at(i)->line, KTextEditor::MarkInterface::markType01 ); + + // just to be sure ;) + marksChanged (); + } +} + +int QuantaBookmarks::insertBookmarks(QPopupMenu& menu, Document *doc, bool insertNavigationItems ) +{ + int insertedItems = 0; + if (doc->markIf) + { + uint line = doc->viewCursorIf->cursorLine(); + const QRegExp re("&(?!&)"); + int idx( -1 ); + int old_menu_count = menu.count(); + KTextEditor::Mark *next = 0; + KTextEditor::Mark *prev = 0; + + QPtrList m = doc->markIf->marks(); + QMemArray sortArray( m.count() ); + QPtrListIterator it( m ); + + if ( it.count() > 0 && insertNavigationItems) + menu.insertSeparator(); + + for( int i = 0; *it; ++it) + { + if( (*it)->type & KTextEditor::MarkInterface::markType01 ) + { + QString bText = KStringHandler::rEmSqueeze + ( doc->editIf->textLine( (*it)->line ), + menu.fontMetrics(), 32 ); + bText.replace(re, "&&"); // kill undesired accellerators! + bText.replace('\t', ' '); // kill tabs, as they are interpreted as shortcuts + + if ( m_sorting == Position ) + { + sortArray[i] = (*it)->line; + ssort( sortArray, i ); + idx = sortArray.find( (*it)->line ); + if (insertNavigationItems) + idx += 3; + i++; + } + + menu.insertItem( + QString("%1 - \"%2\"").arg( (*it)->line+1 ).arg( bText ), + 0, (*it)->line, idx ); + insertedItems++; + + if ( (*it)->line < line ) + { + if ( ! prev || prev->line < (*it)->line ) + prev = (*it); + } + + else if ( (*it)->line > line ) + { + if ( ! next || next->line > (*it)->line ) + next = (*it); + } + } + } + + if (insertNavigationItems) + { + idx = ++old_menu_count; + if ( next ) + { + m_goNext->setText( i18n("&Next: %1 - \"%2\"").arg( next->line + 1 ) + .arg( KStringHandler::rsqueeze( doc->editIf->textLine( next->line ), 24 ) ) ); + m_goNext->plug( &menu, idx ); + idx++; + } + if ( prev ) + { + m_goPrevious->setText( i18n("&Previous: %1 - \"%2\"").arg(prev->line + 1 ) + .arg( KStringHandler::rsqueeze( doc->editIf->textLine( prev->line ), 24 ) ) ); + m_goPrevious->plug( &menu, idx ); + idx++; + } + if ( next || prev ) + menu.insertSeparator( idx ); + } + connect(&menu, SIGNAL(activated(int)), this, SLOT(gotoLineNumber(int))); + } + return insertedItems; +} + +void QuantaBookmarks::bookmarkMenuAboutToShow() +{ + KConfig *config = kapp->config(); + if (config->hasGroup("Kate View Defaults")) + { + config->setGroup("Kate View Defaults"); + m_sorting = config->readNumEntry("Bookmark Menu Sorting", 0) == 0 ? Position : Creation; + } + for (uint i = 0; i < m_othersMenuList.count(); i++) + { + delete m_othersMenuList[i]; + } + m_othersMenuList.clear(); + m_others.clear(); + m_bookmarksMenu->clear(); + marksChanged(); + + Document *doc = m_doc; + if (!doc) + doc = m_viewManager->activeDocument(); + QValueList openedDocuments = m_viewManager->openedDocuments(); + if (doc && doc->markIf) + { + QPtrList m = doc->markIf->marks(); + + if (!m_onlyFromActualDocument) + { + m_bookmarkToggle->setChecked( doc->markIf->mark( doc->viewCursorIf->cursorLine() ) + & KTextEditor::MarkInterface::markType01 ); + m_bookmarkToggle->plug( m_bookmarksMenu ); + m_bookmarkClear->plug( m_bookmarksMenu ); + } + + insertBookmarks(*m_bookmarksMenu, doc, !m_onlyFromActualDocument); + if (openedDocuments.count() > 1 && !m_onlyFromActualDocument) + m_bookmarksMenu->insertSeparator(); + } + if (!m_onlyFromActualDocument) + { + int i = 0; + for (QValueList::Iterator it = openedDocuments.begin(); it != openedDocuments.end(); ++it) + { + if (*it != doc) + { + QPopupMenu *menu = new QPopupMenu(m_bookmarksMenu); + m_bookmarksMenu->insertItem((*it)->url().fileName(), menu); + if (insertBookmarks(*menu, *it, false) > 0) + { + m_othersMenuList.append(menu); + m_others.append(*it); + i++; + } else + delete menu; + } + } + } +} + +/* + Make sure next/prev actions are plugged, and have a clean text +*/ +void QuantaBookmarks::bookmarkMenuAboutToHide() +{ + m_bookmarkToggle->plug( m_bookmarksMenu ); + m_bookmarkClear->plug( m_bookmarksMenu ); + m_goNext->setText( i18n("Next Bookmark") ); + m_goNext->plug( m_bookmarksMenu ); + m_goPrevious->setText( i18n("Previous Bookmark") ); + m_goPrevious->plug( m_bookmarksMenu ); +} + +void QuantaBookmarks::goNext() +{ + Document *doc = m_doc; + if (!doc) + doc = m_viewManager->activeDocument(); + if (doc && doc->markIf) + { + QPtrList m = doc->markIf->marks(); + if (m.isEmpty()) + return; + + uint line = doc->viewCursorIf->cursorLine(); + int found = -1; + + for (uint z=0; z < m.count(); z++) + if ( (m.at(z)->line > line) && ((found == -1) || (uint(found) > m.at(z)->line)) ) + found = m.at(z)->line; + + if (found != -1) + doc->viewCursorIf->setCursorPositionReal(found, 0); + } +} + +void QuantaBookmarks::goPrevious() +{ + Document *doc = m_doc; + if (!doc) + doc = m_viewManager->activeDocument(); + if (doc && doc->markIf) + { + QPtrList m = doc->markIf->marks(); + if (m.isEmpty()) + return; + + uint line = doc->viewCursorIf->cursorLine(); + int found = -1; + + for (uint z=0; z < m.count(); z++) + if ((m.at(z)->line < line) && ((found == -1) || (uint(found) < m.at(z)->line))) + found = m.at(z)->line; + + if (found != -1) + doc->viewCursorIf->setCursorPositionReal(found, 0); + } +} + +void QuantaBookmarks::gotoLineNumber(int line) +{ + Document *doc = m_doc; + if (!doc) + doc = m_viewManager->activeDocument(); + const QObject *s = sender(); + for (uint i = 0; i < m_othersMenuList.count(); i++) + { + if (s == m_othersMenuList[i]) + { + doc = m_others[i]; + break; + } + } + if (doc) + { + if (doc->isUntitled()) + { + emit gotoFileAndLine("file:" + doc->url().path(), line, 0); + } else + { + emit gotoFileAndLine(doc->url().url(), line, 0); + } + } +} + + +void QuantaBookmarks::marksChanged () +{ + Document *doc = m_doc; + if (!doc) + doc = m_viewManager->activeDocument(); + if (doc && doc->markIf) + { + m_bookmarkClear->setEnabled( !doc->markIf->marks().isEmpty() ); + } +} + +#include "quantabookmarks.moc" + +// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/quanta/utility/quantabookmarks.h b/quanta/utility/quantabookmarks.h new file mode 100644 index 00000000..10c0aad4 --- /dev/null +++ b/quanta/utility/quantabookmarks.h @@ -0,0 +1,99 @@ +/* This file is part of the KDE libraries + Copyright (C) 2002, 2003 Anders Lund + Copyright (C) 2002 John Firebaugh + Copyright (C) 2005 Andras Mantia + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +/* Extended bookmark manager. Code taken from the Kate part and adapted to +Quanta, so it works over multiple document */ + +#ifndef QUANTABOOKMARKS_H +#define QUANTABOOKMARKS_H + +#include +#include + +namespace KTextEditor { class Mark; } + +class ViewManager; +class Document; + +class KAction; +class KToggleAction; +class KActionCollection; +class QPopupMenu; +class QMenuData; + + + +class QuantaBookmarks : public QObject +{ + Q_OBJECT + + public: + enum Sorting { Position, Creation }; + QuantaBookmarks(ViewManager *parent, Sorting sort=Position, bool onlyFromActualDocument = false ); + virtual ~QuantaBookmarks(); + + void createActions( KActionCollection* ); + void setBookmarksMenu(QPopupMenu* bookmarksMenu); + + QuantaBookmarks::Sorting sorting() { return m_sorting; }; + void setSorting( Sorting s ) { m_sorting = s; }; + void setDocument(Document *doc) {m_doc = doc;} + + protected: + int insertBookmarks(QPopupMenu& menu, Document *doc, bool insertNavigationItems = true); + void init(KActionCollection* ac = 0L); + + private slots: + void toggleBookmark(); + void clearBookmarks(); + + void bookmarkMenuAboutToShow(); + void bookmarkMenuAboutToHide(); + + void goNext(); + void goPrevious(); + void gotoLineNumber(int line); + + void marksChanged (); + + signals: + void gotoFileAndLine(const QString&, int, int); + + private: + KToggleAction* m_bookmarkToggle; + KAction* m_bookmarkClear; + KAction* m_goNext; + KAction* m_goPrevious; + + Sorting m_sorting; + QPopupMenu* m_bookmarksMenu; + QValueList m_othersMenuList; + QValueList m_others; + ViewManager* m_viewManager; + Document *m_doc; + bool m_onlyFromActualDocument; + + uint _tries; +}; + +#endif + +// kate: space-indent on; indent-width 2; replace-tabs on; +// vim: noet ts=2 diff --git a/quanta/utility/quantacommon.cpp b/quanta/utility/quantacommon.cpp new file mode 100644 index 00000000..7cc7fb1b --- /dev/null +++ b/quanta/utility/quantacommon.cpp @@ -0,0 +1,753 @@ +/*************************************************************************** + quantacommon.cpp - description + ------------------- + begin : Sat Jul 27 2002 + copyright : (C) 2002, 2003 by Andras Mantia + ***************************************************************************/ + +/*************************************************************************** + * * + * 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; version 2 of the License. * + * * + ***************************************************************************/ + +//system includes +#include +#include + +//qt includes +#include +#include +#include +#include +#include +#include +#include + +//kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//remove the below ones when KQPasteAction is removed +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qextfileinfo.h" +#include "quantacommon.h" +#include "tag.h" +#include "dtds.h" +//#include "resource.h" + + +QConfig qConfig; //holds the main configuration settings +QString tmpDir; + +QRegExp scriptBeginRx; +QRegExp scriptEndRx; + +Node *baseNode; +Parser *parser; +KDirWatch *fileWatcher; +KProgress *progressBar; + +QString toolbarExtension = ".toolbar.tgz"; +QRegExp newLineRx("\\n"); +QStringList charList; //hold the list of the &char; chars. See the data/chars file. +QMap replacementMap; +QPtrList tempFileList; +QPtrList tempDirList; +bool typingInProgress; + +QuantaCommon::QuantaCommon(){ +} + +QuantaCommon::~QuantaCommon(){ +} + +/** convert tag to upper or lower case */ +QString QuantaCommon::tagCase( const QString& tag) +{ + QString sTag = tag; + + switch (qConfig.tagCase) + { + case 1: sTag = tag.lower(); + break; + case 2: sTag = tag.upper(); + } + return sTag; +} + +/** convert attr of tag to upper or lower case */ +QString QuantaCommon::attrCase( const QString& attr) +{ + QString sAttr = attr; + + switch (qConfig.attrCase) + { + case 1: sAttr = attr.lower(); + break; + case 2: sAttr = attr.upper(); + } + return sAttr; +} + +/** returns the attribute value in quoted form, by taking care of the +quotation setting*/ +QString QuantaCommon::quoteAttributeValue(const QString& value) +{ + QString quote = qConfig.attrValueQuotation; + return quote + value + quote; +} + +/** Set's up the url correctly from urlString. */ +void QuantaCommon::setUrl(KURL &url, const QString& urlString) +{ + KURL oldUrl = url; + url = urlString; + if (!KProtocolInfo::isKnownProtocol(url)) + { + url = oldUrl; + url.setPath(urlString); + if (url.protocol().isEmpty()) + url.setProtocol("file"); + } +} + +/** No descriptions */ +bool QuantaCommon::isSingleTag(const QString& dtdName, const QString& tag) +{ + bool single = false; + + //!doctype is a common tag to all DTDs not listed in the tagsList + if(tag.lower() == "!doctype" || tag.lower() == "?xml") + return true; + + const DTDStruct* dtd = DTDs::ref()->find(dtdName); + if (dtd && !tag.isEmpty()) + { + QString searchForTag = (dtd->caseSensitive) ? tag : tag.upper(); + QTag* qtag = dtd->tagsList->find(searchForTag); + if (qtag) + single = qtag->isSingle(); + } + + return single; +} + +/** No descriptions */ +bool QuantaCommon::isOptionalTag(const QString& dtdName, const QString& tag) +{ + bool optional = false; + + const DTDStruct* dtd = DTDs::ref()->find(dtdName); + if (dtd && !tag.isEmpty()) + { + QString searchForTag = (dtd->caseSensitive) ? tag : tag.upper(); + QTag* qtag = dtd->tagsList->find(searchForTag); + if (qtag) + optional = qtag->isOptional(); + } + + return optional; +} +/** No descriptions */ +bool QuantaCommon::isKnownTag(const QString& dtdName, const QString& tag) +{ + bool known = false; + + const DTDStruct* dtd = DTDs::ref()->find(dtdName); + if (dtd && !tag.isEmpty()) + { + QString searchForTag = (dtd->caseSensitive) ? tag : tag.upper(); + if (dtd->tagsList->find(searchForTag)) + known = true; + } + + return known; +} + +AttributeList* QuantaCommon::tagAttributes(const QString& dtdName, const QString& tag) +{ + AttributeList* attrs = 0L; + + const DTDStruct* dtd = DTDs::ref()->find(dtdName); + if (dtd && !tag.isEmpty()) + { + QString searchForTag = (dtd->caseSensitive) ? tag : tag.upper(); + QTag* qtag = dtd->tagsList->find(searchForTag); + if (qtag) + attrs = qtag->attributes(); + } + + return attrs; +} + +/** Returns the QTag object for the tag "tag" from the DTD named "dtdname". */ +QTag* QuantaCommon::tagFromDTD(const QString& dtdName, const QString& tag) +{ + const DTDStruct* dtd = DTDs::ref()->find(dtdName); + return tagFromDTD(dtd, tag); +} + +/** Returns the QTag object for the tag "tag" from the DTD. */ +QTag* QuantaCommon::tagFromDTD(const DTDStruct *dtd, const QString& tag) +{ + QTag *qtag = 0; + if (dtd && !tag.isEmpty()) + { + QString searchForTag = (dtd->caseSensitive) ? tag : tag.upper(); + qtag = dtd->tagsList->find(searchForTag); + } + + return qtag; +} + +/** Returns the QTag object for the node "node" from node's DTD. */ +QTag* QuantaCommon::tagFromDTD(Node *node) +{ + if(!node || !node->tag) + return 0L; + + return tagFromDTD(node->tag->dtd(), node->tag->name); +} + +/** Returns an XML style string containing the GUI for attributes. */ +QString QuantaCommon::xmlFromAttributes(AttributeList* attributes) +{ + QString xmlStr; + QTextStream stream( &xmlStr, IO_WriteOnly ); + stream.setEncoding(QTextStream::UnicodeUTF8); + if (attributes) + { + int row = 0; + for ( uint i = 0; i< attributes->count();i++) + { + Attribute *attribute = attributes->at(i); + QString name = attribute->name.left(1).upper()+attribute->name.right(attribute->name.length()-1); + stream << " name +"\" type=\""+attribute->type+"\""; + if (!attribute->defaultValue.isEmpty()) + stream << " defaultValue=\"" + attribute->defaultValue + "\""; + if (!attribute->status.isEmpty()) + stream << " status=\"" + attribute->status + "\""; + stream << ">" << endl; + stream << " " << name << "" << endl; + if (attribute->type != "check") + { + stream << " " << endl; + } + stream << " " << endl; + + if (attribute->type == "list") + { + stream << " " << endl; + for (uint j = 0; j < attribute->values.count(); j++) + { + stream << " " << attribute->values[j] << "" << endl; + } + stream << " " << endl; + } + stream << " " << endl << endl ; + row++; + } //for + } //if + + return xmlStr; +} + + /** Returns 0 if the (line,col) is inside the area specified by the other +arguments, -1 if it is before the area and 1 if it is after. */ +int QuantaCommon::isBetween(int line, int col, int bLine, int bCol, int eLine, +int eCol){ + int pos = 0; + if (line < bLine || (line == bLine && (col < bCol) )) pos = -1; //it is before + if (line > eLine || (line == eLine && (col > eCol) )) pos = 1; //it is after + + return pos; +} + +/** Returns a pointer to a KStandardDirs object usable for plugin searchup. type +is the plugin binary type (exe or lib). The returned pointer must be deleted by +the caller!! */ +KStandardDirs* QuantaCommon::pluginDirs(const char *type) +{ + KStandardDirs *dirs = new KStandardDirs(); + dirs->addKDEDefaults(); + for (uint i = 0; i < qConfig.pluginSearchPaths.count(); i++) + { + dirs->addResourceDir(type, qConfig.pluginSearchPaths[i]); + } + return dirs; +} +/** Return true, if the url belong to the mimetype group. */ +bool QuantaCommon::checkMimeGroup(const KURL& url, const QString& group) +{ + KMimeType::List list = KMimeType::allMimeTypes(); + KMimeType::List::iterator it; + bool status = false; + KMimeType::Ptr mime = KMimeType::findByURL(url); + QString mimetype = mime->name(); + mimetype = mimetype.section('/',-1); + for ( it = list.begin(); it != list.end(); ++it ) + { + if ( ((*it)->name().contains(group)) && ((*it)->name().find(mimetype) != -1) +) { + status = true; + break; + } + } + + if (!status && group == "text") + { + if (url.isLocalFile()) + { + KMimeType::Format f = KMimeType::findFormatByFileContent(url.path()); + if (f.text && f.compression == KMimeType::Format::NoCompression) + status = true; + } else + { + QVariant v = mime->property("X-KDE-text"); + if (v.isValid()) + status = v.toBool(); + } + } + if (!status && group == "text" && mimetype == "x-zerosize") + status = true; + + return status; +} + +/** Return true, if the url has the mimetype type. */ +bool QuantaCommon::checkMimeType(const KURL& url, const QString& type) +{ + bool status = false; + QString mimetype = KMimeType::findByURL(url)->name(); + mimetype = mimetype.section('/',-1); + if (mimetype == type) status = true; + + return status; +} + +/** Return true, if the url has exactly the mimetype type. */ +bool QuantaCommon::checkExactMimeType(const KURL& url, const QString& type) +{ + bool status = false; + QString mimetype = KMimeType::findByURL(url)->name(); + if (mimetype == type) status = true; + + return status; +} + +/** Returns the url without the filename. */ +KURL QuantaCommon::convertToPath(const KURL& url) +{ + KURL result = url; + result.setFileName(""); + result.adjustPath(1); + return result; +} + +/** Return a string to be used when an url is saved to the project file. + Returns url.url() if it's an absolute url and + url.path() if the url is relative */ +QString QuantaCommon::qUrl(const KURL &url) +{ + QString result = url.path(); + if (url.path().startsWith("/")) result = url.url(); + + return result; +} +/** No descriptions */ +void QuantaCommon::dirCreationError(QWidget *widget, const KURL& url) +{ + KMessageBox::error(widget, i18n("Cannot create folder
%1.
Check that you have write permission in the parent folder or that the connection to
%2
is valid.
") + .arg(url.prettyURL(0, KURL::StripFileProtocol)) + .arg(url.protocol()+"://"+url.user()+"@"+url.host()));} + +/** +Adds the backslash before the special chars (like ?, *, . ) so the returned +string can be used in regular expressions.*/ +QString QuantaCommon::makeRxCompatible(const QString& s) +{ + const uint max = 7; + const QRegExp rxs[max]={QRegExp("\\?"), + QRegExp("\\*"), + QRegExp("\\."), + QRegExp("\\^"), + QRegExp("\\$"), + QRegExp("\\{"), + QRegExp("\\}") + }; + const QString strs[max]={QString("\\?"), + QString("\\*"), + QString("\\."), + QString("\\^"), + QString("\\$"), + QString("\\{"), + QString("\\}") + }; + QString str = s; + for (uint i = 0; i < max - 1; i++) + { + str.replace(rxs[i], strs[i]); + } + + return str; +} + +/** Returns the translated a_str in English. A "back-translation" useful e.g in case of CSS elements selected from a listbox. */ +QString QuantaCommon::i18n2normal(const QString& a_str) +{ +//TODO: a QMap lookup would be faster, but we need a pre-built QMap + const int keywordNum = 15 *5; + const QString keywords[keywordNum] = + {"normal", "italic", "oblique", "serif", "sans-serif", + "cursive", "fantasy", "monospace", "small-caps", "lighter", + "bold", "bolder", "xx-small", "x-small", "small", + "medium", "large", "x-large", "xx-large", "smaller", + "larger", "repeat", "repeat-x", "repeat-y", "no-repeat", + "scroll", "fixed", "top", "center", "bottom", + "left", "right", "none", "underline", "overline" + "line-through", "blibk", "justify","baseline", "sub", + "super", "text-top","text-bottom","capitalize","uppercase", + "lowercase","thin", "thick", "[length value]","dotted", + "dashed", "solid", "double", "groove", "ridge", + "inset", "outset", "block", "inline", "list-item", + "none", "pre", "nowrap", "disc", "circle", + "square", "decimal", "lower-roman","upper-roman","lower-alpha", + "upper-alpha","inside","outside", "auto", "both" }; + QString str = a_str; + if (!a_str.isEmpty()) + { + for (int i = 0; i < keywordNum; i++) + { + if (!keywords[i].isEmpty() && a_str == i18n(keywords[i].utf8())) + { + str = keywords[i]; + break; + } + } + } + return str; +} + +static const QChar space(' '); + +void QuantaCommon::removeCommentsAndQuotes(QString &str, const DTDStruct *dtd) +{ + //Replace all the commented strings and the escaped quotation marks (\", \') + // with spaces so they will not mess up our parsing + int pos = 0; + int l; + QString s; + while (pos != -1) + { + pos = dtd->commentsStartRx.search(str, pos); + if (pos != -1) + { + s = dtd->commentsStartRx.cap(); + if (s == "\\\"" || s == "\\'") + { + int i = pos; + int slahNum = 0; + while (i > 0 && str[i] == '\\') + { + slahNum++; + i--; + } + if (slahNum % 2 == 0) + { + pos++; + } else + { + str[pos] = space; + str[pos+1] = space; + pos += 2; + } + } else + { + s = dtd->comments[s]; + l = str.find(s, pos); + l = (l == -1) ? str.length() : l; + for (int i = pos; i < l ; i++) + { + str[i] = space; + } + pos = l + s.length(); + } + } + } + + //Now replace the quoted strings with spaces + QRegExp strRx("(\"[^\"]*\"|'[^']*')"); + pos = 0; + while (pos != -1) + { + pos = strRx.search(str, pos); + if (pos != -1) + { + l = strRx.matchedLength(); + for (int i = pos; i < pos + l ; i++) + { + str[i] = space; + } + pos += l; + } + } + +} + +bool QuantaCommon::insideCommentsOrQuotes(int position, const QString &string, const DTDStruct *dtd) +{ + //Return true if position is inside a commented or quoted string + QString str = string; + int pos = 0; + int l; + QString s; + while (pos != -1) + { + pos = dtd->commentsStartRx.search(str, pos); + if (pos == position) + return true; + if (pos != -1) + { + s = dtd->commentsStartRx.cap(); + if (s == "\\\"" || s == "\\'") + { + int i = pos; + int slahNum = 0; + while (i > 0 && str[i] == '\\') + { + slahNum++; + i--; + } + if (slahNum % 2 == 0) + { + pos++; + } else + { + str[pos] = space; + str[pos+1] = space; + pos += 2; + } + } else + { + s = dtd->comments[s]; + l = str.find(s, pos); + l = (l == -1) ? str.length() : l; + for (int i = pos; i < l ; i++) + { + str[i] = space; + if (i == position) + return true; + } + pos = l + s.length(); + } + } + } + + //Now replace the quoted strings with spaces + const QRegExp strRx("(\"[^\"]*\"|'[^']*')"); + pos = 0; + while (pos != -1) + { + pos = strRx.search(str, pos); + if (pos != -1) + { + l = strRx.matchedLength(); + for (int i = pos; i < pos + l ; i++) + { + str[i] = space; + if (i == position) + return true; + } + pos += l; + } + } + + return false; +} + +DCOPReply QuantaCommon::callDCOPMethod(const QString& interface, const QString& method, const QString& arguments) +{ + QStringList argumentList = QStringList::split(",", arguments, true); + QString app = "quanta"; + if (!kapp->inherits("KUniqueApplication")) + { + pid_t pid = ::getpid(); + app += QString("-%1").arg(pid); + } + DCOPRef quantaRef(app.utf8(), interface.utf8()); + DCOPReply reply; + int argumentCount = argumentList.count(); + if (argumentCount == 0) + { + reply = quantaRef.call(method.utf8()); + } + else if (argumentCount == 1) + { + reply = quantaRef.call(method.utf8(), argumentList[0]); + } + else if (argumentCount == 2) + reply = quantaRef.call(method.utf8(), argumentList[0], argumentList[1]); + else if (argumentCount == 3) + reply = quantaRef.call(method.utf8(), argumentList[0], argumentList[1], argumentList[2]); + else if (argumentCount == 4) + reply = quantaRef.call(method.utf8(), argumentList[0], argumentList[1], argumentList[2], argumentList[3]); + else if (argumentCount == 5) + reply = quantaRef.call(method.utf8(), argumentList[0], argumentList[1], argumentList[2], argumentList[3], argumentList[4]); + else if (argumentCount == 6) + reply = quantaRef.call(method.utf8(), argumentList[0], argumentList[1], argumentList[2], argumentList[3], argumentList[4], argumentList[5]); + else if (argumentCount == 7) + reply = quantaRef.call(method.utf8(), argumentList[0], argumentList[1], argumentList[2], argumentList[3], argumentList[4], argumentList[5], argumentList[6]); + else if (argumentCount == 8) + reply = quantaRef.call(method.utf8(), argumentList[0], argumentList[1], argumentList[2], argumentList[3], argumentList[4], argumentList[5], argumentList[6], argumentList[7]); + + return reply; +} + +void QuantaCommon::normalizeStructure(QString f,QStringList& l) +{ + f.remove("\t"); + f.remove("\n"); + f.remove("\r"); + + while(f.contains("<")) + { + QString z(f); + z.truncate(z.find(">")+1); + z.remove(0,z.find("<")); + f.remove(0,f.find(">")+1); + l.append(z); + } +} + +bool QuantaCommon::closesTag(Tag *tag1, Tag *tag2) +{ + if (tag1->nameSpace.isEmpty()) + { + if (!tag2->nameSpace.isEmpty()) + return false; //namespace missmatch + QString tag1Name = tag1->dtd()->caseSensitive ? tag1->name : tag1->name.upper(); + QString tag2Name = tag2->dtd()->caseSensitive ? tag2->name : tag2->name.upper(); + if ("/" + tag1Name != tag2Name) + return false; //not the closing tag + } else + { + if (tag2->nameSpace.isEmpty()) + return false; //namespace missmatch + QString tag1Name = tag1->dtd()->caseSensitive ? (tag1->nameSpace + tag1->name) : (tag1->nameSpace.upper() + tag1->name.upper()); + QString tag2Name = tag2->dtd()->caseSensitive ? (tag2->nameSpace + tag2->name) : (tag2->nameSpace.upper() + tag2->name.upper()); + if ("/" + tag1Name != tag2Name) + return false; //namespace missmatch or not the closing tag + } + return true; +} + +bool QuantaCommon::closesTag(QString namespaceName, QString tagName, bool caseSensitive, + QString namespaceName2, QString tagName2, bool caseSensitive2) +{ + QString tag1Name, tag2Name; + if(namespaceName.isEmpty()) + { + if(!namespaceName.isEmpty()) + return false;//namespace missmatch + tag1Name = caseSensitive ? tagName : tagName.upper(); + tag2Name = caseSensitive2 ? tagName2 : tagName2.upper(); + if("/" + tag1Name != tag2Name) + return false;//not the closing tag + } + else + { + if(namespaceName2.isEmpty()) + return false;//namespace missmatch + tag1Name = caseSensitive ? (namespaceName + tagName) : (namespaceName.upper() + + tagName.upper()); + tag2Name = caseSensitive2 ? (namespaceName2 + tagName2) : (namespaceName2.upper() + + tagName2.upper()); + if("/" + tag1Name != tag2Name) + return false; //namespace missmatch or not the closing tag + } + return true; +} + +int QuantaCommon::denyBinaryInsert(QWidget *window) +{ + int result = KMessageBox::questionYesNo(window, i18n("The file type is not recognized. \ + Opening binary files may confuse Quanta.\n Are you sure you want to open this file?"), + i18n("Unknown Type"), KStdGuiItem::open(), i18n("Do Not Open"), "Open Everything"); + return result; +} + +bool QuantaCommon::checkOverwrite(const KURL& url, QWidget *window) +{ + bool result = true; + + if (QExtFileInfo::exists(url, false, window)) + { + if (KMessageBox::warningContinueCancel(window, + i18n( "The file %1 already exists.
Do you want to overwrite it?
" ).arg(url.prettyURL(0, KURL::StripFileProtocol)), QString::null, i18n("Overwrite")) == KMessageBox::Cancel) + result = false; + } + + return result; +} + +QStringList QuantaCommon::readPathListEntry(KConfig *config, const QString &pKey) +{ + QStringList list = config->readPathListEntry(pKey); + QStringList::Iterator end = list.end(); + for (QStringList::Iterator it = list.begin(); it != end; ++it) + { + KURL u = KURL::fromPathOrURL(*it); + if (u.isValid() && u.isLocalFile()) + { + u.setPath(QExtFileInfo::canonicalPath(u.path())); + *it = u.url(); + } + } + return list; +} + +QString QuantaCommon::readPathEntry(KConfig *config, const QString &pKey) +{ + QString path = config->readPathEntry(pKey); + KURL u = KURL::fromPathOrURL(path); + if (u.isValid() && u.isLocalFile()) + { + u.setPath(QExtFileInfo::canonicalPath(u.path())); + path = u.url(); + } + return path; +} + +QString QuantaCommon::encodedChar(uint code) +{ + + if (replacementMap.contains(code)) + return QString("%1;").arg(replacementMap[code]); + else + return QString("&#%1;").arg(code); +} + diff --git a/quanta/utility/quantacommon.h b/quanta/utility/quantacommon.h new file mode 100644 index 00000000..a88276b7 --- /dev/null +++ b/quanta/utility/quantacommon.h @@ -0,0 +1,225 @@ +/*************************************************************************** + quantacommon.h - description + ------------------- + begin : Sat Jul 27 2002 + copyright : (C) 2002, 2003 by Andras Mantia + ***************************************************************************/ + +/*************************************************************************** + * * + * 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; version 2 of the License. * + * * + ***************************************************************************/ + +#ifndef QUANTACOMMON_H +#define QUANTACOMMON_H + +#include + +#include "qtag.h" +#include "node.h" +#include "parser.h" + +/**Some common, mostly static functions. + *@author Andras Mantia + */ + +#define DEFAULT_DTD QString("-//W3C//DTD HTML 4.01 Transitional//EN") + +class QString; +class DCOPReply; +class KURL; +class KStandardDirs; +class QWidget; +class Tag; + +class KConfig; +class KPopupMenu; + +/** Describes one abbreviation group */ +class Abbreviation{ +public: +/*A list with abbreviations in the for of: