From 4e41308a0f893437f50a5a4ad37cf09eefb9e76f Mon Sep 17 00:00:00 2001
From: Daniel Teske <daniel.teske@nokia.com>
Date: Mon, 5 Sep 2011 13:47:29 +0200
Subject: [PATCH] Better error feedback on Open project

Task-Nr: QTCREATORBUG-5996
Task-Nr: QTCREATORBUG-5995

Change-Id: I4184a1c652cbfc93a788a8f9b67d936401e197b9
Reviewed-on: http://codereview.qt.nokia.com/4197
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Daniel Teske <daniel.teske@nokia.com>
---
 .../cmakeprojectmanager.cpp                   |  3 +-
 .../cmakeprojectmanager/cmakeprojectmanager.h |  2 +-
 .../genericprojectmanager.cpp                 |  9 +++--
 .../genericprojectmanager.h                   |  2 +-
 .../customwizard/customwizard.cpp             |  5 +--
 src/plugins/projectexplorer/iprojectmanager.h |  2 +-
 .../projectexplorer/pluginfilefactory.cpp     |  2 +-
 .../projectexplorer/projectexplorer.cpp       | 35 +++++++++++++++----
 src/plugins/projectexplorer/projectexplorer.h |  5 +--
 src/plugins/projectexplorer/session.cpp       |  5 ++-
 .../qmlprojectmanager/qmlprojectmanager.cpp   | 10 +++---
 .../qmlprojectmanager/qmlprojectmanager.h     |  2 +-
 .../qt4projectmanager/qt4projectmanager.cpp   | 11 +++---
 .../qt4projectmanager/qt4projectmanager.h     |  2 +-
 .../qtsupport/gettingstartedwelcomepage.cpp   |  5 ++-
 src/plugins/vcsbase/basecheckoutwizard.cpp    |  4 +--
 16 files changed, 62 insertions(+), 42 deletions(-)

diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp
index 081c9917f70..fba0bb99d8a 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp
@@ -131,8 +131,9 @@ void CMakeManager::runCMake(ProjectExplorer::Project *project)
     }
 }
 
-ProjectExplorer::Project *CMakeManager::openProject(const QString &fileName)
+ProjectExplorer::Project *CMakeManager::openProject(const QString &fileName, QString *errorString)
 {
+    Q_UNUSED(errorString)
     // TODO check whether this project is already opened
     return new CMakeProject(this, fileName);
 }
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h
index e09335c41f5..02b82ef57fb 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h
@@ -65,7 +65,7 @@ class CMakeManager : public ProjectExplorer::IProjectManager
 public:
     CMakeManager(CMakeSettingsPage *cmakeSettingsPage);
 
-    virtual ProjectExplorer::Project *openProject(const QString &fileName);
+    virtual ProjectExplorer::Project *openProject(const QString &fileName, QString *errorString);
     virtual QString mimeType() const;
 
     QString cmakeExecutable() const;
diff --git a/src/plugins/genericprojectmanager/genericprojectmanager.cpp b/src/plugins/genericprojectmanager/genericprojectmanager.cpp
index ab02f1a5288..cb28c22b7d0 100644
--- a/src/plugins/genericprojectmanager/genericprojectmanager.cpp
+++ b/src/plugins/genericprojectmanager/genericprojectmanager.cpp
@@ -35,7 +35,6 @@
 #include "genericproject.h"
 
 #include <coreplugin/icore.h>
-#include <coreplugin/messagemanager.h>
 #include <projectexplorer/projectexplorer.h>
 #include <projectexplorer/projectexplorerconstants.h>
 #include <projectexplorer/session.h>
@@ -52,7 +51,7 @@ QString Manager::mimeType() const
     return QLatin1String(Constants::GENERICMIMETYPE);
 }
 
