forked from qt-creator/qt-creator
Move decision on which Qt to use for examples to ExamplesListModel.
Was split between list model and Qt version manager. It's easier to follow what actually happens now, and the change makes it possible to delay that decision to a point where it's necessary. Change-Id: I4bffca2e9207ad32bba9ee4766b62d1a1f9687cd Reviewed-by: Daniel Molkentin <daniel.molkentin@nokia.com>
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/helpmanager.h>
|
||||
#include <qtsupport/qtversionmanager.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -52,7 +53,8 @@ namespace QtSupport {
|
||||
namespace Internal {
|
||||
|
||||
ExamplesListModel::ExamplesListModel(QObject *parent) :
|
||||
QAbstractListModel(parent)
|
||||
QAbstractListModel(parent),
|
||||
m_updateOnQtVersionsChanged(false)
|
||||
{
|
||||
QHash<int, QByteArray> roleNames;
|
||||
roleNames[Name] = "name";
|
||||
@@ -71,10 +73,10 @@ ExamplesListModel::ExamplesListModel(QObject *parent) :
|
||||
roleNames[VideoLength] = "videoLength";
|
||||
setRoleNames(roleNames);
|
||||
|
||||
connect(QtVersionManager::instance(), SIGNAL(updateExamples(QString,QString,QString)),
|
||||
SLOT(cacheExamplesPath(QString,QString,QString)));
|
||||
connect(Core::HelpManager::instance(), SIGNAL(setupFinished()),
|
||||
SLOT(helpInitialized()));
|
||||
connect(QtVersionManager::instance(), SIGNAL(qtVersionsChanged(QList<int>)),
|
||||
this, SLOT(handleQtVersionsChanged()));
|
||||
}
|
||||
|
||||
static inline QString fixStringForTags(const QString &string)
|
||||
@@ -223,30 +225,40 @@ QList<ExampleItem> ExamplesListModel::parseTutorials(QXmlStreamReader* reader, c
|
||||
return tutorials;
|
||||
}
|
||||
|
||||
void ExamplesListModel::readNewsItems(const QString &examplesPath, const QString &demosPath, const QString & sourcePath)
|
||||
void ExamplesListModel::handleQtVersionsChanged()
|
||||
{
|
||||
if (m_updateOnQtVersionsChanged)
|
||||
updateExamples();
|
||||
}
|
||||
|
||||
void ExamplesListModel::updateExamples()
|
||||
{
|
||||
clear();
|
||||
foreach (const QString exampleSource, exampleSources()) {
|
||||
QString examplesFallback;
|
||||
QString demosFallback;
|
||||
QString sourceFallback;
|
||||
foreach (const QString &exampleSource,
|
||||
exampleSources(&examplesFallback, &demosFallback, &sourceFallback)) {
|
||||
QFile exampleFile(exampleSource);
|
||||
if (!exampleFile.open(QIODevice::ReadOnly)) {
|
||||
qDebug() << Q_FUNC_INFO << "Could not open file" << exampleSource;
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
QFileInfo fi(exampleSource);
|
||||
QString offsetPath = fi.path();
|
||||
QDir examplesDir(offsetPath);
|
||||
QDir demosDir(offsetPath);
|
||||
if (offsetPath.startsWith(Core::ICore::resourcePath())) {
|
||||
// Try to get dir from first Qt Version, based on the Qt source directory
|
||||
// at first, since examplesPath / demosPath points at the build directory
|
||||
examplesDir = sourcePath + QLatin1String("/examples");
|
||||
demosDir = sourcePath + QLatin1String("/demos");
|
||||
// SDK case, folders might be called sth else (e.g. 'Examples' with uppercase E)
|
||||
// but examplesPath / demosPath is correct
|
||||
if (!examplesFallback.isEmpty()) {
|
||||
// Look at Qt source directory at first,
|
||||
// since examplesPath() / demosPath() points at the build directory
|
||||
examplesDir = sourceFallback + QLatin1String("/examples");
|
||||
demosDir = sourceFallback + QLatin1String("/demos");
|
||||
// if examples or demos don't exist in source, try the directories
|
||||
// that qmake -query gave (i.e. in the build directory)
|
||||
if (!examplesDir.exists() || !demosDir.exists()) {
|
||||
examplesDir = examplesPath;
|
||||
demosDir = demosPath;
|
||||
examplesDir = examplesFallback;
|
||||
demosDir = demosFallback;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,10 +286,17 @@ void ExamplesListModel::readNewsItems(const QString &examplesPath, const QString
|
||||
emit tagsUpdated();
|
||||
}
|
||||
|
||||
QStringList ExamplesListModel::exampleSources() const
|
||||
QStringList ExamplesListModel::exampleSources(QString *examplesFallback, QString *demosFallback,
|
||||
QString *sourceFallback)
|
||||
{
|
||||
QFileInfoList sources;
|
||||
const QStringList pattern(QLatin1String("*.xml"));
|
||||
QTC_CHECK(examplesFallback);
|
||||
QTC_CHECK(demosFallback);
|
||||
QTC_CHECK(sourceFallback);
|
||||
QStringList sources;
|
||||
QString resourceDir = Core::ICore::resourcePath() + QLatin1String("/welcomescreen/");
|
||||
|
||||
// Qt Creator shipped tutorials
|
||||
sources << (resourceDir + QLatin1String("/qtcreator_tutorials.xml"));
|
||||
|
||||
// Read keys from SDK installer
|
||||
QSettings *settings = Core::ICore::settings(QSettings::SystemScope);
|
||||
@@ -287,47 +306,61 @@ QStringList ExamplesListModel::exampleSources() const
|
||||
sources.append(settings->value(QLatin1String("Location")).toString());
|
||||
}
|
||||
settings->endArray();
|
||||
// if the installer set something, that's enough for us
|
||||
if (size > 0)
|
||||
return sources;
|
||||
|
||||
// try to find a suitable Qt version
|
||||
m_updateOnQtVersionsChanged = true; // this must be updated when the qt versions change
|
||||
// fallbacks are passed back if no example manifest is found
|
||||
// and we fallback to Qt Creator's shipped manifest (e.g. only old Qt Versions found)
|
||||
QString potentialExamplesFallback;
|
||||
QString potentialDemosFallback;
|
||||
QString potentialSourceFallback;
|
||||
bool potentialFallbackHasDeclarative = false; // we prefer Qt's with declarative as fallback
|
||||
const QStringList pattern(QLatin1String("*.xml"));
|
||||
|
||||
bool anyQtVersionHasExamplesFolder = false;
|
||||
if (sources.isEmpty()) {
|
||||
// Try to get dir from first Qt Version
|
||||
QtVersionManager *versionManager = QtVersionManager::instance();
|
||||
foreach (BaseQtVersion *version, versionManager->validVersions()) {
|
||||
// There is no good solution for Qt 5 yet
|
||||
if (version->qtVersion().majorVersion != 4)
|
||||
continue;
|
||||
QtVersionManager *versionManager = QtVersionManager::instance();
|
||||
foreach (BaseQtVersion *version, versionManager->validVersions()) {
|
||||
// There is no good solution for Qt 5 yet
|
||||
if (version->qtVersion().majorVersion != 4)
|
||||
continue;
|
||||
|
||||
QDir examplesDir(version->examplesPath());
|
||||
if (examplesDir.exists()) {
|
||||
sources << examplesDir.entryInfoList(pattern);
|
||||
anyQtVersionHasExamplesFolder = true;
|
||||
QFileInfoList fis;
|
||||
if (version->hasExamples())
|
||||
fis << QDir(version->examplesPath()).entryInfoList(pattern);
|
||||
if (version->hasDemos())
|
||||
fis << QDir(version->demosPath()).entryInfoList(pattern);
|
||||
if (!fis.isEmpty()) {
|
||||
foreach (const QFileInfo &fi, fis)
|
||||
sources.append(fi.filePath());
|
||||
return sources;
|
||||
}
|
||||
// check if this Qt version would be the preferred fallback
|
||||
if (version->hasExamples() && version->hasDemos()) { // cached, so no performance hit
|
||||
bool hasDeclarative = QDir(version->examplesPath() + QLatin1String("/declarative")).exists();
|
||||
if (potentialExamplesFallback.isEmpty()
|
||||
|| (!potentialFallbackHasDeclarative && hasDeclarative)) {
|
||||
potentialFallbackHasDeclarative = hasDeclarative;
|
||||
potentialExamplesFallback = version->examplesPath();
|
||||
potentialDemosFallback = version->demosPath();
|
||||
potentialSourceFallback = version->sourcePath().toString();
|
||||
}
|
||||
|
||||
QDir demosDir(version->demosPath());
|
||||
if (demosDir.exists())
|
||||
sources << demosDir.entryInfoList(pattern);
|
||||
|
||||
if (!sources.isEmpty())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QString resourceDir = Core::ICore::resourcePath() + QLatin1String("/welcomescreen/");
|
||||
|
||||
// Try Creator-provided XML file only
|
||||
if (sources.isEmpty() && anyQtVersionHasExamplesFolder) {
|
||||
if (!potentialExamplesFallback.isEmpty()) {
|
||||
// We didn't find a manifest, use Creator-provided XML file with fall back Qt version
|
||||
// qDebug() << Q_FUNC_INFO << "falling through to Creator-provided XML file";
|
||||
sources << QString(resourceDir + QLatin1String("/examples_fallback.xml"));
|
||||
if (examplesFallback)
|
||||
*examplesFallback = potentialExamplesFallback;
|
||||
if (demosFallback)
|
||||
*demosFallback = potentialDemosFallback;
|
||||
if (sourceFallback)
|
||||
*sourceFallback = potentialSourceFallback;
|
||||
}
|
||||
|
||||
sources << QString(resourceDir + QLatin1String("/qtcreator_tutorials.xml"));
|
||||
|
||||
QStringList ret;
|
||||
foreach (const QFileInfo& source, sources)
|
||||
ret.append(source.filePath());
|
||||
|
||||
return ret;
|
||||
return sources;
|
||||
}
|
||||
|
||||
void ExamplesListModel::clear()
|
||||
@@ -400,17 +433,9 @@ QVariant ExamplesListModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
}
|
||||
|
||||
void ExamplesListModel::cacheExamplesPath(const QString &examplesPath, const QString &demosPath, const QString &sourcePath)
|
||||
{
|
||||
m_cache = QMakePathCache(examplesPath, demosPath, sourcePath);
|
||||
}
|
||||
|
||||
void ExamplesListModel::helpInitialized()
|
||||
{
|
||||
disconnect(this, SLOT(cacheExamplesPath(QString, QString, QString)));
|
||||
connect(QtVersionManager::instance(), SIGNAL(updateExamples(QString,QString,QString)),
|
||||
SLOT(readNewsItems(QString,QString,QString)));
|
||||
readNewsItems(m_cache.examplesPath, m_cache.demosPath, m_cache.sourcePath);
|
||||
updateExamples();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -65,15 +65,6 @@ struct ExampleItem {
|
||||
QString videoLength;
|
||||
};
|
||||
|
||||
struct QMakePathCache {
|
||||
QString examplesPath;
|
||||
QString demosPath;
|
||||
QString sourcePath;
|
||||
QMakePathCache() {}
|
||||
QMakePathCache(const QString &_examplesPath, const QString &_demosPath, const QString &_sourcePath)
|
||||
: examplesPath(_examplesPath), demosPath(_demosPath), sourcePath(_sourcePath) {}
|
||||
};
|
||||
|
||||
class ExamplesListModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -90,8 +81,8 @@ signals:
|
||||
void tagsUpdated();
|
||||
|
||||
public slots:
|
||||
void readNewsItems(const QString &examplesPath, const QString &demosPath, const QString &sourcePath);
|
||||
void cacheExamplesPath(const QString &examplesPath, const QString &demosPath, const QString &sourcePath);
|
||||
void handleQtVersionsChanged();
|
||||
void updateExamples();
|
||||
void helpInitialized();
|
||||
|
||||
private:
|
||||
@@ -99,11 +90,11 @@ private:
|
||||
QList<ExampleItem> parseDemos(QXmlStreamReader* reader, const QString& projectsOffset);
|
||||
QList<ExampleItem> parseTutorials(QXmlStreamReader* reader, const QString& projectsOffset);
|
||||
void clear();
|
||||
QStringList exampleSources() const;
|
||||
QStringList exampleSources(QString *examplesFallback, QString *demosFallback,
|
||||
QString *sourceFallback);
|
||||
QList<ExampleItem> exampleItems;
|
||||
QStringList m_tags;
|
||||
QMakePathCache m_cache;
|
||||
|
||||
bool m_updateOnQtVersionsChanged;
|
||||
};
|
||||
|
||||
class ExamplesListModelFilter : public QSortFilterProxyModel {
|
||||
|
||||
@@ -138,7 +138,7 @@ void QtVersionManager::extensionsInitialized()
|
||||
findSystemQt();
|
||||
}
|
||||
|
||||
connect(Core::ICore::instance(), SIGNAL(coreOpened()), this, SLOT(delayedUpdateSettings()));
|
||||
connect(Core::ICore::instance(), SIGNAL(coreOpened()), this, SLOT(delayedUpdateDocumentation()));
|
||||
saveQtVersions();
|
||||
}
|
||||
|
||||
@@ -513,54 +513,9 @@ void QtVersionManager::updateDumpFor(const Utils::FileName &qmakeCommand)
|
||||
emit dumpUpdatedFor(qmakeCommand);
|
||||
}
|
||||
|
||||
void QtVersionManager::delayedUpdateSettings()
|
||||
void QtVersionManager::delayedUpdateDocumentation()
|
||||
{
|
||||
QTimer::singleShot(100, this, SLOT(updateSettings()));
|
||||
}
|
||||
|
||||
void QtVersionManager::updateSettings()
|
||||
{
|
||||
updateDocumentation();
|
||||
BaseQtVersion *version = 0;
|
||||
QList<BaseQtVersion *> candidates;
|
||||
|
||||
// try to find a version which has both, demos and examples
|
||||
foreach (BaseQtVersion *version, m_versions) {
|
||||
if (version && version->hasExamples() && version->hasDemos())
|
||||
candidates.append(version);
|
||||
}
|
||||
|
||||
// in SDKs, we want to prefer the Qt version shipping with the SDK
|
||||
QSettings *settings = Core::ICore::settings();
|
||||
Utils::FileName preferred = Utils::FileName::fromUserInput(settings->value(QLatin1String("PreferredQMakePath")).toString());
|
||||
if (!preferred.isEmpty()) {
|
||||
#ifdef Q_OS_WIN
|
||||
if (!preferred.endsWith(".exe"))
|
||||
preferred.append(".exe");
|
||||
#endif
|
||||
foreach (version, candidates) {
|
||||
if (version->qmakeCommand() == preferred) {
|
||||
emit updateExamples(version->examplesPath(), version->demosPath(), version->sourcePath().toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// prefer versions with declarative examples
|
||||
foreach (version, candidates) {
|
||||
if (QDir(version->examplesPath() + QLatin1String("/declarative")).exists()) {
|
||||
emit updateExamples(version->examplesPath(), version->demosPath(), version->sourcePath().toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!candidates.isEmpty()) {
|
||||
version = candidates.first();
|
||||
emit updateExamples(version->examplesPath(), version->demosPath(), version->sourcePath().toString());
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
QTimer::singleShot(100, this, SLOT(updateDocumentation()));
|
||||
}
|
||||
|
||||
int QtVersionManager::getUniqueId()
|
||||
@@ -696,7 +651,6 @@ void QtVersionManager::setNewQtVersions(QList<BaseQtVersion *> newVersions)
|
||||
if (!changedVersions.isEmpty())
|
||||
updateDocumentation();
|
||||
|
||||
updateSettings();
|
||||
saveQtVersions();
|
||||
|
||||
if (!changedVersions.isEmpty())
|
||||
|
||||
@@ -107,14 +107,13 @@ signals:
|
||||
// content of BaseQtVersion objects with qmake path might have changed
|
||||
void dumpUpdatedFor(const Utils::FileName &qmakeCommand);
|
||||
void qtVersionsChanged(const QList<int> &uniqueIds);
|
||||
void updateExamples(QString, QString, QString);
|
||||
|
||||
public slots:
|
||||
void updateDumpFor(const Utils::FileName &qmakeCommand);
|
||||
|
||||
private slots:
|
||||
void delayedUpdateSettings();
|
||||
void updateSettings();
|
||||
void delayedUpdateDocumentation();
|
||||
void updateDocumentation();
|
||||
|
||||
private:
|
||||
// This function is really simplistic...
|
||||
@@ -137,7 +136,6 @@ private:
|
||||
// Used by QtVersion
|
||||
int getUniqueId();
|
||||
void addNewVersionsFromInstaller();
|
||||
void updateDocumentation();
|
||||
|
||||
static int indexOfVersionInList(const BaseQtVersion * const version, const QList<BaseQtVersion *> &list);
|
||||
void updateUniqueIdToIndexMap();
|
||||
|
||||
Reference in New Issue
Block a user