From 7836d92621830b6901bab9455e253fb89db9e76f Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 16 Apr 2025 08:46:29 +0200 Subject: [PATCH] Core: Return Result<> from IEditorFactory::startEditor() Change-Id: Ibca35716497ea62e92957db115130a841aff360a Reviewed-by: David Schulz --- .../editormanager/editormanager.cpp | 14 ++-- .../editormanager/ieditorfactory.cpp | 10 ++- .../coreplugin/editormanager/ieditorfactory.h | 7 +- .../coreplugin/editormanager/systemeditor.cpp | 12 ++-- .../qmlprojectmanager/qmlprojectplugin.cpp | 4 +- src/plugins/qtsupport/externaleditors.cpp | 66 +++++++++---------- 6 files changed, 53 insertions(+), 60 deletions(-) diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 1e701cbb4ba..ceed445d0d9 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -929,8 +929,10 @@ IEditor *EditorManagerPrivate::openEditor(EditorView *view, const FilePath &file QTC_ASSERT(factory->isExternalEditor(), factory = factories.isEmpty() ? nullptr : factories.takeFirst(); continue); - if (factory->startEditor(filePath, &errorString)) + const Result<> res = factory->startEditor(filePath); + if (res) break; + errorString = res.error(); } if (errorString.isEmpty()) @@ -3293,13 +3295,13 @@ bool EditorManager::openExternalEditor(const FilePath &filePath, Id editorId) if (!ee) return false; - QString errorMessage; + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - const bool ok = ee->startEditor(filePath, &errorMessage); + const Result<> res = ee->startEditor(filePath); QApplication::restoreOverrideCursor(); - if (!ok) - QMessageBox::critical(ICore::dialogParent(), ::Core::Tr::tr("Opening File"), errorMessage); - return ok; + if (!res) + QMessageBox::critical(ICore::dialogParent(), ::Core::Tr::tr("Opening File"), res.error()); + return res.has_value(); } /*! diff --git a/src/plugins/coreplugin/editormanager/ieditorfactory.cpp b/src/plugins/coreplugin/editormanager/ieditorfactory.cpp index 0c0fc17a204..5ea3b11e06b 100644 --- a/src/plugins/coreplugin/editormanager/ieditorfactory.cpp +++ b/src/plugins/coreplugin/editormanager/ieditorfactory.cpp @@ -298,10 +298,10 @@ IEditor *IEditorFactory::createEditor() const \sa setEditorStarter() */ -bool IEditorFactory::startEditor(const FilePath &filePath, QString *errorMessage) +Result<> IEditorFactory::startEditor(const FilePath &filePath) { - QTC_ASSERT(m_starter, return false); - return m_starter(filePath, errorMessage); + QTC_ASSERT(m_starter, return ResultError(ResultAssert)); + return m_starter(filePath); } /*! @@ -322,8 +322,6 @@ void IEditorFactory::setEditorCreator(const std::function &creator) } /*! - \fn void Core::IEditorFactory::setEditorStarter(const std::function &starter); - Sets the function that is used to open a file for a given \c FilePath to \a starter. @@ -332,7 +330,7 @@ void IEditorFactory::setEditorCreator(const std::function &creator) This is mutually exclusive with the use of setEditorCreator(). */ -void IEditorFactory::setEditorStarter(const std::function &starter) +void IEditorFactory::setEditorStarter(const std::function(const FilePath &)> &starter) { QTC_CHECK(!m_starter); QTC_CHECK(!m_creator); diff --git a/src/plugins/coreplugin/editormanager/ieditorfactory.h b/src/plugins/coreplugin/editormanager/ieditorfactory.h index ddc27eebc33..300f19004db 100644 --- a/src/plugins/coreplugin/editormanager/ieditorfactory.h +++ b/src/plugins/coreplugin/editormanager/ieditorfactory.h @@ -6,6 +6,7 @@ #include "../core_global.h" #include +#include #include @@ -42,7 +43,7 @@ public: bool isExternalEditor() const; IEditor *createEditor() const; - bool startEditor(const Utils::FilePath &filePath, QString *errorMessage); + Utils::Result<> startEditor(const Utils::FilePath &filePath); protected: IEditorFactory(); @@ -52,14 +53,14 @@ protected: void setMimeTypes(const QStringList &mimeTypes) { m_mimeTypes = mimeTypes; } void addMimeType(const QString &mimeType) { m_mimeTypes.append(mimeType); } void setEditorCreator(const std::function &creator); - void setEditorStarter(const std::function &starter); + void setEditorStarter(const std::function(const Utils::FilePath &)> &starter); private: Utils::Id m_id; QString m_displayName; QStringList m_mimeTypes; std::function m_creator; - std::function m_starter; + std::function(const Utils::FilePath &)> m_starter; }; } // namespace Core diff --git a/src/plugins/coreplugin/editormanager/systemeditor.cpp b/src/plugins/coreplugin/editormanager/systemeditor.cpp index 1cfc951ba64..02967654bf9 100644 --- a/src/plugins/coreplugin/editormanager/systemeditor.cpp +++ b/src/plugins/coreplugin/editormanager/systemeditor.cpp @@ -25,17 +25,13 @@ public: setDisplayName(Tr::tr("System Editor")); setMimeTypes({Utils::Constants::OCTET_STREAM_MIMETYPE}); - setEditorStarter([](const FilePath &filePath, QString *errorMessage) { - Q_UNUSED(errorMessage) + setEditorStarter([](const FilePath &filePath) -> Result<> { QUrl url; url.setPath(filePath.toUrlishString()); url.setScheme(QLatin1String("file")); - if (!QDesktopServices::openUrl(url)) { - if (errorMessage) - *errorMessage = Tr::tr("Could not open URL %1.").arg(url.toString()); - return false; - } - return true; + if (!QDesktopServices::openUrl(url)) + return ResultError(Tr::tr("Could not open URL %1.").arg(url.toString())); + return ResultOk; }); } }; diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp index dc1f611fbd0..f0d2e8c0c71 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp @@ -205,9 +205,9 @@ public: setId("Qt.QtDesignStudio"); setDisplayName(Tr::tr("Qt Design Studio")); setMimeTypes({Utils::Constants::QMLUI_MIMETYPE}); - setEditorStarter([](const FilePath &filePath, [[maybe_unused]] QString *errorMessage) { + setEditorStarter([](const FilePath &filePath) { openInQds(filePath); - return true; + return ResultOk; }); } }; diff --git a/src/plugins/qtsupport/externaleditors.cpp b/src/plugins/qtsupport/externaleditors.cpp index 91d7992b802..9fa92a3445d 100644 --- a/src/plugins/qtsupport/externaleditors.cpp +++ b/src/plugins/qtsupport/externaleditors.cpp @@ -163,10 +163,9 @@ static QString findFirstCommand(const QList &qtVersions, return QString(); } -static bool getEditorLaunchData(const CommandForQtVersion &commandForQtVersion, - const FilePath &filePath, - LaunchData *data, - QString *errorMessage) +static Result<> getEditorLaunchData(const CommandForQtVersion &commandForQtVersion, + const FilePath &filePath, + LaunchData *data) { // Check in order for Qt version with the binary: // - active kit of project @@ -174,10 +173,9 @@ static bool getEditorLaunchData(const CommandForQtVersion &commandForQtVersion, // - default kit // - any other kit // As fallback check PATH - if (!KitManager::waitForLoaded()) { - *errorMessage = Tr::tr("Could not load kits in a reasonable amount of time."); - return false; - } + if (!KitManager::waitForLoaded()) + return ResultError(Tr::tr("Could not load kits in a reasonable amount of time.")); + data->workingDirectory.clear(); QList qtVersionsToCheck; // deduplicated after being filled if (const Project *project = ProjectManager::projectForFile(filePath)) { @@ -202,9 +200,8 @@ static bool getEditorLaunchData(const CommandForQtVersion &commandForQtVersion, } if (data->binary.isEmpty()) { - *errorMessage = Tr::tr("The application \"%1\" could not be found.") - .arg(filePath.toUserOutput()); - return false; + return ResultError(Tr::tr("The application \"%1\" could not be found.") + .arg(filePath.toUserOutput())); } // Setup binary + arguments, use Mac Open if appropriate @@ -213,18 +210,17 @@ static bool getEditorLaunchData(const CommandForQtVersion &commandForQtVersion, *data = createMacOpenCommand(*data); if (debug) qDebug() << Q_FUNC_INFO << '\n' << data->binary << data->arguments; - return true; + return ResultOk; } -static bool startEditorProcess(const LaunchData &data, QString *errorMessage) +Result<> startEditorProcess(const LaunchData &data) { if (debug) qDebug() << Q_FUNC_INFO << '\n' << data.binary << data.arguments << data.workingDirectory; const CommandLine cmd{FilePath::fromString(data.binary), data.arguments}; - if (Process::startDetached(cmd, data.workingDirectory)) - return true; - *errorMessage = Tr::tr("Unable to start \"%1\".").arg(cmd.toUserOutput()); - return false; + if (!Process::startDetached(cmd, data.workingDirectory)) + return ResultError(Tr::tr("Unable to start \"%1\".").arg(cmd.toUserOutput())); + return ResultOk; } // ExternalDesignerEditorFactory with Designer Tcp remote control. @@ -258,15 +254,15 @@ public: setDisplayName(::Core::Tr::tr("Qt Widgets Designer")); setMimeTypes({Utils::Constants::FORM_MIMETYPE}); - setEditorStarter([guard](const FilePath &filePath, QString *errorMessage) { + setEditorStarter([guard](const FilePath &filePath) -> Result<> { LaunchData data; // Find the editor binary - if (!getEditorLaunchData(designerBinary, filePath, &data, errorMessage)) - return false; + if (const Result<> res = getEditorLaunchData(designerBinary, filePath, &data); !res) + return res; if (HostOsInfo::isMacHost()) - return startEditorProcess(data, errorMessage); + return startEditorProcess(data); /* Qt Widgets Designer on the remaining platforms: Uses Designer's own * Tcp-based communication mechanism to ensure all files are opened @@ -280,18 +276,16 @@ public: qDebug() << Q_FUNC_INFO << "\nWriting to socket:" << data.binary << filePath; QTcpSocket *socket = it.value(); if (!socket->write(filePath.toUrlishString().toUtf8() + '\n')) { - *errorMessage = Tr::tr("Qt Widgets Designer is not responding (%1).") - .arg(socket->errorString()); - return false; + return ResultError(Tr::tr("Qt Widgets Designer is not responding (%1).") + .arg(socket->errorString())); } - return true; + return ResultOk; } // No process yet. Create socket & launch the process QTcpServer server; - if (!server.listen(QHostAddress::LocalHost)) { - *errorMessage = Tr::tr("Unable to create server socket: %1").arg(server.errorString()); - return false; - } + if (!server.listen(QHostAddress::LocalHost)) + return ResultError(Tr::tr("Unable to create server socket: %1").arg(server.errorString())); + const quint16 port = server.serverPort(); if (debug) qDebug() << Q_FUNC_INFO << "\nLaunching server:" << port << data.binary << filePath; @@ -300,8 +294,9 @@ public: data.arguments.push_front(QString::number(port)); data.arguments.push_front(QLatin1String("-client")); - if (!startEditorProcess(data, errorMessage)) - return false; + if (const Result<> res = startEditorProcess(data); !res) + return res; + // Insert into cache if socket is created, else try again next time if (server.waitForNewConnection(3000)) { QTcpSocket *socket = server.nextPendingConnection(); @@ -312,7 +307,7 @@ public: QObject::connect(socket, &QAbstractSocket::disconnected, guard, mapSlot); QObject::connect(socket, &QAbstractSocket::errorOccurred, guard, mapSlot); } - return true; + return ResultOk; }); } }; @@ -339,10 +334,11 @@ public: setId("Qt.Linguist"); setDisplayName(::Core::Tr::tr("Qt Linguist")); setMimeTypes({Utils::Constants::LINGUIST_MIMETYPE}); - setEditorStarter([](const FilePath &filePath, QString *errorMessage) { + setEditorStarter([](const FilePath &filePath) { LaunchData data; - return getEditorLaunchData(linguistBinary, filePath, &data, errorMessage) - && startEditorProcess(data, errorMessage); + if (const Result<> res = getEditorLaunchData(linguistBinary, filePath, &data); !res) + return res; + return startEditorProcess(data); }); } };