2012-10-02 09:12:39 +02:00
|
|
|
/****************************************************************************
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** This file is part of Qt Creator.
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
2016-01-15 14:57:40 +01:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** GNU General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
2010-12-17 16:01:08 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
****************************************************************************/
|
2008-12-02 16:19:05 +01:00
|
|
|
|
|
|
|
|
#include "session.h"
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "project.h"
|
2015-07-28 18:29:52 +02:00
|
|
|
#include "target.h"
|
|
|
|
|
#include "kit.h"
|
|
|
|
|
#include "buildconfiguration.h"
|
|
|
|
|
#include "deployconfiguration.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "projectexplorer.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>
|
2015-02-26 13:38:54 +01:00
|
|
|
#include <coreplugin/idocument.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <coreplugin/imode.h>
|
|
|
|
|
#include <coreplugin/editormanager/editormanager.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>
|
|
|
|
|
|
2014-09-26 09:14:03 +02:00
|
|
|
#include <texteditor/texteditor.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2014-07-07 19:02:26 +02:00
|
|
|
#include <utils/algorithm.h>
|
2012-03-12 13:03:26 +01:00
|
|
|
#include <utils/stylehelper.h>
|
2008-12-09 15:25:01 +01:00
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QDebug>
|
|
|
|
|
#include <QDir>
|
|
|
|
|
#include <QFileInfo>
|
2008-12-09 15:25:01 +01:00
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QMessageBox>
|
|
|
|
|
#include <QPushButton>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2011-09-02 17:15:18 +02:00
|
|
|
using namespace Core;
|
2013-09-05 11:46:07 +02:00
|
|
|
using namespace Utils;
|
2009-06-03 17:19:26 +02:00
|
|
|
using namespace ProjectExplorer::Internal;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
namespace ProjectExplorer {
|
|
|
|
|
|
2011-04-14 12:58:14 +02:00
|
|
|
/*!
|
|
|
|
|
\class ProjectExplorer::SessionManager
|
|
|
|
|
|
2013-06-05 14:29:24 +02:00
|
|
|
\brief The SessionManager class manages sessions.
|
2011-04-14 12:58:14 +02:00
|
|
|
|
|
|
|
|
TODO the interface of this class is not really great.
|
2013-09-10 17:16:10 +02:00
|
|
|
The implementation suffers from that all the functions from the
|
|
|
|
|
public interface just wrap around functions which do the actual work.
|
2011-04-14 12:58:14 +02:00
|
|
|
This could be improved.
|
|
|
|
|
*/
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
class SessionManagerPrivate
|
|
|
|
|
{
|
|
|
|
|
public:
|
2015-02-02 00:37:38 +02:00
|
|
|
bool projectContainsFile(Project *p, const FileName &fileName) const;
|
2013-09-05 11:46:07 +02:00
|
|
|
void restoreValues(const PersistentSettingsReader &reader);
|
|
|
|
|
void restoreDependencies(const PersistentSettingsReader &reader);
|
|
|
|
|
void restoreStartupProject(const PersistentSettingsReader &reader);
|
|
|
|
|
void restoreEditors(const PersistentSettingsReader &reader);
|
|
|
|
|
void restoreProjects(const QStringList &fileList);
|
|
|
|
|
void askUserAboutFailedProjects();
|
|
|
|
|
void sessionLoadingProgress();
|
|
|
|
|
|
|
|
|
|
bool recursiveDependencyCheck(const QString &newDep, const QString &checkDep) const;
|
|
|
|
|
QStringList dependencies(const QString &proName) const;
|
|
|
|
|
QStringList dependenciesOrder() const;
|
|
|
|
|
void dependencies(const QString &proName, QStringList &result) const;
|
|
|
|
|
|
|
|
|
|
public:
|
2014-07-23 15:36:55 +02:00
|
|
|
static QString windowTitleAddition(const QString &filePath);
|
2016-11-05 10:30:30 +01:00
|
|
|
static QString sessionTitle(const QString &filePath);
|
2014-07-23 15:36:55 +02:00
|
|
|
|
2016-12-19 13:38:11 +01:00
|
|
|
std::unique_ptr<SessionNode> m_sessionNode;
|
2016-04-15 15:43:44 +02:00
|
|
|
QString m_sessionName = QLatin1String("default");
|
|
|
|
|
bool m_virginSession = true;
|
|
|
|
|
bool m_loadingSession = false;
|
|
|
|
|
bool m_casadeSetActive = false;
|
2013-09-05 11:46:07 +02:00
|
|
|
|
|
|
|
|
mutable QStringList m_sessions;
|
2016-09-23 19:14:50 +02:00
|
|
|
mutable QHash<QString, QDateTime> m_sessionDateTimes;
|
2013-09-05 11:46:07 +02:00
|
|
|
|
|
|
|
|
mutable QHash<Project *, QStringList> m_projectFileCache;
|
|
|
|
|
|
2016-04-15 15:43:44 +02:00
|
|
|
Project *m_startupProject = nullptr;
|
2013-09-05 11:46:07 +02:00
|
|
|
QList<Project *> m_projects;
|
|
|
|
|
QStringList m_failedProjects;
|
|
|
|
|
QMap<QString, QStringList> m_depMap;
|
|
|
|
|
QMap<QString, QVariant> m_values;
|
|
|
|
|
QFutureInterface<void> m_future;
|
2016-04-15 15:43:44 +02:00
|
|
|
PersistentSettingsWriter *m_writer = nullptr;
|
2016-11-05 10:30:30 +01:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
static QString locationInProject(const QString &filePath);
|
2013-09-05 11:46:07 +02:00
|
|
|
};
|
|
|
|
|
|
2016-02-26 15:01:51 +01:00
|
|
|
static SessionManager *m_instance = nullptr;
|
|
|
|
|
static SessionManagerPrivate *d = nullptr;
|
2013-09-05 11:46:07 +02:00
|
|
|
|
2016-04-13 15:52:14 +02:00
|
|
|
SessionManager::SessionManager(QObject *parent) : QObject(parent)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
m_instance = this;
|
|
|
|
|
d = new SessionManagerPrivate;
|
|
|
|
|
|
2016-12-19 13:38:11 +01:00
|
|
|
d->m_sessionNode.reset(new SessionNode);
|
2013-09-05 11:46:07 +02:00
|
|
|
|
2015-02-23 14:06:58 +01:00
|
|
|
connect(ModeManager::instance(), &ModeManager::currentModeChanged,
|
|
|
|
|
this, &SessionManager::saveActiveMode);
|
2010-03-03 15:54:32 +01:00
|
|
|
|
2015-02-02 00:37:38 +02:00
|
|
|
connect(EditorManager::instance(), &EditorManager::editorCreated,
|
|
|
|
|
this, &SessionManager::configureEditor);
|
2015-02-23 14:06:58 +01:00
|
|
|
connect(this, &SessionManager::projectAdded,
|
|
|
|
|
EditorManager::instance(), &EditorManager::updateWindowTitles);
|
|
|
|
|
connect(this, &SessionManager::projectRemoved,
|
|
|
|
|
EditorManager::instance(), &EditorManager::updateWindowTitles);
|
|
|
|
|
connect(this, &SessionManager::projectDisplayNameChanged,
|
|
|
|
|
EditorManager::instance(), &EditorManager::updateWindowTitles);
|
|
|
|
|
connect(EditorManager::instance(), &EditorManager::editorOpened,
|
|
|
|
|
[this] { markSessionFileDirty(); });
|
|
|
|
|
connect(EditorManager::instance(), &EditorManager::editorsClosed,
|
|
|
|
|
[this] { markSessionFileDirty(); });
|
2014-07-23 15:36:55 +02:00
|
|
|
|
|
|
|
|
EditorManager::setWindowTitleAdditionHandler(&SessionManagerPrivate::windowTitleAddition);
|
2016-11-05 10:30:30 +01:00
|
|
|
EditorManager::setSessionTitleHandler(&SessionManagerPrivate::sessionTitle);
|
2009-01-20 17:14:00 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
SessionManager::~SessionManager()
|
|
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
emit m_instance->aboutToUnloadSession(d->m_sessionName);
|
|
|
|
|
delete d->m_writer;
|
|
|
|
|
delete d;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2014-10-09 16:46:13 +02:00
|
|
|
SessionManager *SessionManager::instance()
|
2013-09-05 11:46:07 +02:00
|
|
|
{
|
|
|
|
|
return m_instance;
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
bool SessionManager::isDefaultVirgin()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
return isDefaultSession(d->m_sessionName) && d->m_virginSession;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
bool SessionManager::isDefaultSession(const QString &session)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2008-12-09 11:07:24 +01:00
|
|
|
return session == QLatin1String("default");
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2016-03-25 20:00:19 +01:00
|
|
|
void SessionManager::saveActiveMode(Id mode)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2016-03-25 20:00:19 +01:00
|
|
|
if (mode != Core::Constants::MODE_WELCOME)
|
|
|
|
|
setValue(QLatin1String("ActiveMode"), mode.toString());
|
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
|
2016-02-26 15:01:51 +01:00
|
|
|
auto pro = qobject_cast<Project*>(m_instance->sender());
|
2008-12-02 12:01:29 +01:00
|
|
|
if (pro)
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_projectFileCache.remove(pro);
|
2008-12-02 12:01:29 +01:00
|
|
|
else
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_projectFileCache.clear();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
bool SessionManagerPrivate::recursiveDependencyCheck(const QString &newDep, const QString &checkDep) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
if (newDep == checkDep)
|
|
|
|
|
return false;
|
|
|
|
|
|
2016-02-26 15:01:51 +01:00
|
|
|
foreach (const QString &dependency, m_depMap.value(checkDep)) {
|
2008-12-02 12:01:29 +01:00
|
|
|
if (!recursiveDependencyCheck(newDep, dependency))
|
|
|
|
|
return false;
|
2016-02-26 15:01:51 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-16 16:30:22 +01:00
|
|
|
/*
|
2012-05-03 17:05:38 +02:00
|
|
|
* The dependency management exposes an interface based on projects, but
|
2009-01-16 16:30:22 +01:00
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
QList<Project *> SessionManager::dependencies(const Project *project)
|
2009-01-16 16:30:22 +01:00
|
|
|
{
|
2014-05-02 12:22:58 +02:00
|
|
|
const QString proName = project->projectFilePath().toString();
|
2013-09-05 11:46:07 +02:00
|
|
|
const QStringList proDeps = d->m_depMap.value(proName);
|
2009-01-16 16:30:22 +01:00
|
|
|
|
|
|
|
|
QList<Project *> projects;
|
|
|
|
|
foreach (const QString &dep, proDeps) {
|
2015-02-02 00:37:38 +02:00
|
|
|
if (Project *pro = projectForFile(Utils::FileName::fromString(dep)))
|
2009-01-16 16:30:22 +01:00
|
|
|
projects += pro;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return projects;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
bool SessionManager::hasDependency(const Project *project, const Project *depProject)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2014-05-02 12:22:58 +02:00
|
|
|
const QString proName = project->projectFilePath().toString();
|
|
|
|
|
const QString depName = depProject->projectFilePath().toString();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
const QStringList proDeps = d->m_depMap.value(proName);
|
2008-12-02 12:01:29 +01:00
|
|
|
return proDeps.contains(depName);
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
bool SessionManager::canAddDependency(const Project *project, const Project *depProject)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2014-05-02 12:22:58 +02:00
|
|
|
const QString newDep = project->projectFilePath().toString();
|
|
|
|
|
const QString checkDep = depProject->projectFilePath().toString();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
return d->recursiveDependencyCheck(newDep, checkDep);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-08-06 15:31:32 +02:00
|
|
|
bool SessionManager::addDependency(Project *project, Project *depProject)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2014-05-02 12:22:58 +02:00
|
|
|
const QString proName = project->projectFilePath().toString();
|
|
|
|
|
const QString depName = depProject->projectFilePath().toString();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
// check if this dependency is valid
|
2013-09-05 11:46:07 +02:00
|
|
|
if (!d->recursiveDependencyCheck(proName, depName))
|
2008-12-02 12:01:29 +01:00
|
|
|
return false;
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
QStringList proDeps = d->m_depMap.value(proName);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (!proDeps.contains(depName)) {
|
|
|
|
|
proDeps.append(depName);
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_depMap[proName] = proDeps;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2013-09-05 11:46:07 +02:00
|
|
|
emit m_instance->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
|
|
|
{
|
2014-05-02 12:22:58 +02:00
|
|
|
const QString proName = project->projectFilePath().toString();
|
|
|
|
|
const QString depName = depProject->projectFilePath().toString();
|
2009-01-16 16:30:22 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
QStringList proDeps = d->m_depMap.value(proName);
|
2009-01-16 16:30:22 +01:00
|
|
|
proDeps.removeAll(depName);
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
if (proDeps.isEmpty())
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_depMap.remove(proName);
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
else
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_depMap[proName] = proDeps;
|
|
|
|
|
emit m_instance->dependencyChanged(project, depProject);
|
2009-01-16 16:30:22 +01:00
|
|
|
}
|
|
|
|
|
|
2015-07-28 18:29:52 +02:00
|
|
|
bool SessionManager::isProjectConfigurationCascading()
|
|
|
|
|
{
|
|
|
|
|
return d->m_casadeSetActive;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SessionManager::setProjectConfigurationCascading(bool b)
|
|
|
|
|
{
|
|
|
|
|
d->m_casadeSetActive = b;
|
|
|
|
|
markSessionFileDirty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SessionManager::setActiveTarget(Project *project, Target *target, SetActive cascade)
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(project, return);
|
|
|
|
|
|
|
|
|
|
project->setActiveTarget(target);
|
|
|
|
|
|
|
|
|
|
if (!target) // never cascade setting no target
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (cascade != SetActive::Cascade || !d->m_casadeSetActive)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Core::Id kitId = target->kit()->id();
|
|
|
|
|
foreach (Project *otherProject, SessionManager::projects()) {
|
|
|
|
|
if (otherProject == project)
|
|
|
|
|
continue;
|
2016-05-09 13:30:30 +02:00
|
|
|
if (Target *otherTarget = Utils::findOrDefault(otherProject->targets(),
|
|
|
|
|
[kitId](Target *t) { return t->kit()->id() == kitId; }))
|
|
|
|
|
otherProject->setActiveTarget(otherTarget);
|
2015-07-28 18:29:52 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SessionManager::setActiveBuildConfiguration(Target *target, BuildConfiguration *bc, SetActive cascade)
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(target, return);
|
|
|
|
|
target->setActiveBuildConfiguration(bc);
|
|
|
|
|
|
|
|
|
|
if (!bc)
|
|
|
|
|
return;
|
|
|
|
|
if (cascade != SetActive::Cascade || !d->m_casadeSetActive)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Core::Id kitId = target->kit()->id();
|
|
|
|
|
QString name = bc->displayName(); // We match on displayname
|
|
|
|
|
foreach (Project *otherProject, SessionManager::projects()) {
|
|
|
|
|
if (otherProject == target->project())
|
|
|
|
|
continue;
|
|
|
|
|
Target *otherTarget = otherProject->activeTarget();
|
2016-02-17 12:21:41 +01:00
|
|
|
if (!otherTarget || otherTarget->kit()->id() != kitId)
|
2015-07-28 18:29:52 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
foreach (BuildConfiguration *otherBc, otherTarget->buildConfigurations()) {
|
|
|
|
|
if (otherBc->displayName() == name) {
|
|
|
|
|
otherTarget->setActiveBuildConfiguration(otherBc);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SessionManager::setActiveDeployConfiguration(Target *target, DeployConfiguration *dc, SetActive cascade)
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(target, return);
|
|
|
|
|
target->setActiveDeployConfiguration(dc);
|
|
|
|
|
|
|
|
|
|
if (!dc)
|
|
|
|
|
return;
|
|
|
|
|
if (cascade != SetActive::Cascade || !d->m_casadeSetActive)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Core::Id kitId = target->kit()->id();
|
|
|
|
|
QString name = dc->displayName(); // We match on displayname
|
|
|
|
|
foreach (Project *otherProject, SessionManager::projects()) {
|
|
|
|
|
if (otherProject == target->project())
|
|
|
|
|
continue;
|
|
|
|
|
Target *otherTarget = otherProject->activeTarget();
|
2016-02-17 12:21:41 +01:00
|
|
|
if (!otherTarget || otherTarget->kit()->id() != kitId)
|
2015-07-28 18:29:52 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
foreach (DeployConfiguration *otherDc, otherTarget->deployConfigurations()) {
|
|
|
|
|
if (otherDc->displayName() == name) {
|
|
|
|
|
otherTarget->setActiveDeployConfiguration(otherDc);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void SessionManager::setStartupProject(Project *startupProject)
|
|
|
|
|
{
|
2016-02-26 15:01:51 +01:00
|
|
|
QTC_ASSERT((!startupProject)
|
|
|
|
|
|| (startupProject && d->m_projects.contains(startupProject)), return);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
if (d->m_startupProject == startupProject)
|
2009-02-03 11:39:18 +01:00
|
|
|
return;
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_startupProject = startupProject;
|
|
|
|
|
emit m_instance->startupProjectChanged(startupProject);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
Project *SessionManager::startupProject()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
return d->m_startupProject;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2016-06-13 11:41:35 +02:00
|
|
|
void SessionManager::addProject(Project *pro)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2016-06-13 11:41:35 +02:00
|
|
|
QTC_ASSERT(pro, return);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_virginSession = false;
|
2016-06-13 11:41:35 +02:00
|
|
|
QTC_ASSERT(!d->m_projects.contains(pro), return);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2016-06-13 11:41:35 +02:00
|
|
|
d->m_projects.append(pro);
|
|
|
|
|
d->m_sessionNode->addProjectNodes(QList<ProjectNode *>() << pro->rootProjectNode());
|
|
|
|
|
|
|
|
|
|
connect(pro, &Project::fileListChanged,
|
|
|
|
|
m_instance, &SessionManager::clearProjectFileCache);
|
|
|
|
|
|
2016-07-01 09:44:34 +02:00
|
|
|
connect(pro, &Project::displayNameChanged, m_instance, [pro] {
|
|
|
|
|
d->m_sessionNode->projectDisplayNameChanged(pro->rootProjectNode());
|
|
|
|
|
emit m_instance->projectDisplayNameChanged(pro);
|
|
|
|
|
});
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2016-06-13 11:41:35 +02:00
|
|
|
emit m_instance->projectAdded(pro);
|
|
|
|
|
configureEditors(pro);
|
|
|
|
|
connect(pro, &Project::fileListChanged, [pro](){ configureEditors(pro); });
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SessionManager::removeProject(Project *project)
|
|
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_virginSession = false;
|
2016-02-26 15:01:51 +01:00
|
|
|
QTC_ASSERT(project, return);
|
2008-12-02 12:01:29 +01:00
|
|
|
removeProjects(QList<Project*>() << project);
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-31 13:02:08 +02:00
|
|
|
bool SessionManager::loadingSession()
|
|
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
return d->m_loadingSession;
|
2012-05-31 13:02:08 +02:00
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
bool SessionManager::save()
|
|
|
|
|
{
|
2016-10-11 15:34:06 +03:00
|
|
|
// do not save new virgin default sessions
|
|
|
|
|
if (isDefaultVirgin())
|
|
|
|
|
return true;
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
emit m_instance->aboutToSaveSession();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
if (!d->m_writer || d->m_writer->fileName() != sessionNameToFileName(d->m_sessionName)) {
|
|
|
|
|
delete d->m_writer;
|
|
|
|
|
d->m_writer = new PersistentSettingsWriter(sessionNameToFileName(d->m_sessionName),
|
2012-08-17 13:18:31 +02:00
|
|
|
QLatin1String("QtCreatorSession"));
|
|
|
|
|
}
|
2012-02-06 15:39:38 +01:00
|
|
|
|
2012-08-31 17:01:15 +02:00
|
|
|
QVariantMap data;
|
2012-02-06 15:39:38 +01:00
|
|
|
// save the startup project
|
2013-09-05 11:46:07 +02:00
|
|
|
if (d->m_startupProject)
|
2014-05-02 12:22:58 +02:00
|
|
|
data.insert(QLatin1String("StartupProject"), d->m_startupProject->projectFilePath().toString());
|
2012-02-06 15:39:38 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
QColor c = StyleHelper::requestedBaseColor();
|
2012-03-12 13:03:26 +01:00
|
|
|
if (c.isValid()) {
|
|
|
|
|
QString tmp = QString::fromLatin1("#%1%2%3")
|
|
|
|
|
.arg(c.red(), 2, 16, QLatin1Char('0'))
|
|
|
|
|
.arg(c.green(), 2, 16, QLatin1Char('0'))
|
|
|
|
|
.arg(c.blue(), 2, 16, QLatin1Char('0'));
|
2012-11-17 09:21:09 +01:00
|
|
|
data.insert(QLatin1String("Color"), tmp);
|
2012-03-12 13:03:26 +01:00
|
|
|
}
|
|
|
|
|
|
2012-02-06 15:39:38 +01:00
|
|
|
QStringList projectFiles;
|
2013-09-05 11:46:07 +02:00
|
|
|
foreach (Project *pro, d->m_projects)
|
2014-05-02 12:22:58 +02:00
|
|
|
projectFiles << pro->projectFilePath().toString();
|
2012-02-06 15:39:38 +01:00
|
|
|
|
|
|
|
|
// Restore infromation on projects that failed to load:
|
2012-05-08 17:50:15 +02:00
|
|
|
// don't readd projects to the list, which the user loaded
|
2016-02-26 15:01:51 +01:00
|
|
|
foreach (const QString &failed, d->m_failedProjects) {
|
2012-05-08 17:50:15 +02:00
|
|
|
if (!projectFiles.contains(failed))
|
|
|
|
|
projectFiles << failed;
|
2016-02-26 15:01:51 +01:00
|
|
|
}
|
2012-02-06 15:39:38 +01:00
|
|
|
|
2012-08-31 17:01:15 +02:00
|
|
|
data.insert(QLatin1String("ProjectList"), projectFiles);
|
2015-07-28 18:29:52 +02:00
|
|
|
data.insert(QLatin1String("CascadeSetActive"), d->m_casadeSetActive);
|
2012-02-06 15:39:38 +01:00
|
|
|
|
|
|
|
|
QMap<QString, QVariant> depMap;
|
2016-04-13 15:52:14 +02:00
|
|
|
auto i = d->m_depMap.constBegin();
|
2013-09-05 11:46:07 +02:00
|
|
|
while (i != d->m_depMap.constEnd()) {
|
2012-02-06 15:39:38 +01:00
|
|
|
QString key = i.key();
|
|
|
|
|
QStringList values;
|
2016-02-26 15:01:51 +01:00
|
|
|
foreach (const QString &value, i.value())
|
2012-02-06 15:39:38 +01:00
|
|
|
values << value;
|
|
|
|
|
depMap.insert(key, values);
|
|
|
|
|
++i;
|
|
|
|
|
}
|
2012-08-31 17:01:15 +02:00
|
|
|
data.insert(QLatin1String("ProjectDependencies"), QVariant(depMap));
|
2013-08-29 17:17:24 +02:00
|
|
|
data.insert(QLatin1String("EditorSettings"), EditorManager::saveState().toBase64());
|
2012-02-06 15:39:38 +01:00
|
|
|
|
2016-04-13 15:52:14 +02:00
|
|
|
auto end = d->m_values.constEnd();
|
2012-02-06 15:39:38 +01:00
|
|
|
QStringList keys;
|
2016-04-13 15:52:14 +02:00
|
|
|
for (auto it = d->m_values.constBegin(); it != end; ++it) {
|
2012-08-31 17:01:15 +02:00
|
|
|
data.insert(QLatin1String("value-") + it.key(), it.value());
|
2012-02-06 15:39:38 +01:00
|
|
|
keys << it.key();
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-31 17:01:15 +02:00
|
|
|
data.insert(QLatin1String("valueKeys"), keys);
|
2012-02-06 15:39:38 +01:00
|
|
|
|
2015-02-03 23:59:04 +02:00
|
|
|
bool result = d->m_writer->save(data, ICore::mainWindow());
|
2016-09-23 19:14:50 +02:00
|
|
|
if (result) {
|
|
|
|
|
d->m_sessionDateTimes.insert(activeSession(), QDateTime::currentDateTime());
|
|
|
|
|
} else {
|
2014-03-11 18:09:23 +01:00
|
|
|
QMessageBox::warning(ICore::dialogParent(), tr("Error while saving session"),
|
2013-09-05 11:46:07 +02:00
|
|
|
tr("Could not save session to file %1").arg(d->m_writer->fileName().toUserOutput()));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
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
|
|
|
{
|
2016-02-26 15:01:51 +01:00
|
|
|
setStartupProject(nullptr);
|
2012-02-10 12:55:15 +01:00
|
|
|
removeProjects(projects());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2015-04-23 11:06:14 +02:00
|
|
|
QList<Project *> SessionManager::projects()
|
2013-09-05 11:46:07 +02:00
|
|
|
{
|
|
|
|
|
return d->m_projects;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SessionManager::hasProjects()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
return !d->m_projects.isEmpty();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
QStringList SessionManagerPrivate::dependencies(const QString &proName) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
QStringList result;
|
2013-07-09 13:45:52 +02:00
|
|
|
dependencies(proName, result);
|
2008-12-02 12:01:29 +01:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
void SessionManagerPrivate::dependencies(const QString &proName, QStringList &result) const
|
2013-07-09 13:45:52 +02:00
|
|
|
{
|
|
|
|
|
QStringList depends = m_depMap.value(proName);
|
|
|
|
|
|
|
|
|
|
foreach (const QString &dep, depends)
|
|
|
|
|
dependencies(dep, result);
|
|
|
|
|
|
|
|
|
|
if (!result.contains(proName))
|
|
|
|
|
result.append(proName);
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-05 10:30:30 +01:00
|
|
|
QString SessionManagerPrivate::sessionTitle(const QString &filePath)
|
2014-07-23 15:36:55 +02:00
|
|
|
{
|
|
|
|
|
if (SessionManager::isDefaultSession(d->m_sessionName)) {
|
|
|
|
|
if (filePath.isEmpty()) {
|
|
|
|
|
// use single project's name if there is only one loaded.
|
2014-10-13 22:37:28 +03:00
|
|
|
const QList<Project *> projects = SessionManager::projects();
|
2014-07-23 15:36:55 +02:00
|
|
|
if (projects.size() == 1)
|
|
|
|
|
return projects.first()->displayName();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
QString sessionName = d->m_sessionName;
|
|
|
|
|
if (sessionName.isEmpty())
|
|
|
|
|
sessionName = SessionManager::tr("Untitled");
|
|
|
|
|
return sessionName;
|
|
|
|
|
}
|
2016-11-05 10:30:30 +01:00
|
|
|
return QString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString SessionManagerPrivate::locationInProject(const QString &filePath) {
|
|
|
|
|
Project *project = SessionManager::projectForFile(Utils::FileName::fromString(filePath));
|
|
|
|
|
if (!project)
|
|
|
|
|
return QString();
|
|
|
|
|
|
|
|
|
|
Utils::FileName file = Utils::FileName::fromString(filePath);
|
|
|
|
|
Utils::FileName parentDir = file.parentDir();
|
|
|
|
|
if (parentDir == project->projectDirectory())
|
|
|
|
|
return "@ " + project->displayName();
|
|
|
|
|
|
|
|
|
|
if (file.isChildOf(project->projectDirectory())) {
|
|
|
|
|
Utils::FileName dirInProject = parentDir.relativeChildPath(project->projectDirectory());
|
|
|
|
|
return "(" + dirInProject.toUserOutput() + " @ " + project->displayName() + ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For a file that is "outside" the project it belongs to, we display its
|
|
|
|
|
// dir's full path because it is easier to read than a series of "../../.".
|
|
|
|
|
// Example: /home/hugo/GenericProject/App.files lists /home/hugo/lib/Bar.cpp
|
|
|
|
|
return "(" + parentDir.toUserOutput() + " @ " + project->displayName() + ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString SessionManagerPrivate::windowTitleAddition(const QString &filePath)
|
|
|
|
|
{
|
|
|
|
|
return locationInProject(filePath);
|
2014-07-23 15:36:55 +02:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
QStringList SessionManagerPrivate::dependenciesOrder() const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
QList<QPair<QString, QStringList> > unordered;
|
|
|
|
|
QStringList ordered;
|
|
|
|
|
|
|
|
|
|
// copy the map to a temporary list
|
2013-09-05 11:46:07 +02:00
|
|
|
foreach (Project *pro, m_projects) {
|
2015-03-02 09:18:35 +02:00
|
|
|
const QString proName = pro->projectFilePath().toString();
|
2013-09-05 11:46:07 +02:00
|
|
|
unordered << QPair<QString, QStringList>(proName, m_depMap.value(proName));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (!unordered.isEmpty()) {
|
2016-04-13 15:52:14 +02:00
|
|
|
for (int i = (unordered.count() - 1); i >= 0; --i) {
|
2008-12-02 12:01:29 +01:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-16 14:39:07 +01:00
|
|
|
QList<Project *> SessionManager::projectOrder(const Project *project)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
QList<Project *> result;
|
|
|
|
|
|
|
|
|
|
QStringList pros;
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
if (project)
|
2014-05-02 12:22:58 +02:00
|
|
|
pros = d->dependencies(project->projectFilePath().toString());
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
else
|
2013-09-05 11:46:07 +02:00
|
|
|
pros = d->dependenciesOrder();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
foreach (const QString &proFile, pros) {
|
|
|
|
|
foreach (Project *pro, projects()) {
|
2014-05-02 12:22:58 +02:00
|
|
|
if (pro->projectFilePath().toString() == proFile) {
|
2008-12-02 12:01:29 +01:00
|
|
|
result << pro;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-02 00:37:38 +02:00
|
|
|
QList<Node *> SessionManager::nodesForFile(const Utils::FileName &fileName)
|
2014-11-19 17:58:33 +01:00
|
|
|
{
|
2015-02-28 21:45:07 +02:00
|
|
|
FindNodesForFileVisitor findNodes(fileName);
|
2014-11-19 17:58:33 +01:00
|
|
|
sessionNode()->accept(&findNodes);
|
|
|
|
|
return findNodes.nodes();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// node for file returns a randomly selected node if there are multiple
|
|
|
|
|
// prefer to use nodesForFile and figure out which node you want
|
2015-02-02 00:37:38 +02:00
|
|
|
Node *SessionManager::nodeForFile(const Utils::FileName &fileName)
|
2014-11-19 17:58:33 +01:00
|
|
|
{
|
2016-02-26 15:01:51 +01:00
|
|
|
Node *node = nullptr;
|
2014-11-19 17:58:33 +01:00
|
|
|
foreach (Node *n, nodesForFile(fileName)) {
|
|
|
|
|
// prefer file nodes
|
2016-10-31 13:33:13 +01:00
|
|
|
if (!node || (node->nodeType() != NodeType::File && n->nodeType() == NodeType::File))
|
2014-11-19 17:58:33 +01:00
|
|
|
node = n;
|
|
|
|
|
}
|
|
|
|
|
return node;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
Project *SessionManager::projectForNode(Node *node)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
if (!node)
|
2016-02-26 15:01:51 +01:00
|
|
|
return nullptr;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2015-02-18 13:10:40 +01:00
|
|
|
FolderNode *rootProjectNode = node->asFolderNode();
|
2008-12-02 12:01:29 +01:00
|
|
|
if (!rootProjectNode)
|
|
|
|
|
rootProjectNode = node->parentFolderNode();
|
2013-09-05 11:46:07 +02:00
|
|
|
|
2016-12-19 13:38:11 +01:00
|
|
|
while (rootProjectNode && rootProjectNode->parentFolderNode() != d->m_sessionNode.get())
|
2008-12-02 12:01:29 +01:00
|
|
|
rootProjectNode = rootProjectNode->parentFolderNode();
|
|
|
|
|
|
2008-12-17 15:51:48 +01:00
|
|
|
Q_ASSERT(rootProjectNode);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2014-07-10 12:57:06 +02:00
|
|
|
return Utils::findOrDefault(d->m_projects, Utils::equal(&Project::rootProjectNode, rootProjectNode));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2015-02-02 00:37:38 +02:00
|
|
|
Project *SessionManager::projectForFile(const Utils::FileName &fileName)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2008-12-05 15:58:19 +01:00
|
|
|
const QList<Project *> &projectList = projects();
|
2016-02-26 15:01:51 +01:00
|
|
|
foreach (Project *p, projectList) {
|
2014-11-19 17:58:33 +01:00
|
|
|
if (d->projectContainsFile(p, fileName))
|
2008-12-05 15:58:19 +01:00
|
|
|
return p;
|
2016-02-26 15:01:51 +01:00
|
|
|
}
|
2013-09-05 11:46:07 +02:00
|
|
|
|
2016-02-26 15:01:51 +01:00
|
|
|
return nullptr;
|
2008-12-05 15:58:19 +01:00
|
|
|
}
|
|
|
|
|
|
2015-02-02 00:37:38 +02:00
|
|
|
bool SessionManagerPrivate::projectContainsFile(Project *p, const Utils::FileName &fileName) const
|
2008-12-05 15:58:19 +01:00
|
|
|
{
|
|
|
|
|
if (!m_projectFileCache.contains(p))
|
|
|
|
|
m_projectFileCache.insert(p, p->files(Project::AllFiles));
|
|
|
|
|
|
2015-02-02 00:37:38 +02:00
|
|
|
return m_projectFileCache.value(p).contains(fileName.toString());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2015-02-03 23:59:04 +02:00
|
|
|
void SessionManager::configureEditor(IEditor *editor, const QString &fileName)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2016-02-26 15:01:51 +01:00
|
|
|
if (auto textEditor = qobject_cast<TextEditor::BaseTextEditor*>(editor)) {
|
2015-02-02 00:37:38 +02:00
|
|
|
Project *project = projectForFile(Utils::FileName::fromString(fileName));
|
2011-02-01 14:13:54 +01:00
|
|
|
// 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
|
|
|
}
|
|
|
|
|
|
2014-11-04 17:40:29 +01:00
|
|
|
void SessionManager::configureEditors(Project *project)
|
|
|
|
|
{
|
|
|
|
|
foreach (IDocument *document, DocumentModel::openedDocuments()) {
|
2015-02-02 00:37:38 +02:00
|
|
|
if (d->projectContainsFile(project, document->filePath())) {
|
2014-11-04 17:40:29 +01:00
|
|
|
foreach (IEditor *editor, DocumentModel::editorsForDocument(document)) {
|
2016-02-26 15:01:51 +01:00
|
|
|
if (auto textEditor = qobject_cast<TextEditor::BaseTextEditor*>(editor)) {
|
2014-11-04 17:40:29 +01:00
|
|
|
project->editorConfiguration()->configureEditor(textEditor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void SessionManager::removeProjects(QList<Project *> remove)
|
|
|
|
|
{
|
|
|
|
|
QMap<QString, QStringList> resMap;
|
|
|
|
|
|
2016-02-26 15:01:51 +01:00
|
|
|
foreach (Project *pro, remove)
|
2013-09-05 11:46:07 +02:00
|
|
|
emit m_instance->aboutToRemoveProject(pro);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
// Refresh dependencies
|
|
|
|
|
QSet<QString> projectFiles;
|
|
|
|
|
foreach (Project *pro, projects()) {
|
|
|
|
|
if (!remove.contains(pro))
|
2014-05-02 12:22:58 +02:00
|
|
|
projectFiles.insert(pro->projectFilePath().toString());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2016-04-13 15:52:14 +02:00
|
|
|
auto i = projectFiles.begin();
|
2008-12-02 12:01:29 +01:00
|
|
|
while (i != projectFiles.end()) {
|
|
|
|
|
QStringList dependencies;
|
2013-09-05 11:46:07 +02:00
|
|
|
foreach (const QString &dependency, d->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;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
d->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();
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_projects.removeOne(pro);
|
2011-03-21 18:27:54 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
if (pro == d->m_startupProject)
|
2016-02-26 15:01:51 +01:00
|
|
|
setStartupProject(nullptr);
|
2011-03-21 18:27:54 +01:00
|
|
|
|
2015-02-23 14:06:58 +01:00
|
|
|
disconnect(pro, &Project::fileListChanged,
|
|
|
|
|
m_instance, &SessionManager::clearProjectFileCache);
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_projectFileCache.remove(pro);
|
2011-03-21 18:27:54 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_sessionNode->removeProjectNodes(QList<ProjectNode *>() << pro->rootProjectNode());
|
|
|
|
|
emit m_instance->projectRemoved(pro);
|
2011-03-21 18:27:54 +01:00
|
|
|
delete pro;
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-26 15:01:51 +01:00
|
|
|
if (!startupProject())
|
2013-09-05 11:46:07 +02:00
|
|
|
if (!d->m_projects.isEmpty())
|
|
|
|
|
setStartupProject(d->m_projects.first());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2011-04-14 12:58:14 +02:00
|
|
|
/*!
|
2013-09-10 17:16:10 +02:00
|
|
|
Lets other plugins store persistent values within the session file.
|
2011-04-14 12:58:14 +02:00
|
|
|
*/
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void SessionManager::setValue(const QString &name, const QVariant &value)
|
|
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
if (d->m_values.value(name) == value)
|
2010-03-03 15:54:32 +01:00
|
|
|
return;
|
2013-09-05 11:46:07 +02:00
|
|
|
d->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)
|
|
|
|
|
{
|
2016-04-13 15:52:14 +02:00
|
|
|
auto it = d->m_values.constFind(name);
|
2013-09-05 11:46:07 +02:00
|
|
|
return (it == d->m_values.constEnd()) ? QVariant() : *it;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
QString SessionManager::activeSession()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
return d->m_sessionName;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
QStringList SessionManager::sessions()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
if (d->m_sessions.isEmpty()) {
|
2010-01-11 10:22:55 +01:00
|
|
|
// We are not initialized yet, so do that now
|
2015-02-03 23:59:04 +02:00
|
|
|
QDir sessionDir(ICore::userResourcePath());
|
2010-04-21 16:08:13 +02:00
|
|
|
QList<QFileInfo> sessionFiles = sessionDir.entryInfoList(QStringList() << QLatin1String("*.qws"), QDir::NoFilter, QDir::Time);
|
2013-09-05 11:46:07 +02:00
|
|
|
foreach (const QFileInfo &fileInfo, sessionFiles) {
|
2016-09-23 19:14:50 +02:00
|
|
|
const QString &name = fileInfo.completeBaseName();
|
|
|
|
|
d->m_sessionDateTimes.insert(name, fileInfo.lastModified());
|
|
|
|
|
if (name != QLatin1String("default"))
|
|
|
|
|
d->m_sessions << name;
|
2009-06-18 11:36:39 +02:00
|
|
|
}
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_sessions.prepend(QLatin1String("default"));
|
2009-06-18 11:36:39 +02:00
|
|
|
}
|
2013-09-05 11:46:07 +02:00
|
|
|
return d->m_sessions;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2016-09-23 19:14:50 +02:00
|
|
|
QDateTime SessionManager::sessionDateTime(const QString &session)
|
|
|
|
|
{
|
|
|
|
|
return d->m_sessionDateTimes.value(session);
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
FileName SessionManager::sessionNameToFileName(const QString &session)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
return FileName::fromString(ICore::userResourcePath() + QLatin1Char('/') + session + QLatin1String(".qws"));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2011-04-14 12:58:14 +02:00
|
|
|
/*!
|
2013-09-10 17:16:10 +02:00
|
|
|
Creates \a session, but does not actually create the file.
|
2011-04-14 12:58:14 +02:00
|
|
|
*/
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
bool SessionManager::createSession(const QString &session)
|
|
|
|
|
{
|
|
|
|
|
if (sessions().contains(session))
|
|
|
|
|
return false;
|
2013-09-05 11:46:07 +02:00
|
|
|
Q_ASSERT(d->m_sessions.size() > 0);
|
|
|
|
|
d->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);
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-23 15:51:50 +02:00
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\brief Shows a dialog asking the user to confirm deleting the session \p session
|
|
|
|
|
*/
|
|
|
|
|
bool SessionManager::confirmSessionDelete(const QString &session)
|
|
|
|
|
{
|
2015-02-03 23:59:04 +02:00
|
|
|
return QMessageBox::question(ICore::mainWindow(),
|
2013-05-23 15:51:50 +02:00
|
|
|
tr("Delete Session"),
|
|
|
|
|
tr("Delete session %1?").arg(session),
|
|
|
|
|
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-14 12:58:14 +02:00
|
|
|
/*!
|
2013-09-10 17:16:10 +02:00
|
|
|
Deletes \a session name from session list and the file from disk.
|
2011-04-14 12:58:14 +02:00
|
|
|
*/
|
2008-12-02 12:01:29 +01:00
|
|
|
bool SessionManager::deleteSession(const QString &session)
|
|
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
if (!d->m_sessions.contains(session))
|
2008-12-02 12:01:29 +01:00
|
|
|
return false;
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_sessions.removeOne(session);
|
2012-08-20 18:52:20 +02:00
|
|
|
QFile fi(sessionNameToFileName(session).toString());
|
2008-12-02 12:01:29 +01:00
|
|
|
if (fi.exists())
|
|
|
|
|
return fi.remove();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SessionManager::cloneSession(const QString &original, const QString &clone)
|
|
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
if (!d->m_sessions.contains(original))
|
2008-12-02 12:01:29 +01:00
|
|
|
return false;
|
|
|
|
|
|
2012-08-20 18:52:20 +02:00
|
|
|
QFile fi(sessionNameToFileName(original).toString());
|
2008-12-02 12:01:29 +01:00
|
|
|
// If the file does not exist, we can still clone
|
2012-08-20 18:52:20 +02:00
|
|
|
if (!fi.exists() || fi.copy(sessionNameToFileName(clone).toString())) {
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_sessions.insert(1, clone);
|
2016-09-23 19:14:50 +02:00
|
|
|
d->m_sessionDateTimes.insert(clone, QFileInfo(sessionNameToFileName(clone).toString()).lastModified());
|
2008-12-02 12:01:29 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
void SessionManagerPrivate::restoreValues(const PersistentSettingsReader &reader)
|
2012-02-10 12:46:33 +01:00
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
const QStringList keys = reader.restoreValue(QLatin1String("valueKeys")).toStringList();
|
2012-02-10 12:46:33 +01:00
|
|
|
foreach (const QString &key, keys) {
|
|
|
|
|
QVariant value = reader.restoreValue(QLatin1String("value-") + key);
|
|
|
|
|
m_values.insert(key, value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
void SessionManagerPrivate::restoreDependencies(const PersistentSettingsReader &reader)
|
2012-02-10 12:46:33 +01:00
|
|
|
{
|
|
|
|
|
QMap<QString, QVariant> depMap = reader.restoreValue(QLatin1String("ProjectDependencies")).toMap();
|
2016-04-13 15:52:14 +02:00
|
|
|
auto i = depMap.constBegin();
|
2012-02-10 12:46:33 +01:00
|
|
|
while (i != depMap.constEnd()) {
|
|
|
|
|
const QString &key = i.key();
|
2012-10-21 12:38:39 +02:00
|
|
|
if (!m_failedProjects.contains(key)) {
|
|
|
|
|
QStringList values;
|
|
|
|
|
foreach (const QString &value, i.value().toStringList()) {
|
|
|
|
|
if (!m_failedProjects.contains(value))
|
|
|
|
|
values << value;
|
|
|
|
|
}
|
|
|
|
|
m_depMap.insert(key, values);
|
2012-02-10 12:46:33 +01:00
|
|
|
}
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
void SessionManagerPrivate::askUserAboutFailedProjects()
|
2012-02-10 12:46:33 +01:00
|
|
|
{
|
|
|
|
|
QStringList failedProjects = m_failedProjects;
|
|
|
|
|
if (!failedProjects.isEmpty()) {
|
|
|
|
|
QString fileList =
|
|
|
|
|
QDir::toNativeSeparators(failedProjects.join(QLatin1String("<br>")));
|
2016-02-26 15:01:51 +01:00
|
|
|
auto box = new QMessageBox(QMessageBox::Warning,
|
|
|
|
|
SessionManager::tr("Failed to restore project files"),
|
|
|
|
|
SessionManager::tr("Could not restore the following project files:<br><b>%1</b>").
|
|
|
|
|
arg(fileList));
|
|
|
|
|
auto keepButton = new QPushButton(SessionManager::tr("Keep projects in Session"), box);
|
|
|
|
|
auto removeButton = new QPushButton(SessionManager::tr("Remove projects from Session"), box);
|
2012-02-10 12:46:33 +01:00
|
|
|
box->addButton(keepButton, QMessageBox::AcceptRole);
|
|
|
|
|
box->addButton(removeButton, QMessageBox::DestructiveRole);
|
|
|
|
|
|
|
|
|
|
box->exec();
|
|
|
|
|
|
|
|
|
|
if (box->clickedButton() == removeButton)
|
|
|
|
|
m_failedProjects.clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
void SessionManagerPrivate::restoreStartupProject(const PersistentSettingsReader &reader)
|
2012-02-10 12:46:33 +01:00
|
|
|
{
|
|
|
|
|
const QString startupProject = reader.restoreValue(QLatin1String("StartupProject")).toString();
|
|
|
|
|
if (!startupProject.isEmpty()) {
|
2013-09-05 11:46:07 +02:00
|
|
|
foreach (Project *pro, d->m_projects) {
|
2014-05-02 12:22:58 +02:00
|
|
|
if (pro->projectFilePath().toString() == startupProject) {
|
2013-09-05 11:46:07 +02:00
|
|
|
m_instance->setStartupProject(pro);
|
2012-02-10 12:46:33 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-05-08 17:41:08 +02:00
|
|
|
}
|
|
|
|
|
if (!m_startupProject) {
|
2013-11-11 16:51:58 +01:00
|
|
|
if (!startupProject.isEmpty())
|
|
|
|
|
qWarning() << "Could not find startup project" << startupProject;
|
2013-09-05 11:46:07 +02:00
|
|
|
if (!m_projects.isEmpty())
|
|
|
|
|
m_instance->setStartupProject(m_projects.first());
|
2012-02-10 12:46:33 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
void SessionManagerPrivate::restoreEditors(const PersistentSettingsReader &reader)
|
2012-02-10 12:46:33 +01:00
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
const QVariant editorsettings = reader.restoreValue(QLatin1String("EditorSettings"));
|
2012-02-10 12:46:33 +01:00
|
|
|
if (editorsettings.isValid()) {
|
2013-08-29 17:17:24 +02:00
|
|
|
EditorManager::restoreState(QByteArray::fromBase64(editorsettings.toByteArray()));
|
2013-07-08 16:26:29 +02:00
|
|
|
sessionLoadingProgress();
|
2012-02-10 12:46:33 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-14 12:58:14 +02:00
|
|
|
/*!
|
2013-09-10 17:16:10 +02:00
|
|
|
Loads a session, takes a session name (not filename).
|
2011-04-14 12:58:14 +02:00
|
|
|
*/
|
2013-09-05 11:46:07 +02:00
|
|
|
void SessionManagerPrivate::restoreProjects(const QStringList &fileList)
|
2012-02-10 12:46:33 +01:00
|
|
|
{
|
|
|
|
|
// indirectly adds projects to session
|
|
|
|
|
// Keep projects that failed to load in the session!
|
|
|
|
|
m_failedProjects = fileList;
|
|
|
|
|
if (!fileList.isEmpty()) {
|
2015-08-20 14:47:02 +02:00
|
|
|
ProjectExplorerPlugin::OpenProjectResult result = ProjectExplorerPlugin::openProjects(fileList);
|
|
|
|
|
if (!result)
|
|
|
|
|
ProjectExplorerPlugin::showOpenProjectError(result);
|
|
|
|
|
foreach (Project *p, result.projects())
|
2014-05-02 12:22:58 +02:00
|
|
|
m_failedProjects.removeAll(p->projectFilePath().toString());
|
2012-02-10 12:46:33 +01:00
|
|
|
}
|
|
|
|
|
}
|
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
|
2013-09-05 11:46:07 +02:00
|
|
|
if (session == d->m_sessionName && !isDefaultVirgin())
|
2008-12-02 12:01:29 +01:00
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (!sessions().contains(session))
|
|
|
|
|
return false;
|
2011-11-09 17:03:00 +01:00
|
|
|
|
2015-08-20 16:27:19 +02:00
|
|
|
|
|
|
|
|
QStringList fileList;
|
2012-02-10 12:46:33 +01:00
|
|
|
// Try loading the file
|
2013-09-05 11:46:07 +02:00
|
|
|
FileName fileName = sessionNameToFileName(session);
|
2012-02-10 12:46:33 +01:00
|
|
|
PersistentSettingsReader reader;
|
2014-10-24 13:15:54 +02:00
|
|
|
if (fileName.exists()) {
|
2012-02-10 12:46:33 +01:00
|
|
|
if (!reader.load(fileName)) {
|
2014-03-11 18:09:23 +01:00
|
|
|
QMessageBox::warning(ICore::dialogParent(), tr("Error while restoring session"),
|
2012-08-20 18:52:20 +02:00
|
|
|
tr("Could not restore session %1").arg(fileName.toUserOutput()));
|
2015-08-20 16:27:19 +02:00
|
|
|
|
2012-02-10 12:46:33 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
2015-08-20 16:27:19 +02:00
|
|
|
fileList = reader.restoreValue(QLatin1String("ProjectList")).toStringList();
|
2012-02-10 12:46:33 +01:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_loadingSession = true;
|
2012-05-31 13:02:08 +02:00
|
|
|
|
2012-02-10 12:46:33 +01:00
|
|
|
// Allow everyone to set something in the session and before saving
|
2013-09-05 11:46:07 +02:00
|
|
|
emit m_instance->aboutToUnloadSession(d->m_sessionName);
|
2012-02-10 12:46:33 +01:00
|
|
|
|
2016-10-11 15:34:06 +03:00
|
|
|
if (!save()) {
|
|
|
|
|
d->m_loadingSession = false;
|
|
|
|
|
return false;
|
2012-02-10 12:46:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Clean up
|
2013-08-29 17:17:24 +02:00
|
|
|
if (!EditorManager::closeAllEditors()) {
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_loadingSession = false;
|
2012-02-10 12:46:33 +01:00
|
|
|
return false;
|
2012-05-31 13:02:08 +02:00
|
|
|
}
|
2012-02-10 12:46:33 +01:00
|
|
|
|
2016-02-26 15:01:51 +01:00
|
|
|
setStartupProject(nullptr);
|
2015-08-20 16:27:19 +02:00
|
|
|
|
|
|
|
|
QList<Project *> oldProjects = projects();
|
|
|
|
|
auto it = oldProjects.begin();
|
|
|
|
|
auto end = oldProjects.end();
|
|
|
|
|
|
|
|
|
|
while (it != end) {
|
2016-01-08 11:09:37 +01:00
|
|
|
int index = fileList.indexOf((*it)->projectFilePath().toString());
|
2015-08-20 16:27:19 +02:00
|
|
|
if (index != -1) {
|
|
|
|
|
fileList.removeAt(index);
|
|
|
|
|
it = oldProjects.erase(it);
|
|
|
|
|
} else {
|
|
|
|
|
++it;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
removeProjects(oldProjects);
|
2012-02-10 12:46:33 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_failedProjects.clear();
|
|
|
|
|
d->m_depMap.clear();
|
|
|
|
|
d->m_values.clear();
|
2015-07-28 18:29:52 +02:00
|
|
|
d->m_casadeSetActive = false;
|
2011-11-09 17:03:00 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_sessionName = session;
|
2015-04-15 15:38:20 +02:00
|
|
|
delete d->m_writer;
|
2016-02-26 15:01:51 +01:00
|
|
|
d->m_writer = nullptr;
|
2014-07-23 15:36:55 +02:00
|
|
|
EditorManager::updateWindowTitles();
|
2012-02-10 12:46:33 +01:00
|
|
|
|
2014-10-24 13:15:54 +02:00
|
|
|
if (fileName.exists()) {
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_virginSession = false;
|
2012-02-10 12:46:33 +01:00
|
|
|
|
2014-04-17 15:14:14 +02:00
|
|
|
ProgressManager::addTask(d->m_future.future(), tr("Loading Session"),
|
2013-09-03 15:18:37 +02:00
|
|
|
"ProjectExplorer.SessionFile.Load");
|
2012-02-10 12:46:33 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_future.setProgressRange(0, 1);
|
|
|
|
|
d->m_future.setProgressValue(0);
|
2013-07-08 16:26:29 +02:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
d->restoreValues(reader);
|
|
|
|
|
emit m_instance->aboutToLoadSession(session);
|
2012-02-10 12:46:33 +01:00
|
|
|
|
2015-03-11 17:32:27 +01:00
|
|
|
// retrieve all values before the following code could change them again
|
|
|
|
|
Id modeId = Id::fromSetting(value(QLatin1String("ActiveMode")));
|
2015-11-12 14:02:20 +01:00
|
|
|
if (!modeId.isValid())
|
|
|
|
|
modeId = Id(Core::Constants::MODE_EDIT);
|
2015-03-11 17:32:27 +01:00
|
|
|
|
2012-03-12 13:03:26 +01:00
|
|
|
QColor c = QColor(reader.restoreValue(QLatin1String("Color")).toString());
|
|
|
|
|
if (c.isValid())
|
2013-09-05 11:46:07 +02:00
|
|
|
StyleHelper::setBaseColor(c);
|
2012-03-12 13:03:26 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_future.setProgressRange(0, fileList.count() + 1/*initialization above*/ + 1/*editors*/);
|
|
|
|
|
d->m_future.setProgressValue(1);
|
2012-02-10 12:46:33 +01:00
|
|
|
|
2013-02-12 14:25:21 +01:00
|
|
|
// if one processEvents doesn't get the job done
|
|
|
|
|
// just use two!
|
|
|
|
|
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
|
|
|
|
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
2013-09-05 11:46:07 +02:00
|
|
|
d->restoreProjects(fileList);
|
|
|
|
|
d->sessionLoadingProgress();
|
|
|
|
|
d->restoreDependencies(reader);
|
|
|
|
|
d->restoreStartupProject(reader);
|
|
|
|
|
d->restoreEditors(reader);
|
2012-02-10 12:46:33 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_future.reportFinished();
|
|
|
|
|
d->m_future = QFutureInterface<void>();
|
2012-02-10 12:46:33 +01:00
|
|
|
|
2015-11-12 14:02:20 +01:00
|
|
|
// Fall back to Project mode if the startup project is unconfigured and
|
|
|
|
|
// use the mode saved in the session otherwise
|
|
|
|
|
if (d->m_startupProject && d->m_startupProject->needsConfiguration())
|
|
|
|
|
modeId = Id(Constants::MODE_SESSION);
|
2012-02-10 12:46:33 +01:00
|
|
|
|
2012-05-07 18:28:03 +02:00
|
|
|
ModeManager::activateMode(modeId);
|
2012-02-10 12:46:33 +01:00
|
|
|
ModeManager::setFocusToCurrentMode();
|
|
|
|
|
} else {
|
2012-05-07 18:28:03 +02:00
|
|
|
ModeManager::activateMode(Id(Core::Constants::MODE_EDIT));
|
2012-02-10 12:46:33 +01:00
|
|
|
ModeManager::setFocusToCurrentMode();
|
|
|
|
|
}
|
2015-07-28 18:29:52 +02:00
|
|
|
|
|
|
|
|
d->m_casadeSetActive = reader.restoreValue(QLatin1String("CascadeSetActive"), false).toBool();
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
emit m_instance->sessionLoaded(session);
|
2012-02-10 12:46:33 +01:00
|
|
|
|
|
|
|
|
// Starts a event loop, better do that at the very end
|
2013-09-05 11:46:07 +02:00
|
|
|
d->askUserAboutFailedProjects();
|
|
|
|
|
d->m_loadingSession = false;
|
2012-02-10 12:46:33 +01:00
|
|
|
return true;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
QString SessionManager::lastSession()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2012-10-16 18:10:08 +02:00
|
|
|
return ICore::settings()->value(QLatin1String("ProjectExplorer/StartupSession")).toString();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
SessionNode *SessionManager::sessionNode()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2016-12-19 13:38:11 +01:00
|
|
|
return d->m_sessionNode.get();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SessionManager::reportProjectLoadingProgress()
|
|
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
d->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
|
|
|
{
|
2010-03-18 13:42:09 +01:00
|
|
|
if (makeDefaultVirginDirty)
|
2013-09-05 11:46:07 +02:00
|
|
|
d->m_virginSession = false;
|
2010-03-03 15:54:32 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
void SessionManagerPrivate::sessionLoadingProgress()
|
2012-02-06 16:45:03 +01:00
|
|
|
{
|
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);
|
|
|
|
|
}
|
2012-02-23 17:50:30 +01:00
|
|
|
|
2013-09-05 11:46:07 +02:00
|
|
|
QStringList SessionManager::projectsForSessionName(const QString &session)
|
2012-02-23 17:50:30 +01:00
|
|
|
{
|
2013-09-05 11:46:07 +02:00
|
|
|
const FileName fileName = sessionNameToFileName(session);
|
2012-02-23 17:50:30 +01:00
|
|
|
PersistentSettingsReader reader;
|
2014-10-24 13:15:54 +02:00
|
|
|
if (fileName.exists()) {
|
2012-02-23 17:50:30 +01:00
|
|
|
if (!reader.load(fileName)) {
|
2012-08-20 18:52:20 +02:00
|
|
|
qWarning() << "Could not restore session" << fileName.toUserOutput();
|
2012-02-23 17:50:30 +01:00
|
|
|
return QStringList();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return reader.restoreValue(QLatin1String("ProjectList")).toStringList();
|
|
|
|
|
}
|
2013-09-05 11:46:07 +02:00
|
|
|
|
|
|
|
|
} // namespace ProjectExplorer
|