2009-02-25 09:15:00 +01:00
|
|
|
/**************************************************************************
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator
|
|
|
|
|
**
|
2012-01-26 18:33:46 +01:00
|
|
|
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2011-11-02 15:59:12 +01:00
|
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** GNU Lesser General Public License Usage
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2011-04-13 08:42:33 +02:00
|
|
|
** This file may be used under the terms of the GNU Lesser General Public
|
|
|
|
|
** License version 2.1 as published by the Free Software Foundation and
|
|
|
|
|
** appearing in the file LICENSE.LGPL included in the packaging of this file.
|
|
|
|
|
** Please review the following information to ensure the GNU Lesser General
|
|
|
|
|
** Public License version 2.1 requirements will be met:
|
|
|
|
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2010-12-17 16:01:08 +01:00
|
|
|
** In addition, as a special exception, Nokia gives you certain additional
|
2011-04-13 08:42:33 +02:00
|
|
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
2010-12-17 16:01:08 +01:00
|
|
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
|
|
|
**
|
2011-04-13 08:42:33 +02:00
|
|
|
** Other Usage
|
|
|
|
|
**
|
|
|
|
|
** Alternatively, this file may be used in accordance with the terms and
|
|
|
|
|
** conditions contained in a signed written agreement between you and Nokia.
|
|
|
|
|
**
|
2010-12-17 16:01:08 +01:00
|
|
|
** If you have questions regarding the use of this file, please contact
|
2011-11-02 15:59:12 +01:00
|
|
|
** Nokia at qt-info@nokia.com.
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
**************************************************************************/
|
2008-12-02 16:19:05 +01:00
|
|
|
|
|
|
|
|
#include "session.h"
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "project.h"
|
|
|
|
|
#include "projectexplorer.h"
|
|
|
|
|
#include "projectexplorerconstants.h"
|
|
|
|
|
#include "nodesvisitor.h"
|
|
|
|
|
#include "editorconfiguration.h"
|
2012-01-31 13:40:59 +01:00
|
|
|
#include "projectnodes.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
#include <coreplugin/icore.h>
|
|
|
|
|
#include <coreplugin/imode.h>
|
|
|
|
|
#include <coreplugin/filemanager.h>
|
|
|
|
|
#include <coreplugin/editormanager/editormanager.h>
|
|
|
|
|
#include <coreplugin/editormanager/ieditor.h>
|
2010-09-16 15:57:52 +02:00
|
|
|
#include <coreplugin/coreconstants.h>
|
2009-01-13 14:16:36 +01:00
|
|
|
#include <coreplugin/progressmanager/progressmanager.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <coreplugin/modemanager.h>
|
|
|
|
|
|
|
|
|
|
#include <texteditor/itexteditor.h>
|
|
|
|
|
|
2008-12-09 15:25:01 +01:00
|
|
|
#include <utils/listutils.h>
|
|
|
|
|
#include <utils/qtcassert.h>
|
|
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QDebug>
|
|
|
|
|
#include <QDir>
|
|
|
|
|
#include <QFileInfo>
|
|
|
|
|
#include <QFuture>
|
|
|
|
|
#include <QSettings>
|
|
|
|
|
#include <QTimer>
|
2008-12-09 15:25:01 +01:00
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QApplication>
|
|
|
|
|
#include <QMainWindow>
|
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
#include <QPushButton>
|
|
|
|
|
#include <QTextCodec>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
bool debug = false;
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-02 17:15:18 +02:00
|
|
|
using namespace Core;
|
2011-08-16 10:45:23 +02:00
|
|
|
using Utils::PersistentSettingsReader;
|
|
|
|
|
using Utils::PersistentSettingsWriter;
|
2011-09-02 17:15:18 +02:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
using namespace ProjectExplorer;
|
2009-06-03 17:19:26 +02:00
|
|
|
using namespace ProjectExplorer::Internal;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2011-04-14 12:58:14 +02:00
|
|
|
/*!
|
|
|
|
|
\class ProjectExplorer::SessionManager
|
|
|
|
|
|
|
|
|
|
\brief Session management.
|
|
|
|
|
|
|
|
|
|
TODO the interface of this class is not really great.
|
|
|
|
|
The implementation suffers that all the functions from the
|
|
|
|
|
public interface just wrap around functions which do the actual work
|
|
|
|
|
This could be improved.
|
|
|
|
|
*/
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-01-20 17:14:00 +01:00
|
|
|
SessionManager::SessionManager(QObject *parent)
|
|
|
|
|
: QObject(parent),
|
2012-01-31 13:40:59 +01:00
|
|
|
m_sessionNode(new SessionNode(this)),
|
2012-02-06 14:52:35 +01:00
|
|
|
m_sessionName(QLatin1String("default")),
|
2012-02-06 16:52:15 +01:00
|
|
|
m_virginSession(true),
|
|
|
|
|
m_startupProject(0)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2011-09-02 17:15:18 +02:00
|
|
|
connect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)),
|
2008-12-02 12:01:29 +01:00
|
|
|
this, SLOT(saveActiveMode(Core::IMode*)));
|
2010-03-03 15:54:32 +01:00
|
|
|
|
2012-01-24 15:36:40 +01:00
|
|
|
EditorManager *em = ICore::editorManager();
|
2010-03-03 15:54:32 +01:00
|
|
|
|
|
|
|
|
connect(em, SIGNAL(editorCreated(Core::IEditor *, QString)),
|
2011-02-01 14:13:54 +01:00
|
|
|
this, SLOT(configureEditor(Core::IEditor *, QString)));
|
2008-12-02 12:01:29 +01:00
|
|
|
connect(ProjectExplorerPlugin::instance(), SIGNAL(currentProjectChanged(ProjectExplorer::Project *)),
|
|
|
|
|
this, SLOT(updateWindowTitle()));
|
2010-03-03 15:54:32 +01:00
|
|
|
connect(em, SIGNAL(editorOpened(Core::IEditor*)),
|
|
|
|
|
this, SLOT(markSessionFileDirty()));
|
|
|
|
|
connect(em, SIGNAL(editorsClosed(QList<Core::IEditor*>)),
|
|
|
|
|
this, SLOT(markSessionFileDirty()));
|
|
|
|
|
|
|
|
|
|
m_autoSaveSessionTimer = new QTimer(this);
|
|
|
|
|
m_autoSaveSessionTimer->setSingleShot(true);
|
|
|
|
|
m_autoSaveSessionTimer->setInterval(10000);
|
|
|
|
|
connect(m_autoSaveSessionTimer, SIGNAL(timeout()),
|
2012-01-24 15:36:40 +01:00
|
|
|
ICore::instance(), SIGNAL(saveSettingsRequested()));
|
2009-01-20 17:14:00 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
SessionManager::~SessionManager()
|
|
|
|
|
{
|
2012-02-10 12:46:33 +01:00
|
|
|
emit aboutToUnloadSession(m_sessionName);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool SessionManager::isDefaultVirgin() const
|
|
|
|
|
{
|
2010-03-29 13:43:41 +02:00
|
|
|
return isDefaultSession(m_sessionName)
|
|
|
|
|
&& m_virginSession;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SessionManager::isDefaultSession(const QString &session) const
|
|
|
|
|
{
|
2008-12-09 11:07:24 +01:00
|
|
|
return session == QLatin1String("default");
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SessionManager::saveActiveMode(Core::IMode *mode)
|
|
|
|
|
{
|
2010-01-07 18:17:24 +01:00
|
|
|
setValue(QLatin1String("ActiveMode"), mode->id());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SessionManager::clearProjectFileCache()
|
|
|
|
|
{
|
|
|
|
|
// If triggered by the fileListChanged signal of one project
|
|
|
|
|
// only invalidate cache for this project
|
|
|
|
|
Project *pro = qobject_cast<Project*>(sender());
|
|
|
|
|
if (pro)
|
|
|
|
|
m_projectFileCache.remove(pro);
|
|
|
|
|
else
|
|
|
|
|
m_projectFileCache.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SessionManager::recursiveDependencyCheck(const QString &newDep, const QString &checkDep) const
|
|
|
|
|
{
|
|
|
|
|
if (newDep == checkDep)
|
|
|
|
|
return false;
|
|
|
|
|
|
2012-02-06 17:14:52 +01:00
|
|
|
foreach (const QString &dependency, m_depMap.value(checkDep)) {
|
2008-12-02 12:01:29 +01:00
|
|
|
if (!recursiveDependencyCheck(newDep, dependency))
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-16 16:30:22 +01:00
|
|
|
/*
|
|
|
|
|
* TODO: The dependency management exposes an interface based on projects, but
|
|
|
|
|
* is internally purely string based. This is suboptimal. Probably it would be
|
|
|
|
|
* nicer to map the filenames to projects on load and only map it back to
|
|
|
|
|
* filenames when saving.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
QList<Project *> SessionManager::dependencies(const Project *project) const
|
|
|
|
|
{
|
|
|
|
|
const QString &proName = project->file()->fileName();
|
2012-02-06 17:14:52 +01:00
|
|
|
const QStringList &proDeps = m_depMap.value(proName);
|
2009-01-16 16:30:22 +01:00
|
|
|
|
|
|
|
|
QList<Project *> projects;
|
|
|
|
|
foreach (const QString &dep, proDeps) {
|
|
|
|
|
if (Project *pro = projectForFile(dep))
|
|
|
|
|
projects += pro;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return projects;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SessionManager::hasDependency(const Project *project, const Project *depProject) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
const QString &proName = project->file()->fileName();
|
|
|
|
|
const QString &depName = depProject->file()->fileName();
|
|
|
|
|
|
2012-02-06 17:14:52 +01:00
|
|
|
const QStringList &proDeps = m_depMap.value(proName);
|
2008-12-02 12:01:29 +01:00
|
|
|
return proDeps.contains(depName);
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-16 16:30:22 +01:00
|
|
|
bool SessionManager::canAddDependency(const Project *project, const Project *depProject) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
const QString &newDep = project->file()->fileName();
|
|
|
|
|
const QString &checkDep = depProject->file()->fileName();
|
|
|
|
|
|
|
|
|
|
return recursiveDependencyCheck(newDep, checkDep);
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-06 15:31:32 +02:00
|
|
|
bool SessionManager::addDependency(Project *project, Project *depProject)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
const QString &proName = project->file()->fileName();
|
|
|
|
|
const QString &depName = depProject->file()->fileName();
|
|
|
|
|
|
|
|
|
|
// check if this dependency is valid
|
|
|
|
|
if (!recursiveDependencyCheck(proName, depName))
|
|
|
|
|
return false;
|
|
|
|
|
|
2012-02-06 17:14:52 +01:00
|
|
|
QStringList proDeps = m_depMap.value(proName);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (!proDeps.contains(depName)) {
|
|
|
|
|
proDeps.append(depName);
|
2012-02-06 17:14:52 +01:00
|
|
|
m_depMap[proName] = proDeps;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2009-08-06 15:31:32 +02:00
|
|
|
emit dependencyChanged(project, depProject);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-06 15:31:32 +02:00
|
|
|
void SessionManager::removeDependency(Project *project, Project *depProject)
|
2009-01-16 16:30:22 +01:00
|
|
|
{
|
|
|
|
|
const QString &proName = project->file()->fileName();
|
|
|
|
|
const QString &depName = depProject->file()->fileName();
|
|
|
|
|
|
2012-02-06 17:14:52 +01:00
|
|
|
QStringList proDeps = m_depMap.value(proName);
|
2009-01-16 16:30:22 +01:00
|
|
|
proDeps.removeAll(depName);
|
|
|
|
|
if (proDeps.isEmpty()) {
|
2012-02-06 17:14:52 +01:00
|
|
|
m_depMap.remove(proName);
|
2009-01-16 16:30:22 +01:00
|
|
|
} else {
|
2012-02-06 17:14:52 +01:00
|
|
|
m_depMap[proName] = proDeps;
|
2009-01-16 16:30:22 +01:00
|
|
|
}
|
2009-08-06 15:31:32 +02:00
|
|
|
emit dependencyChanged(project, depProject);
|
2009-01-16 16:30:22 +01:00
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void SessionManager::setStartupProject(Project *startupProject)
|
|
|
|
|
{
|
|
|
|
|
if (debug)
|
2012-01-09 16:30:33 +01:00
|
|
|
qDebug() << Q_FUNC_INFO << (startupProject ? startupProject->displayName() : QLatin1String("0"));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
if (startupProject) {
|
2012-02-06 16:58:31 +01:00
|
|
|
Q_ASSERT(m_projects.contains(startupProject));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2012-02-06 16:52:15 +01:00
|
|
|
if (m_startupProject == startupProject)
|
2009-02-03 11:39:18 +01:00
|
|
|
return;
|
|
|
|
|
|
2012-02-06 16:52:15 +01:00
|
|
|
m_startupProject = startupProject;
|
2008-12-02 12:01:29 +01:00
|
|
|
emit startupProjectChanged(startupProject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Project *SessionManager::startupProject() const
|
|
|
|
|
{
|
2012-02-06 16:52:15 +01:00
|
|
|
return m_startupProject;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SessionManager::addProject(Project *project)
|
|
|
|
|
{
|
|
|
|
|
addProjects(QList<Project*>() << project);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SessionManager::addProjects(const QList<Project*> &projects)
|
|
|
|
|
{
|
2010-03-29 13:43:41 +02:00
|
|
|
m_virginSession = false;
|
2008-12-02 12:01:29 +01:00
|
|
|
QList<Project*> clearedList;
|
|
|
|
|
foreach (Project *pro, projects) {
|
2012-02-06 16:58:31 +01:00
|
|
|
if (!m_projects.contains(pro)) {
|
2008-12-02 12:01:29 +01:00
|
|
|
clearedList.append(pro);
|
2012-02-06 16:58:31 +01:00
|
|
|
m_projects.append(pro);
|
2012-01-31 13:40:59 +01:00
|
|
|
m_sessionNode->addProjectNodes(QList<ProjectNode *>() << pro->rootProjectNode());
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
connect(pro, SIGNAL(fileListChanged()),
|
|
|
|
|
this, SLOT(clearProjectFileCache()));
|
|
|
|
|
|
|
|
|
|
if (debug)
|
2010-01-07 18:17:24 +01:00
|
|
|
qDebug() << "SessionManager - adding project " << pro->displayName();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (Project *pro, clearedList) {
|
|
|
|
|
emit projectAdded(pro);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (clearedList.count() == 1)
|
|
|
|
|
emit singleProjectAdded(clearedList.first());
|
|
|
|
|
|
|
|
|
|
// maybe we have a new startup project?
|
|
|
|
|
if (!startupProject())
|
2012-02-06 16:58:31 +01:00
|
|
|
if (!m_projects.isEmpty())
|
|
|
|
|
setStartupProject(m_projects.first());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SessionManager::removeProject(Project *project)
|
|
|
|
|
{
|
2010-03-29 13:43:41 +02:00
|
|
|
m_virginSession = false;
|
2008-12-02 12:01:29 +01:00
|
|
|
if (project == 0) {
|
|
|
|
|
qDebug() << "SessionManager::removeProject(0) ... THIS SHOULD NOT HAPPEN";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
removeProjects(QList<Project*>() << project);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SessionManager::save()
|
|
|
|
|
{
|
|
|
|
|
if (debug)
|
|
|
|
|
qDebug() << "SessionManager - saving session" << m_sessionName;
|
|
|
|
|
|
|
|
|
|
emit aboutToSaveSession();
|
|
|
|
|
|
2012-02-06 15:39:38 +01:00
|
|
|
PersistentSettingsWriter writer;
|
|
|
|
|
|
|
|
|
|
// save the startup project
|
2012-02-06 16:52:15 +01:00
|
|
|
if (m_startupProject) {
|
|
|
|
|
writer.saveValue(QLatin1String("StartupProject"), m_startupProject->file()->fileName());
|
2012-02-06 15:39:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList projectFiles;
|
2012-02-06 16:58:31 +01:00
|
|
|
foreach (Project *pro, m_projects)
|
2012-02-06 15:39:38 +01:00
|
|
|
projectFiles << pro->file()->fileName();
|
|
|
|
|
|
|
|
|
|
// Restore infromation on projects that failed to load:
|
2012-02-06 17:08:01 +01:00
|
|
|
projectFiles.append(m_failedProjects);
|
2012-02-06 15:39:38 +01:00
|
|
|
|
|
|
|
|
writer.saveValue(QLatin1String("ProjectList"), projectFiles);
|
|
|
|
|
|
|
|
|
|
QMap<QString, QVariant> depMap;
|
2012-02-06 17:14:52 +01:00
|
|
|
QMap<QString, QStringList>::const_iterator i = m_depMap.constBegin();
|
|
|
|
|
while (i != m_depMap.constEnd()) {
|
2012-02-06 15:39:38 +01:00
|
|
|
QString key = i.key();
|
|
|
|
|
QStringList values;
|
|
|
|
|
foreach (const QString &value, i.value()) {
|
|
|
|
|
values << value;
|
|
|
|
|
}
|
|
|
|
|
depMap.insert(key, values);
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
writer.saveValue(QLatin1String("ProjectDependencies"), QVariant(depMap));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2012-02-06 15:39:38 +01:00
|
|
|
int editorCount = 0;
|
|
|
|
|
QList<Core::IEditor *> editors = ICore::editorManager()->openedEditors();
|
|
|
|
|
foreach (Core::IEditor *editor, editors) {
|
|
|
|
|
Q_ASSERT(editor);
|
|
|
|
|
if (!editor->isTemporary())
|
|
|
|
|
++editorCount;
|
|
|
|
|
}
|
|
|
|
|
writer.saveValue(QLatin1String("OpenEditors"), editorCount);
|
|
|
|
|
writer.saveValue(QLatin1String("EditorSettings"),
|
|
|
|
|
ICore::editorManager()->saveState().toBase64());
|
|
|
|
|
|
|
|
|
|
QMap<QString, QVariant>::const_iterator it, end;
|
2012-02-06 17:19:36 +01:00
|
|
|
end = m_values.constEnd();
|
2012-02-06 15:39:38 +01:00
|
|
|
QStringList keys;
|
2012-02-06 17:19:36 +01:00
|
|
|
for (it = m_values.constBegin(); it != end; ++it) {
|
2012-02-06 15:39:38 +01:00
|
|
|
writer.saveValue(QLatin1String("value-") + it.key(), it.value());
|
|
|
|
|
keys << it.key();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
writer.saveValue(QLatin1String("valueKeys"), keys);
|
|
|
|
|
|
|
|
|
|
QString fileName = sessionNameToFileName(m_sessionName);
|
|
|
|
|
bool result = writer.save(fileName, QLatin1String("QtCreatorSession"), Core::ICore::mainWindow());
|
2008-12-02 12:01:29 +01:00
|
|
|
if (!result) {
|
|
|
|
|
QMessageBox::warning(0, tr("Error while saving session"),
|
2012-02-06 15:24:13 +01:00
|
|
|
tr("Could not save session to file %1").arg(fileName));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (debug)
|
|
|
|
|
qDebug() << "SessionManager - saving session returned " << result;
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2012-02-10 12:55:15 +01:00
|
|
|
\fn bool SessionManager::closeAllProjects()
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2012-02-10 12:55:15 +01:00
|
|
|
Closes all projects
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
2012-02-10 12:55:15 +01:00
|
|
|
void SessionManager::closeAllProjects()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2012-02-10 12:55:15 +01:00
|
|
|
setStartupProject(0);
|
|
|
|
|
removeProjects(projects());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2008-12-05 15:58:19 +01:00
|
|
|
const QList<Project *> &SessionManager::projects() const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2012-02-06 16:58:31 +01:00
|
|
|
return m_projects;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList SessionManager::dependencies(const QString &proName) const
|
|
|
|
|
{
|
|
|
|
|
QStringList result;
|
2012-02-06 17:14:52 +01:00
|
|
|
foreach (const QString &dep, m_depMap.value(proName))
|
2008-12-02 12:01:29 +01:00
|
|
|
result += dependencies(dep);
|
|
|
|
|
|
|
|
|
|
result << proName;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList SessionManager::dependenciesOrder() const
|
|
|
|
|
{
|
|
|
|
|
QList<QPair<QString, QStringList> > unordered;
|
|
|
|
|
QStringList ordered;
|
|
|
|
|
|
|
|
|
|
// copy the map to a temporary list
|
|
|
|
|
foreach (Project *pro, projects()) {
|
|
|
|
|
const QString &proName = pro->file()->fileName();
|
|
|
|
|
unordered << QPair<QString, QStringList>
|
2012-02-06 17:14:52 +01:00
|
|
|
(proName, m_depMap.value(proName));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (!unordered.isEmpty()) {
|
|
|
|
|
for (int i=(unordered.count()-1); i>=0; --i) {
|
|
|
|
|
if (unordered.at(i).second.isEmpty()) {
|
|
|
|
|
ordered << unordered.at(i).first;
|
|
|
|
|
unordered.removeAt(i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// remove the handled projects from the dependency lists
|
|
|
|
|
// of the remaining unordered projects
|
|
|
|
|
for (int i = 0; i < unordered.count(); ++i) {
|
|
|
|
|
foreach (const QString &pro, ordered) {
|
|
|
|
|
QStringList depList = unordered.at(i).second;
|
|
|
|
|
depList.removeAll(pro);
|
|
|
|
|
unordered[i].second = depList;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ordered;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QList<Project *> SessionManager::projectOrder(Project *project) const
|
|
|
|
|
{
|
|
|
|
|
QList<Project *> result;
|
|
|
|
|
|
|
|
|
|
QStringList pros;
|
|
|
|
|
if (project) {
|
|
|
|
|
pros = dependencies(project->file()->fileName());
|
|
|
|
|
} else {
|
|
|
|
|
pros = dependenciesOrder();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (const QString &proFile, pros) {
|
|
|
|
|
foreach (Project *pro, projects()) {
|
|
|
|
|
if (pro->file()->fileName() == proFile) {
|
|
|
|
|
result << pro;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Project *SessionManager::projectForNode(Node *node) const
|
|
|
|
|
{
|
|
|
|
|
if (!node)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
Project *project = 0;
|
|
|
|
|
|
|
|
|
|
FolderNode *rootProjectNode = qobject_cast<FolderNode*>(node);
|
|
|
|
|
if (!rootProjectNode)
|
|
|
|
|
rootProjectNode = node->parentFolderNode();
|
|
|
|
|
while (rootProjectNode && rootProjectNode->parentFolderNode() != m_sessionNode)
|
|
|
|
|
rootProjectNode = rootProjectNode->parentFolderNode();
|
|
|
|
|
|
2008-12-17 15:51:48 +01:00
|
|
|
Q_ASSERT(rootProjectNode);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
QList<Project *> projectList = projects();
|
|
|
|
|
foreach (Project *p, projectList) {
|
|
|
|
|
if (p->rootProjectNode() == rootProjectNode) {
|
|
|
|
|
project = p;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return project;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-11 17:36:17 +01:00
|
|
|
Node *SessionManager::nodeForFile(const QString &fileName, Project *project) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
Node *node = 0;
|
2009-03-11 17:36:17 +01:00
|
|
|
if (!project)
|
|
|
|
|
project = projectForFile(fileName);
|
|
|
|
|
if (project) {
|
2008-12-02 12:01:29 +01:00
|
|
|
FindNodesForFileVisitor findNodes(fileName);
|
|
|
|
|
project->rootProjectNode()->accept(&findNodes);
|
|
|
|
|
|
|
|
|
|
foreach (Node *n, findNodes.nodes()) {
|
|
|
|
|
// prefer file nodes
|
|
|
|
|
if (!node || (node->nodeType() != FileNodeType && n->nodeType() == FileNodeType))
|
|
|
|
|
node = n;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Project *SessionManager::projectForFile(const QString &fileName) const
|
|
|
|
|
{
|
|
|
|
|
if (debug)
|
|
|
|
|
qDebug() << "SessionManager::projectForFile(" << fileName << ")";
|
|
|
|
|
|
2008-12-05 15:58:19 +01:00
|
|
|
const QList<Project *> &projectList = projects();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2008-12-05 15:58:19 +01:00
|
|
|
// Check current project first
|
2012-01-24 18:57:39 +01:00
|
|
|
Project *currentProject = ProjectExplorerPlugin::currentProject();
|
2008-12-05 15:58:19 +01:00
|
|
|
if (currentProject && projectContainsFile(currentProject, fileName))
|
|
|
|
|
return currentProject;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2008-12-05 15:58:19 +01:00
|
|
|
foreach (Project *p, projectList)
|
|
|
|
|
if (p != currentProject && projectContainsFile(p, fileName))
|
|
|
|
|
return p;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SessionManager::projectContainsFile(Project *p, const QString &fileName) const
|
|
|
|
|
{
|
|
|
|
|
if (!m_projectFileCache.contains(p))
|
|
|
|
|
m_projectFileCache.insert(p, p->files(Project::AllFiles));
|
|
|
|
|
|
|
|
|
|
return m_projectFileCache.value(p).contains(fileName);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2011-02-01 14:13:54 +01:00
|
|
|
void SessionManager::configureEditor(Core::IEditor *editor, const QString &fileName)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2011-02-01 14:13:54 +01:00
|
|
|
if (TextEditor::ITextEditor *textEditor = qobject_cast<TextEditor::ITextEditor*>(editor)) {
|
|
|
|
|
Project *project = projectForFile(fileName);
|
|
|
|
|
// Global settings are the default.
|
2011-02-03 15:48:14 +01:00
|
|
|
if (project)
|
|
|
|
|
project->editorConfiguration()->configureEditor(textEditor);
|
2011-02-01 14:13:54 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SessionManager::updateWindowTitle()
|
|
|
|
|
{
|
2010-09-15 13:49:43 +02:00
|
|
|
if (isDefaultSession(m_sessionName)) {
|
2012-01-24 18:57:39 +01:00
|
|
|
if (Project *currentProject = ProjectExplorerPlugin::currentProject())
|
2012-01-24 15:36:40 +01:00
|
|
|
ICore::editorManager()->setWindowTitleAddition(currentProject->displayName());
|
2010-12-09 19:53:49 +01:00
|
|
|
else
|
2012-01-24 15:36:40 +01:00
|
|
|
ICore::editorManager()->setWindowTitleAddition(QString());
|
2010-09-15 13:49:43 +02:00
|
|
|
} else {
|
2008-12-02 12:01:29 +01:00
|
|
|
QString sessionName = m_sessionName;
|
|
|
|
|
if (sessionName.isEmpty())
|
|
|
|
|
sessionName = tr("Untitled");
|
2012-01-24 15:36:40 +01:00
|
|
|
ICore::editorManager()->setWindowTitleAddition(sessionName);
|
2009-05-21 14:11:13 -05:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SessionManager::removeProjects(QList<Project *> remove)
|
|
|
|
|
{
|
|
|
|
|
QMap<QString, QStringList> resMap;
|
|
|
|
|
|
|
|
|
|
foreach (Project *pro, remove) {
|
|
|
|
|
if (debug)
|
2010-01-07 18:17:24 +01:00
|
|
|
qDebug() << "SessionManager - emitting aboutToRemoveProject(" << pro->displayName() << ")";
|
2008-12-02 12:01:29 +01:00
|
|
|
emit aboutToRemoveProject(pro);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Refresh dependencies
|
|
|
|
|
QSet<QString> projectFiles;
|
|
|
|
|
foreach (Project *pro, projects()) {
|
|
|
|
|
if (!remove.contains(pro))
|
|
|
|
|
projectFiles.insert(pro->file()->fileName());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QSet<QString>::const_iterator i = projectFiles.begin();
|
|
|
|
|
while (i != projectFiles.end()) {
|
|
|
|
|
QStringList dependencies;
|
2012-02-06 17:14:52 +01:00
|
|
|
foreach (const QString &dependency, m_depMap.value(*i)) {
|
2008-12-02 12:01:29 +01:00
|
|
|
if (projectFiles.contains(dependency))
|
|
|
|
|
dependencies << dependency;
|
|
|
|
|
}
|
|
|
|
|
if (!dependencies.isEmpty())
|
|
|
|
|
resMap.insert(*i, dependencies);
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-06 17:14:52 +01:00
|
|
|
m_depMap = resMap;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2011-03-21 18:27:54 +01:00
|
|
|
// TODO: Clear m_modelProjectHash
|
|
|
|
|
|
|
|
|
|
// Delete projects
|
|
|
|
|
foreach (Project *pro, remove) {
|
|
|
|
|
pro->saveSettings();
|
2012-02-06 16:58:31 +01:00
|
|
|
m_projects.removeOne(pro);
|
2011-03-21 18:27:54 +01:00
|
|
|
|
2012-02-06 16:52:15 +01:00
|
|
|
if (pro == m_startupProject)
|
2011-03-21 18:27:54 +01:00
|
|
|
setStartupProject(0);
|
|
|
|
|
|
|
|
|
|
disconnect(pro, SIGNAL(fileListChanged()),
|
|
|
|
|
this, SLOT(clearProjectFileCache()));
|
|
|
|
|
m_projectFileCache.remove(pro);
|
|
|
|
|
|
|
|
|
|
if (debug)
|
|
|
|
|
qDebug() << "SessionManager - emitting projectRemoved(" << pro->displayName() << ")";
|
2012-01-31 13:40:59 +01:00
|
|
|
m_sessionNode->removeProjectNodes(QList<ProjectNode *>() << pro->rootProjectNode());
|
2011-03-21 18:27:54 +01:00
|
|
|
emit projectRemoved(pro);
|
|
|
|
|
delete pro;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
if (startupProject() == 0)
|
2012-02-06 16:58:31 +01:00
|
|
|
if (!m_projects.isEmpty())
|
|
|
|
|
setStartupProject(m_projects.first());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2011-04-14 12:58:14 +02:00
|
|
|
/*!
|
|
|
|
|
\brief Let other plugins store persistent values within the session file.
|
|
|
|
|
*/
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void SessionManager::setValue(const QString &name, const QVariant &value)
|
|
|
|
|
{
|
2012-02-06 17:19:36 +01:00
|
|
|
if (m_values.value(name) == value)
|
2010-03-03 15:54:32 +01:00
|
|
|
return;
|
2012-02-06 17:19:36 +01:00
|
|
|
m_values.insert(name, value);
|
2010-03-18 13:42:09 +01:00
|
|
|
markSessionFileDirty(false);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant SessionManager::value(const QString &name)
|
|
|
|
|
{
|
2012-02-06 17:19:36 +01:00
|
|
|
QMap<QString, QVariant>::const_iterator it = m_values.find(name);
|
|
|
|
|
return (it == m_values.constEnd()) ? QVariant() : *it;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString SessionManager::activeSession() const
|
|
|
|
|
{
|
|
|
|
|
return m_sessionName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList SessionManager::sessions() const
|
|
|
|
|
{
|
2009-06-18 11:36:39 +02:00
|
|
|
if (m_sessions.isEmpty()) {
|
2010-01-11 10:22:55 +01:00
|
|
|
// We are not initialized yet, so do that now
|
2012-01-24 15:36:40 +01:00
|
|
|
QDir sessionDir(Core::ICore::userResourcePath());
|
2010-04-21 16:08:13 +02:00
|
|
|
QList<QFileInfo> sessionFiles = sessionDir.entryInfoList(QStringList() << QLatin1String("*.qws"), QDir::NoFilter, QDir::Time);
|
|
|
|
|
Q_FOREACH(const QFileInfo& fileInfo, sessionFiles) {
|
2012-01-09 16:30:33 +01:00
|
|
|
if (fileInfo.completeBaseName() != QLatin1String("default"))
|
2009-06-18 11:36:39 +02:00
|
|
|
m_sessions << fileInfo.completeBaseName();
|
|
|
|
|
}
|
2012-01-09 16:30:33 +01:00
|
|
|
m_sessions.prepend(QLatin1String("default"));
|
2009-06-18 11:36:39 +02:00
|
|
|
}
|
|
|
|
|
return m_sessions;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2010-09-15 13:39:20 +02:00
|
|
|
QString SessionManager::sessionNameToFileName(const QString &session) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2012-01-24 15:36:40 +01:00
|
|
|
return ICore::userResourcePath() + QLatin1Char('/') + session + QLatin1String(".qws");
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2011-04-14 12:58:14 +02:00
|
|
|
/*!
|
|
|
|
|
\brief Just creates a new session (Does not actually create the file).
|
|
|
|
|
*/
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
bool SessionManager::createSession(const QString &session)
|
|
|
|
|
{
|
|
|
|
|
if (sessions().contains(session))
|
|
|
|
|
return false;
|
2010-04-21 16:08:13 +02:00
|
|
|
Q_ASSERT(m_sessions.size() > 0);
|
|
|
|
|
m_sessions.insert(1, session);
|
2008-12-02 12:01:29 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2010-04-21 16:08:13 +02:00
|
|
|
bool SessionManager::renameSession(const QString &original, const QString &newName)
|
|
|
|
|
{
|
|
|
|
|
if (!cloneSession(original, newName))
|
|
|
|
|
return false;
|
|
|
|
|
if (original == activeSession())
|
|
|
|
|
loadSession(newName);
|
|
|
|
|
return deleteSession(original);
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-14 12:58:14 +02:00
|
|
|
/*!
|
|
|
|
|
\brief Deletes session name from session list and file from disk.
|
|
|
|
|
*/
|
2008-12-02 12:01:29 +01:00
|
|
|
bool SessionManager::deleteSession(const QString &session)
|
|
|
|
|
{
|
2009-06-18 11:36:39 +02:00
|
|
|
if (!m_sessions.contains(session))
|
2008-12-02 12:01:29 +01:00
|
|
|
return false;
|
2009-06-18 11:36:39 +02:00
|
|
|
m_sessions.removeOne(session);
|
2008-12-02 12:01:29 +01:00
|
|
|
QFile fi(sessionNameToFileName(session));
|
|
|
|
|
if (fi.exists())
|
|
|
|
|
return fi.remove();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SessionManager::cloneSession(const QString &original, const QString &clone)
|
|
|
|
|
{
|
2009-06-18 11:36:39 +02:00
|
|
|
if (!m_sessions.contains(original))
|
2008-12-02 12:01:29 +01:00
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
QFile fi(sessionNameToFileName(original));
|
|
|
|
|
// If the file does not exist, we can still clone
|
|
|
|
|
if (!fi.exists() || fi.copy(sessionNameToFileName(clone))) {
|
2010-04-21 16:08:13 +02:00
|
|
|
Q_ASSERT(m_sessions.size() > 0);
|
|
|
|
|
m_sessions.insert(1, clone);
|
2008-12-02 12:01:29 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-10 12:46:33 +01:00
|
|
|
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()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-14 12:58:14 +02:00
|
|
|
/*!
|
|
|
|
|
\brief Loads a session, takes a session name (not filename).
|
|
|
|
|
*/
|
2012-02-10 12:46:33 +01:00
|
|
|
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());
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-04-14 12:58:14 +02:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
bool SessionManager::loadSession(const QString &session)
|
|
|
|
|
{
|
|
|
|
|
// Do nothing if we have that session already loaded,
|
|
|
|
|
// exception if the session is the default virgin session
|
|
|
|
|
// we still want to be able to load the default session
|
|
|
|
|
if (session == m_sessionName && !isDefaultVirgin())
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (!sessions().contains(session))
|
|
|
|
|
return false;
|
2011-11-09 17:03:00 +01:00
|
|
|
|
2012-02-10 12:46:33 +01:00
|
|
|
// Try loading the file
|
2008-12-02 12:01:29 +01:00
|
|
|
QString fileName = sessionNameToFileName(session);
|
2012-02-10 12:46:33 +01:00
|
|
|
PersistentSettingsReader reader;
|
|
|
|
|
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();
|
2011-11-09 17:03:00 +01:00
|
|
|
|
2012-02-10 12:46:33 +01:00
|
|
|
m_sessionName = 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;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString SessionManager::lastSession() const
|
|
|
|
|
{
|
2012-01-24 15:36:40 +01:00
|
|
|
QString fileName = ICore::settings()->value(QLatin1String("ProjectExplorer/StartupSession")).toString();
|
2009-03-20 16:13:46 +01:00
|
|
|
return QFileInfo(fileName).completeBaseName();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SessionNode *SessionManager::sessionNode() const
|
|
|
|
|
{
|
|
|
|
|
return m_sessionNode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SessionManager::reportProjectLoadingProgress()
|
|
|
|
|
{
|
2012-02-06 16:45:03 +01:00
|
|
|
sessionLoadingProgress();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2010-03-18 13:42:09 +01:00
|
|
|
void SessionManager::markSessionFileDirty(bool makeDefaultVirginDirty)
|
2010-03-03 15:54:32 +01:00
|
|
|
{
|
2012-02-06 15:10:05 +01:00
|
|
|
m_autoSaveSessionTimer->start();
|
2010-03-18 13:42:09 +01:00
|
|
|
if (makeDefaultVirginDirty)
|
2010-03-29 13:43:41 +02:00
|
|
|
m_virginSession = false;
|
2010-03-03 15:54:32 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2012-02-06 16:45:03 +01:00
|
|
|
void SessionManager::sessionLoadingProgress()
|
|
|
|
|
{
|
2012-02-06 17:26:31 +01:00
|
|
|
m_future.setProgressValue(m_future.progressValue() + 1);
|
2012-02-06 16:45:03 +01:00
|
|
|
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
|
|
|
|
}
|