// Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "examplecheckout.h" #include "studiowelcomeplugin.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Tasking; using namespace Utils; void ExampleCheckout::registerTypes() { static bool once = []() { qmlRegisterType("ExampleCheckout", 1, 0, "FileDownloader"); qmlRegisterType("ExampleCheckout", 1, 0, "FileExtractor"); return true; }(); QTC_ASSERT(once, ;); } void DataModelDownloader::usageStatisticsDownloadExample(const QString &name) { QmlDesigner::QmlDesignerPlugin::emitUsageStatistics("exampleDownload:" + name); } bool DataModelDownloader::downloadEnabled() const { const Key lastQDSVersionEntry = "QML/Designer/EnableWelcomePageDownload"; return Core::ICore::settings()->value(lastQDSVersionEntry, false).toBool(); } QString DataModelDownloader::targetPath() const { return QmlDesigner::Paths::examplesPathSetting(); } static FilePath tempFilePath() { QStandardPaths::StandardLocation location = QStandardPaths::CacheLocation; return FilePath::fromString(QStandardPaths::writableLocation(location)) .pathAppended("QtDesignStudio"); } DataModelDownloader::DataModelDownloader(QObject * /* parent */) { auto fileInfo = targetFolder().toFileInfo(); m_birthTime = fileInfo.lastModified(); m_exists = fileInfo.exists(); m_fileDownloader.setProbeUrl(true); connect(&m_fileDownloader, &QmlDesigner::FileDownloader::progressChanged, this, &DataModelDownloader::progressChanged); connect(&m_fileDownloader, &QmlDesigner::FileDownloader::downloadFailed, this, &DataModelDownloader::downloadFailed); const ExtensionSystem::PluginSpec *pluginSpec = Utils::findOrDefault(ExtensionSystem::PluginManager::plugins(), Utils::equal(&ExtensionSystem::PluginSpec::name, QString("StudioWelcome"))); if (!pluginSpec) return; ExtensionSystem::IPlugin *plugin = pluginSpec->plugin(); if (!plugin) return; auto studioWelcomePlugin = qobject_cast(plugin); QmlDesigner::StudioConfigSettingsPage *settingsPage = QmlDesigner::QmlDesignerBasePlugin::studioConfigSettingsPage(); if (studioWelcomePlugin && settingsPage) { QObject::connect(settingsPage, &QmlDesigner::StudioConfigSettingsPage::examplesDownloadPathChanged, this, &DataModelDownloader::targetPathMustChange); } connect(&m_fileDownloader, &QmlDesigner::FileDownloader::finishedChanged, this, [this] { m_started = false; if (m_fileDownloader.finished()) { const FilePath archiveFile = FilePath::fromString(m_fileDownloader.outputFile()); const auto sourceAndCommand = Unarchiver::sourceAndCommand(archiveFile); QTC_ASSERT(sourceAndCommand, return); auto unarchiver = new Unarchiver; unarchiver->setSourceAndCommand(*sourceAndCommand); unarchiver->setDestDir(tempFilePath()); QObject::connect(unarchiver, &Unarchiver::done, this, [this, unarchiver](DoneResult result) { QTC_CHECK(result == DoneResult::Success); unarchiver->deleteLater(); emit finished(); }); unarchiver->start(); } }); } void DataModelDownloader::onAvailableChanged() { m_available = m_fileDownloader.available(); emit availableChanged(); if (!m_available) { qWarning() << m_fileDownloader.url() << "failed to download"; return; } if (!m_forceDownload && (m_fileDownloader.lastModified() <= m_birthTime)) return; m_started = true; m_fileDownloader.start(); } bool DataModelDownloader::start() { if (!downloadEnabled()) { m_available = false; emit availableChanged(); return false; } m_fileDownloader.setDownloadEnabled(true); m_fileDownloader.setUrl(QUrl::fromUserInput( "https://download.qt.io/learning/examples/qtdesignstudio/dataImports.zip")); m_started = false; connect(&m_fileDownloader, &QmlDesigner::FileDownloader::availableChanged, this, &DataModelDownloader::onAvailableChanged); return m_started; } bool DataModelDownloader::exists() const { return m_exists; } bool DataModelDownloader::available() const { return m_available; } FilePath DataModelDownloader::targetFolder() const { return FilePath::fromUserInput(tempFilePath().toString() + "/" + "dataImports"); } void DataModelDownloader::setForceDownload(bool b) { m_forceDownload = b; } int DataModelDownloader::progress() const { return m_fileDownloader.progress(); }