-ProjectExplorer::Project *Manager::openProject(const QString &fileName)
+ProjectExplorer::Project *Manager::openProject(const QString &fileName, QString *errorString)
 {
     if (!QFileInfo(fileName).isFile())
         return 0;
@@ -60,9 +59,9 @@ ProjectExplorer::Project *Manager::openProject(const QString &fileName)
     ProjectExplorer::ProjectExplorerPlugin *projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance();
     foreach (ProjectExplorer::Project *pi, projectExplorer->session()->projects()) {
         if (fileName == pi->file()->fileName()) {
-            Core::MessageManager *messageManager = Core::ICore::instance()->messageManager();
-            messageManager->printToOutputPanePopup(tr("Failed opening project '%1': Project already open")
-                                                   .arg(QDir::toNativeSeparators(fileName)));
+            if (errorString)
+                *errorString = tr("Failed opening project '%1': Project already open")
+                    .arg(QDir::toNativeSeparators(fileName));
             return 0;
         }
     }
diff --git a/src/plugins/genericprojectmanager/genericprojectmanager.h b/src/plugins/genericprojectmanager/genericprojectmanager.h
index b46478e9dd8..96bc69d6933 100644
--- a/src/plugins/genericprojectmanager/genericprojectmanager.h
+++ b/src/plugins/genericprojectmanager/genericprojectmanager.h
@@ -48,7 +48,7 @@ public:
     Manager();
 
     virtual QString mimeType() const;
-    virtual ProjectExplorer::Project *openProject(const QString &fileName);
+    virtual ProjectExplorer::Project *openProject(const QString &fileName, QString *errorString);
 
     void notifyChanged(const QString &fileName);
 
diff --git a/src/plugins/projectexplorer/customwizard/customwizard.cpp b/src/plugins/projectexplorer/customwizard/customwizard.cpp
index 7d0a77d4a52..3b15787dccd 100644
--- a/src/plugins/projectexplorer/customwizard/customwizard.cpp
+++ b/src/plugins/projectexplorer/customwizard/customwizard.cpp
@@ -585,10 +585,7 @@ bool CustomProjectWizard::postGenerateOpen(const Core::GeneratedFiles &l, QStrin
     // Post-Generate: Open the project and the editors as desired
     foreach(const Core::GeneratedFile &file, l) {
         if (file.attributes() & Core::GeneratedFile::OpenProjectAttribute) {
-            if (!ProjectExplorer::ProjectExplorerPlugin::instance()->openProject(file.path())) {
-                if (errorMessage)
-                    *errorMessage = tr("The project %1 could not be opened.").
-                                    arg(QDir::toNativeSeparators(file.path()));
+            if (!ProjectExplorer::ProjectExplorerPlugin::instance()->openProject(file.path(), errorMessage)) {
                 return false;
             }
         }
diff --git a/src/plugins/projectexplorer/iprojectmanager.h b/src/plugins/projectexplorer/iprojectmanager.h
index 37a4e3c4bc5..9a0ad2db567 100644
--- a/src/plugins/projectexplorer/iprojectmanager.h
+++ b/src/plugins/projectexplorer/iprojectmanager.h
@@ -53,7 +53,7 @@ public:
     IProjectManager() {}
 
     virtual QString mimeType() const = 0;
-    virtual Project *openProject(const QString &fileName) = 0;
+    virtual Project *openProject(const QString &fileName, QString *errorString) = 0;
 };
 
 } // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/pluginfilefactory.cpp b/src/plugins/projectexplorer/pluginfilefactory.cpp
index 15970c3d192..07147f68a38 100644
--- a/src/plugins/projectexplorer/pluginfilefactory.cpp
+++ b/src/plugins/projectexplorer/pluginfilefactory.cpp
@@ -77,7 +77,7 @@ QString ProjectFileFactory::displayName() const
 Core::IFile *ProjectFileFactory::open(const QString &fileName)
 {
     ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
-    pe->openProject(fileName);
+    pe->openProject(fileName, 0);
     return 0;
 }
 
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index f779b98d1c5..c5197f3b047 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -1018,7 +1018,11 @@ void ProjectExplorerPlugin::loadAction()
                                                     d->m_projectFilterString);
     if (filename.isEmpty())
         return;
-    openProject(filename);
+    QString errorMessage;
+    openProject(filename, &errorMessage);
+
+    if (!errorMessage.isEmpty())
+        QMessageBox::critical(Core::ICore::instance()->mainWindow(), tr("Failed to open project"), errorMessage);
     updateActions();
 }
 
@@ -1229,12 +1233,20 @@ void ProjectExplorerPlugin::savePersistentSettings()
     }
 }
 
