1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2016 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of Qt Creator. 7 ** 8 ** Commercial License Usage 9 ** Licensees holding valid commercial Qt licenses may use this file in 10 ** accordance with the commercial license agreement provided with the 11 ** Software or, alternatively, in accordance with the terms contained in 12 ** a written agreement between you and The Qt Company. For licensing terms 13 ** and conditions see https://www.qt.io/terms-conditions. For further 14 ** information use the contact form at https://www.qt.io/contact-us. 15 ** 16 ** GNU General Public License Usage 17 ** Alternatively, this file may be used under the terms of the GNU 18 ** General Public License version 3 as published by the Free Software 19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 20 ** included in the packaging of this file. Please review the following 21 ** information to ensure the GNU General Public License requirements will 22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 23 ** 24 ****************************************************************************/ 25 26 #pragma once 27 28 #include <coreplugin/editormanager/iexternaleditor.h> 29 30 #include <QStringList> 31 #include <QMap> 32 33 #include <functional> 34 35 QT_BEGIN_NAMESPACE 36 class QTcpSocket; 37 QT_END_NAMESPACE 38 39 namespace QtSupport { class BaseQtVersion; } 40 41 namespace QmakeProjectManager { 42 namespace Internal { 43 44 /* Convenience parametrizable base class for Qt editors/binaries 45 * Provides convenience functions that 46 * try to retrieve the binary of the editor from the Qt version 47 * of the project the file belongs to, falling back to path search 48 * if none is found. On Mac, the "open" mechanism can be optionally be used. */ 49 50 class ExternalQtEditor : public Core::IExternalEditor 51 { 52 Q_OBJECT 53 54 public: 55 // Member function pointer for a QtVersion function return a string (command) 56 using CommandForQtVersion = std::function<QString(const QtSupport::BaseQtVersion *)>; 57 58 static ExternalQtEditor *createLinguistEditor(); 59 static ExternalQtEditor *createDesignerEditor(); 60 61 QStringList mimeTypes() const override; 62 Utils::Id id() const override; 63 QString displayName() const override; 64 65 bool startEditor(const Utils::FilePath &filePath, QString *errorMessage) override; 66 67 // Data required to launch the editor 68 struct LaunchData { 69 QString binary; 70 QStringList arguments; 71 QString workingDirectory; 72 }; 73 74 protected: 75 ExternalQtEditor(Utils::Id id, 76 const QString &displayName, 77 const QString &mimetype, 78 const CommandForQtVersion &commandForQtVersion); 79 80 // Try to retrieve the binary of the editor from the Qt version, 81 // prepare arguments accordingly (Mac "open" if desired) 82 bool getEditorLaunchData(const Utils::FilePath &filePath, 83 LaunchData *data, 84 QString *errorMessage) const; 85 86 // Create and start a detached GUI process executing in the background. 87 // Set the project environment if there is one. 88 bool startEditorProcess(const LaunchData &data, QString *errorMessage); 89 90 private: 91 const QStringList m_mimeTypes; 92 const Utils::Id m_id; 93 const QString m_displayName; 94 const CommandForQtVersion m_commandForQtVersion; 95 }; 96 97 /* Qt Designer on the remaining platforms: Uses Designer's own 98 * Tcp-based communication mechanism to ensure all files are opened 99 * in one instance (per version). */ 100 101 class DesignerExternalEditor : public ExternalQtEditor 102 { 103 Q_OBJECT 104 public: 105 DesignerExternalEditor(); 106 107 bool startEditor(const Utils::FilePath &filePath, QString *errorMessage) override; 108 109 private: 110 void processTerminated(const QString &binary); 111 112 // A per-binary entry containing the socket 113 using ProcessCache = QMap<QString, QTcpSocket*>; 114 115 ProcessCache m_processCache; 116 }; 117 118 } // namespace Internal 119 } // namespace QmakeProjectManager 120