PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/src/plugins/studiowelcome/studiowelcomeplugin.cpp

https://github.com/choenig/qt-creator
C++ | 329 lines | 244 code | 61 blank | 24 comment | 7 complexity | 944dc58d7cf9141d23511b280a947d0c MD5 | raw file
  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2019 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. #include "studiowelcomeplugin.h"
  26. #include <coreplugin/coreconstants.h>
  27. #include <coreplugin/editormanager/editormanager.h>
  28. #include <coreplugin/helpmanager.h>
  29. #include <coreplugin/icore.h>
  30. #include <coreplugin/imode.h>
  31. #include <coreplugin/modemanager.h>
  32. #include <extensionsystem/pluginmanager.h>
  33. #include <extensionsystem/pluginspec.h>
  34. #include <projectexplorer/projectexplorer.h>
  35. #include <projectexplorer/projectexplorer.h>
  36. #include <projectexplorer/projectmanager.h>
  37. #include <utils/checkablemessagebox.h>
  38. #include <utils/icon.h>
  39. #include <utils/stringutils.h>
  40. #include <utils/theme/theme.h>
  41. #include <QAbstractListModel>
  42. #include <QApplication>
  43. #include <QDesktopServices>
  44. #include <QFontDatabase>
  45. #include <QFileInfo>
  46. #include <QPointer>
  47. #include <QQmlContext>
  48. #include <QQmlEngine>
  49. #include <QQuickItem>
  50. #include <QQuickView>
  51. #include <QQuickWidget>
  52. #include <QTimer>
  53. namespace StudioWelcome {
  54. namespace Internal {
  55. const char DO_NOT_SHOW_SPLASHSCREEN_AGAIN_KEY[] = "StudioSplashScreen";
  56. QPointer<QQuickWidget> s_view = nullptr;
  57. class ProjectModel : public QAbstractListModel
  58. {
  59. Q_OBJECT
  60. public:
  61. enum { FilePathRole = Qt::UserRole+1, PrettyFilePathRole };
  62. Q_PROPERTY(bool communityVersion MEMBER m_communityVersion NOTIFY communityVersionChanged)
  63. explicit ProjectModel(QObject *parent = nullptr);
  64. int rowCount(const QModelIndex &parent) const override;
  65. QVariant data(const QModelIndex &index, int role) const override;
  66. QHash<int, QByteArray> roleNames() const override;
  67. Q_INVOKABLE void createProject()
  68. {
  69. ProjectExplorer::ProjectExplorerPlugin::openNewProjectDialog();
  70. }
  71. Q_INVOKABLE void openProject()
  72. {
  73. ProjectExplorer::ProjectExplorerPlugin::openOpenProjectDialog();
  74. }
  75. Q_INVOKABLE void openProjectAt(int row)
  76. {
  77. const QString projectFile = data(index(row, 0),
  78. ProjectModel::FilePathRole).toString();
  79. ProjectExplorer::ProjectExplorerPlugin::openProjectWelcomePage(projectFile);
  80. }
  81. Q_INVOKABLE int get(int)
  82. {
  83. return -1;
  84. }
  85. Q_INVOKABLE void showHelp()
  86. {
  87. QDesktopServices::openUrl(QUrl("qthelp://org.qt-project.qtcreator/doc/index.html"));
  88. }
  89. Q_INVOKABLE void openExample(const QString &example, const QString &formFile)
  90. {
  91. const QString projectFile = Core::ICore::resourcePath() + "/examples/" + example + "/" + example + ".qmlproject";
  92. ProjectExplorer::ProjectExplorerPlugin::openProjectWelcomePage(projectFile);
  93. const QString qmlFile = Core::ICore::resourcePath() + "/examples/" + example + "/" + formFile;
  94. Core::EditorManager::openEditor(qmlFile);
  95. }
  96. public slots:
  97. void resetProjects();
  98. signals:
  99. void communityVersionChanged();
  100. private:
  101. bool m_communityVersion = false;
  102. };
  103. ProjectModel::ProjectModel(QObject *parent)
  104. : QAbstractListModel(parent)
  105. {
  106. connect(ProjectExplorer::ProjectExplorerPlugin::instance(),
  107. &ProjectExplorer::ProjectExplorerPlugin::recentProjectsChanged,
  108. this,
  109. &ProjectModel::resetProjects);
  110. if (!Utils::findOrDefault(ExtensionSystem::PluginManager::plugins(),
  111. Utils::equal(&ExtensionSystem::PluginSpec::name, QString("LicenseChecker"))))
  112. m_communityVersion = true;
  113. }
  114. int ProjectModel::rowCount(const QModelIndex &) const
  115. {
  116. return ProjectExplorer::ProjectExplorerPlugin::recentProjects().count();
  117. }
  118. QVariant ProjectModel::data(const QModelIndex &index, int role) const
  119. {
  120. QPair<QString,QString> data =
  121. ProjectExplorer::ProjectExplorerPlugin::recentProjects().at(index.row());
  122. switch (role) {
  123. case Qt::DisplayRole:
  124. return data.second;
  125. break;
  126. case FilePathRole:
  127. return data.first;
  128. case PrettyFilePathRole:
  129. return Utils::withTildeHomePath(data.first);
  130. default:
  131. return QVariant();
  132. }
  133. return QVariant();
  134. }
  135. QHash<int, QByteArray> ProjectModel::roleNames() const
  136. {
  137. QHash<int, QByteArray> roleNames;
  138. roleNames[Qt::DisplayRole] = "displayName";
  139. roleNames[FilePathRole] = "filePath";
  140. roleNames[PrettyFilePathRole] = "prettyFilePath";
  141. return roleNames;
  142. }
  143. void ProjectModel::resetProjects()
  144. {
  145. beginResetModel();
  146. endResetModel();
  147. }
  148. class WelcomeMode : public Core::IMode
  149. {
  150. Q_OBJECT
  151. public:
  152. WelcomeMode();
  153. ~WelcomeMode() override;
  154. private:
  155. QQuickWidget *m_modeWidget = nullptr;
  156. };
  157. void StudioWelcomePlugin::closeSplashScreen()
  158. {
  159. if (!s_view.isNull()) {
  160. const bool doNotShowAgain = s_view->rootObject()->property("doNotShowAgain").toBool();
  161. if (doNotShowAgain)
  162. Utils::CheckableMessageBox::doNotAskAgain(Core::ICore::settings(),
  163. DO_NOT_SHOW_SPLASHSCREEN_AGAIN_KEY);
  164. s_view->deleteLater();
  165. }
  166. }
  167. StudioWelcomePlugin::~StudioWelcomePlugin()
  168. {
  169. delete m_welcomeMode;
  170. }
  171. bool StudioWelcomePlugin::initialize(const QStringList &arguments, QString *errorString)
  172. {
  173. Q_UNUSED(arguments)
  174. Q_UNUSED(errorString)
  175. qmlRegisterType<ProjectModel>("projectmodel", 1, 0, "ProjectModel");
  176. m_welcomeMode = new WelcomeMode;
  177. QFontDatabase fonts;
  178. QFontDatabase::addApplicationFont(":/studiofonts/TitilliumWeb-Regular.ttf");
  179. QFont systemFont("Titillium Web", QApplication::font().pointSize());
  180. QApplication::setFont(systemFont);
  181. return true;
  182. }
  183. void StudioWelcomePlugin::extensionsInitialized()
  184. {
  185. Core::ModeManager::activateMode(m_welcomeMode->id());
  186. if (Utils::CheckableMessageBox::shouldAskAgain(Core::ICore::settings(),
  187. DO_NOT_SHOW_SPLASHSCREEN_AGAIN_KEY)) {
  188. connect(Core::ICore::instance(), &Core::ICore::coreOpened, this, [this] (){
  189. s_view = new QQuickWidget(Core::ICore::dialogParent());
  190. s_view->setResizeMode(QQuickWidget::SizeRootObjectToView);
  191. s_view->setWindowFlag(Qt::SplashScreen, true);
  192. s_view->setWindowModality(Qt::ApplicationModal);
  193. s_view->engine()->addImportPath("qrc:/studiofonts");
  194. #ifdef QT_DEBUG
  195. s_view->engine()->addImportPath(QLatin1String(STUDIO_QML_PATH)
  196. + "splashscreen/imports");
  197. s_view->setSource(QUrl::fromLocalFile(QLatin1String(STUDIO_QML_PATH)
  198. + "splashscreen/main.qml"));
  199. #else
  200. s_view->engine()->addImportPath("qrc:/qml/splashscreen/imports");
  201. s_view->setSource(QUrl("qrc:/qml/splashscreen/main.qml"));
  202. #endif
  203. QTC_ASSERT(s_view->rootObject(),
  204. qWarning() << "The StudioWelcomePlugin has a runtime depdendency on qt/qtquicktimeline.";
  205. return);
  206. connect(s_view->rootObject(), SIGNAL(closeClicked()), this, SLOT(closeSplashScreen()));
  207. s_view->show();
  208. s_view->raise();
  209. QTimer::singleShot(15000, [this](){ closeSplashScreen(); });
  210. });
  211. }
  212. }
  213. bool StudioWelcomePlugin::delayedInitialize()
  214. {
  215. if (s_view.isNull())
  216. return true;
  217. QTC_ASSERT(s_view->rootObject() , return true);
  218. s_view->rootObject()->setProperty("loadingPlugins", false);
  219. QPointer<QQuickWidget> view = s_view;
  220. connect(Core::ICore::mainWindow()->windowHandle(), &QWindow::visibleChanged, this, [view](){
  221. if (!view.isNull()) {
  222. view->close();
  223. view->deleteLater();
  224. }
  225. });
  226. return false;
  227. }
  228. WelcomeMode::WelcomeMode()
  229. {
  230. setDisplayName(tr("Studio"));
  231. const Utils::Icon FLAT({{":/studiowelcome/images/mode_welcome_mask.png",
  232. Utils::Theme::IconsBaseColor}});
  233. const Utils::Icon FLAT_ACTIVE({{":/studiowelcome/images/mode_welcome_mask.png",
  234. Utils::Theme::IconsModeWelcomeActiveColor}});
  235. setIcon(Utils::Icon::modeIcon(FLAT, FLAT, FLAT_ACTIVE));
  236. setPriority(Core::Constants::P_MODE_WELCOME);
  237. setId(Core::Constants::MODE_WELCOME);
  238. setContextHelp("Qt Creator Manual");
  239. setContext(Core::Context(Core::Constants::C_WELCOME_MODE));
  240. m_modeWidget = new QQuickWidget;
  241. m_modeWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
  242. m_modeWidget->engine()->addImportPath("qrc:/studiofonts");
  243. #ifdef QT_DEBUG
  244. m_modeWidget->engine()->addImportPath(QLatin1String(STUDIO_QML_PATH)
  245. + "welcomepage/imports");
  246. m_modeWidget->setSource(QUrl::fromLocalFile(QLatin1String(STUDIO_QML_PATH)
  247. + "welcomepage/main.qml"));
  248. #else
  249. m_modeWidget->engine()->addImportPath("qrc:/qml/welcomepage/imports");
  250. m_modeWidget->setSource(QUrl("qrc:/qml/welcomepage/main.qml"));
  251. #endif
  252. setWidget(m_modeWidget);
  253. QStringList designStudioQchPathes = {Core::HelpManager::documentationPath()
  254. + "/qtdesignstudio.qch",
  255. Core::HelpManager::documentationPath() + "/qtquick.qch",
  256. Core::HelpManager::documentationPath()
  257. + "/qtquickcontrols.qch"};
  258. Core::HelpManager::registerDocumentation(
  259. Utils::filtered(designStudioQchPathes,
  260. [](const QString &path) { return QFileInfo::exists(path); }));
  261. }
  262. WelcomeMode::~WelcomeMode()
  263. {
  264. delete m_modeWidget;
  265. }
  266. } // namespace Internal
  267. } // namespace StudioWelcome
  268. #include "studiowelcomeplugin.moc"