forked from qt-creator/qt-creator
StudioWelcome: Download data from Qt.io
We try to download new updated data from Qt.io if it is newer. In any case we provide a default that comes with QDS. I removed the check for QmlData, since they should not be required and they stop FileDownloader from running from "pure" C++. Task-number: QDS-6886 Change-Id: I1332c194286e6e91dfcd1c6605931f1ed020bc29 Reviewed-by: Henning Gründl <henning.gruendl@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -196,17 +196,6 @@ void FileDownloader::probeUrl()
|
|||||||
});
|
});
|
||||||
|
|
||||||
QNetworkReply::connect(reply, &QNetworkReply::finished, this, [this, reply]() {
|
QNetworkReply::connect(reply, &QNetworkReply::finished, this, [this, reply]() {
|
||||||
QQmlData *data = QQmlData::get(this, false);
|
|
||||||
if (!data) {
|
|
||||||
qDebug() << Q_FUNC_INFO << "FileDownloader is nullptr.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (QQmlData::wasDeleted(this)) {
|
|
||||||
qDebug() << Q_FUNC_INFO << "FileDownloader was deleted.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reply->error())
|
if (reply->error())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -435,3 +424,76 @@ void FileExtractor::extract()
|
|||||||
QTC_ASSERT(ret, ;);
|
QTC_ASSERT(ret, ;);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Utils::FilePath tempFilePath()
|
||||||
|
{
|
||||||
|
QStandardPaths::StandardLocation location = QStandardPaths::CacheLocation;
|
||||||
|
|
||||||
|
return Utils::FilePath::fromString(QStandardPaths::writableLocation(location))
|
||||||
|
.pathAppended("QtDesignStudio");
|
||||||
|
}
|
||||||
|
|
||||||
|
DataModelDownloader::DataModelDownloader(QObject * /* parent */)
|
||||||
|
{
|
||||||
|
auto fileInfo = targetFolder().toFileInfo();
|
||||||
|
m_birthTime = fileInfo.birthTime();
|
||||||
|
m_exists = fileInfo.exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataModelDownloader::start()
|
||||||
|
{
|
||||||
|
m_fileDownloader.setUrl(QUrl::fromUserInput(
|
||||||
|
"https://download.qt.io/learning/examples/qtdesignstudio/dataImports.zip"));
|
||||||
|
|
||||||
|
connect(&m_fileDownloader, &FileDownloader::availableChanged, this, [this]() {
|
||||||
|
|
||||||
|
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_fileDownloader.start();
|
||||||
|
connect(&m_fileDownloader, &FileDownloader::finishedChanged, this, [this]() {
|
||||||
|
if (m_fileDownloader.finished()) {
|
||||||
|
Utils::Archive *archive = Utils::Archive::unarchive(Utils::FilePath::fromString(
|
||||||
|
m_fileDownloader.tempFile()),
|
||||||
|
tempFilePath());
|
||||||
|
|
||||||
|
archive->setParent(this);
|
||||||
|
QTC_ASSERT(archive, return );
|
||||||
|
|
||||||
|
QObject::connect(archive, &Utils::Archive::finished, this, [this](bool ret) {
|
||||||
|
emit finished();
|
||||||
|
QTC_ASSERT(ret, ;);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DataModelDownloader::exists() const
|
||||||
|
{
|
||||||
|
return m_exists;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DataModelDownloader::available() const
|
||||||
|
{
|
||||||
|
return m_available;
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils::FilePath DataModelDownloader::targetFolder() const
|
||||||
|
{
|
||||||
|
return Utils::FilePath::fromUserInput(tempFilePath().toString() + "/" + "dataImports");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataModelDownloader::setForceDownload(bool b)
|
||||||
|
{
|
||||||
|
m_forceDownload = b;
|
||||||
|
}
|
||||||
|
@@ -154,5 +154,29 @@ private:
|
|||||||
int m_progress = 0;
|
int m_progress = 0;
|
||||||
QFile m_tempFile;
|
QFile m_tempFile;
|
||||||
QDateTime m_lastModified;
|
QDateTime m_lastModified;
|
||||||
bool m_available;
|
bool m_available = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DataModelDownloader : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DataModelDownloader(QObject *parent = nullptr);
|
||||||
|
void start();
|
||||||
|
bool exists() const;
|
||||||
|
bool available() const;
|
||||||
|
Utils::FilePath targetFolder() const;
|
||||||
|
void setForceDownload(bool b);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished();
|
||||||
|
void availableChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
FileDownloader m_fileDownloader;
|
||||||
|
QDateTime m_birthTime;
|
||||||
|
bool m_exists = false;
|
||||||
|
bool m_available = false;
|
||||||
|
bool m_forceDownload = false;
|
||||||
};
|
};
|
||||||
|
@@ -498,6 +498,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QQuickWidget *m_modeWidget = nullptr;
|
QQuickWidget *m_modeWidget = nullptr;
|
||||||
|
DataModelDownloader *m_dataModelDownloader = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
void StudioWelcomePlugin::closeSplashScreen()
|
void StudioWelcomePlugin::closeSplashScreen()
|
||||||
@@ -647,6 +648,28 @@ WelcomeMode::WelcomeMode()
|
|||||||
{
|
{
|
||||||
setDisplayName(tr("Welcome"));
|
setDisplayName(tr("Welcome"));
|
||||||
|
|
||||||
|
const QString welcomePagePath = Core::ICore::resourcePath("qmldesigner/welcomepage").toString();
|
||||||
|
|
||||||
|
m_dataModelDownloader = new DataModelDownloader(this);
|
||||||
|
if (!m_dataModelDownloader->exists()) { //Fallback if data cannot be downloaded
|
||||||
|
Utils::FileUtils::copyRecursively(Utils::FilePath::fromUserInput(welcomePagePath
|
||||||
|
+ "/dataImports"),
|
||||||
|
m_dataModelDownloader->targetFolder());
|
||||||
|
m_dataModelDownloader->setForceDownload(true);
|
||||||
|
}
|
||||||
|
Utils::FilePath readme = Utils::FilePath::fromUserInput(welcomePagePath
|
||||||
|
+ "/dataImports/readme.txt");
|
||||||
|
|
||||||
|
if (!readme.exists()) // Only downloads contain the readme
|
||||||
|
m_dataModelDownloader->setForceDownload(true);
|
||||||
|
|
||||||
|
m_dataModelDownloader->start();
|
||||||
|
|
||||||
|
connect(m_dataModelDownloader, &DataModelDownloader::finished, this, [this](){
|
||||||
|
auto source = m_modeWidget->source();
|
||||||
|
m_modeWidget->engine()->clearComponentCache();
|
||||||
|
m_modeWidget->setSource(source);
|
||||||
|
});
|
||||||
const Utils::Icon FLAT({{":/studiowelcome/images/mode_welcome_mask.png",
|
const Utils::Icon FLAT({{":/studiowelcome/images/mode_welcome_mask.png",
|
||||||
Utils::Theme::IconsBaseColor}});
|
Utils::Theme::IconsBaseColor}});
|
||||||
const Utils::Icon FLAT_ACTIVE({{":/studiowelcome/images/mode_welcome_mask.png",
|
const Utils::Icon FLAT_ACTIVE({{":/studiowelcome/images/mode_welcome_mask.png",
|
||||||
@@ -691,9 +714,8 @@ WelcomeMode::WelcomeMode()
|
|||||||
|
|
||||||
m_modeWidget->engine()->addImportPath(Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources/imports").toString());
|
m_modeWidget->engine()->addImportPath(Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources/imports").toString());
|
||||||
|
|
||||||
const QString welcomePagePath = Core::ICore::resourcePath("qmldesigner/welcomepage").toString();
|
|
||||||
m_modeWidget->engine()->addImportPath(welcomePagePath + "/imports");
|
m_modeWidget->engine()->addImportPath(welcomePagePath + "/imports");
|
||||||
m_modeWidget->engine()->addImportPath(welcomePagePath + "/dataImports");
|
m_modeWidget->engine()->addImportPath(m_dataModelDownloader->targetFolder().toString());
|
||||||
m_modeWidget->setSource(QUrl::fromLocalFile(welcomePagePath + "/main.qml"));
|
m_modeWidget->setSource(QUrl::fromLocalFile(welcomePagePath + "/main.qml"));
|
||||||
|
|
||||||
QShortcut *updateShortcut = nullptr;
|
QShortcut *updateShortcut = nullptr;
|
||||||
|
Reference in New Issue
Block a user