Commit accb0040 authored by Daniel Teske's avatar Daniel Teske
Browse files

SessionManager::loadSession inline impl functions and rewrite



The order of actions and thus the state at which the signals are emitted
has changed. The aboutToUnloadSession comes before the actual saving
now. Also the aboutToLoadSession is after restoring values but before
restoring projects and editors.

Change-Id: I3eae66cffae970f00535d8d6e2bb11a6ca645456
Reviewed-by: default avatarhjk <qthjk@ovi.com>
Reviewed-by: default avatarTobias Hunger <tobias.hunger@nokia.com>
parent 19bab2c1
...@@ -318,7 +318,7 @@ BookmarkManager::BookmarkManager() : ...@@ -318,7 +318,7 @@ BookmarkManager::BookmarkManager() :
connect(Core::ICore::instance(), SIGNAL(contextChanged(Core::IContext*,Core::Context)), connect(Core::ICore::instance(), SIGNAL(contextChanged(Core::IContext*,Core::Context)),
this, SLOT(updateActionStatus())); this, SLOT(updateActionStatus()));
connect(ProjectExplorerPlugin::instance()->session(), SIGNAL(sessionLoaded()), connect(ProjectExplorerPlugin::instance()->session(), SIGNAL(sessionLoaded(QString)),
this, SLOT(loadBookmarks())); this, SLOT(loadBookmarks()));
updateActionStatus(); updateActionStatus();
......
...@@ -685,7 +685,7 @@ CppModelManager::CppModelManager(QObject *parent) ...@@ -685,7 +685,7 @@ CppModelManager::CppModelManager(QObject *parent)
connect(session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project *)), connect(session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project *)),
this, SLOT(onAboutToRemoveProject(ProjectExplorer::Project *))); this, SLOT(onAboutToRemoveProject(ProjectExplorer::Project *)));
connect(session, SIGNAL(aboutToUnloadSession()), connect(session, SIGNAL(aboutToUnloadSession(QString)),
this, SLOT(onAboutToUnloadSession())); this, SLOT(onAboutToUnloadSession()));
qRegisterMetaType<CPlusPlus::Document::Ptr>("CPlusPlus::Document::Ptr"); qRegisterMetaType<CPlusPlus::Document::Ptr>("CPlusPlus::Document::Ptr");
......
...@@ -3398,11 +3398,11 @@ void DebuggerPluginPrivate::extensionsInitialized() ...@@ -3398,11 +3398,11 @@ void DebuggerPluginPrivate::extensionsInitialized()
SLOT(fontSettingsChanged(TextEditor::FontSettings))); SLOT(fontSettingsChanged(TextEditor::FontSettings)));
// ProjectExplorer // ProjectExplorer
connect(sessionManager(), SIGNAL(sessionLoaded()), connect(sessionManager(), SIGNAL(sessionLoaded(QString)),
SLOT(sessionLoaded())); SLOT(sessionLoaded()));
connect(sessionManager(), SIGNAL(aboutToSaveSession()), connect(sessionManager(), SIGNAL(aboutToSaveSession()),
SLOT(aboutToSaveSession())); SLOT(aboutToSaveSession()));
connect(sessionManager(), SIGNAL(aboutToUnloadSession()), connect(sessionManager(), SIGNAL(aboutToUnloadSession(QString)),
SLOT(aboutToUnloadSession())); SLOT(aboutToUnloadSession()));
connect(ProjectExplorerPlugin::instance(), SIGNAL(updateRunActions()), connect(ProjectExplorerPlugin::instance(), SIGNAL(updateRunActions()),
SLOT(updateDebugActions())); SLOT(updateDebugActions()));
......
...@@ -174,7 +174,7 @@ AppOutputPane::AppOutputPane() : ...@@ -174,7 +174,7 @@ AppOutputPane::AppOutputPane() :
m_mainWidget->setLayout(layout); m_mainWidget->setLayout(layout);
connect(ProjectExplorerPlugin::instance()->session(), SIGNAL(aboutToUnloadSession()), connect(ProjectExplorerPlugin::instance()->session(), SIGNAL(aboutToUnloadSession(QString)),
this, SLOT(aboutToUnloadSession())); this, SLOT(aboutToUnloadSession()));
connect(ProjectExplorerPlugin::instance(), SIGNAL(settingsChanged()), connect(ProjectExplorerPlugin::instance(), SIGNAL(settingsChanged()),
this, SLOT(updateFromSettings())); this, SLOT(updateFromSettings()));
......
...@@ -356,9 +356,9 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er ...@@ -356,9 +356,9 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
this, SLOT(startupProjectChanged())); this, SLOT(startupProjectChanged()));
connect(d->m_session, SIGNAL(dependencyChanged(ProjectExplorer::Project*,ProjectExplorer::Project*)), connect(d->m_session, SIGNAL(dependencyChanged(ProjectExplorer::Project*,ProjectExplorer::Project*)),
this, SLOT(updateActions())); this, SLOT(updateActions()));
connect(d->m_session, SIGNAL(sessionLoaded()), connect(d->m_session, SIGNAL(sessionLoaded(QString)),
this, SLOT(updateActions())); this, SLOT(updateActions()));
connect(d->m_session, SIGNAL(sessionLoaded()), connect(d->m_session, SIGNAL(sessionLoaded(QString)),
this, SLOT(updateWelcomePage())); this, SLOT(updateWelcomePage()));
d->m_proWindow = new ProjectWindow; d->m_proWindow = new ProjectWindow;
......
...@@ -151,7 +151,7 @@ ProjectTreeWidget::ProjectTreeWidget(QWidget *parent) ...@@ -151,7 +151,7 @@ ProjectTreeWidget::ProjectTreeWidget(QWidget *parent)
connect(m_explorer->session(), SIGNAL(aboutToLoadSession(QString)), connect(m_explorer->session(), SIGNAL(aboutToLoadSession(QString)),
this, SLOT(disableAutoExpand())); this, SLOT(disableAutoExpand()));
connect(m_explorer->session(), SIGNAL(sessionLoaded()), connect(m_explorer->session(), SIGNAL(sessionLoaded(QString)),
this, SLOT(loadExpandData())); this, SLOT(loadExpandData()));
connect(m_explorer->session(), SIGNAL(aboutToSaveSession()), connect(m_explorer->session(), SIGNAL(aboutToSaveSession()),
this, SLOT(saveExpandData())); this, SLOT(saveExpandData()));
......
...@@ -52,7 +52,7 @@ SessionModel::SessionModel(SessionManager *manager, QObject *parent) ...@@ -52,7 +52,7 @@ SessionModel::SessionModel(SessionManager *manager, QObject *parent)
roleNames[ActiveSessionRole] = "activeSession"; roleNames[ActiveSessionRole] = "activeSession";
roleNames[LastSessionRole] = "lastSession"; roleNames[LastSessionRole] = "lastSession";
setRoleNames(roleNames); setRoleNames(roleNames);
connect(manager, SIGNAL(sessionLoaded()), SLOT(resetSessions())); connect(manager, SIGNAL(sessionLoaded(QString)), SLOT(resetSessions()));
} }
int SessionModel::rowCount(const QModelIndex &) const int SessionModel::rowCount(const QModelIndex &) const
......
...@@ -239,7 +239,7 @@ ProjectWindow::ProjectWindow(QWidget *parent) ...@@ -239,7 +239,7 @@ ProjectWindow::ProjectWindow(QWidget *parent)
connect(m_tabWidget, SIGNAL(currentIndexChanged(int,int)), connect(m_tabWidget, SIGNAL(currentIndexChanged(int,int)),
this, SLOT(showProperties(int,int))); this, SLOT(showProperties(int,int)));
connect(session, SIGNAL(sessionLoaded()), this, SLOT(restoreStatus())); connect(session, SIGNAL(sessionLoaded(QString)), this, SLOT(restoreStatus()));
connect(session, SIGNAL(aboutToSaveSession()), this, SLOT(saveStatus())); connect(session, SIGNAL(aboutToSaveSession()), this, SLOT(saveStatus()));
connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)), connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
......
...@@ -52,7 +52,6 @@ ...@@ -52,7 +52,6 @@
#include <utils/listutils.h> #include <utils/listutils.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/persistentsettings.h>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtCore/QDir> #include <QtCore/QDir>
...@@ -119,7 +118,7 @@ SessionManager::SessionManager(QObject *parent) ...@@ -119,7 +118,7 @@ SessionManager::SessionManager(QObject *parent)
SessionManager::~SessionManager() SessionManager::~SessionManager()
{ {
emit aboutToUnloadSession(); emit aboutToUnloadSession(m_sessionName);
} }
...@@ -303,197 +302,6 @@ void SessionManager::removeProject(Project *project) ...@@ -303,197 +302,6 @@ void SessionManager::removeProject(Project *project)
removeProjects(QList<Project*>() << project); removeProjects(QList<Project*>() << project);
} }
bool SessionManager::createImpl(const QString &fileName)
{
Q_ASSERT(!fileName.isEmpty());
if (debug)
qDebug() << "SessionManager - creating new session " << fileName << " ...";
bool success = true;
if (isDefaultVirgin()) {
// do not save initial and virgin default session
} else if (!save() || !clear()) {
success = false;
}
if (success) {
emit aboutToUnloadSession();
m_startupProject = 0;
m_failedProjects.clear();
m_depMap.clear();
m_values.clear();
const QString &sessionName = sessionNameFromFileName(fileName);
emit aboutToLoadSession(sessionName);
m_sessionName = sessionName;
updateWindowTitle();
setStartupProject(0);
if (!isDefaultVirgin()) {
ModeManager::activateMode(QLatin1String(Core::Constants::MODE_EDIT));
ModeManager::setFocusToCurrentMode();
}
emit sessionLoaded();
}
m_virginSession = true;
if (debug)
qDebug() << "SessionManager - creating new session returns " << success;
return success;
}
bool SessionManager::loadImpl(const QString &fileName)
{
Q_ASSERT(!fileName.isEmpty());
if (debug)
qDebug() << "SessionManager - restoring session " << fileName << " ...";
if (isDefaultVirgin()) {
// do not save initial and virgin default session
} else if (!save() || !clear()) {
m_virginSession = false;
if (debug)
qDebug() << "SessionManager - restoring session returned " << false;
return false;
}
m_virginSession = false;
emit aboutToUnloadSession();
m_startupProject = 0;
m_failedProjects.clear();
m_depMap.clear();
m_values.clear();
const QString &sessionName = sessionNameFromFileName(fileName);
emit aboutToLoadSession(sessionName);
m_sessionName = sessionName;
updateWindowTitle();
PersistentSettingsReader reader;
if (!reader.load(fileName)) {
QMessageBox::warning(0, tr("Error while restoring session"),
tr("Could not restore session %1").arg(fileName));
if (debug)
qDebug() << "SessionManager - restoring session returned " << false;
return false;
}
ICore::progressManager()->addTask(m_future.future(), tr("Session"),
QLatin1String("ProjectExplorer.SessionFile.Load"));
const QStringList &keys = reader.restoreValue(QLatin1String("valueKeys")).toStringList();
foreach (const QString &key, keys) {
QVariant value = reader.restoreValue(QLatin1String("value-") + key);
m_values.insert(key, value);
}
QStringList fileList =
reader.restoreValue(QLatin1String("ProjectList")).toStringList();
int openEditorsCount = reader.restoreValue(QLatin1String("OpenEditors")).toInt();
m_future.setProgressRange(0, fileList.count() + openEditorsCount + 2);
m_future.setProgressValue(1);
// indirectly adds projects to session
// Keep projects that failed to load in the session!
m_failedProjects = fileList;
if (!fileList.isEmpty()) {
QString errors;
QList<Project *> projects = ProjectExplorerPlugin::instance()->openProjects(fileList, &errors);
if (!errors.isEmpty())
QMessageBox::critical(Core::ICore::mainWindow(), tr("Failed to open project"), errors);
foreach (Project *p, projects)
m_failedProjects.removeAll(p->file()->fileName());
}
sessionLoadingProgress();
// convert the relative paths in the dependency map to absolute paths
QMap<QString, QVariant> depMap = reader.restoreValue(QLatin1String("ProjectDependencies")).toMap();
QMap<QString, QVariant>::const_iterator i = depMap.constBegin();
while (i != depMap.constEnd()) {
const QString &key = i.key();
if (m_failedProjects.contains(key))
continue;
QStringList values;
foreach (const QString &value, i.value().toStringList()) {
if (!m_failedProjects.contains(value))
values << value;
}
m_depMap.insert(key, values);
++i;
}
// find and set the startup project
const QString startupProject = reader.restoreValue(QLatin1String("StartupProject")).toString();
if (!startupProject.isEmpty()) {
const QString startupProjectPath = startupProject;
foreach (Project *pro, m_projects) {
if (QDir::cleanPath(pro->file()->fileName()) == startupProjectPath) {
m_startupProject = pro;
break;
}
}
if (!m_startupProject)
qWarning() << "Could not find startup project" << startupProjectPath;
}
const QVariant &editorsettings = reader.restoreValue(QLatin1String("EditorSettings"));
if (editorsettings.isValid()) {
connect(ICore::editorManager(), SIGNAL(editorOpened(Core::IEditor *)),
this, SLOT(sessionLoadingProgress()));
ICore::editorManager()->restoreState(
QByteArray::fromBase64(editorsettings.toByteArray()));
disconnect(ICore::editorManager(), SIGNAL(editorOpened(Core::IEditor *)),
this, SLOT(sessionLoadingProgress()));
}
m_future.reportFinished();
m_future = QFutureInterface<void>();
// we emit this signal here
emit startupProjectChanged(m_startupProject);
QStringList failedProjects = m_failedProjects;
if (!failedProjects.isEmpty()) {
QString fileList =
QDir::toNativeSeparators(failedProjects.join(QLatin1String("<br>")));
QMessageBox * box = new QMessageBox(QMessageBox::Warning,
tr("Failed to restore project files"),
tr("Could not restore the following project files:<br><b>%1</b>").
arg(fileList));
QPushButton * keepButton = new QPushButton(tr("Keep projects in Session"), box);
QPushButton * removeButton = new QPushButton(tr("Remove projects from Session"), box);
box->addButton(keepButton, QMessageBox::AcceptRole);
box->addButton(removeButton, QMessageBox::DestructiveRole);
box->exec();
if (box->clickedButton() == removeButton)
m_failedProjects.clear();
}
// restore the active mode
QString modeIdentifier = value(QLatin1String("ActiveMode")).toString();
if (modeIdentifier.isEmpty())
modeIdentifier = QLatin1String(Core::Constants::MODE_EDIT);
ModeManager::activateMode(modeIdentifier);
ModeManager::setFocusToCurrentMode();
emit sessionLoaded();
if (debug)
qDebug() << "SessionManager - restoring session returned " << true;
return true;
}
bool SessionManager::save() bool SessionManager::save()
{ {
if (debug) if (debug)
...@@ -860,13 +668,6 @@ QString SessionManager::sessionNameToFileName(const QString &session) const ...@@ -860,13 +668,6 @@ QString SessionManager::sessionNameToFileName(const QString &session) const
return ICore::userResourcePath() + QLatin1Char('/') + session + QLatin1String(".qws"); return ICore::userResourcePath() + QLatin1Char('/') + session + QLatin1String(".qws");
} }
QString SessionManager::sessionNameFromFileName(const QString &fileName) const
{
const int slash = fileName.lastIndexOf(QLatin1Char('/'));
Q_ASSERT(slash != -1 && fileName.endsWith(QLatin1String(".qws")));
return fileName.mid(slash + 1, fileName.length() - slash - 5); // Exclude .qws
}
/*! /*!
\brief Just creates a new session (Does not actually create the file). \brief Just creates a new session (Does not actually create the file).
*/ */
...@@ -892,7 +693,6 @@ bool SessionManager::renameSession(const QString &original, const QString &newNa ...@@ -892,7 +693,6 @@ bool SessionManager::renameSession(const QString &original, const QString &newNa
/*! /*!
\brief Deletes session name from session list and file from disk. \brief Deletes session name from session list and file from disk.
*/ */
bool SessionManager::deleteSession(const QString &session) bool SessionManager::deleteSession(const QString &session)
{ {
if (!m_sessions.contains(session)) if (!m_sessions.contains(session))
...@@ -919,9 +719,101 @@ bool SessionManager::cloneSession(const QString &original, const QString &clone) ...@@ -919,9 +719,101 @@ bool SessionManager::cloneSession(const QString &original, const QString &clone)
return false; return false;
} }
void SessionManager::restoreValues(const Utils::PersistentSettingsReader &reader)
{
const QStringList &keys = reader.restoreValue(QLatin1String("valueKeys")).toStringList();
foreach (const QString &key, keys) {
QVariant value = reader.restoreValue(QLatin1String("value-") + key);
m_values.insert(key, value);
}
}
void SessionManager::restoreDependencies(const Utils::PersistentSettingsReader &reader)
{
QMap<QString, QVariant> depMap = reader.restoreValue(QLatin1String("ProjectDependencies")).toMap();
QMap<QString, QVariant>::const_iterator i = depMap.constBegin();
while (i != depMap.constEnd()) {
const QString &key = i.key();
if (m_failedProjects.contains(key))
continue;
QStringList values;
foreach (const QString &value, i.value().toStringList()) {
if (!m_failedProjects.contains(value))
values << value;
}
m_depMap.insert(key, values);
++i;
}
}
void SessionManager::askUserAboutFailedProjects()
{
QStringList failedProjects = m_failedProjects;
if (!failedProjects.isEmpty()) {
QString fileList =
QDir::toNativeSeparators(failedProjects.join(QLatin1String("<br>")));
QMessageBox * box = new QMessageBox(QMessageBox::Warning,
tr("Failed to restore project files"),
tr("Could not restore the following project files:<br><b>%1</b>").
arg(fileList));
QPushButton * keepButton = new QPushButton(tr("Keep projects in Session"), box);
QPushButton * removeButton = new QPushButton(tr("Remove projects from Session"), box);
box->addButton(keepButton, QMessageBox::AcceptRole);
box->addButton(removeButton, QMessageBox::DestructiveRole);
box->exec();
if (box->clickedButton() == removeButton)
m_failedProjects.clear();
}
}
void SessionManager::restoreStartupProject(const Utils::PersistentSettingsReader &reader)
{
const QString startupProject = reader.restoreValue(QLatin1String("StartupProject")).toString();
if (!startupProject.isEmpty()) {
const QString startupProjectPath = startupProject;
foreach (Project *pro, m_projects) {
if (QDir::cleanPath(pro->file()->fileName()) == startupProjectPath) {
setStartupProject(m_startupProject);
break;
}
}
if (!m_startupProject)
qWarning() << "Could not find startup project" << startupProjectPath;
}
}
void SessionManager::restoreEditors(const Utils::PersistentSettingsReader &reader)
{
const QVariant &editorsettings = reader.restoreValue(QLatin1String("EditorSettings"));
if (editorsettings.isValid()) {
connect(ICore::editorManager(), SIGNAL(editorOpened(Core::IEditor *)),
this, SLOT(sessionLoadingProgress()));
ICore::editorManager()->restoreState(
QByteArray::fromBase64(editorsettings.toByteArray()));
disconnect(ICore::editorManager(), SIGNAL(editorOpened(Core::IEditor *)),
this, SLOT(sessionLoadingProgress()));
}
}
/*! /*!
\brief Loads a session, takes a session name (not filename). \brief Loads a session, takes a session name (not filename).
*/ */
void SessionManager::restoreProjects(const QStringList &fileList)
{
// indirectly adds projects to session
// Keep projects that failed to load in the session!
m_failedProjects = fileList;
if (!fileList.isEmpty()) {
QString errors;
QList<Project *> projects = ProjectExplorerPlugin::instance()->openProjects(fileList, &errors);
if (!errors.isEmpty())
QMessageBox::critical(Core::ICore::mainWindow(), tr("Failed to open project"), errors);
foreach (Project *p, projects)
m_failedProjects.removeAll(p->file()->fileName());
}
}
bool SessionManager::loadSession(const QString &session) bool SessionManager::loadSession(const QString &session)
{ {
...@@ -934,12 +826,80 @@ bool SessionManager::loadSession(const QString &session) ...@@ -934,12 +826,80 @@ bool SessionManager::loadSession(const QString &session)
if (!sessions().contains(session)) if (!sessions().contains(session))
return false; return false;
// Try loading the file
QString fileName = sessionNameToFileName(session); QString fileName = sessionNameToFileName(session);
if (QFileInfo(fileName).exists()) PersistentSettingsReader reader;
return loadImpl(fileName); if (QFileInfo(fileName).exists()) {
if (!reader.load(fileName)) {
QMessageBox::warning(0, tr("Error while restoring session"),
tr("Could not restore session %1").arg(fileName));
return false;
}
}
// Allow everyone to set something in the session and before saving
emit aboutToUnloadSession(m_sessionName);
if (!isDefaultVirgin()) {
if (!save())
return false;
}
// Clean up
if (!ICore::editorManager()->closeAllEditors())
return false;
setStartupProject(0);
removeProjects(projects());
m_failedProjects.clear();
m_depMap.clear();
m_values.clear();
// Create a new session with that name m_sessionName = session;
return createImpl(sessionNameToFileName(session)); updateWindowTitle();
if (QFileInfo(fileName).exists()) {
m_virginSession = false;
ICore::progressManager()->addTask(m_future.future(), tr("Session"),
QLatin1String("ProjectExplorer.SessionFile.Load"));
restoreValues(reader);
emit aboutToLoadSession(session);
QStringList fileList =
reader.restoreValue(QLatin1String("ProjectList")).toStringList();
int openEditorsCount = reader.restoreValue(QLatin1String("OpenEditors")).toInt();
m_future.setProgressRange(0, fileList.count() + openEditorsCount + 2);
m_future.setProgressValue(1);
restoreProjects(fileList);
sessionLoadingProgress();
restoreDependencies(reader);
restoreStartupProject(reader);
restoreEditors(reader);
m_future.reportFinished();
m_future = QFutureInterface<void>();
// restore the active mode
QString modeIdentifier = value(QLatin1String("ActiveMode")).toString();
if (modeIdentifier.isEmpty())
modeIdentifier = QLatin1String(Core::Constants::MODE_EDIT);
ModeManager::activateMode(modeIdentifier);
ModeManager::setFocusToCurrentMode();
} else {
ModeManager::activateMode(QLatin1String(Core::Constants::MODE_EDIT));
ModeManager::setFocusToCurrentMode();
}
emit sessionLoaded(session);
// Starts a event loop, better do that at the very end
askUserAboutFailedProjects();
return true;
} }
QString SessionManager::lastSession() const QString SessionManager::lastSession() const
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <QtCore/QStringList> #include <QtCore/QStringList>
#include <QtCore/QMap> #include <QtCore/QMap>
#include <QtCore/QFutureInterface> #include <QtCore/QFutureInterface>
#include <utils/persistentsettings.h>