-bool ProjectExplorerPlugin::openProject(const QString &fileName)
+void ProjectExplorerPlugin::openProjectWelcomePage(const QString &fileName)
+{
+    QString errorMessage;
+    openProject(fileName, &errorMessage);
+    if (!errorMessage.isEmpty())
+        QMessageBox::critical(Core::ICore::instance()->mainWindow(), tr("Failed to open project"), errorMessage);
+}
+
+bool ProjectExplorerPlugin::openProject(const QString &fileName, QString *errorString)
 {
     if (debug)
         qDebug() << "ProjectExplorerPlugin::openProject";
 
-    QList<Project *> list = openProjects(QStringList() << fileName);
+    QList<Project *> list = openProjects(QStringList() << fileName, errorString);
     if (!list.isEmpty()) {
         addToRecentProjects(fileName, list.first()->displayName());
         d->m_session->setStartupProject(list.first());
@@ -1249,7 +1261,7 @@ static inline QList<IProjectManager*> allProjectManagers()
     return pm->getObjects<IProjectManager>();
 }
 
-QList<Project *> ProjectExplorerPlugin::openProjects(const QStringList &fileNames)
+QList<Project *> ProjectExplorerPlugin::openProjects(const QStringList &fileNames, QString *errorString)
 {
     if (debug)
         qDebug() << "ProjectExplorerPlugin - opening projects " << fileNames;
@@ -1261,7 +1273,8 @@ QList<Project *> ProjectExplorerPlugin::openProjects(const QStringList &fileName
         if (const Core::MimeType mt = Core::ICore::instance()->mimeDatabase()->findByFile(QFileInfo(fileName))) {
             foreach (IProjectManager *manager, projectManagers) {
                 if (manager->mimeType() == mt.type()) {
-                    if (Project *pro = manager->openProject(fileName)) {
+                    QString tmp;
+                    if (Project *pro = manager->openProject(fileName, &tmp)) {
                         if (pro->restoreSettings()) {
                             connect(pro, SIGNAL(fileListChanged()), this, SIGNAL(fileListChanged()));
                             d->m_session->addProject(pro);
@@ -1273,6 +1286,11 @@ QList<Project *> ProjectExplorerPlugin::openProjects(const QStringList &fileName
                             delete pro;
                         }
                     }
+                    if (errorString) {
+                        if (!errorString->isEmpty() && !tmp.isEmpty())
+                            errorString->append('\n');
+                        errorString->append(tmp);
+                    }
                     d->m_session->reportProjectLoadingProgress();
                     break;
                 }
@@ -1406,7 +1424,7 @@ void ProjectExplorerPlugin::restoreSession()
     connect(modeManager, SIGNAL(currentModeChanged(Core::IMode*, Core::IMode*)),
             this, SLOT(currentModeChanged(Core::IMode*, Core::IMode*)));
     connect(d->m_welcomePage, SIGNAL(requestSession(QString)), this, SLOT(loadSession(QString)));
-    connect(d->m_welcomePage, SIGNAL(requestProject(QString)), this, SLOT(openProject(QString)));
+    connect(d->m_welcomePage, SIGNAL(requestProject(QString)), this, SLOT(openProjectWelcomePage(QString)));
 
     QStringList combinedList;
     // Converts "filename" "+45" or "filename" ":23"
@@ -2296,7 +2314,10 @@ void ProjectExplorerPlugin::openRecentProject()
         return;
     QString fileName = a->data().toString();
     if (!fileName.isEmpty()) {
-        openProject(fileName);
+        QString errorMessage;
+        openProject(fileName, &errorMessage);
+        if (!errorMessage.isEmpty())
+            QMessageBox::critical(Core::ICore::instance()->mainWindow(), tr("Failed to open project"), errorMessage);
     }
 }
 
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index d10958936b9..480807a4859 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -77,8 +77,9 @@ public:
 
     static ProjectExplorerPlugin *instance();
 
-    Q_SLOT bool openProject(const QString &fileName);
-    QList<Project *> openProjects(const QStringList &fileNames);
+    bool openProject(const QString &fileName, QString *error);
+    QList<Project *> openProjects(const QStringList &fileNames, QString *error);
+    Q_SLOT void openProjectWelcomePage(const QString &fileName);
 
     SessionManager *session() const;
 
diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp
index 6a2929ff281..5ae14bc2357 100644
--- a/src/plugins/projectexplorer/session.cpp
+++ b/src/plugins/projectexplorer/session.cpp
@@ -165,7 +165,10 @@ bool SessionFile::load(const QString &fileName)
     // Keep projects that failed to load in the session!
     m_failedProjects = fileList;
     if (!fileList.isEmpty()) {
-        QList<Project *> projects = ProjectExplorerPlugin::instance()->openProjects(fileList);
+        QString errors;
+        QList<Project *> projects = ProjectExplorerPlugin::instance()->openProjects(fileList, &errors);
+        if (!errors.isEmpty())
+            QMessageBox::critical(Core::ICore::instance()->mainWindow(), tr("Failed to open project"), errors);
         foreach (Project *p, projects)
             m_failedProjects.removeAll(p->file()->fileName());
     }
diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.cpp b/src/plugins/qmlprojectmanager/qmlprojectmanager.cpp
index 1644cb27077..572faa43134 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectmanager.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.cpp
@@ -36,7 +36,6 @@
 
 #include <coreplugin/icore.h>
 #include <coreplugin/ifile.h>
-#include <coreplugin/messagemanager.h>
 #include <projectexplorer/projectexplorerconstants.h>
 #include <projectexplorer/projectexplorer.h>
 #include <projectexplorer/session.h>
@@ -53,17 +52,15 @@ Manager::Manager()
 QString Manager::mimeType() const
 { return QLatin1String(Constants::QMLMIMETYPE); }
 
-ProjectExplorer::Project *Manager::openProject(const QString &fileName)
+ProjectExplorer::Project *Manager::openProject(const QString &fileName, QString *errorString)
 {
-    Core::MessageManager *messageManager = Core::ICore::instance()->messageManager();
-
     QFileInfo fileInfo(fileName);
     ProjectExplorer::ProjectExplorerPlugin *projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance();
 
     foreach (ProjectExplorer::Project *pi, projectExplorer->session()->projects()) {
         if (fileName == pi->file()->fileName()) {
-            messageManager->printToOutputPanePopup(tr("Failed opening project '%1': Project already open")
-                                                   .arg(QDir::toNativeSeparators(fileName)));
+            if (errorString)
+                *errorString = tr("Failed opening project '%1': Project already open") .arg(QDir::toNativeSeparators(fileName));
             return 0;
         }
     }
@@ -71,6 +68,7 @@ ProjectExplorer::Project *Manager::openProject(const QString &fileName)
     if (fileInfo.isFile())
         return new QmlProject(this, fileName);
 
+    *errorString = tr("Failed opening project '%1': Project file is not a file").arg(QDir::toNativeSeparators(fileName));
     return 0;
 }
 
diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.h b/src/plugins/qmlprojectmanager/qmlprojectmanager.h
index 119b02b5fc0..4f1b4ba1208 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectmanager.h
+++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.h
@@ -50,7 +50,7 @@ public:
     Manager();
 
     virtual QString mimeType() const;
-    virtual ProjectExplorer::Project *openProject(const QString &fileName);
+    virtual ProjectExplorer::Project *openProject(const QString &fileName, QString *errorString);
 
     void notifyChanged(const QString &fileName);
 
diff --git a/src/plugins/qt4projectmanager/qt4projectmanager.cpp b/src/plugins/qt4projectmanager/qt4projectmanager.cpp
index df2d7b39d1c..bb69f81d106 100644
--- a/src/plugins/qt4projectmanager/qt4projectmanager.cpp
+++ b/src/plugins/qt4projectmanager/qt4projectmanager.cpp
@@ -46,7 +46,6 @@
 
 #include <coreplugin/icore.h>
 #include <coreplugin/basefilewizard.h>
-#include <coreplugin/messagemanager.h>
 #include <coreplugin/uniqueidmanager.h>
 #include <coreplugin/editormanager/editormanager.h>
 #include <coreplugin/editormanager/ieditor.h>
@@ -232,10 +231,8 @@ static void updateBoilerPlateCodeFiles(const AbstractMobileApp *app, const QStri
     }
 }
 
-ProjectExplorer::Project *Qt4Manager::openProject(const QString &fileName)
+ProjectExplorer::Project *Qt4Manager::openProject(const QString &fileName, QString *errorString)
 {
-    Core::MessageManager *messageManager = Core::ICore::instance()->messageManager();
-
     // TODO Make all file paths relative & remove this hack
     // We convert the path to an absolute one here because qt4project.cpp
     // && profileevaluator use absolute/canonical file paths all over the place
@@ -243,13 +240,15 @@ ProjectExplorer::Project *Qt4Manager::openProject(const QString &fileName)
     QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath();
 
     if (canonicalFilePath.isEmpty()) {
-        messageManager->printToOutputPane(tr("Failed opening project '%1': Project file does not exist").arg(QDir::toNativeSeparators(canonicalFilePath)));
+        if (errorString)
+         *errorString = tr("Failed opening project '%1': Project file does not exist").arg(QDir::toNativeSeparators(fileName));
         return 0;
     }
 
     foreach (ProjectExplorer::Project *pi, projectExplorer()->session()->projects()) {
         if (canonicalFilePath == pi->file()->fileName()) {
-            messageManager->printToOutputPane(tr("Failed opening project '%1': Project already open").arg(QDir::toNativeSeparators(canonicalFilePath)));
+            if (errorString)
+                *errorString = tr("Failed opening project '%1': Project already open").arg(QDir::toNativeSeparators(canonicalFilePath));
             return 0;
         }
     }
diff --git a/src/plugins/qt4projectmanager/qt4projectmanager.h b/src/plugins/qt4projectmanager/qt4projectmanager.h
index 256bf82a98e..9689d760dce 100644
--- a/src/plugins/qt4projectmanager/qt4projectmanager.h
+++ b/src/plugins/qt4projectmanager/qt4projectmanager.h
@@ -81,7 +81,7 @@ public:
     ProjectExplorer::ProjectExplorerPlugin *projectExplorer() const;
 
     virtual QString mimeType() const;
-    ProjectExplorer::Project *openProject(const QString &fileName);
+    ProjectExplorer::Project *openProject(const QString &fileName, QString *errorString);
 
     // Context information used in the slot implementations
     ProjectExplorer::Node *contextNode() const;
diff --git a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
index fe3f3d5e383..2914a3132f2 100644
--- a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
+++ b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
@@ -219,10 +219,13 @@ void GettingStartedWelcomePage::openProject(const QString &projectFile, const QS
         proFile = copyToAlternativeLocation(proFileInfo, filesToOpen);
 
     // don't try to load help and files if loading the help request is being cancelled
-    if (!proFile.isEmpty() && ProjectExplorer::ProjectExplorerPlugin::instance()->openProject(proFile)) {
+    QString errorMessage;
+    if (!proFile.isEmpty() && ProjectExplorer::ProjectExplorerPlugin::instance()->openProject(proFile, &errorMessage)) {
         Core::ICore::instance()->openFiles(filesToOpen);
         Core::ICore::instance()->helpManager()->handleHelpRequest(help.toString()+QLatin1String("?view=split"));
     }
+    if (!errorMessage.isEmpty())
+        QMessageBox::critical(Core::ICore::instance()->mainWindow(), tr("Failed to open project"), errorMessage);
 }
 
 void GettingStartedWelcomePage::updateTagsModel()
diff --git a/src/plugins/vcsbase/basecheckoutwizard.cpp b/src/plugins/vcsbase/basecheckoutwizard.cpp
index d817a56e39f..822054e07fb 100644
--- a/src/plugins/vcsbase/basecheckoutwizard.cpp
+++ b/src/plugins/vcsbase/basecheckoutwizard.cpp
@@ -189,9 +189,7 @@ QString BaseCheckoutWizard::openProject(const QString &path, QString *errorMessa
         return QString();
     // Open. Do not use a busy cursor here as additional wizards might pop up
     const QString projectFile = projectFiles.front().absoluteFilePath();
-    if (!pe->openProject(projectFile)) {
-        *errorMessage = tr("Unable to open the project '%1'.").
-                        arg(QDir::toNativeSeparators(projectFile));
+    if (!pe->openProject(projectFile, errorMessage)) {
         return QString();
     }
     return projectFile;
-- 
GitLab