diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2017-09-15 23:37:24 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2017-09-15 23:37:24 +0900 |
commit | 73e2d6bc1c5d0d5ec4783b44f50a4d5d81d27afc (patch) | |
tree | 6979c1670fa6f7a82a8b502be8c10cdacc7c5210 | |
parent | cd2fc7ba9120fac49ebe6ceaee51bc8eaf802d05 (diff) | |
parent | 6131095c14221ddbd16805059a9f3b3fc6c58225 (diff) | |
download | tdebase-73e2d6bc1c5d0d5ec4783b44f50a4d5d81d27afc.tar.gz tdebase-73e2d6bc1c5d0d5ec4783b44f50a4d5d81d27afc.zip |
Merge branch 'katesessions': add Kate session panel.
-rw-r--r-- | doc/kate/fundamentals.docbook | 13 | ||||
-rw-r--r-- | kate/app/CMakeLists.txt | 4 | ||||
-rw-r--r-- | kate/app/Makefile.am | 2 | ||||
-rw-r--r-- | kate/app/kateapp.cpp | 152 | ||||
-rw-r--r-- | kate/app/kateapp.h | 24 | ||||
-rw-r--r-- | kate/app/kateappIface.cpp | 11 | ||||
-rw-r--r-- | kate/app/kateexternaltools.cpp | 1 | ||||
-rw-r--r-- | kate/app/katefileselector.cpp | 1 | ||||
-rw-r--r-- | kate/app/katemain.h | 1 | ||||
-rw-r--r-- | kate/app/katemainwindow.cpp | 127 | ||||
-rw-r--r-- | kate/app/katemainwindow.h | 49 | ||||
-rw-r--r-- | kate/app/katesavemodifieddialog.cpp | 1 | ||||
-rw-r--r-- | kate/app/katesession.cpp | 1351 | ||||
-rw-r--r-- | kate/app/katesession.h | 828 | ||||
-rw-r--r-- | kate/app/katesessionpanel.cpp | 771 | ||||
-rw-r--r-- | kate/app/katesessionpanel.h | 174 | ||||
-rw-r--r-- | kate/app/kateviewmanager.cpp | 1 | ||||
-rw-r--r-- | kate/app/kateviewspace.cpp | 11 | ||||
-rw-r--r-- | kate/data/kateui.rc | 23 |
19 files changed, 2398 insertions, 1147 deletions
diff --git a/doc/kate/fundamentals.docbook b/doc/kate/fundamentals.docbook index c42614a71..05a56eac6 100644 --- a/doc/kate/fundamentals.docbook +++ b/doc/kate/fundamentals.docbook @@ -156,11 +156,10 @@ Shows license information. <option>-s</option> <option>--start</option> <parameter>name</parameter></userinput></term> <listitem> <para> -Starts kate with the session <parameter>name</parameter>. The session is created -if it does not exist already. If a &kate; instance running the specified session -exists, the specified files are loaded in that instance. When used with the -<option>--use</option> option, an instance running this session will be used as -well. +Starts &kate; with the session <parameter>name</parameter>. If the session does not exist, +a new session with the specified name is created. +If a &kate; instance running the specified session already exists, the specified files are +loaded in that instance. </para> </listitem> </varlistentry> @@ -170,7 +169,7 @@ well. <option>-u</option> <option>--use</option> <parameter>URL</parameter></userinput></term> <listitem> <para> -Causes &kate; to use and existing instance if there is one. If you want all +Causes &kate; to use an existing instance if there is one. If you want all documents to open in one kate instance, you can add this option to the default command in your &tde; application configuration, as well as create a shell alias in your command intepreter if it supports that. @@ -307,7 +306,7 @@ flexibility. In this section we'll look at three items: </term> <listitem> <para> -Toggles the Documents on and off. If the Documents/Filesystem Browser side bar +Toggles the Documents on and off. If the Documents/Filesystem Browser side bar window is not open, &kate; will open the side bar window.</para> </listitem> diff --git a/kate/app/CMakeLists.txt b/kate/app/CMakeLists.txt index 7adea8ea3..77908ffcf 100644 --- a/kate/app/CMakeLists.txt +++ b/kate/app/CMakeLists.txt @@ -38,8 +38,8 @@ set( ${target}_SRCS kbookmarkhandler.cpp katedocmanageriface.skel kateappIface.cpp kateappIface.skel katedocmanageriface.cpp kateexternaltools.cpp katesavemodifieddialog.cpp kateviewspacecontainer.cpp - katemwmodonhddialog.cpp katesession.cpp katemdi.cpp - katetabwidget.cpp + katemwmodonhddialog.cpp katesession.cpp katesessionpanel.cpp + katemdi.cpp katetabwidget.cpp ) tde_add_library( ${target} SHARED AUTOMOC diff --git a/kate/app/Makefile.am b/kate/app/Makefile.am index de2258630..c50f68562 100644 --- a/kate/app/Makefile.am +++ b/kate/app/Makefile.am @@ -10,7 +10,7 @@ libkateinterfaces_la_SOURCES = kateapp.cpp kateconfigdialog.cpp kateconfigplugin 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 + katemwmodonhddialog.cpp katesession.cpp katesessionpanel.cpp katemdi.cpp katetabwidget.cpp libkateinterfaces_la_LIBADD = ../interfaces/libkateinterfacesprivate.la $(LIB_TDEUTILS) ../utils/libkateutils.la diff --git a/kate/app/kateapp.cpp b/kate/app/kateapp.cpp index 9cba61cc6..18251ee09 100644 --- a/kate/app/kateapp.cpp +++ b/kate/app/kateapp.cpp @@ -75,7 +75,7 @@ KateApp::KateApp (TDECmdLineArgs *args) m_pluginManager = new KatePluginManager (TQT_TQOBJECT(this)); // session manager up - m_sessionManager = new KateSessionManager (TQT_TQOBJECT(this)); + m_sessionManager = KateSessionManager::self(); // application dcop interface m_obj = new KateAppDCOPIface (this); @@ -83,6 +83,8 @@ KateApp::KateApp (TDECmdLineArgs *args) kdDebug()<<"Setting KATE_PID: '"<<getpid()<<"'"<<endl; ::setenv( "KATE_PID", TQString(TQString("%1").arg(getpid())).latin1(), 1 ); + connect(this, TQT_SIGNAL(aboutToQuit()), this, TQT_SLOT(slotAboutToQuit())); + // handle restore different if (isRestored()) { @@ -105,14 +107,10 @@ KateApp::KateApp (TDECmdLineArgs *args) KateApp::~KateApp () { - // cu dcop interface - delete m_obj; - - // cu plugin manager - delete m_pluginManager; - - // delete this now, or we crash - delete m_docManager; + delete m_obj; // cu dcop interface + delete m_pluginManager; // cu plugin manager + delete m_sessionManager; // delete session manager + delete m_docManager; // delete document manager. Do this now, or we crash } KateApp *KateApp::self () @@ -139,25 +137,22 @@ TQString KateApp::kateVersion (bool fullVersion) return fullVersion ? TQString ("2.5.%1").arg(KDE::versionMajor()) : TQString ("%1.%2").arg(2.5); } -void KateApp::restoreKate () +void KateApp::restoreKate() { // restore the nice files ;) we need it - Kate::Document::setOpenErrorDialogsActivated (false); - - // activate again correct session!!! - sessionConfig()->setGroup("General"); - TQString lastSession (sessionConfig()->readEntry ("Last Session", "default.katesession")); - sessionManager()->activateSession (new KateSession (sessionManager(), lastSession, ""), false, false, false); + Kate::Document::setOpenErrorDialogsActivated(false); - m_docManager->restoreDocumentList (sessionConfig()); + // restore last session + sessionManager()->restoreLastSession(); + m_docManager->restoreDocumentList(sessionConfig()); - Kate::Document::setOpenErrorDialogsActivated (true); + Kate::Document::setOpenErrorDialogsActivated(true); // restore all windows ;) for (int n=1; TDEMainWindow::canBeRestored(n); n++) newMainWindow(sessionConfig(), TQString ("%1").arg(n)); - // oh, no mainwindow, create one, should not happen, but make sure ;) + // no mainwindow, create one, should not happen, but make sure ;) if (mainWindows() == 0) newMainWindow (); @@ -165,21 +160,60 @@ void KateApp::restoreKate () // TDEStartupInfo::setNewStartupId( activeMainWindow(), startupId()); } -bool KateApp::startupKate () +bool KateApp::startupKate() { - // user specified session to open - if (m_args->isSet ("start")) + if (m_args->isSet("start")) { - sessionManager()->activateSession (sessionManager()->giveSession (TQString::fromLocal8Bit(m_args->getOption("start"))), false, false); + // the user has specified the session to open. If the session does not exist, + // a new session with the specified name will be created + TQCString sessName = m_args->getOption("start"); + int sessId = sessionManager()->getSessionIdFromName(sessName); + if (sessId != KateSessionManager::INVALID_SESSION) + { + sessionManager()->activateSession(sessId); + } + else + { + sessionManager()->newSession(sessName); + } } else { - // let the user choose session if possible - if (!sessionManager()->chooseSession ()) + // check Kate session startup options + int startupOption = sessionManager()->getStartupOption(); + if (startupOption == KateSessionManager::STARTUP_NEW) { - // we will exit kate now, notify the rest of the world we are done - TDEStartupInfo::appStarted (startupId()); - return false; + sessionManager()->newSession(); + } + else if (startupOption == KateSessionManager::STARTUP_LAST) + { + sessionManager()->restoreLastSession(); + } + else // startupOption == KateSessionManager::STARTUP_MANUAL + { + KateSessionChooser *chooser = new KateSessionChooser(NULL); + int result = chooser->exec(); + switch (result) + { + case KateSessionChooser::RESULT_OPEN_NEW: + sessionManager()->newSession(); + break; + + case KateSessionChooser::RESULT_OPEN_EXISTING: + if (!m_sessionManager->activateSession(chooser->getSelectedSessionId())) + { + // Open a new session in case of error + sessionManager()->newSession(); + } + break; + + default: // KateSessionChooser::RESULT_QUIT_KATE: + // Kate will exit now and notify it is done + TDEStartupInfo::appStarted(startupId()); + return false; + break; + } + delete chooser; } } @@ -267,13 +301,11 @@ bool KateApp::startupKate () return true; } -void KateApp::shutdownKate (KateMainWindow *win) +void KateApp::shutdownKate(KateMainWindow *win) { - if (!win->queryClose_internal()) + if (!win->queryClose_internal() || !query_session_close()) return; - sessionManager()->saveActiveSession(true, true); - // detach the dcopClient dcopClient()->detach(); @@ -284,6 +316,60 @@ void KateApp::shutdownKate (KateMainWindow *win) quit (); } +bool KateApp::query_session_close() +{ + bool saveSessions = false; + int switchOption = m_sessionManager->getSwitchOption(); + if (switchOption == KateSessionManager::SWITCH_SAVE) + { + saveSessions = true; + } + else if (switchOption == KateSessionManager::SWITCH_ASK) + { + KDialogBase *dlg = new KDialogBase(i18n("Save Sessions"), + KDialogBase::Yes | KDialogBase::No | KDialogBase::Cancel, + KDialogBase::Cancel, KDialogBase::Cancel, NULL, NULL, true, false, + KStdGuiItem::save(), KStdGuiItem::del(), KStdGuiItem::cancel()); + bool dontAgain = false; + int res = KMessageBox::createKMessageBox(dlg, TQMessageBox::Warning, + i18n("<p>Do you want to save the existing sessions?<p>!!NOTE!!" + "<p>All existing sessions will be removed " + "if you choose \"Delete\""), TQStringList(), + i18n("Do not ask again"), &dontAgain, KMessageBox::Notify); + if (res == KDialogBase::Cancel) + { + return false; + } + if (dontAgain) + { + if (res == KDialogBase::No) + { + m_sessionManager->setSwitchOption(KateSessionManager::SWITCH_DISCARD); + } + else + { + m_sessionManager->setSwitchOption(KateSessionManager::SWITCH_SAVE); + } + } + if (res == KDialogBase::Yes) + { + saveSessions = true; + } + } + + if (saveSessions) + { + m_sessionManager->saveActiveSession(); + } + m_sessionManager->saveConfig(saveSessions); + return true; +} + +void KateApp::reparse_config() +{ + emit optionsChanged(); +} + KatePluginManager *KateApp::pluginManager() { return m_pluginManager; @@ -294,7 +380,7 @@ KateDocManager *KateApp::documentManager () return m_docManager; } -KateSessionManager *KateApp::sessionManager () +KateSessionManager* KateApp::sessionManager() { return m_sessionManager; } diff --git a/kate/app/kateapp.h b/kate/app/kateapp.h index 05d09a7fe..f421df5a7 100644 --- a/kate/app/kateapp.h +++ b/kate/app/kateapp.h @@ -100,7 +100,7 @@ class KDE_EXPORT KateApp : public TDEApplication * shutdown kate application * @param win mainwindow which is used for dialogs */ - void shutdownKate (KateMainWindow *win); + void shutdownKate(KateMainWindow *win); /** * application should exit @@ -108,8 +108,26 @@ class KDE_EXPORT KateApp : public TDEApplication */ bool shouldExit () { return m_shouldExit; } + /** + * to be called when the application is about to quit + * @return should we exit? + */ + bool query_session_close(); + + /** + * called after the config dialog has been closed. The application + * can parse the new configuration and take appropriate actions if required + */ + void reparse_config(); + + signals: + /** + * Emitted when the configuration has or may have been changed + */ + void optionsChanged(); + /** - * other accessors for global unique instances + * other accessors for global unique instances */ public: /** @@ -128,7 +146,7 @@ class KDE_EXPORT KateApp : public TDEApplication * accessor to session manager * @return session manager instance */ - KateSessionManager *sessionManager (); + KateSessionManager *sessionManager(); /** * window management diff --git a/kate/app/kateappIface.cpp b/kate/app/kateappIface.cpp index 259e48b89..bc06f1b78 100644 --- a/kate/app/kateappIface.cpp +++ b/kate/app/kateappIface.cpp @@ -23,6 +23,8 @@ #include "katedocmanager.h" #include "katemainwindow.h" +// FIXME: review Kate's DCOP interface for session management when the new session code is ready + KateAppDCOPIface::KateAppDCOPIface (KateApp *app) : DCOPObject ("KateApplication") , m_app (app) { @@ -89,16 +91,15 @@ bool KateAppDCOPIface::openInput (TQString text) return m_app->openInput (text); } -bool KateAppDCOPIface::activateSession (TQString session) +bool KateAppDCOPIface::activateSession(TQString session) { - m_app->sessionManager()->activateSession (m_app->sessionManager()->giveSession (session)); - + m_app->sessionManager()->activateSession(m_app->sessionManager()->getSessionIdFromName(session)); return true; } -const TQString & KateAppDCOPIface::session() const +const TQString& KateAppDCOPIface::session() const { - return m_app->sessionManager()->activeSession()->sessionName(); + return m_app->sessionManager()->getActiveSessionName(); } // kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/kate/app/kateexternaltools.cpp b/kate/app/kateexternaltools.cpp index f23ef3934..3bb21c934 100644 --- a/kate/app/kateexternaltools.cpp +++ b/kate/app/kateexternaltools.cpp @@ -172,7 +172,6 @@ void KateExternalToolsCommand::reload () { 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); diff --git a/kate/app/katefileselector.cpp b/kate/app/katefileselector.cpp index c4b107912..a57115774 100644 --- a/kate/app/katefileselector.cpp +++ b/kate/app/katefileselector.cpp @@ -413,7 +413,6 @@ void KateFileSelector::btnFilterClick() } } -//FIXME crash on shutdown void KateFileSelector::setActiveDocumentDir() { // kdDebug(13001)<<"KateFileSelector::setActiveDocumentDir()"<<endl; diff --git a/kate/app/katemain.h b/kate/app/katemain.h index 374b834cc..24663f58f 100644 --- a/kate/app/katemain.h +++ b/kate/app/katemain.h @@ -60,6 +60,7 @@ class KateConsole; class KateDocManager; class KateFileList; class KateFileSelector; +class KateSessionPanel; class KateMainWindow; class KatePluginIface; class KatePluginManager; diff --git a/kate/app/katemainwindow.cpp b/kate/app/katemainwindow.cpp index 0bcf08883..1a021beb9 100644 --- a/kate/app/katemainwindow.cpp +++ b/kate/app/katemainwindow.cpp @@ -31,6 +31,7 @@ #include "kateapp.h" #include "katefileselector.h" #include "katefilelist.h" +#include "katesessionpanel.h" #include "kategrepdialog.h" #include "katemailfilesdialog.h" #include "katemainwindowiface.h" @@ -217,6 +218,9 @@ void KateMainWindow::setupMainWindow () fileselector = new KateFileSelector( this, m_viewManager, t, "operator"); connect(fileselector->dirOperator(),TQT_SIGNAL(fileSelected(const KFileItem*)),this,TQT_SLOT(fileSelected(const KFileItem*))); + KateMDI::ToolView *st = createToolView("kate_sessionpanel", KMultiTabBar::Left, SmallIcon("view_choose"), i18n("Sessions")); + m_sessionpanel = new KateSessionPanel( this, m_viewManager, st, "sessionpanel"); + // ONLY ALLOW SHELL ACCESS IF ALLOWED ;) if (KateApp::self()->authorize("shell_access")) { @@ -302,14 +306,29 @@ void KateMainWindow::setupActions() slotWindowActivated (); // session actions - new TDEAction(i18n("Menu entry Session->New", "&New"), "document-new", 0, TQT_TQOBJECT(KateSessionManager::self()), TQT_SLOT(sessionNew()), actionCollection(), "sessions_new"); - new TDEAction(i18n("&Open..."), "document-open", 0, TQT_TQOBJECT(KateSessionManager::self()), TQT_SLOT(sessionOpen()), actionCollection(), "sessions_open"); - new TDEAction(i18n("&Save"), "document-save", 0, TQT_TQOBJECT(KateSessionManager::self()), TQT_SLOT(sessionSave()), actionCollection(), "sessions_save"); - new TDEAction(i18n("Save &As..."), "document-save-as", 0, TQT_TQOBJECT(KateSessionManager::self()), TQT_SLOT(sessionSaveAs()), actionCollection(), "sessions_save_as"); - new TDEAction(i18n("&Manage..."), "view_choose", 0, TQT_TQOBJECT(KateSessionManager::self()), TQT_SLOT(sessionManage()), actionCollection(), "sessions_manage"); - - // quick open menu ;) - new KateSessionsAction (i18n("&Quick Open"), actionCollection(), "sessions_list"); + new TDEAction(i18n("&New"), "list-add", 0, + TQT_TQOBJECT(m_sessionpanel), TQT_SLOT(slotNewSession()), actionCollection(), "session_new"); + new TDEAction(i18n("&Save"), "document-save", 0, + TQT_TQOBJECT(m_sessionpanel), TQT_SLOT(slotSaveSession()), actionCollection(), "session_save"); + new TDEAction(i18n("Save &As..."), "document-save-as", 0, + TQT_TQOBJECT(m_sessionpanel), TQT_SLOT(slotSaveSessionAs()), actionCollection(), "session_save_as"); + new TDEAction(i18n("&Rename"), "edit_user", 0, + TQT_TQOBJECT(m_sessionpanel), TQT_SLOT(slotRenameSession()), actionCollection(), "session_rename"); + new TDEAction(i18n("&Delete"), "edit-delete", 0, + TQT_TQOBJECT(m_sessionpanel), TQT_SLOT(slotDeleteSession()), actionCollection(), "session_delete"); + new TDEAction(i18n("Re&load"), "reload", 0, + TQT_TQOBJECT(m_sessionpanel), TQT_SLOT(slotReloadSession()), actionCollection(), "session_reload"); + new TDEAction(i18n("Acti&vate"), "forward", 0, + TQT_TQOBJECT(m_sessionpanel), TQT_SLOT(slotActivateSession()), actionCollection(), "session_activate"); + new TDEToggleAction(i18n("Toggle read &only"), "encrypted", 0, + TQT_TQOBJECT(m_sessionpanel), TQT_SLOT(slotSessionToggleReadOnly()), actionCollection(), "session_toggle_read_only"); + new TDEAction(i18n("Move &Up"), "go-up", 0, + TQT_TQOBJECT(m_sessionpanel), TQT_SLOT(slotSessionMoveUp()), actionCollection(), "session_move_up"); + new TDEAction(i18n("Move Do&wn"), "go-down", 0, + TQT_TQOBJECT(m_sessionpanel), TQT_SLOT(slotSessionMoveDown()), actionCollection(), "session_move_down"); + new KateSessionListActionMenu(this, i18n("Sele&ct session"), actionCollection(), "session_list"); + + connect(m_sessionpanel, TQT_SIGNAL(selectionChanged()), TQT_TQOBJECT(this), TQT_SLOT(slotSelectionChanged())); } KateTabWidget *KateMainWindow::tabWidget () @@ -323,9 +342,9 @@ void KateMainWindow::slotDocumentCloseAll() { } bool KateMainWindow::queryClose_internal() { - uint documentCount=KateDocManager::self()->documents(); + uint documentCount=KateDocManager::self()->documents(); - if ( ! showModOnDiskPrompt() ) + if ( !showModOnDiskPrompt() ) return false; TQPtrList<Kate::Document> modifiedDocuments=KateDocManager::self()->modifiedDocumentList(); @@ -354,23 +373,22 @@ bool KateMainWindow::queryClose() // just test, not close them actually if (KateApp::self()->sessionSaving()) { - return queryClose_internal (); + return queryClose_internal(); } // normal closing of window // allow to close all windows until the last without restrictions - if ( KateApp::self()->mainWindows () > 1 ) + if (KateApp::self()->mainWindows() > 1) + { return true; + } - // last one: check if we can close all documents, try run + // last one: check if we can close all documents and sessions, try run // and save docs if we really close down ! - if ( queryClose_internal () ) + if (queryClose_internal() && KateApp::self()->query_session_close()) { - KateApp::self()->sessionManager()->saveActiveSession(true, true); - // detach the dcopClient KateApp::self()->dcopClient()->detach(); - return true; } @@ -397,7 +415,7 @@ void KateMainWindow::slotNewToolbarConfig() void KateMainWindow::slotFileQuit() { - KateApp::self()->shutdownKate (this); + KateApp::self()->shutdownKate(this); } void KateMainWindow::readOptions () @@ -434,7 +452,7 @@ void KateMainWindow::saveOptions () config->writeEntry("Show Full Path in Title", m_viewManager->getShowFullPath()); config->writeEntry("Sync Konsole", syncKonsole); config->writeEntry("UseInstance", useInstance); - + fileOpenRecent->saveEntries(config, "Recent Files"); fileselector->writeConfig(config, "fileselector"); filelist->writeConfig(config, "Filelist"); @@ -482,7 +500,7 @@ void KateMainWindow::documentMenuAboutToShow() TQListViewItem * item = filelist->firstChild(); while( item ) { // would it be saner to use the screen width as a limit that some random number?? - TQString name = KStringHandler::rsqueeze( ((KateFileListItem *)item)->document()->docName(), 150 ); + TQString 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, @@ -568,6 +586,9 @@ void KateMainWindow::slotConfigure() dlg->exec(); delete dlg; + + // Inform Kate that options may have been changed + KateApp::self()->reparse_config(); } KURL KateMainWindow::activeDocumentUrl() @@ -820,7 +841,7 @@ void KateMainWindow::updateCaption (Kate::Document *doc) c = m_viewManager->activeView()->getDoc()->url().prettyURL(); } - TQString sessName = KateApp::self()->sessionManager()->activeSession()->sessionName(); + TQString sessName = KateApp::self()->sessionManager()->getActiveSessionName(); if ( !sessName.isEmpty() ) sessName = TQString("%1: ").arg( sessName ); @@ -849,12 +870,68 @@ void KateMainWindow::readProperties(TDEConfig *config) config->setGroup(grp); } -void KateMainWindow::saveGlobalProperties( TDEConfig* sessionConfig ) +//------------------------------------------- +void KateMainWindow::slotSelectionChanged() { - KateDocManager::self()->saveDocumentList (sessionConfig); + TDEActionCollection *mwac = actionCollection(); // Main Window Action Collection + TDEActionPtrList actionList = m_sessionpanel->m_actionCollection->actions(); + TDEActionPtrList::ConstIterator spa_it; + for (spa_it = actionList.begin(); spa_it != actionList.end(); ++spa_it) + { + TDEAction *a = mwac->action((*spa_it)->name()); + TDEToggleAction *ta = dynamic_cast<TDEToggleAction*>(a); + if (ta) + { + ta->setChecked((dynamic_cast<TDEToggleAction*>(*spa_it))->isChecked()); + } + if (a) + { + a->setEnabled((*spa_it)->isEnabled()); + } + } +} - sessionConfig->setGroup("General"); - sessionConfig->writeEntry ("Last Session", KateApp::self()->sessionManager()->activeSession()->sessionFileRelative()); +//------------------------------------------- +void KateMainWindow::activateSession(int sessionId) +{ + if (sessionId < 0 || sessionId == KateApp::self()->sessionManager()->getActiveSessionId()) + { + return; + } + + // Select the required session in the session panel's listview + TQListViewItem *item = m_sessionpanel->m_listview->firstChild(); + int idx = 0; + while (item && idx < sessionId) + { + item = item->nextSibling(); + ++idx; + } + if (idx == sessionId && item) + { + // Required session item found, switch session with consistent behavior + m_sessionpanel->m_listview->setSelected(item, true); + m_sessionpanel->slotActivateSession(); + } +} + +//------------------------------------------- +KateSessionListActionMenu::KateSessionListActionMenu(KateMainWindow *mw, const TQString &text, TQObject *parent, const char *name) + : TDEActionMenu(text, parent, name), m_mainWindow(mw) +{ + connect(popupMenu(), TQT_SIGNAL(aboutToShow()), this, TQT_SLOT(slotAboutToShow())); +} + +//------------------------------------------- +void KateSessionListActionMenu::slotAboutToShow() +{ + popupMenu()->clear(); + + TQPtrList<KateSession> &sessions = KateApp::self()->sessionManager()->getSessionsList(); + for (int idx = 0; idx < (int)sessions.count(); ++idx) + { + popupMenu()->insertItem(sessions[idx]->getSessionName(), m_mainWindow, TQT_SLOT(activateSession(int)), 0, idx); + } } // kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/kate/app/katemainwindow.h b/kate/app/katemainwindow.h index 157b4e57d..aa2a6cee7 100644 --- a/kate/app/katemainwindow.h +++ b/kate/app/katemainwindow.h @@ -68,7 +68,6 @@ class KateMainWindow : public KateMDI::MainWindow, virtual public KParts::PartBa /** * Accessor methodes for interface and child objects */ - public: Kate::MainWindow *mainWindow () { return m_mainWindow; } Kate::ToolViewManager *toolViewManager () { return m_toolViewManager; } @@ -79,7 +78,6 @@ class KateMainWindow : public KateMDI::MainWindow, virtual public KParts::PartBa /** * 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(); @@ -101,14 +99,27 @@ class KateMainWindow : public KateMDI::MainWindow, virtual public KParts::PartBa */ KateTabWidget *tabWidget (); - public: void readProperties(TDEConfig *config); void saveProperties(TDEConfig *config); - void saveGlobalProperties( TDEConfig* sessionConfig ); - public: bool queryClose_internal(); + void openURL (const TQString &name=0L); + + public slots: + /** + * update "Sessions" menu status when selection in session panel has changed + */ + void slotSelectionChanged(); + + /** + * activate the specified session. When there is the need to activate a session + * from the outside (for example from DCOP), using this method assures that + * the session activation is consistent with the behavior of the session panel + * @param sessionId the id of the session to activate + */ + void activateSession(int sessionId); + private: void setupMainWindow(); void setupActions(); @@ -127,11 +138,11 @@ class KateMainWindow : public KateMDI::MainWindow, virtual public KParts::PartBa void dragEnterEvent( TQDragEnterEvent * ); void dropEvent( TQDropEvent * ); + private slots: /** * slots used for actions in the menus/toolbars * or internal signal connections */ - private slots: void newWindow (); void slotConfigure(); @@ -163,18 +174,12 @@ class KateMainWindow : public KateMDI::MainWindow, virtual public KParts::PartBa void pluginHelp(); void slotFullScreen(bool); - public: - void openURL (const TQString &name=0L); - - private slots: void updateGrepDir (bool visible); - + void slotDocumentCloseAll(); + protected: bool event( TQEvent * ); - private slots: - void slotDocumentCloseAll(); - private: static uint uniqueID; uint myID; @@ -198,6 +203,7 @@ class KateMainWindow : public KateMDI::MainWindow, virtual public KParts::PartBa KateFileList *filelist; KateFileSelector *fileselector; + KateSessionPanel *m_sessionpanel; TDEActionMenu* documentOpenWith; @@ -213,6 +219,21 @@ class KateMainWindow : public KateMDI::MainWindow, virtual public KParts::PartBa KateTabWidget *m_tabWidget; }; +class KateSessionListActionMenu : public TDEActionMenu +{ + Q_OBJECT + + public: + KateSessionListActionMenu(KateMainWindow *mw, const TQString &text, TQObject *parent = NULL, const char *name = NULL); + ~KateSessionListActionMenu() {} + + public slots: + void slotAboutToShow(); + + protected: + KateMainWindow *m_mainWindow; +}; + #endif // kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/kate/app/katesavemodifieddialog.cpp b/kate/app/katesavemodifieddialog.cpp index a89fe57f8..9ff79dfb4 100644 --- a/kate/app/katesavemodifieddialog.cpp +++ b/kate/app/katesavemodifieddialog.cpp @@ -156,7 +156,6 @@ KateSaveModifiedDialog::KateSaveModifiedDialog(TQWidget *parent, TQPtrList<Kate: } m_documentRoot->setOpen(true); } else m_documentRoot=0; - //FIXME - Is this the best way? connect(m_list, TQT_SIGNAL(clicked(TQListViewItem *)), TQT_SLOT(slotItemSelected())); connect(m_list, TQT_SIGNAL(doubleClicked(TQListViewItem *)), TQT_SLOT(slotItemSelected())); connect(m_list, TQT_SIGNAL(spacePressed(TQListViewItem *)), TQT_SLOT(slotItemSelected())); diff --git a/kate/app/katesession.cpp b/kate/app/katesession.cpp index 2c0057bf8..4b973214b 100644 --- a/kate/app/katesession.cpp +++ b/kate/app/katesession.cpp @@ -1,4 +1,6 @@ /* This file is part of the KDE project + Copyright (C) 2015-2016 Michele Calgaro <micheleDOTcalgaro__AT__yahooDOTit> + partially based on previous work from Copyright (C) 2005 Christoph Cullmann <cullmann@kde.org> This library is free software; you can redistribute it and/or @@ -17,7 +19,6 @@ */ #include "katesession.h" -#include "katesession.moc" #include "kateapp.h" #include "katemainwindow.h" @@ -27,7 +28,6 @@ #include <tdelocale.h> #include <kdebug.h> #include <kdirwatch.h> -#include <tdelistview.h> #include <kinputdialog.h> #include <kiconloader.h> #include <tdemessagebox.h> @@ -37,884 +37,867 @@ #include <tdepopupmenu.h> #include <tqdir.h> +#include <tqfile.h> #include <tqlabel.h> #include <tqlayout.h> #include <tqvbox.h> #include <tqhbox.h> -#include <tqcheckbox.h> #include <tqdatetime.h> #include <tqmap.h> #include <unistd.h> #include <time.h> -bool operator<( const KateSession::Ptr& a, const KateSession::Ptr& b ) +// FIXME general: need to keep doc list and current session's m_documents in synchro +// all the time (doc open, doc closed, doc renamed). +// To be done when doc list software is developed + +// String constants +namespace +{ + // Kate session + const char *KS_COUNT = "Count"; + const char *KS_DOCCOUNT = "Document count"; + const char *KS_DOCLIST = "Document list"; + const char *KS_GENERAL = "General"; + const char *KS_NAME = "Name"; + const char *KS_OPENDOC = "Open Documents"; + const char *KS_READONLY = "ReadOnly"; + const char *KS_OPEN_MAINWINDOWS = "Open MainWindows"; + const char *KS_UNNAMED = "Unnamed"; + + // Kate session manager + const char *KSM_DIR = "kate/sessions"; + const char *KSM_FILE = "sessions.list"; + const char *KSM_SESSIONS_COUNT = "Sessions count"; + const char *KSM_LAST_SESSION_ID = "Last session id"; + const char *KSM_SESSIONS_LIST = "Sessions list"; + + // Kate app + const char *KAPP_GENERAL = "General"; + const char *KAPP_LAST_SESSION = "Last Session"; + const char *KAPP_STARTUP_SESSION = "Startup Session"; + const char *KAPP_NEW = "new"; + const char *KAPP_LAST = "last"; + const char *KAPP_MANUAL = "manual"; + const char *KAPP_SESSION_EXIT = "Session Exit"; + const char *KAPP_DISCARD = "discard"; + const char *KAPP_SAVE = "save"; + const char *KAPP_ASK = "ask"; +} + +//BEGIN Kate session +KateSession::KateSession(const KateSessionManager &manager, const TQString &sessionName, + const TQString &fileName) : + m_manager(manager), m_sessionName(sessionName), m_filename(fileName), + m_readOnly(false), m_documents(), m_config(NULL) +{ + load(false); +} + +//------------------------------------ +KateSession::KateSession(const KateSession &session, const TQString &newSessionName) : + m_manager(session.m_manager), m_sessionName(newSessionName), m_filename(), + m_readOnly(false), m_documents(session.m_documents), m_config(NULL) +{ + createFilename(); + if (session.m_config) + { + m_config = new KSimpleConfig(m_filename); + session.m_config->copyTo(m_filename, m_config); + m_config->sync(); + } +} + +//------------------------------------ +KateSession::~KateSession() { - return a->sessionName().lower() < b->sessionName().lower(); + if (m_config) + { + delete m_config; + } } -KateSession::KateSession (KateSessionManager *manager, const TQString &fileName, const TQString &name) - : m_sessionFileRel (fileName) - , m_sessionName (name) - , m_documents (0) - , m_manager (manager) - , m_readConfig (0) - , m_writeConfig (0) +//------------------------------------ +void KateSession::setSessionName(const TQString &sessionName) { - init (); + m_sessionName = sessionName.isEmpty() ? i18n(KS_UNNAMED) : sessionName; +} + +//------------------------------------ +bool KateSession::isStillVolatile() const +{ + return m_filename.isEmpty() && m_sessionName == i18n(KS_UNNAMED); } -void KateSession::init () +//------------------------------------ +void KateSession::load(bool includeGUIInfo) { - // given file exists, use it to load some stuff ;) - if (!m_sessionFileRel.isEmpty() && TDEGlobal::dirs()->exists(sessionFile ())) + if (m_config) { - KSimpleConfig config (sessionFile (), true); - - if (m_sessionName.isEmpty()) + delete m_config; + } + + if (TDEGlobal::dirs()->exists(m_filename)) + { + // Create config object if the session file already exists + m_config = new KSimpleConfig(m_filename, m_readOnly); + m_config->setGroup(KS_GENERAL); + // Session general properties + m_sessionName = m_config->readEntry(KS_NAME, i18n(KS_UNNAMED)); + m_readOnly = m_config->readBoolEntry(KS_READONLY, false); + // Document list + if (m_config->hasGroup(KS_DOCLIST)) { - // get the name out of the file - if (m_sessionFileRel == "default.katesession") - m_sessionName = i18n("Default Session"); - else + // Read new style document list (from TDE R14.1.0) + m_config->setGroup(KS_DOCLIST); + int docCount = m_config->readNumEntry(KS_DOCCOUNT, 0); + for (int i = 0; i < docCount; ++i) { - config.setGroup ("General"); - m_sessionName = config.readEntry ("Name", i18n ("Unnamed Session")); + TQString urlStr = m_config->readEntry(TQString("URL_%1").arg(i)); + if (!urlStr.isEmpty()) + { + // Filter out empty URLs + m_documents.append(urlStr); + } } } - - // 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()) + else { - if (m_sessionFileRel == "default.katesession") - m_sessionName = i18n("Default Session"); - else - m_sessionName = i18n("Session (%1)").arg(TQTime::currentTime().toString(Qt::LocalDate)); + // Create document list from old session configuration + // to effortlessly import existing sessions + m_config->setGroup(KS_OPENDOC); + int docCount = m_config->readNumEntry(KS_COUNT, 0); + for (int i = 0; i < docCount; ++i) + { + m_config->setGroup(TQString("Document %1").arg(i)); + TQString urlStr = m_config->readEntry("URL"); + if (!urlStr.isEmpty()) + { + // Filter out empty URLs + m_documents.append(urlStr); + } + } } - - // 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; -} - -TQString KateSession::sessionFile () const -{ - return m_manager->sessionsDir() + "/" + m_sessionFileRel; -} - -bool KateSession::create (const TQString &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); - TQCString tname; - while (true) + else { - tname.setNum (s++); - KMD5 md5 (tname); - m_sessionFileRel = TQString ("%1.katesession").arg (md5.hexDigest().data()); - - if (!TDEGlobal::dirs()->exists(sessionFile ())) - break; + m_filename = TQString::null; + } + if (m_sessionName.isEmpty()) + { + m_sessionName = i18n(KS_UNNAMED); + } + + // Update all current documents if necessary + if (includeGUIInfo) + { + activate(); } - - // 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 TQString &name) -{ - if (name.isEmpty () || m_sessionFileRel.isEmpty() || m_sessionFileRel == "default.katesession") - return false; - - m_sessionName = name; - - TDEConfig config (sessionFile (), false, false); - config.setGroup ("General"); - config.writeEntry ("Name", m_sessionName); - config.sync (); - - return true; -} - -TDEConfig *KateSession::configRead () -{ - if (m_sessionFileRel.isEmpty()) - return 0; - - if (m_readConfig) - return m_readConfig; - - return m_readConfig = new KSimpleConfig (sessionFile (), true); -} - -TDEConfig *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 (TQObject *parent) - : TQObject (parent) - , m_sessionsDir (locateLocal( "data", "kate/sessions")) - , m_activeSession (new KateSession (this, "", "")) -{ - kdDebug() << "LOCAL SESSION DIR: " << m_sessionsDir << endl; - - // create dir if needed - TDEGlobal::dirs()->makeDir (m_sessionsDir); -} - -KateSessionManager::~KateSessionManager() -{ -} - -KateSessionManager *KateSessionManager::self() -{ - return KateApp::self()->sessionManager (); -} - -void KateSessionManager::dirty (const TQString &) -{ - updateSessionList (); } -void KateSessionManager::updateSessionList () +//------------------------------------ +void KateSession::save(bool saveGUIInfo, bool setReadOnly) { - m_sessionList.clear (); - - // Let's get a list of all session we have atm - TQDir dir (m_sessionsDir, "*.katesession"); - - bool foundDefault = false; - for (unsigned int i=0; i < dir.count(); ++i) + if (m_readOnly && !setReadOnly) { - KateSession *session = new KateSession (this, dir[i], ""); - m_sessionList.append (session); + return; + } - kdDebug () << "FOUND SESSION: " << session->sessionName() << " FILE: " << session->sessionFile() << endl; + // create a new session filename if needed + if (m_filename.isEmpty()) + { + createFilename(); + } - if (!foundDefault && (dir[i] == "default.katesession")) - foundDefault = true; + // save session config info + if (!m_config) + { + m_config = new KSimpleConfig(m_filename); } - // add default session, if not there - if (!foundDefault) - m_sessionList.append (new KateSession (this, "default.katesession", i18n("Default Session"))); + if (m_config->hasGroup(KS_GENERAL)) + { + m_config->deleteGroup(KS_GENERAL); + } + m_config->setGroup(KS_GENERAL); + m_config->writeEntry(KS_NAME, m_sessionName); + m_config->writeEntry(KS_READONLY, m_readOnly); - qHeapSort(m_sessionList); -} + if (m_config->hasGroup(KS_DOCLIST)) + { + m_config->deleteGroup(KS_DOCLIST); + } + m_config->setGroup(KS_DOCLIST); + m_config->writeEntry(KS_DOCCOUNT, m_documents.count()); + for (int i = 0; i < (int)m_documents.count(); ++i) + { + m_config->writeEntry(TQString("URL_%1").arg(i), m_documents[i]); + } -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) + // save GUI elements info + if (saveGUIInfo) { - if (KateApp::self()->activeMainWindow()) + KateDocManager::self()->saveDocumentList(m_config); + // save main windows info + int mwCount = KateApp::self()->mainWindows(); + m_config->setGroup(KS_OPEN_MAINWINDOWS); + m_config->writeEntry(KS_COUNT, mwCount); + for (int i = 0; i < mwCount; ++i) { - if (!KateApp::self()->activeMainWindow()->queryClose_internal()) - return; + m_config->setGroup(TQString("MainWindow%1").arg(i)); + KateApp::self()->mainWindow(i)->saveProperties(m_config); } } - // save last session or not? - if (saveLast) - saveActiveSession (true); + m_config->sync(); +} - // really close last - if (closeLast) +//------------------------------------ +void KateSession::activate() +{ + if (KateDocManager::self()->documents() > 0) { - KateDocManager::self()->closeAllDocuments (); + KateDocManager::self()->closeAllDocuments(); } - - // set the new session - m_activeSession = session; - - if (loadNew) + + Kate::Document::setOpenErrorDialogsActivated(false); + if (m_config) { - // open the new session - Kate::Document::setOpenErrorDialogsActivated (false); - - TDEConfig *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) + KateApp::self()->documentManager()->restoreDocumentList(m_config); + + // load main windows info, if it exists + if (m_config->hasGroup(KS_OPEN_MAINWINDOWS)) { - TDEConfig *c = KateApp::self()->config(); - c->setGroup("General"); - - if (c->readBoolEntry("Restore Window Configuration", true)) + m_config->setGroup(KS_OPEN_MAINWINDOWS); + int mwCount = m_config->readUnsignedNumEntry(KS_COUNT, 1); + for (int i = 0; i < mwCount; ++i) { - // 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 >= (int)KateApp::self()->mainWindows()) { - if (i >= KateApp::self()->mainWindows()) - { - KateApp::self()->newMainWindow(sc, TQString ("MainWindow%1").arg(i)); - } - else - { - sc->setGroup(TQString ("MainWindow%1").arg(i)); - KateApp::self()->mainWindow(i)->readProperties (sc); - } + KateApp::self()->newMainWindow(m_config, TQString("MainWindow%1").arg(i)); } - - if (wCount > 0) + else { - while (wCount < KateApp::self()->mainWindows()) - { - KateMainWindow *w = KateApp::self()->mainWindow(KateApp::self()->mainWindows()-1); - KateApp::self()->removeMainWindow (w); - delete w; - } + m_config->setGroup(TQString("MainWindow%1").arg(i)); + KateApp::self()->mainWindow(i)->readProperties(m_config); } } } - - Kate::Document::setOpenErrorDialogsActivated (true); } + Kate::Document::setOpenErrorDialogsActivated(true); } -KateSession::Ptr KateSessionManager::createSession (const TQString &name) +//------------------------------------ +void KateSession::createFilename() { - KateSession::Ptr s = new KateSession (this, "", ""); - s->create (name); - - return s; + // create a new session filename if needed + if (!m_filename.isEmpty()) + { + return; + } + + int s = time(0); + TQCString tname; + TQString tmpName; + while (true) + { + tname.setNum(s++); + KMD5 md5(tname); + tmpName = m_manager.getBaseDir() + TQString("%1.katesession").arg(md5.hexDigest().data()); + if (!TDEGlobal::dirs()->exists(tmpName)) + { + m_filename = tmpName; + break; + } + } } +//END Kate session -KateSession::Ptr KateSessionManager::giveSession (const TQString &name) -{ - if (name.isEmpty()) - return new KateSession (this, "", ""); - updateSessionList(); +//BEGIN KateSessionManager +//------------------------------------ +KateSessionManager *KateSessionManager::ksm_instance = NULL; - for (unsigned int i=0; i < m_sessionList.count(); ++i) +//------------------------------------ +KateSessionManager* KateSessionManager::self() +{ + if (!KateSessionManager::ksm_instance) { - if (m_sessionList[i]->sessionName() == name) - return m_sessionList[i]; + KateSessionManager::ksm_instance = new KateSessionManager(); } - - return createSession (name); -} - -bool KateSessionManager::saveActiveSession (bool tryAsk, bool rememberAsLast) -{ - if (tryAsk) + return KateSessionManager::ksm_instance; +} + +//------------------------------------ +KateSessionManager::KateSessionManager() : + m_baseDir(locateLocal("data", KSM_DIR)+"/"), m_configFile(m_baseDir + KSM_FILE), + m_activeSessionId(INVALID_SESSION), m_lastSessionId(INVALID_SESSION), m_sessions(), + m_config(NULL), m_startupOption(STARTUP_NEW), m_switchOption(SWITCH_DISCARD) +{ + // Session startup and switch options + updateSessionOptions(SO_ALL); + + // Sessions configuration + m_sessions.setAutoDelete(true); + int sessionsCount = 0; + if (TDEGlobal::dirs()->exists(m_configFile)) { - // app config - TDEConfig *c = KateApp::self()->config(); - c->setGroup("General"); - - TQString sesExit (c->readEntry ("Session Exit", "save")); - - if (sesExit == "discard") - return true; - - if (sesExit == "ask") + // Read new style configuration (from TDE R14.1.0) + m_config = new KSimpleConfig(m_configFile); + m_config->setGroup(KSM_SESSIONS_LIST); + sessionsCount = m_config->readNumEntry(KSM_SESSIONS_COUNT, 0); + m_lastSessionId = m_config->readNumEntry(KSM_LAST_SESSION_ID, INVALID_SESSION); + for (int i = 0; i < sessionsCount; ++i) { - KDialogBase* dlg = new KDialogBase(i18n ("Save Session?") - , KDialogBase::Yes | KDialogBase::No - , KDialogBase::Yes, KDialogBase::No - ); - - bool dontAgain = false; - int res = KMessageBox::createKMessageBox(dlg, TQMessageBox::Question, - i18n("Save current session?"), TQStringList(), - i18n("Do not ask again"), &dontAgain, KMessageBox::Notify); - - // remember to not ask again with right setting - if (dontAgain) + TQString urlStr = m_config->readEntry(TQString("URL_%1").arg(i)); + if (!urlStr.isEmpty() && TDEGlobal::dirs()->exists(urlStr)) { - c->setGroup("General"); - - if (res == KDialogBase::No) - c->writeEntry ("Session Exit", "discard"); - else - c->writeEntry ("Session Exit", "save"); + // Filter out empty URLs or non existing sessions + m_sessions.append(new KateSession(*this, TQString::null, urlStr)); } - - if (res == KDialogBase::No) - return true; } } - - TDEConfig *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 ) + else { - sc->setGroup(TQString ("MainWindow%1").arg(i)); - KateApp::self()->mainWindow(i)->saveProperties (sc); + // Create sessions list from session files + // to effortlessly import existing sessions + TQDir sessionDir(m_baseDir, "*.katesession"); + for (unsigned int i = 0; i < sessionDir.count(); ++i) + { + m_sessions.append(new KateSession(*this, TQString::null, m_baseDir+sessionDir[i])); + } } - - sc->sync(); - - if (rememberAsLast) + sessionsCount = (int)m_sessions.count(); + if (sessionsCount == 0) // In the worst case, there is no valid session at all { - TDEConfig *c = KateApp::self()->config(); - c->setGroup("General"); - c->writeEntry ("Last Session", activeSession()->sessionFileRelative()); - c->sync (); + m_sessions.append(new KateSession(*this, TQString::null, TQString::null)); } - - return true; + if (m_lastSessionId < 0 || m_lastSessionId >= (int)m_sessions.count()) + { + m_lastSessionId = 0; // Invalid last session was detected. Use first in the list + } + + //NOTE do not activate any session in the KateSessionManager costructor + // since Kate's main window may not be ready yet. The initial session + // will be activated by KateApp::startupKate() or KateApp::restoreKate() } -bool KateSessionManager::chooseSession () +//------------------------------------ +KateSessionManager::~KateSessionManager() { - bool success = true; - - // app config - TDEConfig *c = KateApp::self()->config(); - c->setGroup("General"); - - // get last used session, default to default session - TQString lastSession (c->readEntry ("Last Session", "default.katesession")); - TQString sesStart (c->readEntry ("Startup Session", "manual")); - - // uhh, just open last used session, show no chooser - if (sesStart == "last") + if (m_config) { - activateSession (new KateSession (this, lastSession, ""), false, false); - return success; + delete m_config; } + m_sessions.clear(); +} - // start with empty new session - if (sesStart == "new") +//------------------------------------ +void KateSessionManager::updateSessionOptions(int optionType) +{ + // Session startup and switch options + TDEConfig *kateCfg = KateApp::self()->config(); + kateCfg->setGroup(KAPP_GENERAL); + + if (optionType == SO_STARTUP || optionType == SO_ALL) { - activateSession (new KateSession (this, "", ""), false, false); - return success; + if (kateCfg->hasKey(KAPP_LAST_SESSION)) + { + // Delete no longer used entry (pre R14.1.0) + kateCfg->deleteEntry(KAPP_LAST_SESSION); + } + TQString startupOption(kateCfg->readEntry(KAPP_STARTUP_SESSION, KAPP_MANUAL)); + if (startupOption == KAPP_LAST) + { + m_startupOption = STARTUP_LAST; + } + else if (startupOption == KAPP_NEW) + { + m_startupOption = STARTUP_NEW; + } + else // startupOption == "manual" + { + m_startupOption = STARTUP_MANUAL; + } } + + if (optionType == SO_SWITCH || optionType == SO_ALL) + { + TQString switchOption(kateCfg->readEntry(KAPP_SESSION_EXIT, KAPP_ASK)); + if (switchOption == KAPP_DISCARD) + { + m_switchOption = SWITCH_DISCARD; + } + else if (switchOption == KAPP_SAVE) + { + m_switchOption = SWITCH_SAVE; + } + else // switchOption == "ask" + { + m_switchOption = SWITCH_ASK; + } + } +} - KateSessionChooser *chooser = new KateSessionChooser (0, lastSession); - - bool retry = true; - int res = 0; - while (retry) +//------------------------------------ +void KateSessionManager::saveSessionOptions(int optionType) +{ + TDEConfig *kateCfg = KateApp::self()->config(); + kateCfg->setGroup(KAPP_GENERAL); + if (optionType == SO_STARTUP || optionType == SO_ALL) + { + if (m_startupOption == STARTUP_LAST) + { + kateCfg->writeEntry(KAPP_STARTUP_SESSION, KAPP_LAST); + } + else if (m_startupOption == STARTUP_NEW) + { + kateCfg->writeEntry(KAPP_STARTUP_SESSION, KAPP_NEW); + } + else // m_startupOption == STARTUP_MANUAL + { + kateCfg->writeEntry(KAPP_STARTUP_SESSION, KAPP_MANUAL); + } + } + + if (optionType == SO_SWITCH || optionType == SO_ALL) { - res = chooser->exec (); + if (m_switchOption == SWITCH_DISCARD) + { + kateCfg->writeEntry(KAPP_SESSION_EXIT, KAPP_DISCARD); + } + else if (m_switchOption == SWITCH_SAVE) + { + kateCfg->writeEntry(KAPP_SESSION_EXIT, KAPP_SAVE); + } + else // m_switchOption == SWITCH_ASK + { + kateCfg->writeEntry(KAPP_SESSION_EXIT, KAPP_ASK); + } + } + kateCfg->sync(); +} - switch (res) +//------------------------------------ +void KateSessionManager::saveConfig(bool saveSessions) +{ + // Session startup and switch options + updateSessionOptions(SO_ALL); + saveSessionOptions(SO_ALL); + + // Sessions configuration + if (!saveSessions) + { + // delete all session files if they exist + for (int i = 0; i < (int)m_sessions.count(); ++i) { - case KateSessionChooser::resultOpen: + const TQString &filename = m_sessions[i]->getSessionFilename(); + if (filename != TQString::null && TQFile::exists(filename)) { - 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; + TQFile::remove(filename); } - - // exit the app lateron - case KateSessionChooser::resultQuit: - success = false; - retry = false; - break; - - default: - activateSession (new KateSession (this, "", ""), false, false); - retry = false; - break; } + + m_sessions.clear(); + m_activeSessionId = INVALID_SESSION; } - - // write back our nice boolean :) - if (success && chooser->reopenLastSession ()) + + if (!m_config) { - c->setGroup("General"); - - if (res == KateSessionChooser::resultOpen) - c->writeEntry ("Startup Session", "last"); - else if (res == KateSessionChooser::resultNew) - c->writeEntry ("Startup Session", "new"); - - c->sync (); + m_config = new KSimpleConfig(m_configFile); } - - delete chooser; - - return success; + if (m_config->hasGroup(KSM_SESSIONS_LIST)) + { + m_config->deleteGroup(KSM_SESSIONS_LIST); + } + m_config->setGroup(KSM_SESSIONS_LIST); + m_config->writeEntry(KSM_SESSIONS_COUNT, m_sessions.count()); + m_config->writeEntry(KSM_LAST_SESSION_ID, m_activeSessionId); + for (int i = 0; i < (int)m_sessions.count(); ++i) + { + saveSession(i, false, false); + m_config->writeEntry(TQString("URL_%1").arg(i), m_sessions[i]->getSessionFilename()); + } + m_config->sync(); } -void KateSessionManager::sessionNew () +//------------------------------------ +const int KateSessionManager::getStartupOption() { - activateSession (new KateSession (this, "", "")); + updateSessionOptions(SO_STARTUP); + return m_startupOption; } -void KateSessionManager::sessionOpen () +//------------------------------------ +const int KateSessionManager::getSwitchOption() { - KateSessionOpenDialog *chooser = new KateSessionOpenDialog (0); + updateSessionOptions(SO_SWITCH); + return m_switchOption; +} - int res = chooser->exec (); +//------------------------------------ +void KateSessionManager::setSwitchOption(int option) +{ + m_switchOption = (option == SWITCH_DISCARD || option == SWITCH_SAVE) ? option : SWITCH_ASK; + saveSessionOptions(SO_SWITCH); + emit switchOptionChanged(); +} - if (res == KateSessionOpenDialog::resultCancel) +//------------------------------------ +const TQString& KateSessionManager::getSessionName(int sessionId) +{ + if (sessionId < 0 || sessionId >= (int)m_sessions.count()) { - delete chooser; - return; + return TQString::null; } - KateSession::Ptr s = chooser->selectedSession (); - - if (s) - activateSession (s); - - delete chooser; + return m_sessions[sessionId]->getSessionName(); } -void KateSessionManager::sessionSave () +//------------------------------------ +KateSession* KateSessionManager::getSessionFromId(int sessionId) { - // if the active session is valid, just save it :) - if (saveActiveSession ()) - return; - - bool ok = false; - TQString name = KInputDialog::getText (i18n("Specify Name for Current Session"), i18n("Session name:"), "", &ok); - - if (!ok) - return; - - if (name.isEmpty()) + if (sessionId < 0 || sessionId >= (int)m_sessions.count()) { - KMessageBox::error (0, i18n("To save a new session, you must specify a name."), i18n ("Missing Session Name")); - return; + return NULL; } - activeSession()->create (name); - saveActiveSession (); + return m_sessions[sessionId]; } -void KateSessionManager::sessionSaveAs () +//------------------------------------ +int KateSessionManager::getSessionIdFromName(const TQString &name) { - bool ok = false; - TQString name = KInputDialog::getText (i18n("Specify New Name for Current Session"), i18n("Session name:"), "", &ok); - - if (!ok) - return; - if (name.isEmpty()) + return INVALID_SESSION; + + for (int i = 0; i < (int)m_sessions.count(); ++i) { - KMessageBox::error (0, i18n("To save a session, you must specify a name."), i18n ("Missing Session Name")); - return; + if (m_sessions[i]->getSessionName() == name) + return i; } - activeSession()->create (name, true); - saveActiveSession (); + return INVALID_SESSION; } - -void KateSessionManager::sessionManage () +//------------------------------------ +bool KateSessionManager::activateSession(int sessionId, bool saveCurr) { - KateSessionManageDialog *dlg = new KateSessionManageDialog (0); - - dlg->exec (); - - delete dlg; -} + if (sessionId < 0 || sessionId >= (int)m_sessions.count()) + { + return false; + } -//BEGIN CHOOSER DIALOG + if (sessionId == m_activeSessionId) + { + return true; + } -class KateSessionChooserItem : public TQListViewItem -{ - public: - KateSessionChooserItem (TDEListView *lv, KateSession::Ptr s) - : TQListViewItem (lv, s->sessionName()) - , session (s) + int oldSessionId = m_activeSessionId; + if (m_activeSessionId != INVALID_SESSION) + { + // Do this only if a session has already been activated earlier, + if (KateApp::self()->activeMainWindow()) { - TQString docs; - docs.setNum (s->documents()); - setText (1, docs); + // First check if all documents can be closed safely + if (!KateApp::self()->activeMainWindow()->queryClose_internal()) + return false; + } + if (saveCurr) + { + saveSession(m_activeSessionId, true); + } + else + { + // Delete current session before activating the new one + const TQString &filename = m_sessions[m_activeSessionId]->getSessionFilename(); + if (filename != TQString::null && TQFile::exists(filename)) + { + TQFile::remove(filename); + } + m_sessions.remove(m_activeSessionId); // this also deletes the KateSession item since auto-deletion is enabled + m_activeSessionId = INVALID_SESSION; + if (sessionId > oldSessionId) + { + --sessionId; + } + emit sessionDeleted(oldSessionId); + oldSessionId = INVALID_SESSION; } - - KateSession::Ptr session; -}; - -KateSessionChooser::KateSessionChooser (TQWidget *parent, const TQString &lastSession) - : KDialogBase ( parent - , "" - , true - , i18n ("Session Chooser") - , KDialogBase::User1 | KDialogBase::User2 | KDialogBase::User3 - , KDialogBase::User2 - , true - , KStdGuiItem::quit () - , KGuiItem (i18n ("Open Session"), "document-open") - , KGuiItem (i18n ("New Session"), "document-new") - ) -{ - TQHBox *page = new TQHBox (this); - page->setMinimumSize (400, 200); - setMainWidget(page); - - TQHBox *hb = new TQHBox (page); - hb->setSpacing (KDialog::spacingHint()); - - TQLabel *label = new TQLabel (hb); - label->setPixmap (UserIcon("sessionchooser")); - label->setFrameStyle (TQFrame::Panel | TQFrame::Sunken); - - TQVBox *vb = new TQVBox (hb); - vb->setSpacing (KDialog::spacingHint()); - - m_sessions = new TDEListView (vb); - m_sessions->addColumn (i18n("Session Name")); - m_sessions->addColumn (i18n("Open Documents")); - m_sessions->setResizeMode (TQListView::AllColumns); - m_sessions->setSelectionMode (TQListView::Single); - m_sessions->setAllColumnsShowFocus (true); - - connect (m_sessions, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(selectionChanged())); - connect (m_sessions, TQT_SIGNAL(doubleClicked(TQListViewItem *, const TQPoint &, int)), this, TQT_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 TQCheckBox (i18n ("&Always use this choice"), vb); - - setResult (resultNone); - - // trigger action update - selectionChanged (); + m_activeSessionId = sessionId; + m_sessions[sessionId]->activate(); + m_lastSessionId = INVALID_SESSION; + emit sessionActivated(m_activeSessionId, oldSessionId); + return true; } -KateSessionChooser::~KateSessionChooser () +//------------------------------------ +int KateSessionManager::newSession(const TQString &sessionName, bool saveCurr) { + m_sessions.append(new KateSession(*this, sessionName, TQString::null)); + int newSessionId = m_sessions.count() - 1; + emit sessionCreated(newSessionId); + activateSession(newSessionId, saveCurr); + return newSessionId; } -KateSession::Ptr KateSessionChooser::selectedSession () +//------------------------------------ +int KateSessionManager::cloneSession(int sessionId, const TQString &sessionName, bool activate, bool deleteCurr) { - KateSessionChooserItem *item = (KateSessionChooserItem *) m_sessions->selectedItem (); - - if (!item) - return 0; + if (sessionId < 0 || sessionId >= (int)m_sessions.count()) + { + return INVALID_SESSION; + } - return item->session; + m_sessions.append(new KateSession(*m_sessions[sessionId], sessionName)); + int newSessionId = m_sessions.count() - 1; + emit sessionCreated(newSessionId); + + // If cloning the active session, the new session will contain the current status + // and the original session will be restored to the last saved state (save as... functionality) + saveSession(newSessionId, sessionId == m_activeSessionId); + if (sessionId == m_activeSessionId) + { + reloadActiveSession(); + } + + if (activate) + { + activateSession(newSessionId, m_activeSessionId != INVALID_SESSION && !deleteCurr); + } + return newSessionId; } -bool KateSessionChooser::reopenLastSession () +//------------------------------------ +bool KateSessionManager::restoreLastSession() { - return m_useLast->isChecked (); + if (m_activeSessionId != INVALID_SESSION) + { + return false; + } + return activateSession(m_lastSessionId, false); } -void KateSessionChooser::slotUser2 () +//------------------------------------------- +void KateSessionManager::saveSession(int sessionId, bool saveGUIInfo, bool setReadOnly) { - done (resultOpen); + if (sessionId < 0 || sessionId >= (int)m_sessions.count()) + { + return; + } + m_sessions[sessionId]->save(saveGUIInfo, setReadOnly); + emit sessionSaved(sessionId); } -void KateSessionChooser::slotUser3 () +//------------------------------------------- +bool KateSessionManager::deleteSession(int sessionId, int actSessId) { - done (resultNew); -} + if (sessionId < 0 || sessionId >= (int)m_sessions.count()) + { + return false; + } -void KateSessionChooser::slotUser1 () -{ - done (resultQuit); -} + // delete session file if it exists + const TQString &filename = m_sessions[sessionId]->getSessionFilename(); + if (filename != TQString::null && TQFile::exists(filename)) + { + TQFile::remove(filename); + } + // delete session + m_sessions.remove(sessionId); // this also deletes the KateSession item since auto-deletion is enabled + if (m_activeSessionId > sessionId) + { + --m_activeSessionId; + } + else if (m_activeSessionId == sessionId) + { + m_activeSessionId = INVALID_SESSION; + } + emit sessionDeleted(sessionId); + if (m_activeSessionId == INVALID_SESSION) + { + if (m_sessions.count() > 0 && actSessId >= 0 && actSessId < (int)m_sessions.count()) + { + activateSession(actSessId, false); + } + else + { + newSession(); + } + } -void KateSessionChooser::selectionChanged () -{ - enableButton (KDialogBase::User2, m_sessions->selectedItem ()); + return true; } -//END CHOOSER DIALOG - -//BEGIN OPEN DIALOG - -KateSessionOpenDialog::KateSessionOpenDialog (TQWidget *parent) - : KDialogBase ( parent - , "" - , true - , i18n ("Open Session") - , KDialogBase::User1 | KDialogBase::User2 - , KDialogBase::User2 - , false - , KStdGuiItem::cancel () - , KGuiItem( i18n("&Open"), "document-open") - ) +//------------------------------------------- +void KateSessionManager::swapSessionsPosition(int sessionId1, int sessionId2) { - TQHBox *page = new TQHBox (this); - page->setMinimumSize (400, 200); - setMainWidget(page); - - TQHBox *hb = new TQHBox (page); - - TQVBox *vb = new TQVBox (hb); - - m_sessions = new TDEListView (vb); - m_sessions->addColumn (i18n("Session Name")); - m_sessions->addColumn (i18n("Open Documents")); - m_sessions->setResizeMode (TQListView::AllColumns); - m_sessions->setSelectionMode (TQListView::Single); - m_sessions->setAllColumnsShowFocus (true); - - connect (m_sessions, TQT_SIGNAL(doubleClicked(TQListViewItem *, const TQPoint &, int)), this, TQT_SLOT(slotUser2())); + if (sessionId1 < 0 || sessionId1 >= (int)m_sessions.count() || + sessionId2 < 0 || sessionId2 >= (int)m_sessions.count() || + sessionId1 == sessionId2) + { + return; + } - KateSessionList &slist (KateSessionManager::self()->sessionList()); - for (unsigned int i=0; i < slist.count(); ++i) + int idxMin, idxMax; + if (sessionId1 < sessionId2) + { + idxMin = sessionId1; + idxMax = sessionId2; + } + else { - new KateSessionChooserItem (m_sessions, slist[i]); + idxMin = sessionId2; + idxMax = sessionId1; } - setResult (resultCancel); -} + KateSession *sessMax = m_sessions.take(idxMax); + KateSession *sessMin = m_sessions.take(idxMin); + m_sessions.insert(idxMin, sessMax); + m_sessions.insert(idxMax, sessMin); + if (m_activeSessionId == sessionId1) + { + m_activeSessionId = sessionId2; + } + else if (m_activeSessionId == sessionId2) + { + m_activeSessionId = sessionId1; + } -KateSessionOpenDialog::~KateSessionOpenDialog () -{ + emit sessionsSwapped(idxMin, idxMax); } -KateSession::Ptr KateSessionOpenDialog::selectedSession () +//------------------------------------------- +void KateSessionManager::moveSessionForward(int sessionId) { - KateSessionChooserItem *item = (KateSessionChooserItem *) m_sessions->selectedItem (); - - if (!item) - return 0; + if (sessionId < 0 || sessionId >= ((int)m_sessions.count() - 1)) + { + return; + } - return item->session; + swapSessionsPosition(sessionId, sessionId + 1); } -void KateSessionOpenDialog::slotUser1 () +//------------------------------------------- +void KateSessionManager::moveSessionBackward(int sessionId) { - done (resultCancel); -} + if (sessionId < 1 || sessionId >= (int)m_sessions.count()) + { + return; + } -void KateSessionOpenDialog::slotUser2 () -{ - done (resultOk); + swapSessionsPosition(sessionId, sessionId - 1); } -//END OPEN DIALOG - -//BEGIN MANAGE DIALOG - -KateSessionManageDialog::KateSessionManageDialog (TQWidget *parent) - : KDialogBase ( parent - , "" - , true - , i18n ("Manage Sessions") - , KDialogBase::User1 - , KDialogBase::User1 - , false - , KStdGuiItem::close () - ) +//------------------------------------------- +void KateSessionManager::renameSession(int sessionId, const TQString &newSessionName) { - TQHBox *page = new TQHBox (this); - page->setMinimumSize (400, 200); - setMainWidget(page); - - TQHBox *hb = new TQHBox (page); - hb->setSpacing (KDialog::spacingHint()); - - m_sessions = new TDEListView (hb); - m_sessions->addColumn (i18n("Session Name")); - m_sessions->addColumn (i18n("Open Documents")); - m_sessions->setResizeMode (TQListView::AllColumns); - m_sessions->setSelectionMode (TQListView::Single); - m_sessions->setAllColumnsShowFocus (true); - - connect (m_sessions, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(selectionChanged())); - - updateSessionList (); - - TQWidget *vb = new TQWidget (hb); - TQVBoxLayout *vbl = new TQVBoxLayout (vb); - vbl->setSpacing (KDialog::spacingHint()); - - m_rename = new KPushButton (i18n("&Rename..."), vb); - connect (m_rename, TQT_SIGNAL(clicked()), this, TQT_SLOT(rename())); - vbl->addWidget (m_rename); - - m_del = new KPushButton (KStdGuiItem::del (), vb); - connect (m_del, TQT_SIGNAL(clicked()), this, TQT_SLOT(del())); - vbl->addWidget (m_del); - - vbl->addStretch (); + if (sessionId < 0 || sessionId >= (int)m_sessions.count()) + { + return; + } - // trigger action update - selectionChanged (); + m_sessions[sessionId]->setSessionName(newSessionName); + emit sessionRenamed(sessionId); } -KateSessionManageDialog::~KateSessionManageDialog () +//------------------------------------------- +void KateSessionManager::setSessionReadOnlyStatus(int sessionId, bool readOnly) { -} + if (sessionId < 0 || sessionId >= (int)m_sessions.count()) + { + return; + } -void KateSessionManageDialog::slotUser1 () -{ - done (0); + m_sessions[sessionId]->setReadOnly(readOnly); + // Session is saved one last time when making it read only + saveSession(sessionId, sessionId == m_activeSessionId, true); } +//END KateSessionManager -void KateSessionManageDialog::selectionChanged () +//BEGIN KateSessionChooser +//------------------------------------------- +KateSessionChooser::KateSessionChooser(TQWidget *parent) + : KDialogBase(parent, "", true, i18n("Session Chooser"), + KDialogBase::User1 | KDialogBase::User2 | KDialogBase::User3, KDialogBase::User2, + true, KStdGuiItem::quit(), KGuiItem(i18n("Open Session"), "document-open"), + KGuiItem(i18n("New Session"), "document-new")), m_listview(NULL) { - KateSessionChooserItem *item = (KateSessionChooserItem *) m_sessions->selectedItem (); + TQHBox *page = new TQHBox(this); + page->setMinimumSize(400, 200); + setMainWidget(page); - m_rename->setEnabled (item && item->session->sessionFileRelative() != "default.katesession"); - m_del->setEnabled (item && item->session->sessionFileRelative() != "default.katesession"); -} + TQHBox *hb = new TQHBox(page); + hb->setSpacing(KDialog::spacingHint()); -void KateSessionManageDialog::rename () -{ - KateSessionChooserItem *item = (KateSessionChooserItem *) m_sessions->selectedItem (); + TQLabel *label = new TQLabel(hb); + label->setPixmap(UserIcon("sessionchooser")); + label->setFrameStyle (TQFrame::Panel | TQFrame::Sunken); - if (!item || item->session->sessionFileRelative() == "default.katesession") - return; + TQVBox *vb = new TQVBox(hb); + vb->setSpacing (KDialog::spacingHint()); - bool ok = false; - TQString name = KInputDialog::getText (i18n("Specify New Name for Session"), i18n("Session name:"), item->session->sessionName(), &ok); + m_listview = new TDEListView(vb); + m_listview->addColumn(i18n("Session Name")); + m_listview->addColumn(i18n("Open Documents")); + m_listview->setSelectionMode(TQListView::Single); + m_listview->setAllColumnsShowFocus(true); + m_listview->setSorting(-1); + m_listview->setResizeMode(TQListView::LastColumn); - if (!ok) - return; + connect (m_listview, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(slotSelectionChanged())); + connect (m_listview, TQT_SIGNAL(executed(TQListViewItem*)), this, TQT_SLOT(slotUser2())); - if (name.isEmpty()) + TQPtrList<KateSession> &sessions = KateSessionManager::self()->getSessionsList(); + for (int idx = sessions.count()-1; idx >= 0; --idx) { - KMessageBox::error (0, i18n("To save a session, you must specify a name."), i18n ("Missing Session Name")); - return; + new KateSessionChooserItem(m_listview, sessions[idx]->getSessionName(), + TQString("%1").arg(sessions[idx]->getDocCount()), idx); } - item->session->rename (name); - updateSessionList (); + setResult(RESULT_NO_OP); + slotSelectionChanged(); // update button status } -void KateSessionManageDialog::del () +//------------------------------------------- +int KateSessionChooser::getSelectedSessionId() { - KateSessionChooserItem *item = (KateSessionChooserItem *) m_sessions->selectedItem (); + KateSessionChooserItem *selectedItem = dynamic_cast<KateSessionChooserItem*>(m_listview->selectedItem()); + if (!selectedItem) + return KateSessionManager::INVALID_SESSION; - if (!item || item->session->sessionFileRelative() == "default.katesession") - return; - - TQFile::remove (item->session->sessionFile()); - KateSessionManager::self()->updateSessionList (); - updateSessionList (); + return selectedItem->getSessionId(); } -void KateSessionManageDialog::updateSessionList () +//------------------------------------------- +void KateSessionChooser::slotUser1() { - m_sessions->clear (); - - KateSessionList &slist (KateSessionManager::self()->sessionList()); - for (unsigned int i=0; i < slist.count(); ++i) - { - new KateSessionChooserItem (m_sessions, slist[i]); - } + done(RESULT_QUIT_KATE); } -//END MANAGE DIALOG - - -KateSessionsAction::KateSessionsAction(const TQString& text, TQObject* parent, const char* name ) - : TDEActionMenu(text, parent, name) +//------------------------------------------- +void KateSessionChooser::slotUser2() { - connect(popupMenu(),TQT_SIGNAL(aboutToShow()),this,TQT_SLOT(slotAboutToShow())); + done(RESULT_OPEN_EXISTING); } -void KateSessionsAction::slotAboutToShow() +//------------------------------------------- +void KateSessionChooser::slotUser3() { - popupMenu()->clear (); - - KateSessionList &slist (KateSessionManager::self()->sessionList()); - for (unsigned int i=0; i < slist.count(); ++i) - { - popupMenu()->insertItem ( - slist[i]->sessionName(), - this, TQT_SLOT (openSession (int)), 0, - i ); - } + done(RESULT_OPEN_NEW); } -void KateSessionsAction::openSession (int i) +//------------------------------------------- +void KateSessionChooser::slotSelectionChanged() { - KateSessionList &slist (KateSessionManager::self()->sessionList()); + enableButton(KDialogBase::User2, m_listview->selectedItem()); +} +//END KateSessionChooser - if ((uint)i >= slist.count()) - return; +#include "katesession.moc" - 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 index b62e72a48..665ac867b 100644 --- a/kate/app/katesession.h +++ b/kate/app/katesession.h @@ -1,4 +1,6 @@ /* This file is part of the KDE project + Copyright (C) 2015-2016 Michele Calgaro <micheleDOTcalgaro__AT__yahooDOTit> + partially based on previous work from Copyright (C) 2005 Christoph Cullmann <cullmann@kde.org> This library is free software; you can redistribute it and/or @@ -27,392 +29,508 @@ #include <tdeaction.h> #include <tqobject.h> +#include <tqptrlist.h> #include <tqvaluelist.h> +#include <tqstringlist.h> +#include <tdelistview.h> -class KateSessionManager; - +class KateViewSpace; class KDirWatch; -class TDEListView; class KPushButton; - +class TDEListView; class TQCheckBox; +class KateSessionManager; -class KateSession : public TDEShared -{ - public: - /** - * Define a Shared-Pointer type - */ - typedef TDESharedPtr<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 TQString &fileName, const TQString &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 - */ - TQString sessionFile () const; - - /** - * relative session filename - * @return relative filename for this session - */ - const TQString &sessionFileRelative () const { return m_sessionFileRel; } - - /** - * session name - * @return name for this session - */ - const TQString &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 TQString &name, bool force = false); - - /** - * rename this session - * @param name new name - * @return success - */ - bool rename (const TQString &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 - */ - TDEConfig *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 - */ - TDEConfig *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 :) - */ - TQString m_sessionFileRel; - - /** - * session name, extracted from the file, to display to the user - */ - TQString 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 TQValueList<KateSession::Ptr> KateSessionList; -class KateSessionManager : public TQObject +//BEGIN KateSession +/** + * An object representing a Kate's session. + */ +class KateSession { - Q_OBJECT + public: + + /** + * create a new session and read the config from fileName if it exists + * @param manager the session manager handling this session + * @param sessionName session name + * @param fileName file where session config is saved to/restored from + */ + KateSession(const KateSessionManager &manager, const TQString &sessionName, const TQString &fileName); + + /** + * duplicate an existing session into a new one with the given new name. + * If the existing session is read-only, the new one will *not* be read-only by default + * @param session the existing session + * @param newSessionName the name of the new session + */ + KateSession(const KateSession &session, const TQString &newSessionName); + + /** + * Destructor + */ + ~KateSession(); + + /** + * @return the session name + */ + const TQString& getSessionName() const { return m_sessionName; } + + /** + * Set the new session name + * @param sessionName the new session name + */ + void setSessionName(const TQString &sessionName); + + /** + * @return whether the session is read only or not + */ + bool isReadOnly() const { return m_readOnly; } + + /** + * Set session read only status + * @param readOnly if true, the session status can not be modified + */ + void setReadOnly(bool readOnly) { m_readOnly = readOnly; } + + /** + * @return the session filename if available, otherwise the null string + */ + const TQString& getSessionFilename() const { return m_filename; } + + /** + * @return whether the session is still volatile, i.e. it has never + * been saved and never been named + */ + bool isStillVolatile() const; + + /** + * @return the number of documents in the session + */ + int getDocCount() const { return m_documents.count(); } + + /** + * Load session info from the saved file + * @param includeGUIInfo if true, also load the information about the GUI elements + */ + void load(bool includeGUIInfo); + + /** + * Save session info + * @param saveGUIInfo if true, save also the information about the GUI elements + * @param setReadOnly necessary to save a session that has to be turned to read only + */ + void save(bool saveGUIInfo, bool setReadOnly = false); + + /** + * Activate the session + */ + void activate(); + + + private: + + friend class KateViewSpace; + + /** + * @return the session config object + */ + TDEConfig* getConfig() const { return m_config; } + + /** + * create a new filename for a session object + */ + void createFilename(); + + const KateSessionManager &m_manager; // The session manager that handles this session + TQString m_sessionName; + TQString m_filename; + bool m_readOnly; + TQStringList m_documents; // document URLs + KSimpleConfig *m_config; // session config - public: - KateSessionManager(TQObject *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 TQString &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 TQString &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 TQString &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 TQString &path); - - public: - /** - * trigger update of session list - */ - void updateSessionList (); - - private: - /** - * absolute path to dir in home dir where to store the sessions - */ - TQString m_sessionsDir; - - /** - * list of current available sessions - */ - KateSessionList m_sessionList; - - /** - * current active session - */ - KateSession::Ptr m_activeSession; }; - -class KateSessionChooser : public KDialogBase +//END KateSession + + +//BEGIN KateSessionManager +//FIXME (advanced - multiple main windows or multiple Kate instances) +//There should be only one session manager regardless of how many main windows of Kate are open. +//Changes should propagate to all session panels. Different Kate main windows should run different +//sessions. If the user switches to a session already opened in another Kate window, the other window +//should be brought up to the screen (eventually ask user confirmation first). +//This would allow a safe use of multiple Kate main windows/instances without overwriting session information +//among them. Currently the last instance/main window to be closed will overwrite the information previously +//saved by other Kate instances. +/** + * The Kate session manager. It takes care of storing and retrieving each session object + * as well as providing methods to operate on them. + * + * @note The Kate session manager takes ownership of each session object it handles. + */ +//FIXME update the sessions.list file when switching to another session or to a new session +// +//FIXME create new unnamed session, choose 'save' as session switch option. Exit Kate. +// Session is saved without asking for a name +//FIXME improve getStartupOption/getSwitchOption/setSwitchOption using new signal +// KateApp::optionsChanged() +//FIXME add kdDebug statement to ease debugging +class KateSessionManager : public TQObject { Q_OBJECT - public: - KateSessionChooser (TQWidget *parent, const TQString &lastSession); - ~KateSessionChooser (); - - KateSession::Ptr selectedSession (); + public: - bool reopenLastSession (); - - enum { - resultQuit = TQDialog::Rejected, - resultOpen, - resultNew, - resultNone + enum + { + INVALID_SESSION = -1 }; - protected slots: - /** - * open session - */ - void slotUser1 (); - - /** - * new session - */ - void slotUser2 (); - - /** - * quit kate - */ - void slotUser3 (); - - /** - * selection has changed - */ - void selectionChanged (); - - private: - TDEListView *m_sessions; - TQCheckBox *m_useLast; -}; - -class KateSessionOpenDialog : public KDialogBase -{ - Q_OBJECT - - public: - KateSessionOpenDialog (TQWidget *parent); - ~KateSessionOpenDialog (); - - KateSession::Ptr selectedSession (); - - enum { - resultOk, - resultCancel + // Session options on Kate startup + enum + { + STARTUP_NEW = 0, // New session + STARTUP_LAST, // Use last session + STARTUP_MANUAL // Manually choose a session }; - - protected slots: - /** - * cancel pressed - */ - void slotUser1 (); - - /** - * ok pressed - */ - void slotUser2 (); - - private: - TDEListView *m_sessions; + + // Session options on session switch or Kate shutdown + enum + { + SWITCH_DISCARD = 0, // Don't save current session + SWITCH_SAVE, // Save current session + SWITCH_ASK // Ask user what to do + }; + + /** + * get a pointer to the unique KateSessionManager instance. + * If the manager does not exist yet, create it. + */ + static KateSessionManager* self(); + + /** + * Destructor + */ + ~KateSessionManager(); + + /** + * Save session manager info + * @param saveSessions true = sessions info will be saved + * false = all sessions will be discarded + */ + void saveConfig(bool saveSessions); + + /** + * @return the session startup option + * The function checks the config file to see if there was any value update + */ + const int getStartupOption(); + + /** + * @return the session switch option + * The function checks the config file to see if there was any value update + */ + const int getSwitchOption(); + + /** + * Set the new session switch preference + * @param option the new option value. Defaults to SWITCH_ASK if the value is invalid. + * @emit switchOptionChanged + */ + void setSwitchOption(int option); + + /** + * @return the session files folder name + */ + const TQString& getBaseDir() const { return m_baseDir; } + + /** + * @return the number of existing sessions + */ + int getSessionCount() const { return m_sessions.count(); } + + /** + * @return the active session id + */ + int getActiveSessionId() const { return m_activeSessionId; } + + /** + * @return the active session name + */ + const TQString& getActiveSessionName() /*FIXME const*/ { return m_sessions[m_activeSessionId]->getSessionName(); } + + /** + * @param sessionId the id of the session of interest + * @return the name of the specified session + */ + const TQString& getSessionName(int sessionId) /*FIXME const*/; + + /** + * @return a reference to the active session + */ + KateSession* getActiveSession() { return m_sessions[m_activeSessionId]; } + + /** + * @param sessionId the id of the session to return + * @return a reference to the specified session + */ + KateSession* getSessionFromId(int sessionId); + + /** + * Return the session id of the first session whose name matches the + * provided one. In case multiple sessions share the same name, + * the id of the first one found will be returned. + * @param name the session name to look for + * @return the session id of the matching session if it is found, + * otherwise KateSessionManager::INVALID_SESSION. + */ + int getSessionIdFromName(const TQString &name); + + /** + * @return a reference to the sessions list + */ + TQPtrList<KateSession>& getSessionsList() { return m_sessions; } + + /** + * Activate the selected session. + * @param sessionId the id of the session to activate + * @param saveCurr if true, save the current session before activating the new one + * @return whether the session was activated or not + * @emit sessionActivated + */ + bool activateSession(int sessionId, bool saveCurr = true); + + /** + * Create a new session and activate it + * @param sessionName new session name + * @param saveCurr if true, save the current session before activating the new one + * @return the id of the newly created session + * @emit sessionCreated + * @emit sessionDeleted (only when leaving an unstored and unnamed session) + */ + int newSession(const TQString &sessionName = TQString::null, bool saveCurr = true); + + /** + * Create a new session and activate it if required + * @param sessionId the id of the session to clone + * @param sessionName the new session name + * @param activate if true, activate the new session after creation + * @param deleteCurr if true, delete the current session after switching + * @return the id of the newly created session + * @emit sessionCreated + */ + int cloneSession(int sessionId, const TQString &sessionName = TQString::null, + bool activate = true, bool deleteCurr = false); + + /** + * Restore the current active session to the last saved state + */ + void reloadActiveSession() { m_sessions[m_activeSessionId]->load(true); } + + /** + * Restore the last saved session. Can only be used before + * any other session has been activated, i.e. on Kate's startup + * @return whether the session was activated or not + */ + bool restoreLastSession(); + + /** + * Saves the active session + * @emit sessionSaved (through invoked "void saveSession(int)" method) + */ + void saveActiveSession() { saveSession(m_activeSessionId); } + + /** + * Save the specified session + * @param sessionId the id of the session to save + * @emit sessionSaved + */ + void saveSession(int sessionId) { saveSession(sessionId, sessionId == m_activeSessionId); } + + /** + * Delete the specified session + * @param sessionId the id of the session to delete + * @param actSessId the id of the next session to activate. + * If INVALID_SESSION or invalid, create a new empty session. + * This is only meaningful when deleting the current active session. + * @return whether the session has been deleted or not + * @emit sessionDeleted + */ + bool deleteSession(int sessionId, int actSessId); + + /** + * Move the specified session forward in the session list (by one position) + * @param sessionId the id of the session to move + */ + void moveSessionForward(int sessionId); + + /** + * Move the specified session backward in the session list (by one position) + * @param sessionId the id of the session to move + */ + void moveSessionBackward(int sessionId); + + /** + * Rename the specified session + * @param sessionId the id of the session to rename + * @param newSessionName the new session name + * @emit sessionRenamed + */ + void renameSession(int sessionId, const TQString &newSessionName); + + /** + * Set the read only status of the specified session + * @param sessionId the id of the session to modify + * @param readOnly the new read only status + */ + void setSessionReadOnlyStatus(int sessionId, bool readOnly); + + signals: + /** + * Emitted when the session switch option has been set/changed + */ + void switchOptionChanged(); + + /** + * Emitted once a session has been activated + * @param newSessionId the id of the previous active session + * @param oldSessionId the id of the new active session + */ + void sessionActivated(int newSessionId, int oldSessionId); + + /** + * Emitted once a session has been created + * @param sessionId the id of the new session + */ + void sessionCreated(int sessionId); + + /** + * Emitted once a session has been saved + * @param sessionId the id of the saved session + */ + void sessionSaved(int sessionId); + + /** + * Emitted once a session has been deleted + * @param sessionId the id of the deleted session + */ + void sessionDeleted(int sessionId); + + /** + * Emitted once the position of the two sessions have been swapped + * @param sessionIdMin the smallest id of the session couple + * @param sessionIdMax the biggest id of the session couple + */ + void sessionsSwapped(int sessionIdMin, int sessionIdMax); + + /** + * Emitted once a session has been renamed + * @param sessionId the id of the new session + */ + void sessionRenamed(int sessionId); + + + protected: + KateSessionManager(); + + // Session options on Kate startup + enum + { + SO_STARTUP = 0, // session startup option only + SO_SWITCH, // session switch option only + SO_ALL, // session startup and switch options + }; + + /** + * Updated the session startup and switch options + * @param optionType specifies which options needs to be updated + */ + void updateSessionOptions(int optionType); + + /** + * Save the session startup and switch options to the config file + * @param optionType specifies which options needs to be saved + */ + void saveSessionOptions(int optionType); + + /** + * Swap the position of the two specified sessions in the session list + * @param sessionId1 the id of the first session + * @param sessionId2 the id of the second session + * @emit sessionsSwapped + */ + void swapSessionsPosition(int sessionId1, int sessionId2); + + /** + * Save the specified session + * @param sessionId the id of the session to save + * @param saveGUIInfo if true, save also the information about the GUI elements + * @param setReadOnly necessary to save a session that has to be turned to read only + * @emit sessionSaved + */ + void saveSession(int sessionId, bool saveGUIInfo, bool setReadOnly = false); + + + TQString m_baseDir; // folder where session files are stored + TQString m_configFile; // file where the session list config is stored + int m_activeSessionId; // id of the active session + int m_lastSessionId; // id of the last active session before closing Kate + TQPtrList<KateSession> m_sessions; // session list + KSimpleConfig *m_config; // session manager config + int m_startupOption; // session option on Kate startup + int m_switchOption; // session option on session switch or Kate shutdown + + static KateSessionManager *ksm_instance; // the only KateSessionManager instance }; +//END KateSessionManager -class KateSessionManageDialog : public KDialogBase -{ - Q_OBJECT +//BEGIN KateSessionChooserItem +class KateSessionChooserItem : public TDEListViewItem +{ public: - KateSessionManageDialog (TQWidget *parent); - ~KateSessionManageDialog (); + KateSessionChooserItem(TQListView *listview, const TQString &sessionName, const TQString &nDoc, int sessionId) + : TDEListViewItem(listview, sessionName, nDoc), m_sessionId(sessionId) {} - protected slots: - /** - * close pressed - */ - void slotUser1 (); + int getSessionId() { return m_sessionId; } + void setSessionId(int sessionId) { m_sessionId = sessionId; } - /** - * selection has changed - */ - void selectionChanged (); + protected: + int m_sessionId; +}; +//END KateSessionChooserItem - /** - * try to rename session - */ - void rename (); - /** - * try to delete session - */ - void del (); +//BEGIN KateSessionChooser +//FIXME create one single KateSessionChooser and reuse it all the time +class KateSessionChooser : public KDialogBase +{ + Q_OBJECT - private: - /** - * update our list - */ - void updateSessionList (); + public: + enum Result + { + RESULT_NO_OP = TQDialog::Rejected, + RESULT_OPEN_EXISTING, + RESULT_OPEN_NEW, + RESULT_QUIT_KATE + }; - private: - TDEListView *m_sessions; - KPushButton *m_rename; - KPushButton *m_del; -}; + KateSessionChooser(TQWidget *parent); + ~KateSessionChooser() {} -class KateSessionsAction : public TDEActionMenu -{ - Q_OBJECT + int getSelectedSessionId(); // return the session id of the selected session - public: - KateSessionsAction(const TQString& text, TQObject* parent = 0, const char* name = 0); - ~KateSessionsAction (){;}; + protected slots: - public slots: - void slotAboutToShow(); + void slotUser1(); // open existing session + void slotUser2(); // open new session + void slotUser3(); // quit kate + void slotSelectionChanged(); // list selection has changed - void openSession (int i); + protected: + TDEListView *m_listview; }; +//END KateSessionChooser #endif diff --git a/kate/app/katesessionpanel.cpp b/kate/app/katesessionpanel.cpp new file mode 100644 index 000000000..0cf7e235b --- /dev/null +++ b/kate/app/katesessionpanel.cpp @@ -0,0 +1,771 @@ +/* This file is part of the TDE project + Copyright (C) 2015-2016 Michele Calgaro <micheleDOTcalgaro__AT__yahooDOTit> + + 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 "katesessionpanel.h" +#include "katesessionpanel.moc" + +#include "kateapp.h" +#include "katemainwindow.h" +#include "kateviewmanager.h" +#include "katesession.h" + +#include <kiconloader.h> +#include <tdelocale.h> +#include <tdemessagebox.h> +#include <tqlistview.h> +#include <tqlabel.h> + + +namespace +{ + const char *KS_UNNAMED = "Unnamed"; +}; + + +//BEGIN KateSessionNameChooser +//------------------------------------------- +KateSessionNameChooser::KateSessionNameChooser(TQWidget *parent, bool showSwitchTo) + : KDialogBase(parent, "", true, i18n("Session Name Chooser"), KDialogBase::User1 | KDialogBase::User2, + KDialogBase::User2, true, KStdGuiItem::cancel(), KGuiItem(i18n("Continue"), "document-new")), + m_showSwitchTo(showSwitchTo) +{ + TQHBox *page = new TQHBox(this); + //page->setMinimumSize(300, 100); + setMainWidget(page); + + TQVBox *vb = new TQVBox(page); + vb->setSpacing(KDialog::spacingHint()); + + TQLabel *label = new TQLabel(vb); + label->setText("Please type the new session name:"); + + m_sessionNameLE = new TQLineEdit(vb); + m_sessionNameLE->setText(i18n(KS_UNNAMED)); + m_sessionNameLE->setFocus(); + + if (m_showSwitchTo) + { + m_activateCB = new TQCheckBox(i18n("Switch to the new session"), vb, NULL); + m_activateCB->setChecked(true); + } + + connect(m_sessionNameLE, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(slotTextChanged())); + slotTextChanged(); // update button status +} + +//------------------------------------------- +TQString KateSessionNameChooser::getSessionName() +{ + return m_sessionNameLE->text(); +} + +//------------------------------------------- +bool KateSessionNameChooser::getActivateFlag() +{ + if (m_showSwitchTo) + { + return m_activateCB->isChecked(); + } + return false; +} + +//------------------------------------------- +void KateSessionNameChooser::slotUser1() +{ + reject(); +} + +//------------------------------------------- +void KateSessionNameChooser::slotUser2() +{ + accept(); +} + +//------------------------------------------- +void KateSessionNameChooser::slotTextChanged() +{ + enableButton(KDialogBase::User2, !m_sessionNameLE->text().isEmpty()); +} +//END KateSessionNameChooser + + +//BEGIN KateSessionPanelToolBarParent +void KateSessionPanelToolBarParent::setToolBar(TDEToolBar *tbar) +{ + m_tbar = tbar; +} + +//------------------------------------------- +void KateSessionPanelToolBarParent::resizeEvent (TQResizeEvent*) +{ + if (m_tbar) + { + setMinimumHeight(m_tbar->sizeHint().height()); + m_tbar->resize(width(),height()); + } +} +//END KateSessionPanelToolBarParent + + +//BEGIN KateSessionPanel +//------------------------------------------- +KateSessionPanel::KateSessionPanel(KateMainWindow *mainWindow, KateViewManager *viewManager, + TQWidget *parent, const char *name) + : TQVBox(parent, name), m_sessionManager(KateSessionManager::self()), + m_actionCollection(new TDEActionCollection(this)), m_columnName(-1), m_columnPixmap(-1) +{ + // Toolbar + setup_toolbar(); + + // Listview + m_listview = new TDEListView(this); + m_listview->header()->hide(); + m_columnName = m_listview->addColumn("Session name"); + m_columnPixmap = m_listview->addColumn("Pixmap", 24); + m_listview->addColumn("Dummy", 1); // Dummy column, only for nice resizing + m_listview->header()->setResizeEnabled(false, m_columnPixmap); + m_listview->setColumnAlignment(m_columnPixmap, TQt::AlignCenter); + m_listview->setMinimumWidth(m_listview->sizeHint().width()); + m_listview->setSorting(-1); + m_listview->setResizeMode(TQListView::LastColumn); + //m_listview->setRootIsDecorated(true); // FIXME disabled until doc list software is developed + + + connect(m_listview, TQT_SIGNAL(selectionChanged()), + this, TQT_SLOT(slotSelectionChanged())); + connect(m_listview, TQT_SIGNAL(executed(TQListViewItem*)), + this, TQT_SLOT(slotItemExecuted(TQListViewItem*))); + connect(m_listview, TQT_SIGNAL(returnPressed(TQListViewItem*)), + this, TQT_SLOT(slotItemExecuted(TQListViewItem*))); + connect(KateApp::self(), TQT_SIGNAL(optionsChanged()), + this, TQT_SLOT(slotSelectionChanged())); + connect(m_sessionManager, TQT_SIGNAL(switchOptionChanged()), + this, TQT_SLOT(slotSelectionChanged())); + connect(m_sessionManager, TQT_SIGNAL(sessionActivated(int, int)), + this, TQT_SLOT(slotSessionActivated(int, int))); + connect(m_sessionManager, TQT_SIGNAL(sessionCreated(int)), + this, TQT_SLOT(slotSessionCreated(int))); + connect(m_sessionManager, TQT_SIGNAL(sessionDeleted(int)), + this, TQT_SLOT(slotSessionDeleted(int))); + connect(m_sessionManager, TQT_SIGNAL(sessionsSwapped(int, int)), + this, TQT_SLOT(slotSessionsSwapped(int, int))); + connect(m_sessionManager, TQT_SIGNAL(sessionRenamed(int)), + this, TQT_SLOT(slotSessionRenamed(int))); + connect(m_listview, TQT_SIGNAL(itemRenamed(TQListViewItem*)), + this, TQT_SLOT(slotLVSessionRenamed(TQListViewItem*))); + + TQPtrList<KateSession>& sessions = m_sessionManager->getSessionsList(); + for (int idx = sessions.count() - 1; idx >= 0; --idx) + { + new KateSessionPanelItem(m_listview, sessions[idx]->getSessionName(), idx); + if (idx == m_sessionManager->getActiveSessionId()) + { + m_listview->setSelected(m_listview->firstChild(), true); + m_listview->firstChild()->setPixmap(m_columnPixmap, SmallIcon("ok")); + } + } + +} + +//------------------------------------------- +void KateSessionPanel::setup_toolbar() +{ + // Toolbar widget and frame + KateSessionPanelToolBarParent *tbarParent = new KateSessionPanelToolBarParent(this); + m_toolbar = new TDEToolBar(tbarParent, "Kate Session Panel Toolbar", true); + tbarParent->setToolBar(m_toolbar); + m_toolbar->setMovingEnabled(false); + m_toolbar->setFlat(true); + m_toolbar->setIconText(TDEToolBar::IconOnly); + m_toolbar->setIconSize(16); + m_toolbar->setEnableContextMenu(false); + + // Toolbar actions + TDEAction *a; + + a = new TDEAction(i18n("New"), SmallIcon("list-add"), 0, + TQT_TQOBJECT(this), TQT_SLOT(slotNewSession()), m_actionCollection, "session_new"); + a->setWhatsThis(i18n("Create a new session and switch to it.")); + a->plug(m_toolbar); + + a = new TDEAction(i18n("Save"), SmallIcon("document-save"), 0, + TQT_TQOBJECT(this), TQT_SLOT(slotSaveSession()), m_actionCollection, "session_save"); + a->setWhatsThis(i18n("Save the selected session.")); + a->plug(m_toolbar); + + a = new TDEAction(i18n("Save as..."), SmallIcon("document-save-as"), 0, + TQT_TQOBJECT(this), TQT_SLOT(slotSaveSessionAs()), m_actionCollection, "session_save_as"); + a->setWhatsThis(i18n("Save an unsaved session with a new name or clone an already saved session " + "into a new session.")); + a->plug(m_toolbar); + + a = new TDEAction(i18n("Rename"), SmallIcon("edit_user"), 0, + TQT_TQOBJECT(this), TQT_SLOT(slotRenameSession()), m_actionCollection, "session_rename"); + a->setWhatsThis(i18n("Rename the selected session.")); + a->plug(m_toolbar); + + a = new TDEAction(i18n("Delete"), SmallIcon("edit-delete"), 0, + TQT_TQOBJECT(this), TQT_SLOT(slotDeleteSession()), m_actionCollection, "session_delete"); + a->setWhatsThis(i18n("Delete the selected session.")); + a->plug(m_toolbar); + + a = new TDEAction(i18n("Reload"), SmallIcon("reload"), 0, + TQT_TQOBJECT(this), TQT_SLOT(slotReloadSession()), m_actionCollection, "session_reload"); + a->setWhatsThis(i18n("Reload the last saved state of the selected session.")); + a->plug(m_toolbar); + + m_toolbar->insertLineSeparator(); + + a = new TDEAction(i18n("Activate"), SmallIcon("forward"), 0, + TQT_TQOBJECT(this), TQT_SLOT(slotActivateSession()), m_actionCollection, "session_activate"); + a->setWhatsThis(i18n("Activate the selected session.")); + a->plug(m_toolbar); + + TDEToggleAction *tglA = new TDEToggleAction(i18n("Toggle read only"), SmallIcon("encrypted"), 0, + TQT_TQOBJECT(this), TQT_SLOT(slotSessionToggleReadOnly()), m_actionCollection, "session_toggle_read_only"); + tglA->setWhatsThis(i18n("Toggle read only status for the selected session.<p>" + "In a read only session, you can work as usual but the list of documents in the session " + "will not be saved when you exit Kate or switch to another session.<p>" + "You can use this option to create template sessions that you wish to keep unchanged over time.")); + tglA->plug(m_toolbar); + + a = new TDEAction(i18n("Move Up"), SmallIcon("go-up"), 0, + TQT_TQOBJECT(this), TQT_SLOT(slotSessionMoveUp()), m_actionCollection, "session_move_up"); + a->setWhatsThis(i18n("Move up the selected session.")); + a->plug(m_toolbar); + + a = new TDEAction(i18n("Move Down"), SmallIcon("go-down"), 0, + TQT_TQOBJECT(this), TQT_SLOT(slotSessionMoveDown()), m_actionCollection, "session_move_down"); + a->setWhatsThis(i18n("Move down the selected session.")); + a->plug(m_toolbar); +} + +//------------------------------------------- +void KateSessionPanel::slotNewSession() +{ + KateSessionNameChooser *nameChooser = new KateSessionNameChooser(this, false); + int result = nameChooser->exec(); + if (result == TQDialog::Accepted) + { + int res = handleSessionSwitch(); + if (res == KMessageBox::Cancel) + { + return; + } + else + { + m_sessionManager->newSession(nameChooser->getSessionName(), res == KMessageBox::Yes); + } + } +} + +//------------------------------------------- +void KateSessionPanel::slotSaveSession() +{ + KateSessionPanelItem *sessionItem = dynamic_cast<KateSessionPanelItem*>(m_listview->selectedItem()); + if (!sessionItem) + { + return; + } + + int sessId = sessionItem->getSessionId(); + const KateSession *ks = m_sessionManager->getSessionFromId(sessId); + if (!ks) + { + return; + } + + if (ks->isStillVolatile()) + { + // Session has never been saved before. Ask user for a session name first + slotSaveSessionAs(); + } + else + { + m_sessionManager->saveSession(sessId); + slotSelectionChanged(); // Update the toolbar button status + } +} + +//------------------------------------------- +void KateSessionPanel::slotSaveSessionAs() +{ + KateSessionPanelItem *sessionItem = dynamic_cast<KateSessionPanelItem*>(m_listview->selectedItem()); + if (!sessionItem) + { + return; + } + int sessId = sessionItem->getSessionId(); + KateSession *ks = m_sessionManager->getSessionFromId(sessId); + if (!ks) + { + return; + } + + // If the session was never saved or named before, the session will be saved with a new name. + // Otherwise it will be cloned into a new session. + bool cloneSession = !ks->isStillVolatile(); + // Get new session name + KateSessionNameChooser *nameChooser = new KateSessionNameChooser(this, cloneSession); + int result = nameChooser->exec(); + if (result == TQDialog::Accepted) + { + if (!cloneSession) + { + // Save unsaved session + m_sessionManager->renameSession(sessId, nameChooser->getSessionName()); + m_sessionManager->saveSession(sessId); + } + else + { + // Clone session + bool activate = nameChooser->getActivateFlag(); + int activeSessionId = m_sessionManager->getActiveSessionId(); + int res = KMessageBox::Yes; + if (activate && sessId != activeSessionId) + { + // Cloning another session and switching to it at the same time, + // handle session switch correctly + res = handleSessionSwitch(); + if (res == KMessageBox::Cancel) + { + return; + } + } + m_sessionManager->cloneSession(sessId, nameChooser->getSessionName(), activate, res == KMessageBox::No); + } + } + + slotSelectionChanged(); // Update the toolbar button status +} + +//------------------------------------------- +void KateSessionPanel::slotRenameSession() +{ + TQListViewItem *sessionItem = m_listview->selectedItem(); + if (!sessionItem) + { + return; + } + + m_listview->rename(m_listview->selectedItem(), m_columnName); +} + +//------------------------------------------- +void KateSessionPanel::slotDeleteSession() +{ + KateSessionPanelItem *sessionItem = dynamic_cast<KateSessionPanelItem*>(m_listview->selectedItem()); + if (!sessionItem) + { + return; + } + + int result = KMessageBox::warningContinueCancel(this, + i18n("Do you really want to delete the session \"%1\"?").arg(sessionItem->text(0)), + i18n("Delete session"), KStdGuiItem::del()); + if (result == KMessageBox::Continue) + { + int sessionId = sessionItem->getSessionId(); + if (sessionId == m_sessionManager->getActiveSessionId()) + { + // First check if all documents can be closed safely + if (KateApp::self()->activeMainWindow()) + { + if (!KateApp::self()->activeMainWindow()->queryClose_internal()) + return; + } + } + //FIXME add options to let user decide what to do when deleting the current session + //(open previous/next session, create new empty session) + m_sessionManager->deleteSession(sessionId, KateSessionManager::INVALID_SESSION); + } +} + +//------------------------------------------- +void KateSessionPanel::slotReloadSession() +{ + KateSessionPanelItem *sessionItem = dynamic_cast<KateSessionPanelItem*>(m_listview->selectedItem()); + if (!sessionItem) + { + return; + } + int sessId = sessionItem->getSessionId(); + if (sessId != m_sessionManager->getActiveSessionId()) + { + return; + } + + // Restore active session to the last saved state + m_sessionManager->reloadActiveSession(); +} + +//------------------------------------------- +void KateSessionPanel::slotActivateSession() +{ + KateSessionPanelItem *newSessionItem = dynamic_cast<KateSessionPanelItem*>(m_listview->selectedItem()); + if (!newSessionItem) + { + return; + } + + int currSessionId = m_sessionManager->getActiveSessionId(); + int newSessionId = newSessionItem->getSessionId(); + if (newSessionId != currSessionId) + { + int res = handleSessionSwitch(); + if (res == KMessageBox::Cancel) + { + return; + } + else + { + m_sessionManager->activateSession(newSessionId, res == KMessageBox::Yes); + } + } +} + +//------------------------------------------- +void KateSessionPanel::slotSessionToggleReadOnly() +{ + KateSessionPanelItem *sessionItem = dynamic_cast<KateSessionPanelItem*>(m_listview->selectedItem()); + const KateSession *ks(NULL); + if (sessionItem) + { + ks = m_sessionManager->getSessionFromId(sessionItem->getSessionId()); + } + if (!sessionItem || !ks) + { + return; + } + + m_sessionManager->setSessionReadOnlyStatus(sessionItem->getSessionId(), !ks->isReadOnly()); + slotSelectionChanged(); // Update the toolbar button status +} + +//------------------------------------------- +void KateSessionPanel::slotSessionMoveUp() +{ + KateSessionPanelItem *sessionItem = dynamic_cast<KateSessionPanelItem*>(m_listview->selectedItem()); + if (!sessionItem) + { + return; + } + + m_sessionManager->moveSessionBackward(sessionItem->getSessionId()); +} + +//------------------------------------------- +void KateSessionPanel::slotSessionMoveDown() +{ + KateSessionPanelItem *sessionItem = dynamic_cast<KateSessionPanelItem*>(m_listview->selectedItem()); + if (!sessionItem) + { + return; + } + + m_sessionManager->moveSessionForward(sessionItem->getSessionId()); +} + +//------------------------------------------- +void KateSessionPanel::slotItemExecuted(TQListViewItem *item) +{ + if (!item) + { + return; + } + + // First level items are sessions. Executing one, will switch to that session. + // This is only allow when the 'Activate' toolbar button is enabled + if (!item->parent() && + m_actionCollection->action("session_activate")->isEnabled()) + { + slotActivateSession(); + return; + } +} + +//------------------------------------------- +void KateSessionPanel::slotSelectionChanged() +{ + KateSessionPanelItem *sessionItem = dynamic_cast<KateSessionPanelItem*>(m_listview->selectedItem()); + const KateSession *ks(NULL); + if (sessionItem) + { + ks = m_sessionManager->getSessionFromId(sessionItem->getSessionId()); + } + + TDEToggleAction *readOnlyAction = dynamic_cast<TDEToggleAction*>( + m_actionCollection->action("session_toggle_read_only")); + if (!sessionItem || !ks || + m_sessionManager->getSwitchOption() == KateSessionManager::SWITCH_DISCARD) + { + m_actionCollection->action("session_save")->setEnabled(false); + m_actionCollection->action("session_save_as")->setEnabled(false); + m_actionCollection->action("session_rename")->setEnabled(false); + m_actionCollection->action("session_delete")->setEnabled(false); + m_actionCollection->action("session_reload")->setEnabled(false); + m_actionCollection->action("session_activate")->setEnabled(false); + m_actionCollection->action("session_move_up")->setEnabled(false); + m_actionCollection->action("session_move_down")->setEnabled(false); + readOnlyAction->setEnabled(false); + readOnlyAction->setChecked(false); + } + else + { + if (ks->isReadOnly()) + { + // Read only sessions can not be saved or renamed + m_actionCollection->action("session_save")->setEnabled(false); + m_actionCollection->action("session_rename")->setEnabled(false); + m_actionCollection->action("session_delete")->setEnabled(false); + } + else + { + m_actionCollection->action("session_save")->setEnabled(true); + m_actionCollection->action("session_rename")->setEnabled(true); + m_actionCollection->action("session_delete")->setEnabled(true); + } + if (ks->getSessionFilename().isEmpty()) + { + // Unstored sessions can not be made readonly + readOnlyAction->setEnabled(false); + readOnlyAction->setChecked(false); + } + else + { + readOnlyAction->setEnabled(true); + readOnlyAction->setChecked(ks->isReadOnly()); + } + int sessId = sessionItem->getSessionId(); + int activeSessId = m_sessionManager->getActiveSessionId(); + m_actionCollection->action("session_save_as")->setEnabled(true); + m_actionCollection->action("session_reload")->setEnabled(sessId == activeSessId); + m_actionCollection->action("session_activate")->setEnabled(sessId != activeSessId); + m_actionCollection->action("session_move_up")->setEnabled(sessId > 0); + m_actionCollection->action("session_move_down")->setEnabled(sessId < (m_sessionManager->getSessionCount() - 1)); + } + + emit selectionChanged(); +} + +//------------------------------------------- +void KateSessionPanel::slotSessionActivated(int newSessionId, int oldSessionId) +{ + // Move the active session marker + TQListViewItem *item = NULL; + if (oldSessionId != KateSessionManager::INVALID_SESSION) + { + // Old volatile sessions may have already been deleted. + // Remove the marker only for valid sessions. + item = m_listview->firstChild(); + for (int idx = 0; idx < oldSessionId; ++idx) + { + item = item->nextSibling(); + } + item->setPixmap(m_columnPixmap, TQPixmap()); + } + + item = m_listview->firstChild(); + for (int idx = 0; idx < newSessionId; ++idx) + { + item = item->nextSibling(); + } + item->setPixmap(m_columnPixmap, SmallIcon("ok")); + m_listview->setSelected(item, true); + slotSelectionChanged(); // Update the toolbar button status +} + +//------------------------------------------- +void KateSessionPanel::slotSessionCreated(int sessionId) +{ + TQPtrList<KateSession>& sessions = m_sessionManager->getSessionsList(); + new KateSessionPanelItem(m_listview, m_listview->lastItem(), sessions[sessionId]->getSessionName(), + sessionId); +} + +//------------------------------------------- +void KateSessionPanel::slotSessionDeleted(int sessionId) +{ + // delete item from listview + TQListViewItem *item = m_listview->firstChild(); + int idx = 0; + for (; idx < sessionId; ++idx) + { + item = item->nextSibling(); + } + TQListViewItem *nextItem = item->nextSibling(); + delete item; + // update session id of all following items + item = nextItem; + while (item) + { + dynamic_cast<KateSessionPanelItem*>(item)->setSessionId(idx++); + item = item->nextSibling(); + } +} + +//------------------------------------------- +void KateSessionPanel::slotSessionsSwapped(int sessionIdMin, int sessionIdMax) +{ + if (sessionIdMin == sessionIdMax) + { + return; + } + + if (sessionIdMin > sessionIdMax) + { + // this is not executed when the slot is connected to m_sessionManager's + // sessionsSwapped(int, int) signal + int tmp = sessionIdMin; + sessionIdMin = sessionIdMax; + sessionIdMax = tmp; + } + + TQListViewItem *selectedItem = m_listview->selectedItem(); + + // Looks for the previous siblings of the two items + TQListViewItem *siblMin(NULL), *siblMax(NULL), *itemMin(NULL), *itemMax(NULL); + TQListViewItem *currItem = m_listview->firstChild(); + TQListViewItem *nextItem(NULL); + while (currItem) + { + nextItem = currItem->nextSibling(); + KateSessionPanelItem *sessionItem = dynamic_cast<KateSessionPanelItem*>(nextItem); + if (sessionItem->getSessionId() == sessionIdMin) + { + siblMin = currItem; + itemMin = nextItem; + } + else if (sessionItem->getSessionId() == sessionIdMax) + { + siblMax = currItem; + itemMax = nextItem; + break; + } + currItem = nextItem; + } + if (!itemMin) + { + // The sessionIdMin item was the first of the list + itemMin = m_listview->firstChild(); + } + // Remove the two items and place them in their new positions + m_listview->takeItem(itemMax); + m_listview->takeItem(itemMin); + m_listview->insertItem(itemMin); + m_listview->insertItem(itemMax); + itemMax->moveItem(siblMin); + if (siblMax != itemMin) + { + itemMin->moveItem(siblMax); + } + else + { + itemMin->moveItem(itemMax); + } + // Update item's session id + (dynamic_cast<KateSessionPanelItem*>(itemMax))->setSessionId(sessionIdMin); + (dynamic_cast<KateSessionPanelItem*>(itemMin))->setSessionId(sessionIdMax); + + m_listview->setSelected(selectedItem, true); +} + +//------------------------------------------- +void KateSessionPanel::slotSessionRenamed(int sessionId) +{ + TQListViewItem *item = m_listview->firstChild(); + for (int idx = 0; idx < sessionId; ++idx) + { + item = item->nextSibling(); + } + item->setText(m_columnName, m_sessionManager->getSessionName(sessionId)); +} + +//------------------------------------------- +void KateSessionPanel::slotLVSessionRenamed(TQListViewItem *item) +{ + KateSessionPanelItem *sessionItem = dynamic_cast<KateSessionPanelItem*>(item); + if (!sessionItem) + { + return; + } + + m_sessionManager->renameSession(sessionItem->getSessionId(), sessionItem->text(m_columnName)); +} + +//------------------------------------------- +int KateSessionPanel::handleSessionSwitch() +{ + const KateSession *ks = m_sessionManager->getActiveSession(); + int switchOption = m_sessionManager->getSwitchOption(); + if (!ks || switchOption == KateSessionManager::SWITCH_DISCARD) + { + return KMessageBox::No; + } + + if (switchOption == KateSessionManager::SWITCH_ASK) + { + KDialogBase *dlg = new KDialogBase(i18n("Save Session"), + KDialogBase::Yes | KDialogBase::No | KDialogBase::Cancel, + KDialogBase::Cancel, KDialogBase::Cancel, NULL, NULL, true, false, + KStdGuiItem::save(), KStdGuiItem::del(), KStdGuiItem::cancel()); + bool dontAgain = false; + int res = KMessageBox::createKMessageBox(dlg, TQMessageBox::Warning, + i18n("<p>Do you want to save the current session?<p>!!NOTE!!" + "<p>The session will be removed if you choose \"Delete\""), TQStringList(), + i18n("Do not ask again"), &dontAgain, KMessageBox::Notify); + if (res == KDialogBase::Cancel) + { + return KMessageBox::Cancel; + } + if (dontAgain) + { + if (res == KDialogBase::No) + { + m_sessionManager->setSwitchOption(KateSessionManager::SWITCH_DISCARD); + } + else + { + m_sessionManager->setSwitchOption(KateSessionManager::SWITCH_SAVE); + } + } + if (res == KDialogBase::No) + { + return KMessageBox::No; + } + } + + // At this point the session needs to be saved. + // Make sure to handle volatile sessions correctly. + if (ks->isStillVolatile()) + { + KateSessionNameChooser *nameChooser = new KateSessionNameChooser(this, false); + int res = nameChooser->exec(); + if (res == TQDialog::Accepted) + { + m_sessionManager->renameSession(m_sessionManager->getActiveSessionId(), nameChooser->getSessionName()); + } + else + { + return KMessageBox::Cancel; + } + } + + return KMessageBox::Yes; +} +//END KateSessionPanel diff --git a/kate/app/katesessionpanel.h b/kate/app/katesessionpanel.h new file mode 100644 index 000000000..acaec56cd --- /dev/null +++ b/kate/app/katesessionpanel.h @@ -0,0 +1,174 @@ +/* This file is part of the TDE project + Copyright (C) 2015-2016 Michele Calgaro <micheleDOTcalgaro__AT__yahooDOTit> + + 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_SESSIONPANEL_H__ +#define __KATE_SESSIONPANEL_H__ + +/* + The kate session panel displays the available sessions (and their documents) + in a treeview list and allows for quick switching among them. + A toolbar on the top also provides quick access to actions needed + to manage sessions. +*/ + +#include <tqvbox.h> +#include <tdetoolbar.h> +#include <tdelistview.h> +#include <tqframe.h> +#include <tqlineedit.h> +#include <tqcheckbox.h> +#include <kdialogbase.h> + +class KateMainWindow; +class KateViewManager; +class KateSessionManager; +class TDEActionCollection; + + +//BEGIN KateSessionNameChooser +//FIXME create one single KateSessionNameChooser and reuse it all the time +//FIXME improve string to distinguish between new session and saving an unnamed session +class KateSessionNameChooser : public KDialogBase +{ + Q_OBJECT + + public: + + KateSessionNameChooser(TQWidget *parent, bool showSwitchTo); + ~KateSessionNameChooser() {} + + TQString getSessionName(); // return the session name typed by the user + bool getActivateFlag(); // return whether to switch to the new session or not + + protected slots: + + void slotUser1(); // create new session + void slotUser2(); // cancel + void slotTextChanged(); // session name has changed + + protected: + TQLineEdit *m_sessionNameLE; + TQCheckBox *m_activateCB; + bool m_showSwitchTo; // if true, display the m_activateCB checkbox +}; +//BEGIN KateSessionNameChooser + + +//BEGIN KateSessionPanelToolBarParent +class KateSessionPanelToolBarParent: public TQFrame +{ + Q_OBJECT + + public: + KateSessionPanelToolBarParent(TQWidget *parent) : TQFrame(parent), m_tbar(0) {} + ~KateSessionPanelToolBarParent() {} + void setToolBar(TDEToolBar *tbar); + + protected: + virtual void resizeEvent (TQResizeEvent*); + + private: + TDEToolBar *m_tbar; +}; +//END KateSessionPanelToolBarParent + + +//BEGIN KateSessionPanelItem +class KateSessionPanelItem : public TDEListViewItem +{ + public: + KateSessionPanelItem(TQListView *listview, const TQString &sessionName, int sessionId) + : TDEListViewItem(listview, sessionName), m_sessionId(sessionId) {} + KateSessionPanelItem(TQListView *listview, TQListViewItem *after, const TQString &sessionName, int sessionId) + : TDEListViewItem(listview, after, sessionName), m_sessionId(sessionId) {} + + int getSessionId() { return m_sessionId; } + void setSessionId(int sessionId) { m_sessionId = sessionId; } + + protected: + int m_sessionId; +}; +//END KateSessionPanelItem + + +//BEGIN KateSessionPanel +class KateSessionPanel : public TQVBox +{ + Q_OBJECT + + friend class KateMainWindow; + + public: + + KateSessionPanel(KateMainWindow *mainWindow=0, KateViewManager *viewManager=0, + TQWidget *parent=0, const char *name=0); + ~KateSessionPanel() {} + + signals: + /** + * Emitted when the session selection in the panel has changed + */ + void selectionChanged(); + + + public slots: + void slotNewSession(); + void slotSaveSession(); + void slotSaveSessionAs(); + void slotRenameSession(); + void slotDeleteSession(); + void slotReloadSession(); + void slotActivateSession(); + void slotSessionToggleReadOnly(); + void slotSessionMoveUp(); + void slotSessionMoveDown(); + void slotItemExecuted(TQListViewItem *item); + + void slotSelectionChanged(); /** @emit selectionChanged */ + void slotSessionActivated(int newSessionId, int oldSessionId); + void slotSessionCreated(int sessionId); + void slotSessionDeleted(int sessionId); + void slotSessionsSwapped(int sessionIdMin, int sessionIdMax); + void slotSessionRenamed(int sessionId); + void slotLVSessionRenamed(TQListViewItem *item); + + protected: + void setup_toolbar(); + + /* Checks the session switch option. If the choice is 'ask user', + opens a dialog and asks the user what to do. + Returns one of the following: + - KMessageBox::Cancel : the user wants to abort the current operation + - KMessageBox::No : the user wants to discard the session and continue + - KMessageBox::Yes : the user wants to save the session and continue + If the current session is volatile and the session needs to be saved, + it will also ask the user to provide a session name. + */ + int handleSessionSwitch(); + + KateSessionManager *m_sessionManager; + TDEActionCollection *m_actionCollection; + TDEToolBar *m_toolbar; + TDEListView *m_listview; + int m_columnName; + int m_columnPixmap; +}; +//END KateSessionPanel + + +#endif //__KATE_SESSIONPANEL_H__ diff --git a/kate/app/kateviewmanager.cpp b/kate/app/kateviewmanager.cpp index ca361232a..47ece5270 100644 --- a/kate/app/kateviewmanager.cpp +++ b/kate/app/kateviewmanager.cpp @@ -462,7 +462,6 @@ void KateViewManager::setShowFullPath( bool enable ) /** * session config functions */ -// FIXME 3.0 - make those config goups more streamlined: "objN:objN..." void KateViewManager::saveViewConfiguration(TDEConfig *config,const TQString& grp) { // Use the same group name for view configuration as usual for sessions. diff --git a/kate/app/kateviewspace.cpp b/kate/app/kateviewspace.cpp index ebc7a3b97..a4066ee5a 100644 --- a/kate/app/kateviewspace.cpp +++ b/kate/app/kateviewspace.cpp @@ -110,15 +110,16 @@ void KateViewSpace::addView(Kate::View* v, bool show) if ( !m_group.isEmpty() ) { TQString fn = v->getDoc()->url().prettyURL(); - if ( ! fn.isEmpty() ) + if (!fn.isEmpty()) { TQString vgroup = TQString("%1 %2").arg(m_group).arg(fn); - KateSession::Ptr as = KateSessionManager::self()->activeSession (); - if ( as->configRead() && as->configRead()->hasGroup( vgroup ) ) + const KateSession *as = KateSessionManager::self()->getActiveSession(); + TDEConfig *asCfg = as->getConfig(); + if (asCfg && asCfg->hasGroup(vgroup)) { - as->configRead()->setGroup( vgroup ); - v->readSessionConfig ( as->configRead() ); + asCfg->setGroup(vgroup); + v->readSessionConfig(asCfg); } } } diff --git a/kate/data/kateui.rc b/kate/data/kateui.rc index 5368c26c4..260b513b1 100644 --- a/kate/data/kateui.rc +++ b/kate/data/kateui.rc @@ -1,5 +1,5 @@ <!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> -<kpartgui name="kate" version="49"> +<kpartgui name="kate" version="50"> <MenuBar noMerge="1"> <Menu name="file"><text>&File</text> @@ -60,14 +60,19 @@ </Menu> <Menu name="sessions"><text>Sess&ions</text> - <Action name="sessions_new"/> - <Action name="sessions_open"/> - <Action name="sessions_list"/> - <Separator /> - <Action name="sessions_save"/> - <Action name="sessions_save_as"/> - <Separator /> - <Action name="sessions_manage"/> + <Action name="session_list"/> + <Separator/> + <Action name="session_new"/> + <Action name="session_save"/> + <Action name="session_save_as"/> + <Action name="session_rename"/> + <Action name="session_delete"/> + <Action name="session_reload"/> + <Separator/> + <Action name="session_activate"/> + <Action name="session_toggle_read_only"/> + <Action name="session_move_up"/> + <Action name="session_move_down"/> </Menu> <Menu name="settings"><text>&Settings</text> |