Kate session panel: fixed handling of volatile sessions. Also bug fixes and improved model-view code separation

Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
pull/2/head
Michele Calgaro 8 years ago
parent 749b05ce92
commit 074f8c7ccb

@ -1 +1 @@
Subproject commit 1d8a7873c0e0660c58a2d0d7b054d216d5f06b0a
Subproject commit 416e4baaa96058a323968657ee51d5eb0ff0c5c6

@ -172,7 +172,7 @@ bool KateApp::startupKate()
}
else
{
sessionManager()->newSession(sessName, true);
sessionManager()->newSession(sessName);
}
}
else

@ -71,7 +71,7 @@ namespace
const char *KSM_DIR = "kate/sessions";
const char *KSM_FILE = "sessions.list";
const char *KSM_SESSIONS_COUNT = "Sessions count";
const char *KSM_ACTIVE_SESSION_ID = "Active session id";
const char *KSM_LAST_SESSION_ID = "Last session id";
const char *KSM_SESSIONS_LIST = "Sessions list";
}
@ -90,7 +90,12 @@ KateSession::KateSession(const KateSession &session, const TQString &newSessionN
m_readOnly(false), m_documents(session.m_documents), m_config(NULL)
{
createFilename();
m_config = dynamic_cast<KSimpleConfig*>(session.m_config->copyTo(m_filename));
if (session.m_config)
{
m_config = new KSimpleConfig(m_filename);
session.m_config->copyTo(m_filename, m_config);
m_config->sync();
}
}
//------------------------------------
@ -108,6 +113,12 @@ void KateSession::setSessionName(const TQString &sessionName)
m_sessionName = sessionName.isEmpty() ? i18n(KS_UNNAMED) : sessionName;
}
//------------------------------------
bool KateSession::isStillVolatile() const
{
return m_filename.isEmpty() && m_sessionName == i18n(KS_UNNAMED);
}
//------------------------------------
void KateSession::load(bool includeGUIInfo)
{
@ -167,7 +178,7 @@ void KateSession::load(bool includeGUIInfo)
m_sessionName = i18n(KS_UNNAMED);
}
// Update e all current documents if necessary
// Update all current documents if necessary
if (includeGUIInfo)
{
activate();
@ -238,31 +249,31 @@ void KateSession::activate()
{
KateDocManager::self()->closeAllDocuments();
}
Kate::Document::setOpenErrorDialogsActivated(false);
if (m_config)
{
KateApp::self()->documentManager()->restoreDocumentList(m_config);
}
// load main windows info, if it exists
if (m_config && m_config->hasGroup(KS_OPEN_MAINWINDOWS))
{
m_config->setGroup(KS_OPEN_MAINWINDOWS);
int mwCount = m_config->readUnsignedNumEntry(KS_COUNT, 1);
for (int i=0; i<mwCount; ++i)
// load main windows info, if it exists
if (m_config->hasGroup(KS_OPEN_MAINWINDOWS))
{
if (i >= (int)KateApp::self()->mainWindows())
{
KateApp::self()->newMainWindow(m_config, TQString("MainWindow%1").arg(i));
}
else
m_config->setGroup(KS_OPEN_MAINWINDOWS);
int mwCount = m_config->readUnsignedNumEntry(KS_COUNT, 1);
for (int i = 0; i < mwCount; ++i)
{
m_config->setGroup(TQString("MainWindow%1").arg(i));
KateApp::self()->mainWindow(i)->readProperties(m_config);
if (i >= (int)KateApp::self()->mainWindows())
{
KateApp::self()->newMainWindow(m_config, TQString("MainWindow%1").arg(i));
}
else
{
m_config->setGroup(TQString("MainWindow%1").arg(i));
KateApp::self()->mainWindow(i)->readProperties(m_config);
}
}
}
}
Kate::Document::setOpenErrorDialogsActivated(true);
}
@ -310,7 +321,7 @@ KateSessionManager* KateSessionManager::self()
//------------------------------------
KateSessionManager::KateSessionManager() :
m_baseDir(locateLocal("data", KSM_DIR)+"/"), m_configFile(m_baseDir + KSM_FILE),
m_activeSessionId(0), m_firstActivation(true), m_sessions(), m_config(NULL)
m_activeSessionId(INVALID_SESSION), m_lastSessionId(INVALID_SESSION), m_sessions(), m_config(NULL)
{
m_sessions.setAutoDelete(true);
@ -321,7 +332,7 @@ KateSessionManager::KateSessionManager() :
m_config = new KSimpleConfig(m_configFile);
m_config->setGroup(KSM_SESSIONS_LIST);
sessionsCount = m_config->readNumEntry(KSM_SESSIONS_COUNT, 0);
m_activeSessionId = m_config->readNumEntry(KSM_ACTIVE_SESSION_ID, 0);
m_lastSessionId = m_config->readNumEntry(KSM_LAST_SESSION_ID, INVALID_SESSION);
for (int i = 0; i < sessionsCount; ++i)
{
TQString urlStr = m_config->readEntry(TQString("URL_%1").arg(i));
@ -347,19 +358,19 @@ KateSessionManager::KateSessionManager() :
{
m_sessions.append(new KateSession(*this, TQString::null, TQString::null));
}
if (m_activeSessionId < 0 || m_activeSessionId >= (int)m_sessions.count())
if (m_lastSessionId < 0 || m_lastSessionId >= (int)m_sessions.count())
{
m_activeSessionId = 0; // Invalid active session was detected. Use first in the list
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 void KateApp::restoreKate()
// will be activated by KateApp::startupKate() or KateApp::restoreKate()
}
//------------------------------------
KateSessionManager::~KateSessionManager()
{
saveConfig();
saveConfig(true);
if (m_config)
{
delete m_config;
@ -376,7 +387,7 @@ KateSessionManager::~KateSessionManager()
// FIXME An option need to be added to Configure Kate -> Sessions to allow Kate to ask about
// saving unnamed sessions before closing the current session. Default value is off as per
// point above.
void KateSessionManager::saveConfig()
void KateSessionManager::saveConfig(bool saveSessions)
{
if (!m_config)
{
@ -388,11 +399,14 @@ void KateSessionManager::saveConfig()
}
m_config->setGroup(KSM_SESSIONS_LIST);
m_config->writeEntry(KSM_SESSIONS_COUNT, m_sessions.count());
m_config->writeEntry(KSM_ACTIVE_SESSION_ID, m_activeSessionId);
m_config->writeEntry(KSM_LAST_SESSION_ID, m_activeSessionId);
for (int i = 0; i < (int)m_sessions.count(); ++i)
{
// Save the session first, to make sure a new session has an associated file
m_sessions[i]->save(false);
//FIXME need to consider when sessions has to be saved.
if (saveSessions)
{
saveSession(i, false, false);
}
m_config->writeEntry(TQString("URL_%1").arg(i), m_sessions[i]->getSessionFilename());
}
m_config->sync();
@ -424,7 +438,7 @@ KateSession* KateSessionManager::getSessionFromId(int sessionId)
int KateSessionManager::getSessionIdFromName(const TQString &name)
{
if (name.isEmpty())
return KateSessionManager::INVALID_SESSION;
return INVALID_SESSION;
for (int i = 0; i < (int)m_sessions.count(); ++i)
{
@ -432,23 +446,24 @@ int KateSessionManager::getSessionIdFromName(const TQString &name)
return i;
}
return KateSessionManager::INVALID_SESSION;
return INVALID_SESSION;
}
//------------------------------------
bool KateSessionManager::activateSession(int sessionId, bool saveCurr)
{
if (sessionId < 0)
if (sessionId < 0 || sessionId >= (int)m_sessions.count())
{
return false;
}
if (!m_firstActivation && sessionId == m_activeSessionId)
if (sessionId == m_activeSessionId)
{
return true;
}
if (!m_firstActivation)
int oldSessionId = m_activeSessionId;
if (m_activeSessionId != INVALID_SESSION)
{
// Do this only if a session has already been activated earlier,
if (KateApp::self()->activeMainWindow())
@ -457,30 +472,38 @@ bool KateSessionManager::activateSession(int sessionId, bool saveCurr)
if (!KateApp::self()->activeMainWindow()->queryClose_internal())
return false;
}
if (saveCurr && m_activeSessionId != INVALID_SESSION)
if (saveCurr)
{
m_sessions[m_activeSessionId]->save(true);
saveSession(m_activeSessionId, true);
}
else if (m_sessions[m_activeSessionId]->isStillVolatile())
{
// Automatically delete unstored and unnamed sessions when activating another one
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;
}
}
int oldSessionId = m_activeSessionId;
m_activeSessionId = sessionId;
m_sessions[sessionId]->activate();
m_firstActivation = false;
m_lastSessionId = INVALID_SESSION;
emit sessionActivated(m_activeSessionId, oldSessionId);
return true;
}
//------------------------------------
int KateSessionManager::newSession(const TQString &sessionName, bool activate)
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);
if (activate)
{
activateSession(newSessionId, m_activeSessionId != INVALID_SESSION);
}
activateSession(newSessionId, saveCurr);
return newSessionId;
}
@ -498,9 +521,12 @@ int KateSessionManager::cloneSession(int sessionId, const TQString &sessionName,
// 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)
m_sessions[newSessionId]->save(true);
reloadActiveSession();
/* saveSession(newSessionId, sessionId == m_activeSessionId);
if (sessionId == m_activeSessionId)
{
reloadActiveSession();
}
*/
if (activate)
{
activateSession(newSessionId, m_activeSessionId != INVALID_SESSION);
@ -511,27 +537,26 @@ int KateSessionManager::cloneSession(int sessionId, const TQString &sessionName,
//------------------------------------
bool KateSessionManager::restoreLastSession()
{
if (!m_firstActivation)
if (m_activeSessionId != INVALID_SESSION)
{
return false;
}
// NOTE: m_activeSessionId contains the id of the last active session
return activateSession(m_activeSessionId, false);
return activateSession(m_lastSessionId, false);
}
//-------------------------------------------
void KateSessionManager::saveSession(int sessionId)
void KateSessionManager::saveSession(int sessionId, bool saveGUIInfo, bool setReadOnly)
{
if (sessionId < 0 || sessionId >= (int)m_sessions.count())
{
return;
}
m_sessions[sessionId]->save(sessionId == m_activeSessionId);
m_sessions[sessionId]->save(saveGUIInfo, setReadOnly);
emit sessionSaved(sessionId);
}
//-------------------------------------------
bool KateSessionManager::deleteSession(int sessionId)
bool KateSessionManager::deleteSession(int sessionId, int actSessId)
{
if (sessionId < 0 || sessionId >= (int)m_sessions.count())
{
@ -555,10 +580,16 @@ bool KateSessionManager::deleteSession(int sessionId)
m_activeSessionId = INVALID_SESSION;
}
emit sessionDeleted(sessionId);
// if the active session was deleted, create a new unnamed session and activate it
if (m_activeSessionId == INVALID_SESSION)
{
newSession();
if (m_sessions.count() > 0 && actSessId >= 0 && actSessId < (int)m_sessions.count())
{
activateSession(actSessId, false);
}
else
{
newSession();
}
}
return true;
@ -646,7 +677,7 @@ void KateSessionManager::setSessionReadOnlyStatus(int sessionId, bool readOnly)
m_sessions[sessionId]->setReadOnly(readOnly);
// Session is saved one last time when making it read only
m_sessions[sessionId]->save(sessionId == m_activeSessionId, true);
saveSession(sessionId, sessionId == m_activeSessionId, true);
}
//END KateSessionManager

@ -98,6 +98,12 @@ class KateSession
*/
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
*/
@ -163,8 +169,6 @@ class KateSession
* @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 a new unnamed session and switch to another session. The first session is saved without
//asking the user for a new session name. This is wrong.
class KateSessionManager : public TQObject
{
Q_OBJECT
@ -187,11 +191,6 @@ class KateSessionManager : public TQObject
*/
~KateSessionManager();
/**
* Save session manager info
*/
void saveConfig();
/**
* @return the session files folder name
*/
@ -249,13 +248,14 @@ class KateSessionManager : public TQObject
bool activateSession(int sessionId, bool saveCurr = true);
/**
* Create a new session and activate it if required
* Create a new session and activate it
* @param sessionName new session name
* @param activate if true, activate the new session after creation
* @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 activate = true);
int newSession(const TQString &sessionName = TQString::null, bool saveCurr = true);
/**
* Create a new session and activate it if required
@ -290,15 +290,18 @@ class KateSessionManager : public TQObject
* @param sessionId the id of the session to save
* @emit sessionSaved
*/
void saveSession(int sessionId);
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);
bool deleteSession(int sessionId, int actSessId);
/**
* Move the specified session forward in the session list (by one position)
@ -370,6 +373,12 @@ class KateSessionManager : public TQObject
protected:
KateSessionManager();
/**
* Save session manager info
* @param saveSessions if true, all sessions will be saved again
*/
void saveConfig(bool saveSessions);
/**
* Swap the position of the two specified sessions in the session list
* @param sessionId1 the id of the first session
@ -378,11 +387,20 @@ class KateSessionManager : public TQObject
*/
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; // index of the active session
bool m_firstActivation; // true until at least one session has been activated
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
@ -408,6 +426,7 @@ class KateSessionChooserItem : public TDEListViewItem
//BEGIN KateSessionChooser
//FIXME create one single KateSessionChooser and reuse it all the time
class KateSessionChooser : public KDialogBase
{
Q_OBJECT

@ -19,6 +19,7 @@
#include "katesessionpanel.h"
#include "katesessionpanel.moc"
#include "kateapp.h"
#include "katemainwindow.h"
#include "kateviewmanager.h"
#include "katesession.h"
@ -195,7 +196,7 @@ void KateSessionPanel::setup_toolbar()
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."));
a->setWhatsThis(i18n("Create a new session and switch to it."));
a->plug(m_toolbar);
a = new TDEAction(i18n("Save"), SmallIcon("document-save"), 0,
@ -253,13 +254,20 @@ void KateSessionPanel::setup_toolbar()
//-------------------------------------------
void KateSessionPanel::slotNewSession()
{
KateSessionNameChooser *nameChooser = new KateSessionNameChooser(this, true);
KateSessionNameChooser *nameChooser = new KateSessionNameChooser(this, false);
int result = nameChooser->exec();
if (result == TQDialog::Accepted)
{
m_sessionManager->newSession(nameChooser->getSessionName(), nameChooser->getActivateFlag());
int res = handleVolatileSession();
if (res == KMessageBox::Cancel)
{
return;
}
else
{
m_sessionManager->newSession(nameChooser->getSessionName(), res == KMessageBox::Yes);
}
}
delete nameChooser;
}
//-------------------------------------------
@ -278,7 +286,7 @@ void KateSessionPanel::slotSaveSession()
return;
}
if (ks->getSessionFilename().isEmpty() && ks->getSessionName() == i18n(KS_UNNAMED))
if (ks->isStillVolatile())
{
// Session has never been saved before. Ask user for a session name first
slotSaveSessionAs();
@ -305,15 +313,9 @@ void KateSessionPanel::slotSaveSessionAs()
return;
}
// If the session was never saved before, the session will be saved with a new name.
// If the session was already saved once, it will be cloned into a new session.
bool cloneSession = true;
//FIXME replace ks->getSessionFilename().isEmpty() with a function that tests for m_fileExists
if (ks->getSessionFilename().isEmpty() && ks->getSessionName() == i18n(KS_UNNAMED))
{
// Session has never been saved before.
cloneSession = false;
}
// If the session was never saved or named before, the session will be saved with a new name.
// If the session was already saved or named once, 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();
@ -332,7 +334,6 @@ void KateSessionPanel::slotSaveSessionAs()
}
}
delete nameChooser;
slotSelectionChanged(); // Update the toolbar button status
}
@ -358,11 +359,23 @@ void KateSessionPanel::slotDeleteSession()
}
int result = KMessageBox::warningContinueCancel(this,
i18n("Do you really want to delete the session '%1'?").arg(sessionItem->text(0)),
i18n("Do you really want to delete the session \"%1\"?").arg(sessionItem->text(0)),
i18n("Delete session"), KStdGuiItem::del());
if (result == KMessageBox::Continue)
{
m_sessionManager->deleteSession(sessionItem->getSessionId());
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);
}
}
@ -397,7 +410,15 @@ void KateSessionPanel::slotActivateSession()
int newSessionId = newSessionItem->getSessionId();
if (newSessionId != currSessionId)
{
m_sessionManager->activateSession(newSessionId);
int res = handleVolatileSession();
if (res == KMessageBox::Cancel)
{
return;
}
else
{
m_sessionManager->activateSession(newSessionId, res == KMessageBox::Yes);
}
}
}
@ -520,12 +541,18 @@ void KateSessionPanel::slotSelectionChanged()
void KateSessionPanel::slotSessionActivated(int newSessionId, int oldSessionId)
{
// Move the active session marker
TQListViewItem *item = m_listview->firstChild();
for (int idx = 0; idx < oldSessionId; ++idx)
{
item = item->nextSibling();
}
item->setPixmap(m_columnPixmap, TQPixmap());
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)
@ -654,4 +681,32 @@ void KateSessionPanel::slotLVSessionRenamed(TQListViewItem *item)
m_sessionManager->renameSession(sessionItem->getSessionId(), sessionItem->text(m_columnName));
}
//-------------------------------------------
int KateSessionPanel::handleVolatileSession()
{
const KateSession *ks = m_sessionManager->getActiveSession();
if (!ks || !ks->isStillVolatile())
{
return (!ks ? KMessageBox::No : KMessageBox::Yes);
}
int msgres = KMessageBox::warningYesNoCancel(this, i18n("<p>You are leaving a volatile session."
"<p>Do you want to save or discard it?").arg(ks->getSessionName()),
i18n("Close session"), KStdGuiItem::save(), KStdGuiItem::discard());
if (msgres == KMessageBox::Yes)
{
KateSessionNameChooser *nameChooser = new KateSessionNameChooser(this, false);
int result = nameChooser->exec();
if (result == TQDialog::Accepted)
{
m_sessionManager->renameSession(m_sessionManager->getActiveSessionId(), nameChooser->getSessionName());
}
else
{
msgres = KMessageBox::Cancel;
}
}
return msgres;
}
//END KateSessionPanel

@ -41,6 +41,7 @@ class TDEActionCollection;
//BEGIN KateSessionNameChooser
//FIXME create one single KateSessionNameChooser and reuse it all the time
class KateSessionNameChooser : public KDialogBase
{
Q_OBJECT
@ -137,8 +138,19 @@ class KateSessionPanel : public TQVBox
void slotSessionRenamed(int sessionId);
void slotLVSessionRenamed(TQListViewItem *item);
private:
protected:
void setup_toolbar();
/* In case the current session is still volatile, asks the user whether
he wants to save or discard the session.
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
In case the user decides to save the session, the function also sets
the new session name provided in the dialog box.
*/
int handleVolatileSession();
KateMainWindow *m_mainWin;
KateViewManager *m_viewManager;

Loading…
Cancel
Save