summaryrefslogtreecommitdiffstats
path: root/kate/app
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit4aed2c8219774f5d797760606b8489a92ddc5163 (patch)
tree3f8c130f7d269626bf6a9447407ef6c35954426a /kate/app
downloadtdebase-4aed2c8219774f5d797760606b8489a92ddc5163.tar.gz
tdebase-4aed2c8219774f5d797760606b8489a92ddc5163.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kate/app')
-rw-r--r--kate/app/Makefile.am29
-rw-r--r--kate/app/kateapp.cpp399
-rw-r--r--kate/app/kateapp.h243
-rw-r--r--kate/app/kateappIface.cpp104
-rw-r--r--kate/app/kateappIface.h94
-rw-r--r--kate/app/kateconfigdialog.cpp441
-rw-r--r--kate/app/kateconfigdialog.h82
-rw-r--r--kate/app/kateconfigplugindialogpage.cpp121
-rw-r--r--kate/app/kateconfigplugindialogpage.h69
-rw-r--r--kate/app/kateconsole.cpp143
-rw-r--r--kate/app/kateconsole.h116
-rw-r--r--kate/app/katedocmanager.cpp611
-rw-r--r--kate/app/katedocmanager.h156
-rw-r--r--kate/app/katedocmanageriface.cpp131
-rw-r--r--kate/app/katedocmanageriface.h62
-rw-r--r--kate/app/kateexternaltools.cpp873
-rw-r--r--kate/app/kateexternaltools.h229
-rw-r--r--kate/app/katefilelist.cpp652
-rw-r--r--kate/app/katefilelist.h191
-rw-r--r--kate/app/katefileselector.cpp722
-rw-r--r--kate/app/katefileselector.h172
-rw-r--r--kate/app/kategrepdialog.cpp544
-rw-r--r--kate/app/kategrepdialog.h97
-rw-r--r--kate/app/katemailfilesdialog.cpp112
-rw-r--r--kate/app/katemailfilesdialog.h59
-rw-r--r--kate/app/katemain.cpp256
-rw-r--r--kate/app/katemain.h70
-rw-r--r--kate/app/katemainwindow.cpp854
-rw-r--r--kate/app/katemainwindow.h216
-rw-r--r--kate/app/katemainwindowiface.cpp27
-rw-r--r--kate/app/katemainwindowiface.h41
-rw-r--r--kate/app/katemdi.cpp969
-rw-r--r--kate/app/katemdi.h442
-rw-r--r--kate/app/katemwmodonhddialog.cpp281
-rw-r--r--kate/app/katemwmodonhddialog.h61
-rw-r--r--kate/app/katepluginmanager.cpp221
-rw-r--r--kate/app/katepluginmanager.h90
-rw-r--r--kate/app/katesavemodifieddialog.cpp226
-rw-r--r--kate/app/katesavemodifieddialog.h48
-rw-r--r--kate/app/katesession.cpp920
-rw-r--r--kate/app/katesession.h418
-rw-r--r--kate/app/katetabwidget.cpp161
-rw-r--r--kate/app/katetabwidget.h69
-rw-r--r--kate/app/kateviewmanager.cpp514
-rw-r--r--kate/app/kateviewmanager.h154
-rw-r--r--kate/app/kateviewspace.cpp422
-rw-r--r--kate/app/kateviewspace.h121
-rw-r--r--kate/app/kateviewspacecontainer.cpp758
-rw-r--r--kate/app/kateviewspacecontainer.h161
-rw-r--r--kate/app/kbookmarkhandler.cpp98
-rw-r--r--kate/app/kbookmarkhandler.h72
-rw-r--r--kate/app/kwritemain.cpp712
-rw-r--r--kate/app/kwritemain.h138
53 files changed, 14972 insertions, 0 deletions
diff --git a/kate/app/Makefile.am b/kate/app/Makefile.am
new file mode 100644
index 000000000..6175f3203
--- /dev/null
+++ b/kate/app/Makefile.am
@@ -0,0 +1,29 @@
+lib_LTLIBRARIES = libkateinterfaces.la
+bin_PROGRAMS =
+kdeinit_LTLIBRARIES = kate.la kwrite.la
+
+libkateinterfaces_la_SOURCES = kateapp.cpp kateconfigdialog.cpp kateconfigplugindialogpage.cpp \
+ kateconsole.cpp katedocmanager.cpp katefilelist.cpp katefileselector.cpp \
+ katemainwindow.cpp katepluginmanager.cpp \
+ kateviewmanager.cpp kateviewspace.cpp \
+ katemainwindowiface.skel katemainwindowiface.cpp kategrepdialog.cpp \
+ katemailfilesdialog.cpp kbookmarkhandler.cpp \
+ katedocmanageriface.skel kateappIface.cpp kateappIface.skel katedocmanageriface.cpp \
+ kateexternaltools.cpp katesavemodifieddialog.cpp kateviewspacecontainer.cpp \
+ katemwmodonhddialog.cpp katesession.cpp katemdi.cpp katetabwidget.cpp
+
+libkateinterfaces_la_LIBADD = ../interfaces/libkateinterfacesprivate.la $(LIB_KUTILS) ../utils/libkateutils.la
+
+libkateinterfaces_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) -no-undefined
+
+kate_la_SOURCES = katemain.cpp
+kate_la_LIBADD = libkateinterfaces.la
+kate_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) -module -avoid-version
+
+kwrite_la_SOURCES = kwritemain.cpp
+kwrite_la_LIBADD = -lkatepartinterfaces ../utils/libkateutils.la
+kwrite_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) -module -avoid-version
+
+METASOURCES = AUTO
+
+INCLUDES= -I../interfaces -I$(srcdir)/../lib $(all_includes)
diff --git a/kate/app/kateapp.cpp b/kate/app/kateapp.cpp
new file mode 100644
index 000000000..00b58b8b5
--- /dev/null
+++ b/kate/app/kateapp.cpp
@@ -0,0 +1,399 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kateapp.h"
+#include "kateapp.moc"
+
+#include "katedocmanager.h"
+#include "katepluginmanager.h"
+#include "kateviewmanager.h"
+#include "kateappIface.h"
+#include "katesession.h"
+#include "katemainwindow.h"
+
+#include "../interfaces/application.h"
+
+#include <kdeversion.h>
+#include <kcmdlineargs.h>
+#include <dcopclient.h>
+#include <kconfig.h>
+#include <kwin.h>
+#include <ktip.h>
+#include <kdebug.h>
+#include <klibloader.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <ksimpleconfig.h>
+#include <kstartupinfo.h>
+
+#include <qfile.h>
+#include <qtimer.h>
+#include <qdir.h>
+#include <qtextcodec.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+KateApp::KateApp (KCmdLineArgs *args)
+ : KApplication ()
+ , m_args (args)
+ , m_shouldExit (false)
+{
+ // Don't handle DCOP requests yet
+ dcopClient()->suspend();
+
+ // insert right translations for the katepart
+ KGlobal::locale()->insertCatalogue("katepart");
+
+ // some global default
+ Kate::Document::setFileChangedDialogsActivated (true);
+
+ // application interface
+ m_application = new Kate::Application (this);
+
+ // doc + project man
+ m_docManager = new KateDocManager (this);
+
+ // init all normal plugins
+ m_pluginManager = new KatePluginManager (this);
+
+ // session manager up
+ m_sessionManager = new KateSessionManager (this);
+
+ // application dcop interface
+ m_obj = new KateAppDCOPIface (this);
+
+ kdDebug()<<"Setting KATE_PID: '"<<getpid()<<"'"<<endl;
+ ::setenv( "KATE_PID", QString("%1").arg(getpid()).latin1(), 1 );
+
+ // handle restore different
+ if (isRestored())
+ {
+ restoreKate ();
+ }
+ else
+ {
+ // let us handle our command line args and co ;)
+ // we can exit here if session chooser decides
+ if (!startupKate ())
+ {
+ m_shouldExit = true;
+ return;
+ }
+ }
+
+ // Ok. We are ready for DCOP requests.
+ dcopClient()->resume();
+}
+
+KateApp::~KateApp ()
+{
+ // cu dcop interface
+ delete m_obj;
+
+ // cu plugin manager
+ delete m_pluginManager;
+
+ // delete this now, or we crash
+ delete m_docManager;
+}
+
+KateApp *KateApp::self ()
+{
+ return (KateApp *) kapp;
+}
+
+Kate::Application *KateApp::application ()
+{
+ return m_application;
+}
+
+/**
+ * Has always been the Kate Versioning Scheme:
+ * KDE X.Y.Z contains Kate X-1.Y.Z
+ */
+QString KateApp::kateVersion (bool fullVersion)
+{
+ return fullVersion ? QString ("%1.%2.%3").arg(KDE::versionMajor() - 1).arg(KDE::versionMinor()).arg(KDE::versionRelease())
+ : QString ("%1.%2").arg(KDE::versionMajor() - 1).arg(KDE::versionMinor());
+}
+
+void KateApp::restoreKate ()
+{
+ // restore the nice files ;) we need it
+ Kate::Document::setOpenErrorDialogsActivated (false);
+
+ // activate again correct session!!!
+ sessionConfig()->setGroup("General");
+ QString lastSession (sessionConfig()->readEntry ("Last Session", "default.katesession"));
+ sessionManager()->activateSession (new KateSession (sessionManager(), lastSession, ""), false, false, false);
+
+ m_docManager->restoreDocumentList (sessionConfig());
+
+ Kate::Document::setOpenErrorDialogsActivated (true);
+
+ // restore all windows ;)
+ for (int n=1; KMainWindow::canBeRestored(n); n++)
+ newMainWindow(sessionConfig(), QString ("%1").arg(n));
+
+ // oh, no mainwindow, create one, should not happen, but make sure ;)
+ if (mainWindows() == 0)
+ newMainWindow ();
+
+ // Do not notify about start there: this makes kicker crazy and kate go to a wrong desktop.
+ // KStartupInfo::setNewStartupId( activeMainWindow(), startupId());
+}
+
+bool KateApp::startupKate ()
+{
+ // user specified session to open
+ if (m_args->isSet ("start"))
+ {
+ sessionManager()->activateSession (sessionManager()->giveSession (QString::fromLocal8Bit(m_args->getOption("start"))), false, false);
+ }
+ else
+ {
+ // let the user choose session if possible
+ if (!sessionManager()->chooseSession ())
+ {
+ // we will exit kate now, notify the rest of the world we are done
+ KStartupInfo::appStarted (startupId());
+ return false;
+ }
+ }
+
+ // oh, no mainwindow, create one, should not happen, but make sure ;)
+ if (mainWindows() == 0)
+ newMainWindow ();
+
+ // notify about start
+ KStartupInfo::setNewStartupId( activeMainWindow(), startupId());
+
+ QTextCodec *codec = m_args->isSet("encoding") ? QTextCodec::codecForName(m_args->getOption("encoding")) : 0;
+
+ bool tempfileSet = KCmdLineArgs::isTempFileSet();
+
+ Kate::Document::setOpenErrorDialogsActivated (false);
+ uint id = 0;
+ for (int z=0; z<m_args->count(); z++)
+ {
+ // this file is no local dir, open it, else warn
+ bool noDir = !m_args->url(z).isLocalFile() || !QDir (m_args->url(z).path()).exists();
+
+ if (noDir)
+ {
+ // open a normal file
+ if (codec)
+ id = activeMainWindow()->viewManager()->openURL( m_args->url(z), codec->name(), false, tempfileSet );
+ else
+ id = activeMainWindow()->viewManager()->openURL( m_args->url(z), QString::null, false, tempfileSet );
+ }
+ else
+ KMessageBox::sorry( activeMainWindow(),
+ i18n("The file '%1' could not be opened: it is not a normal file, it is a folder.").arg(m_args->url(z).url()) );
+ }
+
+ Kate::Document::setOpenErrorDialogsActivated (true);
+
+ // handle stdin input
+ if( m_args->isSet( "stdin" ) )
+ {
+ QTextIStream input(stdin);
+
+ // set chosen codec
+ if (codec)
+ input.setCodec (codec);
+
+ QString line;
+ QString text;
+
+ do
+ {
+ line = input.readLine();
+ text.append( line + "\n" );
+ } while( !line.isNull() );
+
+ openInput (text);
+ }
+ else if ( id )
+ activeMainWindow()->viewManager()->activateView( id );
+
+ if ( activeMainWindow()->viewManager()->viewCount () == 0 )
+ activeMainWindow()->viewManager()->activateView(m_docManager->firstDocument()->documentNumber());
+
+ int line = 0;
+ int column = 0;
+ bool nav = false;
+
+ if (m_args->isSet ("line"))
+ {
+ line = m_args->getOption ("line").toInt();
+ nav = true;
+ }
+
+ if (m_args->isSet ("column"))
+ {
+ column = m_args->getOption ("column").toInt();
+ nav = true;
+ }
+
+ if (nav)
+ activeMainWindow()->viewManager()->activeView ()->setCursorPosition (line, column);
+
+ // show the nice tips
+ KTipDialog::showTip(activeMainWindow());
+
+ return true;
+}
+
+void KateApp::shutdownKate (KateMainWindow *win)
+{
+ if (!win->queryClose_internal())
+ return;
+
+ sessionManager()->saveActiveSession(true, true);
+
+ // detach the dcopClient
+ dcopClient()->detach();
+
+ // cu main windows
+ while (!m_mainWindows.isEmpty())
+ delete m_mainWindows[0];
+
+ quit ();
+}
+
+KatePluginManager *KateApp::pluginManager()
+{
+ return m_pluginManager;
+}
+
+KateDocManager *KateApp::documentManager ()
+{
+ return m_docManager;
+}
+
+KateSessionManager *KateApp::sessionManager ()
+{
+ return m_sessionManager;
+}
+
+bool KateApp::openURL (const KURL &url, const QString &encoding, bool isTempFile)
+{
+ KateMainWindow *mainWindow = activeMainWindow ();
+
+ if (!mainWindow)
+ return false;
+
+ QTextCodec *codec = encoding.isEmpty() ? 0 : QTextCodec::codecForName(encoding.latin1());
+
+ kdDebug () << "OPEN URL "<< encoding << endl;
+
+ // this file is no local dir, open it, else warn
+ bool noDir = !url.isLocalFile() || !QDir (url.path()).exists();
+
+ if (noDir)
+ {
+ // open a normal file
+ if (codec)
+ mainWindow->viewManager()->openURL( url, codec->name(), true, isTempFile );
+ else
+ mainWindow->viewManager()->openURL( url, QString::null, true, isTempFile );
+ }
+ else
+ KMessageBox::sorry( mainWindow,
+ i18n("The file '%1' could not be opened: it is not a normal file, it is a folder.").arg(url.url()) );
+
+ return true;
+}
+
+bool KateApp::setCursor (int line, int column)
+{
+ KateMainWindow *mainWindow = activeMainWindow ();
+
+ if (!mainWindow)
+ return false;
+
+ mainWindow->viewManager()->activeView ()->setCursorPosition (line, column);
+
+ return true;
+}
+
+bool KateApp::openInput (const QString &text)
+{
+ activeMainWindow()->viewManager()->openURL( "", "", true );
+
+ if (!activeMainWindow()->viewManager()->activeView ())
+ return false;
+
+ activeMainWindow()->viewManager()->activeView ()->getDoc()->setText (text);
+
+ return true;
+}
+
+KateMainWindow *KateApp::newMainWindow (KConfig *sconfig, const QString &sgroup)
+{
+ KateMainWindow *mainWindow = new KateMainWindow (sconfig, sgroup);
+ m_mainWindows.push_back (mainWindow);
+
+ if ((mainWindows() > 1) && m_mainWindows[m_mainWindows.count()-2]->viewManager()->activeView())
+ mainWindow->viewManager()->activateView ( m_mainWindows[m_mainWindows.count()-2]->viewManager()->activeView()->getDoc()->documentNumber() );
+ else if ((mainWindows() > 1) && (m_docManager->documents() > 0))
+ mainWindow->viewManager()->activateView ( (m_docManager->document(m_docManager->documents()-1))->documentNumber() );
+ else if ((mainWindows() > 1) && (m_docManager->documents() < 1))
+ mainWindow->viewManager()->openURL ( KURL() );
+
+ mainWindow->show ();
+
+ return mainWindow;
+}
+
+void KateApp::removeMainWindow (KateMainWindow *mainWindow)
+{
+ m_mainWindows.remove (mainWindow);
+}
+
+KateMainWindow *KateApp::activeMainWindow ()
+{
+ if (m_mainWindows.isEmpty())
+ return 0;
+
+ int n = m_mainWindows.findIndex ((KateMainWindow *)activeWindow());
+
+ if (n < 0)
+ n=0;
+
+ return m_mainWindows[n];
+}
+
+uint KateApp::mainWindows () const
+{
+ return m_mainWindows.size();
+}
+
+KateMainWindow *KateApp::mainWindow (uint n)
+{
+ if (n < m_mainWindows.size())
+ return m_mainWindows[n];
+
+ return 0;
+}
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/kateapp.h b/kate/app/kateapp.h
new file mode 100644
index 000000000..ff1d9d967
--- /dev/null
+++ b/kate/app/kateapp.h
@@ -0,0 +1,243 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KATE_APP_H__
+#define __KATE_APP_H__
+
+#include "katemain.h"
+
+#include <kapplication.h>
+
+#include <qvaluelist.h>
+
+class KateSessionManager;
+class KateAppDCOPIface;
+
+namespace Kate {
+ class Application;
+}
+
+class KCmdLineArgs;
+
+/**
+ * Kate Application
+ * This class represents the core kate application object
+ */
+class KDE_EXPORT KateApp : public KApplication
+{
+ Q_OBJECT
+
+ /**
+ * constructors & accessor to app object + plugin interface for it
+ */
+ public:
+ /**
+ * application constructor
+ * @param args parsed command line args
+ */
+ KateApp (KCmdLineArgs *args);
+
+ /**
+ * application destructor
+ */
+ ~KateApp ();
+
+ /**
+ * static accessor to avoid casting ;)
+ * @return app instance
+ */
+ static KateApp *self ();
+
+ /**
+ * accessor to the Kate::Application plugin interface
+ * @return application plugin interface
+ */
+ Kate::Application *application ();
+
+ /**
+ * Returns the current Kate version (X.Y) or (X.Y.Z)
+ * @param fullVersion should full version be returned?
+ * @return Kate version
+ */
+ static QString kateVersion (bool fullVersion = true);
+
+ /**
+ * kate init
+ */
+ private:
+ /**
+ * restore a old kate session
+ */
+ void restoreKate ();
+
+ /**
+ * try to start kate
+ * @return success, if false, kate should exit
+ */
+ bool startupKate ();
+
+ /**
+ * kate shutdown
+ */
+ public:
+ /**
+ * shutdown kate application
+ * @param win mainwindow which is used for dialogs
+ */
+ void shutdownKate (KateMainWindow *win);
+
+ /**
+ * application should exit
+ * @return should we exit?
+ */
+ bool shouldExit () { return m_shouldExit; }
+
+ /**
+ * other accessors for global unique instances
+ */
+ public:
+ /**
+ * accessor to plugin manager
+ * @return plugin manager instance
+ */
+ KatePluginManager *pluginManager();
+
+ /**
+ * accessor to document manager
+ * @return document manager instance
+ */
+ KateDocManager *documentManager ();
+
+ /**
+ * accessor to session manager
+ * @return session manager instance
+ */
+ KateSessionManager *sessionManager ();
+
+ /**
+ * window management
+ */
+ public:
+ /**
+ * create a new main window, use given config if any for restore
+ * @param sconfig session config object
+ * @param sgroup session group for this window
+ * @return new constructed main window
+ */
+ KateMainWindow *newMainWindow (KConfig *sconfig = 0, const QString &sgroup = "");
+
+ /**
+ * removes the mainwindow given, DOES NOT DELETE IT
+ * @param mainWindow window to remove
+ */
+ void removeMainWindow (KateMainWindow *mainWindow);
+
+ /**
+ * give back current active main window
+ * can only be 0 at app start or exit
+ * @return current active main window
+ */
+ KateMainWindow *activeMainWindow ();
+
+ /**
+ * give back number of existing main windows
+ * @return number of main windows
+ */
+ uint mainWindows () const;
+
+ /**
+ * give back the window you want
+ * @param n window index
+ * @return requested main window
+ */
+ KateMainWindow *mainWindow (uint n);
+
+ /**
+ * some stuff for the dcop API
+ */
+ public:
+ /**
+ * open url with given encoding
+ * used by kate if --use given
+ * @param url filename
+ * @param encoding encoding name
+ * @param isTempFile if set to true and the file is a local file, it will be deleted when the document is closed.
+ * @return success
+ */
+ bool openURL (const KURL &url, const QString &encoding, bool isTempFile );
+
+ /**
+ * position cursor in current active view
+ * @param line line to set
+ * @param column column to set
+ * @return success
+ */
+ bool setCursor (int line, int column);
+
+ /**
+ * helper to handle stdin input
+ * open a new document/view, fill it with the text given
+ * @param text text to fill in the new doc/view
+ * @return success
+ */
+ bool openInput (const QString &text);
+
+ private:
+ /**
+ * kate's command line args
+ */
+ KCmdLineArgs *m_args;
+
+ /**
+ * plugin interface
+ */
+ Kate::Application *m_application;
+
+ /**
+ * document manager
+ */
+ KateDocManager *m_docManager;
+
+ /**
+ * plugin manager
+ */
+ KatePluginManager *m_pluginManager;
+
+ /**
+ * session manager
+ */
+ KateSessionManager *m_sessionManager;
+
+ /**
+ * known main windows
+ */
+ QValueList<KateMainWindow*> m_mainWindows;
+
+ /**
+ * dcop interface
+ */
+ KateAppDCOPIface *m_obj;
+
+ /**
+ * should exit flag
+ */
+ bool m_shouldExit;
+};
+
+#endif
diff --git a/kate/app/kateappIface.cpp b/kate/app/kateappIface.cpp
new file mode 100644
index 000000000..b70be960a
--- /dev/null
+++ b/kate/app/kateappIface.cpp
@@ -0,0 +1,104 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kateappIface.h"
+
+#include "kateapp.h"
+#include "katesession.h"
+#include "katedocmanager.h"
+#include "katemainwindow.h"
+
+KateAppDCOPIface::KateAppDCOPIface (KateApp *app) : DCOPObject ("KateApplication")
+ , m_app (app)
+{
+}
+
+DCOPRef KateAppDCOPIface::documentManager ()
+{
+ return DCOPRef (m_app->documentManager()->dcopObject ());
+}
+
+DCOPRef KateAppDCOPIface::activeMainWindow ()
+{
+ KateMainWindow *win = m_app->activeMainWindow();
+
+ if (win)
+ return DCOPRef (win->dcopObject ());
+
+ return DCOPRef ();
+}
+
+uint KateAppDCOPIface::activeMainWindowNumber ()
+{
+ KateMainWindow *win = m_app->activeMainWindow();
+
+ if (win)
+ return win->mainWindowNumber ();
+
+ return 0;
+}
+
+
+uint KateAppDCOPIface::mainWindows ()
+{
+ return m_app->mainWindows ();
+}
+
+DCOPRef KateAppDCOPIface::mainWindow (uint n)
+{
+ KateMainWindow *win = m_app->mainWindow(n);
+
+ if (win)
+ return DCOPRef (win->dcopObject ());
+
+ return DCOPRef ();
+}
+
+bool KateAppDCOPIface::openURL (KURL url, QString encoding)
+{
+ return m_app->openURL (url, encoding, false);
+}
+
+bool KateAppDCOPIface::openURL (KURL url, QString encoding, bool isTempFile)
+{
+ return m_app->openURL (url, encoding, isTempFile);
+}
+
+bool KateAppDCOPIface::setCursor (int line, int column)
+{
+ return m_app->setCursor (line, column);
+}
+
+bool KateAppDCOPIface::openInput (QString text)
+{
+ return m_app->openInput (text);
+}
+
+bool KateAppDCOPIface::activateSession (QString session)
+{
+ m_app->sessionManager()->activateSession (m_app->sessionManager()->giveSession (session));
+
+ return true;
+}
+
+const QString & KateAppDCOPIface::session() const
+{
+ return m_app->sessionManager()->activeSession()->sessionName();
+}
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/kateappIface.h b/kate/app/kateappIface.h
new file mode 100644
index 000000000..577c36e41
--- /dev/null
+++ b/kate/app/kateappIface.h
@@ -0,0 +1,94 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _kateapp_Iface_h_
+#define _kateapp_Iface_h_
+
+#include <dcopobject.h>
+#include <dcopref.h>
+#include <kurl.h>
+
+class KateApp;
+
+class KateAppDCOPIface : public DCOPObject
+{
+ K_DCOP
+
+ public:
+ KateAppDCOPIface (KateApp *app);
+
+ k_dcop:
+ DCOPRef documentManager ();
+
+ DCOPRef activeMainWindow ();
+
+ uint activeMainWindowNumber ();
+
+ uint mainWindows ();
+ DCOPRef mainWindow (uint n = 0);
+
+ /**
+ * open a file with given url and encoding
+ * will get view created
+ * @param url url of the file
+ * @param encoding encoding name
+ * @return success
+ */
+ bool openURL (KURL url, QString encoding);
+
+ /**
+ * Like the above, but adds an option to let the documentManager know
+ * if the file should be deleted when closed.
+ * @p isTempFile should be set to true with the --tempfile option set ONLY,
+ * files opened with this set to true will be deleted when closed.
+ */
+ bool openURL(KURL url, QString encoding, bool isTempFile);
+
+ /**
+ * set cursor of active view in active main window
+ * @param line line for cursor
+ * @param column column for cursor
+ * @return success
+ */
+ bool setCursor (int line, int column);
+
+ /**
+ * helper to handle stdin input
+ * open a new document/view, fill it with the text given
+ * @param text text to fill in the new doc/view
+ * @return success
+ */
+ bool openInput (QString text);
+
+ /**
+ * activate a given session
+ * @param session session name
+ * @return success
+ */
+ bool activateSession (QString session);
+
+ /**
+ * @return the name of the active session
+ */
+ const QString & session() const;
+
+ private:
+ KateApp *m_app;
+};
+
+#endif
diff --git a/kate/app/kateconfigdialog.cpp b/kate/app/kateconfigdialog.cpp
new file mode 100644
index 000000000..62d86054b
--- /dev/null
+++ b/kate/app/kateconfigdialog.cpp
@@ -0,0 +1,441 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kateconfigdialog.h"
+#include "kateconfigdialog.moc"
+
+#include "katemainwindow.h"
+
+#include "kateconsole.h"
+#include "katedocmanager.h"
+#include "katepluginmanager.h"
+#include "kateconfigplugindialogpage.h"
+#include "kateviewmanager.h"
+#include "kateapp.h"
+#include "katefileselector.h"
+#include "katefilelist.h"
+#include "kateexternaltools.h"
+
+#include <qbuttongroup.h>
+#include <qcheckbox.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qspinbox.h>
+#include <qvbox.h>
+#include <qwhatsthis.h>
+#include <qcombobox.h>
+
+#include <kinstance.h>
+#include <kdebug.h>
+#include <kdialogbase.h>
+#include <kglobalaccel.h>
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <kiconloader.h>
+#include <kkeydialog.h>
+#include <klistbox.h>
+#include <klocale.h>
+#include <ksimpleconfig.h>
+#include <kstdaction.h>
+#include <kstandarddirs.h>
+#include <kwin.h>
+#include <kseparator.h>
+
+KateConfigDialog::KateConfigDialog ( KateMainWindow *parent, Kate::View *view )
+ : KDialogBase ( KDialogBase::TreeList,
+ i18n("Configure"),
+ KDialogBase::Ok | KDialogBase::Apply|KDialogBase::Cancel | KDialogBase::Help,
+ KDialogBase::Ok,
+ parent,
+ "configdialog" )
+{
+ KConfig *config = KateApp::self()->config();
+
+ KWin::setIcons( winId(), KateApp::self()->icon(), KateApp::self()->miniIcon() );
+
+ actionButton( KDialogBase::Apply)->setEnabled( false );
+
+ mainWindow = parent;
+
+ setMinimumSize(600,400);
+
+ v = view;
+
+ pluginPages.setAutoDelete (false);
+ editorPages.setAutoDelete (false);
+
+ QStringList path;
+
+ setShowIconsInTreeList(true);
+
+ path.clear();
+ path << i18n("Application");
+ setFolderIcon (path, SmallIcon("kate", KIcon::SizeSmall));
+
+ path.clear();
+
+ //BEGIN General page
+ path << i18n("Application") << i18n("General");
+ QFrame* frGeneral = addPage(path, i18n("General Options"), BarIcon("gohome", KIcon::SizeSmall));
+
+ QVBoxLayout *lo = new QVBoxLayout( frGeneral );
+ lo->setSpacing(KDialog::spacingHint());
+ config->setGroup("General");
+
+ // GROUP with the one below: "Appearance"
+ QButtonGroup *bgStartup = new QButtonGroup( 1, Qt::Horizontal, i18n("&Appearance"), frGeneral );
+ lo->addWidget( bgStartup );
+
+ // show full path in title
+ config->setGroup("General");
+ cb_fullPath = new QCheckBox( i18n("&Show full path in title"), bgStartup);
+ cb_fullPath->setChecked( mainWindow->viewManager()->getShowFullPath() );
+ QWhatsThis::add(cb_fullPath,i18n("If this option is checked, the full document path will be shown in the window caption."));
+ connect( cb_fullPath, SIGNAL( toggled( bool ) ), this, SLOT( slotChanged() ) );
+
+
+ // GROUP with the one below: "Behavior"
+ bgStartup = new QButtonGroup( 1, Qt::Horizontal, i18n("&Behavior"), frGeneral );
+ lo->addWidget( bgStartup );
+
+ // sync the konsole ?
+ cb_syncKonsole = new QCheckBox(bgStartup);
+ cb_syncKonsole->setText(i18n("Sync &terminal emulator with active document"));
+ cb_syncKonsole->setChecked(parent->syncKonsole);
+ QWhatsThis::add( cb_syncKonsole, i18n(
+ "If this is checked, the built in Konsole will <code>cd</code> to the directory "
+ "of the active document when started and whenever the active document changes, "
+ "if the document is a local file.") );
+ connect( cb_syncKonsole, SIGNAL( toggled( bool ) ), this, SLOT( slotChanged() ) );
+
+ // modified files notification
+ cb_modNotifications = new QCheckBox(
+ i18n("Wa&rn about files modified by foreign processes"), bgStartup );
+ cb_modNotifications->setChecked( parent->modNotification );
+ QWhatsThis::add( cb_modNotifications, i18n(
+ "If enabled, when Kate receives focus you will be asked what to do with "
+ "files that have been modified on the hard disk. If not enabled, you will "
+ "be asked what to do with a file that has been modified on the hard disk only "
+ "when that file gains focus inside Kate.") );
+ connect( cb_modNotifications, SIGNAL( toggled( bool ) ),
+ this, SLOT( slotChanged() ) );
+
+ // GROUP with the one below: "Meta-informations"
+ bgStartup = new QButtonGroup( 1, Qt::Horizontal, i18n("Meta-Information"), frGeneral );
+ lo->addWidget( bgStartup );
+
+ // save meta infos
+ cb_saveMetaInfos = new QCheckBox( bgStartup );
+ cb_saveMetaInfos->setText(i18n("Keep &meta-information past sessions"));
+ cb_saveMetaInfos->setChecked(KateDocManager::self()->getSaveMetaInfos());
+ QWhatsThis::add(cb_saveMetaInfos, i18n(
+ "Check this if you want document configuration like for example "
+ "bookmarks to be saved past editor sessions. The configuration will be "
+ "restored if the document has not changed when reopened."));
+ connect( cb_saveMetaInfos, SIGNAL( toggled( bool ) ), this, SLOT( slotChanged() ) );
+
+ // meta infos days
+ QHBox *hbDmf = new QHBox( bgStartup );
+ hbDmf->setEnabled(KateDocManager::self()->getSaveMetaInfos());
+ QLabel *lDmf = new QLabel( i18n("&Delete unused meta-information after:"), hbDmf );
+ sb_daysMetaInfos = new QSpinBox( 0, 180, 1, hbDmf );
+ sb_daysMetaInfos->setSpecialValueText(i18n("(never)"));
+ sb_daysMetaInfos->setSuffix(i18n(" day(s)"));
+ sb_daysMetaInfos->setValue( KateDocManager::self()->getDaysMetaInfos() );
+ lDmf->setBuddy( sb_daysMetaInfos );
+ connect( cb_saveMetaInfos, SIGNAL( toggled( bool ) ), hbDmf, SLOT( setEnabled( bool ) ) );
+ connect( sb_daysMetaInfos, SIGNAL( valueChanged ( int ) ), this, SLOT( slotChanged() ) );
+
+ lo->addStretch(1); // :-] works correct without autoadd
+ //END General page
+
+ path.clear();
+
+ //BEGIN Session page
+ path << i18n("Application") << i18n("Sessions");
+ QFrame* frSessions = addPage(path, i18n("Session Management"), BarIcon("history", KIcon::SizeSmall));
+
+ lo = new QVBoxLayout( frSessions );
+ lo->setSpacing(KDialog::spacingHint());
+
+ // GROUP with the one below: "Startup"
+ bgStartup = new QButtonGroup( 1, Qt::Horizontal, i18n("Elements of Sessions"), frSessions );
+ lo->addWidget( bgStartup );
+
+ // restore view config
+ cb_restoreVC = new QCheckBox( bgStartup );
+ cb_restoreVC->setText(i18n("Include &window configuration"));
+ config->setGroup("General");
+ cb_restoreVC->setChecked( config->readBoolEntry("Restore Window Configuration", true) );
+ QWhatsThis::add(cb_restoreVC, i18n(
+ "Check this if you want all your views and frames restored each time you open Kate"));
+ connect( cb_restoreVC, SIGNAL( toggled( bool ) ), this, SLOT( slotChanged() ) );
+
+ QRadioButton *rb1, *rb2, *rb3;
+
+ sessions_start = new QButtonGroup( 1, Qt::Horizontal, i18n("Behavior on Application Startup"), frSessions );
+ lo->add (sessions_start);
+
+ sessions_start->setRadioButtonExclusive( true );
+ sessions_start->insert( rb1=new QRadioButton( i18n("&Start new session"), sessions_start ), 0 );
+ sessions_start->insert( rb2=new QRadioButton( i18n("&Load last-used session"), sessions_start ), 1 );
+ sessions_start->insert( rb3=new QRadioButton( i18n("&Manually choose a session"), sessions_start ), 2 );
+
+ config->setGroup("General");
+ QString sesStart (config->readEntry ("Startup Session", "manual"));
+ if (sesStart == "new")
+ sessions_start->setButton (0);
+ else if (sesStart == "last")
+ sessions_start->setButton (1);
+ else
+ sessions_start->setButton (2);
+
+ connect(rb1, SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
+ connect(rb2, SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
+ connect(rb3, SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
+
+ sessions_exit = new QButtonGroup( 1, Qt::Horizontal, i18n("Behavior on Application Exit or Session Switch"), frSessions );
+ lo->add (sessions_exit);
+
+ sessions_exit->setRadioButtonExclusive( true );
+ sessions_exit->insert( rb1=new QRadioButton( i18n("&Do not save session"), sessions_exit ), 0 );
+ sessions_exit->insert( rb2=new QRadioButton( i18n("&Save session"), sessions_exit ), 1 );
+ sessions_exit->insert( rb3=new QRadioButton( i18n("&Ask user"), sessions_exit ), 2 );
+
+ config->setGroup("General");
+ QString sesExit (config->readEntry ("Session Exit", "save"));
+ if (sesExit == "discard")
+ sessions_exit->setButton (0);
+ else if (sesExit == "save")
+ sessions_exit->setButton (1);
+ else
+ sessions_exit->setButton (2);
+
+ connect(rb1, SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
+ connect(rb2, SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
+ connect(rb3, SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
+
+ lo->addStretch(1); // :-] works correct without autoadd
+ //END Session page
+
+ path.clear();
+
+ // file selector page
+ path << i18n("Application") << i18n("File Selector");
+
+ QVBox *page = addVBoxPage( path, i18n("File Selector Settings"),
+ BarIcon("fileopen", KIcon::SizeSmall) );
+ fileSelConfigPage = new KFSConfigPage( page, "file selector config page",
+ mainWindow->fileselector );
+ connect( fileSelConfigPage, SIGNAL( changed() ), this, SLOT( slotChanged() ) );
+ path.clear();
+
+ path << i18n("Application") << i18n("Document List");
+ page = addVBoxPage( path, i18n("Document List Settings"),
+ BarIcon("view_text", KIcon::SizeSmall) );
+ filelistConfigPage = new KFLConfigPage( page, "file list config page",
+ mainWindow->filelist );
+ connect( filelistConfigPage, SIGNAL( changed() ), this, SLOT( slotChanged() ) );
+ path.clear();
+
+ path << i18n("Application") << i18n("Plugins");
+ /*QVBox **/page=addVBoxPage(path,i18n("Plugin Manager"),
+ BarIcon("connect_established",KIcon::SizeSmall));
+ KateConfigPluginPage *configPluginPage = new KateConfigPluginPage(page, this);
+ connect( configPluginPage, SIGNAL( changed() ), this, SLOT( slotChanged() ) );
+
+ // Tools->External Tools menu
+ path.clear();
+ path << i18n("Application") << i18n("External Tools");
+ page = addVBoxPage( path, i18n("External Tools"),
+ BarIcon("configure", KIcon::SizeSmall) );
+ configExternalToolsPage = new KateExternalToolsConfigWidget(page, "external tools config page");
+ connect( configExternalToolsPage, SIGNAL(changed()), this, SLOT(slotChanged()) );
+
+ // editor widgets from kwrite/kwdialog
+ path.clear();
+ path << i18n("Editor");
+ setFolderIcon (path, SmallIcon("edit", KIcon::SizeSmall));
+
+ for (uint i = 0; i < KTextEditor::configInterfaceExtension (v->document())->configPages (); i++)
+ {
+ path.clear();
+ path << i18n("Editor") << KTextEditor::configInterfaceExtension (v->document())->configPageName (i);
+ /*QVBox **/page = addVBoxPage(path, KTextEditor::configInterfaceExtension (v->document())->configPageFullName (i),
+ KTextEditor::configInterfaceExtension (v->document())->configPagePixmap(i, KIcon::SizeSmall) );
+
+ KTextEditor::ConfigPage *cPage = KTextEditor::configInterfaceExtension (v->document())->configPage(i, page);
+ connect( cPage, SIGNAL( changed() ), this, SLOT( slotChanged() ) );
+ editorPages.append (cPage);
+ }
+
+ KatePluginList &pluginList (KatePluginManager::self()->pluginList());
+ for (unsigned int i=0; i < pluginList.size(); ++i)
+ {
+ if ( pluginList[i].load
+ && Kate::pluginConfigInterfaceExtension(pluginList[i].plugin) )
+ addPluginPage (pluginList[i].plugin);
+ }
+
+ enableButtonSeparator(true);
+ dataChanged = false;
+ unfoldTreeList ();
+}
+
+KateConfigDialog::~KateConfigDialog()
+{
+}
+
+void KateConfigDialog::addPluginPage (Kate::Plugin *plugin)
+{
+ if (!Kate::pluginConfigInterfaceExtension(plugin))
+ return;
+
+ for (uint i=0; i<Kate::pluginConfigInterfaceExtension(plugin)->configPages(); i++)
+ {
+ QStringList path;
+ path.clear();
+ path << i18n("Application")<<i18n("Plugins") << Kate::pluginConfigInterfaceExtension(plugin)->configPageName(i);
+ QVBox *page=addVBoxPage(path, Kate::pluginConfigInterfaceExtension(plugin)->configPageFullName(i), Kate::pluginConfigInterfaceExtension(plugin)->configPagePixmap(i, KIcon::SizeSmall));
+
+ PluginPageListItem *info=new PluginPageListItem;
+ info->plugin = plugin;
+ info->page = Kate::pluginConfigInterfaceExtension(plugin)->configPage (i, page);
+ connect( info->page, SIGNAL( changed() ), this, SLOT( slotChanged() ) );
+ pluginPages.append(info);
+ }
+}
+
+void KateConfigDialog::removePluginPage (Kate::Plugin *plugin)
+{
+ if (!Kate::pluginConfigInterfaceExtension(plugin))
+ return;
+
+ for (uint i=0; i<pluginPages.count(); i++)
+ {
+ if ( pluginPages.at(i)->plugin == plugin )
+ {
+ QWidget *w = pluginPages.at(i)->page->parentWidget();
+ delete pluginPages.at(i)->page;
+ delete w;
+ pluginPages.remove(pluginPages.at(i));
+ i--;
+ }
+ }
+}
+
+void KateConfigDialog::slotOk()
+{
+ slotApply();
+ accept();
+}
+
+void KateConfigDialog::slotApply()
+{
+ KConfig *config = KateApp::self()->config();
+
+ // if data changed apply the kate app stuff
+ if( dataChanged )
+ {
+ config->setGroup("General");
+
+ config->writeEntry("Restore Window Configuration", cb_restoreVC->isChecked());
+
+ int bu = sessions_start->id (sessions_start->selected());
+
+ if (bu == 0)
+ config->writeEntry ("Startup Session", "new");
+ else if (bu == 1)
+ config->writeEntry ("Startup Session", "last");
+ else
+ config->writeEntry ("Startup Session", "manual");
+
+ bu = sessions_exit->id (sessions_exit->selected());
+
+ if (bu == 0)
+ config->writeEntry ("Session Exit", "discard");
+ else if (bu == 1)
+ config->writeEntry ("Session Exit", "save");
+ else
+ config->writeEntry ("Session Exit", "ask");
+
+ config->writeEntry("Save Meta Infos", cb_saveMetaInfos->isChecked());
+ KateDocManager::self()->setSaveMetaInfos(cb_saveMetaInfos->isChecked());
+
+ config->writeEntry("Days Meta Infos", sb_daysMetaInfos->value() );
+ KateDocManager::self()->setDaysMetaInfos(sb_daysMetaInfos->value());
+
+ config->writeEntry("Modified Notification", cb_modNotifications->isChecked());
+ mainWindow->modNotification = cb_modNotifications->isChecked();
+
+ mainWindow->syncKonsole = cb_syncKonsole->isChecked();
+
+ fileSelConfigPage->apply();
+
+ filelistConfigPage->apply();
+
+ configExternalToolsPage->apply();
+ KateExternalToolsCommand::self()->reload();
+ for (uint i=0; i < KateApp::self()->mainWindows(); i++)
+ {
+ KateMainWindow *win = KateApp::self()->mainWindow (i);
+ win->externalTools->reload();
+ }
+ //mainWindow->externalTools->reload();
+
+ mainWindow->viewManager()->setShowFullPath( cb_fullPath->isChecked() ); // hm, stored 2 places :(
+
+ mainWindow->saveOptions ();
+
+ // save plugin config !!
+ KateApp::self()->pluginManager()->writeConfig ();
+ }
+
+ //
+ // editor config ! (the apply() methode will check the changed state internally)
+ //
+ for (uint i=0; i<editorPages.count(); i++)
+ {
+ editorPages.at(i)->apply();
+ }
+
+ v->getDoc()->writeConfig(config);
+
+ //
+ // plugins config ! (the apply() methode SHOULD check the changed state internally)
+ //
+ for (uint i=0; i<pluginPages.count(); i++)
+ {
+ pluginPages.at(i)->page->apply();
+ }
+
+ config->sync();
+
+ dataChanged = false;
+ actionButton( KDialogBase::Apply)->setEnabled( false );
+}
+
+void KateConfigDialog::slotChanged()
+{
+ dataChanged = true;
+ actionButton( KDialogBase::Apply)->setEnabled( true );
+}
diff --git a/kate/app/kateconfigdialog.h b/kate/app/kateconfigdialog.h
new file mode 100644
index 000000000..3fb523b61
--- /dev/null
+++ b/kate/app/kateconfigdialog.h
@@ -0,0 +1,82 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __kate_configdialog_h__
+#define __kate_configdialog_h__
+
+#include "katemain.h"
+
+#include "../interfaces/plugin.h"
+#include "../interfaces/pluginconfiginterface.h"
+#include "../interfaces/pluginconfiginterfaceextension.h"
+
+#include <kate/document.h>
+#include <ktexteditor/configinterfaceextension.h>
+
+#include <kdialogbase.h>
+
+class QCheckBox;
+class QSpinBox;
+class QButtonGroup;
+
+struct PluginPageListItem
+{
+ Kate::Plugin *plugin;
+ Kate::PluginConfigPage *page;
+};
+
+class KateConfigDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ KateConfigDialog (KateMainWindow *parent, Kate::View *view);
+ ~KateConfigDialog ();
+
+ public:
+ void addPluginPage (Kate::Plugin *plugin);
+ void removePluginPage (Kate::Plugin *plugin);
+
+ protected slots:
+ void slotOk();
+ void slotApply();
+ void slotChanged();
+
+ private:
+ KateMainWindow *mainWindow;
+
+ Kate::View* v;
+ bool dataChanged;
+
+ QCheckBox *cb_fullPath;
+ QCheckBox *cb_syncKonsole;
+ QCheckBox *cb_modNotifications;
+ QCheckBox *cb_saveMetaInfos;
+ QSpinBox *sb_daysMetaInfos;
+ QCheckBox* cb_restoreVC;
+ QButtonGroup *sessions_start;
+ QButtonGroup *sessions_exit;
+ Kate::ConfigPage *fileSelConfigPage;
+ Kate::ConfigPage *filelistConfigPage;
+ Kate::ConfigPage *configExternalToolsPage;
+ QPtrList<PluginPageListItem> pluginPages;
+ QPtrList<KTextEditor::ConfigPage> editorPages;
+};
+
+#endif
diff --git a/kate/app/kateconfigplugindialogpage.cpp b/kate/app/kateconfigplugindialogpage.cpp
new file mode 100644
index 000000000..7269d5f5b
--- /dev/null
+++ b/kate/app/kateconfigplugindialogpage.cpp
@@ -0,0 +1,121 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kateconfigplugindialogpage.h"
+#include "kateconfigplugindialogpage.moc"
+
+#include "katepluginmanager.h"
+#include "kateconfigdialog.h"
+#include <klistbox.h>
+#include "kateapp.h"
+#include <qstringlist.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <klocale.h>
+#include <qpushbutton.h>
+#include <qtooltip.h>
+#include <kiconloader.h>
+#include <qwhatsthis.h>
+
+class KatePluginListItem : public QCheckListItem
+{
+ public:
+ KatePluginListItem(bool checked, KatePluginInfo *info, QListView *parent);
+ KatePluginInfo *info() const { return mInfo; }
+
+ protected:
+ void stateChange(bool);
+
+ private:
+ KatePluginInfo *mInfo;
+ bool silentStateChange;
+};
+
+KatePluginListItem::KatePluginListItem(bool checked, KatePluginInfo *info, QListView *parent)
+ : QCheckListItem(parent, info->service->name(), CheckBox)
+ , mInfo(info)
+ , silentStateChange(false)
+{
+ silentStateChange = true;
+ setOn(checked);
+ silentStateChange = false;
+}
+
+void KatePluginListItem::stateChange(bool b)
+{
+ if(!silentStateChange)
+ static_cast<KatePluginListView *>(listView())->stateChanged(this, b);
+}
+
+KatePluginListView::KatePluginListView(QWidget *parent, const char *name)
+ : KListView(parent, name)
+{
+}
+
+void KatePluginListView::stateChanged(KatePluginListItem *item, bool b)
+{
+ emit stateChange(item, b);
+}
+
+KateConfigPluginPage::KateConfigPluginPage(QWidget *parent, KateConfigDialog *dialog):QVBox(parent)
+{
+ myDialog=dialog;
+
+ KatePluginListView* listView = new KatePluginListView(this);
+ listView->addColumn(i18n("Name"));
+ listView->addColumn(i18n("Comment"));
+ QWhatsThis::add(listView,i18n("Here you can see all available Kate plugins. Those with a check mark are loaded, and will be loaded again the next time Kate is started."));
+
+ connect(listView, SIGNAL(stateChange(KatePluginListItem *, bool)), this, SLOT(stateChange(KatePluginListItem *, bool)));
+
+ KatePluginList &pluginList (KatePluginManager::self()->pluginList());
+ for (unsigned int i=0; i < pluginList.size(); ++i)
+ {
+ KatePluginListItem *item = new KatePluginListItem(pluginList[i].load, &pluginList[i], listView);
+ item->setText(0, pluginList[i].service->name());
+ item->setText(1, pluginList[i].service->comment());
+ }
+}
+
+ void KateConfigPluginPage::stateChange(KatePluginListItem *item, bool b)
+{
+ if(b)
+ loadPlugin(item);
+ else
+ unloadPlugin(item);
+
+ emit changed();
+}
+
+void KateConfigPluginPage::loadPlugin (KatePluginListItem *item)
+{
+ KatePluginManager::self()->loadPlugin (item->info());
+ KatePluginManager::self()->enablePluginGUI (item->info());
+ myDialog->addPluginPage (item->info()->plugin);
+
+ item->setOn(true);
+}
+
+void KateConfigPluginPage::unloadPlugin (KatePluginListItem *item)
+{
+ myDialog->removePluginPage (item->info()->plugin);
+ KatePluginManager::self()->unloadPlugin (item->info());
+
+ item->setOn(false);
+}
diff --git a/kate/app/kateconfigplugindialogpage.h b/kate/app/kateconfigplugindialogpage.h
new file mode 100644
index 000000000..f65da880b
--- /dev/null
+++ b/kate/app/kateconfigplugindialogpage.h
@@ -0,0 +1,69 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KATE_CONFIGPLUGINDIALOGPAGE_H__
+#define __KATE_CONFIGPLUGINDIALOGPAGE_H__
+
+#include "katemain.h"
+#include "katepluginmanager.h"
+
+#include <klistview.h>
+
+#include <qvbox.h>
+
+class KatePluginListItem;
+
+class KatePluginListView : public KListView
+{
+ Q_OBJECT
+
+ friend class KatePluginListItem;
+
+ public:
+ KatePluginListView (QWidget *parent = 0, const char *name = 0);
+
+ signals:
+ void stateChange(KatePluginListItem *, bool);
+
+ private:
+ void stateChanged(KatePluginListItem *, bool);
+};
+
+class KateConfigPluginPage: public QVBox
+{
+ Q_OBJECT
+
+ public:
+ KateConfigPluginPage(QWidget *parent, class KateConfigDialog *dialog);
+ ~KateConfigPluginPage(){;};
+
+ private:
+ class KateConfigDialog *myDialog;
+
+ signals:
+ void changed();
+
+ private slots:
+ void stateChange(KatePluginListItem *, bool);
+
+ void loadPlugin (KatePluginListItem *);
+ void unloadPlugin (KatePluginListItem *);
+};
+
+#endif
diff --git a/kate/app/kateconsole.cpp b/kate/app/kateconsole.cpp
new file mode 100644
index 000000000..5220859b2
--- /dev/null
+++ b/kate/app/kateconsole.cpp
@@ -0,0 +1,143 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2002 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ 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 "kateconsole.h"
+#include "kateconsole.moc"
+
+#include "katemain.h"
+#include "katemdi.h"
+#include "katemainwindow.h"
+#include "kateviewmanager.h"
+
+#include <kate/view.h>
+#include <kate/document.h>
+
+#include <kde_terminal_interface.h>
+
+#include <kparts/part.h>
+
+#include <kurl.h>
+#include <klibloader.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+
+KateConsole::KateConsole (KateMainWindow *mw, KateMDI::ToolView* parent)
+ : QVBox (parent)
+ , m_part (0)
+ , m_mw (mw)
+ , m_toolView (parent)
+{
+}
+
+KateConsole::~KateConsole ()
+{
+ if (m_part)
+ disconnect ( m_part, SIGNAL(destroyed()), this, SLOT(slotDestroyed()) );
+}
+
+void KateConsole::loadConsoleIfNeeded()
+{
+ if (m_part) return;
+
+ if (!topLevelWidget() || !parentWidget()) return;
+ if (!topLevelWidget() || !isVisibleTo(topLevelWidget())) return;
+
+ KLibFactory *factory = KLibLoader::self()->factory("libkonsolepart");
+
+ if (!factory) return;
+
+ m_part = static_cast<KParts::ReadOnlyPart *>(factory->create(this,"libkonsolepart", "KParts::ReadOnlyPart"));
+
+ if (!m_part) return;
+
+ setFocusProxy(m_part->widget());
+
+ KGlobal::locale()->insertCatalogue("konsole");
+
+ m_part->widget()->show();
+
+ connect ( m_part, SIGNAL(destroyed()), this, SLOT(slotDestroyed()) );
+
+ if (m_mw->viewManager()->activeView())
+ if (m_mw->viewManager()->activeView()->getDoc()->url().isValid())
+ cd(KURL( m_mw->viewManager()->activeView()->getDoc()->url().path() ));
+}
+
+void KateConsole::slotDestroyed ()
+{
+ m_part = 0;
+
+ // hide the dockwidget
+ if (parentWidget())
+ {
+ m_mw->hideToolView (m_toolView);
+ m_mw->centralWidget()->setFocus ();
+ }
+}
+
+void KateConsole::showEvent(QShowEvent *)
+{
+ if (m_part) return;
+
+ loadConsoleIfNeeded();
+}
+
+void KateConsole::cd (const KURL &url)
+{
+ loadConsoleIfNeeded();
+
+ if (!m_part) return;
+
+ m_part->openURL (url);
+}
+
+void KateConsole::sendInput( const QString& text )
+{
+ loadConsoleIfNeeded();
+
+ if (!m_part) return;
+
+ TerminalInterface *t = static_cast<TerminalInterface*>( m_part->qt_cast( "TerminalInterface" ) );
+
+ if (!t) return;
+
+ t->sendInput (text);
+}
+
+void KateConsole::slotPipeToConsole ()
+{
+ if (KMessageBox::warningContinueCancel
+ (m_mw
+ , i18n ("Do you really want to pipe the text to the console? This will execute any contained commands with your user rights.")
+ , i18n ("Pipe to Console?")
+ , i18n("Pipe to Console"), "Pipe To Console Warning") != KMessageBox::Continue)
+ return;
+
+ Kate::View *v = m_mw->viewManager()->activeView();
+
+ if (!v)
+ return;
+
+ if (v->getDoc()->hasSelection ())
+ sendInput (v->getDoc()->selection());
+ else
+ sendInput (v->getDoc()->text());
+}
diff --git a/kate/app/kateconsole.h b/kate/app/kateconsole.h
new file mode 100644
index 000000000..1750df11d
--- /dev/null
+++ b/kate/app/kateconsole.h
@@ -0,0 +1,116 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2002 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KATE_CONSOLE_H__
+#define __KATE_CONSOLE_H__
+
+#include "katemain.h"
+
+#include <kurl.h>
+
+#include <qvbox.h>
+
+namespace KParts {
+ class ReadOnlyPart;
+}
+
+namespace KateMDI {
+ class ToolView;
+}
+
+class KateMainWindow;
+
+/**
+ * KateConsole
+ * This class is used for the internal terminal emulator
+ * It uses internally the konsole part, thx to konsole devs :)
+ */
+class KateConsole : public QVBox
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * construct us
+ * @param mw main window
+ * @param parent toolview
+ */
+ KateConsole (KateMainWindow *mw, KateMDI::ToolView* parent);
+
+ /**
+ * destruct us
+ */
+ ~KateConsole ();
+
+ /**
+ * cd to dir
+ * @param url given dir
+ */
+ void cd (const KURL &url);
+
+ /**
+ * send given text to console
+ * @param text commands for console
+ */
+ void sendInput( const QString& text );
+
+ public slots:
+ /**
+ * pipe current document to console
+ */
+ void slotPipeToConsole ();
+
+ private slots:
+ /**
+ * the konsole exited ;)
+ * handle that, hide the dock
+ */
+ void slotDestroyed ();
+
+ /**
+ * construct console if needed
+ */
+ void loadConsoleIfNeeded();
+
+ protected:
+ /**
+ * the konsole get shown
+ * @param ev show event
+ */
+ void showEvent(QShowEvent *ev);
+
+ private:
+ /**
+ * console part
+ */
+ KParts::ReadOnlyPart *m_part;
+
+ /**
+ * main window of this console
+ */
+ KateMainWindow *m_mw;
+
+ /**
+ * toolview for this console
+ */
+ KateMDI::ToolView *m_toolView;
+};
+
+#endif
diff --git a/kate/app/katedocmanager.cpp b/kate/app/katedocmanager.cpp
new file mode 100644
index 000000000..fe6491f78
--- /dev/null
+++ b/kate/app/katedocmanager.cpp
@@ -0,0 +1,611 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "katedocmanager.h"
+#include "katedocmanager.moc"
+#include "kateapp.h"
+#include "katemainwindow.h"
+#include "kateviewmanager.h"
+#include "katedocmanageriface.h"
+#include "kateexternaltools.h"
+#include "kateviewspacecontainer.h"
+
+#include <kate/view.h>
+
+#include <ktexteditor/encodinginterface.h>
+
+#include <kparts/factory.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kconfig.h>
+#include <klibloader.h>
+#include <kmdcodec.h>
+#include <kmessagebox.h>
+#include <kencodingfiledialog.h>
+#include <kio/job.h>
+#include <kwin.h>
+
+#include <qdatetime.h>
+#include <qtextcodec.h>
+#include <qprogressdialog.h>
+
+KateDocManager::KateDocManager (QObject *parent)
+ : QObject (parent)
+ , m_saveMetaInfos(true)
+ , m_daysMetaInfos(0)
+{
+ m_factory = (KParts::Factory *) KLibLoader::self()->factory ("libkatepart");
+
+ m_documentManager = new Kate::DocumentManager (this);
+ m_docList.setAutoDelete(true);
+ m_docDict.setAutoDelete(false);
+ m_docInfos.setAutoDelete(true);
+
+ m_dcop = new KateDocManagerDCOPIface (this);
+
+ m_metaInfos = new KConfig("metainfos", false, false, "appdata");
+
+ createDoc ();
+}
+
+KateDocManager::~KateDocManager ()
+{
+ // save config
+ if (!m_docList.isEmpty())
+ m_docList.at(0)->writeConfig(KateApp::self()->config());
+
+ if (m_saveMetaInfos)
+ {
+ // saving meta-infos when file is saved is not enough, we need to do it once more at the end
+ for (Kate::Document *doc = m_docList.first(); doc; doc = m_docList.next())
+ saveMetaInfos(doc);
+
+ // purge saved filesessions
+ if (m_daysMetaInfos > 0)
+ {
+ QStringList groups = m_metaInfos->groupList();
+ QDateTime *def = new QDateTime(QDate(1970, 1, 1));
+ for (QStringList::Iterator it = groups.begin(); it != groups.end(); ++it)
+ {
+ m_metaInfos->setGroup(*it);
+ QDateTime last = m_metaInfos->readDateTimeEntry("Time", def);
+ if (last.daysTo(QDateTime::currentDateTime()) > m_daysMetaInfos)
+ m_metaInfos->deleteGroup(*it);
+ }
+ delete def;
+ }
+ }
+
+ delete m_dcop;
+ delete m_metaInfos;
+}
+
+KateDocManager *KateDocManager::self ()
+{
+ return KateApp::self()->documentManager ();
+}
+
+Kate::Document *KateDocManager::createDoc ()
+{
+ KTextEditor::Document *doc = (KTextEditor::Document *) m_factory->createPart (0, "", this, "", "KTextEditor::Document");
+
+ m_docList.append((Kate::Document *)doc);
+ m_docDict.insert (doc->documentNumber(), (Kate::Document *)doc);
+ m_docInfos.insert (doc, new KateDocumentInfo ());
+
+ if (m_docList.count() < 2)
+ ((Kate::Document *)doc)->readConfig(KateApp::self()->config());
+
+ emit documentCreated ((Kate::Document *)doc);
+ emit m_documentManager->documentCreated ((Kate::Document *)doc);
+
+ connect(doc,SIGNAL(modifiedOnDisc(Kate::Document *, bool, unsigned char)),this,SLOT(slotModifiedOnDisc(Kate::Document *, bool, unsigned char)));
+ return (Kate::Document *)doc;
+}
+
+void KateDocManager::deleteDoc (Kate::Document *doc)
+{
+ uint id = doc->documentNumber();
+ uint activeId = 0;
+ if (m_currentDoc)
+ activeId = m_currentDoc->documentNumber ();
+
+ if (m_docList.count() < 2)
+ doc->writeConfig(KateApp::self()->config());
+
+ m_docInfos.remove (doc);
+ m_docDict.remove (id);
+ m_docList.remove (doc);
+
+ emit documentDeleted (id);
+ emit m_documentManager->documentDeleted (id);
+
+ // ohh, current doc was deleted
+ if (activeId == id)
+ {
+ // special case of documentChanged, no longer any doc here !
+ m_currentDoc = 0;
+
+ emit documentChanged ();
+ emit m_documentManager->documentChanged ();
+ }
+}
+
+Kate::Document *KateDocManager::document (uint n)
+{
+ return m_docList.at(n);
+}
+
+Kate::Document *KateDocManager::activeDocument ()
+{
+ return m_currentDoc;
+}
+
+void KateDocManager::setActiveDocument (Kate::Document *doc)
+{
+ if (!doc)
+ return;
+
+ if (m_currentDoc && (m_currentDoc->documentNumber() == doc->documentNumber()))
+ return;
+
+ m_currentDoc = doc;
+
+ emit documentChanged ();
+ emit m_documentManager->documentChanged ();
+}
+
+Kate::Document *KateDocManager::firstDocument ()
+{
+ return m_docList.first();
+}
+
+Kate::Document *KateDocManager::nextDocument ()
+{
+ return m_docList.next();
+}
+
+Kate::Document *KateDocManager::documentWithID (uint id)
+{
+ return m_docDict[id];
+}
+
+const KateDocumentInfo *KateDocManager::documentInfo (Kate::Document *doc)
+{
+ return m_docInfos[doc];
+}
+
+int KateDocManager::findDocument (Kate::Document *doc)
+{
+ return m_docList.find (doc);
+}
+
+uint KateDocManager::documents ()
+{
+ return m_docList.count ();
+}
+
+int KateDocManager::findDocument ( KURL url )
+{
+ QPtrListIterator<Kate::Document> it(m_docList);
+
+ for (; it.current(); ++it)
+ {
+ if ( it.current()->url() == url)
+ return it.current()->documentNumber();
+ }
+ return -1;
+}
+
+Kate::Document *KateDocManager::findDocumentByUrl( KURL url )
+{
+ for (QPtrListIterator<Kate::Document> it(m_docList); it.current(); ++it)
+ {
+ if ( it.current()->url() == url)
+ return it.current();
+ }
+
+ return 0L;
+}
+
+bool KateDocManager::isOpen(KURL url)
+{
+ // return just if we found some document with this url
+ return findDocumentByUrl (url) != 0;
+}
+
+Kate::Document *KateDocManager::openURL (const KURL& url,const QString &encoding, uint *id, bool isTempFile)
+{
+ // special handling if still only the first initial doc is there
+ if (!documentList().isEmpty() && (documentList().count() == 1) && (!documentList().at(0)->isModified() && documentList().at(0)->url().isEmpty()))
+ {
+ Kate::Document* doc = documentList().getFirst();
+
+ doc->setEncoding(encoding);
+
+ if (!loadMetaInfos(doc, url))
+ doc->openURL (url);
+
+ if (id)
+ *id=doc->documentNumber();
+
+ if ( isTempFile && !url.isEmpty() && url.isLocalFile() )
+ {
+ QFileInfo fi( url.path() );
+ if ( fi.exists() )
+ {
+ m_tempFiles[ doc->documentNumber() ] = qMakePair(url, fi.lastModified());
+ kdDebug(13001)<<"temporary file will be deleted after use unless modified: "<<url.prettyURL()<<endl;
+ }
+ }
+
+ connect(doc, SIGNAL(modStateChanged(Kate::Document *)), this, SLOT(slotModChanged(Kate::Document *)));
+
+ emit initialDocumentReplaced();
+
+ return doc;
+ }
+
+ Kate::Document *doc = findDocumentByUrl (url);
+ if ( !doc )
+ {
+ doc = (Kate::Document *)createDoc ();
+
+ doc->setEncoding(encoding.isNull() ? Kate::Document::defaultEncoding() : encoding);
+
+ if (!loadMetaInfos(doc, url))
+ doc->openURL (url);
+ }
+
+ if (id)
+ *id=doc->documentNumber();
+
+ if ( isTempFile && !url.isEmpty() && url.isLocalFile() )
+ {
+ QFileInfo fi( url.path() );
+ if ( fi.exists() )
+ {
+ m_tempFiles[ doc->documentNumber() ] = qMakePair(url, fi.lastModified());
+ kdDebug(13001)<<"temporary file will be deleted after use unless modified: "<<url.prettyURL()<<endl;
+ }
+ }
+
+ return doc;
+}
+
+bool KateDocManager::closeDocument(class Kate::Document *doc,bool closeURL)
+{
+ if (!doc) return false;
+
+ saveMetaInfos(doc);
+ if (closeURL)
+ if (!doc->closeURL()) return false;
+
+ QPtrList<Kate::View> closeList;
+ uint documentNumber = doc->documentNumber();
+
+ for (uint i=0; i < KateApp::self()->mainWindows (); i++ )
+ {
+ KateApp::self()->mainWindow(i)->viewManager()->closeViews(documentNumber);
+ }
+
+ if ( closeURL && m_tempFiles.contains( documentNumber ) )
+ {
+ QFileInfo fi( m_tempFiles[ documentNumber ].first.path() );
+ if ( fi.lastModified() <= m_tempFiles[ documentNumber ].second /*||
+ KMessageBox::questionYesNo( KateApp::self()->activeMainWindow(),
+ i18n("The supposedly temporary file %1 has been modified. "
+ "Do you want to delete it anyway?").arg(m_tempFiles[ documentNumber ].first.prettyURL()),
+ i18n("Delete File?") ) == KMessageBox::Yes*/ )
+ {
+ KIO::del( m_tempFiles[ documentNumber ].first, false, false );
+ kdDebug(13001)<<"Deleted temporary file "<<m_tempFiles[ documentNumber ].first<<endl;
+ m_tempFiles.remove( documentNumber );
+ }
+ else
+ kdWarning(13001)<<"The supposedly temporary file "<<m_tempFiles[ documentNumber ].first.prettyURL()<<" have been modified since loaded, and has not been deleted."<<endl;
+ }
+
+ deleteDoc (doc);
+
+ // never ever empty the whole document list
+ if (m_docList.isEmpty())
+ createDoc ();
+
+ return true;
+}
+
+bool KateDocManager::closeDocument(uint n)
+{
+ return closeDocument(document(n));
+}
+
+bool KateDocManager::closeDocumentWithID(uint id)
+{
+ return closeDocument(documentWithID(id));
+}
+
+bool KateDocManager::closeAllDocuments(bool closeURL)
+{
+ bool res = true;
+
+ QPtrList<Kate::Document> docs = m_docList;
+
+ for (uint i=0; i < KateApp::self()->mainWindows (); i++ )
+ {
+ KateApp::self()->mainWindow(i)->viewManager()->setViewActivationBlocked(true);
+ }
+
+ while (!docs.isEmpty() && res)
+ if (! closeDocument(docs.at(0),closeURL) )
+ res = false;
+ else
+ docs.remove ((uint)0);
+
+ for (uint i=0; i < KateApp::self()->mainWindows (); i++ )
+ {
+ KateApp::self()->mainWindow(i)->viewManager()->setViewActivationBlocked(false);
+
+ for (uint s=0; s < KateApp::self()->mainWindow(i)->viewManager()->containers()->count(); s++)
+ KateApp::self()->mainWindow(i)->viewManager()->containers()->at(s)->activateView (m_docList.at(0)->documentNumber());
+ }
+
+ return res;
+}
+
+QPtrList<Kate::Document> KateDocManager::modifiedDocumentList() {
+ QPtrList<Kate::Document> modified;
+ for (QPtrListIterator<Kate::Document> it(m_docList); it.current(); ++it) {
+ Kate::Document *doc = it.current();
+ if (doc->isModified()) {
+ modified.append(doc);
+ }
+ }
+ return modified;
+}
+
+
+bool KateDocManager::queryCloseDocuments(KateMainWindow *w)
+{
+ uint docCount = m_docList.count();
+ for (QPtrListIterator<Kate::Document> it(m_docList); it.current(); ++it)
+ {
+ Kate::Document *doc = it.current();
+
+ if (doc->url().isEmpty() && doc->isModified())
+ {
+ int msgres=KMessageBox::warningYesNoCancel( w,
+ i18n("<p>The document '%1' has been modified, but not saved."
+ "<p>Do you want to save your changes or discard them?").arg( doc->docName() ),
+ i18n("Close Document"), KStdGuiItem::save(), KStdGuiItem::discard() );
+
+ if (msgres==KMessageBox::Cancel)
+ return false;
+
+ if (msgres==KMessageBox::Yes)
+ {
+ KEncodingFileDialog::Result r=KEncodingFileDialog::getSaveURLAndEncoding(
+ KTextEditor::encodingInterface(doc)->encoding(),QString::null,QString::null,w,i18n("Save As"));
+
+ doc->setEncoding( r.encoding );
+
+ if (!r.URLs.isEmpty())
+ {
+ KURL tmp = r.URLs.first();
+
+ if ( !doc->saveAs( tmp ) )
+ return false;
+ }
+ else
+ return false;
+ }
+ }
+ else
+ {
+ if (!doc->queryClose())
+ return false;
+ }
+ }
+
+ // document count changed while queryClose, abort and notify user
+ if (m_docList.count() > docCount)
+ {
+ KMessageBox::information (w,
+ i18n ("New file opened while trying to close Kate, closing aborted."),
+ i18n ("Closing Aborted"));
+ return false;
+ }
+
+ return true;
+}
+
+
+void KateDocManager::saveAll()
+{
+ for (QPtrListIterator<Kate::Document> it(m_docList); it.current(); ++it)
+ if ( it.current()->isModified() && it.current()->views().count() )
+ ((Kate::View*)it.current()->views().first())->save();
+}
+
+void KateDocManager::saveDocumentList (KConfig* config)
+{
+ QString prevGrp=config->group();
+ config->setGroup ("Open Documents");
+ QString grp = config->group();
+
+ config->writeEntry ("Count", m_docList.count());
+
+ int i=0;
+ for ( Kate::Document *doc = m_docList.first(); doc; doc = m_docList.next() )
+ {
+ config->setGroup(QString("Document %1").arg(i));
+ doc->writeSessionConfig(config);
+ config->setGroup(grp);
+
+ i++;
+ }
+
+ config->setGroup(prevGrp);
+}
+
+void KateDocManager::restoreDocumentList (KConfig* config)
+{
+ QString prevGrp=config->group();
+ config->setGroup ("Open Documents");
+ QString grp = config->group();
+
+ unsigned int count = config->readUnsignedNumEntry("Count", 0);
+
+ if (count == 0)
+ {
+ config->setGroup(prevGrp);
+ return;
+ }
+
+ QProgressDialog *pd = new QProgressDialog(
+ i18n("Reopening files from the last session..."),
+ QString::null,
+ count,
+ 0,
+ "openprog");
+
+ KWin::setOnDesktop(pd->winId(), KWin::currentDesktop());
+ pd->setCaption (KateApp::self()->makeStdCaption(i18n("Starting Up")));
+
+ bool first = true;
+ for (unsigned int i=0; i < count; i++)
+ {
+ config->setGroup(QString("Document %1").arg(i));
+ Kate::Document *doc = 0;
+
+ if (first)
+ {
+ first = false;
+ doc = document (0);
+ }
+ else
+ doc = createDoc ();
+
+ doc->readSessionConfig(config);
+ config->setGroup (grp);
+
+ pd->setProgress(pd->progress()+1);
+ KateApp::self()->processEvents();
+ }
+
+ delete pd;
+
+ config->setGroup(prevGrp);
+}
+
+void KateDocManager::slotModifiedOnDisc (Kate::Document *doc, bool b, unsigned char reason)
+{
+ if (m_docInfos[doc])
+ {
+ m_docInfos[doc]->modifiedOnDisc = b;
+ m_docInfos[doc]->modifiedOnDiscReason = reason;
+ }
+}
+
+void KateDocManager::slotModChanged(Kate::Document *doc)
+{
+ saveMetaInfos(doc);
+}
+
+/**
+ * Load file and file' meta-informations iif the MD5 didn't change since last time.
+ */
+bool KateDocManager::loadMetaInfos(Kate::Document *doc, const KURL &url)
+{
+ if (!m_saveMetaInfos)
+ return false;
+
+ if (!m_metaInfos->hasGroup(url.prettyURL()))
+ return false;
+
+ QCString md5;
+ bool ok = true;
+
+ if (computeUrlMD5(url, md5))
+ {
+ m_metaInfos->setGroup(url.prettyURL());
+ QString old_md5 = m_metaInfos->readEntry("MD5");
+
+ if ((const char *)md5 == old_md5)
+ doc->readSessionConfig(m_metaInfos);
+ else
+ {
+ m_metaInfos->deleteGroup(url.prettyURL());
+ ok = false;
+ }
+
+ m_metaInfos->sync();
+ }
+
+ return ok && doc->url() == url;
+}
+
+/**
+ * Save file' meta-informations iif doc is in 'unmodified' state
+ */
+void KateDocManager::saveMetaInfos(Kate::Document *doc)
+{
+ QCString md5;
+
+ if (!m_saveMetaInfos)
+ return;
+
+ if (doc->isModified())
+ {
+// kdDebug (13020) << "DOC MODIFIED: no meta data saved" << endl;
+ return;
+ }
+
+ if (computeUrlMD5(doc->url(), md5))
+ {
+ m_metaInfos->setGroup(doc->url().prettyURL());
+ doc->writeSessionConfig(m_metaInfos);
+ m_metaInfos->writeEntry("MD5", (const char *)md5);
+ m_metaInfos->writeEntry("Time", QDateTime::currentDateTime());
+ m_metaInfos->sync();
+ }
+}
+
+bool KateDocManager::computeUrlMD5(const KURL &url, QCString &result)
+{
+ QFile f(url.path());
+
+ if (f.open(IO_ReadOnly))
+ {
+ KMD5 md5;
+
+ if (!md5.update(f))
+ return false;
+
+ md5.hexDigest(result);
+ f.close();
+ }
+ else
+ return false;
+
+ return true;
+}
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/katedocmanager.h b/kate/app/katedocmanager.h
new file mode 100644
index 000000000..8d302687b
--- /dev/null
+++ b/kate/app/katedocmanager.h
@@ -0,0 +1,156 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KATE_DOCMANAGER_H__
+#define __KATE_DOCMANAGER_H__
+
+#include "katemain.h"
+#include "../interfaces/documentmanager.h"
+
+#include <kate/document.h>
+
+#include <qguardedptr.h>
+#include <qptrlist.h>
+#include <qobject.h>
+#include <qptrdict.h>
+#include <qintdict.h>
+#include <qmap.h>
+#include <qpair.h>
+
+namespace KParts { class Factory; }
+
+class KConfig;
+class DCOPObject;
+
+class KateDocumentInfo
+{
+ public:
+ KateDocumentInfo ()
+ : modifiedOnDisc (false),
+ modifiedOnDiscReason (0)
+ {
+ }
+
+ bool modifiedOnDisc;
+ unsigned char modifiedOnDiscReason;
+};
+
+typedef QPair<KURL,QDateTime> TPair;
+
+class KateDocManager : public QObject
+{
+ Q_OBJECT
+
+ public:
+ KateDocManager (QObject *parent);
+ ~KateDocManager ();
+
+ static KateDocManager *self ();
+
+ Kate::DocumentManager *documentManager () { return m_documentManager; };
+
+ Kate::Document *createDoc ();
+ void deleteDoc (Kate::Document *doc);
+
+ Kate::Document *document (uint n);
+
+ Kate::Document *activeDocument ();
+ void setActiveDocument (Kate::Document *doc);
+
+ Kate::Document *firstDocument ();
+ Kate::Document *nextDocument ();
+
+ // search document with right documentNumber()
+ Kate::Document *documentWithID (uint id);
+
+ const KateDocumentInfo *documentInfo (Kate::Document *doc);
+
+ int findDocument (Kate::Document *doc);
+ /** Returns the documentNumber of the doc with url URL or -1 if no such doc is found */
+ int findDocument (KURL url);
+ // Anders: The above is not currently stable ?
+ Kate::Document *findDocumentByUrl( KURL url );
+
+ bool isOpen(KURL url);
+
+ uint documents ();
+
+ QPtrList<Kate::Document> &documentList () { return m_docList; };
+
+ Kate::Document *openURL(const KURL&,const QString &encoding=QString::null,uint *id =0,bool isTempFile=false);
+
+ bool closeDocument(class Kate::Document *,bool closeURL=true);
+ bool closeDocument(uint);
+ bool closeDocumentWithID(uint);
+ bool closeAllDocuments(bool closeURL=true);
+
+ QPtrList<Kate::Document> modifiedDocumentList();
+ bool queryCloseDocuments(KateMainWindow *w);
+
+ void saveDocumentList (class KConfig *config);
+ void restoreDocumentList (class KConfig *config);
+
+ DCOPObject *dcopObject () { return m_dcop; };
+
+ inline bool getSaveMetaInfos() { return m_saveMetaInfos; };
+ inline void setSaveMetaInfos(bool b) { m_saveMetaInfos = b; };
+
+ inline int getDaysMetaInfos() { return m_daysMetaInfos; };
+ inline void setDaysMetaInfos(int i) { m_daysMetaInfos = i; };
+
+ public slots:
+ /**
+ * saves all documents that has at least one view.
+ * documents with no views are ignored :P
+ */
+ void saveAll();
+
+ signals:
+ void documentCreated (Kate::Document *doc);
+ void documentDeleted (uint documentNumber);
+ void documentChanged ();
+ void initialDocumentReplaced ();
+
+ private slots:
+ void slotModifiedOnDisc (Kate::Document *doc, bool b, unsigned char reason);
+ void slotModChanged(Kate::Document *doc);
+
+ private:
+ bool loadMetaInfos(Kate::Document *doc, const KURL &url);
+ void saveMetaInfos(Kate::Document *doc);
+ bool computeUrlMD5(const KURL &url, QCString &result);
+
+ Kate::DocumentManager *m_documentManager;
+ QPtrList<Kate::Document> m_docList;
+ QIntDict<Kate::Document> m_docDict;
+ QPtrDict<KateDocumentInfo> m_docInfos;
+ QMap<uint,TPair> m_tempFiles;
+ QGuardedPtr<Kate::Document> m_currentDoc;
+ KConfig *m_metaInfos;
+ bool m_saveMetaInfos;
+ int m_daysMetaInfos;
+
+ DCOPObject *m_dcop;
+
+ KParts::Factory *m_factory;
+
+};
+
+#endif
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/katedocmanageriface.cpp b/kate/app/katedocmanageriface.cpp
new file mode 100644
index 000000000..9c2eabc03
--- /dev/null
+++ b/kate/app/katedocmanageriface.cpp
@@ -0,0 +1,131 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Ian Reinhart Geiser <geiseri@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "katedocmanageriface.h"
+
+#include "katedocmanager.h"
+
+#include <kdebug.h>
+
+KateDocManagerDCOPIface::KateDocManagerDCOPIface (KateDocManager *dm) : DCOPObject ("KateDocumentManager"), m_dm (dm)
+{
+
+}
+
+// bit more error save than the forcing c cast ;()
+DCOPRef KateDocManagerDCOPIface::document (uint n)
+{
+ Kate::Document *doc = m_dm->document(n);
+
+ if (!doc)
+ return DCOPRef ();
+
+ DCOPObject *obj = static_cast<DCOPObject*>(doc->qt_cast("DCOPObject"));
+
+ if (!obj)
+ return DCOPRef ();
+
+ return DCOPRef (obj);
+}
+
+DCOPRef KateDocManagerDCOPIface::activeDocument ()
+{
+ Kate::Document *doc = m_dm->activeDocument();
+
+ if (!doc)
+ return DCOPRef ();
+
+ DCOPObject *obj = static_cast<DCOPObject*>(doc->qt_cast("DCOPObject"));
+
+ if (!obj)
+ return DCOPRef ();
+
+ return DCOPRef (obj);
+}
+
+uint KateDocManagerDCOPIface::activeDocumentNumber ()
+{
+ Kate::Document *doc = m_dm->activeDocument();
+
+ if (doc)
+ return doc->documentNumber ();
+
+ return 0;
+}
+
+DCOPRef KateDocManagerDCOPIface::documentWithID (uint id)
+{
+ Kate::Document *doc = m_dm->documentWithID (id);
+
+ if (!doc)
+ return DCOPRef ();
+
+ DCOPObject *obj = static_cast<DCOPObject*>(doc->qt_cast("DCOPObject"));
+
+ if (!obj)
+ return DCOPRef ();
+
+ return DCOPRef (obj);
+}
+
+DCOPRef KateDocManagerDCOPIface::openURL (KURL url, QString encoding)
+{
+ Kate::Document *doc = m_dm->openURL (url, encoding);
+
+ if (!doc)
+ return DCOPRef ();
+
+ DCOPObject *obj = static_cast<DCOPObject*>(doc->qt_cast("DCOPObject"));
+
+ if (!obj)
+ return DCOPRef ();
+
+ return DCOPRef (obj);
+}
+
+bool KateDocManagerDCOPIface::closeDocument(uint n)
+{
+ return m_dm->closeDocument(n);
+}
+
+bool KateDocManagerDCOPIface::closeDocumentWithID(uint id)
+{
+ return m_dm->closeDocumentWithID (id);
+}
+
+bool KateDocManagerDCOPIface::closeAllDocuments()
+{
+ return m_dm->closeAllDocuments();
+}
+
+bool KateDocManagerDCOPIface::isOpen(KURL url)
+{
+ return m_dm->isOpen (url);
+}
+
+uint KateDocManagerDCOPIface::documents ()
+{
+ return m_dm->documents();
+}
+
+int KateDocManagerDCOPIface::findDocument (KURL url)
+{
+ return m_dm->findDocument (url);
+}
+
+
diff --git a/kate/app/katedocmanageriface.h b/kate/app/katedocmanageriface.h
new file mode 100644
index 000000000..7a2cb5506
--- /dev/null
+++ b/kate/app/katedocmanageriface.h
@@ -0,0 +1,62 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Ian Reinhart Geiser <geiseri@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _katedocmanager_Iface_h_
+#define _katedocmanager_Iface_h_
+
+#include <dcopobject.h>
+#include <dcopref.h>
+
+#include <kurl.h>
+
+class KateDocManager;
+
+class KateDocManagerDCOPIface : public DCOPObject
+{
+ K_DCOP
+
+ public:
+ KateDocManagerDCOPIface (KateDocManager *dm);
+
+ k_dcop:
+ DCOPRef document (uint n);
+
+ DCOPRef activeDocument ();
+
+ uint activeDocumentNumber ();
+
+ DCOPRef documentWithID (uint id);
+
+ int findDocument (KURL url);
+
+ bool isOpen (KURL url);
+
+ uint documents ();
+
+ DCOPRef openURL (KURL url, QString encoding);
+
+ bool closeDocument (uint n);
+
+ bool closeDocumentWithID (uint id);
+
+ bool closeAllDocuments ();
+
+ private:
+ KateDocManager *m_dm;
+};
+#endif
diff --git a/kate/app/kateexternaltools.cpp b/kate/app/kateexternaltools.cpp
new file mode 100644
index 000000000..50c07709b
--- /dev/null
+++ b/kate/app/kateexternaltools.cpp
@@ -0,0 +1,873 @@
+/*
+ This file is part of the Kate text editor of the KDE project.
+
+ 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.
+
+ ---
+ Copyright (C) 2004, Anders Lund <anders@alweb.dk>
+*/
+// TODO
+// Icons
+// Direct shortcut setting
+//BEGIN Includes
+#include "kateexternaltools.h"
+#include "kateexternaltools.moc"
+#include "katedocmanager.h"
+#include "kateviewmanager.h"
+#include "kateapp.h"
+
+#include "katemainwindow.h"
+
+#include <kate/view.h>
+#include <kate/document.h>
+
+#include <klistbox.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kmimetypechooser.h>
+#include <kconfig.h>
+#include <krun.h>
+#include <kicondialog.h>
+#include <kpopupmenu.h>
+#include <kdebug.h>
+
+#include <qbitmap.h>
+#include <qcombobox.h>
+#include <qfile.h>
+#include <qpushbutton.h>
+#include <qlineedit.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qlistbox.h>
+#include <qmap.h>
+#include <qregexp.h>
+#include <qtextedit.h>
+#include <qtoolbutton.h>
+#include <qwhatsthis.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+//END Includes
+
+KateExternalToolsCommand *KateExternalToolsCommand::s_self=0;
+
+//BEGIN KateExternalTool
+KateExternalTool::KateExternalTool( const QString &name,
+ const QString &command,
+ const QString &icon,
+ const QString &tryexec,
+ const QStringList &mimetypes,
+ const QString &acname,
+ const QString &cmdname,
+ int save )
+ : name ( name ),
+ command ( command ),
+ icon ( icon ),
+ tryexec ( tryexec ),
+ mimetypes ( mimetypes ),
+ acname ( acname ),
+ cmdname ( cmdname ),
+ save ( save )
+{
+ //if ( ! tryexec.isEmpty() )
+ hasexec = checkExec();
+}
+
+bool KateExternalTool::checkExec()
+{
+ // if tryexec is empty, it is the first word of command
+ if ( tryexec.isEmpty() )
+ tryexec = command.section( " ", 0, 0, QString::SectionSkipEmpty );
+
+ // NOTE this code is modified taken from kdesktopfile.cpp, from KDesktopFile::tryExec()
+ if (!tryexec.isEmpty()) {
+ if (tryexec[0] == '/') {
+ if (::access(QFile::encodeName(tryexec), R_OK | X_OK))
+ return false;
+
+ m_exec = tryexec;
+ } else {
+ // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!!
+ // Environment PATH may contain filenames in 8bit locale cpecified
+ // encoding (Like a filenames).
+ QStringList dirs = QStringList::split(':', QFile::decodeName(::getenv("PATH")));
+ QStringList::Iterator it(dirs.begin());
+ bool match = false;
+ for (; it != dirs.end(); ++it)
+ {
+ QString fName = *it + "/" + tryexec;
+ if (::access(QFile::encodeName(fName), R_OK | X_OK) == 0)
+ {
+ match = true;
+ m_exec = fName;
+ break;
+ }
+ }
+ // didn't match at all
+ if (!match)
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+bool KateExternalTool::valid( const QString &mt ) const
+{
+ return mimetypes.isEmpty() || mimetypes.contains( mt );
+}
+//END KateExternalTool
+
+//BEGIN KateExternalToolsCommand
+KateExternalToolsCommand::KateExternalToolsCommand() : Kate::Command() {
+ m_inited=false;
+ reload();
+}
+
+QStringList KateExternalToolsCommand::cmds () {
+ return m_list;
+}
+
+KateExternalToolsCommand *KateExternalToolsCommand::self () {
+ if (s_self) return s_self;
+ s_self=new KateExternalToolsCommand;
+ return s_self;
+}
+
+void KateExternalToolsCommand::reload () {
+ m_list.clear();
+ m_map.clear();
+
+ KConfig config("externaltools", false, false, "appdata");
+ config.setGroup("Global");
+ QStringList tools = config.readListEntry("tools");
+
+
+ for( QStringList::Iterator it = tools.begin(); it != tools.end(); ++it )
+ {
+ if ( *it == "---" )
+ continue;
+
+
+ config.setGroup( *it );
+
+ KateExternalTool t = KateExternalTool(
+ config.readEntry( "name", "" ),
+ config.readEntry( "command", ""),
+ config.readEntry( "icon", ""),
+ config.readEntry( "executable", ""),
+ config.readListEntry( "mimetypes" ),
+ config.readEntry( "acname", "" ),
+ config.readEntry( "cmdname", "" ) );
+ // FIXME test for a command name first!
+ if ( t.hasexec && (!t.cmdname.isEmpty())) {
+ m_list.append("exttool-"+t.cmdname);
+ m_map.insert("exttool-"+t.cmdname,t.acname);
+ }
+ }
+ if (m_inited) {
+ Kate::Document::unregisterCommand(this);
+ Kate::Document::registerCommand(this);
+ }
+ else m_inited=true;
+}
+
+bool KateExternalToolsCommand::exec (Kate::View *view, const QString &cmd, QString &) {
+ QWidget *wv=dynamic_cast<QWidget*>(view);
+ if (!wv) {
+// kdDebug(13001)<<"KateExternalToolsCommand::exec: Could not get view widget"<<endl;
+ return false;
+ }
+ KateMDI::MainWindow *dmw=dynamic_cast<KateMDI::MainWindow*>(wv->topLevelWidget());
+ if (!dmw) {
+// kdDebug(13001)<<"KateExternalToolsCommand::exec: Could not get main window"<<endl;
+ return false;
+ }
+// kdDebug(13001)<<"cmd="<<cmd.stripWhiteSpace()<<endl;
+ QString actionName=m_map[cmd.stripWhiteSpace()];
+ if (actionName.isEmpty()) return false;
+// kdDebug(13001)<<"actionName is not empty:"<<actionName<<endl;
+ KateExternalToolsMenuAction *a=
+ dynamic_cast<KateExternalToolsMenuAction*>(dmw->action("tools_external"));
+ if (!a) return false;
+// kdDebug(13001)<<"trying to find action"<<endl;
+ KAction *a1=a->actionCollection()->action(actionName.utf8());
+ if (!a1) return false;
+// kdDebug(13001)<<"activating action"<<endl;
+ a1->activate();
+ return true;
+}
+
+bool KateExternalToolsCommand::help (Kate::View *, const QString &, QString &) {
+ return false;
+}
+//END KateExternalToolsCommand
+
+//BEGIN KateExternalToolAction
+KateExternalToolAction::KateExternalToolAction( QObject *parent,
+ const char *name, KateExternalTool *t)
+ : KAction( parent, name ),
+ tool ( t )
+{
+ setText( t->name );
+ if ( ! t->icon.isEmpty() )
+ setIconSet( SmallIconSet( t->icon ) );
+
+ connect( this ,SIGNAL(activated()), this, SLOT(slotRun()) );
+}
+
+bool KateExternalToolAction::expandMacro( const QString &str, QStringList &ret )
+{
+ KateMainWindow *mw = (KateMainWindow*)parent()->parent();
+
+ Kate::View *view = mw->viewManager()->activeView();
+ if ( ! view ) return false;
+
+
+ if ( str == "URL" )
+ ret += mw->activeDocumentUrl().url();
+ else if ( str == "directory" ) // directory of current doc
+ ret += mw->activeDocumentUrl().directory();
+ else if ( str == "filename" )
+ ret += mw->activeDocumentUrl().fileName();
+ else if ( str == "line" ) // cursor line of current doc
+ ret += QString::number( view->cursorLine() );
+ else if ( str == "col" ) // cursor col of current doc
+ ret += QString::number( view->cursorColumn() );
+ else if ( str == "selection" ) // selection of current doc if any
+ ret += view->getDoc()->selection();
+ else if ( str == "text" ) // text of current doc
+ ret += view->getDoc()->text();
+ else if ( str == "URLs" ) {
+ for( Kate::Document *doc = KateDocManager::self()->firstDocument(); doc; doc = KateDocManager::self()->nextDocument() )
+ if ( ! doc->url().isEmpty() )
+ ret += doc->url().url();
+ } else
+ return false;
+ return true;
+}
+
+KateExternalToolAction::~KateExternalToolAction() {
+ delete(tool);
+}
+
+void KateExternalToolAction::slotRun()
+{
+ // expand the macros in command if any,
+ // and construct a command with an absolute path
+ QString cmd = tool->command;
+
+ if ( ! expandMacrosShellQuote( cmd ) )
+ {
+ KMessageBox::sorry( (KateMainWindow*)parent()->parent(),
+ i18n("Failed to expand the command '%1'.").arg( cmd ),
+ i18n( "Kate External Tools") );
+ return;
+ }
+ kdDebug(13001)<<"externaltools: Running command: "<<cmd<<endl;
+
+ // save documents if requested
+ KateMainWindow *mw = (KateMainWindow*)parent()->parent();
+ if ( tool->save == 1 )
+ mw->viewManager()->activeView()->document()->save();
+ else if ( tool->save == 2 )
+ mw->actionCollection()->action("file_save_all")->activate();
+
+ KRun::runCommand( cmd, tool->tryexec, tool->icon );
+}
+//END KateExternalToolAction
+
+//BEGIN KateExternalToolsMenuAction
+KateExternalToolsMenuAction::KateExternalToolsMenuAction( const QString &text,
+ QObject *parent,
+ const char* name,
+ KateMainWindow *mw )
+ : KActionMenu( text, parent, name ),
+ mainwindow( mw )
+{
+
+ m_actionCollection = new KActionCollection( mainwindow );
+
+ connect(KateDocManager::self(),SIGNAL(documentChanged()),this,SLOT(slotDocumentChanged()));
+
+ reload();
+}
+
+void KateExternalToolsMenuAction::reload()
+{
+ m_actionCollection->clear ();
+ popupMenu()->clear();
+
+ // load all the tools, and create a action for each of them
+ KConfig *config = new KConfig( "externaltools", false, false, "appdata" );
+ config->setGroup( "Global" );
+ QStringList tools = config->readListEntry( "tools" );
+
+ // if there are tools that are present but not explicitly removed,
+ // add them to the end of the list
+ config->setReadDefaults( true );
+ QStringList dtools = config->readListEntry( "tools" );
+ int gver = config->readNumEntry( "version", 1 );
+ config->setReadDefaults( false );
+
+ int ver = config->readNumEntry( "version" );
+ if ( ver <= gver )
+ {
+ QStringList removed = config->readListEntry( "removed" );
+ bool sepadded = false;
+ for (QStringList::iterator itg = dtools.begin(); itg != dtools.end(); ++itg )
+ {
+ if ( ! tools.contains( *itg ) &&
+ ! removed.contains( *itg ) )
+ {
+ if ( ! sepadded )
+ {
+ tools << "---";
+ sepadded = true;
+ }
+ tools << *itg;
+ }
+ }
+
+ config->writeEntry( "tools", tools );
+ config->sync();
+ config->writeEntry( "version", gver );
+ }
+
+ for( QStringList::Iterator it = tools.begin(); it != tools.end(); ++it )
+ {
+ if ( *it == "---" )
+ {
+ popupMenu()->insertSeparator();
+ // a separator
+ continue;
+ }
+
+ config->setGroup( *it );
+
+ KateExternalTool *t = new KateExternalTool(
+ config->readEntry( "name", "" ),
+ config->readEntry( "command", ""),
+ config->readEntry( "icon", ""),
+ config->readEntry( "executable", ""),
+ config->readListEntry( "mimetypes" ),
+ config->readEntry( "acname", "" ),
+ config->readEntry( "cmdname", "" ),
+ config->readNumEntry( "save", 0 ) );
+
+ if ( t->hasexec )
+ insert( new KateExternalToolAction( m_actionCollection, t->acname.ascii(), t ) );
+ }
+
+ m_actionCollection->readShortcutSettings( "Shortcuts", config );
+ slotDocumentChanged();
+ delete config;
+}
+
+void KateExternalToolsMenuAction::slotDocumentChanged()
+{
+ // try to enable/disable to match current mime type
+ Kate::DocumentExt *de = documentExt( KateDocManager::self()->activeDocument() );
+ if ( de )
+ {
+ QString mt = de->mimeType();
+ QStringList l;
+ bool b;
+
+ KActionPtrList actions = m_actionCollection->actions();
+ for (KActionPtrList::iterator it = actions.begin(); it != actions.end(); ++it )
+ {
+ KateExternalToolAction *action = dynamic_cast<KateExternalToolAction*>(*it);
+ if ( action )
+ {
+ l = action->tool->mimetypes;
+ b = ( ! l.count() || l.contains( mt ) );
+ action->setEnabled( b );
+ }
+ }
+ }
+}
+//END KateExternalToolsMenuAction
+
+//BEGIN ToolItem
+/**
+ * This is a QListBoxItem, that has a KateExternalTool. The text is the Name
+ * of the tool.
+ */
+class ToolItem : public QListBoxPixmap
+{
+ public:
+ ToolItem( QListBox *lb, const QPixmap &icon, KateExternalTool *tool )
+ : QListBoxPixmap( lb, icon, tool->name ),
+ tool ( tool )
+ {;}
+
+ ~ToolItem() {};
+
+ KateExternalTool *tool;
+};
+//END ToolItem
+
+//BEGIN KateExternalToolServiceEditor
+KateExternalToolServiceEditor::KateExternalToolServiceEditor( KateExternalTool *tool,
+ QWidget *parent, const char *name )
+ : KDialogBase( parent, name, true, i18n("Edit External Tool"), KDialogBase::Ok|KDialogBase::Cancel ),
+ tool( tool )
+{
+ // create a entry for each property
+ // fill in the values from the service if available
+ QWidget *w = new QWidget( this );
+ setMainWidget( w );
+ QGridLayout *lo = new QGridLayout( w );
+ lo->setSpacing( KDialogBase::spacingHint() );
+
+ QLabel *l;
+
+ leName = new QLineEdit( w );
+ lo->addWidget( leName, 1, 2 );
+ l = new QLabel( leName, i18n("&Label:"), w );
+ l->setAlignment( l->alignment()|Qt::AlignRight );
+ lo->addWidget( l, 1, 1 );
+ if ( tool ) leName->setText( tool->name );
+ QWhatsThis::add( leName, i18n(
+ "The name will be displayed in the 'Tools->External' menu") );
+
+ btnIcon = new KIconButton( w );
+ btnIcon->setIconSize( KIcon::SizeSmall );
+ lo->addWidget( btnIcon, 1, 3 );
+ if ( tool && !tool->icon.isEmpty() )
+ btnIcon->setIcon( tool->icon );
+
+ teCommand = new QTextEdit( w );
+ lo->addMultiCellWidget( teCommand, 2, 2, 2, 3 );
+ l = new QLabel( teCommand, i18n("S&cript:"), w );
+ l->setAlignment( Qt::AlignTop|Qt::AlignRight );
+ lo->addWidget( l, 2, 1 );
+ if ( tool ) teCommand->setText( tool->command );
+ QWhatsThis::add( teCommand, i18n(
+ "<p>The script to execute to invoke the tool. The script is passed "
+ "to /bin/sh for execution. The following macros "
+ "will be expanded:</p>"
+ "<ul><li><code>%URL</code> - the URL of the current document."
+ "<li><code>%URLs</code> - a list of the URLs of all open documents."
+ "<li><code>%directory</code> - the URL of the directory containing "
+ "the current document."
+ "<li><code>%filename</code> - the filename of the current document."
+ "<li><code>%line</code> - the current line of the text cursor in the "
+ "current view."
+ "<li><code>%column</code> - the column of the text cursor in the "
+ "current view."
+ "<li><code>%selection</code> - the selected text in the current view."
+ "<li><code>%text</code> - the text of the current document.</ul>" ) );
+
+
+ leExecutable = new QLineEdit( w );
+ lo->addMultiCellWidget( leExecutable, 3, 3, 2, 3 );
+ l = new QLabel( leExecutable, i18n("&Executable:"), w );
+ l->setAlignment( l->alignment()|Qt::AlignRight );
+ lo->addWidget( l, 3, 1 );
+ if ( tool ) leExecutable->setText( tool->tryexec );
+ QWhatsThis::add( leExecutable, i18n(
+ "The executable used by the command. This is used to check if a tool "
+ "should be displayed; if not set, the first word of <em>command</em> "
+ "will be used.") );
+
+ leMimetypes = new QLineEdit( w );
+ lo->addWidget( leMimetypes, 4, 2 );
+ l = new QLabel( leMimetypes, i18n("&Mime types:"), w );
+ l->setAlignment( l->alignment()|Qt::AlignRight );
+ lo->addWidget( l, 4, 1 );
+ if ( tool ) leMimetypes->setText( tool->mimetypes.join("; ") );
+ QWhatsThis::add( leMimetypes, i18n(
+ "A semicolon-separated list of mime types for which this tool should "
+ "be available; if this is left empty, the tool is always available. "
+ "To choose from known mimetypes, press the button on the right.") );
+
+ QToolButton *btnMTW = new QToolButton(w);
+ lo->addWidget( btnMTW, 4, 3 );
+ btnMTW->setIconSet(QIconSet(SmallIcon("wizard")));
+ connect(btnMTW, SIGNAL(clicked()), this, SLOT(showMTDlg()));
+ QWhatsThis::add( btnMTW, i18n(
+ "Click for a dialog that can help you creating a list of mimetypes.") );
+
+ cmbSave = new QComboBox(w);
+ lo->addMultiCellWidget( cmbSave, 5, 5, 2, 3 );
+ l = new QLabel( cmbSave, i18n("&Save:"), w );
+ l->setAlignment( l->alignment()|Qt::AlignRight );
+ lo->addWidget( l, 5, 1 );
+ QStringList sl;
+ sl << i18n("None") << i18n("Current Document") << i18n("All Documents");
+ cmbSave->insertStringList( sl );
+ if ( tool ) cmbSave->setCurrentItem( tool->save );
+ QWhatsThis::add( cmbSave, i18n(
+ "You can elect to save the current or all [modified] documents prior to "
+ "running the command. This is helpful if you want to pass URLs to "
+ "an application like, for example, an FTP client.") );
+
+
+ leCmdLine = new QLineEdit( w );
+ lo->addMultiCellWidget( leCmdLine, 6, 6, 2, 3 );
+ l = new QLabel( leCmdLine, i18n("&Command line name:"), w );
+ l->setAlignment( l->alignment()|Qt::AlignRight );
+ lo->addWidget( l, 6, 1 );
+ if ( tool ) leCmdLine->setText( tool->cmdname );
+ QWhatsThis::add( leCmdLine, i18n(
+ "If you specify a name here, you can invoke the command from the view "
+ "command lines with exttool-the_name_you_specified_here. "
+ "Please do not use spaces or tabs in the name."));
+
+}
+
+void KateExternalToolServiceEditor::slotOk()
+{
+ if ( leName->text().isEmpty() ||
+ teCommand->text().isEmpty() )
+ {
+ KMessageBox::information( this, i18n("You must specify at least a name and a command") );
+ return;
+ }
+
+ KDialogBase::slotOk();
+}
+
+void KateExternalToolServiceEditor::showMTDlg()
+{
+ QString text = i18n("Select the MimeTypes for which to enable this tool.");
+ QStringList list = QStringList::split( QRegExp("\\s*;\\s*"), leMimetypes->text() );
+ KMimeTypeChooserDialog d( i18n("Select Mime Types"), text, list, "text", this );
+ if ( d.exec() == KDialogBase::Accepted ) {
+ leMimetypes->setText( d.chooser()->mimeTypes().join(";") );
+ }
+}
+//END KateExternalToolServiceEditor
+
+//BEGIN KateExternalToolsConfigWidget
+KateExternalToolsConfigWidget::KateExternalToolsConfigWidget( QWidget *parent, const char* name )
+ : Kate::ConfigPage( parent, name ),
+ m_changed( false )
+{
+ QGridLayout *lo = new QGridLayout( this, 5, 5, 0, KDialog::spacingHint() );
+
+ lbTools = new KListBox( this );
+ lo->addMultiCellWidget( lbTools, 1, 4, 0, 3 );
+ connect( lbTools, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()) );
+
+ btnNew = new QPushButton( i18n("&New..."), this );
+ lo->addWidget( btnNew, 5, 0 );
+ connect( btnNew, SIGNAL(clicked()), this, SLOT(slotNew()) );
+
+ btnRemove = new QPushButton( i18n("&Remove"), this );
+ lo->addWidget( btnRemove, 5, 2 );
+ connect( btnRemove, SIGNAL(clicked()), this, SLOT(slotRemove()) );
+
+ btnEdit = new QPushButton( i18n("&Edit..."), this );
+ lo->addWidget( btnEdit, 5, 1 );
+ connect( btnEdit, SIGNAL(clicked()), this, SLOT(slotEdit()) );
+
+ QPushButton *b = new QPushButton( i18n("Insert &Separator"), this );
+ lo->addWidget( b, 5, 3 );
+ connect( b, SIGNAL(clicked()), this, SLOT(slotInsertSeparator()) );
+
+ btnMoveUp = new QPushButton( SmallIconSet("up"), "", this );
+ lo->addWidget( btnMoveUp, 2, 4 );
+ connect( btnMoveUp, SIGNAL(clicked()), this, SLOT(slotMoveUp()) );
+
+ btnMoveDwn = new QPushButton( SmallIconSet("down"), "", this );
+ lo->addWidget( btnMoveDwn, 3, 4 );
+ connect( btnMoveDwn, SIGNAL(clicked()), this, SLOT(slotMoveDown()) );
+
+ connect( lbTools, SIGNAL( doubleClicked ( QListBoxItem * ) ), this, SLOT( slotEdit() ) );
+
+ lo->setRowStretch( 1, 1 );
+ lo->setRowStretch( 4, 1 );
+ lo->setColStretch( 0, 1 );
+ lo->setColStretch( 1, 1 );
+ lo->setColStretch( 2, 1 );
+
+
+ QWhatsThis::add( lbTools, i18n(
+ "This list shows all the configured tools, represented by their menu text.") );
+
+ config = new KConfig("externaltools", false, false, "appdata");
+ reload();
+ slotSelectionChanged();
+}
+
+KateExternalToolsConfigWidget::~KateExternalToolsConfigWidget()
+{
+ delete config;
+}
+
+void KateExternalToolsConfigWidget::reload()
+{
+ //m_tools.clear();
+ lbTools->clear();
+
+ // load the files from a KConfig
+ config->setGroup( "Global" );
+ QStringList tools = config->readListEntry("tools");
+
+ for( QStringList::Iterator it = tools.begin(); it != tools.end(); ++it )
+ {
+ if ( *it == "---" )
+ {
+ new QListBoxText( lbTools, "---" );
+ }
+ else
+ {
+ config->setGroup( *it );
+
+ KateExternalTool *t = new KateExternalTool(
+ config->readEntry( "name", "" ),
+ config->readEntry( "command", ""),
+ config->readEntry( "icon", ""),
+ config->readEntry( "executable", ""),
+ config->readListEntry( "mimetypes" ),
+ config->readEntry( "acname" ),
+ config->readEntry( "cmdname"),
+ config->readNumEntry( "save", 0 ) );
+
+ if ( t->hasexec ) // we only show tools that are also in the menu.
+ new ToolItem( lbTools, t->icon.isEmpty() ? blankIcon() : SmallIcon( t->icon ), t );
+ }
+ }
+ m_changed = false;
+}
+
+QPixmap KateExternalToolsConfigWidget::blankIcon()
+{
+ QPixmap pm( KIcon::SizeSmall, KIcon::SizeSmall );
+ pm.fill();
+ pm.setMask( pm.createHeuristicMask() );
+ return pm;
+}
+
+void KateExternalToolsConfigWidget::apply()
+{
+ if ( ! m_changed )
+ return;
+ m_changed = false;
+
+ // save a new list
+ // save each item
+ QStringList tools;
+ for ( uint i = 0; i < lbTools->count(); i++ )
+ {
+ if ( lbTools->text( i ) == "---" )
+ {
+ tools << "---";
+ continue;
+ }
+ KateExternalTool *t = ((ToolItem*)lbTools->item( i ))->tool;
+// kdDebug(13001)<<"adding tool: "<<t->name<<endl;
+ tools << t->acname;
+
+ config->setGroup( t->acname );
+ config->writeEntry( "name", t->name );
+ config->writeEntry( "command", t->command );
+ config->writeEntry( "icon", t->icon );
+ config->writeEntry( "executable", t->tryexec );
+ config->writeEntry( "mimetypes", t->mimetypes );
+ config->writeEntry( "acname", t->acname );
+ config->writeEntry( "cmdname", t->cmdname );
+ config->writeEntry( "save", t->save );
+ }
+
+ config->setGroup("Global");
+ config->writeEntry( "tools", tools );
+
+ // if any tools was removed, try to delete their groups, and
+ // add the group names to the list of removed items.
+ if ( m_removed.count() )
+ {
+ for ( QStringList::iterator it = m_removed.begin(); it != m_removed.end(); ++it )
+ {
+ if ( config->hasGroup( *it ) )
+ config->deleteGroup( *it );
+ }
+ QStringList removed = config->readListEntry( "removed" );
+ removed += m_removed;
+
+ // clean up the list of removed items, so that it does not contain
+ // non-existing groups (we can't remove groups from a non-owned global file).
+ config->sync();
+ QStringList::iterator it1 = removed.begin();
+ while( it1 != removed.end() )
+ {
+ if ( ! config->hasGroup( *it1 ) )
+ it1 = removed.remove( it1 );
+ else
+ ++it1;
+ }
+ config->writeEntry( "removed", removed );
+ }
+
+ config->sync();
+}
+
+void KateExternalToolsConfigWidget::slotSelectionChanged()
+{
+ // update button state
+ bool hs = lbTools->selectedItem() != 0;
+ btnEdit->setEnabled( hs && dynamic_cast<ToolItem*>(lbTools->selectedItem()) );
+ btnRemove->setEnabled( hs );
+ btnMoveUp->setEnabled( ( lbTools->currentItem() > 0 ) && hs );
+ btnMoveDwn->setEnabled( ( lbTools->currentItem() < (int)lbTools->count()-1 )&&hs );
+}
+
+void KateExternalToolsConfigWidget::slotNew()
+{
+ // display a editor, and if it is OK'd, create a new tool and
+ // create a listbox item for it
+ KateExternalToolServiceEditor editor( 0, this );
+
+ if ( editor.exec() )
+ {
+ KateExternalTool *t = new KateExternalTool(
+ editor.leName->text(),
+ editor.teCommand->text(),
+ editor.btnIcon->icon(),
+ editor.leExecutable->text(),
+ QStringList::split( QRegExp("\\s*;\\s*"), editor.leMimetypes->text() ) );
+
+ // This is sticky, it does not change again, so that shortcuts sticks
+ // TODO check for dups
+ t->acname = "externaltool_" + QString(t->name).replace( QRegExp("\\W+"), "" );
+
+ new ToolItem ( lbTools, t->icon.isEmpty() ? blankIcon() : SmallIcon( t->icon ), t );
+
+ slotChanged();
+ m_changed = true;
+ }
+}
+
+void KateExternalToolsConfigWidget::slotRemove()
+{
+ // add the tool action name to a list of removed items,
+ // remove the current listbox item
+ if ( lbTools->currentItem() > -1 ) {
+ ToolItem *i = dynamic_cast<ToolItem*>(lbTools->selectedItem());
+ if ( i )
+ m_removed << i->tool->acname;
+
+ lbTools->removeItem( lbTools->currentItem() );
+ slotChanged();
+ m_changed = true;
+ }
+}
+
+void KateExternalToolsConfigWidget::slotEdit()
+{
+ if( !dynamic_cast<ToolItem*>(lbTools->selectedItem()) ) return;
+ // show the item in an editor
+ KateExternalTool *t = ((ToolItem*)lbTools->selectedItem())->tool;
+ KateExternalToolServiceEditor editor( t, this);
+ config->setGroup( "Editor" );
+ editor.resize( config->readSizeEntry( "Size" ) );
+ if ( editor.exec() /*== KDialogBase::Ok*/ )
+ {
+
+ bool elementChanged = ( ( editor.btnIcon->icon() != t->icon ) || (editor.leName->text() != t->name ) ) ;
+
+ t->name = editor.leName->text();
+ t->cmdname = editor.leCmdLine->text();
+ t->command = editor.teCommand->text();
+ t->icon = editor.btnIcon->icon();
+ t->tryexec = editor.leExecutable->text();
+ t->mimetypes = QStringList::split( QRegExp("\\s*;\\s*"), editor.leMimetypes->text() );
+ t->save = editor.cmbSave->currentItem();
+
+ //if the icon has changed or name changed, I have to renew the listbox item :S
+ if ( elementChanged )
+ {
+ int idx = lbTools->index( lbTools->selectedItem() );
+ lbTools->removeItem( idx );
+ lbTools->insertItem( new ToolItem( 0, t->icon.isEmpty() ? blankIcon() : SmallIcon( t->icon ), t ), idx );
+ }
+
+ slotChanged();
+ m_changed = true;
+ }
+
+ config->setGroup( "Editor" );
+ config->writeEntry( "Size", editor.size() );
+ config->sync();
+}
+
+void KateExternalToolsConfigWidget::slotInsertSeparator()
+{
+ lbTools->insertItem( "---", lbTools->currentItem()+1 );
+ slotChanged();
+ m_changed = true;
+}
+
+void KateExternalToolsConfigWidget::slotMoveUp()
+{
+ // move the current item in the listbox upwards if possible
+ QListBoxItem *item = lbTools->selectedItem();
+ if ( ! item ) return;
+
+ int idx = lbTools->index( item );
+
+ if ( idx < 1 ) return;
+
+ if ( dynamic_cast<ToolItem*>(item) )
+ {
+ KateExternalTool *tool = ((ToolItem*)item)->tool;
+ lbTools->removeItem( idx );
+ lbTools->insertItem( new ToolItem( 0, tool->icon.isEmpty() ? blankIcon() : SmallIcon( tool->icon ), tool ), idx-1 );
+ }
+ else // a separator!
+ {
+ lbTools->removeItem( idx );
+ lbTools->insertItem( new QListBoxText( 0, "---" ), idx-1 );
+ }
+
+ lbTools->setCurrentItem( idx - 1 );
+ slotSelectionChanged();
+ slotChanged();
+ m_changed = true;
+}
+
+void KateExternalToolsConfigWidget::slotMoveDown()
+{
+ // move the current item in the listbox downwards if possible
+ QListBoxItem *item = lbTools->selectedItem();
+ if ( ! item ) return;
+
+ uint idx = lbTools->index( item );
+
+ if ( idx > lbTools->count()-1 ) return;
+
+ if ( dynamic_cast<ToolItem*>(item) )
+ {
+ KateExternalTool *tool = ((ToolItem*)item)->tool;
+ lbTools->removeItem( idx );
+ lbTools->insertItem( new ToolItem( 0, tool->icon.isEmpty() ? blankIcon() : SmallIcon( tool->icon ), tool ), idx+1 );
+ }
+ else // a separator!
+ {
+ lbTools->removeItem( idx );
+ lbTools->insertItem( new QListBoxText( 0, "---" ), idx+1 );
+ }
+
+ lbTools->setCurrentItem( idx+1 );
+ slotSelectionChanged();
+ slotChanged();
+ m_changed = true;
+}
+//END KateExternalToolsConfigWidget
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/kateexternaltools.h b/kate/app/kateexternaltools.h
new file mode 100644
index 000000000..4a5ecdacc
--- /dev/null
+++ b/kate/app/kateexternaltools.h
@@ -0,0 +1,229 @@
+/*
+ This file is part of the Kate text editor of the KDE project.
+ It describes a "external tools" action for kate and provides a dialog
+ page to configure that.
+
+ 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.
+
+ ---
+ Copyright (C) 2004, Anders Lund <anders@alweb.dk>
+*/
+
+#ifndef _KATE_EXTERNAL_TOOLS_H_
+#define _KATE_EXTERNAL_TOOLS_H_
+
+#include <kaction.h>
+#include <kdialogbase.h>
+#include <kate/document.h>
+#include <kmacroexpander.h>
+#include <qpixmap.h>
+
+/**
+ * The external tools action
+ * This action creates a menu, in which each item will launch a process
+ * with the provided arguments, which may include the following macros:
+ * - %URLS: the URLs of all open documents.
+ * - %URL: The URL of the active document.
+ * - %filedir: The directory of the current document, if that is a local file.
+ * - %selection: The selection of the active document.
+ * - %text: The text of the active document.
+ * - %line: The line number of the cursor in the active view.
+ * - %column: The column of the cursor in the active view.
+ *
+ * Each item has the following properties:
+ * - Name: The friendly text for the menu
+ * - Exec: The command to execute, including arguments.
+ * - TryExec: the name of the executable, if not available, the
+ * item will not be displayed.
+ * - MimeTypes: An optional list of mimetypes. The item will be disabled or
+ * hidden if the current file is not of one of the indicated types.
+ *
+ */
+class KateExternalToolsMenuAction : public KActionMenu
+{
+ friend class KateExternalToolAction;
+
+ Q_OBJECT
+ public:
+ KateExternalToolsMenuAction( const QString &text=QString::null, QObject *parent=0, const char* name=0, class KateMainWindow *mw=0 );
+ ~KateExternalToolsMenuAction() {};
+
+ /**
+ * This will load all the confiured services.
+ */
+ void reload();
+
+ class KActionCollection *actionCollection() { return m_actionCollection; }
+
+ private slots:
+ void slotDocumentChanged();
+
+ private:
+ class KActionCollection *m_actionCollection;
+ class KateMainWindow *mainwindow; // for the actions to access view/doc managers
+};
+
+/**
+ * This Action contains a KateExternalTool
+ */
+class KateExternalToolAction : public KAction, public KWordMacroExpander
+{
+ Q_OBJECT
+ public:
+ KateExternalToolAction( QObject *parent, const char *name, class KateExternalTool *t );
+ ~KateExternalToolAction();
+ protected:
+ virtual bool expandMacro( const QString &str, QStringList &ret );
+
+ private slots:
+ void slotRun();
+
+ public:
+ class KateExternalTool *tool;
+};
+
+/**
+ * This class defines a single external tool.
+ */
+class KateExternalTool
+{
+ public:
+ KateExternalTool( const QString &name=QString::null,
+ const QString &command=QString::null,
+ const QString &icon=QString::null,
+ const QString &tryexec=QString::null,
+ const QStringList &mimetypes=QStringList(),
+ const QString &acname=QString::null,
+ const QString &cmdname=QString::null,
+ int save=0 );
+ ~KateExternalTool() {};
+
+ QString name; ///< The name used in the menu.
+ QString command; ///< The command to execute.
+ QString icon; ///< the icon to use in the menu.
+ QString tryexec; ///< The name or path of the executable.
+ QStringList mimetypes; ///< Optional list of mimetypes for which this action is valid.
+ bool hasexec; ///< This is set by the constructor by calling checkExec(), if a value is present.
+ QString acname; ///< The name for the action. This is generated first time the action is is created.
+ QString cmdname; ///< The name for the commandline.
+ int save; ///< We can save documents prior to activating the tool command: 0 = nothing, 1 = current document, 2 = all documents.
+
+ /**
+ * @return true if mimetypes is empty, or the @p mimetype matches.
+ */
+ bool valid( const QString &mimetype ) const;
+ /**
+ * @return true if "tryexec" exists and has the executable bit set, or is
+ * empty.
+ * This is run at least once, and the tool is disabled if it fails.
+ */
+ bool checkExec();
+
+ private:
+ QString m_exec; ///< The fully qualified path of the executable.
+};
+
+/**
+ * The config widget.
+ * The config widget allows the user to view a list of services of the type
+ * "Kate/ExternalTool" and add, remove or edit them.
+ */
+class KateExternalToolsConfigWidget : public Kate::ConfigPage
+{
+ Q_OBJECT
+ public:
+ KateExternalToolsConfigWidget( QWidget *parent, const char* name);
+ virtual ~KateExternalToolsConfigWidget();
+
+ virtual void apply();
+ virtual void reload();
+ virtual void reset() { reload(); } // sigh
+ virtual void defaults() { reload(); } // double sigh
+
+ private slots:
+ void slotNew();
+ void slotEdit();
+ void slotRemove();
+ void slotInsertSeparator();
+
+ void slotMoveUp();
+ void slotMoveDown();
+
+ void slotSelectionChanged();
+
+ private:
+ QPixmap blankIcon();
+
+ QStringList m_removed;
+
+ class KListBox *lbTools;
+ class QPushButton *btnNew, *btnRemove, *btnEdit, *btnMoveUp, *btnMoveDwn;
+
+ class KConfig *config;
+
+ bool m_changed;
+};
+
+/**
+ * A Singleton class for invoking external tools with the view command line
+ */
+ class KateExternalToolsCommand : public Kate::Command {
+ public:
+ KateExternalToolsCommand ();
+ virtual ~KateExternalToolsCommand () {};
+ static KateExternalToolsCommand *self();
+ void reload();
+ public:
+ virtual QStringList cmds ();
+ virtual bool exec (Kate::View *view, const QString &cmd, QString &msg);
+ virtual bool help (Kate::View *view, const QString &cmd, QString &msg);
+ private:
+ static KateExternalToolsCommand *s_self;
+ QStringList m_list;
+ QMap<QString,QString> m_map;
+ bool m_inited;
+ };
+
+/**
+ * A Dialog to edit a single KateExternalTool object
+ */
+class KateExternalToolServiceEditor : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+
+ KateExternalToolServiceEditor( KateExternalTool *tool=0,
+ QWidget *parent=0, const char *name=0 );
+
+ class QLineEdit *leName, *leExecutable, *leMimetypes,*leCmdLine;
+ class QTextEdit *teCommand;
+ class KIconButton *btnIcon;
+ class QComboBox *cmbSave;
+
+ private slots:
+ /**
+ * Run when the OK button is clicked, to ensure critical values are provided
+ */
+ void slotOk();
+ /**
+ * show a mimetype chooser dialog
+ */
+ void showMTDlg();
+
+ private:
+ KateExternalTool *tool;
+};
+#endif //_KATE_EXTERNAL_TOOLS_H_
diff --git a/kate/app/katefilelist.cpp b/kate/app/katefilelist.cpp
new file mode 100644
index 000000000..8c350d45a
--- /dev/null
+++ b/kate/app/katefilelist.cpp
@@ -0,0 +1,652 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ 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.
+*/
+
+//BEGIN Includes
+#include "katefilelist.h"
+#include "katefilelist.moc"
+
+#include "katedocmanager.h"
+#include "kateviewmanager.h"
+#include "katemainwindow.h"
+
+#include <qapplication.h>
+#include <qpainter.h>
+#include <qpopupmenu.h>
+#include <qheader.h>
+#include <qcolor.h>
+#include <qcheckbox.h>
+#include <qhbox.h>
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qwhatsthis.h>
+
+#include <kiconloader.h>
+#include <kconfig.h>
+#include <klocale.h>
+#include <kglobalsettings.h>
+#include <kpassivepopup.h>
+#include <kdebug.h>
+#include <kapplication.h>
+#include <kstringhandler.h>
+#include <kcolorbutton.h>
+#include <kdialog.h>
+//END Includes
+
+//BEGIN ToolTip
+class ToolTip : public QToolTip
+{
+ public:
+ ToolTip( QWidget *parent, KateFileList *lv )
+ : QToolTip( parent ),
+ m_listView( lv )
+ {
+ }
+ virtual ~ToolTip() {};
+
+ void maybeTip( const QPoint &pos )
+ {
+ QListViewItem *i = m_listView->itemAt( pos );
+ if ( ! i ) return;
+
+ KateFileListItem *item = ((KateFileListItem*)i);
+ if ( ! item ) return;
+
+ tip( m_listView->itemRect( i ), m_listView->tooltip( item, 0 ) );
+
+ }
+
+ private:
+ KateFileList *m_listView;
+};
+
+//END ToolTip
+
+//BEGIN KateFileList
+KateFileList::KateFileList (KateMainWindow *main,
+ KateViewManager *_viewManager,
+ QWidget * parent, const char * name )
+ : KListView (parent, name)
+ , m_sort( KateFileList::sortByID )
+{
+ m_main = main;
+ m_tooltip = new ToolTip( viewport(), this );
+
+ // default colors
+ m_viewShade = QColor( 51, 204, 255 );
+ m_editShade = QColor( 255, 102, 153 );
+ m_enableBgShading = false;
+
+ setFocusPolicy ( QWidget::NoFocus );
+
+ viewManager = _viewManager;
+
+ header()->hide();
+ addColumn("Document Name");
+
+ setSelectionMode( QListView::Single );
+ setSorting( 0, true );
+ setShowToolTips( false );
+
+ setupActions ();
+
+ for (uint i = 0; i < KateDocManager::self()->documents(); i++)
+ {
+ slotDocumentCreated (KateDocManager::self()->document(i));
+ slotModChanged (KateDocManager::self()->document(i));
+ }
+
+ connect(KateDocManager::self(),SIGNAL(documentCreated(Kate::Document *)),
+ this,SLOT(slotDocumentCreated(Kate::Document *)));
+ connect(KateDocManager::self(),SIGNAL(documentDeleted(uint)),
+ this,SLOT(slotDocumentDeleted(uint)));
+
+ // don't Honour KDE single/double click setting, this files are already open,
+ // no need for hassle of considering double-click
+ connect(this,SIGNAL(selectionChanged(QListViewItem *)),
+ this,SLOT(slotActivateView(QListViewItem *)));
+ connect(viewManager,SIGNAL(viewChanged()), this,SLOT(slotViewChanged()));
+ connect(this,SIGNAL(contextMenuRequested( QListViewItem *, const QPoint &, int )),
+ this,SLOT(slotMenu ( QListViewItem *, const QPoint &, int )));
+}
+
+KateFileList::~KateFileList ()
+{
+ delete m_tooltip;
+}
+
+void KateFileList::setupActions ()
+{
+ windowNext = KStdAction::back(this, SLOT(slotPrevDocument()), m_main->actionCollection());
+ windowPrev = KStdAction::forward(this, SLOT(slotNextDocument()), m_main->actionCollection());
+ sortAction = new KSelectAction( i18n("Sort &By"), 0,
+ m_main->actionCollection(), "filelist_sortby" );
+ QStringList l;
+ l << i18n("Opening Order") << i18n("Document Name") << i18n("URL");
+ sortAction->setItems( l );
+ connect( sortAction, SIGNAL(activated(int)), this, SLOT(setSortType(int)) );
+}
+
+void KateFileList::updateActions ()
+{
+ windowNext->setEnabled(KateDocManager::self()->documents() > 1);
+ windowPrev->setEnabled(KateDocManager::self()->documents() > 1);
+}
+
+void KateFileList::keyPressEvent(QKeyEvent *e) {
+ if ( ( e->key() == Key_Return ) || ( e->key() == Key_Enter ) )
+ {
+ e->accept();
+ slotActivateView( currentItem() );
+ }
+ else
+ {
+ KListView::keyPressEvent(e);
+ }
+}
+
+// Protect single mode selection: don't let them
+// leftclick outside items.
+// ### if we get to accept keyboard navigation, set focus before
+// returning
+void KateFileList::contentsMousePressEvent( QMouseEvent *e )
+{
+ if ( ! itemAt( contentsToViewport( e->pos() ) ) )
+ return;
+
+ KListView::contentsMousePressEvent( e );
+}
+
+void KateFileList::resizeEvent( QResizeEvent *e )
+{
+ KListView::resizeEvent( e );
+
+ // ### We may want to actually calculate the widest field,
+ // since it's not automatically scrinked. If I add support for
+ // tree or marks, the changes of the required width will vary
+ // a lot with opening/closing of files and display changes for
+ // the mark branches.
+ int w = viewport()->width();
+ if ( columnWidth( 0 ) < w )
+ setColumnWidth( 0, w );
+}
+
+void KateFileList::slotNextDocument()
+{
+ if ( ! currentItem() || childCount() == 0 )
+ return;
+
+ // ### more checking once more item types are added
+
+ if ( currentItem()->nextSibling() )
+ viewManager->activateView( ((KateFileListItem*)currentItem()->nextSibling())->documentNumber() );
+ else
+ viewManager->activateView( ((KateFileListItem *)firstChild())->documentNumber() );
+}
+
+void KateFileList::slotPrevDocument()
+{
+ if ( ! currentItem() || childCount() == 0 )
+ return;
+
+ // ### more checking once more item types are added
+
+ if ( currentItem()->itemAbove() )
+ viewManager->activateView( ((KateFileListItem*)currentItem()->itemAbove())->documentNumber() );
+ else
+ viewManager->activateView( ((KateFileListItem *)lastItem())->documentNumber() );
+}
+
+void KateFileList::slotDocumentCreated (Kate::Document *doc)
+{
+ new KateFileListItem( this, doc/*, doc->documentNumber()*/ );
+ connect(doc,SIGNAL(modStateChanged(Kate::Document *)),this,SLOT(slotModChanged(Kate::Document *)));
+ connect(doc,SIGNAL(nameChanged(Kate::Document *)),this,SLOT(slotNameChanged(Kate::Document *)));
+ connect(doc,SIGNAL(modifiedOnDisc(Kate::Document *, bool, unsigned char)),this,SLOT(slotModifiedOnDisc(Kate::Document *, bool, unsigned char)));
+
+ sort();
+ updateActions ();
+}
+
+void KateFileList::slotDocumentDeleted (uint documentNumber)
+{
+ QListViewItem * item = firstChild();
+ while( item ) {
+ if ( ((KateFileListItem *)item)->documentNumber() == documentNumber )
+ {
+// m_viewHistory.removeRef( (KateFileListItem *)item );
+// m_editHistory.removeRef( (KateFileListItem *)item );
+
+ removeItem( item );
+
+ break;
+ }
+ item = item->nextSibling();
+ }
+
+ updateActions ();
+}
+
+void KateFileList::slotActivateView( QListViewItem *item )
+{
+ if ( ! item || item->rtti() != RTTI_KateFileListItem )
+ return;
+
+ viewManager->activateView( ((KateFileListItem *)item)->documentNumber() );
+}
+
+void KateFileList::slotModChanged (Kate::Document *doc)
+{
+ if (!doc) return;
+
+ QListViewItem * item = firstChild();
+ while( item )
+ {
+ if ( ((KateFileListItem *)item)->documentNumber() == doc->documentNumber() )
+ break;
+
+ item = item->nextSibling();
+ }
+
+ if ( ((KateFileListItem *)item)->document()->isModified() )
+ {
+ m_editHistory.removeRef( (KateFileListItem *)item );
+ m_editHistory.prepend( (KateFileListItem *)item );
+
+ for ( uint i=0; i < m_editHistory.count(); i++ )
+ {
+ m_editHistory.at( i )->setEditHistPos( i+1 );
+ repaintItem( m_editHistory.at( i ) );
+ }
+ }
+ else
+ repaintItem( item );
+}
+
+void KateFileList::slotModifiedOnDisc (Kate::Document *doc, bool, unsigned char)
+{
+ slotModChanged( doc );
+}
+
+void KateFileList::slotNameChanged (Kate::Document *doc)
+{
+ if (!doc) return;
+
+ // ### using nextSibling to *only* look at toplevel items.
+ // child items could be marks for example
+ QListViewItem * item = firstChild();
+ while( item ) {
+ if ( ((KateFileListItem*)item)->document() == doc )
+ {
+ item->setText( 0, doc->docName() );
+ repaintItem( item );
+ break;
+ }
+ item = item->nextSibling();
+ }
+ updateSort();
+}
+
+void KateFileList::slotViewChanged ()
+{
+ if (!viewManager->activeView()) return;
+
+ Kate::View *view = viewManager->activeView();
+ uint dn = view->getDoc()->documentNumber();
+
+ QListViewItem * i = firstChild();
+ while( i ) {
+ if ( ((KateFileListItem *)i)->documentNumber() == dn )
+ {
+ break;
+ }
+ i = i->nextSibling();
+ }
+
+ if ( ! i )
+ return;
+
+ KateFileListItem *item = (KateFileListItem*)i;
+ setCurrentItem( item );
+
+ // ### During load of file lists, all the loaded views gets active.
+ // Do something to avoid shading them -- maybe not creating views, just
+ // open the documents???
+
+
+// int p = 0;
+// if ( m_viewHistory.count() )
+// {
+// int p = m_viewHistory.findRef( item ); // only repaint items that needs it
+// }
+
+ m_viewHistory.removeRef( item );
+ m_viewHistory.prepend( item );
+
+ for ( uint i=0; i < m_viewHistory.count(); i++ )
+ {
+ m_viewHistory.at( i )->setViewHistPos( i+1 );
+ repaintItem( m_viewHistory.at( i ) );
+ }
+
+}
+
+void KateFileList::slotMenu ( QListViewItem *item, const QPoint &p, int /*col*/ )
+{
+ if (!item)
+ return;
+
+ QPopupMenu *menu = (QPopupMenu*) ((viewManager->mainWindow())->factory()->container("filelist_popup", viewManager->mainWindow()));
+
+ if (menu)
+ menu->exec(p);
+}
+
+QString KateFileList::tooltip( QListViewItem *item, int )
+{
+ KateFileListItem *i = ((KateFileListItem*)item);
+ if ( ! i ) return QString::null;
+
+ QString str;
+ const KateDocumentInfo *info = KateDocManager::self()->documentInfo(i->document());
+
+ if (info && info->modifiedOnDisc)
+ {
+ if (info->modifiedOnDiscReason == 1)
+ str += i18n("<b>This file was changed (modified) on disk by another program.</b><br />");
+ else if (info->modifiedOnDiscReason == 2)
+ str += i18n("<b>This file was changed (created) on disk by another program.</b><br />");
+ else if (info->modifiedOnDiscReason == 3)
+ str += i18n("<b>This file was changed (deleted) on disk by another program.</b><br />");
+ }
+
+ str += i->document()->url().prettyURL();
+ return str;
+}
+
+
+void KateFileList::setSortType (int s)
+{
+ m_sort = s;
+ updateSort ();
+}
+
+void KateFileList::updateSort ()
+{
+ sort ();
+}
+
+void KateFileList::readConfig( KConfig *config, const QString &group )
+{
+ QString oldgroup = config->group();
+ config->setGroup( group );
+
+ setSortType( config->readNumEntry( "Sort Type", sortByID ) );
+ m_viewShade = config->readColorEntry( "View Shade", &m_viewShade );
+ m_editShade = config->readColorEntry( "Edit Shade", &m_editShade );
+ m_enableBgShading = config->readBoolEntry( "Shading Enabled", &m_enableBgShading );
+
+ sortAction->setCurrentItem( sortType() );
+
+ config->setGroup( oldgroup );
+}
+
+void KateFileList::writeConfig( KConfig *config, const QString &group )
+{
+ QString oldgroup = config->group();
+ config->setGroup( group );
+
+ config->writeEntry( "Sort Type", m_sort );
+ config->writeEntry( "View Shade", m_viewShade );
+ config->writeEntry( "Edit Shade", m_editShade );
+ config->writeEntry( "Shading Enabled", m_enableBgShading );
+
+ config->setGroup( oldgroup );
+}
+
+void KateFileList::takeItem( QListViewItem *item )
+{
+ if ( item->rtti() == RTTI_KateFileListItem )
+ {
+ m_editHistory.removeRef( (KateFileListItem*)item );
+ m_viewHistory.removeRef( (KateFileListItem*)item );
+ }
+ QListView::takeItem( item );
+}
+//END KateFileList
+
+//BEGIN KateFileListItem
+KateFileListItem::KateFileListItem( QListView* lv,
+ Kate::Document *_doc )
+ : QListViewItem( lv, _doc->docName() ),
+ doc( _doc ),
+ m_viewhistpos( 0 ),
+ m_edithistpos( 0 ),
+ m_docNumber( _doc->documentNumber() )
+{
+}
+
+KateFileListItem::~KateFileListItem()
+{
+}
+
+const QPixmap *KateFileListItem::pixmap ( int column ) const
+{
+ if ( column == 0) {
+ static QPixmap noPm = SmallIcon ("null");
+ static QPixmap modPm = SmallIcon("modified");
+ static QPixmap discPm = SmallIcon("modonhd");
+ static QPixmap modmodPm = SmallIcon("modmod");
+
+ const KateDocumentInfo *info = KateDocManager::self()->documentInfo(doc);
+
+ if (info && info->modifiedOnDisc)
+ return doc->isModified() ? &modmodPm : &discPm;
+ else
+ return doc->isModified() ? &modPm : &noPm;
+ }
+
+ return 0;
+}
+
+void KateFileListItem::paintCell( QPainter *painter, const QColorGroup & cg, int column, int width, int align )
+{
+ KateFileList *fl = (KateFileList*)listView();
+ if ( ! fl ) return;
+
+ if ( column == 0 )
+ {
+ QColorGroup cgNew = cg;
+
+ // replace the base color with a different shading if necessary...
+ if ( fl->shadingEnabled() && m_viewhistpos > 1 )
+ {
+ QColor b( cg.base() );
+
+ QColor shade = fl->viewShade();
+ QColor eshade = fl->editShade();
+ int hc = fl->histCount();
+ // If this file is in the edit history, blend in the eshade
+ // color. The blend is weighted by the position in the editing history
+ if ( fl->shadingEnabled() && m_edithistpos > 0 )
+ {
+ int ec = fl->editHistCount();
+ int v = hc-m_viewhistpos;
+ int e = ec-m_edithistpos+1;
+ e = e*e;
+ int n = QMAX(v + e, 1);
+ shade.setRgb(
+ ((shade.red()*v) + (eshade.red()*e))/n,
+ ((shade.green()*v) + (eshade.green()*e))/n,
+ ((shade.blue()*v) + (eshade.blue()*e))/n
+ );
+ }
+ // blend in the shade color.
+ // max transperancy < .5, latest is most colored.
+ float t = (0.5/hc)*(hc-m_viewhistpos+1);
+ b.setRgb(
+ (int)((b.red()*(1-t)) + (shade.red()*t)),
+ (int)((b.green()*(1-t)) + (shade.green()*t)),
+ (int)((b.blue()*(1-t)) + (shade.blue()*t))
+ );
+
+ cgNew.setColor(QColorGroup::Base, b);
+ }
+
+ QListViewItem::paintCell( painter, cgNew, column, width, align );
+ }
+ else
+ QListViewItem::paintCell( painter, cg, column, width, align );
+}
+
+int KateFileListItem::compare ( QListViewItem * i, int col, bool ascending ) const
+{
+ if ( i->rtti() == RTTI_KateFileListItem )
+ {
+ switch( ((KateFileList*)listView())->sortType() )
+ {
+ case KateFileList::sortByID:
+ {
+
+ int d = (int)doc->documentNumber() - ((KateFileListItem*)i)->documentNumber();
+ return ascending ? d : -d;
+ break;
+ }
+ case KateFileList::sortByURL:
+ return doc->url().prettyURL().compare( ((KateFileListItem*)i)->document()->url().prettyURL() );
+ break;
+ default:
+ return QListViewItem::compare( i, col, ascending );
+ }
+ }
+ return 0;
+}
+//END KateFileListItem
+
+//BEGIN KFLConfigPage
+KFLConfigPage::KFLConfigPage( QWidget* parent, const char *name, KateFileList *fl )
+ : Kate::ConfigPage( parent, name ),
+ m_filelist( fl ),
+ m_changed( false )
+{
+ QVBoxLayout *lo1 = new QVBoxLayout( this );
+ int spacing = KDialog::spacingHint();
+ lo1->setSpacing( spacing );
+
+ QGroupBox *gb = new QGroupBox( 1, Qt::Horizontal, i18n("Background Shading"), this );
+ lo1->addWidget( gb );
+
+ QWidget *g = new QWidget( gb );
+ QGridLayout *lo = new QGridLayout( g, 2, 2 );
+ lo->setSpacing( KDialog::spacingHint() );
+ cbEnableShading = new QCheckBox( i18n("&Enable background shading"), g );
+ lo->addMultiCellWidget( cbEnableShading, 1, 1, 0, 1 );
+
+ kcbViewShade = new KColorButton( g );
+ lViewShade = new QLabel( kcbViewShade, i18n("&Viewed documents' shade:"), g );
+ lo->addWidget( lViewShade, 2, 0 );
+ lo->addWidget( kcbViewShade, 2, 1 );
+
+ kcbEditShade = new KColorButton( g );
+ lEditShade = new QLabel( kcbEditShade, i18n("&Modified documents' shade:"), g );
+ lo->addWidget( lEditShade, 3, 0 );
+ lo->addWidget( kcbEditShade, 3, 1 );
+
+ // sorting
+ QHBox *hbSorting = new QHBox( this );
+ lo1->addWidget( hbSorting );
+ lSort = new QLabel( i18n("&Sort by:"), hbSorting );
+ cmbSort = new QComboBox( hbSorting );
+ lSort->setBuddy( cmbSort );
+ QStringList l;
+ l << i18n("Opening Order") << i18n("Document Name") << i18n("URL");
+ cmbSort->insertStringList( l );
+
+ lo1->insertStretch( -1, 10 );
+
+ QWhatsThis::add( cbEnableShading, i18n(
+ "When background shading is enabled, documents that have been viewed "
+ "or edited within the current session will have a shaded background. "
+ "The most recent documents have the strongest shade.") );
+ QWhatsThis::add( kcbViewShade, i18n(
+ "Set the color for shading viewed documents.") );
+ QWhatsThis::add( kcbEditShade, i18n(
+ "Set the color for modified documents. This color is blended into "
+ "the color for viewed files. The most recently edited documents get "
+ "most of this color.") );
+
+ QWhatsThis::add( cmbSort, i18n(
+ "Set the sorting method for the documents.") );
+
+ reload();
+
+ slotEnableChanged();
+ connect( cbEnableShading, SIGNAL(toggled(bool)), this, SLOT(slotMyChanged()) );
+ connect( cbEnableShading, SIGNAL(toggled(bool)), this, SLOT(slotEnableChanged()) );
+ connect( kcbViewShade, SIGNAL(changed(const QColor&)), this, SLOT(slotMyChanged()) );
+ connect( kcbEditShade, SIGNAL(changed(const QColor&)), this, SLOT(slotMyChanged()) );
+ connect( cmbSort, SIGNAL(activated(int)), this, SLOT(slotMyChanged()) );
+}
+
+void KFLConfigPage::apply()
+{
+ if ( ! m_changed )
+ return;
+ m_changed = false;
+
+ // Change settings in the filelist
+ m_filelist->m_viewShade = kcbViewShade->color();
+ m_filelist->m_editShade = kcbEditShade->color();
+ m_filelist->m_enableBgShading = cbEnableShading->isChecked();
+ m_filelist->setSortType( cmbSort->currentItem() );
+ // repaint the affected items
+ m_filelist->triggerUpdate();
+}
+
+void KFLConfigPage::reload()
+{
+ // read in from config file
+ KConfig *config = kapp->config();
+ config->setGroup( "Filelist" );
+ cbEnableShading->setChecked( config->readBoolEntry("Shading Enabled", &m_filelist->m_enableBgShading ) );
+ kcbViewShade->setColor( config->readColorEntry("View Shade", &m_filelist->m_viewShade ) );
+ kcbEditShade->setColor( config->readColorEntry("Edit Shade", &m_filelist->m_editShade ) );
+ cmbSort->setCurrentItem( m_filelist->sortType() );
+ m_changed = false;
+}
+
+void KFLConfigPage::slotEnableChanged()
+{
+ kcbViewShade->setEnabled( cbEnableShading->isChecked() );
+ kcbEditShade->setEnabled( cbEnableShading->isChecked() );
+ lViewShade->setEnabled( cbEnableShading->isChecked() );
+ lEditShade->setEnabled( cbEnableShading->isChecked() );
+}
+
+void KFLConfigPage::slotMyChanged()
+{
+ m_changed = true;
+ slotChanged();
+}
+
+//END KFLConfigPage
+
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/katefilelist.h b/kate/app/katefilelist.h
new file mode 100644
index 000000000..7615eb63d
--- /dev/null
+++ b/kate/app/katefilelist.h
@@ -0,0 +1,191 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KATE_FILELIST_H__
+#define __KATE_FILELIST_H__
+
+#include "katemain.h"
+
+#include <kate/document.h>
+
+#include <klistview.h>
+
+#include <qtooltip.h>
+#include <qcolor.h>
+#include <qptrlist.h>
+
+#define RTTI_KateFileListItem 1001
+
+class KateMainWindow;
+
+class KAction;
+class KSelectAction;
+
+class KateFileListItem : public QListViewItem
+{
+ public:
+ KateFileListItem( QListView *lv,
+ Kate::Document *doc );
+ ~KateFileListItem();
+
+ inline uint documentNumber () { return m_docNumber; }
+ inline Kate::Document * document() { return doc; }
+
+ int rtti() const { return RTTI_KateFileListItem; }
+
+ /**
+ * Sets the view history position.
+ */
+ void setViewHistPos( int p ) { m_viewhistpos = p; }
+ /**
+ * Sets the edit history position.
+ */
+ void setEditHistPos( int p ) { m_edithistpos = p; }
+
+ protected:
+ virtual const QPixmap *pixmap ( int column ) const;
+ void paintCell( QPainter *painter, const QColorGroup & cg, int column, int width, int align );
+ /**
+ * Reimplemented so we can sort by a number of different document properties.
+ */
+ int compare ( QListViewItem * i, int col, bool ascending ) const;
+
+ private:
+ Kate::Document *doc;
+ int m_viewhistpos; ///< this gets set by the list as needed
+ int m_edithistpos; ///< this gets set by the list as needed
+ uint m_docNumber;
+};
+
+class KateFileList : public KListView
+{
+ Q_OBJECT
+
+ friend class KFLConfigPage;
+
+ public:
+ KateFileList (KateMainWindow *main, KateViewManager *_viewManager, QWidget * parent = 0, const char * name = 0 );
+ ~KateFileList ();
+
+ int sortType () const { return m_sort; };
+ void updateSort ();
+
+ enum sorting {
+ sortByID = 0,
+ sortByName = 1,
+ sortByURL = 2
+ };
+
+ QString tooltip( QListViewItem *item, int );
+
+ uint histCount() const { return m_viewHistory.count(); }
+ uint editHistCount() const { return m_editHistory.count(); }
+ QColor editShade() const { return m_editShade; }
+ QColor viewShade() const { return m_viewShade; }
+ bool shadingEnabled() { return m_enableBgShading; }
+
+ void readConfig( class KConfig *config, const QString &group );
+ void writeConfig( class KConfig *config, const QString &group );
+
+ /**
+ * reimplemented to remove the item from the history stacks
+ */
+ void takeItem( QListViewItem * );
+
+ public slots:
+ void setSortType (int s);
+ void slotNextDocument();
+ void slotPrevDocument();
+
+ private slots:
+ void slotDocumentCreated (Kate::Document *doc);
+ void slotDocumentDeleted (uint documentNumber);
+ void slotActivateView( QListViewItem *item );
+ void slotModChanged (Kate::Document *doc);
+ void slotModifiedOnDisc (Kate::Document *doc, bool b, unsigned char reason);
+ void slotNameChanged (Kate::Document *doc);
+ void slotViewChanged ();
+ void slotMenu ( QListViewItem *item, const QPoint &p, int col );
+
+ protected:
+ virtual void keyPressEvent( QKeyEvent *e );
+ /**
+ * Reimplemented to force Single mode for real:
+ * don't let a mouse click outside items deselect.
+ */
+ virtual void contentsMousePressEvent( QMouseEvent *e );
+ /**
+ * Reimplemented to make sure the first (and only) column is at least
+ * the width of the viewport
+ */
+ virtual void resizeEvent( QResizeEvent *e );
+
+ private:
+ void setupActions ();
+ void updateActions ();
+
+ private:
+ KateMainWindow *m_main;
+ KateViewManager *viewManager;
+
+ int m_sort;
+ bool notify;
+
+ KAction* windowNext;
+ KAction* windowPrev;
+ KSelectAction* sortAction;
+
+ QPtrList<KateFileListItem> m_viewHistory;
+ QPtrList<KateFileListItem> m_editHistory;
+
+ QColor m_viewShade, m_editShade;
+ bool m_enableBgShading;
+
+ class ToolTip *m_tooltip;
+};
+
+class KFLConfigPage : public Kate::ConfigPage {
+ Q_OBJECT
+ public:
+ KFLConfigPage( QWidget* parent=0, const char *name=0, KateFileList *fl=0 );
+ virtual ~KFLConfigPage() {};
+
+ virtual void apply();
+ virtual void reload();
+
+ public slots:
+ void slotEnableChanged();
+
+ private slots:
+ void slotMyChanged();
+
+ private:
+ class QCheckBox *cbEnableShading;
+ class KColorButton *kcbViewShade, *kcbEditShade;
+ class QLabel *lEditShade, *lViewShade, *lSort;
+ class QComboBox *cmbSort;
+ KateFileList *m_filelist;
+
+ bool m_changed;
+};
+
+
+#endif
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/katefileselector.cpp b/kate/app/katefileselector.cpp
new file mode 100644
index 000000000..bdc39fc9a
--- /dev/null
+++ b/kate/app/katefileselector.cpp
@@ -0,0 +1,722 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ 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.
+*/
+
+//BEGIN Includes
+#include "katefileselector.h"
+#include "katefileselector.moc"
+
+#include "katemainwindow.h"
+#include "kateviewmanager.h"
+#include "kbookmarkhandler.h"
+
+#include "kactionselector.h"
+
+#include <qlayout.h>
+#include <qtoolbutton.h>
+#include <qhbox.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qstrlist.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qapplication.h>
+#include <qlistbox.h>
+#include <qscrollbar.h>
+#include <qspinbox.h>
+#include <qgroupbox.h>
+#include <qcheckbox.h>
+#include <qregexp.h>
+#include <qdockarea.h>
+#include <qtimer.h>
+#include <qdir.h>
+
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <kurlcombobox.h>
+#include <kurlcompletion.h>
+#include <kprotocolinfo.h>
+#include <kdiroperator.h>
+#include <kconfig.h>
+#include <klocale.h>
+#include <kcombobox.h>
+#include <kaction.h>
+#include <kmessagebox.h>
+#include <ktoolbarbutton.h>
+#include <qtoolbar.h>
+#include <kpopupmenu.h>
+#include <kdialog.h>
+#include <kdebug.h>
+//END Includes
+
+//BEGIN Toolbar
+ // from kfiledialog.cpp - avoid qt warning in STDERR (~/.xsessionerrors)
+static void silenceQToolBar(QtMsgType, const char *){}
+
+// helper classes to be able to have a toolbar without move handle
+KateFileSelectorToolBar::KateFileSelectorToolBar(QWidget *parent)
+ : KToolBar( parent, "Kate FileSelector Toolbar", true )
+{
+ setMinimumWidth(10);
+}
+
+KateFileSelectorToolBar::~KateFileSelectorToolBar(){}
+
+void KateFileSelectorToolBar::setMovingEnabled( bool)
+{
+ KToolBar::setMovingEnabled(false);
+}
+
+
+KateFileSelectorToolBarParent::KateFileSelectorToolBarParent(QWidget *parent)
+ :QFrame(parent),m_tb(0){}
+KateFileSelectorToolBarParent::~KateFileSelectorToolBarParent(){}
+void KateFileSelectorToolBarParent::setToolBar(KateFileSelectorToolBar *tb)
+{
+ m_tb=tb;
+}
+
+void KateFileSelectorToolBarParent::resizeEvent ( QResizeEvent * )
+{
+ if (m_tb)
+ {
+ setMinimumHeight(m_tb->sizeHint().height());
+ m_tb->resize(width(),height());
+ }
+}
+//END
+
+//BEGIN Constructor/destructor
+
+KateFileSelector::KateFileSelector( KateMainWindow *mainWindow,
+ KateViewManager *viewManager,
+ QWidget * parent, const char * name )
+ : QVBox (parent, name),
+ mainwin(mainWindow),
+ viewmanager(viewManager)
+{
+ mActionCollection = new KActionCollection( this );
+
+ QtMsgHandler oldHandler = qInstallMsgHandler( silenceQToolBar );
+
+ KateFileSelectorToolBarParent *tbp=new KateFileSelectorToolBarParent(this);
+ toolbar = new KateFileSelectorToolBar(tbp);
+ tbp->setToolBar(toolbar);
+ toolbar->setMovingEnabled(false);
+ toolbar->setFlat(true);
+ qInstallMsgHandler( oldHandler );
+
+ cmbPath = new KURLComboBox( KURLComboBox::Directories, true, this, "path combo" );
+ cmbPath->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ));
+ KURLCompletion* cmpl = new KURLCompletion(KURLCompletion::DirCompletion);
+ cmbPath->setCompletionObject( cmpl );
+ cmbPath->setAutoDeleteCompletionObject( true );
+ cmbPath->listBox()->installEventFilter( this );
+
+ dir = new KDirOperator(KURL(), this, "operator");
+ dir->setView(KFile::/* Simple */Detail);
+ dir->view()->setSelectionMode(KFile::Extended);
+ connect ( dir, SIGNAL( viewChanged(KFileView *) ),
+ this, SLOT( selectorViewChanged(KFileView *) ) );
+ setStretchFactor(dir, 2);
+
+ KActionCollection *coll = dir->actionCollection();
+ // some shortcuts of diroperator that clashes with Kate
+ coll->action( "delete" )->setShortcut( KShortcut( ALT + Key_Delete ) );
+ coll->action( "reload" )->setShortcut( KShortcut( ALT + Key_F5 ) );
+ coll->action( "back" )->setShortcut( KShortcut( ALT + SHIFT + Key_Left ) );
+ coll->action( "forward" )->setShortcut( KShortcut( ALT + SHIFT + Key_Right ) );
+ // some consistency - reset up for dir too
+ coll->action( "up" )->setShortcut( KShortcut( ALT + SHIFT + Key_Up ) );
+ coll->action( "home" )->setShortcut( KShortcut( CTRL + ALT + Key_Home ) );
+
+ // bookmarks action!
+ KActionMenu *acmBookmarks = new KActionMenu( i18n("Bookmarks"), "bookmark",
+ mActionCollection, "bookmarks" );
+ acmBookmarks->setDelayed( false );
+ bookmarkHandler = new KBookmarkHandler( this, acmBookmarks->popupMenu() );
+ QHBox* filterBox = new QHBox(this);
+
+ btnFilter = new QToolButton( filterBox );
+ btnFilter->setIconSet( SmallIconSet("filter" ) );
+ btnFilter->setToggleButton( true );
+ filter = new KHistoryCombo( true, filterBox, "filter");
+ filter->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ));
+ filterBox->setStretchFactor(filter, 2);
+ connect( btnFilter, SIGNAL( clicked() ), this, SLOT( btnFilterClick() ) );
+
+ connect( filter, SIGNAL( activated(const QString&) ),
+ SLOT( slotFilterChange(const QString&) ) );
+ connect( filter, SIGNAL( returnPressed(const QString&) ),
+ filter, SLOT( addToHistory(const QString&) ) );
+
+ // kaction for the dir sync method
+ acSyncDir = new KAction( i18n("Current Document Folder"), "curfiledir", 0,
+ this, SLOT( setActiveDocumentDir() ), mActionCollection, "sync_dir" );
+ toolbar->setIconText( KToolBar::IconOnly );
+ toolbar->setIconSize( 16 );
+ toolbar->setEnableContextMenu( false );
+
+ connect( cmbPath, SIGNAL( urlActivated( const KURL& )),
+ this, SLOT( cmbPathActivated( const KURL& ) ));
+ connect( cmbPath, SIGNAL( returnPressed( const QString& )),
+ this, SLOT( cmbPathReturnPressed( const QString& ) ));
+ connect(dir, SIGNAL(urlEntered(const KURL&)),
+ this, SLOT(dirUrlEntered(const KURL&)) );
+
+ connect(dir, SIGNAL(finishedLoading()),
+ this, SLOT(dirFinishedLoading()) );
+
+ // enable dir sync button if current doc has a valid URL
+ connect ( viewmanager, SIGNAL( viewChanged() ),
+ this, SLOT( kateViewChanged() ) );
+
+ // Connect the bookmark handler
+ connect( bookmarkHandler, SIGNAL( openURL( const QString& )),
+ this, SLOT( setDir( const QString& ) ) );
+
+ waitingUrl = QString::null;
+
+ // whatsthis help
+ QWhatsThis::add( cmbPath,
+ i18n("<p>Here you can enter a path for a folder to display."
+ "<p>To go to a folder previously entered, press the arrow on "
+ "the right and choose one. <p>The entry has folder "
+ "completion. Right-click to choose how completion should behave.") );
+ QWhatsThis::add( filter,
+ i18n("<p>Here you can enter a name filter to limit which files are displayed."
+ "<p>To clear the filter, toggle off the filter button to the left."
+ "<p>To reapply the last filter used, toggle on the filter button." ) );
+ QWhatsThis::add( btnFilter,
+ i18n("<p>This button clears the name filter when toggled off, or "
+ "reapplies the last filter used when toggled on.") );
+
+}
+
+KateFileSelector::~KateFileSelector()
+{
+}
+//END Constroctor/Destrctor
+
+//BEGIN Public Methods
+
+void KateFileSelector::readConfig(KConfig *config, const QString & name)
+{
+ dir->setViewConfig( config, name + ":view" );
+ dir->readConfig(config, name + ":dir");
+ dir->setView( KFile::Default );
+ dir->view()->setSelectionMode(KFile::Extended);
+ config->setGroup( name );
+
+ // set up the toolbar
+ setupToolbar( config );
+
+ cmbPath->setMaxItems( config->readNumEntry( "pathcombo history len", 9 ) );
+ cmbPath->setURLs( config->readPathListEntry( "dir history" ) );
+ // if we restore history
+ if ( config->readBoolEntry( "restore location", true ) || kapp->isRestored() ) {
+ QString loc( config->readPathEntry( "location" ) );
+ if ( ! loc.isEmpty() ) {
+// waitingDir = loc;
+// QTimer::singleShot(0, this, SLOT(initialDirChangeHack()));
+ setDir( loc );
+ }
+ }
+
+ // else is automatic, as cmpPath->setURL is called when a location is entered.
+
+ filter->setMaxCount( config->readNumEntry( "filter history len", 9 ) );
+ filter->setHistoryItems( config->readListEntry("filter history"), true );
+ lastFilter = config->readEntry( "last filter" );
+ QString flt("");
+ if ( config->readBoolEntry( "restore last filter", true ) || kapp->isRestored() )
+ flt = config->readEntry("current filter");
+ filter->lineEdit()->setText( flt );
+ slotFilterChange( flt );
+
+ autoSyncEvents = config->readNumEntry( "AutoSyncEvents", 0 );
+}
+
+void KateFileSelector::initialDirChangeHack()
+{
+ setDir( waitingDir );
+}
+
+void KateFileSelector::setupToolbar( KConfig *config )
+{
+ toolbar->clear();
+ QStringList tbactions = config->readListEntry( "toolbar actions", ',' );
+ if ( tbactions.isEmpty() ) {
+ // reasonable collection for default toolbar
+ tbactions << "up" << "back" << "forward" << "home" <<
+ "short view" << "detailed view" <<
+ "bookmarks" << "sync_dir";
+ }
+ KAction *ac;
+ for ( QStringList::Iterator it=tbactions.begin(); it != tbactions.end(); ++it ) {
+ if ( *it == "bookmarks" || *it == "sync_dir" )
+ ac = mActionCollection->action( (*it).latin1() );
+ else
+ ac = dir->actionCollection()->action( (*it).latin1() );
+ if ( ac )
+ ac->plug( toolbar );
+ }
+}
+
+void KateFileSelector::writeConfig(KConfig *config, const QString & name)
+{
+ dir->writeConfig(config,name + ":dir");
+
+ config->setGroup( name );
+ config->writeEntry( "pathcombo history len", cmbPath->maxItems() );
+ QStringList l;
+ for (int i = 0; i < cmbPath->count(); i++) {
+ l.append( cmbPath->text( i ) );
+ }
+ config->writePathEntry( "dir history", l );
+ config->writePathEntry( "location", cmbPath->currentText() );
+
+ config->writeEntry( "filter history len", filter->maxCount() );
+ config->writeEntry( "filter history", filter->historyItems() );
+ config->writeEntry( "current filter", filter->currentText() );
+ config->writeEntry( "last filter", lastFilter );
+ config->writeEntry( "AutoSyncEvents", autoSyncEvents );
+}
+
+void KateFileSelector::setView(KFile::FileView view)
+{
+ dir->setView(view);
+ dir->view()->setSelectionMode(KFile::Extended);
+}
+
+//END Public Methods
+
+//BEGIN Public Slots
+
+void KateFileSelector::slotFilterChange( const QString & nf )
+{
+ QString f = nf.stripWhiteSpace();
+ bool empty = f.isEmpty() || f == "*";
+ QToolTip::remove( btnFilter );
+ if ( empty ) {
+ dir->clearFilter();
+ filter->lineEdit()->setText( QString::null );
+ QToolTip::add( btnFilter,
+ QString( i18n("Apply last filter (\"%1\")") ).arg( lastFilter ) );
+ }
+ else {
+ dir->setNameFilter( f );
+ lastFilter = f;
+ QToolTip::add( btnFilter, i18n("Clear filter") );
+ }
+ btnFilter->setOn( !empty );
+ dir->updateDir();
+ // this will be never true after the filter has been used;)
+ btnFilter->setEnabled( !( empty && lastFilter.isEmpty() ) );
+
+}
+
+bool kateFileSelectorIsReadable ( const KURL& url )
+{
+ if ( !url.isLocalFile() )
+ return true; // what else can we say?
+
+ QDir dir (url.path());
+ return dir.exists ();
+}
+
+void KateFileSelector::setDir( KURL u )
+{
+ KURL newurl;
+
+ if ( !u.isValid() )
+ newurl.setPath( QDir::homeDirPath() );
+ else
+ newurl = u;
+
+ QString pathstr = newurl.path(+1);
+ newurl.setPath(pathstr);
+
+ if ( !kateFileSelectorIsReadable ( newurl ) )
+ newurl.cd(QString::fromLatin1(".."));
+
+ if ( !kateFileSelectorIsReadable (newurl) )
+ newurl.setPath( QDir::homeDirPath() );
+
+ dir->setURL(newurl, true);
+}
+
+//END Public Slots
+
+//BEGIN Private Slots
+
+void KateFileSelector::cmbPathActivated( const KURL& u )
+{
+ cmbPathReturnPressed( u.url() );
+}
+
+void KateFileSelector::cmbPathReturnPressed( const QString& u )
+{
+ KURL typedURL( u );
+ if ( typedURL.hasPass() )
+ typedURL.setPass( QString::null );
+
+ QStringList urls = cmbPath->urls();
+ urls.remove( typedURL.url() );
+ urls.prepend( typedURL.url() );
+ cmbPath->setURLs( urls, KURLComboBox::RemoveBottom );
+ dir->setFocus();
+ dir->setURL( KURL(u), true );
+}
+
+void KateFileSelector::dirUrlEntered( const KURL& u )
+{
+ cmbPath->setURL( u );
+}
+
+void KateFileSelector::dirFinishedLoading()
+{
+}
+
+
+/*
+ When the button in the filter box toggles:
+ If off:
+ If the name filer is anything but "" or "*", reset it.
+ If on:
+ Set last filter.
+*/
+void KateFileSelector::btnFilterClick()
+{
+ if ( !btnFilter->isOn() ) {
+ slotFilterChange( QString::null );
+ }
+ else {
+ filter->lineEdit()->setText( lastFilter );
+ slotFilterChange( lastFilter );
+ }
+}
+
+//FIXME crash on shutdown
+void KateFileSelector::setActiveDocumentDir()
+{
+// kdDebug(13001)<<"KateFileSelector::setActiveDocumentDir()"<<endl;
+ KURL u = mainwin->activeDocumentUrl();
+// kdDebug(13001)<<"URL: "<<u.prettyURL()<<endl;
+ if (!u.isEmpty())
+ setDir( u.upURL() );
+// kdDebug(13001)<<"... setActiveDocumentDir() DONE!"<<endl;
+}
+
+void KateFileSelector::kateViewChanged()
+{
+ if ( autoSyncEvents & DocumentChanged )
+ {
+// kdDebug(13001)<<"KateFileSelector::do a sync ()"<<endl;
+ // if visible, sync
+ if ( isVisible() ) {
+ setActiveDocumentDir();
+ waitingUrl = QString::null;
+ }
+ // else set waiting url
+ else {
+ KURL u = mainwin->activeDocumentUrl();
+ if (!u.isEmpty())
+ waitingUrl = u.directory();
+ }
+ }
+
+ // TODO: make sure the button is disabled if the directory is unreadable, eg
+ // the document URL has protocol http
+ acSyncDir->setEnabled( ! mainwin->activeDocumentUrl().directory().isEmpty() );
+}
+
+void KateFileSelector::selectorViewChanged( KFileView * newView )
+{
+ newView->setSelectionMode(KFile::Extended);
+}
+
+//END Private Slots
+
+//BEGIN Protected
+
+void KateFileSelector::focusInEvent( QFocusEvent * )
+{
+ dir->setFocus();
+}
+
+void KateFileSelector::showEvent( QShowEvent * )
+{
+ // sync if we should
+ if ( autoSyncEvents & GotVisible ) {
+// kdDebug(13001)<<"syncing fs on show"<<endl;
+ setActiveDocumentDir();
+ waitingUrl = QString::null;
+ }
+ // else, if we have a waiting URL set it
+ else if ( ! waitingUrl.isEmpty() ) {
+ setDir( waitingUrl );
+ waitingUrl = QString::null;
+ }
+}
+
+bool KateFileSelector::eventFilter( QObject* o, QEvent *e )
+{
+ /*
+ This is rather unfortunate, but:
+ QComboBox does not support setting the size of the listbox to something
+ reasonable. Even using listbox->setVariableWidth() does not yield a
+ satisfying result, something is wrong with the handling of the sizehint.
+ And the popup is rather useless, if the paths are only partly visible.
+ */
+ QListBox *lb = cmbPath->listBox();
+ if ( o == lb && e->type() == QEvent::Show ) {
+ int add = lb->height() < lb->contentsHeight() ? lb->verticalScrollBar()->width() : 0;
+ int w = QMIN( mainwin->width(), lb->contentsWidth() + add );
+ lb->resize( w, lb->height() );
+ // TODO - move the listbox to a suitable place if nessecary
+ // TODO - decide if it is worth caching the size while untill the contents
+ // are changed.
+ }
+ // TODO - same thing for the completion popup?
+ return QWidget::eventFilter( o, e );
+}
+
+//END Protected
+
+//BEGIN ACtionLBItem
+/*
+ QListboxItem that can store and return a string,
+ used for the toolbar action selector.
+*/
+class ActionLBItem : public QListBoxPixmap {
+ public:
+ ActionLBItem( QListBox *lb=0,
+ const QPixmap &pm = QPixmap(),
+ const QString &text=QString::null,
+ const QString &str=QString::null ) :
+ QListBoxPixmap( lb, pm, text ),
+ _str(str) {};
+ QString idstring() { return _str; };
+ private:
+ QString _str;
+};
+//END ActionLBItem
+
+//BEGIN KFSConfigPage
+////////////////////////////////////////////////////////////////////////////////
+// KFSConfigPage implementation
+////////////////////////////////////////////////////////////////////////////////
+KFSConfigPage::KFSConfigPage( QWidget *parent, const char *name, KateFileSelector *kfs )
+ : Kate::ConfigPage( parent, name ),
+ fileSelector( kfs ),
+ m_changed( false )
+{
+ QVBoxLayout *lo = new QVBoxLayout( this );
+ int spacing = KDialog::spacingHint();
+ lo->setSpacing( spacing );
+
+ // Toolbar - a lot for a little...
+ QGroupBox *gbToolbar = new QGroupBox( 1, Qt::Vertical, i18n("Toolbar"), this );
+ acSel = new KActionSelector( gbToolbar );
+ acSel->setAvailableLabel( i18n("A&vailable actions:") );
+ acSel->setSelectedLabel( i18n("S&elected actions:") );
+ lo->addWidget( gbToolbar );
+ connect( acSel, SIGNAL( added( QListBoxItem * ) ), this, SLOT( slotMyChanged() ) );
+ connect( acSel, SIGNAL( removed( QListBoxItem * ) ), this, SLOT( slotMyChanged() ) );
+ connect( acSel, SIGNAL( movedUp( QListBoxItem * ) ), this, SLOT( slotMyChanged() ) );
+ connect( acSel, SIGNAL( movedDown( QListBoxItem * ) ), this, SLOT( slotMyChanged() ) );
+
+ // Sync
+ QGroupBox *gbSync = new QGroupBox( 1, Qt::Horizontal, i18n("Auto Synchronization"), this );
+ cbSyncActive = new QCheckBox( i18n("When a docu&ment becomes active"), gbSync );
+ cbSyncShow = new QCheckBox( i18n("When the file selector becomes visible"), gbSync );
+ lo->addWidget( gbSync );
+ connect( cbSyncActive, SIGNAL( toggled( bool ) ), this, SLOT( slotMyChanged() ) );
+ connect( cbSyncShow, SIGNAL( toggled( bool ) ), this, SLOT( slotMyChanged() ) );
+
+ // Histories
+ QHBox *hbPathHist = new QHBox ( this );
+ QLabel *lbPathHist = new QLabel( i18n("Remember &locations:"), hbPathHist );
+ sbPathHistLength = new QSpinBox( hbPathHist );
+ lbPathHist->setBuddy( sbPathHistLength );
+ lo->addWidget( hbPathHist );
+ connect( sbPathHistLength, SIGNAL( valueChanged ( int ) ), this, SLOT( slotMyChanged() ) );
+
+ QHBox *hbFilterHist = new QHBox ( this );
+ QLabel *lbFilterHist = new QLabel( i18n("Remember &filters:"), hbFilterHist );
+ sbFilterHistLength = new QSpinBox( hbFilterHist );
+ lbFilterHist->setBuddy( sbFilterHistLength );
+ lo->addWidget( hbFilterHist );
+ connect( sbFilterHistLength, SIGNAL( valueChanged ( int ) ), this, SLOT( slotMyChanged() ) );
+
+ // Session
+ QGroupBox *gbSession = new QGroupBox( 1, Qt::Horizontal, i18n("Session"), this );
+ cbSesLocation = new QCheckBox( i18n("Restore loca&tion"), gbSession );
+ cbSesFilter = new QCheckBox( i18n("Restore last f&ilter"), gbSession );
+ lo->addWidget( gbSession );
+ connect( cbSesLocation, SIGNAL( toggled( bool ) ), this, SLOT( slotMyChanged() ) );
+ connect( cbSesFilter, SIGNAL( toggled( bool ) ), this, SLOT( slotMyChanged() ) );
+
+ // make it look nice
+ lo->addStretch( 1 );
+
+ // be helpfull
+ /*
+ QWhatsThis::add( lbAvailableActions, i18n(
+ "<p>Available actions for the toolbar. To add an action, select it here "
+ "and press the add (<strong>-&gt;</strong>) button" ) );
+ QWhatsThis::add( lbUsedActions, i18n(
+ "<p>Actions used in the toolbar. To remove an action, select it and "
+ "press the remove (<strong>&lt;-</strong>) button."
+ "<p>To change the order of the actions, use the Up and Down buttons to "
+ "move the selected action.") );
+ */
+ QString lhwt( i18n(
+ "<p>Decides how many locations to keep in the history of the location "
+ "combo box.") );
+ QWhatsThis::add( lbPathHist, lhwt );
+ QWhatsThis::add( sbPathHistLength, lhwt );
+ QString fhwt( i18n(
+ "<p>Decides how many filters to keep in the history of the filter "
+ "combo box.") );
+ QWhatsThis::add( lbFilterHist, fhwt );
+ QWhatsThis::add( sbFilterHistLength, fhwt );
+ QString synwt( i18n(
+ "<p>These options allow you to have the File Selector automatically "
+ "change location to the folder of the active document on certain "
+ "events."
+ "<p>Auto synchronization is <em>lazy</em>, meaning it will not take "
+ "effect until the file selector is visible."
+ "<p>None of these are enabled by default, but you can always sync the "
+ "location by pressing the sync button in the toolbar.") );
+ QWhatsThis::add( gbSync, synwt );
+ QWhatsThis::add( cbSesLocation, i18n(
+ "<p>If this option is enabled (default), the location will be restored "
+ "when you start Kate.<p><strong>Note</strong> that if the session is "
+ "handled by the KDE session manager, the location is always restored.") );
+ QWhatsThis::add( cbSesFilter, i18n(
+ "<p>If this option is enabled (default), the current filter will be "
+ "restored when you start Kate.<p><strong>Note</strong> that if the "
+ "session is handled by the KDE session manager, the filter is always "
+ "restored."
+ "<p><strong>Note</strong> that some of the autosync settings may "
+ "override the restored location if on.") );
+
+ init();
+
+}
+
+void KFSConfigPage::apply()
+{
+ if ( ! m_changed )
+ return;
+
+ m_changed = false;
+
+ KConfig *config = kapp->config();
+ config->setGroup( "fileselector" );
+ // toolbar
+ QStringList l;
+ QListBoxItem *item = acSel->selectedListBox()->firstItem();
+ ActionLBItem *aItem;
+ while ( item )
+ {
+ aItem = (ActionLBItem*)item;
+ if ( aItem )
+ {
+ l << aItem->idstring();
+ }
+ item = item->next();
+ }
+ config->writeEntry( "toolbar actions", l );
+ fileSelector->setupToolbar( config );
+ // sync
+ int s = 0;
+ if ( cbSyncActive->isChecked() )
+ s |= KateFileSelector::DocumentChanged;
+ if ( cbSyncShow->isChecked() )
+ s |= KateFileSelector::GotVisible;
+ fileSelector->autoSyncEvents = s;
+
+ // histories
+ fileSelector->cmbPath->setMaxItems( sbPathHistLength->value() );
+ fileSelector->filter->setMaxCount( sbFilterHistLength->value() );
+ // session - theese are read/written directly to the app config,
+ // as they are not needed during operation.
+ config->writeEntry( "restore location", cbSesLocation->isChecked() );
+ config->writeEntry( "restore last filter", cbSesFilter->isChecked() );
+}
+
+void KFSConfigPage::reload()
+{
+ // hmm, what is this supposed to do, actually??
+ init();
+ m_changed = false;
+}
+void KFSConfigPage::init()
+{
+ KConfig *config = kapp->config();
+ config->setGroup( "fileselector" );
+ // toolbar
+ QStringList l = config->readListEntry( "toolbar actions", ',' );
+ if ( l.isEmpty() ) // default toolbar
+ l << "up" << "back" << "forward" << "home" <<
+ "short view" << "detailed view" <<
+ "bookmarks" << "sync_dir";
+
+ // actions from diroperator + two of our own
+ QStringList allActions;
+ allActions << "up" << "back" << "forward" << "home" <<
+ "reload" << "mkdir" << "delete" <<
+ "short view" << "detailed view" /*<< "view menu" <<
+ "show hidden" << "properties"*/ <<
+ "bookmarks" << "sync_dir";
+ QRegExp re("&(?=[^&])");
+ KAction *ac;
+ QListBox *lb;
+ for ( QStringList::Iterator it=allActions.begin(); it != allActions.end(); ++it ) {
+ lb = l.contains( *it ) ? acSel->selectedListBox() : acSel->availableListBox();
+ if ( *it == "bookmarks" || *it == "sync_dir" )
+ ac = fileSelector->actionCollection()->action( (*it).latin1() );
+ else
+ ac = fileSelector->dirOperator()->actionCollection()->action( (*it).latin1() );
+ if ( ac )
+ new ActionLBItem( lb, SmallIcon( ac->icon() ), ac->text().replace( re, "" ), *it );
+ }
+
+ // sync
+ int s = fileSelector->autoSyncEvents;
+ cbSyncActive->setChecked( s & KateFileSelector::DocumentChanged );
+ cbSyncShow->setChecked( s & KateFileSelector::GotVisible );
+ // histories
+ sbPathHistLength->setValue( fileSelector->cmbPath->maxItems() );
+ sbFilterHistLength->setValue( fileSelector->filter->maxCount() );
+ // session
+ cbSesLocation->setChecked( config->readBoolEntry( "restore location", true ) );
+ cbSesFilter->setChecked( config->readBoolEntry( "restore last filter", true ) );
+}
+
+void KFSConfigPage::slotMyChanged()
+{
+ m_changed = true;
+ slotChanged();
+}
+//END KFSConfigPage
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/katefileselector.h b/kate/app/katefileselector.h
new file mode 100644
index 000000000..0bab4c257
--- /dev/null
+++ b/kate/app/katefileselector.h
@@ -0,0 +1,172 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KATE_FILESELECTOR_H__
+#define __KATE_FILESELECTOR_H__
+
+#include "katemain.h"
+#include "katedocmanager.h"
+#include <kate/document.h>
+
+#include <qvbox.h>
+#include <kfile.h>
+#include <kurl.h>
+#include <ktoolbar.h>
+#include <qframe.h>
+
+class KateMainWindow;
+class KateViewManager;
+class KActionCollection;
+class KActionSelector;
+class KFileView;
+
+/*
+ The kate file selector presents a directory view, in which the default action is
+ to open the activated file.
+ Additinally, a toolbar for managing the kdiroperator widget + sync that to
+ the directory of the current file is available, as well as a filter widget
+ allowing to filter the displayed files using a name filter.
+*/
+
+/* I think this fix for not moving toolbars is better */
+class KateFileSelectorToolBar: public KToolBar
+{
+ Q_OBJECT
+public:
+ KateFileSelectorToolBar(QWidget *parent);
+ virtual ~KateFileSelectorToolBar();
+
+ virtual void setMovingEnabled( bool b );
+};
+
+class KateFileSelectorToolBarParent: public QFrame
+{
+ Q_OBJECT
+public:
+ KateFileSelectorToolBarParent(QWidget *parent);
+ ~KateFileSelectorToolBarParent();
+ void setToolBar(KateFileSelectorToolBar *tb);
+private:
+ KateFileSelectorToolBar *m_tb;
+protected:
+ virtual void resizeEvent ( QResizeEvent * );
+};
+
+class KateFileSelector : public QVBox
+{
+ Q_OBJECT
+
+ friend class KFSConfigPage;
+
+ public:
+ /* When to sync to current document directory */
+ enum AutoSyncEvent { DocumentChanged=1, GotVisible=2 };
+
+ KateFileSelector( KateMainWindow *mainWindow=0, KateViewManager *viewManager=0,
+ QWidget * parent = 0, const char * name = 0 );
+ ~KateFileSelector();
+
+ void readConfig( KConfig *, const QString & );
+ void writeConfig( KConfig *, const QString & );
+ void setupToolbar( KConfig * );
+ void setView( KFile::FileView );
+ KDirOperator *dirOperator(){ return dir; }
+ KActionCollection *actionCollection() { return mActionCollection; };
+
+ public slots:
+ void slotFilterChange(const QString&);
+ void setDir(KURL);
+ void setDir( const QString& url ) { setDir( KURL( url ) ); };
+ void kateViewChanged();
+ void selectorViewChanged( KFileView * );
+
+ private slots:
+ void cmbPathActivated( const KURL& u );
+ void cmbPathReturnPressed( const QString& u );
+ void dirUrlEntered( const KURL& u );
+ void dirFinishedLoading();
+ void setActiveDocumentDir();
+ void btnFilterClick();
+
+ protected:
+ void focusInEvent( QFocusEvent * );
+ void showEvent( QShowEvent * );
+ bool eventFilter( QObject *, QEvent * );
+ void initialDirChangeHack();
+
+ private:
+ class KateFileSelectorToolBar *toolbar;
+ KActionCollection *mActionCollection;
+ class KBookmarkHandler *bookmarkHandler;
+ KURLComboBox *cmbPath;
+ KDirOperator * dir;
+ class KAction *acSyncDir;
+ KHistoryCombo * filter;
+ class QToolButton *btnFilter;
+
+ KateMainWindow *mainwin;
+ KateViewManager *viewmanager;
+
+ QString lastFilter;
+ int autoSyncEvents; // enabled autosync events
+ QString waitingUrl; // maybe display when we gets visible
+ QString waitingDir;
+};
+
+/* TODO anders
+ KFSFilterHelper
+ A popup widget presenting a listbox with checkable items
+ representing the mime types available in the current directory, and
+ providing a name filter based on those.
+*/
+
+/*
+ Config page for file selector.
+ Allows for configuring the toolbar, the history length
+ of the path and file filter combos, and how to handle
+ user closed session.
+*/
+class KFSConfigPage : public Kate::ConfigPage {
+ Q_OBJECT
+ public:
+ KFSConfigPage( QWidget* parent=0, const char *name=0, KateFileSelector *kfs=0);
+ virtual ~KFSConfigPage() {};
+
+ virtual void apply();
+ virtual void reload();
+
+ private slots:
+ void slotMyChanged();
+
+ private:
+ void init();
+
+ KateFileSelector *fileSelector;
+ KActionSelector *acSel;
+ class QSpinBox *sbPathHistLength, *sbFilterHistLength;
+ class QCheckBox *cbSyncActive, *cbSyncShow;
+ class QCheckBox *cbSesLocation, *cbSesFilter;
+
+ bool m_changed;
+};
+
+
+#endif //__KATE_FILESELECTOR_H__
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/kategrepdialog.cpp b/kate/app/kategrepdialog.cpp
new file mode 100644
index 000000000..8816862de
--- /dev/null
+++ b/kate/app/kategrepdialog.cpp
@@ -0,0 +1,544 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001, 2004 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ 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 "kategrepdialog.h"
+#include "katemainwindow.h"
+
+#include <qobject.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qevent.h>
+#include <qlistbox.h>
+#include <qregexp.h>
+#include <qwhatsthis.h>
+#include <qcursor.h>
+
+#include <kapplication.h>
+#include <kaccelmanager.h>
+#include <kbuttonbox.h>
+#include <kfiledialog.h>
+#include <kprocess.h>
+#include <kapplication.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kpushbutton.h>
+#include <kurlrequester.h>
+#include <kurlcompletion.h>
+#include <kcombobox.h>
+#include <klineedit.h>
+
+const char *template_desc[] = {
+ "normal",
+ "assignment",
+ "->MEMBER(",
+ "class::MEMBER(",
+ "OBJECT->member(",
+ 0
+};
+
+const char *strTemplate[] = {
+ "%s",
+ "\\<%s\\>[\t ]*=[^=]",
+ "\\->[\\t ]*\\<%s\\>[\\t ]*(",
+ "[a-z0-9_$]\\+[\\t ]*::[\\t ]*\\<%s\\>[\\t ]*(",
+ "\\<%s\\>[\\t ]*\\->[\\t ]*[a-z0-9_$]\\+[\\t ]*(",
+ 0
+};
+
+
+GrepTool::GrepTool(QWidget *parent, const char *name)
+ : QWidget(parent, name/*, false*/), m_fixFocus(true), childproc(0)
+{
+ setCaption(i18n("Find in Files"));
+ config = KGlobal::config();
+ config->setGroup("GrepTool");
+ lastSearchItems = config->readListEntry("LastSearchItems");
+ lastSearchPaths = config->readListEntry("LastSearchPaths");
+ lastSearchFiles = config->readListEntry("LastSearchFiles");
+
+ if( lastSearchFiles.isEmpty() )
+ {
+ // if there are no entries, most probably the first Kate start.
+ // Initialize with default values.
+ lastSearchFiles << "*.h,*.hxx,*.cpp,*.cc,*.C,*.cxx,*.idl,*.c"
+ << "*.cpp,*.cc,*.C,*.cxx,*.c"
+ << "*.h,*.hxx,*.idl"
+ << "*";
+ }
+
+ QGridLayout *layout = new QGridLayout(this, 6, 3, 4, 4);
+ layout->setColStretch(0, 10);
+ layout->addColSpacing(1, 10);
+ layout->setColStretch(1, 0);
+ layout->setColStretch(2, 1);
+ layout->setRowStretch(1, 0);
+ layout->setRowStretch(2, 10);
+ layout->setRowStretch(4, 0);
+
+ QGridLayout *loInput = new QGridLayout(4, 2, 4);
+ layout->addLayout(loInput, 0, 0);
+ loInput->setColStretch(0, 0);
+ loInput->setColStretch(1, 20);
+
+ QLabel *lPattern = new QLabel(i18n("Pattern:"), this);
+ lPattern->setFixedSize(lPattern->sizeHint());
+ loInput->addWidget(lPattern, 0, 0, AlignRight | AlignVCenter);
+
+ QBoxLayout *loPattern = new QHBoxLayout( 4 );
+ loInput->addLayout( loPattern, 0, 1 );
+ cmbPattern = new KComboBox(true, this);
+ cmbPattern->setDuplicatesEnabled(false);
+ cmbPattern->insertStringList(lastSearchItems);
+ cmbPattern->setEditText(QString::null);
+ cmbPattern->setInsertionPolicy(QComboBox::NoInsertion);
+ lPattern->setBuddy(cmbPattern);
+ cmbPattern->setFocus();
+ cmbPattern->setMinimumSize(cmbPattern->sizeHint());
+ loPattern->addWidget( cmbPattern );
+
+ cbCasesensitive = new QCheckBox(i18n("Case sensitive"), this);
+ cbCasesensitive->setMinimumWidth(cbCasesensitive->sizeHint().width());
+ cbCasesensitive->setChecked(config->readBoolEntry("CaseSensitive", true));
+ loPattern->addWidget(cbCasesensitive);
+
+ cbRegex = new QCheckBox( i18n("Regular expression"), this );
+ cbRegex->setMinimumWidth( cbRegex->sizeHint().width() );
+ cbRegex->setChecked( config->readBoolEntry( "Regex", true ) );
+ loPattern->addWidget( cbRegex );
+ loPattern->setStretchFactor( cmbPattern, 100 );
+
+ QLabel *lTemplate = new QLabel(i18n("Template:"), this);
+ lTemplate->setFixedSize(lTemplate->sizeHint());
+ loInput->addWidget(lTemplate, 1, 0, AlignRight | AlignVCenter);
+
+ QBoxLayout *loTemplate = new QHBoxLayout(4);
+ loInput->addLayout(loTemplate, 1, 1);
+
+ leTemplate = new KLineEdit(this);
+ lTemplate->setBuddy(leTemplate);
+ leTemplate->setText(strTemplate[0]);
+ leTemplate->setMinimumSize(leTemplate->sizeHint());
+ loTemplate->addWidget(leTemplate);
+
+ KComboBox *cmbTemplate = new KComboBox(false, this);
+ cmbTemplate->insertStrList(template_desc);
+ cmbTemplate->adjustSize();
+ cmbTemplate->setFixedSize(cmbTemplate->size());
+ loTemplate->addWidget(cmbTemplate);
+
+ QLabel *lFiles = new QLabel(i18n("Files:"), this);
+ lFiles->setFixedSize(lFiles->sizeHint());
+ loInput->addWidget(lFiles, 2, 0, AlignRight | AlignVCenter);
+
+ cmbFiles = new KComboBox(true, this);
+ lFiles->setBuddy(cmbFiles->focusProxy());
+ cmbFiles->setMinimumSize(cmbFiles->sizeHint());
+ cmbFiles->setInsertionPolicy(QComboBox::NoInsertion);
+ cmbFiles->setDuplicatesEnabled(false);
+ cmbFiles->insertStringList(lastSearchFiles);
+ loInput->addWidget(cmbFiles, 2, 1);
+
+ QLabel *lDir = new QLabel(i18n("Folder:"), this);
+ lDir->setFixedSize(lDir->sizeHint());
+ loInput->addWidget(lDir, 3, 0, AlignRight | AlignVCenter);
+
+ QBoxLayout *loDir = new QHBoxLayout(3);
+ loInput->addLayout(loDir, 3, 1);
+
+ KComboBox* cmbUrl = new KComboBox(true, this);
+ cmbUrl->setMinimumWidth(80); // make sure that 800x600 res works
+ cmbUrl->setDuplicatesEnabled(false);
+ cmbUrl->setInsertionPolicy(QComboBox::NoInsertion);
+ cmbDir = new KURLRequester( cmbUrl, this, "dir combo" );
+ cmbDir->completionObject()->setMode(KURLCompletion::DirCompletion);
+ cmbDir->comboBox()->insertStringList(lastSearchPaths);
+ cmbDir->setMode( KFile::Directory|KFile::LocalOnly );
+ loDir->addWidget(cmbDir, 1);
+ lDir->setBuddy(cmbDir);
+
+ cbRecursive = new QCheckBox(i18n("Recursive"), this);
+ cbRecursive->setMinimumWidth(cbRecursive->sizeHint().width());
+ cbRecursive->setChecked(config->readBoolEntry("Recursive", true));
+ loDir->addWidget(cbRecursive);
+
+ KButtonBox *actionbox = new KButtonBox(this, Qt::Vertical);
+ layout->addWidget(actionbox, 0, 2);
+ actionbox->addStretch();
+ btnSearch = static_cast<KPushButton*>(actionbox->addButton(KGuiItem(i18n("Find"),"find")));
+ btnSearch->setDefault(true);
+ btnClear = static_cast<KPushButton*>(actionbox->addButton( KStdGuiItem::clear() ));
+ actionbox->addStretch();
+ actionbox->layout();
+
+ lbResult = new QListBox(this);
+ QFontMetrics rb_fm(lbResult->fontMetrics());
+ layout->addMultiCellWidget(lbResult, 2, 2, 0, 2);
+
+ layout->activate();
+
+ KAcceleratorManager::manage( this );
+
+ QWhatsThis::add(lPattern,
+ i18n("<p>Enter the expression you want to search for here."
+ "<p>If 'regular expression' is unchecked, any non-space letters in your "
+ "expression will be escaped with a backslash character."
+ "<p>Possible meta characters are:<br>"
+ "<b>.</b> - Matches any character<br>"
+ "<b>^</b> - Matches the beginning of a line<br>"
+ "<b>$</b> - Matches the end of a line<br>"
+ "<b>\\&lt;</b> - Matches the beginning of a word<br>"
+ "<b>\\&gt;</b> - Matches the end of a word"
+ "<p>The following repetition operators exist:<br>"
+ "<b>?</b> - The preceding item is matched at most once<br>"
+ "<b>*</b> - The preceding item is matched zero or more times<br>"
+ "<b>+</b> - The preceding item is matched one or more times<br>"
+ "<b>{<i>n</i>}</b> - The preceding item is matched exactly <i>n</i> times<br>"
+ "<b>{<i>n</i>,}</b> - The preceding item is matched <i>n</i> or more times<br>"
+ "<b>{,<i>n</i>}</b> - The preceding item is matched at most <i>n</i> times<br>"
+ "<b>{<i>n</i>,<i>m</i>}</b> - The preceding item is matched at least <i>n</i>, "
+ "but at most <i>m</i> times."
+ "<p>Furthermore, backreferences to bracketed subexpressions are available "
+ "via the notation <code>\\#</code>."
+ "<p>See the grep(1) documentation for the full documentation."
+ ));
+ QWhatsThis::add(lFiles,
+ i18n("Enter the file name pattern of the files to search here.\n"
+ "You may give several patterns separated by commas."));
+ QWhatsThis::add(lTemplate,
+ i18n("You can choose a template for the pattern from the combo box\n"
+ "and edit it here. The string %s in the template is replaced\n"
+ "by the pattern input field, resulting in the regular expression\n"
+ "to search for."));
+ QWhatsThis::add(lDir,
+ i18n("Enter the folder which contains the files in which you want to search."));
+ QWhatsThis::add(cbRecursive,
+ i18n("Check this box to search in all subfolders."));
+ QWhatsThis::add(cbCasesensitive,
+ i18n("If this option is enabled (the default), the search will be case sensitive."));
+ QWhatsThis::add( cbRegex, i18n(
+ "<p>If this is enabled, your pattern will be passed unmodified to "
+ "<em>grep(1)</em>. Otherwise, all characters that are not letters will be "
+ "escaped using a backslash character to prevent grep from interpreting "
+ "them as part of the expression.") );
+ QWhatsThis::add(lbResult,
+ i18n("The results of the grep run are listed here. Select a\n"
+ "filename/line number combination and press Enter or doubleclick\n"
+ "on the item to show the respective line in the editor."));
+
+ // event filter, do something relevant for RETURN
+ cmbPattern->installEventFilter( this );
+ leTemplate->installEventFilter( this );
+ cmbFiles->installEventFilter( this );
+ cmbDir->comboBox()->installEventFilter( this );
+
+ connect( cmbTemplate, SIGNAL(activated(int)),
+ SLOT(templateActivated(int)) );
+ connect( lbResult, SIGNAL(selected(const QString&)),
+ SLOT(itemSelected(const QString&)) );
+ connect( btnSearch, SIGNAL(clicked()),
+ SLOT(slotSearch()) );
+ connect( btnClear, SIGNAL(clicked()),
+ SLOT(slotClear()) );
+ connect( cmbPattern->lineEdit(), SIGNAL(textChanged ( const QString & )),
+ SLOT( patternTextChanged( const QString & )));
+
+ patternTextChanged( cmbPattern->lineEdit()->text());
+}
+
+
+GrepTool::~GrepTool()
+{
+ delete childproc;
+}
+
+void GrepTool::patternTextChanged( const QString & _text)
+{
+ btnSearch->setEnabled( !_text.isEmpty() );
+}
+
+void GrepTool::templateActivated(int index)
+{
+ leTemplate->setText(strTemplate[index]);
+}
+
+void GrepTool::itemSelected(const QString& item)
+{
+ int pos;
+ QString filename, linenumber;
+
+ QString str = item;
+ if ( (pos = str.find(':')) != -1)
+ {
+ filename = str.left(pos);
+ str = str.mid(pos+1);
+ if ( (pos = str.find(':')) != -1)
+ {
+ filename = m_workingDir + QDir::separator() + filename;
+ linenumber = str.left(pos);
+ emit itemSelected(filename,linenumber.toInt()-1);
+ }
+ }
+}
+
+void GrepTool::processOutput()
+{
+ int pos;
+ while ( (pos = buf.find('\n')) != -1)
+ {
+ QString item = buf.mid(2,pos-2);
+ if (!item.isEmpty())
+ lbResult->insertItem(item);
+ buf = buf.mid(pos+1);
+ }
+ kapp->processEvents();
+}
+
+void GrepTool::slotSearch()
+{
+ if ( cmbPattern->currentText().isEmpty() )
+ {
+ cmbPattern->setFocus();
+ return;
+ }
+
+ if ( cmbDir->url().isEmpty() || ! QDir(cmbDir->url()).exists() )
+ {
+ cmbDir->setFocus();
+ KMessageBox::information( this, i18n(
+ "You must enter an existing local folder in the 'Folder' entry."),
+ i18n("Invalid Folder"), "Kate grep tool: invalid folder" );
+ return;
+ }
+
+ if ( ! leTemplate->text().contains("%s") )
+ {
+ leTemplate->setFocus();
+ return;
+ }
+
+ if ( childproc && childproc->isRunning() )
+ {
+ childproc->kill();
+ return;
+ }
+
+ slotClear ();
+
+ m_workingDir = cmbDir->url();
+
+ QString s = cmbPattern->currentText();
+ if ( ! cbRegex->isChecked() )
+ s.replace( QRegExp( "([^\\w'()<>])" ), "\\\\1" );
+ QString pattern = leTemplate->text();
+ pattern.replace( "%s", s );
+
+ childproc = new KProcess();
+ childproc->setWorkingDirectory( m_workingDir );
+ *childproc << "find" << ".";
+ if (!cbRecursive->isChecked())
+ *childproc << "-maxdepth" << "1";
+ if (!cmbFiles->currentText().isEmpty() )
+ {
+ QStringList files = QStringList::split ( ",", cmbFiles->currentText(), FALSE );
+ *childproc << "(";
+ bool first = true;
+ for ( QStringList::Iterator it = files.begin(); it != files.end(); ++it )
+ {
+ if (!first)
+ *childproc << "-o";
+ *childproc << "-name" << (*it);
+ first = false;
+ }
+ *childproc << ")";
+ }
+ *childproc << "-exec" << "grep";
+ if (!cbCasesensitive->isChecked())
+ *childproc << "-i";
+ *childproc << "-n" << "-e" << pattern << "{}";
+ *childproc << "/dev/null"; //trick to have grep always display the filename
+ *childproc << ";";
+
+ connect( childproc, SIGNAL(processExited(KProcess *)),
+ SLOT(childExited()) );
+ connect( childproc, SIGNAL(receivedStdout(KProcess *, char *, int)),
+ SLOT(receivedOutput(KProcess *, char *, int)) );
+ connect( childproc, SIGNAL(receivedStderr(KProcess *, char *, int)),
+ SLOT(receivedErrOutput(KProcess *, char *, int)) );
+
+ // actually it should be checked whether the process was started successfully
+ lbResult->setCursor( QCursor(Qt::WaitCursor) );
+ btnClear->setEnabled( false );
+ btnSearch->setGuiItem( KGuiItem(i18n("Cancel"), "button_cancel"));
+ childproc->start(KProcess::NotifyOnExit, KProcess::AllOutput);
+}
+
+void GrepTool::slotSearchFor(const QString &pattern)
+{
+ slotClear();
+ cmbPattern->setEditText(pattern);
+ slotSearch();
+}
+
+void GrepTool::finish()
+{
+ btnSearch->setEnabled( !cmbPattern->lineEdit()->text().isEmpty() );
+
+ buf += '\n';
+ processOutput();
+ delete childproc;
+ childproc = 0;
+
+ config->setGroup("GrepTool");
+
+ QString cmbText = cmbPattern->currentText();
+ bool itemsRemoved = lastSearchItems.remove(cmbText) > 0;
+ lastSearchItems.prepend(cmbText);
+ if (itemsRemoved)
+ {
+ cmbPattern->removeItem(cmbPattern->currentItem());
+ }
+ cmbPattern->insertItem(cmbText, 0);
+ cmbPattern->setCurrentItem(0);
+ if (lastSearchItems.count() > 10) {
+ lastSearchItems.pop_back();
+ cmbPattern->removeItem(cmbPattern->count() - 1);
+ }
+ config->writeEntry("LastSearchItems", lastSearchItems);
+
+
+ cmbText = cmbDir->url();
+ itemsRemoved = lastSearchPaths.remove(cmbText) > 0;
+ lastSearchPaths.prepend(cmbText);
+ if (itemsRemoved)
+ {
+ cmbDir->comboBox()->removeItem(cmbDir->comboBox()->currentItem());
+ }
+ cmbDir->comboBox()->insertItem(cmbText, 0);
+ cmbDir->comboBox()->setCurrentItem(0);
+ if (lastSearchPaths.count() > 10)
+ {
+ lastSearchPaths.pop_back();
+ cmbDir->comboBox()->removeItem(cmbDir->comboBox()->count() - 1);
+ }
+ config->writeEntry("LastSearchPaths", lastSearchPaths);
+
+
+ cmbText = cmbFiles->currentText();
+ itemsRemoved = lastSearchFiles.remove(cmbText) > 0;
+ lastSearchFiles.prepend(cmbText);
+ if (itemsRemoved)
+ {
+ cmbFiles->removeItem(cmbFiles->currentItem());
+ }
+ cmbFiles->insertItem(cmbText, 0);
+ cmbFiles->setCurrentItem(0);
+ if (lastSearchFiles.count() > 10) {
+ lastSearchFiles.pop_back();
+ cmbFiles->removeItem(cmbFiles->count() - 1);
+ }
+ config->writeEntry("LastSearchFiles", lastSearchFiles);
+
+ config->writeEntry("Recursive", cbRecursive->isChecked());
+ config->writeEntry("CaseSensitive", cbCasesensitive->isChecked());
+ config->writeEntry("Regex", cbRegex->isChecked());
+}
+
+void GrepTool::slotCancel()
+{
+ finish();
+}
+
+void GrepTool::childExited()
+{
+// int status = childproc->exitStatus();
+ lbResult->unsetCursor();
+ btnClear->setEnabled( true );
+ btnSearch->setGuiItem( KGuiItem(i18n("Find"), "find") );
+
+ if ( ! errbuf.isEmpty() )
+ {
+ KMessageBox::information( parentWidget(), i18n("<strong>Error:</strong><p>") + errbuf, i18n("Grep Tool Error") );
+ errbuf.truncate(0);
+ }
+ else
+ finish();
+}
+
+void GrepTool::receivedOutput(KProcess */*proc*/, char *buffer, int buflen)
+{
+ buf += QCString(buffer, buflen+1);
+ processOutput();
+}
+
+void GrepTool::receivedErrOutput(KProcess */*proc*/, char *buffer, int buflen)
+{
+ errbuf += QCString( buffer, buflen + 1 );
+}
+
+void GrepTool::slotClear()
+{
+ finish();
+ lbResult->clear();
+}
+
+void GrepTool::updateDirName(const QString &dir)
+{
+ if (m_lastUpdatedDir != dir)
+ {
+ setDirName (dir);
+ m_lastUpdatedDir = dir;
+ }
+}
+
+void GrepTool::setDirName(const QString &dir){
+ cmbDir->setURL(dir);
+}
+
+bool GrepTool::eventFilter( QObject *o, QEvent *e )
+{
+ if ( e->type() == QEvent::KeyPress && (
+ ((QKeyEvent*)e)->key() == Qt::Key_Return ||
+ ((QKeyEvent*)e)->key() == Qt::Key_Enter ) )
+ {
+ slotSearch();
+ return true;
+ }
+
+ return QWidget::eventFilter( o, e );
+}
+
+void GrepTool::focusInEvent ( QFocusEvent * ev )
+{
+ QWidget::focusInEvent(ev);
+ if (m_fixFocus) {
+ m_fixFocus = false;
+ cmbPattern->setFocus();
+ }
+}
+
+void GrepTool::showEvent( QShowEvent * ev )
+{
+ QWidget::showEvent(ev);
+ m_fixFocus = true;
+}
+
+#include "kategrepdialog.moc"
diff --git a/kate/app/kategrepdialog.h b/kate/app/kategrepdialog.h
new file mode 100644
index 000000000..5ed3b2b69
--- /dev/null
+++ b/kate/app/kategrepdialog.h
@@ -0,0 +1,97 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _GREPDIALOG_H_
+#define _GREPDIALOG_H_
+
+#include <kdialog.h>
+#include <qstringlist.h>
+
+class QLineEdit;
+class KComboBox;
+class QCheckBox;
+class QListBox;
+class KPushButton;
+class QLabel;
+class KProcess;
+class KConfig;
+class KURLRequester;
+class QEvent;
+
+class GrepTool : public QWidget
+{
+ Q_OBJECT
+
+public:
+ GrepTool(QWidget *parent, const char *name=0);
+ ~GrepTool();
+
+ // only updates if the dir you give to it differs from the last one given to it !
+ void updateDirName(const QString &);
+
+ void setDirName(const QString &);
+
+
+signals:
+ void itemSelected(const QString &abs_filename, int line);
+
+public slots:
+ void slotSearchFor(const QString &pattern);
+
+protected:
+ bool eventFilter( QObject *, QEvent * );
+ void focusInEvent ( QFocusEvent * );
+ void showEvent( QShowEvent * );
+ bool m_fixFocus;
+
+private slots:
+ void templateActivated(int index);
+ void childExited();
+ void receivedOutput(KProcess *proc, char *buffer, int buflen);
+ void receivedErrOutput(KProcess *proc, char *buffer, int buflen);
+ void itemSelected(const QString&);
+ void slotSearch();
+ void slotCancel();
+ void slotClear();
+ void patternTextChanged( const QString &);
+private:
+ void processOutput();
+ void finish();
+
+ QLineEdit *leTemplate;
+ KComboBox *cmbFiles, *cmbPattern;
+ KURLRequester *cmbDir;
+ QCheckBox *cbRecursive;
+ QCheckBox *cbCasesensitive, *cbRegex;
+ QListBox *lbResult;
+ KPushButton *btnSearch, *btnClear;
+ KProcess *childproc;
+ QString buf;
+ QString errbuf;
+ KConfig* config;
+ QStringList lastSearchItems;
+ QStringList lastSearchPaths;
+ QStringList lastSearchFiles;
+ QString m_lastUpdatedDir;
+ QString m_workingDir;
+};
+
+
+#endif
diff --git a/kate/app/katemailfilesdialog.cpp b/kate/app/katemailfilesdialog.cpp
new file mode 100644
index 000000000..03bd497df
--- /dev/null
+++ b/kate/app/katemailfilesdialog.cpp
@@ -0,0 +1,112 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ 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 "katemailfilesdialog.h"
+#include "katemainwindow.h"
+#include "kateviewmanager.h"
+#include "katedocmanager.h"
+
+#include <klistview.h>
+#include <klocale.h>
+#include <kurl.h>
+
+#include <qevent.h>
+#include <qlabel.h>
+#include <qstringlist.h>
+#include <qvbox.h>
+
+/* a private check list item, that can store a Kate::Document*. */
+class KateDocCheckItem : public QCheckListItem {
+ public:
+ KateDocCheckItem( QListView *parent, const QString& text, Kate::Document *d )
+ : QCheckListItem( parent, text, QCheckListItem::CheckBox ), mdoc(d) {};
+ Kate::Document *doc() { return mdoc; };
+ private:
+ Kate::Document *mdoc;
+};
+
+///////////////////////////////////////////////////////////////////////////
+// KateMailDialog implementation
+///////////////////////////////////////////////////////////////////////////
+KateMailDialog::KateMailDialog( QWidget *parent, KateMainWindow *mainwin )
+ : KDialogBase( parent, "kate mail dialog", true, i18n("Email Files"),
+ Ok|Cancel|User1, Ok, false,
+ KGuiItem( i18n("&Show All Documents >>") ) ),
+ mainWindow( mainwin )
+{
+ setButtonGuiItem( KDialogBase::Ok, KGuiItem( i18n("&Mail..."), "mail_send") );
+ mw = makeVBoxMainWidget();
+ mw->installEventFilter( this );
+
+ lInfo = new QLabel( i18n(
+ "<p>Press <strong>Mail...</strong> to email the current document."
+ "<p>To select more documents to send, press <strong>Show All Documents&nbsp;&gt;&gt;</strong>."), mw );
+ // TODO avoid untill needed - later
+ list = new KListView( mw );
+ list->addColumn( i18n("Name") );
+ list->addColumn( i18n("URL") );
+ Kate::Document *currentDoc = mainWindow->viewManager()->activeView()->getDoc();
+ uint n = KateDocManager::self()->documents();
+ uint i = 0;
+ QCheckListItem *item;
+ while ( i < n ) {
+ Kate::Document *doc = KateDocManager::self()->document( i );
+ if ( doc ) {
+ item = new KateDocCheckItem( list, doc->docName(), doc );
+ item->setText( 1, doc->url().prettyURL() );
+ if ( doc == currentDoc ) {
+ item->setOn( true );
+ item->setSelected( true );
+ }
+ }
+ i++;
+ }
+ list->hide();
+ connect( this, SIGNAL(user1Clicked()), this, SLOT(slotShowButton()) );
+ mw->setMinimumSize( lInfo->sizeHint() );
+}
+
+QPtrList<Kate::Document> KateMailDialog::selectedDocs()
+{
+ QPtrList<Kate::Document> l;
+ QListViewItem *item = list->firstChild();
+ while ( item ) {
+ if ( ((KateDocCheckItem*)item)->isOn() )
+ l.append( ((KateDocCheckItem*)item)->doc() );
+ item = item->nextSibling();
+ }
+ return l;
+}
+
+void KateMailDialog::slotShowButton()
+{
+ if ( list->isVisible() ) {
+ setButtonText( User1, i18n("&Show All Documents >>") );
+ list->hide();
+ }
+ else {
+ list->show();
+ setButtonText( User1, i18n("&Hide Document List <<") );
+ lInfo->setText( i18n("Press <strong>Mail...</strong> to send selected documents") );
+
+ }
+ mw->setMinimumSize( QSize( lInfo->sizeHint().width(), mw->sizeHint().height()) );
+ setMinimumSize( calculateSize( mw->minimumSize().width(), mw->sizeHint().height() ) );
+ resize( width(), minimumHeight() );
+}
+#include "katemailfilesdialog.moc"
diff --git a/kate/app/katemailfilesdialog.h b/kate/app/katemailfilesdialog.h
new file mode 100644
index 000000000..906cd99fa
--- /dev/null
+++ b/kate/app/katemailfilesdialog.h
@@ -0,0 +1,59 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _KATE_MAILFILES_DIALOG_H_
+#define _KATE_MAILFILES_DIALOG_H_
+
+#include <kate/document.h>
+
+#include <kdialogbase.h>
+#include <kurl.h>
+#include <qptrlist.h>
+
+class QString;
+class QStringList;
+class KateMainWindow;
+
+/**
+ This is a dialog for choosing which of the open files to mail.
+ The current file is selected by default, the dialog can be expanded
+ to display all the files if required.
+
+*/
+class KateMailDialog : public KDialogBase {
+ Q_OBJECT
+ public:
+ KateMailDialog( QWidget *parent=0,
+ KateMainWindow *mainwin=0 );
+ ~KateMailDialog() {};
+
+ /**
+ @return a list of the selected docs.
+ */
+ QPtrList<Kate::Document> selectedDocs();
+ private slots:
+ void slotShowButton();
+ private:
+ class KListView *list;
+ class QLabel *lInfo;
+ KateMainWindow *mainWindow;
+ class QVBox *mw;
+
+};
+
+#endif // _KATE_MAILFILES_DIALOG_H_
diff --git a/kate/app/katemain.cpp b/kate/app/katemain.cpp
new file mode 100644
index 000000000..892f49271
--- /dev/null
+++ b/kate/app/katemain.cpp
@@ -0,0 +1,256 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kateapp.h"
+
+#include <kstandarddirs.h>
+#include <klocale.h>
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <kglobal.h>
+#include <kconfig.h>
+#include <kinstance.h>
+#include <kstartupinfo.h>
+#include <dcopclient.h>
+#include <dcopref.h>
+#include <kdebug.h>
+
+#include <qtextcodec.h>
+
+#include <stdlib.h>
+
+static KCmdLineOptions options[] =
+{
+ { "s", 0 , 0 },
+ { "start <name>", I18N_NOOP("Start Kate with a given session"), 0 },
+ { "u", 0, 0 },
+ { "use", I18N_NOOP("Use a already running kate instance (if possible)"), 0 },
+ { "p", 0, 0 },
+ { "pid <pid>", I18N_NOOP("Only try to reuse kate instance with this pid"), 0 },
+ { "e", 0, 0 },
+ { "encoding <name>", I18N_NOOP("Set encoding for the file to open"), 0 },
+ { "l", 0, 0 },
+ { "line <line>", I18N_NOOP("Navigate to this line"), 0 },
+ { "c", 0, 0 },
+ { "column <column>", I18N_NOOP("Navigate to this column"), 0 },
+ { "i", 0, 0 },
+ { "stdin", I18N_NOOP("Read the contents of stdin"), 0 },
+ { "+[URL]", I18N_NOOP("Document to open"), 0 },
+ KCmdLineLastOption
+};
+
+extern "C" KDE_EXPORT int kdemain( int argc, char **argv )
+{
+ // here we go, construct the Kate version
+ QString kateVersion = KateApp::kateVersion();
+
+ KAboutData aboutData ("kate", I18N_NOOP("Kate"), kateVersion.latin1(),
+ I18N_NOOP( "Kate - Advanced Text Editor" ), KAboutData::License_LGPL_V2,
+ I18N_NOOP( "(c) 2000-2005 The Kate Authors" ), 0, "http://kate.kde.org");
+
+ aboutData.addAuthor ("Christoph Cullmann", I18N_NOOP("Maintainer"), "cullmann@kde.org", "http://www.babylon2k.de");
+ aboutData.addAuthor ("Anders Lund", I18N_NOOP("Core Developer"), "anders@alweb.dk", "http://www.alweb.dk");
+ aboutData.addAuthor ("Joseph Wenninger", I18N_NOOP("Core Developer"), "jowenn@kde.org","http://stud3.tuwien.ac.at/~e9925371");
+ aboutData.addAuthor ("Hamish Rodda",I18N_NOOP("Core Developer"), "rodda@kde.org");
+ aboutData.addAuthor ("Waldo Bastian", I18N_NOOP( "The cool buffersystem" ), "bastian@kde.org" );
+ aboutData.addAuthor ("Charles Samuels", I18N_NOOP("The Editing Commands"), "charles@kde.org");
+ aboutData.addAuthor ("Matt Newell", I18N_NOOP("Testing, ..."), "newellm@proaxis.com");
+ aboutData.addAuthor ("Michael Bartl", I18N_NOOP("Former Core Developer"), "michael.bartl1@chello.at");
+ aboutData.addAuthor ("Michael McCallum", I18N_NOOP("Core Developer"), "gholam@xtra.co.nz");
+ aboutData.addAuthor ("Jochen Wilhemly", I18N_NOOP( "KWrite Author" ), "digisnap@cs.tu-berlin.de" );
+ aboutData.addAuthor ("Michael Koch",I18N_NOOP("KWrite port to KParts"), "koch@kde.org");
+ aboutData.addAuthor ("Christian Gebauer", 0, "gebauer@kde.org" );
+ aboutData.addAuthor ("Simon Hausmann", 0, "hausmann@kde.org" );
+ aboutData.addAuthor ("Glen Parker",I18N_NOOP("KWrite Undo History, Kspell integration"), "glenebob@nwlink.com");
+ aboutData.addAuthor ("Scott Manson",I18N_NOOP("KWrite XML Syntax highlighting support"), "sdmanson@alltel.net");
+ aboutData.addAuthor ("John Firebaugh",I18N_NOOP("Patches and more"), "jfirebaugh@kde.org");
+ aboutData.addAuthor ("Dominik Haumann", I18N_NOOP("Developer & Highlight wizard"), "dhdev@gmx.de");
+
+ aboutData.addCredit ("Matteo Merli",I18N_NOOP("Highlighting for RPM Spec-Files, Perl, Diff and more"), "merlim@libero.it");
+ aboutData.addCredit ("Rocky Scaletta",I18N_NOOP("Highlighting for VHDL"), "rocky@purdue.edu");
+ aboutData.addCredit ("Yury Lebedev",I18N_NOOP("Highlighting for SQL"),"");
+ aboutData.addCredit ("Chris Ross",I18N_NOOP("Highlighting for Ferite"),"");
+ aboutData.addCredit ("Nick Roux",I18N_NOOP("Highlighting for ILERPG"),"");
+ aboutData.addCredit ("Carsten Niehaus", I18N_NOOP("Highlighting for LaTeX"),"");
+ aboutData.addCredit ("Per Wigren", I18N_NOOP("Highlighting for Makefiles, Python"),"");
+ aboutData.addCredit ("Jan Fritz", I18N_NOOP("Highlighting for Python"),"");
+ aboutData.addCredit ("Daniel Naber","","");
+ aboutData.addCredit ("Roland Pabel",I18N_NOOP("Highlighting for Scheme"),"");
+ aboutData.addCredit ("Cristi Dumitrescu",I18N_NOOP("PHP Keyword/Datatype list"),"");
+ aboutData.addCredit ("Carsten Pfeiffer", I18N_NOOP("Very nice help"), "");
+ aboutData.addCredit (I18N_NOOP("All people who have contributed and I have forgotten to mention"),"","");
+
+ aboutData.setTranslator(I18N_NOOP2("NAME OF TRANSLATORS","Your names"), I18N_NOOP2("EMAIL OF TRANSLATORS","Your emails"));
+
+ // command line args init and co
+ KCmdLineArgs::init (argc, argv, &aboutData);
+ KCmdLineArgs::addCmdLineOptions (options);
+ KCmdLineArgs::addTempFileOption();
+ KateApp::addCmdLineOptions ();
+
+ // get our command line args ;)
+ KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
+
+ // now, first try to contact running kate instance if needed
+ if ( args->isSet("use") || (::getenv("KATE_PID")!=0) )
+ {
+ DCOPClient client;
+ client.attach ();
+
+ // get all attached clients ;)
+ QCStringList allClients = client.registeredApplications();
+
+ // search for a kate app client, use the first found
+ QCString kateApp;
+
+ if ( args->isSet("start") )
+ {
+ for (unsigned int i=0; i < allClients.count(); i++)
+ {
+ if (allClients[i] == "kate" || allClients[i].left(5) == "kate-")
+ {
+ DCOPRef ref( allClients[i], "KateApplication" );
+ QString s = ref.call( "session" );
+ if ( QString(args->getOption("start")) == s )
+ {
+ kateApp = allClients[i];
+ break;
+ }
+ }
+ }
+ }
+ else if ( (args->isSet("pid")) || (::getenv("KATE_PID") !=0 ) )
+ {
+ QCString tryApp;
+ if ( args->isSet("pid") )
+ tryApp = args->getOption("pid");
+ else
+ tryApp = ::getenv("KATE_PID");
+
+ if ( client.isApplicationRegistered( tryApp.prepend("kate-") ) )
+ kateApp = tryApp;
+ }
+ else
+ {
+ for (unsigned int i=0; i < allClients.count(); ++i)
+ {
+ if (allClients[i] == "kate" || allClients[i].left(5) == "kate-")
+ {
+ kateApp = allClients[i];
+ break;
+ }
+ }
+ }
+
+ // found a matching kate client ;)
+ if (!kateApp.isEmpty())
+ {
+ kdDebug () << "kate app: " << kateApp << endl;
+ // make kdeinit happy
+ client.registerAs( "kate" );
+
+ DCOPRef kRef (kateApp, "KateApplication");
+
+ if (args->isSet ("start"))
+ kRef.call( "activateSession", QString (args->getOption("start")) );
+
+ QString enc = args->isSet("encoding") ? args->getOption("encoding") : QCString("");
+
+ bool tempfileSet = KCmdLineArgs::isTempFileSet();
+
+ for (int z=0; z<args->count(); z++)
+ kRef.call( "openURL", args->url(z), enc, tempfileSet );
+
+ if( args->isSet( "stdin" ) )
+ {
+ QTextIStream input(stdin);
+
+ // set chosen codec
+ QTextCodec *codec = args->isSet("encoding") ? QTextCodec::codecForName(args->getOption("encoding")) : 0;
+
+ if (codec)
+ input.setCodec (codec);
+
+ QString line;
+ QString text;
+
+ do
+ {
+ line = input.readLine();
+ text.append( line + "\n" );
+ } while( !line.isNull() );
+
+ kRef.call( "openInput", text );
+ }
+
+ int line = 0;
+ int column = 0;
+ bool nav = false;
+
+ if (args->isSet ("line"))
+ {
+ line = args->getOption ("line").toInt();
+ nav = true;
+ }
+
+ if (args->isSet ("column"))
+ {
+ column = args->getOption ("column").toInt();
+ nav = true;
+ }
+
+ if (nav)
+ kRef.call( "setCursor", line, column );
+
+ // since the user tried to open a document, let us assume [s]he
+ // wants to see that document.
+ // ### what to do about the infamous focus stealing prevention?
+ uint mwn = kRef.call("activeMainWindowNumber");
+ QCString smwn;
+ DCOPRef wRef( kateApp, QCString( "__KateMainWindow#") + smwn.setNum(mwn) );
+ if ( wRef.call("minimized") )
+ {
+ if ( wRef.call( "maximized" ) )
+ wRef.call( "maximize" );
+ else
+ wRef.call("restore");
+ }
+ wRef.call( "raise" );
+
+ // stop startup notification
+ KStartupInfo::appStarted( );
+
+ return 0;
+ }
+ }
+
+ // construct the real kate app object ;)
+ KateApp app (args);
+
+ // app execution should already end :)
+ if (app.shouldExit())
+ {
+ return 0;
+ }
+
+ // execute ourself ;)
+ return app.exec();
+}
+
+// kate: space-indent on; indent-width 2; replace-tabs on; mixed-indent off;
diff --git a/kate/app/katemain.h b/kate/app/katemain.h
new file mode 100644
index 000000000..7d2f65da9
--- /dev/null
+++ b/kate/app/katemain.h
@@ -0,0 +1,70 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KATE_MAIN_H__
+#define __KATE_MAIN_H__
+
+#include <config.h>
+
+class QComboBox;
+class QDateTime;
+class QEvent;
+class QFileInfo;
+class QGridLayout;
+class QLabel;
+class QListBox;
+class QObject;
+class QPixmap;
+class QVBoxLayout;
+class QString;
+class QWidgetStack;
+
+class KAction;
+class KActionMenu;
+class KConfig;
+class KDirOperator;
+class KEditToolbar;
+class KFileViewItem;
+class KHistoryCombo;
+class KLineEdit;
+class KListBox;
+class KProcess;
+class KPushButton;
+class KRecentFilesAction;
+class KSelectAction;
+class KStatusBar;
+class KToggleAction;
+class KURL;
+class KURLComboBox;
+
+class KateApp;
+class KateConfigDlg;
+class KateConsole;
+class KateDocManager;
+class KateFileList;
+class KateFileSelector;
+class KateMainWindow;
+class KatePluginIface;
+class KatePluginManager;
+class KateSidebar;
+class KateViewManager;
+class KateViewSpace;
+
+#endif
diff --git a/kate/app/katemainwindow.cpp b/kate/app/katemainwindow.cpp
new file mode 100644
index 000000000..772f63339
--- /dev/null
+++ b/kate/app/katemainwindow.cpp
@@ -0,0 +1,854 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ 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.
+*/
+
+//BEGIN Includes
+#include "katemainwindow.h"
+#include "katemainwindow.moc"
+
+#include "kateconfigdialog.h"
+#include "kateconsole.h"
+#include "katedocmanager.h"
+#include "katepluginmanager.h"
+#include "kateconfigplugindialogpage.h"
+#include "kateviewmanager.h"
+#include "kateapp.h"
+#include "katefileselector.h"
+#include "katefilelist.h"
+#include "kategrepdialog.h"
+#include "katemailfilesdialog.h"
+#include "katemainwindowiface.h"
+#include "kateexternaltools.h"
+#include "katesavemodifieddialog.h"
+#include "katemwmodonhddialog.h"
+#include "katesession.h"
+#include "katetabwidget.h"
+
+#include "../interfaces/mainwindow.h"
+#include "../interfaces/toolviewmanager.h"
+
+#include <dcopclient.h>
+#include <kinstance.h>
+#include <kaboutdata.h>
+#include <kaction.h>
+#include <kcmdlineargs.h>
+#include <kdebug.h>
+#include <kdialogbase.h>
+#include <kdiroperator.h>
+#include <kdockwidget.h>
+#include <kedittoolbar.h>
+#include <kfiledialog.h>
+#include <kglobalaccel.h>
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <kiconloader.h>
+#include <kkeydialog.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kmimetype.h>
+#include <kopenwith.h>
+#include <kpopupmenu.h>
+#include <ksimpleconfig.h>
+#include <kstatusbar.h>
+#include <kstdaction.h>
+#include <kstandarddirs.h>
+#include <ktrader.h>
+#include <kuniqueapplication.h>
+#include <kurldrag.h>
+#include <kdesktopfile.h>
+#include <khelpmenu.h>
+#include <kmultitabbar.h>
+#include <ktip.h>
+#include <kmenubar.h>
+#include <kstringhandler.h>
+#include <qlayout.h>
+#include <qptrvector.h>
+
+#include <assert.h>
+#include <unistd.h>
+//END
+
+uint KateMainWindow::uniqueID = 1;
+
+KateMainWindow::KateMainWindow (KConfig *sconfig, const QString &sgroup)
+ : KateMDI::MainWindow (0,(QString("__KateMainWindow#%1").arg(uniqueID)).latin1())
+{
+ // first the very important id
+ myID = uniqueID;
+ uniqueID++;
+
+ m_modignore = false;
+
+ console = 0;
+ greptool = 0;
+
+ // here we go, set some usable default sizes
+ if (!initialGeometrySet())
+ {
+ int scnum = QApplication::desktop()->screenNumber(parentWidget());
+ QRect desk = QApplication::desktop()->screenGeometry(scnum);
+
+ QSize size;
+
+ // try to load size
+ if (sconfig)
+ {
+ sconfig->setGroup (sgroup);
+ size.setWidth (sconfig->readNumEntry( QString::fromLatin1("Width %1").arg(desk.width()), 0 ));
+ size.setHeight (sconfig->readNumEntry( QString::fromLatin1("Height %1").arg(desk.height()), 0 ));
+ }
+
+ // if thats fails, try to reuse size
+ if (size.isEmpty())
+ {
+ // first try to reuse size known from current or last created main window ;=)
+ if (KateApp::self()->mainWindows () > 0)
+ {
+ KateMainWindow *win = KateApp::self()->activeMainWindow ();
+
+ if (!win)
+ win = KateApp::self()->mainWindow (KateApp::self()->mainWindows ()-1);
+
+ size = win->size();
+ }
+ else // now fallback to hard defaults ;)
+ {
+ // first try global app config
+ KateApp::self()->config()->setGroup ("MainWindow");
+ size.setWidth (KateApp::self()->config()->readNumEntry( QString::fromLatin1("Width %1").arg(desk.width()), 0 ));
+ size.setHeight (KateApp::self()->config()->readNumEntry( QString::fromLatin1("Height %1").arg(desk.height()), 0 ));
+
+ if (size.isEmpty())
+ size = QSize (kMin (700, desk.width()), kMin(480, desk.height()));
+ }
+
+ resize (size);
+ }
+ }
+
+ // start session restore if needed
+ startRestore (sconfig, sgroup);
+
+ m_mainWindow = new Kate::MainWindow (this);
+ m_toolViewManager = new Kate::ToolViewManager (this);
+
+ m_dcop = new KateMainWindowDCOPIface (this);
+
+ // setup the most important widgets
+ setupMainWindow();
+
+ // setup the actions
+ setupActions();
+
+ setStandardToolBarMenuEnabled( true );
+ setXMLFile( "kateui.rc" );
+ createShellGUI ( true );
+
+ KatePluginManager::self()->enableAllPluginsGUI (this);
+
+ if ( KateApp::self()->authorize("shell_access") )
+ Kate::Document::registerCommand(KateExternalToolsCommand::self());
+
+ // connect documents menu aboutToshow
+ documentMenu = (QPopupMenu*)factory()->container("documents", this);
+ connect(documentMenu, SIGNAL(aboutToShow()), this, SLOT(documentMenuAboutToShow()));
+
+ // caption update
+ for (uint i = 0; i < KateDocManager::self()->documents(); i++)
+ slotDocumentCreated (KateDocManager::self()->document(i));
+
+ connect(KateDocManager::self(),SIGNAL(documentCreated(Kate::Document *)),this,SLOT(slotDocumentCreated(Kate::Document *)));
+
+ readOptions();
+
+ if (sconfig)
+ m_viewManager->restoreViewConfiguration (sconfig, sgroup);
+
+ finishRestore ();
+
+ setAcceptDrops(true);
+}
+
+KateMainWindow::~KateMainWindow()
+{
+ // first, save our fallback window size ;)
+ KateApp::self()->config()->setGroup ("MainWindow");
+ saveWindowSize (KateApp::self()->config());
+
+ // save other options ;=)
+ saveOptions();
+
+ KateApp::self()->removeMainWindow (this);
+
+ KatePluginManager::self()->disableAllPluginsGUI (this);
+
+ delete m_dcop;
+}
+
+void KateMainWindow::setupMainWindow ()
+{
+ setToolViewStyle( KMultiTabBar::KDEV3ICON );
+
+ m_tabWidget = new KateTabWidget (centralWidget());
+
+ m_viewManager = new KateViewManager (this);
+
+ KateMDI::ToolView *ft = createToolView("kate_filelist", KMultiTabBar::Left, SmallIcon("kmultiple"), i18n("Documents"));
+ filelist = new KateFileList (this, m_viewManager, ft, "filelist");
+ filelist->readConfig(KateApp::self()->config(), "Filelist");
+
+ KateMDI::ToolView *t = createToolView("kate_fileselector", KMultiTabBar::Left, SmallIcon("fileopen"), i18n("Filesystem Browser"));
+ fileselector = new KateFileSelector( this, m_viewManager, t, "operator");
+ connect(fileselector->dirOperator(),SIGNAL(fileSelected(const KFileItem*)),this,SLOT(fileSelected(const KFileItem*)));
+
+ // ONLY ALLOW SHELL ACCESS IF ALLOWED ;)
+ if (KateApp::self()->authorize("shell_access"))
+ {
+ t = createToolView("kate_greptool", KMultiTabBar::Bottom, SmallIcon("filefind"), i18n("Find in Files") );
+ greptool = new GrepTool( t, "greptool" );
+ connect(greptool, SIGNAL(itemSelected(const QString &,int)), this, SLOT(slotGrepToolItemSelected(const QString &,int)));
+ connect(t,SIGNAL(visibleChanged(bool)),this, SLOT(updateGrepDir (bool)));
+ // WARNING HACK - anders: showing the greptool seems to make the menu accels work
+ greptool->show();
+
+ t = createToolView("kate_console", KMultiTabBar::Bottom, SmallIcon("konsole"), i18n("Terminal"));
+ console = new KateConsole (this, t);
+ }
+
+ // make per default the filelist visible, if we are in session restore, katemdi will skip this ;)
+ showToolView (ft);
+}
+
+void KateMainWindow::setupActions()
+{
+ KAction *a;
+
+ KStdAction::openNew( m_viewManager, SLOT( slotDocumentNew() ), actionCollection(), "file_new" )->setWhatsThis(i18n("Create a new document"));
+ KStdAction::open( m_viewManager, SLOT( slotDocumentOpen() ), actionCollection(), "file_open" )->setWhatsThis(i18n("Open an existing document for editing"));
+
+ fileOpenRecent = KStdAction::openRecent (m_viewManager, SLOT(openURL (const KURL&)), actionCollection());
+ fileOpenRecent->setWhatsThis(i18n("This lists files which you have opened recently, and allows you to easily open them again."));
+
+ a=new KAction( i18n("Save A&ll"),"save_all", CTRL+Key_L, KateDocManager::self(), SLOT( saveAll() ), actionCollection(), "file_save_all" );
+ a->setWhatsThis(i18n("Save all open, modified documents to disk."));
+
+ KStdAction::close( m_viewManager, SLOT( slotDocumentClose() ), actionCollection(), "file_close" )->setWhatsThis(i18n("Close the current document."));
+
+ a=new KAction( i18n( "Clos&e All" ), 0, this, SLOT( slotDocumentCloseAll() ), actionCollection(), "file_close_all" );
+ a->setWhatsThis(i18n("Close all open documents."));
+
+ KStdAction::mail( this, SLOT(slotMail()), actionCollection() )->setWhatsThis(i18n("Send one or more of the open documents as email attachments."));
+
+ KStdAction::quit( this, SLOT( slotFileQuit() ), actionCollection(), "file_quit" )->setWhatsThis(i18n("Close this window"));
+
+ a=new KAction(i18n("&New Window"), "window_new", 0, this, SLOT(newWindow()), actionCollection(), "view_new_view");
+ a->setWhatsThis(i18n("Create a new Kate view (a new window with the same document list)."));
+
+ if ( KateApp::self()->authorize("shell_access") )
+ {
+ externalTools = new KateExternalToolsMenuAction( i18n("External Tools"), actionCollection(), "tools_external", this );
+ externalTools->setWhatsThis( i18n("Launch external helper applications") );
+ }
+
+ KToggleAction* showFullScreenAction = KStdAction::fullScreen( 0, 0, actionCollection(),this);
+ connect( showFullScreenAction,SIGNAL(toggled(bool)), this,SLOT(slotFullScreen(bool)));
+
+ documentOpenWith = new KActionMenu(i18n("Open W&ith"), actionCollection(), "file_open_with");
+ documentOpenWith->setWhatsThis(i18n("Open the current document using another application registered for its file type, or an application of your choice."));
+ connect(documentOpenWith->popupMenu(), SIGNAL(aboutToShow()), this, SLOT(mSlotFixOpenWithMenu()));
+ connect(documentOpenWith->popupMenu(), SIGNAL(activated(int)), this, SLOT(slotOpenWithMenuAction(int)));
+
+ a=KStdAction::keyBindings(this, SLOT(editKeys()), actionCollection());
+ a->setWhatsThis(i18n("Configure the application's keyboard shortcut assignments."));
+
+ a=KStdAction::configureToolbars(this, SLOT(slotEditToolbars()), actionCollection());
+ a->setWhatsThis(i18n("Configure which items should appear in the toolbar(s)."));
+
+ KAction* settingsConfigure = KStdAction::preferences(this, SLOT(slotConfigure()), actionCollection(), "settings_configure");
+ settingsConfigure->setWhatsThis(i18n("Configure various aspects of this application and the editing component."));
+
+ // pipe to terminal action
+ if (KateApp::self()->authorize("shell_access"))
+ new KAction(i18n("&Pipe to Console"), "pipe", 0, console, SLOT(slotPipeToConsole()), actionCollection(), "tools_pipe_to_terminal");
+
+ // tip of the day :-)
+ KStdAction::tipOfDay( this, SLOT( tipOfTheDay() ), actionCollection() )->setWhatsThis(i18n("This shows useful tips on the use of this application."));
+
+ if (KatePluginManager::self()->pluginList().count() > 0)
+ {
+ a=new KAction(i18n("&Plugins Handbook"), 0, this, SLOT(pluginHelp()), actionCollection(), "help_plugins_contents");
+ a->setWhatsThis(i18n("This shows help files for various available plugins."));
+ }
+
+ connect(m_viewManager,SIGNAL(viewChanged()),this,SLOT(slotWindowActivated()));
+ connect(m_viewManager,SIGNAL(viewChanged()),this,SLOT(slotUpdateOpenWith()));
+
+ slotWindowActivated ();
+
+ // session actions
+ new KAction(i18n("Menu entry Session->New", "&New"), "filenew", 0, KateSessionManager::self(), SLOT(sessionNew()), actionCollection(), "sessions_new");
+ new KAction(i18n("&Open..."), "fileopen", 0, KateSessionManager::self(), SLOT(sessionOpen()), actionCollection(), "sessions_open");
+ new KAction(i18n("&Save"), "filesave", 0, KateSessionManager::self(), SLOT(sessionSave()), actionCollection(), "sessions_save");
+ new KAction(i18n("Save &As..."), "filesaveas", 0, KateSessionManager::self(), SLOT(sessionSaveAs()), actionCollection(), "sessions_save_as");
+ new KAction(i18n("&Manage..."), "view_choose", 0, KateSessionManager::self(), SLOT(sessionManage()), actionCollection(), "sessions_manage");
+
+ // quick open menu ;)
+ new KateSessionsAction (i18n("&Quick Open"), actionCollection(), "sessions_list");
+}
+
+KateTabWidget *KateMainWindow::tabWidget ()
+{
+ return m_tabWidget;
+}
+
+void KateMainWindow::slotDocumentCloseAll() {
+ if (queryClose_internal())
+ KateDocManager::self()->closeAllDocuments(false);
+}
+
+bool KateMainWindow::queryClose_internal() {
+ uint documentCount=KateDocManager::self()->documents();
+
+ if ( ! showModOnDiskPrompt() )
+ return false;
+
+ QPtrList<Kate::Document> modifiedDocuments=KateDocManager::self()->modifiedDocumentList();
+ bool shutdown=(modifiedDocuments.count()==0);
+
+ if (!shutdown) {
+ shutdown=KateSaveModifiedDialog::queryClose(this,modifiedDocuments);
+ }
+
+ if ( KateDocManager::self()->documents() > documentCount ) {
+ KMessageBox::information (this,
+ i18n ("New file opened while trying to close Kate, closing aborted."),
+ i18n ("Closing Aborted"));
+ shutdown=false;
+ }
+
+ return shutdown;
+}
+
+/**
+ * queryClose(), take care that after the last mainwindow the stuff is closed
+ */
+bool KateMainWindow::queryClose()
+{
+ // session saving, can we close all views ?
+ // just test, not close them actually
+ if (KateApp::self()->sessionSaving())
+ {
+ return queryClose_internal ();
+ }
+
+ // normal closing of window
+ // allow to close all windows until the last without restrictions
+ if ( KateApp::self()->mainWindows () > 1 )
+ return true;
+
+ // last one: check if we can close all documents, try run
+ // and save docs if we really close down !
+ if ( queryClose_internal () )
+ {
+ KateApp::self()->sessionManager()->saveActiveSession(true, true);
+
+ // detach the dcopClient
+ KateApp::self()->dcopClient()->detach();
+
+ return true;
+ }
+
+ return false;
+}
+
+void KateMainWindow::newWindow ()
+{
+ KateApp::self()->newMainWindow ();
+}
+
+void KateMainWindow::slotEditToolbars()
+{
+ saveMainWindowSettings( KateApp::self()->config(), "MainWindow" );
+ KEditToolbar dlg( factory() );
+ connect( &dlg, SIGNAL(newToolbarConfig()), this, SLOT(slotNewToolbarConfig()) );
+ dlg.exec();
+}
+
+void KateMainWindow::slotNewToolbarConfig()
+{
+ applyMainWindowSettings( KateApp::self()->config(), "MainWindow" );
+}
+
+void KateMainWindow::slotFileQuit()
+{
+ KateApp::self()->shutdownKate (this);
+}
+
+void KateMainWindow::readOptions ()
+{
+ KConfig *config = KateApp::self()->config ();
+
+ config->setGroup("General");
+ syncKonsole = config->readBoolEntry("Sync Konsole", true);
+ modNotification = config->readBoolEntry("Modified Notification", false);
+ KateDocManager::self()->setSaveMetaInfos(config->readBoolEntry("Save Meta Infos", true));
+ KateDocManager::self()->setDaysMetaInfos(config->readNumEntry("Days Meta Infos", 30));
+
+ m_viewManager->setShowFullPath(config->readBoolEntry("Show Full Path in Title", false));
+
+ fileOpenRecent->loadEntries(config, "Recent Files");
+
+ fileselector->readConfig(config, "fileselector");
+}
+
+void KateMainWindow::saveOptions ()
+{
+ KConfig *config = KateApp::self()->config ();
+
+ config->setGroup("General");
+
+ if (console)
+ config->writeEntry("Show Console", console->isVisible());
+ else
+ config->writeEntry("Show Console", false);
+
+ config->writeEntry("Save Meta Infos", KateDocManager::self()->getSaveMetaInfos());
+
+ config->writeEntry("Days Meta Infos", KateDocManager::self()->getDaysMetaInfos());
+
+ config->writeEntry("Show Full Path in Title", m_viewManager->getShowFullPath());
+
+ config->writeEntry("Sync Konsole", syncKonsole);
+
+ fileOpenRecent->saveEntries(config, "Recent Files");
+
+ fileselector->writeConfig(config, "fileselector");
+
+ filelist->writeConfig(config, "Filelist");
+}
+
+void KateMainWindow::slotWindowActivated ()
+{
+ if (m_viewManager->activeView())
+ {
+ if (console && syncKonsole)
+ {
+ static QString path;
+ QString newPath = m_viewManager->activeView()->getDoc()->url().directory();
+
+ if ( newPath != path )
+ {
+ path = newPath;
+ console->cd (KURL( path ));
+ }
+ }
+
+ updateCaption (m_viewManager->activeView()->getDoc());
+ }
+
+ // update proxy
+ centralWidget()->setFocusProxy (m_viewManager->activeView());
+}
+
+void KateMainWindow::slotUpdateOpenWith()
+{
+ if (m_viewManager->activeView())
+ documentOpenWith->setEnabled(!m_viewManager->activeView()->document()->url().isEmpty());
+ else
+ documentOpenWith->setEnabled(false);
+}
+
+void KateMainWindow::documentMenuAboutToShow()
+{
+ // remove documents
+ while (documentMenu->count() > 3)
+ documentMenu->removeItemAt (3);
+
+ QListViewItem * item = filelist->firstChild();
+ while( item ) {
+ // would it be saner to use the screen width as a limit that some random number??
+ QString name = KStringHandler::rsqueeze( ((KateFileListItem *)item)->document()->docName(), 150 );
+ Kate::Document* doc = ((KateFileListItem *)item)->document();
+ documentMenu->insertItem (
+ doc->isModified() ? i18n("'document name [*]', [*] means modified", "%1 [*]").arg(name) : name,
+ m_viewManager, SLOT (activateView (int)), 0,
+ ((KateFileListItem *)item)->documentNumber () );
+
+ item = item->nextSibling();
+ }
+ if (m_viewManager->activeView())
+ documentMenu->setItemChecked ( m_viewManager->activeView()->getDoc()->documentNumber(), true);
+}
+
+void KateMainWindow::slotGrepToolItemSelected(const QString &filename,int linenumber)
+{
+ KURL fileURL;
+ fileURL.setPath( filename );
+ m_viewManager->openURL( fileURL );
+ if ( m_viewManager->activeView() == 0 ) return;
+ m_viewManager->activeView()->gotoLineNumber( linenumber );
+ raise();
+ setActiveWindow();
+}
+
+void KateMainWindow::dragEnterEvent( QDragEnterEvent *event )
+{
+ event->accept(KURLDrag::canDecode(event));
+}
+
+void KateMainWindow::dropEvent( QDropEvent *event )
+{
+ slotDropEvent(event);
+}
+
+void KateMainWindow::slotDropEvent( QDropEvent * event )
+{
+ KURL::List textlist;
+ if (!KURLDrag::decode(event, textlist)) return;
+
+ for (KURL::List::Iterator i=textlist.begin(); i != textlist.end(); ++i)
+ {
+ m_viewManager->openURL (*i);
+ }
+}
+
+void KateMainWindow::editKeys()
+{
+ KKeyDialog dlg ( false, this );
+
+ QPtrList<KXMLGUIClient> clients = guiFactory()->clients();
+
+ for( QPtrListIterator<KXMLGUIClient> it( clients ); it.current(); ++it )
+ dlg.insert ( (*it)->actionCollection(), (*it)->instance()->aboutData()->programName() );
+
+ dlg.insert( externalTools->actionCollection(), i18n("External Tools") );
+
+ dlg.configure();
+
+ QPtrList<Kate::Document> l=KateDocManager::self()->documentList();
+ for (uint i=0;i<l.count();i++) {
+// kdDebug(13001)<<"reloading Keysettings for document "<<i<<endl;
+ l.at(i)->reloadXML();
+ QPtrList<class KTextEditor::View> l1=l.at(i)->views ();//KTextEditor::Document
+ for (uint i1=0;i1<l1.count();i1++) {
+ l1.at(i1)->reloadXML();
+// kdDebug(13001)<<"reloading Keysettings for view "<<i<<"/"<<i1<<endl;
+ }
+ }
+
+ externalTools->actionCollection()->writeShortcutSettings( "Shortcuts", new KConfig("externaltools", false, false, "appdata") );
+}
+
+void KateMainWindow::openURL (const QString &name)
+{
+ m_viewManager->openURL (KURL(name));
+}
+
+void KateMainWindow::slotConfigure()
+{
+ if (!m_viewManager->activeView())
+ return;
+
+ KateConfigDialog* dlg = new KateConfigDialog (this, m_viewManager->activeView());
+ dlg->exec();
+
+ delete dlg;
+}
+
+KURL KateMainWindow::activeDocumentUrl()
+{
+ // anders: i make this one safe, as it may be called during
+ // startup (by the file selector)
+ Kate::View *v = m_viewManager->activeView();
+ if ( v )
+ return v->getDoc()->url();
+ return KURL();
+}
+
+void KateMainWindow::fileSelected(const KFileItem * /*file*/)
+{
+ const KFileItemList *list=fileselector->dirOperator()->selectedItems();
+ KFileItem *tmp;
+ for (KFileItemListIterator it(*list); (tmp = it.current()); ++it)
+ {
+ m_viewManager->openURL(tmp->url());
+ fileselector->dirOperator()->view()->setSelected(tmp,false);
+ }
+}
+
+// TODO make this work
+void KateMainWindow::mSlotFixOpenWithMenu()
+{
+ //kdDebug(13001)<<"13000"<<"fixing open with menu"<<endl;
+ documentOpenWith->popupMenu()->clear();
+ // get a list of appropriate services.
+ KMimeType::Ptr mime = KMimeType::findByURL( m_viewManager->activeView()->getDoc()->url() );
+ //kdDebug(13001)<<"13000"<<"url: "<<m_viewManager->activeView()->getDoc()->url().prettyURL()<<"mime type: "<<mime->name()<<endl;
+ // some checking goes here...
+ KTrader::OfferList offers = KTrader::self()->query(mime->name(), "Type == 'Application'");
+ // for each one, insert a menu item...
+ for(KTrader::OfferList::Iterator it = offers.begin(); it != offers.end(); ++it) {
+ if ((*it)->name() == "Kate") continue;
+ documentOpenWith->popupMenu()->insertItem( SmallIcon( (*it)->icon() ), (*it)->name() );
+ }
+ // append "Other..." to call the KDE "open with" dialog.
+ documentOpenWith->popupMenu()->insertItem(i18n("&Other..."));
+}
+
+void KateMainWindow::slotOpenWithMenuAction(int idx)
+{
+ KURL::List list;
+ list.append( m_viewManager->activeView()->getDoc()->url() );
+ QString appname = documentOpenWith->popupMenu()->text(idx);
+
+ appname = appname.remove('&'); //Remove a possible accelerator ... otherwise the application might not get found.
+ if ( appname.compare(i18n("Other...")) == 0 ) {
+ // display "open with" dialog
+ KOpenWithDlg dlg(list);
+ if (dlg.exec())
+ KRun::run(*dlg.service(), list);
+ return;
+ }
+
+ QString qry = QString("((Type == 'Application') and (Name == '%1'))").arg( appname.latin1() );
+ KMimeType::Ptr mime = KMimeType::findByURL( m_viewManager->activeView()->getDoc()->url() );
+ KTrader::OfferList offers = KTrader::self()->query(mime->name(), qry);
+
+ if (!offers.isEmpty()) {
+ KService::Ptr app = offers.first();
+ KRun::run(*app, list);
+ }
+ else
+ KMessageBox::error(this, i18n("Application '%1' not found!").arg(appname.latin1()), i18n("Application Not Found!"));
+}
+
+void KateMainWindow::pluginHelp()
+{
+ KateApp::self()->invokeHelp (QString::null, "kate-plugins");
+}
+
+void KateMainWindow::slotMail()
+{
+ KateMailDialog *d = new KateMailDialog(this, this);
+ if ( ! d->exec() )
+ {
+ delete d;
+ return;
+ }
+ QPtrList<Kate::Document> attDocs = d->selectedDocs();
+ delete d;
+ // Check that all selected files are saved (or shouldn't be)
+ QStringList urls; // to atthatch
+ Kate::Document *doc;
+ QPtrListIterator<Kate::Document> it(attDocs);
+ for ( ; it.current(); ++it ) {
+ doc = it.current();
+ if (!doc) continue;
+ if ( doc->url().isEmpty() ) {
+ // unsaved document. back out unless it gets saved
+ int r = KMessageBox::questionYesNo( this,
+ i18n("<p>The current document has not been saved, and "
+ "cannot be attached to an email message."
+ "<p>Do you want to save it and proceed?"),
+ i18n("Cannot Send Unsaved File"),KStdGuiItem::saveAs(),KStdGuiItem::cancel() );
+ if ( r == KMessageBox::Yes ) {
+ Kate::View *v = (Kate::View*)doc->views().first();
+ int sr = v->saveAs();
+ if ( sr == Kate::View::SAVE_OK ) { ;
+ }
+ else {
+ if ( sr != Kate::View::SAVE_CANCEL ) // ERROR or RETRY(?)
+ KMessageBox::sorry( this, i18n("The file could not be saved. Please check "
+ "if you have write permission.") );
+ continue;
+ }
+ }
+ else
+ continue;
+ }
+ if ( doc->isModified() ) {
+ // warn that document is modified and offer to save it before proceeding.
+ int r = KMessageBox::warningYesNoCancel( this,
+ i18n("<p>The current file:<br><strong>%1</strong><br>has been "
+ "modified. Modifications will not be available in the attachment."
+ "<p>Do you want to save it before sending it?").arg(doc->url().prettyURL()),
+ i18n("Save Before Sending?"), KStdGuiItem::save(), i18n("Do Not Save") );
+ switch ( r ) {
+ case KMessageBox::Cancel:
+ continue;
+ case KMessageBox::Yes:
+ doc->save();
+ if ( doc->isModified() ) { // read-only docs ends here, if modified. Hmm.
+ KMessageBox::sorry( this, i18n("The file could not be saved. Please check "
+ "if you have write permission.") );
+ continue;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ // finally call the mailer
+ urls << doc->url().url();
+ } // check selected docs done
+ if ( ! urls.count() )
+ return;
+ KateApp::self()->invokeMailer( QString::null, // to
+ QString::null, // cc
+ QString::null, // bcc
+ QString::null, // subject
+ QString::null, // body
+ QString::null, // msgfile
+ urls // urls to atthatch
+ );
+}
+void KateMainWindow::tipOfTheDay()
+{
+ KTipDialog::showTip( /*0*/this, QString::null, true );
+}
+
+void KateMainWindow::slotFullScreen(bool t)
+{
+ if (t)
+ showFullScreen();
+ else
+ showNormal();
+}
+
+void KateMainWindow::updateGrepDir (bool visible)
+{
+ // grepdlg gets hidden
+ if (!visible)
+ return;
+
+ if ( m_viewManager->activeView() )
+ {
+ if ( m_viewManager->activeView()->getDoc()->url().isLocalFile() )
+ {
+ greptool->updateDirName( m_viewManager->activeView()->getDoc()->url().directory() );
+ }
+ }
+}
+
+bool KateMainWindow::event( QEvent *e )
+{
+ uint type = e->type();
+ if ( type == QEvent::WindowActivate && modNotification )
+ {
+ showModOnDiskPrompt();
+ }
+ return KateMDI::MainWindow::event( e );
+}
+
+bool KateMainWindow::showModOnDiskPrompt()
+{
+ Kate::Document *doc;
+
+ DocVector list( KateDocManager::self()->documents() );
+ uint cnt = 0;
+ for( doc = KateDocManager::self()->firstDocument(); doc; doc = KateDocManager::self()->nextDocument() )
+ {
+ if ( KateDocManager::self()->documentInfo( doc )->modifiedOnDisc )
+ {
+ list.insert( cnt, doc );
+ cnt++;
+ }
+ }
+
+ if ( cnt && !m_modignore )
+ {
+ list.resize( cnt );
+ KateMwModOnHdDialog mhdlg( list, this );
+ m_modignore = true;
+ bool res = mhdlg.exec();
+ m_modignore = false;
+
+ return res;
+ }
+ return true;
+}
+
+void KateMainWindow::slotDocumentCreated (Kate::Document *doc)
+{
+ connect(doc,SIGNAL(modStateChanged(Kate::Document *)),this,SLOT(updateCaption(Kate::Document *)));
+ connect(doc,SIGNAL(nameChanged(Kate::Document *)),this,SLOT(updateCaption(Kate::Document *)));
+ connect(doc,SIGNAL(nameChanged(Kate::Document *)),this,SLOT(slotUpdateOpenWith()));
+
+ updateCaption (doc);
+}
+
+void KateMainWindow::updateCaption (Kate::Document *doc)
+{
+ if (!m_viewManager->activeView())
+ {
+ setCaption ("", false);
+ return;
+ }
+
+ if (!(m_viewManager->activeView()->getDoc() == doc))
+ return;
+
+ QString c;
+ if (m_viewManager->activeView()->getDoc()->url().isEmpty() || (!m_viewManager->getShowFullPath()))
+ {
+ c = m_viewManager->activeView()->getDoc()->docName();
+ }
+ else
+ {
+ c = m_viewManager->activeView()->getDoc()->url().prettyURL();
+ }
+
+ QString sessName = KateApp::self()->sessionManager()->activeSession()->sessionName();
+ if ( !sessName.isEmpty() )
+ sessName = QString("%1: ").arg( sessName );
+
+ setCaption( sessName + KStringHandler::lsqueeze(c,64),
+ m_viewManager->activeView()->getDoc()->isModified());
+}
+
+void KateMainWindow::saveProperties(KConfig *config)
+{
+ QString grp=config->group();
+
+ saveSession(config, grp);
+ m_viewManager->saveViewConfiguration (config, grp);
+
+ config->setGroup(grp);
+}
+
+void KateMainWindow::readProperties(KConfig *config)
+{
+ QString grp=config->group();
+
+ startRestore(config, grp);
+ finishRestore ();
+ m_viewManager->restoreViewConfiguration (config, grp);
+
+ config->setGroup(grp);
+}
+
+void KateMainWindow::saveGlobalProperties( KConfig* sessionConfig )
+{
+ KateDocManager::self()->saveDocumentList (sessionConfig);
+
+ sessionConfig->setGroup("General");
+ sessionConfig->writeEntry ("Last Session", KateApp::self()->sessionManager()->activeSession()->sessionFileRelative());
+}
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/katemainwindow.h b/kate/app/katemainwindow.h
new file mode 100644
index 000000000..d5a67f65b
--- /dev/null
+++ b/kate/app/katemainwindow.h
@@ -0,0 +1,216 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KATE_MAINWINDOW_H__
+#define __KATE_MAINWINDOW_H__
+
+#include "katemain.h"
+#include "katemdi.h"
+
+#include <kate/view.h>
+#include <kate/document.h>
+
+#include <kparts/part.h>
+
+#include <kaction.h>
+
+class KateTabWidget;
+class GrepTool;
+
+namespace Kate {
+ class MainWindow;
+ class ToolViewManager;
+}
+
+class KFileItem;
+class KRecentFilesAction;
+class DCOPObject;
+
+class KateExternalToolsMenuAction;
+
+class KateMainWindow : public KateMDI::MainWindow, virtual public KParts::PartBase
+{
+ Q_OBJECT
+
+ friend class KateConfigDialog;
+ friend class KateViewManager;
+
+ public:
+ /**
+ * Construct the window and restore it's state from given config if any
+ * @param sconfig session config for this window, 0 if none
+ * @param sgroup session config group to use
+ */
+ KateMainWindow (KConfig *sconfig, const QString &sgroup);
+
+ /**
+ * Destruct the nice window
+ */
+ ~KateMainWindow();
+
+ /**
+ * Accessor methodes for interface and child objects
+ */
+ public:
+ Kate::MainWindow *mainWindow () { return m_mainWindow; }
+ Kate::ToolViewManager *toolViewManager () { return m_toolViewManager; }
+
+ KateViewManager *viewManager () { return m_viewManager; }
+
+ DCOPObject *dcopObject () { return m_dcop; }
+
+ /**
+ * various methodes to get some little info out of this
+ */
+ public:
+ /** Returns the URL of the current document.
+ * anders: I add this for use from the file selector. */
+ KURL activeDocumentUrl();
+
+ uint mainWindowNumber () const { return myID; }
+
+ /**
+ * Prompts the user for what to do with files that are modified on disk if any.
+ * This is optionally run when the window receives focus, and when the last
+ * window is closed.
+ * @return true if no documents are modified on disk, or all documents were
+ * handled by the dialog; otherwise (the dialog was canceled) false.
+ */
+ bool showModOnDiskPrompt();
+
+ /**
+ * central tabwidget ;)
+ * @return tab widget
+ */
+ KateTabWidget *tabWidget ();
+
+ public:
+ void readProperties(KConfig *config);
+ void saveProperties(KConfig *config);
+ void saveGlobalProperties( KConfig* sessionConfig );
+
+ public:
+ bool queryClose_internal();
+
+ private:
+ void setupMainWindow();
+ void setupActions();
+ bool queryClose();
+
+ /**
+ * read some global options from katerc
+ */
+ void readOptions();
+
+ /**
+ * save some global options to katerc
+ */
+ void saveOptions();
+
+ void dragEnterEvent( QDragEnterEvent * );
+ void dropEvent( QDropEvent * );
+
+ /**
+ * slots used for actions in the menus/toolbars
+ * or internal signal connections
+ */
+ private slots:
+ void newWindow ();
+
+ void slotConfigure();
+
+ void slotOpenWithMenuAction(int idx);
+
+ void slotGrepToolItemSelected ( const QString &filename, int linenumber );
+ void slotMail();
+
+ void slotFileQuit();
+ void slotEditToolbars();
+ void slotNewToolbarConfig();
+ void slotWindowActivated ();
+ void slotUpdateOpenWith();
+ void documentMenuAboutToShow();
+ void slotDropEvent(QDropEvent *);
+ void editKeys();
+ void mSlotFixOpenWithMenu();
+
+ void fileSelected(const KFileItem *file);
+
+ void tipOfTheDay();
+
+ /* to update the caption */
+ void slotDocumentCreated (Kate::Document *doc);
+ void updateCaption (Kate::Document *doc);
+
+ void pluginHelp ();
+ void slotFullScreen(bool);
+
+ public:
+ void openURL (const QString &name=0L);
+
+ private slots:
+ void updateGrepDir (bool visible);
+
+ protected:
+ bool event( QEvent * );
+
+ private slots:
+ void slotDocumentCloseAll();
+
+ private:
+ static uint uniqueID;
+ uint myID;
+
+ Kate::MainWindow *m_mainWindow;
+ Kate::ToolViewManager *m_toolViewManager;
+
+ bool syncKonsole;
+ bool modNotification;
+
+ DCOPObject *m_dcop;
+
+ // console
+ KateConsole *console;
+
+ // management items
+ KateViewManager *m_viewManager;
+
+ KRecentFilesAction *fileOpenRecent;
+
+ KateFileList *filelist;
+ KateFileSelector *fileselector;
+
+ KActionMenu* documentOpenWith;
+
+ QPopupMenu *documentMenu;
+
+ KToggleAction* settingsShowFilelist;
+ KToggleAction* settingsShowFileselector;
+
+ KateExternalToolsMenuAction *externalTools;
+ GrepTool * greptool;
+ bool m_modignore, m_grrr;
+
+ KateTabWidget *m_tabWidget;
+};
+
+#endif
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/katemainwindowiface.cpp b/kate/app/katemainwindowiface.cpp
new file mode 100644
index 000000000..9a748ffc9
--- /dev/null
+++ b/kate/app/katemainwindowiface.cpp
@@ -0,0 +1,27 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Ian Reinhart Geiser <geiseri@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "katemainwindowiface.h"
+
+#include "katemainwindow.h"
+
+#include <kdebug.h>
+
+KateMainWindowDCOPIface::KateMainWindowDCOPIface (KateMainWindow *w) : DCOPObject ((QString("KateMainWindow#%1").arg(w->mainWindowNumber())).latin1()), m_w (w)
+{
+}
diff --git a/kate/app/katemainwindowiface.h b/kate/app/katemainwindowiface.h
new file mode 100644
index 000000000..3292d1b15
--- /dev/null
+++ b/kate/app/katemainwindowiface.h
@@ -0,0 +1,41 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Ian Reinhart Geiser <geiseri@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _katemainwindow_Iface_h_
+#define _katemainwindow_Iface_h_
+
+#include <dcopobject.h>
+#include <dcopref.h>
+
+#include <kurl.h>
+
+class KateMainWindow;
+
+class KateMainWindowDCOPIface : public DCOPObject
+{
+ K_DCOP
+
+ public:
+ KateMainWindowDCOPIface (KateMainWindow *w);
+
+ k_dcop:
+
+ private:
+ KateMainWindow *m_w;
+};
+#endif
diff --git a/kate/app/katemdi.cpp b/kate/app/katemdi.cpp
new file mode 100644
index 000000000..fbe9be1e1
--- /dev/null
+++ b/kate/app/katemdi.cpp
@@ -0,0 +1,969 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 2005 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2002, 2003 Joseph Wenninger <jowenn@kde.org>
+
+ GUIClient partly based on ktoolbarhandler.cpp: Copyright (C) 2002 Simon Hausmann <hausmann@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "katemdi.h"
+#include "katemdi.moc"
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <kapplication.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kiconloader.h>
+#include <kpopupmenu.h>
+#include <kmessagebox.h>
+
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qevent.h>
+
+namespace KateMDI {
+
+//BEGIN SPLITTER
+
+Splitter::Splitter(Orientation o, QWidget* parent, const char* name)
+ : QSplitter(o, parent, name)
+{
+}
+
+Splitter::~Splitter()
+{
+}
+
+bool Splitter::isLastChild(QWidget* w) const
+{
+ return ( idAfter( w ) == 0 );
+}
+
+int Splitter::idAfter ( QWidget * w ) const
+{
+ return QSplitter::idAfter (w);
+}
+
+//END SPLITTER
+
+
+//BEGIN TOGGLETOOLVIEWACTION
+
+ToggleToolViewAction::ToggleToolViewAction ( const QString& text, const KShortcut& cut, ToolView *tv,
+ QObject* parent, const char* name )
+ : KToggleAction(text,cut,parent,name)
+ , m_tv(tv)
+{
+ connect(this,SIGNAL(toggled(bool)),this,SLOT(slotToggled(bool)));
+ connect(m_tv,SIGNAL(visibleChanged(bool)),this,SLOT(visibleChanged(bool)));
+
+ setChecked(m_tv->visible());
+}
+
+ToggleToolViewAction::~ToggleToolViewAction()
+{
+ unplugAll();
+}
+
+void ToggleToolViewAction::visibleChanged(bool)
+{
+ if (isChecked() != m_tv->visible())
+ setChecked (m_tv->visible());
+}
+
+void ToggleToolViewAction::slotToggled(bool t)
+{
+ if (t)
+ {
+ m_tv->mainWindow()->showToolView (m_tv);
+ m_tv->setFocus ();
+ }
+ else
+ {
+ m_tv->mainWindow()->hideToolView (m_tv);
+ m_tv->mainWindow()->centralWidget()->setFocus ();
+ }
+}
+
+//END TOGGLETOOLVIEWACTION
+
+
+//BEGIN GUICLIENT
+
+static const char *actionListName = "kate_mdi_window_actions";
+
+static const char *guiDescription = ""
+ "<!DOCTYPE kpartgui><kpartgui name=\"kate_mdi_window_actions\">"
+ "<MenuBar>"
+ " <Menu name=\"window\">"
+ " <ActionList name=\"%1\" />"
+ " </Menu>"
+ "</MenuBar>"
+ "</kpartgui>";
+
+GUIClient::GUIClient ( MainWindow *mw )
+ : QObject ( mw )
+ , KXMLGUIClient ( mw )
+ , m_mw (mw)
+{
+ connect( m_mw->guiFactory(), SIGNAL( clientAdded( KXMLGUIClient * ) ),
+ this, SLOT( clientAdded( KXMLGUIClient * ) ) );
+
+ if ( domDocument().documentElement().isNull() )
+ {
+ QString completeDescription = QString::fromLatin1( guiDescription )
+ .arg( actionListName );
+
+ setXML( completeDescription, false /*merge*/ );
+ }
+
+ if (actionCollection()->kaccel()==0)
+ actionCollection()->setWidget(m_mw);
+
+ m_toolMenu = new KActionMenu(i18n("Tool &Views"),actionCollection(),"kate_mdi_toolview_menu");
+ m_showSidebarsAction = new KToggleAction( i18n("Show Side&bars"),
+ CTRL|ALT|SHIFT|Key_F, actionCollection(), "kate_mdi_sidebar_visibility" );
+ m_showSidebarsAction->setCheckedState(i18n("Hide Side&bars"));
+ m_showSidebarsAction->setChecked( m_mw->sidebarsVisible() );
+ connect( m_showSidebarsAction, SIGNAL( toggled( bool ) ),
+ m_mw, SLOT( setSidebarsVisible( bool ) ) );
+
+ m_toolMenu->insert( m_showSidebarsAction );
+ m_toolMenu->insert( new KActionSeparator( m_toolMenu ) );
+
+ // read shortcuts
+ actionCollection()->readShortcutSettings( "Shortcuts", kapp->config() );
+}
+
+GUIClient::~GUIClient()
+{
+}
+
+void GUIClient::updateSidebarsVisibleAction()
+{
+ m_showSidebarsAction->setChecked( m_mw->sidebarsVisible() );
+}
+
+void GUIClient::registerToolView (ToolView *tv)
+{
+ QString aname = QString("kate_mdi_toolview_") + tv->id;
+
+ // try to read the action shortcut
+ KShortcut sc;
+ KConfig *cfg = kapp->config();
+ QString _grp = cfg->group();
+ cfg->setGroup("Shortcuts");
+ sc = KShortcut( cfg->readEntry( aname, "" ) );
+ cfg->setGroup( _grp );
+
+ KToggleAction *a = new ToggleToolViewAction(i18n("Show %1").arg(tv->text),
+ sc,tv, actionCollection(), aname.latin1() );
+
+ a->setCheckedState(i18n("Hide %1").arg(tv->text));
+
+ m_toolViewActions.append(a);
+ m_toolMenu->insert(a);
+
+ m_toolToAction.insert (tv, a);
+
+ updateActions();
+}
+
+void GUIClient::unregisterToolView (ToolView *tv)
+{
+ KAction *a = m_toolToAction[tv];
+
+ if (!a)
+ return;
+
+ m_toolViewActions.remove(a);
+ delete a;
+
+ m_toolToAction.remove (tv);
+
+ updateActions();
+}
+
+void GUIClient::clientAdded( KXMLGUIClient *client )
+{
+ if ( client == this )
+ updateActions();
+}
+
+void GUIClient::updateActions()
+{
+ if ( !factory() )
+ return;
+
+ unplugActionList( actionListName );
+
+ QPtrList<KAction> addList;
+ addList.append(m_toolMenu);
+
+ plugActionList( actionListName, addList );
+}
+
+//END GUICLIENT
+
+
+//BEGIN TOOLVIEW
+
+ToolView::ToolView (MainWindow *mainwin, Sidebar *sidebar, QWidget *parent)
+ : QVBox (parent)
+ , m_mainWin (mainwin)
+ , m_sidebar (sidebar)
+ , m_visible (false)
+ , persistent (false)
+{
+}
+
+ToolView::~ToolView ()
+{
+ m_mainWin->toolViewDeleted (this);
+}
+
+void ToolView::setVisible (bool vis)
+{
+ if (m_visible == vis)
+ return;
+
+ m_visible = vis;
+ emit visibleChanged (m_visible);
+}
+
+bool ToolView::visible () const
+{
+ return m_visible;
+}
+
+void ToolView::childEvent ( QChildEvent *ev )
+{
+ // set the widget to be focus proxy if possible
+ if (ev->inserted() && ev->child() && ev->child()->qt_cast("QWidget"))
+ setFocusProxy ((QWidget *)(ev->child()->qt_cast("QWidget")));
+
+ QVBox::childEvent (ev);
+}
+
+//END TOOLVIEW
+
+
+//BEGIN SIDEBAR
+
+Sidebar::Sidebar (KMultiTabBar::KMultiTabBarPosition pos, MainWindow *mainwin, QWidget *parent)
+ : KMultiTabBar ((pos == KMultiTabBar::Top || pos == KMultiTabBar::Bottom) ? KMultiTabBar::Horizontal : KMultiTabBar::Vertical, parent)
+ , m_mainWin (mainwin)
+ , m_splitter (0)
+ , m_ownSplit (0)
+ , m_lastSize (0)
+{
+ setPosition( pos );
+ hide ();
+}
+
+Sidebar::~Sidebar ()
+{
+}
+
+void Sidebar::setSplitter (Splitter *sp)
+{
+ m_splitter = sp;
+ m_ownSplit = new Splitter ((position() == KMultiTabBar::Top || position() == KMultiTabBar::Bottom) ? Qt::Horizontal : Qt::Vertical, m_splitter);
+ m_ownSplit->setOpaqueResize( KGlobalSettings::opaqueResize() );
+ m_ownSplit->setChildrenCollapsible( false );
+ m_splitter->setResizeMode( m_ownSplit, QSplitter::KeepSize );
+ m_ownSplit->hide ();
+}
+
+ToolView *Sidebar::addWidget (const QPixmap &icon, const QString &text, ToolView *widget)
+{
+ static int id = 0;
+
+ if (widget)
+ {
+ if (widget->sidebar() == this)
+ return widget;
+
+ widget->sidebar()->removeWidget (widget);
+ }
+
+ int newId = ++id;
+
+ appendTab (icon, newId, text);
+
+ if (!widget)
+ {
+ widget = new ToolView (m_mainWin, this, m_ownSplit);
+ widget->hide ();
+ widget->icon = icon;
+ widget->text = text;
+ }
+ else
+ {
+ widget->hide ();
+ widget->reparent (m_ownSplit, 0, QPoint());
+ widget->m_sidebar = this;
+ }
+
+ // save it's pos ;)
+ widget->persistent = false;
+
+ m_idToWidget.insert (newId, widget);
+ m_widgetToId.insert (widget, newId);
+ m_toolviews.push_back (widget);
+
+ show ();
+
+ connect(tab(newId),SIGNAL(clicked(int)),this,SLOT(tabClicked(int)));
+ tab(newId)->installEventFilter(this);
+
+ return widget;
+}
+
+bool Sidebar::removeWidget (ToolView *widget)
+{
+ if (!m_widgetToId.contains(widget))
+ return false;
+
+ removeTab(m_widgetToId[widget]);
+
+ m_idToWidget.remove (m_widgetToId[widget]);
+ m_widgetToId.remove (widget);
+ m_toolviews.remove (widget);
+
+ bool anyVis = false;
+ QIntDictIterator<ToolView> it( m_idToWidget );
+ for ( ; it.current(); ++it )
+ {
+ if (!anyVis)
+ anyVis = it.current()->isVisible();
+ }
+
+ if (m_idToWidget.isEmpty())
+ {
+ m_ownSplit->hide ();
+ hide ();
+ }
+ else if (!anyVis)
+ m_ownSplit->hide ();
+
+ return true;
+}
+
+bool Sidebar::showWidget (ToolView *widget)
+{
+ if (!m_widgetToId.contains(widget))
+ return false;
+
+ // hide other non-persistent views
+ QIntDictIterator<ToolView> it( m_idToWidget );
+ for ( ; it.current(); ++it )
+ if ((it.current() != widget) && !it.current()->persistent)
+ {
+ it.current()->hide();
+ setTab (it.currentKey(), false);
+ it.current()->setVisible(false);
+ }
+
+ setTab (m_widgetToId[widget], true);
+
+ m_ownSplit->show ();
+ widget->show ();
+
+ widget->setVisible (true);
+
+ return true;
+}
+
+bool Sidebar::hideWidget (ToolView *widget)
+{
+ if (!m_widgetToId.contains(widget))
+ return false;
+
+ bool anyVis = false;
+
+ updateLastSize ();
+
+ for ( QIntDictIterator<ToolView> it( m_idToWidget ); it.current(); ++it )
+ {
+ if (it.current() == widget)
+ {
+ it.current()->hide();
+ continue;
+ }
+
+ if (!anyVis)
+ anyVis = it.current()->isVisible();
+ }
+
+ // lower tab
+ setTab (m_widgetToId[widget], false);
+
+ if (!anyVis)
+ m_ownSplit->hide ();
+
+ widget->setVisible (false);
+
+ return true;
+}
+
+void Sidebar::tabClicked(int i)
+{
+ ToolView *w = m_idToWidget[i];
+
+ if (!w)
+ return;
+
+ if (isTabRaised(i))
+ {
+ showWidget (w);
+ w->setFocus ();
+ }
+ else
+ {
+ hideWidget (w);
+ m_mainWin->centralWidget()->setFocus ();
+ }
+}
+
+bool Sidebar::eventFilter(QObject *obj, QEvent *ev)
+{
+ if (ev->type()==QEvent::ContextMenu)
+ {
+ QContextMenuEvent *e = (QContextMenuEvent *) ev;
+ KMultiTabBarTab *bt = dynamic_cast<KMultiTabBarTab*>(obj);
+ if (bt)
+ {
+ kdDebug()<<"Request for popup"<<endl;
+
+ m_popupButton = bt->id();
+
+ ToolView *w = m_idToWidget[m_popupButton];
+
+ if (w)
+ {
+ KPopupMenu *p = new KPopupMenu (this);
+
+ p->insertTitle(SmallIcon("view_remove"), i18n("Behavior"), 50);
+
+ p->insertItem(w->persistent ? SmallIconSet("window_nofullscreen") : SmallIconSet("window_fullscreen"), w->persistent ? i18n("Make Non-Persistent") : i18n("Make Persistent"), 10);
+
+ p->insertTitle(SmallIcon("move"), i18n("Move To"), 51);
+
+ if (position() != 0)
+ p->insertItem(SmallIconSet("back"), i18n("Left Sidebar"),0);
+
+ if (position() != 1)
+ p->insertItem(SmallIconSet("forward"), i18n("Right Sidebar"),1);
+
+ if (position() != 2)
+ p->insertItem(SmallIconSet("up"), i18n("Top Sidebar"),2);
+
+ if (position() != 3)
+ p->insertItem(SmallIconSet("down"), i18n("Bottom Sidebar"),3);
+
+ connect(p, SIGNAL(activated(int)),
+ this, SLOT(buttonPopupActivate(int)));
+
+ p->exec(e->globalPos());
+ delete p;
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+void Sidebar::show()
+{
+ if (m_idToWidget.isEmpty() || !m_mainWin->sidebarsVisible() )
+ return;
+
+ KMultiTabBar::show( );
+}
+
+void Sidebar::buttonPopupActivate (int id)
+{
+ ToolView *w = m_idToWidget[m_popupButton];
+
+ if (!w)
+ return;
+
+ // move ids
+ if (id < 4)
+ {
+ // move + show ;)
+ m_mainWin->moveToolView (w, (KMultiTabBar::KMultiTabBarPosition) id);
+ m_mainWin->showToolView (w);
+ }
+
+ // toggle persistent
+ if (id == 10)
+ w->persistent = !w->persistent;
+}
+
+void Sidebar::updateLastSize ()
+{
+ QValueList<int> s = m_splitter->sizes ();
+
+ int i = 0;
+ if ((position() == KMultiTabBar::Right || position() == KMultiTabBar::Bottom))
+ i = 2;
+
+ // little threshold
+ if (s[i] > 2)
+ m_lastSize = s[i];
+}
+
+class TmpToolViewSorter
+{
+ public:
+ ToolView *tv;
+ unsigned int pos;
+};
+
+void Sidebar::restoreSession (KConfig *config)
+{
+ // get the last correct placed toolview
+ unsigned int firstWrong = 0;
+ for ( ; firstWrong < m_toolviews.size(); ++firstWrong )
+ {
+ ToolView *tv = m_toolviews[firstWrong];
+
+ unsigned int pos = config->readUnsignedNumEntry (QString ("Kate-MDI-ToolView-%1-Sidebar-Position").arg(tv->id), firstWrong);
+
+ if (pos != firstWrong)
+ break;
+ }
+
+ // we need to reshuffle, ahhh :(
+ if (firstWrong < m_toolviews.size())
+ {
+ // first: collect the items to reshuffle
+ QValueList<TmpToolViewSorter> toSort;
+ for (unsigned int i=firstWrong; i < m_toolviews.size(); ++i)
+ {
+ TmpToolViewSorter s;
+ s.tv = m_toolviews[i];
+ s.pos = config->readUnsignedNumEntry (QString ("Kate-MDI-ToolView-%1-Sidebar-Position").arg(m_toolviews[i]->id), i);
+ toSort.push_back (s);
+ }
+
+ // now: sort the stuff we need to reshuffle
+ for (unsigned int m=0; m < toSort.size(); ++m)
+ for (unsigned int n=m+1; n < toSort.size(); ++n)
+ if (toSort[n].pos < toSort[m].pos)
+ {
+ TmpToolViewSorter tmp = toSort[n];
+ toSort[n] = toSort[m];
+ toSort[m] = tmp;
+ }
+
+ // then: remove this items from the button bar
+ // do this backwards, to minimize the relayout efforts
+ for (int i=m_toolviews.size()-1; i >= (int)firstWrong; --i)
+ {
+ removeTab (m_widgetToId[m_toolviews[i]]);
+ }
+
+ // insert the reshuffled things in order :)
+ for (unsigned int i=0; i < toSort.size(); ++i)
+ {
+ ToolView *tv = toSort[i].tv;
+
+ m_toolviews[firstWrong+i] = tv;
+
+ // readd the button
+ int newId = m_widgetToId[tv];
+ appendTab (tv->icon, newId, tv->text);
+ connect(tab(newId),SIGNAL(clicked(int)),this,SLOT(tabClicked(int)));
+ tab(newId)->installEventFilter(this);
+
+ // reshuffle in splitter
+ m_ownSplit->moveToLast (tv);
+ }
+ }
+
+ // update last size if needed
+ updateLastSize ();
+
+ // restore the own splitter sizes
+ QValueList<int> s = config->readIntListEntry (QString ("Kate-MDI-Sidebar-%1-Splitter").arg(position()));
+ m_ownSplit->setSizes (s);
+
+ // show only correct toolviews, remember persistent values ;)
+ bool anyVis = false;
+ for ( unsigned int i=0; i < m_toolviews.size(); ++i )
+ {
+ ToolView *tv = m_toolviews[i];
+
+ tv->persistent = config->readBoolEntry (QString ("Kate-MDI-ToolView-%1-Persistent").arg(tv->id), false);
+ tv->setVisible (config->readBoolEntry (QString ("Kate-MDI-ToolView-%1-Visible").arg(tv->id), false));
+
+ if (!anyVis)
+ anyVis = tv->visible();
+
+ setTab (m_widgetToId[tv],tv->visible());
+
+ if (tv->visible())
+ tv->show();
+ else
+ tv->hide ();
+ }
+
+ if (anyVis)
+ m_ownSplit->show();
+ else
+ m_ownSplit->hide();
+}
+
+void Sidebar::saveSession (KConfig *config)
+{
+ // store the own splitter sizes
+ QValueList<int> s = m_ownSplit->sizes();
+ config->writeEntry (QString ("Kate-MDI-Sidebar-%1-Splitter").arg(position()), s);
+
+ // store the data about all toolviews in this sidebar ;)
+ for ( unsigned int i=0; i < m_toolviews.size(); ++i )
+ {
+ ToolView *tv = m_toolviews[i];
+
+ config->writeEntry (QString ("Kate-MDI-ToolView-%1-Position").arg(tv->id), tv->sidebar()->position());
+ config->writeEntry (QString ("Kate-MDI-ToolView-%1-Sidebar-Position").arg(tv->id), i);
+ config->writeEntry (QString ("Kate-MDI-ToolView-%1-Visible").arg(tv->id), tv->visible());
+ config->writeEntry (QString ("Kate-MDI-ToolView-%1-Persistent").arg(tv->id), tv->persistent);
+ }
+}
+
+//END SIDEBAR
+
+
+//BEGIN MAIN WINDOW
+
+MainWindow::MainWindow (QWidget* parentWidget, const char* name)
+ : KParts::MainWindow( parentWidget, name)
+ , m_sidebarsVisible(true)
+ , m_restoreConfig (0)
+ , m_guiClient (new GUIClient (this))
+{
+ // init the internal widgets
+ QHBox *hb = new QHBox (this);
+ setCentralWidget(hb);
+
+ m_sidebars[KMultiTabBar::Left] = new Sidebar (KMultiTabBar::Left, this, hb);
+
+ m_hSplitter = new Splitter (Qt::Horizontal, hb);
+ m_hSplitter->setOpaqueResize( KGlobalSettings::opaqueResize() );
+
+ m_sidebars[KMultiTabBar::Left]->setSplitter (m_hSplitter);
+
+ QVBox *vb = new QVBox (m_hSplitter);
+ m_hSplitter->setCollapsible(vb, false);
+
+ m_sidebars[KMultiTabBar::Top] = new Sidebar (KMultiTabBar::Top, this, vb);
+
+ m_vSplitter = new Splitter (Qt::Vertical, vb);
+ m_vSplitter->setOpaqueResize( KGlobalSettings::opaqueResize() );
+
+ m_sidebars[KMultiTabBar::Top]->setSplitter (m_vSplitter);
+
+ m_centralWidget = new QVBox (m_vSplitter);
+ m_vSplitter->setCollapsible(m_centralWidget, false);
+
+ m_sidebars[KMultiTabBar::Bottom] = new Sidebar (KMultiTabBar::Bottom, this, vb);
+ m_sidebars[KMultiTabBar::Bottom]->setSplitter (m_vSplitter);
+
+ m_sidebars[KMultiTabBar::Right] = new Sidebar (KMultiTabBar::Right, this, hb);
+ m_sidebars[KMultiTabBar::Right]->setSplitter (m_hSplitter);
+}
+
+MainWindow::~MainWindow ()
+{
+ // cu toolviews
+ while (!m_toolviews.isEmpty())
+ delete m_toolviews[0];
+
+ // seems like we really should delete this by hand ;)
+ delete m_centralWidget;
+
+ for (unsigned int i=0; i < 4; ++i)
+ delete m_sidebars[i];
+}
+
+QWidget *MainWindow::centralWidget () const
+{
+ return m_centralWidget;
+}
+
+ToolView *MainWindow::createToolView (const QString &identifier, KMultiTabBar::KMultiTabBarPosition pos, const QPixmap &icon, const QString &text)
+{
+ if (m_idToWidget[identifier])
+ return 0;
+
+ // try the restore config to figure out real pos
+ if (m_restoreConfig && m_restoreConfig->hasGroup (m_restoreGroup))
+ {
+ m_restoreConfig->setGroup (m_restoreGroup);
+ pos = (KMultiTabBar::KMultiTabBarPosition) m_restoreConfig->readNumEntry (QString ("Kate-MDI-ToolView-%1-Position").arg(identifier), pos);
+ }
+
+ ToolView *v = m_sidebars[pos]->addWidget (icon, text, 0);
+ v->id = identifier;
+
+ m_idToWidget.insert (identifier, v);
+ m_toolviews.push_back (v);
+
+ // register for menu stuff
+ m_guiClient->registerToolView (v);
+
+ return v;
+}
+
+ToolView *MainWindow::toolView (const QString &identifier) const
+{
+ return m_idToWidget[identifier];
+}
+
+void MainWindow::toolViewDeleted (ToolView *widget)
+{
+ if (!widget)
+ return;
+
+ if (widget->mainWindow() != this)
+ return;
+
+ // unregister from menu stuff
+ m_guiClient->unregisterToolView (widget);
+
+ widget->sidebar()->removeWidget (widget);
+
+ m_idToWidget.remove (widget->id);
+ m_toolviews.remove (widget);
+}
+
+void MainWindow::setSidebarsVisible( bool visible )
+{
+ m_sidebarsVisible = visible;
+
+ m_sidebars[0]->setShown(visible);
+ m_sidebars[1]->setShown(visible);
+ m_sidebars[2]->setShown(visible);
+ m_sidebars[3]->setShown(visible);
+
+ m_guiClient->updateSidebarsVisibleAction();
+
+ // show information message box, if the users hides the sidebars
+ if( !m_sidebarsVisible )
+ {
+ KMessageBox::information( this,
+ i18n("<qt>You are about to hide the sidebars. With "
+ "hidden sidebars it is not possible to directly "
+ "access the tool views with the mouse anymore, "
+ "so if you need to access the sidebars again "
+ "invoke <b>Window &gt; Tool Views &gt; Show Sidebars</b> "
+ "in the menu. It is still possible to show/hide "
+ "the tool views with the assigned shortcuts.</qt>"),
+ QString::null, "Kate hide sidebars notification message" );
+ }
+}
+
+bool MainWindow::sidebarsVisible() const
+{
+ return m_sidebarsVisible;
+}
+
+void MainWindow::setToolViewStyle (KMultiTabBar::KMultiTabBarStyle style)
+{
+ m_sidebars[0]->setStyle(style);
+ m_sidebars[1]->setStyle(style);
+ m_sidebars[2]->setStyle(style);
+ m_sidebars[3]->setStyle(style);
+}
+
+KMultiTabBar::KMultiTabBarStyle MainWindow::toolViewStyle () const
+{
+ // all sidebars have the same style, so just take Top
+ return m_sidebars[KMultiTabBar::Top]->tabStyle();
+}
+
+bool MainWindow::moveToolView (ToolView *widget, KMultiTabBar::KMultiTabBarPosition pos)
+{
+ if (!widget || widget->mainWindow() != this)
+ return false;
+
+ // try the restore config to figure out real pos
+ if (m_restoreConfig && m_restoreConfig->hasGroup (m_restoreGroup))
+ {
+ m_restoreConfig->setGroup (m_restoreGroup);
+ pos = (KMultiTabBar::KMultiTabBarPosition) m_restoreConfig->readNumEntry (QString ("Kate-MDI-ToolView-%1-Position").arg(widget->id), pos);
+ }
+
+ m_sidebars[pos]->addWidget (widget->icon, widget->text, widget);
+
+ return true;
+}
+
+bool MainWindow::showToolView (ToolView *widget)
+{
+ if (!widget || widget->mainWindow() != this)
+ return false;
+
+ // skip this if happens during restoring, or we will just see flicker
+ if (m_restoreConfig && m_restoreConfig->hasGroup (m_restoreGroup))
+ return true;
+
+ return widget->sidebar()->showWidget (widget);
+}
+
+bool MainWindow::hideToolView (ToolView *widget)
+{
+ if (!widget || widget->mainWindow() != this)
+ return false;
+
+ // skip this if happens during restoring, or we will just see flicker
+ if (m_restoreConfig && m_restoreConfig->hasGroup (m_restoreGroup))
+ return true;
+
+ return widget->sidebar()->hideWidget (widget);
+}
+
+void MainWindow::startRestore (KConfig *config, const QString &group)
+{
+ // first save this stuff
+ m_restoreConfig = config;
+ m_restoreGroup = group;
+
+ if (!m_restoreConfig || !m_restoreConfig->hasGroup (m_restoreGroup))
+ {
+ // set sane default sizes
+ QValueList<int> hs;
+ hs << 200 << 100 << 200;
+ QValueList<int> vs;
+ vs << 150 << 100 << 200;
+
+ m_sidebars[0]->setLastSize (hs[0]);
+ m_sidebars[1]->setLastSize (hs[2]);
+ m_sidebars[2]->setLastSize (vs[0]);
+ m_sidebars[3]->setLastSize (vs[2]);
+
+ m_hSplitter->setSizes(hs);
+ m_vSplitter->setSizes(vs);
+ return;
+ }
+
+ // apply size once, to get sizes ready ;)
+ m_restoreConfig->setGroup (m_restoreGroup);
+ restoreWindowSize (m_restoreConfig);
+
+ m_restoreConfig->setGroup (m_restoreGroup);
+
+ // get main splitter sizes ;)
+ QValueList<int> hs = m_restoreConfig->readIntListEntry ("Kate-MDI-H-Splitter");
+ QValueList<int> vs = m_restoreConfig->readIntListEntry ("Kate-MDI-V-Splitter");
+
+ m_sidebars[0]->setLastSize (hs[0]);
+ m_sidebars[1]->setLastSize (hs[2]);
+ m_sidebars[2]->setLastSize (vs[0]);
+ m_sidebars[3]->setLastSize (vs[2]);
+
+ m_hSplitter->setSizes(hs);
+ m_vSplitter->setSizes(vs);
+
+ setToolViewStyle( (KMultiTabBar::KMultiTabBarStyle)m_restoreConfig->readNumEntry ("Kate-MDI-Sidebar-Style", (int)toolViewStyle()) );
+
+ // after reading m_sidebarsVisible, update the GUI toggle action
+ m_sidebarsVisible = m_restoreConfig->readBoolEntry ("Kate-MDI-Sidebar-Visible", true );
+ m_guiClient->updateSidebarsVisibleAction();
+}
+
+void MainWindow::finishRestore ()
+{
+ if (!m_restoreConfig)
+ return;
+
+ if (m_restoreConfig->hasGroup (m_restoreGroup))
+ {
+ // apply all settings, like toolbar pos and more ;)
+ applyMainWindowSettings(m_restoreConfig, m_restoreGroup);
+
+ // reshuffle toolviews only if needed
+ m_restoreConfig->setGroup (m_restoreGroup);
+ for ( unsigned int i=0; i < m_toolviews.size(); ++i )
+ {
+ KMultiTabBar::KMultiTabBarPosition newPos = (KMultiTabBar::KMultiTabBarPosition) m_restoreConfig->readNumEntry (QString ("Kate-MDI-ToolView-%1-Position").arg(m_toolviews[i]->id), m_toolviews[i]->sidebar()->position());
+
+ if (m_toolviews[i]->sidebar()->position() != newPos)
+ {
+ moveToolView (m_toolviews[i], newPos);
+ }
+ }
+
+ // restore the sidebars
+ m_restoreConfig->setGroup (m_restoreGroup);
+ for (unsigned int i=0; i < 4; ++i)
+ m_sidebars[i]->restoreSession (m_restoreConfig);
+ }
+
+ // clear this stuff, we are done ;)
+ m_restoreConfig = 0;
+ m_restoreGroup = "";
+}
+
+void MainWindow::saveSession (KConfig *config, const QString &group)
+{
+ if (!config)
+ return;
+
+ saveMainWindowSettings (config, group);
+
+ config->setGroup (group);
+
+ // save main splitter sizes ;)
+ QValueList<int> hs = m_hSplitter->sizes();
+ QValueList<int> vs = m_vSplitter->sizes();
+
+ if (hs[0] <= 2 && !m_sidebars[0]->splitterVisible ())
+ hs[0] = m_sidebars[0]->lastSize();
+ if (hs[2] <= 2 && !m_sidebars[1]->splitterVisible ())
+ hs[2] = m_sidebars[1]->lastSize();
+ if (vs[0] <= 2 && !m_sidebars[2]->splitterVisible ())
+ vs[0] = m_sidebars[2]->lastSize();
+ if (vs[2] <= 2 && !m_sidebars[3]->splitterVisible ())
+ vs[2] = m_sidebars[3]->lastSize();
+
+ config->writeEntry ("Kate-MDI-H-Splitter", hs);
+ config->writeEntry ("Kate-MDI-V-Splitter", vs);
+
+ // save sidebar style
+ config->writeEntry ("Kate-MDI-Sidebar-Style", (int)toolViewStyle());
+ config->writeEntry ("Kate-MDI-Sidebar-Visible", m_sidebarsVisible );
+
+ // save the sidebars
+ for (unsigned int i=0; i < 4; ++i)
+ m_sidebars[i]->saveSession (config);
+}
+
+//END MAIN WINDOW
+
+} // namespace KateMDI
+
+// kate: space-indent on; indent-width 2;
diff --git a/kate/app/katemdi.h b/kate/app/katemdi.h
new file mode 100644
index 000000000..2aa6429bd
--- /dev/null
+++ b/kate/app/katemdi.h
@@ -0,0 +1,442 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 2005 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2002, 2003 Joseph Wenninger <jowenn@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KATE_MDI_H__
+#define __KATE_MDI_H__
+
+#include <kparts/mainwindow.h>
+
+#include <kmultitabbar.h>
+#include <kxmlguiclient.h>
+#include <kaction.h>
+
+#include <qdict.h>
+#include <qintdict.h>
+#include <qmap.h>
+#include <qsplitter.h>
+#include <qpixmap.h>
+#include <qptrlist.h>
+
+namespace KateMDI {
+
+
+/** This class is needed because QSplitter cant return an index for a widget. */
+class Splitter : public QSplitter
+{
+ Q_OBJECT
+
+ public:
+ Splitter(Orientation o, QWidget* parent=0, const char* name=0);
+ ~Splitter();
+
+ /** Since there is supposed to be only 2 childs of a katesplitter,
+ * any child other than the last is the first.
+ * This method uses QSplitter::idAfter(widget) which
+ * returns 0 if there is no widget after this one.
+ * This results in an error if widget is not a child
+ * in this splitter */
+ bool isLastChild(QWidget* w) const;
+
+ int idAfter ( QWidget * w ) const;
+};
+
+class ToggleToolViewAction : public KToggleAction
+{
+ Q_OBJECT
+
+ public:
+ ToggleToolViewAction ( const QString& text, const KShortcut& cut,
+ class ToolView *tv, QObject* parent = 0, const char* name = 0 );
+
+ virtual ~ToggleToolViewAction();
+
+ protected slots:
+ void slotToggled(bool);
+ void visibleChanged(bool);
+
+ private:
+ ToolView *m_tv;
+};
+
+class GUIClient : public QObject, public KXMLGUIClient
+{
+ Q_OBJECT
+
+ public:
+ GUIClient ( class MainWindow *mw );
+ virtual ~GUIClient();
+
+ void registerToolView (ToolView *tv);
+ void unregisterToolView (ToolView *tv);
+ void updateSidebarsVisibleAction();
+
+ private slots:
+ void clientAdded( KXMLGUIClient *client );
+ void updateActions();
+
+ private:
+ MainWindow *m_mw;
+ KToggleAction *m_showSidebarsAction;
+ QPtrList<KAction> m_toolViewActions;
+ QMap<ToolView*, KAction*> m_toolToAction;
+ KActionMenu *m_toolMenu;
+};
+
+class ToolView : public QVBox
+{
+ Q_OBJECT
+
+ friend class Sidebar;
+ friend class MainWindow;
+ friend class GUIClient;
+ friend class ToggleToolViewAction;
+
+ protected:
+ /**
+ * ToolView
+ * Objects of this clas represent a toolview in the mainwindow
+ * you should only add one widget as child to this toolview, it will
+ * be automatically set to be the focus proxy of the toolview
+ * @param mainwin main window for this toolview
+ * @param sidebar sidebar of this toolview
+ * @param parent parent widget, e.g. the splitter of one of the sidebars
+ */
+ ToolView (class MainWindow *mainwin, class Sidebar *sidebar, QWidget *parent);
+
+ public:
+ /**
+ * destuct me, this is allowed for all, will care itself that the toolview is removed
+ * from the mainwindow and sidebar
+ */
+ virtual ~ToolView ();
+
+ signals:
+ /**
+ * toolview hidden or shown
+ * @param bool is this toolview made visible?
+ */
+ void visibleChanged (bool visible);
+
+ /**
+ * some internal methodes needed by the main window and the sidebars
+ */
+ protected:
+ MainWindow *mainWindow () { return m_mainWin; }
+
+ Sidebar *sidebar () { return m_sidebar; }
+
+ void setVisible (bool vis);
+
+ public:
+ bool visible () const;
+
+ protected:
+ void childEvent ( QChildEvent *ev );
+
+ private:
+ MainWindow *m_mainWin;
+ Sidebar *m_sidebar;
+
+ /**
+ * unique id
+ */
+ QString id;
+
+ /**
+ * is visible in sidebar
+ */
+ bool m_visible;
+
+ /**
+ * is this view persistent?
+ */
+ bool persistent;
+
+ QPixmap icon;
+ QString text;
+};
+
+class Sidebar : public KMultiTabBar
+{
+ Q_OBJECT
+
+ public:
+ Sidebar (KMultiTabBar::KMultiTabBarPosition pos, class MainWindow *mainwin, QWidget *parent);
+ virtual ~Sidebar ();
+
+ void setSplitter (Splitter *sp);
+
+ public:
+ ToolView *addWidget (const QPixmap &icon, const QString &text, ToolView *widget);
+ bool removeWidget (ToolView *widget);
+
+ bool showWidget (ToolView *widget);
+ bool hideWidget (ToolView *widget);
+
+ void setLastSize (int s) { m_lastSize = s; }
+ int lastSize () const { return m_lastSize; }
+ void updateLastSize ();
+
+ bool splitterVisible () const { return m_ownSplit->isVisible(); }
+
+ void restoreSession ();
+
+ /**
+ * restore the current session config from given object, use current group
+ * @param config config object to use
+ */
+ void restoreSession (KConfig *config);
+
+ /**
+ * save the current session config to given object, use current group
+ * @param config config object to use
+ */
+ void saveSession (KConfig *config);
+
+ public slots:
+ // reimplemented, to block a show() call if we have no children or if
+ // all sidebars are forced hidden.
+ virtual void show();
+
+ private slots:
+ void tabClicked(int);
+
+ protected:
+ bool eventFilter(QObject *obj, QEvent *ev);
+
+ private slots:
+ void buttonPopupActivate (int id);
+
+ private:
+ MainWindow *m_mainWin;
+
+ KMultiTabBar::KMultiTabBarPosition m_pos;
+ Splitter *m_splitter;
+ KMultiTabBar *m_tabBar;
+ Splitter *m_ownSplit;
+
+ QIntDict<ToolView> m_idToWidget;
+ QMap<ToolView*, int> m_widgetToId;
+
+ /**
+ * list of all toolviews around in this sidebar
+ */
+ QValueList<ToolView*> m_toolviews;
+
+ int m_lastSize;
+
+ int m_popupButton;
+};
+
+class MainWindow : public KParts::MainWindow
+{
+ Q_OBJECT
+
+ friend class ToolView;
+
+ //
+ // Constructor area
+ //
+ public:
+ /**
+ * Constructor
+ */
+ MainWindow (QWidget* parentWidget = 0, const char* name = 0);
+
+ /**
+ * Destructor
+ */
+ virtual ~MainWindow ();
+
+ //
+ // public interfaces
+ //
+ public:
+ /**
+ * central widget ;)
+ * use this as parent for your content
+ * this widget will get focus if a toolview is hidden
+ * @return central widget
+ */
+ QWidget *centralWidget () const;
+
+ /**
+ * add a given widget to the given sidebar if possible, name is very important
+ * @param identifier unique identifier for this toolview
+ * @param pos position for the toolview, if we are in session restore, this is only a preference
+ * @param icon icon to use for the toolview
+ * @param text text to use in addition to icon
+ * @return created toolview on success or 0
+ */
+ ToolView *createToolView (const QString &identifier, KMultiTabBar::KMultiTabBarPosition pos, const QPixmap &icon, const QString &text);
+
+ /**
+ * give you handle to toolview for the given name, 0 if no toolview around
+ * @param identifier toolview name
+ * @return toolview if existing, else 0
+ */
+ ToolView *toolView (const QString &identifier) const;
+
+ /**
+ * set the toolview's tabbar style.
+ * @param style the tabbar style.
+ */
+ void setToolViewStyle (KMultiTabBar::KMultiTabBarStyle style);
+
+ /**
+ * get the toolview's tabbar style. Call this before @p startRestore(),
+ * otherwise you overwrite the usersettings.
+ * @return toolview's tabbar style
+ */
+ KMultiTabBar::KMultiTabBarStyle toolViewStyle () const;
+
+ /**
+ * get the sidebars' visibility.
+ * @return false, if the sidebars' visibility is forced hidden, otherwise true
+ */
+ bool sidebarsVisible() const;
+
+ public slots:
+ /**
+ * set the sidebars' visibility to @p visible. If false, the sidebars
+ * are @e always hidden. Usually you do not have to call this because
+ * the user can set this in the menu.
+ * @param visible sidebars visibility
+ */
+ void setSidebarsVisible( bool visible );
+
+ protected:
+ /**
+ * called by toolview destructor
+ * @param widget toolview which is destroyed
+ */
+ void toolViewDeleted (ToolView *widget);
+
+ /**
+ * modifiers for existing toolviews
+ */
+ public:
+ /**
+ * move a toolview around
+ * @param widget toolview to move
+ * @param pos position to move too, during session restore, only preference
+ * @return success
+ */
+ bool moveToolView (ToolView *widget, KMultiTabBar::KMultiTabBarPosition pos);
+
+ /**
+ * show given toolview, discarded while session restore
+ * @param widget toolview to show
+ * @return success
+ */
+ bool showToolView (ToolView *widget);
+
+ /**
+ * hide given toolview, discarded while session restore
+ * @param widget toolview to hide
+ * @return success
+ */
+ bool hideToolView (ToolView *widget);
+
+ /**
+ * session saving and restore stuff
+ */
+ public:
+ /**
+ * start the restore
+ * @param config config object to use
+ * @param group config group to use
+ */
+ void startRestore (KConfig *config, const QString &group);
+
+ /**
+ * finish the restore
+ */
+ void finishRestore ();
+
+ /**
+ * save the current session config to given object and group
+ * @param config config object to use
+ * @param group config group to use
+ */
+ void saveSession (KConfig *config, const QString &group);
+
+ /**
+ * internal data ;)
+ */
+ private:
+ /**
+ * map identifiers to widgets
+ */
+ QDict<ToolView> m_idToWidget;
+
+ /**
+ * list of all toolviews around
+ */
+ QValueList<ToolView*> m_toolviews;
+
+ /**
+ * widget, which is the central part of the
+ * main window ;)
+ */
+ QWidget *m_centralWidget;
+
+ /**
+ * horizontal splitter
+ */
+ Splitter *m_hSplitter;
+
+ /**
+ * vertical splitter
+ */
+ Splitter *m_vSplitter;
+
+ /**
+ * sidebars for the four sides
+ */
+ Sidebar *m_sidebars[4];
+
+ /**
+ * sidebars state.
+ */
+ bool m_sidebarsVisible;
+
+ /**
+ * config object for session restore, only valid between
+ * start and finish restore calls
+ */
+ KConfig *m_restoreConfig;
+
+ /**
+ * restore group
+ */
+ QString m_restoreGroup;
+
+ /**
+ * out guiclient
+ */
+ GUIClient *m_guiClient;
+};
+
+}
+
+#endif
+
+// kate: space-indent on; indent-width 2;
diff --git a/kate/app/katemwmodonhddialog.cpp b/kate/app/katemwmodonhddialog.cpp
new file mode 100644
index 000000000..efbee3cb5
--- /dev/null
+++ b/kate/app/katemwmodonhddialog.cpp
@@ -0,0 +1,281 @@
+/*
+ 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.
+
+ ---
+ Copyright (C) 2004, Anders Lund <anders@alweb.dk>
+*/
+
+#include "katemwmodonhddialog.h"
+#include "katemwmodonhddialog.moc"
+
+#include "katedocmanager.h"
+
+#include <kate/document.h>
+
+#include <kiconloader.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kprocio.h>
+#include <krun.h>
+#include <ktempfile.h>
+#include <kpushbutton.h>
+
+#include <qlabel.h>
+#include <qlistview.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qwhatsthis.h>
+#include <qvbox.h>
+
+class KateDocItem : public QCheckListItem
+{
+ public:
+ KateDocItem( Kate::Document *doc, const QString &status, KListView *lv )
+ : QCheckListItem( lv, doc->url().prettyURL(), CheckBox ),
+ document( doc )
+ {
+ setText( 1, status );
+ if ( ! doc->isModified() )
+ setOn( On );
+ }
+ ~KateDocItem() {};
+
+ Kate::Document *document;
+};
+
+
+KateMwModOnHdDialog::KateMwModOnHdDialog( DocVector docs, QWidget *parent, const char *name )
+ : KDialogBase( parent, name, true, i18n("Documents Modified on Disk"),
+ User1|User2|User3, User3, false,
+ KGuiItem (i18n("&Ignore"), "fileclose"),
+ KGuiItem (i18n("&Overwrite"), "filesave"),
+ KGuiItem (i18n("&Reload"), "reload") )
+{
+ setButtonWhatsThis( User1, i18n(
+ "Removes the modified flag from the selected documents and closes the "
+ "dialog if there are no more unhandled documents.") );
+ setButtonWhatsThis( User2, i18n(
+ "Overwrite selected documents, discarding the disk changes and closes the "
+ "dialog if there are no more unhandled documents.") );
+ setButtonWhatsThis( User3, i18n(
+ "Reloads the selected documents from disk and closes the dialog if there "
+ "are no more unhandled documents.") );
+
+ QVBox *w = makeVBoxMainWidget();
+ w->setSpacing( KDialog::spacingHint() );
+
+ QHBox *lo1 = new QHBox( w );
+
+ // dialog text
+ QLabel *icon = new QLabel( lo1 );
+ icon->setPixmap( DesktopIcon("messagebox_warning") );
+
+ QLabel *t = new QLabel( i18n(
+ "<qt>The documents listed below has changed on disk.<p>Select one "
+ "or more at the time and press an action button until the list is empty.</qt>"), lo1 );
+ lo1->setStretchFactor( t, 1000 );
+
+ // document list
+ lvDocuments = new KListView( w );
+ lvDocuments->addColumn( i18n("Filename") );
+ lvDocuments->addColumn( i18n("Status on Disk") );
+ lvDocuments->setSelectionMode( QListView::Single );
+
+ QStringList l;
+ l << "" << i18n("Modified") << i18n("Created") << i18n("Deleted");
+ for ( uint i=0; i < docs.size(); i++ )
+ new KateDocItem( docs[i], l[ (uint)KateDocManager::self()->documentInfo( docs[i] )->modifiedOnDiscReason ], lvDocuments );
+
+ connect( lvDocuments, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()) );
+
+ // diff button
+ QHBox *lo2 = new QHBox ( w );
+ QWidget *d = new QWidget (lo2);
+ lo2->setStretchFactor (d, 2);
+ btnDiff = new KPushButton( KGuiItem (i18n("&View Difference"), "edit"), lo2 );
+
+ QWhatsThis::add( btnDiff, i18n(
+ "Calculates the difference between the the editor contents and the disk "
+ "file for the selected document, and shows the difference with the "
+ "default application. Requires diff(1).") );
+ connect( btnDiff, SIGNAL(clicked()), this, SLOT(slotDiff()) );
+
+ slotSelectionChanged();
+ m_tmpfile = 0;
+}
+
+KateMwModOnHdDialog::~KateMwModOnHdDialog()
+{
+}
+
+void KateMwModOnHdDialog::slotUser1()
+{
+ handleSelected( Ignore );
+}
+
+void KateMwModOnHdDialog::slotUser2()
+{
+ handleSelected( Overwrite );
+}
+
+void KateMwModOnHdDialog::slotUser3()
+{
+ handleSelected( Reload );
+}
+
+void KateMwModOnHdDialog::handleSelected( int action )
+{
+ // collect all items we can remove
+ QValueList<QListViewItem *> itemsToDelete;
+ for ( QListViewItemIterator it ( lvDocuments ); it.current(); ++it )
+ {
+ KateDocItem *item = static_cast<KateDocItem *>(it.current());
+
+ if ( item->isOn() )
+ {
+ int reason = (int)KateDocManager::self()->documentInfo( item->document )->modifiedOnDiscReason;
+ bool succes = true;
+
+ Kate::DocumentExt *dext = documentExt( item->document );
+ if ( ! dext ) continue;
+
+ dext->setModifiedOnDisk( 0 );
+ switch ( action )
+ {
+ case Overwrite:
+ succes = item->document->save();
+ if ( ! succes )
+ {
+ KMessageBox::sorry( this,
+ i18n("Could not save the document \n'%1'").
+ arg( item->document->url().prettyURL() ) );
+ }
+ break;
+
+ case Reload:
+ item->document->reloadFile();
+ break;
+
+ default:
+ break;
+ }
+
+ if ( succes )
+ itemsToDelete.append (item);
+ else
+ dext->setModifiedOnDisk( reason );
+ }
+ }
+
+ // remove the marked items
+ for (unsigned int i=0; i < itemsToDelete.count(); ++i)
+ delete itemsToDelete[i];
+
+ // any documents left unhandled?
+ if ( ! lvDocuments->childCount() )
+ done( Ok );
+}
+
+void KateMwModOnHdDialog::slotSelectionChanged()
+{
+ // set the diff button enabled
+ btnDiff->setEnabled( lvDocuments->currentItem() &&
+ KateDocManager::self()->documentInfo( ((KateDocItem*)lvDocuments->currentItem())->document )->modifiedOnDiscReason != 3 );
+}
+
+// ### the code below is slightly modified from kdelibs/kate/part/katedialogs,
+// class KateModOnHdPrompt.
+void KateMwModOnHdDialog::slotDiff()
+{
+ if ( m_tmpfile ) // we are allready somewhere in this process.
+ return;
+
+ if ( ! lvDocuments->currentItem() )
+ return;
+
+ Kate::Document *doc = ((KateDocItem*)lvDocuments->currentItem())->document;
+
+ // don't try o diff a deleted file
+ if ( KateDocManager::self()->documentInfo( doc )->modifiedOnDiscReason == 3 )
+ return;
+
+ // Start a KProcess that creates a diff
+ KProcIO *p = new KProcIO();
+ p->setComm( KProcess::All );
+ *p << "diff" << "-u" << "-" << doc->url().path();
+ connect( p, SIGNAL(processExited(KProcess*)), this, SLOT(slotPDone(KProcess*)) );
+ connect( p, SIGNAL(readReady(KProcIO*)), this, SLOT(slotPRead(KProcIO*)) );
+
+ setCursor( WaitCursor );
+
+ p->start( KProcess::NotifyOnExit, true );
+
+ uint lastln = doc->numLines();
+ for ( uint l = 0; l < lastln; l++ )
+ p->writeStdin( doc->textLine( l ), l < lastln );
+
+ p->closeWhenDone();
+}
+
+void KateMwModOnHdDialog::slotPRead( KProcIO *p)
+{
+ // create a file for the diff if we haven't one allready
+ if ( ! m_tmpfile )
+ m_tmpfile = new KTempFile();
+ // put all the data we have in it
+ QString stmp;
+ bool dataRead = false;
+ while ( p->readln( stmp, false ) > -1 ) {
+ *m_tmpfile->textStream() << stmp << endl;
+ dataRead = true;
+ }
+
+ if (dataRead)
+ p->ackRead();
+}
+
+void KateMwModOnHdDialog::slotPDone( KProcess *p )
+{
+ setCursor( ArrowCursor );
+ if( ! m_tmpfile )
+ {
+ // dominik: there were only whitespace changes, so that the diff returned by
+ // diff(1) has 0 bytes. So slotPRead() is never called, as there is
+ // no data, so that m_tmpfile was never created and thus is NULL.
+ // NOTE: would be nice, if we could produce a fake-diff, so that kompare
+ // tells us "The files are identical". Right now, we get an ugly
+ // "Could not parse diff output".
+ m_tmpfile = new KTempFile();
+ }
+ m_tmpfile->close();
+
+ if ( ! p->normalExit() /*|| p->exitStatus()*/ )
+ {
+ KMessageBox::sorry( this,
+ i18n("The diff command failed. Please make sure that "
+ "diff(1) is installed and in your PATH."),
+ i18n("Error Creating Diff") );
+ delete m_tmpfile;
+ m_tmpfile = 0;
+ return;
+ }
+
+ KRun::runURL( m_tmpfile->name(), "text/x-diff", true );
+ delete m_tmpfile;
+ m_tmpfile = 0;
+}
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/katemwmodonhddialog.h b/kate/app/katemwmodonhddialog.h
new file mode 100644
index 000000000..86ecd252a
--- /dev/null
+++ b/kate/app/katemwmodonhddialog.h
@@ -0,0 +1,61 @@
+/*
+ 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.
+
+ ---
+ Copyright (C) 2004, Anders Lund <anders@alweb.dk>
+*/
+
+#ifndef _KATE_MW_MODONHD_DIALOG_H_
+#define _KATE_MW_MODONHD_DIALOG_H_
+
+#include <kdialogbase.h>
+#include <qptrvector.h>
+#include <kate/document.h>
+
+typedef QPtrVector<Kate::Document> DocVector;
+class KProcIO;
+class KProcess;
+/**
+ * A dialog for handling multiple documents modified on disk
+ * from within KateMainWindow
+ */
+class KateMwModOnHdDialog : public KDialogBase
+{
+ Q_OBJECT
+ public:
+ KateMwModOnHdDialog( DocVector docs, QWidget *parent=0, const char *name=0 );
+ ~KateMwModOnHdDialog();
+
+ protected slots:
+ void slotUser1();
+ void slotUser2();
+ void slotUser3();
+
+ private slots:
+ void slotDiff();
+ void slotSelectionChanged();
+ void slotPRead(KProcIO*);
+ void slotPDone(KProcess*);
+
+ private:
+ enum Action { Ignore, Overwrite, Reload };
+ void handleSelected( int action );
+ class KListView *lvDocuments;
+ class QPushButton *btnDiff;
+ class KTempFile *m_tmpfile;
+};
+
+#endif // _KATE_MW_MODONHD_DIALOG_H_
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/katepluginmanager.cpp b/kate/app/katepluginmanager.cpp
new file mode 100644
index 000000000..e3390e6a2
--- /dev/null
+++ b/kate/app/katepluginmanager.cpp
@@ -0,0 +1,221 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ 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 "katepluginmanager.h"
+#include "katepluginmanager.moc"
+
+#include "kateapp.h"
+#include "katemainwindow.h"
+
+#include "../interfaces/application.h"
+
+#include <kconfig.h>
+#include <qstringlist.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <qfile.h>
+
+KatePluginManager::KatePluginManager(QObject *parent) : QObject (parent)
+{
+ m_pluginManager = new Kate::PluginManager (this);
+ setupPluginList ();
+
+ loadConfig ();
+ loadAllEnabledPlugins ();
+}
+
+KatePluginManager::~KatePluginManager()
+{
+ // first write config
+ writeConfig ();
+
+ // than unload the plugins
+ unloadAllPlugins ();
+}
+
+KatePluginManager *KatePluginManager::self()
+{
+ return KateApp::self()->pluginManager ();
+}
+
+void KatePluginManager::setupPluginList ()
+{
+ QValueList<KService::Ptr> traderList= KTrader::self()->query("Kate/Plugin", "(not ('Kate/ProjectPlugin' in ServiceTypes)) and (not ('Kate/InitPlugin' in ServiceTypes))");
+
+ for(KTrader::OfferList::Iterator it(traderList.begin()); it != traderList.end(); ++it)
+ {
+ KService::Ptr ptr = (*it);
+
+ QString pVersion = ptr->property("X-Kate-Version").toString();
+
+// if ((pVersion >= "2.5") && (pVersion <= KateApp::kateVersion(false)))
+ if (pVersion == "2.5")
+ {
+ KatePluginInfo info;
+
+ info.load = false;
+ info.service = ptr;
+ info.plugin = 0L;
+
+ m_pluginList.push_back (info);
+ }
+ }
+}
+
+void KatePluginManager::loadConfig ()
+{
+ KateApp::self()->config()->setGroup("Kate Plugins");
+
+ for (unsigned int i=0; i < m_pluginList.size(); ++i)
+ m_pluginList[i].load = KateApp::self()->config()->readBoolEntry (m_pluginList[i].service->library(), false) ||
+ KateApp::self()->config()->readBoolEntry (m_pluginList[i].service->property("X-Kate-PluginName").toString(),false);
+}
+
+void KatePluginManager::writeConfig ()
+{
+ KateApp::self()->config()->setGroup("Kate Plugins");
+
+ for (unsigned int i=0; i < m_pluginList.size(); ++i)
+ {
+ QString saveName=m_pluginList[i].service->property("X-Kate-PluginName").toString();
+
+ if (saveName.isEmpty())
+ saveName = m_pluginList[i].service->library();
+
+ KateApp::self()->config()->writeEntry (saveName, m_pluginList[i].load);
+ }
+}
+
+void KatePluginManager::loadAllEnabledPlugins ()
+{
+ for (unsigned int i=0; i < m_pluginList.size(); ++i)
+ {
+ if (m_pluginList[i].load)
+ loadPlugin (&m_pluginList[i]);
+ else
+ unloadPlugin (&m_pluginList[i]);
+ }
+}
+
+void KatePluginManager::unloadAllPlugins ()
+{
+ for (unsigned int i=0; i < m_pluginList.size(); ++i)
+ {
+ if (m_pluginList[i].plugin)
+ unloadPlugin (&m_pluginList[i]);
+ }
+}
+
+void KatePluginManager::enableAllPluginsGUI (KateMainWindow *win)
+{
+ for (unsigned int i=0; i < m_pluginList.size(); ++i)
+ {
+ if (m_pluginList[i].load)
+ enablePluginGUI (&m_pluginList[i], win);
+ }
+}
+
+void KatePluginManager::disableAllPluginsGUI (KateMainWindow *win)
+{
+ for (unsigned int i=0; i < m_pluginList.size(); ++i)
+ {
+ if (m_pluginList[i].load)
+ disablePluginGUI (&m_pluginList[i], win);
+ }
+}
+
+void KatePluginManager::loadPlugin (KatePluginInfo *item)
+{
+ QString pluginName=item->service->property("X-Kate-PluginName").toString();
+
+ if (pluginName.isEmpty())
+ pluginName=item->service->library();
+
+ item->load = (item->plugin = Kate::createPlugin (QFile::encodeName(item->service->library()), Kate::application(), 0, pluginName));
+}
+
+void KatePluginManager::unloadPlugin (KatePluginInfo *item)
+{
+ disablePluginGUI (item);
+ if (item->plugin) delete item->plugin;
+ item->plugin = 0L;
+ item->load = false;
+}
+
+void KatePluginManager::enablePluginGUI (KatePluginInfo *item, KateMainWindow *win)
+{
+ if (!item->plugin) return;
+ if (!Kate::pluginViewInterface(item->plugin)) return;
+
+ Kate::pluginViewInterface(item->plugin)->addView(win->mainWindow());
+}
+
+void KatePluginManager::enablePluginGUI (KatePluginInfo *item)
+{
+ if (!item->plugin) return;
+ if (!Kate::pluginViewInterface(item->plugin)) return;
+
+ for (uint i=0; i< KateApp::self()->mainWindows(); i++)
+ {
+ Kate::pluginViewInterface(item->plugin)->addView(KateApp::self()->mainWindow(i)->mainWindow());
+ }
+}
+
+void KatePluginManager::disablePluginGUI (KatePluginInfo *item, KateMainWindow *win)
+{
+ if (!item->plugin) return;
+ if (!Kate::pluginViewInterface(item->plugin)) return;
+
+ Kate::pluginViewInterface(item->plugin)->removeView(win->mainWindow());
+}
+
+void KatePluginManager::disablePluginGUI (KatePluginInfo *item)
+{
+ if (!item->plugin) return;
+ if (!Kate::pluginViewInterface(item->plugin)) return;
+
+ for (uint i=0; i< KateApp::self()->mainWindows(); i++)
+ {
+ Kate::pluginViewInterface(item->plugin)->removeView(KateApp::self()->mainWindow(i)->mainWindow());
+ }
+}
+
+Kate::Plugin *KatePluginManager::plugin(const QString &name)
+{
+ for (unsigned int i=0; i < m_pluginList.size(); ++i)
+ {
+ KatePluginInfo *info = &m_pluginList[i];
+ QString pluginName=info->service->property("X-Kate-PluginName").toString();
+ if (pluginName.isEmpty())
+ pluginName=info->service->library();
+ if (pluginName==name)
+ {
+ if (info->plugin)
+ return info->plugin;
+ else
+ break;
+ }
+ }
+ return 0;
+}
+
+bool KatePluginManager::pluginAvailable(const QString &){return false;}
+class Kate::Plugin *KatePluginManager::loadPlugin(const QString &,bool ){return 0;}
+void KatePluginManager::unloadPlugin(const QString &,bool){;}
diff --git a/kate/app/katepluginmanager.h b/kate/app/katepluginmanager.h
new file mode 100644
index 000000000..76f9578b2
--- /dev/null
+++ b/kate/app/katepluginmanager.h
@@ -0,0 +1,90 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KATE_PLUGINMANAGER_H__
+#define __KATE_PLUGINMANAGER_H__
+
+#include "katemain.h"
+
+#include "../interfaces/plugin.h"
+#include "../interfaces/pluginmanager.h"
+
+#include <ktrader.h>
+
+#include <qobject.h>
+#include <qvaluelist.h>
+
+class KatePluginInfo
+{
+ public:
+ bool load;
+ KService::Ptr service;
+ Kate::Plugin *plugin;
+};
+
+typedef QValueList<KatePluginInfo> KatePluginList;
+
+class KatePluginManager : public QObject
+{
+ Q_OBJECT
+
+ public:
+ KatePluginManager(QObject *parent);
+ ~KatePluginManager();
+
+ static KatePluginManager *self();
+
+ Kate::PluginManager *pluginManager () const { return m_pluginManager; };
+
+ void loadAllEnabledPlugins ();
+ void unloadAllPlugins ();
+
+ void enableAllPluginsGUI (KateMainWindow *win);
+ void disableAllPluginsGUI (KateMainWindow *win);
+
+ void loadConfig ();
+ void writeConfig ();
+
+ void loadPlugin (KatePluginInfo *item);
+ void unloadPlugin (KatePluginInfo *item);
+
+ void enablePluginGUI (KatePluginInfo *item, KateMainWindow *win);
+ void enablePluginGUI (KatePluginInfo *item);
+
+ void disablePluginGUI (KatePluginInfo *item, KateMainWindow *win);
+ void disablePluginGUI (KatePluginInfo *item);
+
+ inline KatePluginList & pluginList () { return m_pluginList; };
+
+ Kate::Plugin *plugin (const QString &name);
+ bool pluginAvailable (const QString &name);
+
+ Kate::Plugin *loadPlugin (const QString &name, bool permanent=true);
+ void unloadPlugin (const QString &name, bool permanent=true);
+
+ private:
+ Kate::PluginManager *m_pluginManager;
+
+ void setupPluginList ();
+
+ KatePluginList m_pluginList;
+};
+
+#endif
diff --git a/kate/app/katesavemodifieddialog.cpp b/kate/app/katesavemodifieddialog.cpp
new file mode 100644
index 000000000..51dc1ea61
--- /dev/null
+++ b/kate/app/katesavemodifieddialog.cpp
@@ -0,0 +1,226 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Joseph Wenninger <jowenn@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "katesavemodifieddialog.h"
+#include "katesavemodifieddialog.moc"
+
+#include <klocale.h>
+#include <qlistview.h>
+#include <klistview.h>
+#include <kguiitem.h>
+#include <kactivelabel.h>
+#include <kstdguiitem.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <kencodingfiledialog.h>
+#include <ktexteditor/encodinginterface.h>
+
+class AbstractKateSaveModifiedDialogCheckListItem:public QCheckListItem {
+public:
+ AbstractKateSaveModifiedDialogCheckListItem(QListViewItem *parent,const QString& title, const QString& url):QCheckListItem(parent,title,QCheckListItem::CheckBox) {
+ setText(1,url);
+ setOn(true);
+ setState(InitialState);
+ }
+ virtual ~AbstractKateSaveModifiedDialogCheckListItem() {
+ }
+ virtual bool synchronousSave(QWidget *dialogParent)=0;
+ enum STATE{InitialState,SaveOKState,SaveFailedState};
+ STATE state() const { return m_state;}
+ void setState(enum STATE state) {
+ m_state=state;
+ KIconLoader *loader = KGlobal::instance()->iconLoader();
+ switch (state) {
+ case InitialState:
+ setPixmap(0,QPixmap());
+ break;
+ case SaveOKState:
+ setPixmap(0,loader->loadIcon("ok",KIcon::NoGroup,height()));
+ break;
+ case SaveFailedState:
+ setPixmap(0,loader->loadIcon("cancel",KIcon::NoGroup,height()));
+ break;
+ }
+ }
+private:
+ STATE m_state;
+};
+
+class KateSaveModifiedDocumentCheckListItem:public AbstractKateSaveModifiedDialogCheckListItem {
+public:
+ KateSaveModifiedDocumentCheckListItem(QListViewItem *parent,Kate::Document *document):AbstractKateSaveModifiedDialogCheckListItem(parent,document->docName(),document->url().prettyURL()){
+ m_document=document;
+ }
+ virtual ~KateSaveModifiedDocumentCheckListItem() {
+ }
+ virtual bool synchronousSave(QWidget *dialogParent) {
+ if (m_document->url().isEmpty() ) {
+ KEncodingFileDialog::Result r=KEncodingFileDialog::getSaveURLAndEncoding(
+ KTextEditor::encodingInterface(m_document)->encoding(),QString::null,QString::null,dialogParent,i18n("Save As (%1)").arg(m_document->docName()));
+
+ m_document->setEncoding( r.encoding );
+ if (!r.URLs.isEmpty()) {
+ KURL tmp = r.URLs.first();
+ if ( !m_document->saveAs( tmp ) ) {
+ setState(SaveFailedState);
+ setText(1,m_document->url().prettyURL());
+ return false;
+ } else {
+ bool sc=m_document->waitSaveComplete();
+ setText(1,m_document->url().prettyURL());
+ if (!sc) {
+ setState(SaveFailedState);
+ return false;
+ } else {
+ setState(SaveOKState);
+ return true;
+ }
+ }
+ } else {
+ setState(SaveFailedState);
+ return false;
+ }
+ } else { //document has an exising location
+ if ( !m_document->save() ) {
+ setState(SaveFailedState);
+ setText(1,m_document->url().prettyURL());
+ return false;
+ } else {
+ bool sc=m_document->waitSaveComplete();
+ setText(1,m_document->url().prettyURL());
+ if (!sc) {
+ setState(SaveFailedState);
+ return false;
+ } else {
+ setState(SaveOKState);
+ return true;
+ }
+ }
+
+ }
+
+ return false;
+
+ }
+private:
+ Kate::Document *m_document;
+};
+
+KateSaveModifiedDialog::KateSaveModifiedDialog(QWidget *parent, QPtrList<Kate::Document> documents):
+ KDialogBase( parent, "KateSaveModifiedDialog", true, i18n("Save Documents"), Yes | No | Cancel) {
+
+ KGuiItem saveItem=KStdGuiItem::save();
+ saveItem.setText(i18n("&Save Selected"));
+ setButtonGuiItem(KDialogBase::Yes,saveItem);
+
+ setButtonGuiItem(KDialogBase::No,KStdGuiItem::dontSave());
+
+ KGuiItem cancelItem=KStdGuiItem::cancel();
+ cancelItem.setText(i18n("&Abort Closing"));
+ setButtonGuiItem(KDialogBase::Cancel,cancelItem);
+
+ QVBox *box=makeVBoxMainWidget();
+ new KActiveLabel(i18n("<qt>The following documents have been modified. Do you want to save them before closing?</qt>"),box);
+ m_list=new KListView(box);
+ m_list->addColumn(i18n("Title"));
+ m_list->addColumn(i18n("Location"));
+ m_list->setRootIsDecorated(true);
+ m_list->setResizeMode(QListView::LastColumn);
+ if (0) {
+ m_projectRoot=new QListViewItem(m_list,i18n("Projects"));
+ } else m_projectRoot=0;
+ if (documents.count()>0) {
+ m_documentRoot=new QListViewItem(m_list,i18n("Documents"));
+ const uint docCnt=documents.count();
+ for (uint i=0;i<docCnt;i++) {
+ new KateSaveModifiedDocumentCheckListItem(m_documentRoot,documents.at(i));
+ }
+ m_documentRoot->setOpen(true);
+ } else m_documentRoot=0;
+ //FIXME - Is this the best way?
+ connect(m_list, SIGNAL(clicked(QListViewItem *)), SLOT(slotItemSelected()));
+ connect(m_list, SIGNAL(doubleClicked(QListViewItem *)), SLOT(slotItemSelected()));
+ connect(m_list, SIGNAL(spacePressed(QListViewItem *)), SLOT(slotItemSelected()));
+ if(documents.count()>3) { //For 3 or less, it would be quicker just to tick or untick them yourself, so don't clutter the gui.
+ connect(new QPushButton(i18n("Se&lect All"),box),SIGNAL(clicked()),this,SLOT(slotSelectAll()));
+ }
+}
+
+KateSaveModifiedDialog::~KateSaveModifiedDialog() {
+}
+
+void KateSaveModifiedDialog::slotItemSelected() {
+ kdDebug(13001) << "slotItemSelected()" << endl;
+
+ for(QListViewItem *it=m_documentRoot->firstChild();it;it=it->nextSibling()) {
+ if(((QCheckListItem*)it)->isOn()) {
+ enableButton(KDialogBase::Yes, true);
+ return;
+ }
+ }
+ enableButton(KDialogBase::Yes, false);
+}
+
+static void selectItems(QListViewItem *root) {
+ if (!root) return;
+ for (QListViewItem *it=root->firstChild();it;it=it->nextSibling()) {
+ ((QCheckListItem*)it)->setOn(true);
+ }
+}
+
+void KateSaveModifiedDialog::slotSelectAll() {
+ selectItems(m_documentRoot);
+ slotItemSelected();
+}
+
+
+void KateSaveModifiedDialog::slotUser2() {
+ kdDebug(13001)<<"KateSaveModifiedDialog::slotYes()"<<endl;
+ if (doSave(m_documentRoot)) done(QDialog::Accepted);
+}
+
+void KateSaveModifiedDialog::slotUser1() {
+ done(QDialog::Accepted);
+}
+
+bool KateSaveModifiedDialog::doSave(QListViewItem *root) {
+ if (root) {
+ for (QListViewItem *it=root->firstChild();it;it=it->nextSibling()) {
+ AbstractKateSaveModifiedDialogCheckListItem *cit= (AbstractKateSaveModifiedDialogCheckListItem*)it;
+ if (cit->isOn() && (cit->state()!=AbstractKateSaveModifiedDialogCheckListItem::SaveOKState)) {
+ if (!cit->synchronousSave(this /*perhaps that should be the kate mainwindow*/)) {
+ KMessageBox::sorry( this, i18n("Data you requested to be saved could not be written. Please choose how you want to proceed."));
+ return false;
+ }
+ } else if ((!cit->isOn()) && (cit->state()==AbstractKateSaveModifiedDialogCheckListItem::SaveFailedState)) {
+ cit->setState(AbstractKateSaveModifiedDialogCheckListItem::InitialState);
+ }
+
+ }
+ }
+ return true;
+}
+
+bool KateSaveModifiedDialog::queryClose(QWidget *parent,QPtrList<Kate::Document> documents) {
+ KateSaveModifiedDialog d(parent,documents);
+ return (d.exec()!=QDialog::Rejected);
+}
diff --git a/kate/app/katesavemodifieddialog.h b/kate/app/katesavemodifieddialog.h
new file mode 100644
index 000000000..65817356b
--- /dev/null
+++ b/kate/app/katesavemodifieddialog.h
@@ -0,0 +1,48 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Joseph Wenninger <jowenn@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _KATE_SAVE_MODIFIED_DIALOG_
+#define _KATE_SAVE_MODIFIED_DIALOG_
+
+#include <kdialogbase.h>
+#include <kate/document.h>
+
+class QListViewItem;
+class KListView;
+
+class KateSaveModifiedDialog: public KDialogBase {
+ Q_OBJECT
+public:
+ KateSaveModifiedDialog(QWidget *parent, QPtrList<Kate::Document> documents);
+ virtual ~KateSaveModifiedDialog();
+ static bool queryClose(QWidget *parent,QPtrList<Kate::Document> documents);
+protected:
+ virtual void slotUser2();
+ virtual void slotUser1();
+ bool doSave(QListViewItem *root);
+protected slots:
+ void slotSelectAll();
+ void slotItemSelected();
+
+private:
+ QListViewItem *m_projectRoot;
+ QListViewItem *m_documentRoot;
+ KListView *m_list;
+};
+
+#endif
diff --git a/kate/app/katesession.cpp b/kate/app/katesession.cpp
new file mode 100644
index 000000000..0d208c566
--- /dev/null
+++ b/kate/app/katesession.cpp
@@ -0,0 +1,920 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Christoph Cullmann <cullmann@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "katesession.h"
+#include "katesession.moc"
+
+#include "kateapp.h"
+#include "katemainwindow.h"
+#include "katedocmanager.h"
+
+#include <kstandarddirs.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kdirwatch.h>
+#include <klistview.h>
+#include <kinputdialog.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kmdcodec.h>
+#include <kstdguiitem.h>
+#include <kpushbutton.h>
+#include <kpopupmenu.h>
+
+#include <qdir.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qcheckbox.h>
+#include <qdatetime.h>
+#include <qmap.h>
+
+#include <unistd.h>
+#include <time.h>
+
+bool operator<( const KateSession::Ptr& a, const KateSession::Ptr& b )
+{
+ return a->sessionName().lower() < b->sessionName().lower();
+}
+
+KateSession::KateSession (KateSessionManager *manager, const QString &fileName, const QString &name)
+ : m_sessionFileRel (fileName)
+ , m_sessionName (name)
+ , m_documents (0)
+ , m_manager (manager)
+ , m_readConfig (0)
+ , m_writeConfig (0)
+{
+ init ();
+}
+
+void KateSession::init ()
+{
+ // given file exists, use it to load some stuff ;)
+ if (!m_sessionFileRel.isEmpty() && KGlobal::dirs()->exists(sessionFile ()))
+ {
+ KSimpleConfig config (sessionFile (), true);
+
+ if (m_sessionName.isEmpty())
+ {
+ // get the name out of the file
+ if (m_sessionFileRel == "default.katesession")
+ m_sessionName = i18n("Default Session");
+ else
+ {
+ config.setGroup ("General");
+ m_sessionName = config.readEntry ("Name", i18n ("Unnamed Session"));
+ }
+ }
+
+ // get the document count
+ config.setGroup ("Open Documents");
+ m_documents = config.readUnsignedNumEntry("Count", 0);
+
+ return;
+ }
+
+ // filename not empty, create the file
+ // anders: When will this ever happen???
+ if (!m_sessionFileRel.isEmpty())
+ {
+ kdDebug(13001)<<"Kate::Session: initializing unexisting file!"<<endl;
+ // uhh, no name given
+ if (m_sessionName.isEmpty())
+ {
+ if (m_sessionFileRel == "default.katesession")
+ m_sessionName = i18n("Default Session");
+ else
+ m_sessionName = i18n("Session (%1)").arg(QTime::currentTime().toString(Qt::LocalDate));
+ }
+
+ // create the file, write name to it!
+ KSimpleConfig config (sessionFile ());
+ config.setGroup ("General");
+ config.writeEntry ("Name", m_sessionName);
+
+ config.sync ();
+ }
+}
+
+KateSession::~KateSession ()
+{
+ delete m_readConfig;
+ delete m_writeConfig;
+}
+
+QString KateSession::sessionFile () const
+{
+ return m_manager->sessionsDir() + "/" + m_sessionFileRel;
+}
+
+bool KateSession::create (const QString &name, bool force)
+{
+ if (!force && (name.isEmpty() || !m_sessionFileRel.isEmpty()))
+ return false;
+
+ delete m_writeConfig;
+ m_writeConfig = 0;
+
+ delete m_readConfig;
+ m_readConfig = 0;
+
+ m_sessionName = name;
+
+ // get a usable filename
+ int s = time(0);
+ QCString tname;
+ while (true)
+ {
+ tname.setNum (s++);
+ KMD5 md5 (tname);
+ m_sessionFileRel = QString ("%1.katesession").arg (md5.hexDigest().data());
+
+ if (!KGlobal::dirs()->exists(sessionFile ()))
+ break;
+ }
+
+ // create the file, write name to it!
+ KSimpleConfig config (sessionFile ());
+ config.setGroup ("General");
+ config.writeEntry ("Name", m_sessionName);
+ config.sync ();
+
+ // reinit ourselfs ;)
+ init ();
+
+ return true;
+}
+
+bool KateSession::rename (const QString &name)
+{
+ if (name.isEmpty () || m_sessionFileRel.isEmpty() || m_sessionFileRel == "default.katesession")
+ return false;
+
+ m_sessionName = name;
+
+ KConfig config (sessionFile (), false, false);
+ config.setGroup ("General");
+ config.writeEntry ("Name", m_sessionName);
+ config.sync ();
+
+ return true;
+}
+
+KConfig *KateSession::configRead ()
+{
+ if (m_sessionFileRel.isEmpty())
+ return 0;
+
+ if (m_readConfig)
+ return m_readConfig;
+
+ return m_readConfig = new KSimpleConfig (sessionFile (), true);
+}
+
+KConfig *KateSession::configWrite ()
+{
+ if (m_sessionFileRel.isEmpty())
+ return 0;
+
+ if (m_writeConfig)
+ return m_writeConfig;
+
+ m_writeConfig = new KSimpleConfig (sessionFile ());
+ m_writeConfig->setGroup ("General");
+ m_writeConfig->writeEntry ("Name", m_sessionName);
+
+ return m_writeConfig;
+}
+
+KateSessionManager::KateSessionManager (QObject *parent)
+ : QObject (parent)
+ , m_sessionsDir (locateLocal( "data", "kate/sessions"))
+ , m_activeSession (new KateSession (this, "", ""))
+{
+ kdDebug() << "LOCAL SESSION DIR: " << m_sessionsDir << endl;
+
+ // create dir if needed
+ KGlobal::dirs()->makeDir (m_sessionsDir);
+}
+
+KateSessionManager::~KateSessionManager()
+{
+}
+
+KateSessionManager *KateSessionManager::self()
+{
+ return KateApp::self()->sessionManager ();
+}
+
+void KateSessionManager::dirty (const QString &)
+{
+ updateSessionList ();
+}
+
+void KateSessionManager::updateSessionList ()
+{
+ m_sessionList.clear ();
+
+ // Let's get a list of all session we have atm
+ QDir dir (m_sessionsDir, "*.katesession");
+
+ bool foundDefault = false;
+ for (unsigned int i=0; i < dir.count(); ++i)
+ {
+ KateSession *session = new KateSession (this, dir[i], "");
+ m_sessionList.append (session);
+
+ kdDebug () << "FOUND SESSION: " << session->sessionName() << " FILE: " << session->sessionFile() << endl;
+
+ if (!foundDefault && (dir[i] == "default.katesession"))
+ foundDefault = true;
+ }
+
+ // add default session, if not there
+ if (!foundDefault)
+ m_sessionList.append (new KateSession (this, "default.katesession", i18n("Default Session")));
+
+ qHeapSort(m_sessionList);
+}
+
+void KateSessionManager::activateSession (KateSession::Ptr session, bool closeLast, bool saveLast, bool loadNew)
+{
+ // don't reload.
+ // ### comparing the pointers directly is b0rk3d :(
+ if ( ! session->sessionName().isEmpty() && session->sessionName() == m_activeSession->sessionName() )
+ return;
+ // try to close last session
+ if (closeLast)
+ {
+ if (KateApp::self()->activeMainWindow())
+ {
+ if (!KateApp::self()->activeMainWindow()->queryClose_internal())
+ return;
+ }
+ }
+
+ // save last session or not?
+ if (saveLast)
+ saveActiveSession (true);
+
+ // really close last
+ if (closeLast)
+ {
+ KateDocManager::self()->closeAllDocuments ();
+ }
+
+ // set the new session
+ m_activeSession = session;
+
+ if (loadNew)
+ {
+ // open the new session
+ Kate::Document::setOpenErrorDialogsActivated (false);
+
+ KConfig *sc = activeSession()->configRead();
+
+ if (sc)
+ KateApp::self()->documentManager()->restoreDocumentList (sc);
+
+ // if we have no session config object, try to load the default
+ // (anonymous/unnamed sessions)
+ if ( ! sc )
+ sc = new KSimpleConfig( sessionsDir() + "/default.katesession" );
+
+ // window config
+ if (sc)
+ {
+ KConfig *c = KateApp::self()->config();
+ c->setGroup("General");
+
+ if (c->readBoolEntry("Restore Window Configuration", true))
+ {
+ // a new, named session, read settings of the default session.
+ if ( ! sc->hasGroup("Open MainWindows") )
+ sc = new KSimpleConfig( sessionsDir() + "/default.katesession" );
+
+ sc->setGroup ("Open MainWindows");
+ unsigned int wCount = sc->readUnsignedNumEntry("Count", 1);
+
+ for (unsigned int i=0; i < wCount; ++i)
+ {
+ if (i >= KateApp::self()->mainWindows())
+ {
+ KateApp::self()->newMainWindow(sc, QString ("MainWindow%1").arg(i));
+ }
+ else
+ {
+ sc->setGroup(QString ("MainWindow%1").arg(i));
+ KateApp::self()->mainWindow(i)->readProperties (sc);
+ }
+ }
+
+ if (wCount > 0)
+ {
+ while (wCount < KateApp::self()->mainWindows())
+ {
+ KateMainWindow *w = KateApp::self()->mainWindow(KateApp::self()->mainWindows()-1);
+ KateApp::self()->removeMainWindow (w);
+ delete w;
+ }
+ }
+ }
+ }
+
+ Kate::Document::setOpenErrorDialogsActivated (true);
+ }
+}
+
+KateSession::Ptr KateSessionManager::createSession (const QString &name)
+{
+ KateSession::Ptr s = new KateSession (this, "", "");
+ s->create (name);
+
+ return s;
+}
+
+KateSession::Ptr KateSessionManager::giveSession (const QString &name)
+{
+ if (name.isEmpty())
+ return new KateSession (this, "", "");
+
+ updateSessionList();
+
+ for (unsigned int i=0; i < m_sessionList.count(); ++i)
+ {
+ if (m_sessionList[i]->sessionName() == name)
+ return m_sessionList[i];
+ }
+
+ return createSession (name);
+}
+
+bool KateSessionManager::saveActiveSession (bool tryAsk, bool rememberAsLast)
+{
+ if (tryAsk)
+ {
+ // app config
+ KConfig *c = KateApp::self()->config();
+ c->setGroup("General");
+
+ QString sesExit (c->readEntry ("Session Exit", "save"));
+
+ if (sesExit == "discard")
+ return true;
+
+ if (sesExit == "ask")
+ {
+ KDialogBase* dlg = new KDialogBase(i18n ("Save Session?")
+ , KDialogBase::Yes | KDialogBase::No
+ , KDialogBase::Yes, KDialogBase::No
+ );
+
+ bool dontAgain = false;
+ int res = KMessageBox::createKMessageBox(dlg, QMessageBox::Question,
+ i18n("Save current session?"), QStringList(),
+ i18n("Do not ask again"), &dontAgain, KMessageBox::Notify);
+
+ // remember to not ask again with right setting
+ if (dontAgain)
+ {
+ c->setGroup("General");
+
+ if (res == KDialogBase::No)
+ c->writeEntry ("Session Exit", "discard");
+ else
+ c->writeEntry ("Session Exit", "save");
+ }
+
+ if (res == KDialogBase::No)
+ return true;
+ }
+ }
+
+ KConfig *sc = activeSession()->configWrite();
+
+ if (!sc)
+ return false;
+
+ KateDocManager::self()->saveDocumentList (sc);
+
+ sc->setGroup ("Open MainWindows");
+ sc->writeEntry ("Count", KateApp::self()->mainWindows ());
+
+ // save config for all windows around ;)
+ for (unsigned int i=0; i < KateApp::self()->mainWindows (); ++i )
+ {
+ sc->setGroup(QString ("MainWindow%1").arg(i));
+ KateApp::self()->mainWindow(i)->saveProperties (sc);
+ }
+
+ sc->sync();
+
+ if (rememberAsLast)
+ {
+ KConfig *c = KateApp::self()->config();
+ c->setGroup("General");
+ c->writeEntry ("Last Session", activeSession()->sessionFileRelative());
+ c->sync ();
+ }
+
+ return true;
+}
+
+bool KateSessionManager::chooseSession ()
+{
+ bool success = true;
+
+ // app config
+ KConfig *c = KateApp::self()->config();
+ c->setGroup("General");
+
+ // get last used session, default to default session
+ QString lastSession (c->readEntry ("Last Session", "default.katesession"));
+ QString sesStart (c->readEntry ("Startup Session", "manual"));
+
+ // uhh, just open last used session, show no chooser
+ if (sesStart == "last")
+ {
+ activateSession (new KateSession (this, lastSession, ""), false, false);
+ return success;
+ }
+
+ // start with empty new session
+ if (sesStart == "new")
+ {
+ activateSession (new KateSession (this, "", ""), false, false);
+ return success;
+ }
+
+ KateSessionChooser *chooser = new KateSessionChooser (0, lastSession);
+
+ bool retry = true;
+ int res = 0;
+ while (retry)
+ {
+ res = chooser->exec ();
+
+ switch (res)
+ {
+ case KateSessionChooser::resultOpen:
+ {
+ KateSession::Ptr s = chooser->selectedSession ();
+
+ if (!s)
+ {
+ KMessageBox::error (chooser, i18n("No session selected to open."), i18n ("No Session Selected"));
+ break;
+ }
+
+ activateSession (s, false, false);
+ retry = false;
+ break;
+ }
+
+ // exit the app lateron
+ case KateSessionChooser::resultQuit:
+ success = false;
+ retry = false;
+ break;
+
+ default:
+ activateSession (new KateSession (this, "", ""), false, false);
+ retry = false;
+ break;
+ }
+ }
+
+ // write back our nice boolean :)
+ if (success && chooser->reopenLastSession ())
+ {
+ c->setGroup("General");
+
+ if (res == KateSessionChooser::resultOpen)
+ c->writeEntry ("Startup Session", "last");
+ else if (res == KateSessionChooser::resultNew)
+ c->writeEntry ("Startup Session", "new");
+
+ c->sync ();
+ }
+
+ delete chooser;
+
+ return success;
+}
+
+void KateSessionManager::sessionNew ()
+{
+ activateSession (new KateSession (this, "", ""));
+}
+
+void KateSessionManager::sessionOpen ()
+{
+ KateSessionOpenDialog *chooser = new KateSessionOpenDialog (0);
+
+ int res = chooser->exec ();
+
+ if (res == KateSessionOpenDialog::resultCancel)
+ {
+ delete chooser;
+ return;
+ }
+
+ KateSession::Ptr s = chooser->selectedSession ();
+
+ if (s)
+ activateSession (s);
+
+ delete chooser;
+}
+
+void KateSessionManager::sessionSave ()
+{
+ // if the active session is valid, just save it :)
+ if (saveActiveSession ())
+ return;
+
+ bool ok = false;
+ QString name = KInputDialog::getText (i18n("Specify Name for Current Session"), i18n("Session name:"), "", &ok);
+
+ if (!ok)
+ return;
+
+ if (name.isEmpty())
+ {
+ KMessageBox::error (0, i18n("To save a new session, you must specify a name."), i18n ("Missing Session Name"));
+ return;
+ }
+
+ activeSession()->create (name);
+ saveActiveSession ();
+}
+
+void KateSessionManager::sessionSaveAs ()
+{
+ bool ok = false;
+ QString name = KInputDialog::getText (i18n("Specify New Name for Current Session"), i18n("Session name:"), "", &ok);
+
+ if (!ok)
+ return;
+
+ if (name.isEmpty())
+ {
+ KMessageBox::error (0, i18n("To save a session, you must specify a name."), i18n ("Missing Session Name"));
+ return;
+ }
+
+ activeSession()->create (name, true);
+ saveActiveSession ();
+}
+
+
+void KateSessionManager::sessionManage ()
+{
+ KateSessionManageDialog *dlg = new KateSessionManageDialog (0);
+
+ dlg->exec ();
+
+ delete dlg;
+}
+
+//BEGIN CHOOSER DIALOG
+
+class KateSessionChooserItem : public QListViewItem
+{
+ public:
+ KateSessionChooserItem (KListView *lv, KateSession::Ptr s)
+ : QListViewItem (lv, s->sessionName())
+ , session (s)
+ {
+ QString docs;
+ docs.setNum (s->documents());
+ setText (1, docs);
+ }
+
+ KateSession::Ptr session;
+};
+
+KateSessionChooser::KateSessionChooser (QWidget *parent, const QString &lastSession)
+ : KDialogBase ( parent
+ , ""
+ , true
+ , i18n ("Session Chooser")
+ , KDialogBase::User1 | KDialogBase::User2 | KDialogBase::User3
+ , KDialogBase::User2
+ , true
+ , KStdGuiItem::quit ()
+ , KGuiItem (i18n ("Open Session"), "fileopen")
+ , KGuiItem (i18n ("New Session"), "filenew")
+ )
+{
+ QHBox *page = new QHBox (this);
+ page->setMinimumSize (400, 200);
+ setMainWidget(page);
+
+ QHBox *hb = new QHBox (page);
+ hb->setSpacing (KDialog::spacingHint());
+
+ QLabel *label = new QLabel (hb);
+ label->setPixmap (UserIcon("sessionchooser"));
+ label->setFrameStyle (QFrame::Panel | QFrame::Sunken);
+
+ QVBox *vb = new QVBox (hb);
+ vb->setSpacing (KDialog::spacingHint());
+
+ m_sessions = new KListView (vb);
+ m_sessions->addColumn (i18n("Session Name"));
+ m_sessions->addColumn (i18n("Open Documents"));
+ m_sessions->setResizeMode (QListView::AllColumns);
+ m_sessions->setSelectionMode (QListView::Single);
+ m_sessions->setAllColumnsShowFocus (true);
+
+ connect (m_sessions, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
+ connect (m_sessions, SIGNAL(doubleClicked(QListViewItem *, const QPoint &, int)), this, SLOT(slotUser2()));
+
+ KateSessionList &slist (KateSessionManager::self()->sessionList());
+ for (unsigned int i=0; i < slist.count(); ++i)
+ {
+ KateSessionChooserItem *item = new KateSessionChooserItem (m_sessions, slist[i]);
+
+ if (slist[i]->sessionFileRelative() == lastSession)
+ m_sessions->setSelected (item, true);
+ }
+
+ m_useLast = new QCheckBox (i18n ("&Always use this choice"), vb);
+
+ setResult (resultNone);
+
+ // trigger action update
+ selectionChanged ();
+}
+
+KateSessionChooser::~KateSessionChooser ()
+{
+}
+
+KateSession::Ptr KateSessionChooser::selectedSession ()
+{
+ KateSessionChooserItem *item = (KateSessionChooserItem *) m_sessions->selectedItem ();
+
+ if (!item)
+ return 0;
+
+ return item->session;
+}
+
+bool KateSessionChooser::reopenLastSession ()
+{
+ return m_useLast->isChecked ();
+}
+
+void KateSessionChooser::slotUser2 ()
+{
+ done (resultOpen);
+}
+
+void KateSessionChooser::slotUser3 ()
+{
+ done (resultNew);
+}
+
+void KateSessionChooser::slotUser1 ()
+{
+ done (resultQuit);
+}
+
+void KateSessionChooser::selectionChanged ()
+{
+ enableButton (KDialogBase::User2, m_sessions->selectedItem ());
+}
+
+//END CHOOSER DIALOG
+
+//BEGIN OPEN DIALOG
+
+KateSessionOpenDialog::KateSessionOpenDialog (QWidget *parent)
+ : KDialogBase ( parent
+ , ""
+ , true
+ , i18n ("Open Session")
+ , KDialogBase::User1 | KDialogBase::User2
+ , KDialogBase::User2
+ , false
+ , KStdGuiItem::cancel ()
+ , KGuiItem( i18n("&Open"), "fileopen")
+ )
+{
+ QHBox *page = new QHBox (this);
+ page->setMinimumSize (400, 200);
+ setMainWidget(page);
+
+ QHBox *hb = new QHBox (page);
+
+ QVBox *vb = new QVBox (hb);
+
+ m_sessions = new KListView (vb);
+ m_sessions->addColumn (i18n("Session Name"));
+ m_sessions->addColumn (i18n("Open Documents"));
+ m_sessions->setResizeMode (QListView::AllColumns);
+ m_sessions->setSelectionMode (QListView::Single);
+ m_sessions->setAllColumnsShowFocus (true);
+
+ connect (m_sessions, SIGNAL(doubleClicked(QListViewItem *, const QPoint &, int)), this, SLOT(slotUser2()));
+
+ KateSessionList &slist (KateSessionManager::self()->sessionList());
+ for (unsigned int i=0; i < slist.count(); ++i)
+ {
+ new KateSessionChooserItem (m_sessions, slist[i]);
+ }
+
+ setResult (resultCancel);
+}
+
+KateSessionOpenDialog::~KateSessionOpenDialog ()
+{
+}
+
+KateSession::Ptr KateSessionOpenDialog::selectedSession ()
+{
+ KateSessionChooserItem *item = (KateSessionChooserItem *) m_sessions->selectedItem ();
+
+ if (!item)
+ return 0;
+
+ return item->session;
+}
+
+void KateSessionOpenDialog::slotUser1 ()
+{
+ done (resultCancel);
+}
+
+void KateSessionOpenDialog::slotUser2 ()
+{
+ done (resultOk);
+}
+
+//END OPEN DIALOG
+
+//BEGIN MANAGE DIALOG
+
+KateSessionManageDialog::KateSessionManageDialog (QWidget *parent)
+ : KDialogBase ( parent
+ , ""
+ , true
+ , i18n ("Manage Sessions")
+ , KDialogBase::User1
+ , KDialogBase::User1
+ , false
+ , KStdGuiItem::close ()
+ )
+{
+ QHBox *page = new QHBox (this);
+ page->setMinimumSize (400, 200);
+ setMainWidget(page);
+
+ QHBox *hb = new QHBox (page);
+ hb->setSpacing (KDialog::spacingHint());
+
+ m_sessions = new KListView (hb);
+ m_sessions->addColumn (i18n("Session Name"));
+ m_sessions->addColumn (i18n("Open Documents"));
+ m_sessions->setResizeMode (QListView::AllColumns);
+ m_sessions->setSelectionMode (QListView::Single);
+ m_sessions->setAllColumnsShowFocus (true);
+
+ connect (m_sessions, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
+
+ updateSessionList ();
+
+ QWidget *vb = new QWidget (hb);
+ QVBoxLayout *vbl = new QVBoxLayout (vb);
+ vbl->setSpacing (KDialog::spacingHint());
+
+ m_rename = new KPushButton (i18n("&Rename..."), vb);
+ connect (m_rename, SIGNAL(clicked()), this, SLOT(rename()));
+ vbl->addWidget (m_rename);
+
+ m_del = new KPushButton (KStdGuiItem::del (), vb);
+ connect (m_del, SIGNAL(clicked()), this, SLOT(del()));
+ vbl->addWidget (m_del);
+
+ vbl->addStretch ();
+
+ // trigger action update
+ selectionChanged ();
+}
+
+KateSessionManageDialog::~KateSessionManageDialog ()
+{
+}
+
+void KateSessionManageDialog::slotUser1 ()
+{
+ done (0);
+}
+
+
+void KateSessionManageDialog::selectionChanged ()
+{
+ KateSessionChooserItem *item = (KateSessionChooserItem *) m_sessions->selectedItem ();
+
+ m_rename->setEnabled (item && item->session->sessionFileRelative() != "default.katesession");
+ m_del->setEnabled (item && item->session->sessionFileRelative() != "default.katesession");
+}
+
+void KateSessionManageDialog::rename ()
+{
+ KateSessionChooserItem *item = (KateSessionChooserItem *) m_sessions->selectedItem ();
+
+ if (!item || item->session->sessionFileRelative() == "default.katesession")
+ return;
+
+ bool ok = false;
+ QString name = KInputDialog::getText (i18n("Specify New Name for Session"), i18n("Session name:"), item->session->sessionName(), &ok);
+
+ if (!ok)
+ return;
+
+ if (name.isEmpty())
+ {
+ KMessageBox::error (0, i18n("To save a session, you must specify a name."), i18n ("Missing Session Name"));
+ return;
+ }
+
+ item->session->rename (name);
+ updateSessionList ();
+}
+
+void KateSessionManageDialog::del ()
+{
+ KateSessionChooserItem *item = (KateSessionChooserItem *) m_sessions->selectedItem ();
+
+ if (!item || item->session->sessionFileRelative() == "default.katesession")
+ return;
+
+ QFile::remove (item->session->sessionFile());
+ KateSessionManager::self()->updateSessionList ();
+ updateSessionList ();
+}
+
+void KateSessionManageDialog::updateSessionList ()
+{
+ m_sessions->clear ();
+
+ KateSessionList &slist (KateSessionManager::self()->sessionList());
+ for (unsigned int i=0; i < slist.count(); ++i)
+ {
+ new KateSessionChooserItem (m_sessions, slist[i]);
+ }
+}
+
+//END MANAGE DIALOG
+
+
+KateSessionsAction::KateSessionsAction(const QString& text, QObject* parent, const char* name )
+ : KActionMenu(text, parent, name)
+{
+ connect(popupMenu(),SIGNAL(aboutToShow()),this,SLOT(slotAboutToShow()));
+}
+
+void KateSessionsAction::slotAboutToShow()
+{
+ popupMenu()->clear ();
+
+ KateSessionList &slist (KateSessionManager::self()->sessionList());
+ for (unsigned int i=0; i < slist.count(); ++i)
+ {
+ popupMenu()->insertItem (
+ slist[i]->sessionName(),
+ this, SLOT (openSession (int)), 0,
+ i );
+ }
+}
+
+void KateSessionsAction::openSession (int i)
+{
+ KateSessionList &slist (KateSessionManager::self()->sessionList());
+
+ if ((uint)i >= slist.count())
+ return;
+
+ KateSessionManager::self()->activateSession(slist[(uint)i]);
+}
+// kate: space-indent on; indent-width 2; replace-tabs on; mixed-indent off;
diff --git a/kate/app/katesession.h b/kate/app/katesession.h
new file mode 100644
index 000000000..899daff53
--- /dev/null
+++ b/kate/app/katesession.h
@@ -0,0 +1,418 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Christoph Cullmann <cullmann@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KATE_SESSION_H__
+#define __KATE_SESSION_H__
+
+#include "katemain.h"
+
+#include <kdialogbase.h>
+#include <ksimpleconfig.h>
+#include <ksharedptr.h>
+#include <kaction.h>
+
+#include <qobject.h>
+#include <qvaluelist.h>
+
+class KateSessionManager;
+
+class KDirWatch;
+class KListView;
+class KPushButton;
+
+class QCheckBox;
+
+class KateSession : public KShared
+{
+ public:
+ /**
+ * Define a Shared-Pointer type
+ */
+ typedef KSharedPtr<KateSession> Ptr;
+
+ public:
+ /**
+ * create a session from given file
+ * @param fileName session filename, relative
+ * @param name session name
+ * @param manager pointer to the manager
+ */
+ KateSession (KateSessionManager *manager, const QString &fileName, const QString &name);
+
+ /**
+ * init the session object, after construction or create
+ */
+ void init ();
+
+ /**
+ * destruct me
+ */
+ ~KateSession ();
+
+ /**
+ * session filename, absolute, calculated out of relative filename + session dir
+ * @return absolute path to session file
+ */
+ QString sessionFile () const;
+
+ /**
+ * relative session filename
+ * @return relative filename for this session
+ */
+ const QString &sessionFileRelative () const { return m_sessionFileRel; }
+
+ /**
+ * session name
+ * @return name for this session
+ */
+ const QString &sessionName () const { return m_sessionName; }
+
+ /**
+ * is this a valid session? if not, don't use any session if this is
+ * the active one
+ */
+ bool isNew () const { return m_sessionName.isEmpty(); }
+
+ /**
+ * create the session file, if not existing
+ * @param name name for this session
+ * @param force force to create new file
+ * @return true if created, false if no creation needed
+ */
+ bool create (const QString &name, bool force = false);
+
+ /**
+ * rename this session
+ * @param name new name
+ * @return success
+ */
+ bool rename (const QString &name);
+
+ /**
+ * config to read
+ * on first access, will create the config object, delete will be done automagic
+ * return 0 if we have no file to read config from atm
+ * @return config to read from
+ */
+ KConfig *configRead ();
+
+ /**
+ * config to write
+ * on first access, will create the config object, delete will be done automagic
+ * return 0 if we have no file to write config to atm
+ * @return config to write from
+ */
+ KConfig *configWrite ();
+
+ /**
+ * count of documents in this session
+ * @return documents count
+ */
+ unsigned int documents () const { return m_documents; }
+
+ private:
+ /**
+ * session filename, in local location we can write to
+ * relative filename to the session dirs :)
+ */
+ QString m_sessionFileRel;
+
+ /**
+ * session name, extracted from the file, to display to the user
+ */
+ QString m_sessionName;
+
+ /**
+ * number of document of this session
+ */
+ unsigned int m_documents;
+
+ /**
+ * KateSessionMananger
+ */
+ KateSessionManager *m_manager;
+
+ /**
+ * simpleconfig to read from
+ */
+ KSimpleConfig *m_readConfig;
+
+ /**
+ * simpleconfig to write to
+ */
+ KSimpleConfig *m_writeConfig;
+};
+
+typedef QValueList<KateSession::Ptr> KateSessionList;
+
+class KateSessionManager : public QObject
+{
+ Q_OBJECT
+
+ public:
+ KateSessionManager(QObject *parent);
+ ~KateSessionManager();
+
+ /**
+ * allow access to this :)
+ * @return instance of the session manager
+ */
+ static KateSessionManager *self();
+
+ /**
+ * allow access to the session list
+ * kept up to date by watching the dir
+ */
+ inline KateSessionList & sessionList () { updateSessionList (); return m_sessionList; }
+
+ /**
+ * activate a session
+ * first, it will look if a session with this name exists in list
+ * if yes, it will use this session, else it will create a new session file
+ * @param session session to activate
+ * @param closeLast try to close last session or not?
+ * @param saveLast try to save last session or not?
+ * @param loadNew load new session stuff?
+ */
+ void activateSession (KateSession::Ptr session, bool closeLast = true, bool saveLast = true, bool loadNew = true);
+
+ /**
+ * create a new session
+ * @param name session name
+ */
+ KateSession::Ptr createSession (const QString &name);
+
+ /**
+ * return session with given name
+ * if no existing session matches, create new one with this name
+ * @param name session name
+ */
+ KateSession::Ptr giveSession (const QString &name);
+
+ /**
+ * save current session
+ * for sessions without filename: save nothing
+ * @param tryAsk should we ask user if needed?
+ * @param rememberAsLast remember this session as last used?
+ * @return success
+ */
+ bool saveActiveSession (bool tryAsk = false, bool rememberAsLast = false);
+
+ /**
+ * return the current active session
+ * sessionFile == empty means we have no session around for this instance of kate
+ * @return session active atm
+ */
+ inline KateSession::Ptr activeSession () { return m_activeSession; }
+
+ /**
+ * session dir
+ * @return global session dir
+ */
+ inline const QString &sessionsDir () const { return m_sessionsDir; }
+
+ /**
+ * initial session chooser, on app start
+ * @return success, if false, app should exit
+ */
+ bool chooseSession ();
+
+ public slots:
+ /**
+ * try to start a new session
+ * asks user first for name
+ */
+ void sessionNew ();
+
+ /**
+ * try to open a existing session
+ */
+ void sessionOpen ();
+
+ /**
+ * try to save current session
+ */
+ void sessionSave ();
+
+ /**
+ * try to save as current session
+ */
+ void sessionSaveAs ();
+
+ /**
+ * show dialog to manage our sessions
+ */
+ void sessionManage ();
+
+ private slots:
+ void dirty (const QString &path);
+
+ public:
+ /**
+ * trigger update of session list
+ */
+ void updateSessionList ();
+
+ private:
+ /**
+ * absolute path to dir in home dir where to store the sessions
+ */
+ QString m_sessionsDir;
+
+ /**
+ * list of current available sessions
+ */
+ KateSessionList m_sessionList;
+
+ /**
+ * current active session
+ */
+ KateSession::Ptr m_activeSession;
+};
+
+class KateSessionChooser : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ KateSessionChooser (QWidget *parent, const QString &lastSession);
+ ~KateSessionChooser ();
+
+ KateSession::Ptr selectedSession ();
+
+ bool reopenLastSession ();
+
+ enum {
+ resultQuit = QDialog::Rejected,
+ resultOpen,
+ resultNew,
+ resultNone
+ };
+
+ protected slots:
+ /**
+ * open session
+ */
+ void slotUser1 ();
+
+ /**
+ * new session
+ */
+ void slotUser2 ();
+
+ /**
+ * quit kate
+ */
+ void slotUser3 ();
+
+ /**
+ * selection has changed
+ */
+ void selectionChanged ();
+
+ private:
+ KListView *m_sessions;
+ QCheckBox *m_useLast;
+};
+
+class KateSessionOpenDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ KateSessionOpenDialog (QWidget *parent);
+ ~KateSessionOpenDialog ();
+
+ KateSession::Ptr selectedSession ();
+
+ enum {
+ resultOk,
+ resultCancel
+ };
+
+ protected slots:
+ /**
+ * cancel pressed
+ */
+ void slotUser1 ();
+
+ /**
+ * ok pressed
+ */
+ void slotUser2 ();
+
+ private:
+ KListView *m_sessions;
+};
+
+class KateSessionManageDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ KateSessionManageDialog (QWidget *parent);
+ ~KateSessionManageDialog ();
+
+ protected slots:
+ /**
+ * close pressed
+ */
+ void slotUser1 ();
+
+ /**
+ * selection has changed
+ */
+ void selectionChanged ();
+
+ /**
+ * try to rename session
+ */
+ void rename ();
+
+ /**
+ * try to delete session
+ */
+ void del ();
+
+ private:
+ /**
+ * update our list
+ */
+ void updateSessionList ();
+
+ private:
+ KListView *m_sessions;
+ KPushButton *m_rename;
+ KPushButton *m_del;
+};
+
+class KateSessionsAction : public KActionMenu
+{
+ Q_OBJECT
+
+ public:
+ KateSessionsAction(const QString& text, QObject* parent = 0, const char* name = 0);
+ ~KateSessionsAction (){;};
+
+ public slots:
+ void slotAboutToShow();
+
+ void openSession (int i);
+};
+
+#endif
diff --git a/kate/app/katetabwidget.cpp b/kate/app/katetabwidget.cpp
new file mode 100644
index 000000000..c24357be5
--- /dev/null
+++ b/kate/app/katetabwidget.cpp
@@ -0,0 +1,161 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2002,2003 Joseph Wenninger <jowenn@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "katetabwidget.h"
+#include "katetabwidget.moc"
+
+#include <qtabbar.h>
+
+//BEGIN KateTabWidget
+
+KateTabWidget::KateTabWidget(QWidget* parent, const char* name)
+ : KTabWidget(parent,name)
+ , m_visibility (ShowWhenMoreThanOneTab)
+{
+ tabBar()->hide();
+
+ setHoverCloseButton(true);
+
+ connect(this, SIGNAL(closeRequest(QWidget*)), this, SLOT(closeTab(QWidget*)));
+}
+
+KateTabWidget::~KateTabWidget()
+{
+}
+
+void KateTabWidget::closeTab(QWidget* w)
+{
+ w->close();
+}
+
+void KateTabWidget::addTab ( QWidget * child, const QString & label )
+{
+ KTabWidget::addTab(child,label);
+ showPage(child);
+ maybeShow();
+}
+
+void KateTabWidget::addTab ( QWidget * child, const QIconSet & iconset, const QString & label )
+{
+ KTabWidget::addTab(child,iconset,label);
+ showPage(child);
+ maybeShow();
+}
+
+void KateTabWidget::addTab ( QWidget * child, QTab * tab )
+{
+ KTabWidget::addTab(child,tab);
+ showPage(child);
+ maybeShow();
+}
+
+void KateTabWidget::insertTab ( QWidget * child, const QString & label, int index)
+{
+ KTabWidget::insertTab(child,label,index);
+ showPage(child);
+ maybeShow();
+ tabBar()->repaint();
+}
+
+void KateTabWidget::insertTab ( QWidget * child, const QIconSet & iconset, const QString & label, int index )
+{
+ KTabWidget::insertTab(child,iconset,label,index);
+ showPage(child);
+ maybeShow();
+ tabBar()->repaint();
+}
+
+void KateTabWidget::insertTab ( QWidget * child, QTab * tab, int index)
+{
+ KTabWidget::insertTab(child,tab,index);
+ showPage(child);
+ maybeShow();
+ tabBar()->repaint();
+}
+
+void KateTabWidget::removePage ( QWidget * w )
+{
+ KTabWidget::removePage(w);
+ maybeShow();
+}
+
+void KateTabWidget::maybeShow()
+{
+ switch (m_visibility)
+ {
+ case AlwaysShowTabs:
+ tabBar()->show();
+
+ // show/hide corner widgets
+ if (count() == 0)
+ setCornerWidgetVisibility(false);
+ else
+ setCornerWidgetVisibility(true);
+
+ break;
+
+ case ShowWhenMoreThanOneTab:
+ if (count()<2) tabBar()->hide();
+ else tabBar()->show();
+
+ // show/hide corner widgets
+ if (count() < 2)
+ setCornerWidgetVisibility(false);
+ else
+ setCornerWidgetVisibility(true);
+
+ break;
+
+ case NeverShowTabs:
+ tabBar()->hide();
+ break;
+ }
+}
+
+void KateTabWidget::setCornerWidgetVisibility(bool visible)
+{
+ // there are two corner widgets: on TopLeft and on TopTight!
+
+ if (cornerWidget(Qt::TopLeft) ) {
+ if (visible)
+ cornerWidget(Qt::TopLeft)->show();
+ else
+ cornerWidget(Qt::TopLeft)->hide();
+ }
+
+ if (cornerWidget(Qt::TopRight) ) {
+ if (visible)
+ cornerWidget(Qt::TopRight)->show();
+ else
+ cornerWidget(Qt::TopRight)->hide();
+ }
+}
+
+void KateTabWidget::setTabWidgetVisibility( TabWidgetVisibility visibility )
+{
+ m_visibility = visibility;
+ maybeShow();
+}
+
+KateTabWidget::TabWidgetVisibility KateTabWidget::tabWidgetVisibility( ) const
+{
+ return m_visibility;
+}
+
+//END KateTabWidget
diff --git a/kate/app/katetabwidget.h b/kate/app/katetabwidget.h
new file mode 100644
index 000000000..765f83fdb
--- /dev/null
+++ b/kate/app/katetabwidget.h
@@ -0,0 +1,69 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2002,2003 Joseph Wenninger <jowenn@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KATE_TABWIDGET_H__
+#define __KATE_TABWIDGET_H__
+
+#include <ktabwidget.h>
+
+class KateTabWidget : public KTabWidget
+{
+ Q_OBJECT
+
+ public:
+ enum TabWidgetVisibility {
+ AlwaysShowTabs = 0,
+ ShowWhenMoreThanOneTab = 1,
+ NeverShowTabs = 2
+ };
+
+ public:
+ KateTabWidget(QWidget* parent, const char* name=0);
+ virtual ~KateTabWidget();
+
+ virtual void addTab ( QWidget * child, const QString & label );
+
+ virtual void addTab ( QWidget * child, const QIconSet & iconset, const QString & label );
+
+ virtual void addTab ( QWidget * child, QTab * tab );
+
+ virtual void insertTab ( QWidget * child, const QString & label, int index = -1 );
+
+ virtual void insertTab ( QWidget * child, const QIconSet & iconset, const QString & label, int index = -1 );
+
+ virtual void insertTab ( QWidget * child, QTab * tab, int index = -1 );
+
+ virtual void removePage ( QWidget * w );
+
+ TabWidgetVisibility tabWidgetVisibility() const;
+
+ void setTabWidgetVisibility( TabWidgetVisibility );
+
+ private slots:
+ void closeTab(QWidget* w);
+
+ private:
+ void maybeShow();
+ void setCornerWidgetVisibility(bool visible);
+
+ private:
+ TabWidgetVisibility m_visibility;
+};
+
+#endif
diff --git a/kate/app/kateviewmanager.cpp b/kate/app/kateviewmanager.cpp
new file mode 100644
index 000000000..39b6020ee
--- /dev/null
+++ b/kate/app/kateviewmanager.cpp
@@ -0,0 +1,514 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ 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.
+*/
+
+//BEGIN Includes
+#include "kateviewmanager.h"
+#include "kateviewmanager.moc"
+
+#include "katemainwindow.h"
+#include "katedocmanager.h"
+#include "kateviewspacecontainer.h"
+#include "katetabwidget.h"
+
+#include <dcopclient.h>
+#include <kaction.h>
+#include <kcmdlineargs.h>
+#include <kdebug.h>
+#include <kdiroperator.h>
+#include <kdockwidget.h>
+#include <kencodingfiledialog.h>
+#include <kiconloader.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <ktoolbar.h>
+#include <kmessagebox.h>
+#include <ksimpleconfig.h>
+#include <kstdaction.h>
+#include <kstandarddirs.h>
+#include <kglobalsettings.h>
+#include <kstdaccel.h>
+
+#include <ktexteditor/encodinginterface.h>
+
+#include <qobjectlist.h>
+#include <qstringlist.h>
+#include <qfileinfo.h>
+#include <qtoolbutton.h>
+#include <qtooltip.h>
+//END Includes
+
+KateViewManager::KateViewManager (KateMainWindow *parent)
+ : QObject (parent),
+ showFullPath(false), m_mainWindow(parent)
+{
+ // while init
+ m_init=true;
+
+ // some stuff for the tabwidget
+ m_mainWindow->tabWidget()->setTabReorderingEnabled( true );
+
+ // important, set them up, as we use them in other methodes
+ setupActions ();
+
+ guiMergedView=0;
+
+ m_viewManager = new Kate::ViewManager (this);
+ m_currentContainer=0;
+ connect(m_mainWindow->tabWidget(),SIGNAL(currentChanged(QWidget*)),this,SLOT(tabChanged(QWidget*)));
+ slotNewTab();
+ tabChanged(m_mainWindow->tabWidget()->currentPage());
+
+ // no memleaks
+ m_viewSpaceContainerList.setAutoDelete(true);
+
+ // init done
+ m_init=false;
+}
+
+KateViewManager::~KateViewManager ()
+{
+ m_viewSpaceContainerList.setAutoDelete(false);
+}
+
+void KateViewManager::setupActions ()
+{
+ KAction *a;
+
+ /**
+ * tabbing
+ */
+ a=new KAction ( i18n("New Tab"),"tab_new", 0, this, SLOT(slotNewTab()),
+ m_mainWindow->actionCollection(), "view_new_tab" );
+
+ m_closeTab = new KAction ( i18n("Close Current Tab"),"tab_remove",0,this,SLOT(slotCloseTab()),
+ m_mainWindow->actionCollection(),"view_close_tab");
+
+ m_activateNextTab
+ = new KAction( i18n( "Activate Next Tab" ),
+ QApplication::reverseLayout() ? KStdAccel::tabPrev() : KStdAccel::tabNext(),
+ this, SLOT( activateNextTab() ), m_mainWindow->actionCollection(), "view_next_tab" );
+
+ m_activatePrevTab
+ = new KAction( i18n( "Activate Previous Tab" ),
+ QApplication::reverseLayout() ? KStdAccel::tabNext() : KStdAccel::tabPrev(),
+ this, SLOT( activatePrevTab() ), m_mainWindow->actionCollection(), "view_prev_tab" );
+
+ /**
+ * view splitting
+ */
+ a=new KAction ( i18n("Split Ve&rtical"), "view_right", CTRL+SHIFT+Key_L, this, SLOT(
+ slotSplitViewSpaceVert() ), m_mainWindow->actionCollection(), "view_split_vert");
+
+ a->setWhatsThis(i18n("Split the currently active view vertically into two views."));
+
+ a=new KAction ( i18n("Split &Horizontal"), "view_bottom", CTRL+SHIFT+Key_T, this, SLOT(
+ slotSplitViewSpaceHoriz() ), m_mainWindow->actionCollection(), "view_split_horiz");
+
+ a->setWhatsThis(i18n("Split the currently active view horizontally into two views."));
+
+ m_closeView = new KAction ( i18n("Cl&ose Current View"), "view_remove", CTRL+SHIFT+Key_R, this,
+ SLOT( slotCloseCurrentViewSpace() ), m_mainWindow->actionCollection(),
+ "view_close_current_space" );
+
+ m_closeView->setWhatsThis(i18n("Close the currently active splitted view"));
+
+ goNext=new KAction(i18n("Next View"),Key_F8,this,
+ SLOT(activateNextView()),m_mainWindow->actionCollection(),"go_next");
+
+ goNext->setWhatsThis(i18n("Make the next split view the active one."));
+
+ goPrev=new KAction(i18n("Previous View"),SHIFT+Key_F8, this, SLOT(activatePrevView()),m_mainWindow->actionCollection(),"go_prev");
+
+ goPrev->setWhatsThis(i18n("Make the previous split view the active one."));
+
+ /**
+ * buttons for tabbing
+ */
+ QToolButton *b = new QToolButton( m_mainWindow->tabWidget() );
+ connect( b, SIGNAL( clicked() ),
+ this, SLOT( slotNewTab() ) );
+ b->setIconSet( SmallIcon( "tab_new" ) );
+ b->adjustSize();
+ QToolTip::add(b, i18n("Open a new tab"));
+ m_mainWindow->tabWidget()->setCornerWidget( b, TopLeft );
+
+ b = m_closeTabButton = new QToolButton( m_mainWindow->tabWidget() );
+ connect( b, SIGNAL( clicked() ),
+ this, SLOT( slotCloseTab() ) );
+ b->setIconSet( SmallIcon( "tab_remove" ) );
+ b->adjustSize();
+ QToolTip::add(b, i18n("Close the current tab"));
+ m_mainWindow->tabWidget()->setCornerWidget( b, TopRight );
+}
+
+void KateViewManager::updateViewSpaceActions ()
+{
+ if (!m_currentContainer) return;
+
+ m_closeView->setEnabled (m_currentContainer->viewSpaceCount() > 1);
+ goNext->setEnabled (m_currentContainer->viewSpaceCount() > 1);
+ goPrev->setEnabled (m_currentContainer->viewSpaceCount() > 1);
+}
+
+void KateViewManager::tabChanged(QWidget* widget) {
+ KateViewSpaceContainer *container=static_cast<KateViewSpaceContainer*>(widget->qt_cast("KateViewSpaceContainer"));
+ Q_ASSERT(container);
+ m_currentContainer=container;
+
+ if (container) {
+ container->reactivateActiveView();
+
+ }
+
+ m_closeTab->setEnabled(m_mainWindow->tabWidget()->count() > 1);
+ m_activateNextTab->setEnabled(m_mainWindow->tabWidget()->count() > 1);
+ m_activatePrevTab->setEnabled(m_mainWindow->tabWidget()->count() > 1);
+ m_closeTabButton->setEnabled (m_mainWindow->tabWidget()->count() > 1);
+
+ updateViewSpaceActions ();
+}
+
+void KateViewManager::slotNewTab()
+{
+ uint documentNumber=0;
+
+ if (m_currentContainer)
+ {
+ if (m_currentContainer->activeView())
+ documentNumber = m_currentContainer->activeView()->getDoc()->documentNumber();
+ }
+
+ KateViewSpaceContainer *container=new KateViewSpaceContainer (m_mainWindow->tabWidget(), this);
+ m_viewSpaceContainerList.append(container);
+ m_mainWindow->tabWidget()->addTab (container, "");
+
+ connect(container,SIGNAL(viewChanged()),this,SIGNAL(viewChanged()));
+ connect(container,SIGNAL(viewChanged()),m_viewManager,SIGNAL(viewChanged()));
+
+ if (!m_init)
+ {
+ container->activateView(documentNumber);
+ container->setShowFullPath(showFullPath);
+ m_mainWindow->slotWindowActivated ();
+ }
+}
+
+void KateViewManager::slotCloseTab()
+{
+ if (m_viewSpaceContainerList.count() <= 1) return;
+ if (!m_currentContainer) return;
+
+ int pos = m_viewSpaceContainerList.find (m_currentContainer);
+
+ if (pos == -1)
+ return;
+
+ if (guiMergedView)
+ m_mainWindow->guiFactory()->removeClient (guiMergedView );
+
+ m_viewSpaceContainerList.remove (pos);
+
+ if ((uint)pos >= m_viewSpaceContainerList.count())
+ pos = m_viewSpaceContainerList.count()-1;
+
+ tabChanged(m_viewSpaceContainerList.at (pos));
+}
+
+void KateViewManager::activateNextTab()
+{
+ if( m_mainWindow->tabWidget()->count() <= 1 ) return;
+
+ int iTab = m_mainWindow->tabWidget()->currentPageIndex();
+
+ iTab++;
+
+ if( iTab == m_mainWindow->tabWidget()->count() )
+ iTab = 0;
+
+ m_mainWindow->tabWidget()->setCurrentPage( iTab );
+}
+
+void KateViewManager::activatePrevTab()
+{
+ if( m_mainWindow->tabWidget()->count() <= 1 ) return;
+
+ int iTab = m_mainWindow->tabWidget()->currentPageIndex();
+
+ iTab--;
+
+ if( iTab == -1 )
+ iTab = m_mainWindow->tabWidget()->count() - 1;
+
+ m_mainWindow->tabWidget()->setCurrentPage( iTab );
+}
+
+void KateViewManager::activateSpace (Kate::View* v)
+{
+ if (m_currentContainer) {
+ m_currentContainer->activateSpace(v);
+ }
+}
+
+void KateViewManager::activateView ( Kate::View *view ) {
+ if (m_currentContainer) {
+ m_currentContainer->activateView(view);
+ }
+}
+
+KateViewSpace* KateViewManager::activeViewSpace ()
+{
+ if (m_currentContainer) {
+ return m_currentContainer->activeViewSpace();
+ }
+ return 0L;
+}
+
+Kate::View* KateViewManager::activeView ()
+{
+ if (m_currentContainer) {
+ return m_currentContainer->activeView();
+ }
+ return 0L;
+}
+
+void KateViewManager::setActiveSpace ( KateViewSpace* vs )
+{
+ if (m_currentContainer) {
+ m_currentContainer->setActiveSpace(vs);
+ }
+
+}
+
+void KateViewManager::setActiveView ( Kate::View* view )
+{
+ if (m_currentContainer) {
+ m_currentContainer->setActiveView(view);
+ }
+
+}
+
+
+void KateViewManager::activateView( uint documentNumber )
+{
+ if (m_currentContainer) {
+ m_currentContainer->activateView(documentNumber);
+ }
+}
+
+uint KateViewManager::viewCount ()
+{
+ uint viewCount=0;
+ for (uint i=0;i<m_viewSpaceContainerList.count();i++) {
+ viewCount+=m_viewSpaceContainerList.at(i)->viewCount();
+ }
+ return viewCount;
+
+}
+
+uint KateViewManager::viewSpaceCount ()
+{
+ uint viewSpaceCount=0;
+ for (uint i=0;i<m_viewSpaceContainerList.count();i++) {
+ viewSpaceCount+=m_viewSpaceContainerList.at(i)->viewSpaceCount();
+ }
+ return viewSpaceCount;
+}
+
+void KateViewManager::setViewActivationBlocked (bool block)
+{
+ for (uint i=0;i<m_viewSpaceContainerList.count();i++)
+ m_viewSpaceContainerList.at(i)->m_blockViewCreationAndActivation=block;
+}
+
+void KateViewManager::activateNextView()
+{
+ if (m_currentContainer) {
+ m_currentContainer->activateNextView();
+ }
+}
+
+void KateViewManager::activatePrevView()
+{
+ if (m_currentContainer) {
+ m_currentContainer->activatePrevView();
+ }
+}
+
+void KateViewManager::closeViews(uint documentNumber)
+{
+ for (uint i=0;i<m_viewSpaceContainerList.count();i++) {
+ m_viewSpaceContainerList.at(i)->closeViews(documentNumber);
+ }
+ tabChanged(m_currentContainer);
+}
+
+void KateViewManager::slotDocumentNew ()
+{
+ if (m_currentContainer) m_currentContainer->createView ();
+}
+
+void KateViewManager::slotDocumentOpen ()
+{
+ Kate::View *cv = activeView();
+
+ if (cv) {
+ KEncodingFileDialog::Result r=KEncodingFileDialog::getOpenURLsAndEncoding(
+ (cv ? KTextEditor::encodingInterface(cv->document())->encoding() : Kate::Document::defaultEncoding()),
+ (cv ? cv->document()->url().url() : QString::null),
+ QString::null,m_mainWindow,i18n("Open File"));
+
+ uint lastID = 0;
+ for (KURL::List::Iterator i=r.URLs.begin(); i != r.URLs.end(); ++i)
+ lastID = openURL( *i, r.encoding, false );
+
+ if (lastID > 0)
+ activateView (lastID);
+ }
+}
+
+void KateViewManager::slotDocumentClose ()
+{
+ // no active view, do nothing
+ if (!activeView()) return;
+
+ // prevent close document if only one view alive and the document of
+ // it is not modified and empty !!!
+ if ( (KateDocManager::self()->documents() == 1)
+ && !activeView()->getDoc()->isModified()
+ && activeView()->getDoc()->url().isEmpty()
+ && (activeView()->getDoc()->length() == 0) )
+ {
+ activeView()->getDoc()->closeURL();
+ return;
+ }
+
+ // close document
+ KateDocManager::self()->closeDocument (activeView()->getDoc());
+}
+
+uint KateViewManager::openURL (const KURL &url, const QString& encoding, bool activate, bool isTempFile )
+{
+ uint id = 0;
+ Kate::Document *doc = KateDocManager::self()->openURL (url, encoding, &id, isTempFile );
+
+ if (!doc->url().isEmpty())
+ m_mainWindow->fileOpenRecent->addURL( doc->url() );
+
+ if (activate)
+ activateView( id );
+
+ return id;
+}
+
+void KateViewManager::openURL (const KURL &url)
+{
+ openURL (url, QString::null);
+}
+
+void KateViewManager::removeViewSpace (KateViewSpace *viewspace)
+{
+ if (m_currentContainer) {
+ m_currentContainer->removeViewSpace(viewspace);
+ }
+}
+
+void KateViewManager::slotCloseCurrentViewSpace()
+{
+ if (m_currentContainer) {
+ m_currentContainer->slotCloseCurrentViewSpace();
+ }
+}
+
+void KateViewManager::slotSplitViewSpaceVert()
+{
+ if (m_currentContainer) {
+ m_currentContainer->slotSplitViewSpaceVert();
+ }
+}
+
+void KateViewManager::slotSplitViewSpaceHoriz()
+{
+ if (m_currentContainer) {
+ m_currentContainer->slotSplitViewSpaceHoriz();
+ }
+}
+
+void KateViewManager::setShowFullPath( bool enable )
+{
+ showFullPath=enable;
+ for (uint i=0;i<m_viewSpaceContainerList.count();i++) {
+ m_viewSpaceContainerList.at(i)->setShowFullPath(enable);
+ }
+ m_mainWindow->slotWindowActivated ();
+ }
+
+/**
+ * session config functions
+ */
+// FIXME 3.0 - make those config goups more streamlined: "objN:objN..."
+void KateViewManager::saveViewConfiguration(KConfig *config,const QString& grp)
+{
+ // Use the same group name for view configuration as usual for sessions.
+ // (When called by session manager grp is a 1-based index for the main window)
+ QString group = grp;
+ bool ok = false;
+ int n = group.toInt( &ok );
+ if ( ok )
+ group = QString( "MainWindow%1" ).arg( n-1 );
+
+ config->setGroup(group);
+ config->writeEntry("ViewSpaceContainers",m_viewSpaceContainerList.count());
+ config->writeEntry("Active ViewSpaceContainer", m_mainWindow->tabWidget()->currentPageIndex());
+ for (uint i=0;i<m_viewSpaceContainerList.count();i++) {
+ m_viewSpaceContainerList.at(i)->saveViewConfiguration(config,group+QString(":ViewSpaceContainer-%1:").arg(i));
+ }
+}
+
+void KateViewManager::restoreViewConfiguration (KConfig *config, const QString& grp)
+{
+ // Use the same group name for view configuration as usual for sessions.
+ // (When called by session manager grp is a 1-based index for the main window)
+ QString group = grp;
+ bool ok = false;
+ int n = group.toInt( &ok );
+ if ( ok )
+ group = QString( "MainWindow%1" ).arg( n-1 );
+
+ config->setGroup(group);
+ uint tabCount=config->readNumEntry("ViewSpaceContainers",0);
+ int activeOne=config->readNumEntry("Active ViewSpaceContainer",0);
+ if (tabCount==0) return;
+ m_viewSpaceContainerList.at(0)->restoreViewConfiguration(config,group+QString(":ViewSpaceContainer-0:"));
+ for (uint i=1;i<tabCount;i++) {
+ slotNewTab();
+ m_viewSpaceContainerList.at(i)->restoreViewConfiguration(config,group+QString(":ViewSpaceContainer-%1:").arg(i));
+ }
+
+ if (activeOne != m_mainWindow->tabWidget()->currentPageIndex())
+ m_mainWindow->tabWidget()->setCurrentPage (activeOne);
+
+ updateViewSpaceActions();
+}
+
+KateMainWindow *KateViewManager::mainWindow() {
+ return m_mainWindow;
+}
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/kateviewmanager.h b/kate/app/kateviewmanager.h
new file mode 100644
index 000000000..6eb33e9f5
--- /dev/null
+++ b/kate/app/kateviewmanager.h
@@ -0,0 +1,154 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KATE_VIEWMANAGER_H__
+#define __KATE_VIEWMANAGER_H__
+
+#include "katemain.h"
+#include "../interfaces/viewmanager.h"
+
+#include <kate/view.h>
+#include <kate/document.h>
+#include <qguardedptr.h>
+
+class KateMainWindow;
+class KateViewSpaceContainer;
+
+class KConfig;
+class KAction;
+
+class QToolButton;
+
+class KateViewManager : public QObject
+{
+ Q_OBJECT
+
+ public:
+ KateViewManager (KateMainWindow *parent);
+ ~KateViewManager ();
+
+ Kate::ViewManager *viewManager () const { return m_viewManager; };
+
+ KateViewSpaceContainer *activeContainer () { return m_currentContainer; }
+
+ QPtrList<KateViewSpaceContainer> *containers() { return &m_viewSpaceContainerList; }
+
+ void updateViewSpaceActions ();
+
+ private:
+ /**
+ * create all actions needed for the view manager
+ */
+ void setupActions ();
+
+ public:
+ /* This will save the splitter configuration */
+ void saveViewConfiguration(KConfig *config,const QString& group);
+
+ /* restore it */
+ void restoreViewConfiguration (KConfig *config,const QString& group);
+
+ uint openURL (const KURL &url, const QString& encoding, bool activate = true, bool isTempFile=false);
+
+ public slots:
+ void openURL (const KURL &url);
+
+ private:
+ void removeViewSpace (KateViewSpace *viewspace);
+
+ bool showFullPath;
+
+ public:
+ Kate::View* activeView ();
+ KateViewSpace* activeViewSpace ();
+
+ uint viewCount ();
+ uint viewSpaceCount ();
+
+ void setViewActivationBlocked (bool block);
+
+ public:
+ void closeViews(uint documentNumber);
+ KateMainWindow *mainWindow();
+
+ private slots:
+ void activateView ( Kate::View *view );
+ void activateSpace ( Kate::View* v );
+
+ void tabChanged(QWidget*);
+
+ public slots:
+ bool getShowFullPath() const { return showFullPath; }
+
+ void activateView ( uint documentNumber );
+ void activateView ( int documentNumber ) { activateView((uint) documentNumber); };
+
+ void slotDocumentNew ();
+ void slotDocumentOpen ();
+ void slotDocumentClose ();
+
+ /** Splits the active viewspace horizontally */
+ void slotSplitViewSpaceHoriz ();
+ /** Splits the active viewspace vertically */
+ void slotSplitViewSpaceVert ();
+
+ void slotNewTab();
+ void slotCloseTab ();
+ void activateNextTab ();
+ void activatePrevTab ();
+
+ void slotCloseCurrentViewSpace();
+
+ void setActiveSpace ( KateViewSpace* vs );
+ void setActiveView ( Kate::View* view );
+
+ void setShowFullPath(bool enable);
+
+ void activateNextView();
+ void activatePrevView();
+
+ protected:
+ friend class KateViewSpaceContainer;
+
+ QGuardedPtr<Kate::View> guiMergedView;
+
+ signals:
+ void statusChanged (Kate::View *, int, int, int, bool, int, const QString &);
+ void statChanged ();
+ void viewChanged ();
+
+ private:
+ Kate::ViewManager *m_viewManager;
+ QPtrList<KateViewSpaceContainer> m_viewSpaceContainerList;
+ KateViewSpaceContainer *m_currentContainer;
+
+ KateMainWindow *m_mainWindow;
+ bool m_init;
+
+ QToolButton *m_closeTabButton;
+ KAction *m_closeView;
+ KAction *m_closeTab;
+ KAction *m_activateNextTab;
+ KAction *m_activatePrevTab;
+ KAction *goNext;
+ KAction *goPrev;
+};
+
+#endif
diff --git a/kate/app/kateviewspace.cpp b/kate/app/kateviewspace.cpp
new file mode 100644
index 000000000..9efb155e4
--- /dev/null
+++ b/kate/app/kateviewspace.cpp
@@ -0,0 +1,422 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001, 2005 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ 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 "kateviewspace.h"
+#include "kateviewspace.moc"
+
+#include "katemainwindow.h"
+#include "kateviewspacecontainer.h"
+#include "katedocmanager.h"
+#include "kateapp.h"
+#include "katesession.h"
+
+#include <kiconloader.h>
+#include <klocale.h>
+#include <ksqueezedtextlabel.h>
+#include <kconfig.h>
+#include <kdebug.h>
+
+#include <qwidgetstack.h>
+#include <qpainter.h>
+#include <qlabel.h>
+#include <qcursor.h>
+#include <qpopupmenu.h>
+#include <qpixmap.h>
+
+//BEGIN KVSSBSep
+/*
+ "KateViewSpaceStatusBarSeparator"
+ A 2 px line to separate the statusbar from the view.
+ It is here to compensate for the lack of a frame in the view,
+ I think Kate looks very nice this way, as QScrollView with frame
+ looks slightly clumsy...
+ Slight 3D effect. I looked for suitable QStyle props or methods,
+ but found none, though maybe it should use QStyle::PM_DefaultFrameWidth
+ for height (TRY!).
+ It does look a bit funny with flat styles (Light, .Net) as is,
+ but there are on methods to paint panel lines separately. And,
+ those styles tends to look funny on their own, as a light line
+ in a 3D frame next to a light contents widget is not functional.
+ Also, QStatusBar is up to now completely ignorant to style.
+ -anders
+*/
+class KVSSBSep : public QWidget {
+public:
+ KVSSBSep( KateViewSpace *parent=0) : QWidget(parent)
+ {
+ setFixedHeight( 2 );
+ }
+protected:
+ void paintEvent( QPaintEvent *e )
+ {
+ QPainter p( this );
+ p.setPen( colorGroup().shadow() );
+ p.drawLine( e->rect().left(), 0, e->rect().right(), 0 );
+ p.setPen( ((KateViewSpace*)parentWidget())->isActiveSpace() ? colorGroup().light() : colorGroup().midlight() );
+ p.drawLine( e->rect().left(), 1, e->rect().right(), 1 );
+ }
+};
+//END KVSSBSep
+
+//BEGIN KateViewSpace
+KateViewSpace::KateViewSpace( KateViewSpaceContainer *viewManager,
+ QWidget* parent, const char* name )
+ : QVBox(parent, name),
+ m_viewManager( viewManager )
+{
+ mViewList.setAutoDelete(false);
+
+ stack = new QWidgetStack( this );
+ setStretchFactor(stack, 1);
+ stack->setFocus();
+ //sep = new KVSSBSep( this );
+ mStatusBar = new KateVSStatusBar(this);
+ mIsActiveSpace = false;
+ mViewCount = 0;
+
+ setMinimumWidth (mStatusBar->minimumWidth());
+ m_group = QString::null;
+}
+
+KateViewSpace::~KateViewSpace()
+{
+}
+
+void KateViewSpace::polish()
+{
+ mStatusBar->show();
+}
+
+void KateViewSpace::addView(Kate::View* v, bool show)
+{
+ // restore the config of this view if possible
+ if ( !m_group.isEmpty() )
+ {
+ QString fn = v->getDoc()->url().prettyURL();
+ if ( ! fn.isEmpty() )
+ {
+ QString vgroup = QString("%1 %2").arg(m_group).arg(fn);
+
+ KateSession::Ptr as = KateSessionManager::self()->activeSession ();
+ if ( as->configRead() && as->configRead()->hasGroup( vgroup ) )
+ {
+ as->configRead()->setGroup( vgroup );
+ v->readSessionConfig ( as->configRead() );
+ }
+ }
+ }
+
+ uint id = mViewList.count();
+ stack->addWidget(v, id);
+ if (show) {
+ mViewList.append(v);
+ showView( v );
+ }
+ else {
+ Kate::View* c = mViewList.current();
+ mViewList.prepend( v );
+ showView( c );
+ }
+}
+
+void KateViewSpace::removeView(Kate::View* v)
+{
+ disconnect( v->getDoc(), SIGNAL(modifiedChanged()),
+ mStatusBar, SLOT(modifiedChanged()) );
+
+ bool active = ( v == currentView() );
+
+ mViewList.remove (v);
+ stack->removeWidget (v);
+
+ if ( ! active )
+ return;
+
+ if (currentView() != 0L)
+ showView(mViewList.current());
+ else if (mViewList.count() > 0)
+ showView(mViewList.last());
+}
+
+bool KateViewSpace::showView(Kate::View* v)
+{
+ return showView( v->getDoc()->documentNumber() );
+}
+
+bool KateViewSpace::showView(uint documentNumber)
+{
+ QPtrListIterator<Kate::View> it (mViewList);
+ it.toLast();
+ for( ; it.current(); --it ) {
+ if (((Kate::Document*)it.current()->getDoc())->documentNumber() == documentNumber) {
+ if ( currentView() )
+ disconnect( currentView()->getDoc(), SIGNAL(modifiedChanged()),
+ mStatusBar, SLOT(modifiedChanged()) );
+
+ Kate::View* kv = it.current();
+ connect( kv->getDoc(), SIGNAL(modifiedChanged()),
+ mStatusBar, SLOT(modifiedChanged()) );
+
+ mViewList.removeRef( kv );
+ mViewList.append( kv );
+ stack->raiseWidget( kv );
+ kv->show();
+ mStatusBar->modifiedChanged();
+ return true;
+ }
+ }
+ return false;
+}
+
+
+Kate::View* KateViewSpace::currentView()
+{
+ if (mViewList.count() > 0)
+ return (Kate::View*)stack->visibleWidget();
+
+ return 0L;
+}
+
+bool KateViewSpace::isActiveSpace()
+{
+ return mIsActiveSpace;
+}
+
+void KateViewSpace::setActive( bool active, bool )
+{
+ mIsActiveSpace = active;
+
+ // change the statusbar palette and make sure it gets updated
+ QPalette pal( palette() );
+ if ( ! active )
+ {
+ pal.setColor( QColorGroup::Background, pal.active().mid() );
+ pal.setColor( QColorGroup::Light, pal.active().midlight() );
+ }
+
+ mStatusBar->setPalette( pal );
+ mStatusBar->update();
+ //sep->update();
+}
+
+bool KateViewSpace::event( QEvent *e )
+{
+ if ( e->type() == QEvent::PaletteChange )
+ {
+ setActive( mIsActiveSpace );
+ return true;
+ }
+ return QVBox::event( e );
+}
+
+void KateViewSpace::slotStatusChanged (Kate::View *view, int r, int c, int ovr, bool block, int mod, const QString &msg)
+{
+ if ((QWidgetStack *)view->parentWidget() != stack)
+ return;
+ mStatusBar->setStatus( r, c, ovr, block, mod, msg );
+}
+
+void KateViewSpace::saveConfig ( KConfig* config, int myIndex ,const QString& viewConfGrp)
+{
+// kdDebug()<<"KateViewSpace::saveConfig("<<myIndex<<", "<<viewConfGrp<<") - currentView: "<<currentView()<<")"<<endl;
+ QString group = QString(viewConfGrp+"-ViewSpace %1").arg( myIndex );
+
+ config->setGroup (group);
+ config->writeEntry ("Count", mViewList.count());
+
+ if (currentView())
+ config->writeEntry( "Active View", currentView()->getDoc()->url().prettyURL() );
+
+ // Save file list, includeing cursor position in this instance.
+ QPtrListIterator<Kate::View> it(mViewList);
+
+ int idx = 0;
+ for (; it.current(); ++it)
+ {
+ if ( !it.current()->getDoc()->url().isEmpty() )
+ {
+ config->setGroup( group );
+ config->writeEntry( QString("View %1").arg( idx ), it.current()->getDoc()->url().prettyURL() );
+
+ // view config, group: "ViewSpace <n> url"
+ QString vgroup = QString("%1 %2").arg(group).arg(it.current()->getDoc()->url().prettyURL());
+ config->setGroup( vgroup );
+ it.current()->writeSessionConfig( config );
+ }
+
+ idx++;
+ }
+}
+
+void KateViewSpace::modifiedOnDisc(Kate::Document *, bool, unsigned char)
+{
+ if ( currentView() )
+ mStatusBar->updateMod( currentView()->getDoc()->isModified() );
+}
+
+void KateViewSpace::restoreConfig ( KateViewSpaceContainer *viewMan, KConfig* config, const QString &group )
+{
+ config->setGroup (group);
+ QString fn = config->readEntry( "Active View" );
+
+ if ( !fn.isEmpty() )
+ {
+ Kate::Document *doc = KateDocManager::self()->findDocumentByUrl (KURL(fn));
+
+ if (doc)
+ {
+ // view config, group: "ViewSpace <n> url"
+ QString vgroup = QString("%1 %2").arg(group).arg(fn);
+ config->setGroup( vgroup );
+
+ viewMan->createView (doc);
+
+ Kate::View *v = viewMan->activeView ();
+
+ if (v)
+ v->readSessionConfig( config );
+ }
+ }
+
+ if (mViewList.isEmpty())
+ viewMan->createView (KateDocManager::self()->document(0));
+
+ m_group = group; // used for restroing view configs later
+}
+//END KateViewSpace
+
+//BEGIN KateVSStatusBar
+KateVSStatusBar::KateVSStatusBar ( KateViewSpace *parent, const char *name )
+ : KStatusBar( parent, name ),
+ m_viewSpace( parent )
+{
+ m_lineColLabel = new QLabel( this );
+ addWidget( m_lineColLabel, 0, false );
+ m_lineColLabel->setAlignment( Qt::AlignCenter );
+ m_lineColLabel->installEventFilter( this );
+
+ m_modifiedLabel = new QLabel( QString(" "), this );
+ addWidget( m_modifiedLabel, 0, false );
+ m_modifiedLabel->setAlignment( Qt::AlignCenter );
+ m_modifiedLabel->installEventFilter( this );
+
+ m_insertModeLabel = new QLabel( i18n(" INS "), this );
+ addWidget( m_insertModeLabel, 0, false );
+ m_insertModeLabel->setAlignment( Qt::AlignCenter );
+ m_insertModeLabel->installEventFilter( this );
+
+ m_selectModeLabel = new QLabel( i18n(" NORM "), this );
+ addWidget( m_selectModeLabel, 0, false );
+ m_selectModeLabel->setAlignment( Qt::AlignCenter );
+ m_selectModeLabel->installEventFilter( this );
+
+ m_fileNameLabel=new KSqueezedTextLabel( this );
+ addWidget( m_fileNameLabel, 1, true );
+ m_fileNameLabel->setMinimumSize( 0, 0 );
+ m_fileNameLabel->setSizePolicy(QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Fixed ));
+ m_fileNameLabel->setAlignment( /*Qt::AlignRight*/Qt::AlignLeft );
+ m_fileNameLabel->installEventFilter( this );
+
+ installEventFilter( this );
+ m_modPm = SmallIcon("modified");
+ m_modDiscPm = SmallIcon("modonhd");
+ m_modmodPm = SmallIcon("modmod");
+ m_noPm = SmallIcon("null");
+}
+
+KateVSStatusBar::~KateVSStatusBar ()
+{
+}
+
+void KateVSStatusBar::setStatus( int r, int c, int ovr, bool block, int, const QString &msg )
+{
+ m_lineColLabel->setText(
+ i18n(" Line: %1 Col: %2 ").arg(KGlobal::locale()->formatNumber(r+1, 0))
+ .arg(KGlobal::locale()->formatNumber(c+1, 0)) );
+
+ if (ovr == 0)
+ m_insertModeLabel->setText( i18n(" R/O ") );
+ else if (ovr == 1)
+ m_insertModeLabel->setText( i18n(" OVR ") );
+ else if (ovr == 2)
+ m_insertModeLabel->setText( i18n(" INS ") );
+
+// updateMod( mod );
+
+ m_selectModeLabel->setText( block ? i18n(" BLK ") : i18n(" NORM ") );
+
+ m_fileNameLabel->setText( msg );
+}
+
+void KateVSStatusBar::updateMod( bool mod )
+{
+ Kate::View *v = m_viewSpace->currentView();
+ if ( v )
+ {
+ const KateDocumentInfo *info
+ = KateDocManager::self()->documentInfo ( v->getDoc() );
+
+ bool modOnHD = info && info->modifiedOnDisc;
+
+ m_modifiedLabel->setPixmap(
+ mod ?
+ info && modOnHD ?
+ m_modmodPm :
+ m_modPm :
+ info && modOnHD ?
+ m_modDiscPm :
+ m_noPm
+ );
+ }
+}
+
+void KateVSStatusBar::modifiedChanged()
+{
+ Kate::View *v = m_viewSpace->currentView();
+ if ( v )
+ updateMod( v->getDoc()->isModified() );
+}
+
+void KateVSStatusBar::showMenu()
+{
+ KMainWindow* mainWindow = static_cast<KMainWindow*>( topLevelWidget() );
+ QPopupMenu* menu = static_cast<QPopupMenu*>( mainWindow->factory()->container("viewspace_popup", mainWindow ) );
+
+ if (menu)
+ menu->exec(QCursor::pos());
+}
+
+bool KateVSStatusBar::eventFilter(QObject*,QEvent *e)
+{
+ if (e->type()==QEvent::MouseButtonPress)
+ {
+ if ( m_viewSpace->currentView() )
+ m_viewSpace->currentView()->setFocus();
+
+ if ( ((QMouseEvent*)e)->button()==RightButton)
+ showMenu();
+
+ return true;
+ }
+
+ return false;
+}
+//END KateVSStatusBar
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/kateviewspace.h b/kate/app/kateviewspace.h
new file mode 100644
index 000000000..a07b5f6da
--- /dev/null
+++ b/kate/app/kateviewspace.h
@@ -0,0 +1,121 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KATE_VIEWSPACE_H__
+#define __KATE_VIEWSPACE_H__
+
+#include "katemain.h"
+
+#include <kate/view.h>
+#include <kate/document.h>
+
+#include <qptrlist.h>
+#include <qwidget.h>
+#include <qvbox.h>
+#include <kstatusbar.h>
+
+class KVSSBSep;
+
+class KConfig;
+class KSqueezedTextLabel;
+class KateViewSpaceContainer;
+
+class KateVSStatusBar : public KStatusBar
+{
+ Q_OBJECT
+
+ public:
+ KateVSStatusBar ( KateViewSpace *parent = 0L, const char *name = 0L );
+ virtual ~KateVSStatusBar ();
+
+ public slots:
+ void setStatus( int r, int c, int ovr, bool block, int mod, const QString &msg );
+ void updateMod( bool );
+ /**
+ * changed the modified icon according to document state.
+ * @since Kate 2.4
+ */
+ void modifiedChanged();
+
+ protected:
+ virtual bool eventFilter (QObject*,QEvent *);
+ virtual void showMenu ();
+
+ private:
+ QLabel* m_lineColLabel;
+ QLabel* m_modifiedLabel;
+ QLabel* m_insertModeLabel;
+ QLabel* m_selectModeLabel;
+ KSqueezedTextLabel* m_fileNameLabel;
+ QPixmap m_modPm, m_modDiscPm, m_modmodPm, m_noPm;
+ class KateViewSpace *m_viewSpace;
+};
+
+class KateViewSpace : public QVBox
+{
+ friend class KateViewSpaceContainer;
+ friend class KateVSStatusBar;
+
+ Q_OBJECT
+
+ public:
+ KateViewSpace(KateViewSpaceContainer *, QWidget* parent=0, const char* name=0);
+ ~KateViewSpace();
+ bool isActiveSpace();
+ void setActive(bool b, bool showled=false);
+ QWidgetStack* stack;
+ void addView(Kate::View* v, bool show=true);
+ void removeView(Kate::View* v);
+ bool showView(Kate::View* v);
+ bool showView(uint docID);
+ Kate::View* currentView();
+ int viewCount() const { return mViewList.count(); }
+
+ void saveConfig (KConfig* config, int myIndex,const QString& viewConfGrp);
+ void restoreConfig ( class KateViewSpaceContainer *viewMan, KConfig* config, const QString &group );
+
+
+ protected:
+ /** reimplemented to catch QEvent::PaletteChange,
+ since we use a modified palette for the statusbar */
+ bool event( QEvent * );
+
+ private:
+ bool mIsActiveSpace;
+ KateVSStatusBar* mStatusBar;
+ QLabel* l;
+ QPixmap i_active;
+ QPixmap i_empty;
+ QPtrList<Kate::View> mViewList;
+ int mViewCount;
+ KVSSBSep *sep;
+ KateViewSpaceContainer *m_viewManager;
+ QString m_group;
+
+ private slots:
+ void slotStatusChanged (Kate::View *view, int r, int c, int ovr, bool block, int mod, const QString &msg);
+
+ public slots:
+ void polish();
+ void modifiedOnDisc(Kate::Document *, bool, unsigned char);
+};
+
+#endif
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/kateviewspacecontainer.cpp b/kate/app/kateviewspacecontainer.cpp
new file mode 100644
index 000000000..08a3bf6f6
--- /dev/null
+++ b/kate/app/kateviewspacecontainer.cpp
@@ -0,0 +1,758 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ 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.
+*/
+
+//BEGIN Includes
+#include "kateviewspacecontainer.h"
+#include "kateviewspacecontainer.moc"
+
+#include "katetabwidget.h"
+#include "katemainwindow.h"
+#include "katedocmanager.h"
+#include "kateviewmanager.h"
+#include "kateviewspace.h"
+
+#include <dcopclient.h>
+#include <kaction.h>
+#include <kcmdlineargs.h>
+#include <kdebug.h>
+#include <kdiroperator.h>
+#include <kdockwidget.h>
+#include <kencodingfiledialog.h>
+#include <kiconloader.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <ktoolbar.h>
+#include <kmessagebox.h>
+#include <ksimpleconfig.h>
+#include <kstdaction.h>
+#include <kstandarddirs.h>
+#include <kglobalsettings.h>
+#include <kstringhandler.h>
+
+#include <ktexteditor/encodinginterface.h>
+
+#include <qlayout.h>
+#include <qobjectlist.h>
+#include <qstringlist.h>
+#include <qvbox.h>
+#include <qtimer.h>
+#include <qfileinfo.h>
+
+//END Includes
+
+KateViewSpaceContainer::KateViewSpaceContainer (QWidget *parent, KateViewManager *viewManager)
+ : QVBox (parent)
+ , m_viewManager(viewManager)
+ , m_blockViewCreationAndActivation (false)
+ , m_activeViewRunning (false)
+ , m_pendingViewCreation(false)
+{
+ // no memleaks
+ m_viewList.setAutoDelete(true);
+ m_viewSpaceList.setAutoDelete(true);
+
+ KateViewSpace* vs = new KateViewSpace( this, this );
+ connect(this, SIGNAL(statusChanged(Kate::View *, int, int, int, bool, int, const QString&)), vs, SLOT(slotStatusChanged(Kate::View *, int, int, int, bool, int, const QString&)));
+ vs->setActive( true );
+ m_viewSpaceList.append(vs);
+ connect( this, SIGNAL(viewChanged()), this, SLOT(slotViewChanged()) );
+ connect(KateDocManager::self(), SIGNAL(initialDocumentReplaced()), this, SIGNAL(viewChanged()));
+
+ connect(KateDocManager::self(),SIGNAL(documentCreated(Kate::Document *)),this,SLOT(documentCreated(Kate::Document *)));
+ connect(KateDocManager::self(),SIGNAL(documentDeleted(uint)),this,SLOT(documentDeleted(uint)));
+}
+
+KateViewSpaceContainer::~KateViewSpaceContainer ()
+{
+ m_viewList.setAutoDelete(false);
+ m_viewSpaceList.setAutoDelete(false);
+}
+
+void KateViewSpaceContainer::documentCreated (Kate::Document *doc)
+{
+ if (m_blockViewCreationAndActivation) return;
+
+ if (!activeView())
+ activateView (doc->documentNumber());
+}
+
+void KateViewSpaceContainer::documentDeleted (uint)
+{
+ if (m_blockViewCreationAndActivation) return;
+
+ // just for the case we close a document out of many and this was the active one
+ // if all docs are closed, this will be handled by the documentCreated
+ if (!activeView() && (KateDocManager::self()->documents() > 0))
+ createView (KateDocManager::self()->document(KateDocManager::self()->documents()-1));
+}
+
+bool KateViewSpaceContainer::createView ( Kate::Document *doc )
+{
+ if (m_blockViewCreationAndActivation) return false;
+
+ // create doc
+ if (!doc)
+ doc = KateDocManager::self()->createDoc ();
+
+ // create view
+ Kate::View *view = (Kate::View *) doc->createView (this, 0L);
+
+ m_viewList.append (view);
+
+ // disable settings dialog action
+ view->actionCollection()->remove (view->actionCollection()->action( "set_confdlg" ));
+
+ // popup menu
+ view->installPopup ((QPopupMenu*)(mainWindow()->factory()->container("ktexteditor_popup", mainWindow())) );
+
+ connect(view->getDoc(),SIGNAL(nameChanged(Kate::Document *)),this,SLOT(statusMsg()));
+ connect(view,SIGNAL(cursorPositionChanged()),this,SLOT(statusMsg()));
+ connect(view,SIGNAL(newStatus()),this,SLOT(statusMsg()));
+ connect(view->getDoc(), SIGNAL(undoChanged()), this, SLOT(statusMsg()));
+ connect(view,SIGNAL(dropEventPass(QDropEvent *)), mainWindow(),SLOT(slotDropEvent(QDropEvent *)));
+ connect(view,SIGNAL(gotFocus(Kate::View *)),this,SLOT(activateSpace(Kate::View *)));
+
+ activeViewSpace()->addView( view );
+ activateView( view );
+ connect( doc, SIGNAL(modifiedOnDisc(Kate::Document *, bool, unsigned char)),
+ activeViewSpace(), SLOT(modifiedOnDisc(Kate::Document *, bool, unsigned char)) );
+
+ return true;
+}
+
+bool KateViewSpaceContainer::deleteView (Kate::View *view, bool delViewSpace)
+{
+ if (!view) return true;
+
+ KateViewSpace *viewspace = (KateViewSpace *)view->parentWidget()->parentWidget();
+
+ viewspace->removeView (view);
+
+ mainWindow()->guiFactory ()->removeClient (view);
+
+ // remove view from list and memory !!
+ m_viewList.remove (view);
+
+ if (delViewSpace)
+ if ( viewspace->viewCount() == 0 )
+ removeViewSpace( viewspace );
+
+ return true;
+}
+
+KateViewSpace* KateViewSpaceContainer::activeViewSpace ()
+{
+ QPtrListIterator<KateViewSpace> it(m_viewSpaceList);
+
+ for (; it.current(); ++it)
+ {
+ if ( it.current()->isActiveSpace() )
+ return it.current();
+ }
+
+ if (m_viewSpaceList.count() > 0)
+ {
+ m_viewSpaceList.first()->setActive( true );
+ return m_viewSpaceList.first();
+ }
+
+ return 0L;
+}
+
+Kate::View* KateViewSpaceContainer::activeView ()
+{
+ if (m_activeViewRunning)
+ return 0L;
+
+ m_activeViewRunning = true;
+
+ for (QPtrListIterator<Kate::View> it(m_viewList); it.current(); ++it)
+ {
+ if ( it.current()->isActive() )
+ {
+ m_activeViewRunning = false;
+ return it.current();
+ }
+ }
+
+ // if we get to here, no view isActive()
+ // first, try to get one from activeViewSpace()
+ KateViewSpace* vs;
+ if ( (vs = activeViewSpace()) )
+ {
+ if ( vs->currentView() )
+ {
+ activateView (vs->currentView());
+
+ m_activeViewRunning = false;
+ return vs->currentView();
+ }
+ }
+
+ // last attempt: just pick first
+ if (m_viewList.count() > 0)
+ {
+ activateView (m_viewList.first());
+
+ m_activeViewRunning = false;
+ return m_viewList.first();
+ }
+
+ m_activeViewRunning = false;
+
+ // no views exists!
+ return 0L;
+}
+
+void KateViewSpaceContainer::setActiveSpace ( KateViewSpace* vs )
+{
+ if (activeViewSpace())
+ activeViewSpace()->setActive( false );
+
+ vs->setActive( true, viewSpaceCount() > 1 );
+}
+
+void KateViewSpaceContainer::setActiveView ( Kate::View* view )
+{
+ if (activeView())
+ activeView()->setActive( false );
+
+ view->setActive( true );
+}
+
+void KateViewSpaceContainer::activateSpace (Kate::View* v)
+{
+ if (!v) return;
+
+ KateViewSpace* vs = (KateViewSpace*)v->parentWidget()->parentWidget();
+
+ if (!vs->isActiveSpace()) {
+ setActiveSpace (vs);
+ activateView(v);
+ }
+}
+
+void KateViewSpaceContainer::reactivateActiveView() {
+ Kate::View *view=activeView();
+ if (view) {
+ view->setActive(false);
+ activateView(view);
+ } else if (m_pendingViewCreation) {
+ m_pendingViewCreation=false;
+ disconnect(m_pendingDocument,SIGNAL(nameChanged(Kate::Document *)),this,SLOT(slotPendingDocumentNameChanged()));
+ createView(m_pendingDocument);
+ }
+}
+
+void KateViewSpaceContainer::activateView ( Kate::View *view )
+{
+ if (!view) return;
+
+ if (!view->isActive())
+ {
+ if ( !activeViewSpace()->showView (view) )
+ {
+ // since it wasn't found, give'em a new one
+ createView ( view->getDoc() );
+ return;
+ }
+
+ setActiveView (view);
+ m_viewList.findRef (view);
+
+ mainWindow()->toolBar ()->setUpdatesEnabled (false);
+
+ if (m_viewManager->guiMergedView)
+ mainWindow()->guiFactory()->removeClient (m_viewManager->guiMergedView );
+
+ m_viewManager->guiMergedView = view;
+
+ if (!m_blockViewCreationAndActivation)
+ mainWindow()->guiFactory ()->addClient( view );
+
+ mainWindow()->toolBar ()->setUpdatesEnabled (true);
+
+ statusMsg();
+
+ emit viewChanged ();
+ }
+
+ KateDocManager::self()->setActiveDocument(view->getDoc());
+}
+
+void KateViewSpaceContainer::activateView( uint documentNumber )
+{
+ if ( activeViewSpace()->showView(documentNumber) ) {
+ activateView( activeViewSpace()->currentView() );
+ }
+ else
+ {
+ QPtrListIterator<Kate::View> it(m_viewList);
+ for ( ;it.current(); ++it)
+ {
+ if ( it.current()->getDoc()->documentNumber() == documentNumber )
+ {
+ createView( it.current()->getDoc() );
+ return;
+ }
+ }
+
+ Kate::Document *d = (Kate::Document *)KateDocManager::self()->documentWithID(documentNumber);
+ createView (d);
+ }
+}
+
+uint KateViewSpaceContainer::viewCount ()
+{
+ return m_viewList.count();
+}
+
+uint KateViewSpaceContainer::viewSpaceCount ()
+{
+ return m_viewSpaceList.count();
+}
+
+void KateViewSpaceContainer::slotViewChanged()
+{
+ if ( activeView() && !activeView()->hasFocus())
+ activeView()->setFocus();
+}
+
+void KateViewSpaceContainer::activateNextView()
+{
+ uint i = m_viewSpaceList.find (activeViewSpace())+1;
+
+ if (i >= m_viewSpaceList.count())
+ i=0;
+
+ setActiveSpace (m_viewSpaceList.at(i));
+ activateView(m_viewSpaceList.at(i)->currentView());
+}
+
+void KateViewSpaceContainer::activatePrevView()
+{
+ int i = m_viewSpaceList.find (activeViewSpace())-1;
+
+ if (i < 0)
+ i=m_viewSpaceList.count()-1;
+
+ setActiveSpace (m_viewSpaceList.at(i));
+ activateView(m_viewSpaceList.at(i)->currentView());
+}
+
+void KateViewSpaceContainer::closeViews(uint documentNumber)
+{
+ QPtrList<Kate::View> closeList;
+
+ for (uint z=0 ; z < m_viewList.count(); z++)
+ {
+ Kate::View* current = m_viewList.at(z);
+ if ( current->getDoc()->documentNumber() == documentNumber )
+ {
+ closeList.append (current);
+ }
+ }
+
+ while ( !closeList.isEmpty() )
+ {
+ Kate::View *view = closeList.first();
+ deleteView (view, true);
+ closeList.removeFirst();
+ }
+
+ if (m_blockViewCreationAndActivation) return;
+ QTimer::singleShot(0,this,SIGNAL(viewChanged()));
+ //emit m_viewManager->viewChanged ();
+}
+
+void KateViewSpaceContainer::slotPendingDocumentNameChanged() {
+ QString c;
+ if (m_pendingDocument->url().isEmpty() || (!showFullPath))
+ {
+ c = m_pendingDocument->docName();
+ }
+ else
+ {
+ c = m_pendingDocument->url().prettyURL();
+ }
+ setCaption(KStringHandler::lsqueeze(c,32));
+}
+
+void KateViewSpaceContainer::statusMsg ()
+{
+ if (!activeView()) return;
+
+ Kate::View* v = activeView();
+
+ bool readOnly = !v->getDoc()->isReadWrite();
+ uint config = v->getDoc()->configFlags();
+
+ int ovr = 0;
+ if (readOnly)
+ ovr = 0;
+ else
+ {
+ if (config & Kate::Document::cfOvr)
+ {
+ ovr=1;
+ }
+ else
+ {
+ ovr=2;
+ }
+ }
+
+ int mod = (int)v->getDoc()->isModified();
+ bool block=v->getDoc()->blockSelectionMode();
+
+ QString c;
+ if (v->getDoc()->url().isEmpty() || (!showFullPath))
+ {
+ c = v->getDoc()->docName();
+ }
+ else
+ {
+ c = v->getDoc()->url().prettyURL();
+ }
+
+ m_viewManager->mainWindow()->tabWidget()->changeTab (this, KStringHandler::lsqueeze(c,32));
+ emit statusChanged (v, v->cursorLine(), v->cursorColumn(), ovr,block, mod, KStringHandler::lsqueeze(c,64));
+ emit statChanged ();
+}
+
+void KateViewSpaceContainer::splitViewSpace( KateViewSpace* vs,
+ bool isHoriz,
+ bool atTop)
+{
+// kdDebug(13001)<<"splitViewSpace()"<<endl;
+
+ if (!activeView()) return;
+ if (!vs) vs = activeViewSpace();
+
+ bool isFirstTime = vs->parentWidget() == this;
+
+ QValueList<int> psizes;
+ if ( ! isFirstTime )
+ if ( QSplitter *ps = static_cast<QSplitter*>(vs->parentWidget()->qt_cast("QSplitter")) )
+ psizes = ps->sizes();
+
+ Qt::Orientation o = isHoriz ? Qt::Vertical : Qt::Horizontal;
+ KateMDI::Splitter* s = new KateMDI::Splitter(o, vs->parentWidget());
+ s->setOpaqueResize( KGlobalSettings::opaqueResize() );
+
+ if (! isFirstTime) {
+ // anders: make sure the split' viewspace is always
+ // correctly positioned.
+ // If viewSpace is the first child, the new splitter must be moveToFirst'd
+ if ( !((KateMDI::Splitter*)vs->parentWidget())->isLastChild( vs ) )
+ ((KateMDI::Splitter*)s->parentWidget())->moveToFirst( s );
+ }
+ vs->reparent( s, 0, QPoint(), true );
+ KateViewSpace* vsNew = new KateViewSpace( this, s );
+
+ if (atTop)
+ s->moveToFirst( vsNew );
+
+ if (!isFirstTime)
+ if (QSplitter *ps = static_cast<QSplitter*>(s->parentWidget()->qt_cast("QSplitter")) )
+ ps->setSizes( psizes );
+
+ s->show();
+
+ QValueList<int> sizes;
+ int space = 50;//isHoriz ? s->parentWidget()->height()/2 : s->parentWidget()->width()/2;
+ sizes << space << space;
+ s->setSizes( sizes );
+
+ connect(this, SIGNAL(statusChanged(Kate::View *, int, int, int, bool, int, const QString &)), vsNew, SLOT(slotStatusChanged(Kate::View *, int, int,int, bool, int, const QString &)));
+ m_viewSpaceList.append( vsNew );
+ activeViewSpace()->setActive( false );
+ vsNew->setActive( true, true );
+ vsNew->show();
+
+ createView (activeView()->getDoc());
+
+ if (this == m_viewManager->activeContainer())
+ m_viewManager->updateViewSpaceActions ();
+
+// kdDebug(13001)<<"splitViewSpace() - DONE!"<<endl;
+}
+
+void KateViewSpaceContainer::removeViewSpace (KateViewSpace *viewspace)
+{
+ // abort if viewspace is 0
+ if (!viewspace) return;
+
+ // abort if this is the last viewspace
+ if (m_viewSpaceList.count() < 2) return;
+
+ KateMDI::Splitter* p = (KateMDI::Splitter*)viewspace->parentWidget();
+
+ // find out if it is the first child for repositioning
+ // see below
+ bool pIsFirst = false;
+
+ // save some size information
+ KateMDI::Splitter* pp=0L;
+ QValueList<int> ppsizes;
+ if (m_viewSpaceList.count() > 2 && p->parentWidget() != this)
+ {
+ pp = (KateMDI::Splitter*)p->parentWidget();
+ ppsizes = pp->sizes();
+ pIsFirst = !pp->isLastChild( p ); // simple logic, right-
+ }
+
+ // Figure out where to put views that are still needed
+ KateViewSpace* next;
+ if (m_viewSpaceList.find(viewspace) == 0)
+ next = m_viewSpaceList.next();
+ else
+ next = m_viewSpaceList.prev();
+
+ // Reparent views in viewspace that are last views, delete the rest.
+ int vsvc = viewspace->viewCount();
+ while (vsvc > 0)
+ {
+ if (viewspace->currentView())
+ {
+ Kate::View* v = viewspace->currentView();
+
+ if (v->isLastView())
+ {
+ viewspace->removeView(v);
+ next->addView( v, false );
+ }
+ else
+ {
+ deleteView( v, false );
+ }
+ }
+ vsvc = viewspace->viewCount();
+ }
+
+ m_viewSpaceList.remove( viewspace );
+
+ // reparent the other sibling of the parent.
+ while (p->children ())
+ {
+ QWidget* other = ((QWidget *)(( QPtrList<QObject>*)p->children())->first());
+
+ other->reparent( p->parentWidget(), 0, QPoint(), true );
+ // We also need to find the right viewspace to become active
+ if (pIsFirst)
+ ((KateMDI::Splitter*)p->parentWidget())->moveToFirst( other );
+ if ( other->isA("KateViewSpace") ) {
+ setActiveSpace( (KateViewSpace*)other );
+ }
+ else {
+ QObjectList* l = other->queryList( "KateViewSpace" );
+ if ( l->first() != 0 ) { // I REALLY hope so!
+ setActiveSpace( (KateViewSpace*)l->first() );
+ }
+ delete l;
+ }
+ }
+
+ delete p;
+
+ if (!ppsizes.isEmpty())
+ pp->setSizes( ppsizes );
+
+ // find the view that is now active.
+ Kate::View* v = activeViewSpace()->currentView();
+ if ( v )
+ activateView( v );
+
+ if (this == m_viewManager->activeContainer())
+ m_viewManager->updateViewSpaceActions ();
+
+ emit viewChanged();
+}
+
+void KateViewSpaceContainer::slotCloseCurrentViewSpace()
+{
+ removeViewSpace(activeViewSpace());
+}
+
+void KateViewSpaceContainer::setShowFullPath( bool enable )
+{
+ showFullPath = enable;
+ statusMsg ();
+ //m_mainWindow->slotWindowActivated ();
+}
+
+/**
+ * session config functions
+ */
+
+void KateViewSpaceContainer::saveViewConfiguration(KConfig *config,const QString& group)
+{
+ bool weHaveSplittersAlive (viewSpaceCount() > 1);
+
+ config->setGroup (group); //"View Configuration");
+ config->writeEntry ("Splitters", weHaveSplittersAlive);
+
+ // no splitters around
+ if (!weHaveSplittersAlive)
+ {
+ config->writeEntry("Active Viewspace", 0);
+ m_viewSpaceList.first()->saveConfig ( config, 0,group );
+
+ return;
+ }
+
+ // I need the first splitter, the one which has this as parent.
+ KateMDI::Splitter* s;
+ QObjectList *l = queryList("KateMDI::Splitter", 0, false, false);
+ QObjectListIt it( *l );
+
+ if ( (s = (KateMDI::Splitter*)it.current()) != 0 )
+ saveSplitterConfig( s, 0, config , group);
+
+ delete l;
+}
+
+void KateViewSpaceContainer::restoreViewConfiguration (KConfig *config, const QString& group)
+{
+ config->setGroup(group);
+ //config->setGroup ("View Configuration");
+
+ // no splitters around, ohhh :()
+ if (!config->readBoolEntry ("Splitters"))
+ {
+ // only add the new views needed, let the old stay, won't hurt if one around
+ m_viewSpaceList.first ()->restoreConfig (this, config, QString(group+"-ViewSpace 0"));
+ }
+ else
+ {
+ // send all views + their gui to **** ;)
+ for (uint i=0; i < m_viewList.count(); i++)
+ mainWindow()->guiFactory ()->removeClient (m_viewList.at(i));
+
+ m_viewList.clear ();
+
+ // cu viewspaces
+ m_viewSpaceList.clear();
+
+ // call restoreSplitter for Splitter 0
+ restoreSplitter( config, QString(group+"-Splitter 0"), this,group );
+ }
+
+ // finally, make the correct view active.
+ config->setGroup (group);
+/*
+ KateViewSpace *vs = m_viewSpaceList.at( config->readNumEntry("Active ViewSpace") );
+ if ( vs )
+ activateSpace( vs->currentView() );
+ */
+}
+
+
+void KateViewSpaceContainer::saveSplitterConfig( KateMDI::Splitter* s, int idx, KConfig* config, const QString& viewConfGrp )
+{
+ QString grp = QString(viewConfGrp+"-Splitter %1").arg(idx);
+ config->setGroup(grp);
+
+ // Save sizes, orient, children for this splitter
+ config->writeEntry( "Sizes", s->sizes() );
+ config->writeEntry( "Orientation", s->orientation() );
+
+ QStringList childList;
+ // a katesplitter has two children, of which one may be a KateSplitter.
+ const QObjectList* l = s->children();
+ QObjectListIt it( *l );
+ QObject* obj;
+ for (; it.current(); ++it) {
+ obj = it.current();
+ QString n; // name for child list, see below
+ // For KateViewSpaces, ask them to save the file list.
+ if ( obj->isA("KateViewSpace") ) {
+ n = QString(viewConfGrp+"-ViewSpace %1").arg( m_viewSpaceList.find((KateViewSpace*)obj) );
+ ((KateViewSpace*)obj)->saveConfig ( config, m_viewSpaceList.find((KateViewSpace*)obj), viewConfGrp);
+ // save active viewspace
+ if ( ((KateViewSpace*)obj)->isActiveSpace() ) {
+ config->setGroup(viewConfGrp);
+ config->writeEntry("Active Viewspace", m_viewSpaceList.find((KateViewSpace*)obj) );
+ }
+ }
+ // For KateSplitters, recurse
+ else if ( obj->isA("KateMDI::Splitter") ) {
+ idx++;
+ saveSplitterConfig( (KateMDI::Splitter*)obj, idx, config,viewConfGrp);
+ n = QString(viewConfGrp+"-Splitter %1").arg( idx );
+ }
+ // make sure list goes in right place!
+ if (!n.isEmpty()) {
+ if ( childList.count() > 0 && ! s->isLastChild( (QWidget*)obj ) )
+ childList.prepend( n );
+ else
+ childList.append( n );
+ }
+ }
+
+ // reset config group.
+ config->setGroup(grp);
+ config->writeEntry("Children", childList);
+}
+
+void KateViewSpaceContainer::restoreSplitter( KConfig* config, const QString &group, QWidget* parent, const QString& viewConfGrp)
+{
+ config->setGroup( group );
+
+ KateMDI::Splitter* s = new KateMDI::Splitter((Qt::Orientation)config->readNumEntry("Orientation"), parent);
+
+ QStringList children = config->readListEntry( "Children" );
+ for (QStringList::Iterator it=children.begin(); it!=children.end(); ++it)
+ {
+ // for a viewspace, create it and open all documents therein.
+ if ( (*it).startsWith(viewConfGrp+"-ViewSpace") )
+ {
+ KateViewSpace* vs = new KateViewSpace( this, s );
+
+ connect(this, SIGNAL(statusChanged(Kate::View *, int, int, int, bool, int, const QString &)), vs, SLOT(slotStatusChanged(Kate::View *, int, int, int, bool, int, const QString &)));
+
+ if (m_viewSpaceList.isEmpty())
+ vs->setActive (true);
+
+ m_viewSpaceList.append( vs );
+
+ vs->show();
+ setActiveSpace( vs );
+
+ vs->restoreConfig (this, config, *it);
+ }
+ else
+ {
+ // for a splitter, recurse.
+ restoreSplitter( config, QString(*it), s, viewConfGrp );
+ }
+ }
+
+ // set sizes
+ config->setGroup( group );
+ s->setSizes( config->readIntListEntry("Sizes") );
+ s->show();
+}
+
+KateMainWindow *KateViewSpaceContainer::mainWindow() {
+ return m_viewManager->mainWindow();
+}
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kate/app/kateviewspacecontainer.h b/kate/app/kateviewspacecontainer.h
new file mode 100644
index 000000000..e8c64bd4e
--- /dev/null
+++ b/kate/app/kateviewspacecontainer.h
@@ -0,0 +1,161 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KATE_VIEWSPACE_CONTAINER_H__
+#define __KATE_VIEWSPACE_CONTAINER_H__
+
+#include "katemain.h"
+#include "../interfaces/viewmanager.h"
+
+#include <kate/view.h>
+#include <kate/document.h>
+
+#include "katemdi.h"
+
+class KConfig;
+class KateMainWindow;
+
+class KateViewSpaceContainer: public QVBox
+{
+ Q_OBJECT
+
+ friend class KateViewSpace;
+ friend class KateVSStatusBar;
+
+ public:
+ KateViewSpaceContainer (QWidget *parent, KateViewManager *viewManager);
+
+ ~KateViewSpaceContainer ();
+
+ inline QPtrList<Kate::View> &viewList () { return m_viewList; };
+
+ public:
+ /* This will save the splitter configuration */
+ void saveViewConfiguration(KConfig *config,const QString& group);
+
+ /* restore it */
+ void restoreViewConfiguration (KConfig *config,const QString& group);
+
+ private:
+ /**
+ * create and activate a new view for doc, if doc == 0, then
+ * create a new document
+ */
+ bool createView ( Kate::Document *doc =0L );
+
+ bool deleteView ( Kate::View *view, bool delViewSpace = true);
+
+ void moveViewtoSplit (Kate::View *view);
+ void moveViewtoStack (Kate::View *view);
+
+ /* Save the configuration of a single splitter.
+ * If child splitters are found, it calls it self with those as the argument.
+ * If a viewspace child is found, it is asked to save its filelist.
+ */
+ void saveSplitterConfig(KateMDI::Splitter* s, int idx=0, KConfig* config=0L, const QString& viewConfGrp="");
+
+ /** Restore a single splitter.
+ * This is all the work is done for @see saveSplitterConfig()
+ */
+ void restoreSplitter ( KConfig* config, const QString &group, QWidget* parent , const QString& viewConfGrp);
+
+ void removeViewSpace (KateViewSpace *viewspace);
+
+ bool showFullPath;
+
+ public:
+ Kate::View* activeView ();
+ KateViewSpace* activeViewSpace ();
+
+ uint viewCount ();
+ uint viewSpaceCount ();
+
+ bool isViewActivationBlocked(){return m_blockViewCreationAndActivation;};
+
+ public:
+ void closeViews(uint documentNumber);
+ KateMainWindow *mainWindow();
+ friend class KateViewManager;
+
+ private slots:
+ void activateView ( Kate::View *view );
+ void activateSpace ( Kate::View* v );
+ void slotViewChanged();
+ void reactivateActiveView();
+ void slotPendingDocumentNameChanged();
+
+ void documentCreated (Kate::Document *doc);
+ void documentDeleted (uint docNumber);
+
+ public slots:
+ /* Splits a KateViewSpace into two.
+ * The operation is performed by creating a KateMDI::Splitter in the parent of the KateViewSpace to be split,
+ * which is then moved to that splitter. Then a new KateViewSpace is created and added to the splitter,
+ * and a KateView is created to populate the new viewspace. The new KateView is made the active one,
+ * because createView() does that.
+ * If no viewspace is provided, the result of activeViewSpace() is used.
+ * The isHoriz, true pr default, decides the orientation of the splitting action.
+ * If atTop is true, the new viewspace will be moved to the first position in the new splitter.
+ * If a newViewUrl is provided, the new view will show the document in that URL if any, otherwise
+ * the document of the current view in the viewspace to be split is used.
+ */
+ void splitViewSpace( KateViewSpace* vs=0L, bool isHoriz=true, bool atTop=false );
+
+ bool getShowFullPath() const { return showFullPath; }
+
+ void activateView ( uint documentNumber );
+ void activateView ( int documentNumber ) { activateView((uint) documentNumber); };
+
+ /** Splits the active viewspace horizontally */
+ void slotSplitViewSpaceHoriz () { splitViewSpace(); }
+ /** Splits the active viewspace vertically */
+ void slotSplitViewSpaceVert () { splitViewSpace( 0L, false ); }
+
+ void slotCloseCurrentViewSpace();
+
+ void statusMsg ();
+
+ void setActiveSpace ( KateViewSpace* vs );
+ void setActiveView ( Kate::View* view );
+
+ void setShowFullPath(bool enable);
+
+ void activateNextView();
+ void activatePrevView();
+
+ signals:
+ void statusChanged (Kate::View *, int, int, int, bool, int, const QString &);
+ void statChanged ();
+ void viewChanged ();
+
+ private:
+ KateViewManager *m_viewManager;
+ QPtrList<KateViewSpace> m_viewSpaceList;
+ QPtrList<Kate::View> m_viewList;
+
+ bool m_blockViewCreationAndActivation;
+
+ bool m_activeViewRunning;
+
+ bool m_pendingViewCreation;
+ QGuardedPtr<Kate::Document> m_pendingDocument;
+};
+
+#endif
diff --git a/kate/app/kbookmarkhandler.cpp b/kate/app/kbookmarkhandler.cpp
new file mode 100644
index 000000000..ada4d7a21
--- /dev/null
+++ b/kate/app/kbookmarkhandler.cpp
@@ -0,0 +1,98 @@
+/* This file is part of the KDE project
+ Copyright (C) xxxx KFile Authors
+ Copyright (C) 2002 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ 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 "katefileselector.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <qtextstream.h>
+
+#include <kbookmarkimporter.h>
+#include <kpopupmenu.h>
+#include <ksavefile.h>
+#include <kstandarddirs.h>
+#include <kdiroperator.h>
+#include <kaction.h>
+
+#include "kbookmarkhandler.h"
+#include "kbookmarkhandler.moc"
+
+
+KBookmarkHandler::KBookmarkHandler( KateFileSelector *parent, KPopupMenu* kpopupmenu )
+ : QObject( parent, "KBookmarkHandler" ),
+ KBookmarkOwner(),
+ mParent( parent ),
+ m_menu( kpopupmenu ),
+ m_importStream( 0L )
+{
+ if (!m_menu)
+ m_menu = new KPopupMenu( parent, "bookmark menu" );
+
+ QString file = locate( "data", "kate/fsbookmarks.xml" );
+ if ( file.isEmpty() )
+ file = locateLocal( "data", "kate/fsbookmarks.xml" );
+
+ KBookmarkManager *manager = KBookmarkManager::managerForFile( file, false);
+ manager->setUpdate( true );
+ manager->setShowNSBookmarks( false );
+
+ m_bookmarkMenu = new KBookmarkMenu( manager, this, m_menu, 0, true );
+}
+
+KBookmarkHandler::~KBookmarkHandler()
+{
+ // delete m_bookmarkMenu; ###
+}
+
+QString KBookmarkHandler::currentURL() const
+{
+ return mParent->dirOperator()->url().url();
+}
+
+
+void KBookmarkHandler::slotNewBookmark( const QString& /*text*/,
+ const QCString& url,
+ const QString& additionalInfo )
+{
+ *m_importStream << "<bookmark icon=\"" << KMimeType::iconForURL( KURL( url ) );
+ *m_importStream << "\" href=\"" << QString::fromUtf8(url) << "\">\n";
+ *m_importStream << "<title>" << (additionalInfo.isEmpty() ? QString::fromUtf8(url) : additionalInfo) << "</title>\n</bookmark>\n";
+}
+
+void KBookmarkHandler::slotNewFolder( const QString& text, bool /*open*/,
+ const QString& /*additionalInfo*/ )
+{
+ *m_importStream << "<folder icon=\"bookmark_folder\">\n<title=\"";
+ *m_importStream << text << "\">\n";
+}
+
+void KBookmarkHandler::newSeparator()
+{
+ *m_importStream << "<separator/>\n";
+}
+
+void KBookmarkHandler::endFolder()
+{
+ *m_importStream << "</folder>\n";
+}
+
+void KBookmarkHandler::virtual_hook( int id, void* data )
+{ KBookmarkOwner::virtual_hook( id, data ); }
+
diff --git a/kate/app/kbookmarkhandler.h b/kate/app/kbookmarkhandler.h
new file mode 100644
index 000000000..15697e283
--- /dev/null
+++ b/kate/app/kbookmarkhandler.h
@@ -0,0 +1,72 @@
+/* This file is part of the KDE project
+ Copyright (C) xxxx KFile Authors
+ Copyright (C) 2002 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _KBOOKMARKHANDLER_H_
+#define _KBOOKMARKHANDLER_H_
+
+#include <kbookmarkmanager.h>
+#include <kbookmarkmenu.h>
+
+class KateFileSelector;
+
+class KActionMenu;
+
+class QTextStream;
+class KPopupMenu;
+
+class KBookmarkHandler : public QObject, public KBookmarkOwner
+{
+ Q_OBJECT
+
+public:
+ KBookmarkHandler( KateFileSelector *parent, KPopupMenu *kpopupmenu=0 );
+ ~KBookmarkHandler();
+
+ // KBookmarkOwner interface:
+ virtual void openBookmarkURL( const QString& url ) { emit openURL( url ); }
+ virtual QString currentURL() const;
+
+ KPopupMenu *menu() const { return m_menu; }
+
+signals:
+ void openURL( const QString& url );
+
+private slots:
+ void slotNewBookmark( const QString& text, const QCString& url,
+ const QString& additionalInfo );
+ void slotNewFolder( const QString& text, bool open,
+ const QString& additionalInfo );
+ void newSeparator();
+ void endFolder();
+
+protected:
+ virtual void virtual_hook( int id, void* data );
+
+private:
+ KateFileSelector *mParent;
+ KPopupMenu *m_menu;
+ KBookmarkMenu *m_bookmarkMenu;
+
+ QTextStream *m_importStream;
+
+ //class KBookmarkHandlerPrivate *d;
+};
+
+
+#endif // _KBOOKMARKHANDLER_H_
diff --git a/kate/app/kwritemain.cpp b/kate/app/kwritemain.cpp
new file mode 100644
index 000000000..5dab9340d
--- /dev/null
+++ b/kate/app/kwritemain.cpp
@@ -0,0 +1,712 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ 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 "kwritemain.h"
+#include "kwritemain.moc"
+
+#include <kate/document.h>
+#include <kate/view.h>
+
+#include <ktexteditor/configinterface.h>
+#include <ktexteditor/sessionconfiginterface.h>
+#include <ktexteditor/viewcursorinterface.h>
+#include <ktexteditor/printinterface.h>
+#include <ktexteditor/encodinginterface.h>
+#include <ktexteditor/editorchooser.h>
+#include <ktexteditor/popupmenuinterface.h>
+
+#include <kio/netaccess.h>
+
+#include <kdeversion.h>
+#include <dcopclient.h>
+#include <kurldrag.h>
+#include <kencodingfiledialog.h>
+#include <kdiroperator.h>
+#include <kiconloader.h>
+#include <kaboutdata.h>
+#include <kstatusbar.h>
+#include <kstdaction.h>
+#include <kaction.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <kapplication.h>
+#include <klocale.h>
+#include <kurl.h>
+#include <kconfig.h>
+#include <kcmdlineargs.h>
+#include <kmessagebox.h>
+#include <kkeydialog.h>
+#include <kedittoolbar.h>
+#include <kparts/event.h>
+#include <kmenubar.h>
+
+#include <qdropsite.h>
+#include <qdragobject.h>
+#include <qvbox.h>
+#include <qtextcodec.h>
+#include <qlayout.h>
+
+// StatusBar field IDs
+#define KWRITE_ID_GEN 1
+
+QPtrList<KTextEditor::Document> KWrite::docList;
+QPtrList<KWrite> KWrite::winList;
+
+KWrite::KWrite (KTextEditor::Document *doc)
+ : m_view(0),
+ m_recentFiles(0),
+ m_paShowPath(0),
+ m_paShowStatusBar(0)
+{
+ if ( !doc )
+ {
+ if ( !(doc = KTextEditor::EditorChooser::createDocument(0,"KTextEditor::Document")) )
+ {
+ KMessageBox::error(this, i18n("A KDE text-editor component could not be found;\n"
+ "please check your KDE installation."));
+ kapp->exit(1);
+ }
+
+ docList.append(doc);
+ }
+
+ m_view = doc->createView (this, 0L);
+
+ setCentralWidget(m_view);
+
+ setupActions();
+ setupStatusBar();
+
+ setAcceptDrops(true);
+
+ connect(m_view,SIGNAL(newStatus()),this,SLOT(newCaption()));
+ connect(m_view,SIGNAL(viewStatusMsg(const QString &)),this,SLOT(newStatus(const QString &)));
+ connect(m_view->document(),SIGNAL(fileNameChanged()),this,SLOT(newCaption()));
+ connect(m_view->document(),SIGNAL(fileNameChanged()),this,SLOT(slotFileNameChanged()));
+ connect(m_view,SIGNAL(dropEventPass(QDropEvent *)),this,SLOT(slotDropEvent(QDropEvent *)));
+
+ setXMLFile( "kwriteui.rc" );
+ createShellGUI( true );
+ guiFactory()->addClient( m_view );
+
+ // install a working kate part popup dialog thingy
+ if (static_cast<Kate::View*>(m_view->qt_cast("Kate::View")))
+ static_cast<Kate::View*>(m_view->qt_cast("Kate::View"))->installPopup ((QPopupMenu*)(factory()->container("ktexteditor_popup", this)) );
+
+ // init with more usefull size, stolen from konq :)
+ if (!initialGeometrySet())
+ resize( QSize(700, 480).expandedTo(minimumSizeHint()));
+
+ // call it as last thing, must be sure everything is already set up ;)
+ setAutoSaveSettings ();
+
+ readConfig ();
+
+ winList.append (this);
+
+ show ();
+}
+
+KWrite::~KWrite()
+{
+ winList.remove (this);
+
+ if (m_view->document()->views().count() == 1)
+ {
+ docList.remove(m_view->document());
+ delete m_view->document();
+ }
+
+ kapp->config()->sync ();
+}
+
+void KWrite::setupActions()
+{
+ KStdAction::close( this, SLOT(slotFlush()), actionCollection(), "file_close" )->setWhatsThis(i18n("Use this to close the current document"));
+
+ // setup File menu
+ KStdAction::print(this, SLOT(printDlg()), actionCollection())->setWhatsThis(i18n("Use this command to print the current document"));
+ KStdAction::openNew( this, SLOT(slotNew()), actionCollection(), "file_new" )->setWhatsThis(i18n("Use this command to create a new document"));
+ KStdAction::open( this, SLOT( slotOpen() ), actionCollection(), "file_open" )->setWhatsThis(i18n("Use this command to open an existing document for editing"));
+
+ m_recentFiles = KStdAction::openRecent(this, SLOT(slotOpen(const KURL&)),
+ actionCollection());
+ m_recentFiles->setWhatsThis(i18n("This lists files which you have opened recently, and allows you to easily open them again."));
+
+ KAction *a=new KAction(i18n("&New Window"), "window_new", 0, this, SLOT(newView()),
+ actionCollection(), "view_new_view");
+ a->setWhatsThis(i18n("Create another view containing the current document"));
+
+ a=new KAction(i18n("Choose Editor..."),0,this,SLOT(changeEditor()),
+ actionCollection(),"settings_choose_editor");
+ a->setWhatsThis(i18n("Override the system wide setting for the default editing component"));
+
+ KStdAction::quit(this, SLOT(close()), actionCollection())->setWhatsThis(i18n("Close the current document view"));
+
+ // setup Settings menu
+ setStandardToolBarMenuEnabled(true);
+
+ m_paShowStatusBar = KStdAction::showStatusbar(this, SLOT(toggleStatusBar()), actionCollection(), "settings_show_statusbar");
+ m_paShowStatusBar->setWhatsThis(i18n("Use this command to show or hide the view's statusbar"));
+
+ m_paShowPath = new KToggleAction(i18n("Sho&w Path"), 0, this, SLOT(newCaption()),
+ actionCollection(), "set_showPath");
+ m_paShowPath->setCheckedState(i18n("Hide Path"));
+ m_paShowPath->setWhatsThis(i18n("Show the complete document path in the window caption"));
+ a=KStdAction::keyBindings(this, SLOT(editKeys()), actionCollection());
+ a->setWhatsThis(i18n("Configure the application's keyboard shortcut assignments."));
+
+ a=KStdAction::configureToolbars(this, SLOT(editToolbars()), actionCollection());
+ a->setWhatsThis(i18n("Configure which items should appear in the toolbar(s)."));
+}
+
+void KWrite::setupStatusBar()
+{
+ statusBar()->insertItem("", KWRITE_ID_GEN);
+}
+
+// load on url
+void KWrite::loadURL(const KURL &url)
+{
+ m_view->document()->openURL(url);
+}
+
+// is closing the window wanted by user ?
+bool KWrite::queryClose()
+{
+ if (m_view->document()->views().count() > 1)
+ return true;
+
+ if (m_view->document()->queryClose())
+ {
+ writeConfig();
+
+ return true;
+ }
+
+ return false;
+}
+
+void KWrite::changeEditor()
+{
+ KWriteEditorChooser choose(this);
+ choose.exec();
+}
+
+void KWrite::slotFlush ()
+{
+ m_view->document()->closeURL();
+}
+
+void KWrite::slotNew()
+{
+ new KWrite();
+}
+
+void KWrite::slotOpen()
+{
+ if (KTextEditor::encodingInterface(m_view->document()))
+ {
+ KEncodingFileDialog::Result r=KEncodingFileDialog::getOpenURLsAndEncoding(
+ KTextEditor::encodingInterface(m_view->document())->encoding(),
+ m_view->document()->url().url(),QString::null,this,i18n("Open File"));
+
+ for (KURL::List::Iterator i=r.URLs.begin(); i != r.URLs.end(); ++i)
+ {
+ encoding = r.encoding;
+ slotOpen ( *i );
+ }
+ }
+ else
+ {
+ KURL::List l=KFileDialog::getOpenURLs(m_view->document()->url().url(),QString::null,this,QString::null);
+ for (KURL::List::Iterator i=l.begin(); i != l.end(); ++i)
+ {
+ slotOpen ( *i );
+ }
+ }
+}
+
+void KWrite::slotOpen( const KURL& url )
+{
+ if (url.isEmpty()) return;
+
+ if (!KIO::NetAccess::exists(url, true, this))
+ {
+ KMessageBox::error (this, i18n("The given file could not be read, check if it exists or if it is readable for the current user."));
+ return;
+ }
+
+ if (m_view->document()->isModified() || !m_view->document()->url().isEmpty())
+ {
+ KWrite *t = new KWrite();
+ if (KTextEditor::encodingInterface(t->m_view->document())) KTextEditor::encodingInterface(t->m_view->document())->setEncoding(encoding);
+ t->loadURL(url);
+ }
+ else
+ {
+ if (KTextEditor::encodingInterface(m_view->document())) KTextEditor::encodingInterface(m_view->document())->setEncoding(encoding);
+ loadURL(url);
+ }
+}
+
+void KWrite::slotFileNameChanged()
+{
+ if ( ! m_view->document()->url().isEmpty() )
+ m_recentFiles->addURL( m_view->document()->url() );
+}
+
+void KWrite::newView()
+{
+ new KWrite(m_view->document());
+}
+
+void KWrite::toggleStatusBar()
+{
+ if( m_paShowStatusBar->isChecked() )
+ statusBar()->show();
+ else
+ statusBar()->hide();
+}
+
+void KWrite::editKeys()
+{
+ KKeyDialog dlg;
+ dlg.insert(actionCollection());
+ if( m_view )
+ dlg.insert(m_view->actionCollection());
+ dlg.configure();
+}
+
+void KWrite::editToolbars()
+{
+ saveMainWindowSettings( kapp->config(), "MainWindow" );
+ KEditToolbar *dlg = new KEditToolbar(guiFactory());
+ connect( dlg, SIGNAL(newToolbarConfig()), this, SLOT(slotNewToolbarConfig()) );
+ dlg->exec();
+ delete dlg;
+}
+
+void KWrite::slotNewToolbarConfig()
+{
+ applyMainWindowSettings( kapp->config(), "MainWindow" );
+}
+
+
+void KWrite::printNow()
+{
+ KTextEditor::printInterface(m_view->document())->print ();
+}
+
+void KWrite::printDlg()
+{
+ KTextEditor::printInterface(m_view->document())->printDialog ();
+}
+
+void KWrite::newStatus(const QString &msg)
+{
+ newCaption();
+
+ statusBar()->changeItem(msg,KWRITE_ID_GEN);
+}
+
+void KWrite::newCaption()
+{
+ if (m_view->document()->url().isEmpty()) {
+ setCaption(i18n("Untitled"),m_view->document()->isModified());
+ }
+ else
+ {
+ QString c;
+ if (!m_paShowPath->isChecked())
+ {
+ c = m_view->document()->url().fileName();
+
+ //File name shouldn't be too long - Maciek
+ if (c.length() > 64)
+ c = c.left(64) + "...";
+ }
+ else
+ {
+ c = m_view->document()->url().prettyURL();
+
+ //File name shouldn't be too long - Maciek
+ if (c.length() > 64)
+ c = "..." + c.right(64);
+ }
+
+ setCaption (c, m_view->document()->isModified());
+ }
+}
+
+void KWrite::dragEnterEvent( QDragEnterEvent *event )
+{
+ event->accept(KURLDrag::canDecode(event));
+}
+
+void KWrite::dropEvent( QDropEvent *event )
+{
+ slotDropEvent(event);
+}
+
+void KWrite::slotDropEvent( QDropEvent *event )
+{
+ KURL::List textlist;
+
+ if (!KURLDrag::decode(event, textlist))
+ return;
+
+ for (KURL::List::Iterator i=textlist.begin(); i != textlist.end(); ++i)
+ slotOpen (*i);
+}
+
+void KWrite::slotEnableActions( bool enable )
+{
+ QValueList<KAction *> actions = actionCollection()->actions();
+ QValueList<KAction *>::ConstIterator it = actions.begin();
+ QValueList<KAction *>::ConstIterator end = actions.end();
+
+ for (; it != end; ++it )
+ (*it)->setEnabled( enable );
+
+ actions = m_view->actionCollection()->actions();
+ it = actions.begin();
+ end = actions.end();
+
+ for (; it != end; ++it )
+ (*it)->setEnabled( enable );
+}
+
+//common config
+void KWrite::readConfig(KConfig *config)
+{
+ config->setGroup("General Options");
+
+ m_paShowStatusBar->setChecked( config->readBoolEntry("ShowStatusBar") );
+ m_paShowPath->setChecked( config->readBoolEntry("ShowPath") );
+
+ m_recentFiles->loadEntries(config, "Recent Files");
+
+ if (m_view && KTextEditor::configInterface(m_view->document()))
+ KTextEditor::configInterface(m_view->document())->readConfig(config);
+
+ if( m_paShowStatusBar->isChecked() )
+ statusBar()->show();
+ else
+ statusBar()->hide();
+}
+
+void KWrite::writeConfig(KConfig *config)
+{
+ config->setGroup("General Options");
+
+ config->writeEntry("ShowStatusBar",m_paShowStatusBar->isChecked());
+ config->writeEntry("ShowPath",m_paShowPath->isChecked());
+
+ m_recentFiles->saveEntries(config, "Recent Files");
+
+ if (m_view && KTextEditor::configInterface(m_view->document()))
+ KTextEditor::configInterface(m_view->document())->writeConfig(config);
+
+ config->sync ();
+}
+
+//config file
+void KWrite::readConfig()
+{
+ KConfig *config = kapp->config();
+ readConfig(config);
+}
+
+void KWrite::writeConfig()
+{
+ KConfig *config = kapp->config();
+ writeConfig(config);
+}
+
+// session management
+void KWrite::restore(KConfig *config, int n)
+{
+ readPropertiesInternal(config, n);
+}
+
+void KWrite::readProperties(KConfig *config)
+{
+ readConfig(config);
+
+ if (KTextEditor::sessionConfigInterface(m_view))
+ KTextEditor::sessionConfigInterface(m_view)->readSessionConfig(config);
+}
+
+void KWrite::saveProperties(KConfig *config)
+{
+ writeConfig(config);
+ config->writeEntry("DocumentNumber",docList.find(m_view->document()) + 1);
+
+ if (KTextEditor::sessionConfigInterface(m_view))
+ KTextEditor::sessionConfigInterface(m_view)->writeSessionConfig(config);
+}
+
+void KWrite::saveGlobalProperties(KConfig *config) //save documents
+{
+ config->setGroup("Number");
+ config->writeEntry("NumberOfDocuments",docList.count());
+
+ for (uint z = 1; z <= docList.count(); z++)
+ {
+ QString buf = QString("Document %1").arg(z);
+ config->setGroup(buf);
+
+ KTextEditor::Document *doc = docList.at(z - 1);
+
+ if (KTextEditor::configInterface(doc))
+ KTextEditor::configInterface(doc)->writeSessionConfig(config);
+ }
+
+ for (uint z = 1; z <= winList.count(); z++)
+ {
+ QString buf = QString("Window %1").arg(z);
+ config->setGroup(buf);
+
+ config->writeEntry("DocumentNumber",docList.find(winList.at(z-1)->view()->document()) + 1);
+ }
+}
+
+//restore session
+void KWrite::restore()
+{
+ KConfig *config = kapp->sessionConfig();
+
+ if (!config)
+ return;
+
+ int docs, windows;
+ QString buf;
+ KTextEditor::Document *doc;
+ KWrite *t;
+
+ config->setGroup("Number");
+ docs = config->readNumEntry("NumberOfDocuments");
+ windows = config->readNumEntry("NumberOfWindows");
+
+ for (int z = 1; z <= docs; z++)
+ {
+ buf = QString("Document %1").arg(z);
+ config->setGroup(buf);
+ doc=KTextEditor::EditorChooser::createDocument(0,"KTextEditor::Document");
+
+ if (KTextEditor::configInterface(doc))
+ KTextEditor::configInterface(doc)->readSessionConfig(config);
+ docList.append(doc);
+ }
+
+ for (int z = 1; z <= windows; z++)
+ {
+ buf = QString("Window %1").arg(z);
+ config->setGroup(buf);
+ t = new KWrite(docList.at(config->readNumEntry("DocumentNumber") - 1));
+ t->restore(config,z);
+ }
+}
+
+static KCmdLineOptions options[] =
+{
+ { "stdin", I18N_NOOP("Read the contents of stdin"), 0},
+ { "encoding <argument>", I18N_NOOP("Set encoding for the file to open"), 0 },
+ { "line <argument>", I18N_NOOP("Navigate to this line"), 0 },
+ { "column <argument>", I18N_NOOP("Navigate to this column"), 0 },
+ { "+[URL]", I18N_NOOP("Document to open"), 0 },
+ KCmdLineLastOption
+};
+
+extern "C" KDE_EXPORT int kdemain(int argc, char **argv)
+{
+ Kate::Document::setFileChangedDialogsActivated (true);
+
+ KLocale::setMainCatalogue("kate"); //lukas: set this to have the kwritepart translated using kate message catalog
+
+ // here we go, construct the KWrite version
+ QString kWriteVersion = QString ("%1.%2.%3").arg(KDE::versionMajor() + 1).arg(KDE::versionMinor()).arg(KDE::versionRelease());
+
+ KAboutData aboutData ( "kwrite",
+ I18N_NOOP("KWrite"),
+ kWriteVersion.latin1(),
+ I18N_NOOP( "KWrite - Text Editor" ), KAboutData::License_LGPL_V2,
+ I18N_NOOP( "(c) 2000-2005 The Kate Authors" ), 0, "http://kate.kde.org" );
+
+ aboutData.addAuthor ("Christoph Cullmann", I18N_NOOP("Maintainer"), "cullmann@kde.org", "http://www.babylon2k.de");
+ aboutData.addAuthor ("Anders Lund", I18N_NOOP("Core Developer"), "anders@alweb.dk", "http://www.alweb.dk");
+ aboutData.addAuthor ("Joseph Wenninger", I18N_NOOP("Core Developer"), "jowenn@kde.org","http://stud3.tuwien.ac.at/~e9925371");
+ aboutData.addAuthor ("Hamish Rodda",I18N_NOOP("Core Developer"), "rodda@kde.org");
+ aboutData.addAuthor ("Waldo Bastian", I18N_NOOP( "The cool buffersystem" ), "bastian@kde.org" );
+ aboutData.addAuthor ("Charles Samuels", I18N_NOOP("The Editing Commands"), "charles@kde.org");
+ aboutData.addAuthor ("Matt Newell", I18N_NOOP("Testing, ..."), "newellm@proaxis.com");
+ aboutData.addAuthor ("Michael Bartl", I18N_NOOP("Former Core Developer"), "michael.bartl1@chello.at");
+ aboutData.addAuthor ("Michael McCallum", I18N_NOOP("Core Developer"), "gholam@xtra.co.nz");
+ aboutData.addAuthor ("Jochen Wilhemly", I18N_NOOP( "KWrite Author" ), "digisnap@cs.tu-berlin.de" );
+ aboutData.addAuthor ("Michael Koch",I18N_NOOP("KWrite port to KParts"), "koch@kde.org");
+ aboutData.addAuthor ("Christian Gebauer", 0, "gebauer@kde.org" );
+ aboutData.addAuthor ("Simon Hausmann", 0, "hausmann@kde.org" );
+ aboutData.addAuthor ("Glen Parker",I18N_NOOP("KWrite Undo History, Kspell integration"), "glenebob@nwlink.com");
+ aboutData.addAuthor ("Scott Manson",I18N_NOOP("KWrite XML Syntax highlighting support"), "sdmanson@alltel.net");
+ aboutData.addAuthor ("John Firebaugh",I18N_NOOP("Patches and more"), "jfirebaugh@kde.org");
+
+ aboutData.addCredit ("Matteo Merli",I18N_NOOP("Highlighting for RPM Spec-Files, Perl, Diff and more"), "merlim@libero.it");
+ aboutData.addCredit ("Rocky Scaletta",I18N_NOOP("Highlighting for VHDL"), "rocky@purdue.edu");
+ aboutData.addCredit ("Yury Lebedev",I18N_NOOP("Highlighting for SQL"),"");
+ aboutData.addCredit ("Chris Ross",I18N_NOOP("Highlighting for Ferite"),"");
+ aboutData.addCredit ("Nick Roux",I18N_NOOP("Highlighting for ILERPG"),"");
+ aboutData.addCredit ("Carsten Niehaus", I18N_NOOP("Highlighting for LaTeX"),"");
+ aboutData.addCredit ("Per Wigren", I18N_NOOP("Highlighting for Makefiles, Python"),"");
+ aboutData.addCredit ("Jan Fritz", I18N_NOOP("Highlighting for Python"),"");
+ aboutData.addCredit ("Daniel Naber","","");
+ aboutData.addCredit ("Roland Pabel",I18N_NOOP("Highlighting for Scheme"),"");
+ aboutData.addCredit ("Cristi Dumitrescu",I18N_NOOP("PHP Keyword/Datatype list"),"");
+ aboutData.addCredit ("Carsten Pfeiffer", I18N_NOOP("Very nice help"), "");
+ aboutData.addCredit (I18N_NOOP("All people who have contributed and I have forgotten to mention"),"","");
+
+ aboutData.setTranslator(I18N_NOOP("_: NAME OF TRANSLATORS\nYour names"), I18N_NOOP("_: EMAIL OF TRANSLATORS\nYour emails"));
+
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineArgs::addCmdLineOptions( options );
+
+ KApplication a;
+
+ KGlobal::locale()->insertCatalogue("katepart");
+
+ DCOPClient *client = kapp->dcopClient();
+ if (!client->isRegistered())
+ {
+ client->attach();
+ client->registerAs("kwrite");
+ }
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ if (kapp->isRestored())
+ {
+ KWrite::restore();
+ }
+ else
+ {
+ bool nav = false;
+ int line = 0, column = 0;
+
+ QTextCodec *codec = args->isSet("encoding") ? QTextCodec::codecForName(args->getOption("encoding")) : 0;
+
+ if (args->isSet ("line"))
+ {
+ line = args->getOption ("line").toInt();
+ nav = true;
+ }
+
+ if (args->isSet ("column"))
+ {
+ column = args->getOption ("column").toInt();
+ nav = true;
+ }
+
+ if ( args->count() == 0 )
+ {
+ KWrite *t = new KWrite;
+
+ if( args->isSet( "stdin" ) )
+ {
+ QTextIStream input(stdin);
+
+ // set chosen codec
+ if (codec)
+ input.setCodec (codec);
+
+ QString line;
+ QString text;
+
+ do
+ {
+ line = input.readLine();
+ text.append( line + "\n" );
+ } while( !line.isNull() );
+
+
+ KTextEditor::EditInterface *doc = KTextEditor::editInterface (t->view()->document());
+ if( doc )
+ doc->setText( text );
+ }
+
+ if (nav && KTextEditor::viewCursorInterface(t->view()))
+ KTextEditor::viewCursorInterface(t->view())->setCursorPosition (line, column);
+ }
+ else
+ {
+ for ( int z = 0; z < args->count(); z++ )
+ {
+ KWrite *t = new KWrite();
+
+ // this file is no local dir, open it, else warn
+ bool noDir = !args->url(z).isLocalFile() || !QDir (args->url(z).path()).exists();
+
+ if (noDir)
+ {
+ if (Kate::document (t->view()->document()))
+ Kate::Document::setOpenErrorDialogsActivated (false);
+
+ if (codec && KTextEditor::encodingInterface(t->view()->document()))
+ KTextEditor::encodingInterface(t->view()->document())->setEncoding(codec->name());
+
+ t->loadURL( args->url( z ) );
+
+ if (Kate::document (t->view()->document()))
+ Kate::Document::setOpenErrorDialogsActivated (true);
+
+ if (nav && KTextEditor::viewCursorInterface(t->view()))
+ KTextEditor::viewCursorInterface(t->view())->setCursorPosition (line, column);
+ }
+ else
+ KMessageBox::sorry( t, i18n("The file '%1' could not be opened: it is not a normal file, it is a folder.").arg(args->url(z).url()) );
+ }
+ }
+ }
+
+ // no window there, uh, ohh, for example borked session config !!!
+ // create at least one !!
+ if (KWrite::noWindows())
+ new KWrite();
+
+ return a.exec ();
+}
+
+KWriteEditorChooser::KWriteEditorChooser(QWidget *):
+ KDialogBase(KDialogBase::Plain,i18n("Choose Editor Component"),KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Cancel)
+{
+ (new QVBoxLayout(plainPage()))->setAutoAdd(true);
+ m_chooser=new KTextEditor::EditorChooser(plainPage(),"Editor Chooser");
+ setMainWidget(m_chooser);
+ m_chooser->readAppSetting();
+}
+
+KWriteEditorChooser::~KWriteEditorChooser() {
+;
+}
+
+void KWriteEditorChooser::slotOk() {
+ m_chooser->writeAppSetting();
+ KDialogBase::slotOk();
+}
+// kate: space-indent on; indent-width 2; replace-tabs on; mixed-indent off;
diff --git a/kate/app/kwritemain.h b/kate/app/kwritemain.h
new file mode 100644
index 000000000..7af2c67ad
--- /dev/null
+++ b/kate/app/kwritemain.h
@@ -0,0 +1,138 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
+ Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
+ Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KWRITE_MAIN_H__
+#define __KWRITE_MAIN_H__
+
+#include <ktexteditor/view.h>
+#include <ktexteditor/document.h>
+
+#include <kparts/mainwindow.h>
+
+#include <kdialogbase.h>
+
+namespace KTextEditor { class EditorChooser; }
+
+class KAction;
+class KToggleAction;
+class KSelectAction;
+class KRecentFilesAction;
+
+class KWrite : public KParts::MainWindow
+{
+ Q_OBJECT
+
+ public:
+ KWrite(KTextEditor::Document * = 0L);
+ ~KWrite();
+
+ void loadURL(const KURL &url);
+
+ KTextEditor::View *view() const { return m_view; }
+
+ static bool noWindows () { return winList.isEmpty(); }
+
+ private:
+ void setupActions();
+ void setupStatusBar();
+
+ bool queryClose();
+
+ void dragEnterEvent( QDragEnterEvent * );
+ void dropEvent( QDropEvent * );
+
+ public slots:
+ void slotNew();
+ void slotFlush ();
+ void slotOpen();
+ void slotOpen( const KURL& url);
+ void newView();
+ void toggleStatusBar();
+ void editKeys();
+ void editToolbars();
+ void changeEditor();
+
+ private slots:
+ void slotNewToolbarConfig();
+
+ public slots:
+ void printNow();
+ void printDlg();
+
+ void newStatus(const QString &msg);
+ void newCaption();
+
+ void slotDropEvent(QDropEvent *);
+
+ void slotEnableActions( bool enable );
+
+ /**
+ * adds a changed URL to the recent files
+ */
+ void slotFileNameChanged();
+
+ //config file functions
+ public:
+ void readConfig (KConfig *);
+ void writeConfig (KConfig *);
+
+ void readConfig ();
+ void writeConfig ();
+
+ //session management
+ public:
+ void restore(KConfig *,int);
+ static void restore();
+
+ private:
+ void readProperties(KConfig *);
+ void saveProperties(KConfig *);
+ void saveGlobalProperties(KConfig *);
+
+ private:
+ KTextEditor::View * m_view;
+
+ KRecentFilesAction * m_recentFiles;
+ KToggleAction * m_paShowPath;
+ KToggleAction * m_paShowStatusBar;
+
+ QString encoding;
+
+ static QPtrList<KTextEditor::Document> docList;
+ static QPtrList<KWrite> winList;
+};
+
+class KWriteEditorChooser: public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ KWriteEditorChooser(QWidget *parent);
+ virtual ~KWriteEditorChooser();
+
+ private:
+ KTextEditor::EditorChooser *m_chooser;
+
+ protected slots:
+ void slotOk();
+};
+
+#endif
+// kate: space-indent on; indent-width 2; replace-tabs on; mixed-indent off;