Commit 7b708cd3 authored by Eike Ziller's avatar Eike Ziller
Browse files

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: default avatarDaniel Molkentin <daniel.molkentin@nokia.com>
parent 3c3d231a
......@@ -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;
QDir examplesDir(version->examplesPath());
if (examplesDir.exists()) {
sources << examplesDir.entryInfoList(pattern);
anyQtVersionHasExamplesFolder = true;
QtVersionManager *versionManager = QtVersionManager::instance();
foreach (BaseQtVersion *version, versionManager->validVersions()) {
// There is no good solution for Qt 5 yet
if (version->qtVersion().majorVersion != 4)
continue;
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();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment