QtSupport: Use setup functions for linguist and designer factories

Change-Id: I5083544dd7e8e16e8b5ed349d23fdcfc0d022330
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
hjk
2024-01-18 13:14:00 +01:00
parent 5772a85751
commit 670116f2c3
3 changed files with 84 additions and 79 deletions

View File

@@ -4,6 +4,7 @@
#include "externaleditors.h" #include "externaleditors.h"
#include <coreplugin/coreplugintr.h> #include <coreplugin/coreplugintr.h>
#include <coreplugin/editormanager/ieditorfactory.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
@@ -234,7 +235,7 @@ static bool startEditorProcess(const LaunchData &data, QString *errorMessage)
return true; return true;
} }
// DesignerExternalEditor with Designer Tcp remote control. // ExternalDesignerEditorFactory with Designer Tcp remote control.
// A per-binary entry containing the socket // A per-binary entry containing the socket
using ProcessCache = QMap<QString, QTcpSocket*>; using ProcessCache = QMap<QString, QTcpSocket*>;
@@ -256,67 +257,76 @@ static void processTerminated(const QString &binary)
socket->deleteLater(); socket->deleteLater();
} }
DesignerExternalEditor::DesignerExternalEditor() class ExternalDesignerFactory final : public Core::IEditorFactory
{ {
setId("Qt.Designer"); public:
setDisplayName(::Core::Tr::tr("Qt Designer")); explicit ExternalDesignerFactory(QObject *guard)
setMimeTypes({Utils::Constants::FORM_MIMETYPE}); {
setId("Qt.Designer");
setDisplayName(::Core::Tr::tr("Qt Designer"));
setMimeTypes({Utils::Constants::FORM_MIMETYPE});
setEditorStarter([this](const FilePath &filePath, QString *errorMessage) { setEditorStarter([guard](const FilePath &filePath, QString *errorMessage) {
LaunchData data; LaunchData data;
// Find the editor binary // Find the editor binary
if (!getEditorLaunchData(designerBinary, filePath, &data, errorMessage)) if (!getEditorLaunchData(designerBinary, filePath, &data, errorMessage))
return false; return false;
if (HostOsInfo::isMacHost()) if (HostOsInfo::isMacHost())
return startEditorProcess(data, errorMessage); return startEditorProcess(data, errorMessage);
/* Qt Designer on the remaining platforms: Uses Designer's own /* Qt Designer on the remaining platforms: Uses Designer's own
* Tcp-based communication mechanism to ensure all files are opened * Tcp-based communication mechanism to ensure all files are opened
* in one instance (per version). */ * in one instance (per version). */
// Known one? // Known one?
const ProcessCache::iterator it = m_processCache.find(data.binary); const ProcessCache::iterator it = m_processCache.find(data.binary);
if (it != m_processCache.end()) { if (it != m_processCache.end()) {
// Process is known, write to its socket to cause it to open the file // Process is known, write to its socket to cause it to open the file
if (debug) if (debug)
qDebug() << Q_FUNC_INFO << "\nWriting to socket:" << data.binary << filePath; qDebug() << Q_FUNC_INFO << "\nWriting to socket:" << data.binary << filePath;
QTcpSocket *socket = it.value(); QTcpSocket *socket = it.value();
if (!socket->write(filePath.toString().toUtf8() + '\n')) { if (!socket->write(filePath.toString().toUtf8() + '\n')) {
*errorMessage = Tr::tr("Qt Designer is not responding (%1).").arg(socket->errorString()); *errorMessage = Tr::tr("Qt Designer is not responding (%1).").arg(socket->errorString());
return false;
}
return true;
}
// 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; return false;
} }
return true; const quint16 port = server.serverPort();
} if (debug)
// No process yet. Create socket & launch the process qDebug() << Q_FUNC_INFO << "\nLaunching server:" << port << data.binary << filePath;
QTcpServer server; // Start first one with file and socket as '-client port file'
if (!server.listen(QHostAddress::LocalHost)) { // Wait for the socket listening
*errorMessage = Tr::tr("Unable to create server socket: %1").arg(server.errorString()); data.arguments.push_front(QString::number(port));
return false; data.arguments.push_front(QLatin1String("-client"));
}
const quint16 port = server.serverPort();
if (debug)
qDebug() << Q_FUNC_INFO << "\nLaunching server:" << port << data.binary << filePath;
// Start first one with file and socket as '-client port file'
// Wait for the socket listening
data.arguments.push_front(QString::number(port));
data.arguments.push_front(QLatin1String("-client"));
if (!startEditorProcess(data, errorMessage)) if (!startEditorProcess(data, errorMessage))
return false; return false;
// Insert into cache if socket is created, else try again next time // Insert into cache if socket is created, else try again next time
if (server.waitForNewConnection(3000)) { if (server.waitForNewConnection(3000)) {
QTcpSocket *socket = server.nextPendingConnection(); QTcpSocket *socket = server.nextPendingConnection();
socket->setParent(&m_guard); socket->setParent(guard);
const QString binary = data.binary; const QString binary = data.binary;
m_processCache.insert(binary, socket); m_processCache.insert(binary, socket);
auto mapSlot = [binary] { processTerminated(binary); }; auto mapSlot = [binary] { processTerminated(binary); };
QObject::connect(socket, &QAbstractSocket::disconnected, &m_guard, mapSlot); QObject::connect(socket, &QAbstractSocket::disconnected, guard, mapSlot);
QObject::connect(socket, &QAbstractSocket::errorOccurred, &m_guard, mapSlot); QObject::connect(socket, &QAbstractSocket::errorOccurred, guard, mapSlot);
} }
return true; return true;
}); });
}
};
void setupExternalDesigner(QObject *guard)
{
static ExternalDesignerFactory theExternalDesignerFactory(guard);
} }
// Linguist // Linguist
@@ -328,16 +338,25 @@ static QString linguistBinary(const QtSupport::QtVersion *qtVersion)
return QLatin1String(HostOsInfo::isMacHost() ? "Linguist" : "linguist"); return QLatin1String(HostOsInfo::isMacHost() ? "Linguist" : "linguist");
} }
LinguistEditor::LinguistEditor() class ExternalLinguistFactory : public Core::IEditorFactory
{ {
setId("Qt.Linguist"); public:
setDisplayName(::Core::Tr::tr("Qt Linguist")); ExternalLinguistFactory()
setMimeTypes({Utils::Constants::LINGUIST_MIMETYPE}); {
setEditorStarter([](const FilePath &filePath, QString *errorMessage) { setId("Qt.Linguist");
LaunchData data; setDisplayName(::Core::Tr::tr("Qt Linguist"));
return getEditorLaunchData(linguistBinary, filePath, &data, errorMessage) setMimeTypes({Utils::Constants::LINGUIST_MIMETYPE});
&& startEditorProcess(data, errorMessage); setEditorStarter([](const FilePath &filePath, QString *errorMessage) {
}); LaunchData data;
return getEditorLaunchData(linguistBinary, filePath, &data, errorMessage)
&& startEditorProcess(data, errorMessage);
});
}
};
void setupExternalLinguist()
{
static ExternalLinguistFactory theExternalDesignerFactory;
} }
} // QtSupport::Internal } // QtSupport::Internal

View File

@@ -3,25 +3,11 @@
#pragma once #pragma once
#include <coreplugin/editormanager/ieditorfactory.h>
#include <QObject> #include <QObject>
namespace QtSupport::Internal { namespace QtSupport::Internal {
class DesignerExternalEditor : public Core::IEditorFactory void setupExternalDesigner(QObject *guard);
{ void setupExternalLinguist();
public:
DesignerExternalEditor();
private:
QObject m_guard;
};
class LinguistEditor : public Core::IEditorFactory
{
public:
LinguistEditor();
};
} // QtSupport::Internal } // QtSupport::Internal

View File

@@ -48,9 +48,6 @@ namespace QtSupport::Internal {
class QtSupportPluginPrivate class QtSupportPluginPrivate
{ {
public: public:
DesignerExternalEditor designerEditor;
LinguistEditor linguistEditor;
TranslationWizardPageFactory translationWizardPageFactory; TranslationWizardPageFactory translationWizardPageFactory;
}; };
@@ -109,6 +106,9 @@ void QtSupportPlugin::initialize()
setupUicGenerator(); setupUicGenerator();
setupQScxmlcGenerator(); setupQScxmlcGenerator();
setupExternalDesigner(this);
setupExternalLinguist();
theProcessRunner() = processRunnerCallback; theProcessRunner() = processRunnerCallback;
thePrompter() = [this](const QString &msg, const QStringList &context) -> std::optional<QString> { thePrompter() = [this](const QString &msg, const QStringList &context) -> std::optional<QString> {