forked from qt-creator/qt-creator
QtSupport: Fix and simplify ExampleListModel
This mainly removes no more needed glue code and fixes a recent regression where the example set picker combobox on the Examples welcome page always displayed the name of the first item, no matter which set was displayed on the main canvas Task-number: QTCREATORBUG-15727 Change-Id: I15b4c97f2e079a7470f6f63cde587dd4be58c40e Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -186,20 +186,9 @@ int ExampleSetModel::getExtraExampleSetIndex(int i) const
|
|||||||
return variant.toInt();
|
return variant.toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<int, QByteArray> ExampleSetModel::roleNames() const
|
|
||||||
{
|
|
||||||
static QHash<int, QByteArray> roleNames{
|
|
||||||
{Qt::UserRole + 1, "text"},
|
|
||||||
{Qt::UserRole + 2, "QtId"},
|
|
||||||
{Qt::UserRole + 3, "extraSetIndex"}
|
|
||||||
};
|
|
||||||
return roleNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExamplesListModel::ExamplesListModel(QObject *parent) :
|
ExamplesListModel::ExamplesListModel(QObject *parent) :
|
||||||
QAbstractListModel(parent),
|
QAbstractListModel(parent),
|
||||||
m_exampleSetModel(new ExampleSetModel(this, this)),
|
m_exampleSetModel(new ExampleSetModel(this, this))
|
||||||
m_selectedExampleSetIndex(-1)
|
|
||||||
{
|
{
|
||||||
// read extra example sets settings
|
// read extra example sets settings
|
||||||
QSettings *settings = Core::ICore::settings();
|
QSettings *settings = Core::ICore::settings();
|
||||||
@@ -625,77 +614,21 @@ QString prefixForItem(const ExampleItem &item)
|
|||||||
|
|
||||||
QVariant ExamplesListModel::data(const QModelIndex &index, int role) const
|
QVariant ExamplesListModel::data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
if (!index.isValid() || index.row()+1 > m_exampleItems.count())
|
if (!index.isValid() || index.row() >= m_exampleItems.count())
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
ExampleItem item = m_exampleItems.at(index.row());
|
const ExampleItem &item = m_exampleItems.at(index.row());
|
||||||
switch (role)
|
switch (role)
|
||||||
{
|
{
|
||||||
case Qt::DisplayRole: // for search only
|
case Qt::DisplayRole: // for search only
|
||||||
return QString(prefixForItem(item) + item.name + QLatin1Char(' ') + item.tags.join(QLatin1Char(' ')));
|
return QString(prefixForItem(item) + item.name + ' ' + item.tags.join(' '));
|
||||||
case Name:
|
case Qt::UserRole:
|
||||||
return item.name;
|
return QVariant::fromValue<ExampleItem>(item);
|
||||||
case ProjectPath:
|
|
||||||
return item.projectPath;
|
|
||||||
case Description:
|
|
||||||
return item.description;
|
|
||||||
case ImageUrl:
|
|
||||||
return item.imageUrl;
|
|
||||||
case DocUrl:
|
|
||||||
return item.docUrl;
|
|
||||||
case FilesToOpen:
|
|
||||||
return item.filesToOpen;
|
|
||||||
case MainFile:
|
|
||||||
return item.mainFile;
|
|
||||||
case Tags:
|
|
||||||
return item.tags;
|
|
||||||
case Difficulty:
|
|
||||||
return item.difficulty;
|
|
||||||
case Dependencies:
|
|
||||||
return item.dependencies;
|
|
||||||
case HasSourceCode:
|
|
||||||
return item.hasSourceCode;
|
|
||||||
case Type:
|
|
||||||
return item.type;
|
|
||||||
case IsVideo:
|
|
||||||
return item.isVideo;
|
|
||||||
case VideoUrl:
|
|
||||||
return item.videoUrl;
|
|
||||||
case VideoLength:
|
|
||||||
return item.videoLength;
|
|
||||||
case Platforms:
|
|
||||||
return item.platforms;
|
|
||||||
case IsHighlighted:
|
|
||||||
return item.isHighlighted;
|
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<int, QByteArray> ExamplesListModel::roleNames() const
|
|
||||||
{
|
|
||||||
static QHash<int, QByteArray> roleNames{
|
|
||||||
{Name, "name"},
|
|
||||||
{ProjectPath, "projectPath"},
|
|
||||||
{ImageUrl, "imageUrl"},
|
|
||||||
{Description, "description"},
|
|
||||||
{DocUrl, "docUrl"},
|
|
||||||
{FilesToOpen, "filesToOpen"},
|
|
||||||
{MainFile, "mainFile"},
|
|
||||||
{Tags, "tags"},
|
|
||||||
{Difficulty, "difficulty"},
|
|
||||||
{Type, "type"},
|
|
||||||
{HasSourceCode, "hasSourceCode"},
|
|
||||||
{Dependencies, "dependencies"},
|
|
||||||
{IsVideo, "isVideo"},
|
|
||||||
{VideoUrl, "videoUrl"},
|
|
||||||
{VideoLength, "videoLength"},
|
|
||||||
{Platforms, "platforms"},
|
|
||||||
{IsHighlighted, "isHighlighted"}
|
|
||||||
};
|
|
||||||
return roleNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExamplesListModel::update()
|
void ExamplesListModel::update()
|
||||||
{
|
{
|
||||||
updateQtVersions();
|
updateQtVersions();
|
||||||
@@ -713,20 +646,19 @@ void ExamplesListModel::selectExampleSet(int index)
|
|||||||
m_selectedExampleSetIndex = index;
|
m_selectedExampleSetIndex = index;
|
||||||
m_exampleSetModel->writeCurrentIdToSettings(m_selectedExampleSetIndex);
|
m_exampleSetModel->writeCurrentIdToSettings(m_selectedExampleSetIndex);
|
||||||
updateExamples();
|
updateExamples();
|
||||||
emit selectedExampleSetChanged();
|
emit selectedExampleSetChanged(m_selectedExampleSetIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExamplesListModelFilter::ExamplesListModelFilter(ExamplesListModel *sourceModel, QObject *parent) :
|
QStringList ExamplesListModel::exampleSets() const
|
||||||
|
{
|
||||||
|
return Utils::transform(m_qtVersions, &BaseQtVersion::displayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExamplesListModelFilter::ExamplesListModelFilter(ExamplesListModel *sourceModel, bool showTutorialsOnly, QObject *parent) :
|
||||||
QSortFilterProxyModel(parent),
|
QSortFilterProxyModel(parent),
|
||||||
m_showTutorialsOnly(true),
|
m_showTutorialsOnly(showTutorialsOnly),
|
||||||
m_sourceModel(sourceModel),
|
m_sourceModel(sourceModel)
|
||||||
m_timerId(0),
|
|
||||||
m_blockIndexUpdate(false),
|
|
||||||
m_qtVersionManagerInitialized(false),
|
|
||||||
m_helpManagerInitialized(false),
|
|
||||||
m_initalized(false),
|
|
||||||
m_exampleDataRequested(false)
|
|
||||||
{
|
{
|
||||||
// initialization hooks
|
// initialization hooks
|
||||||
connect(QtVersionManager::instance(), &QtVersionManager::qtVersionsLoaded,
|
connect(QtVersionManager::instance(), &QtVersionManager::qtVersionsLoaded,
|
||||||
@@ -734,13 +666,10 @@ ExamplesListModelFilter::ExamplesListModelFilter(ExamplesListModel *sourceModel,
|
|||||||
connect(Core::HelpManager::instance(), &Core::HelpManager::setupFinished,
|
connect(Core::HelpManager::instance(), &Core::HelpManager::setupFinished,
|
||||||
this, &ExamplesListModelFilter::helpManagerInitialized);
|
this, &ExamplesListModelFilter::helpManagerInitialized);
|
||||||
|
|
||||||
connect(this, &ExamplesListModelFilter::showTutorialsOnlyChanged,
|
|
||||||
this, &ExamplesListModelFilter::updateFilter);
|
|
||||||
|
|
||||||
connect(m_sourceModel, &ExamplesListModel::selectedExampleSetChanged,
|
|
||||||
this, &ExamplesListModelFilter::exampleSetIndexChanged);
|
|
||||||
|
|
||||||
setSourceModel(m_sourceModel);
|
setSourceModel(m_sourceModel);
|
||||||
|
setDynamicSortFilter(true);
|
||||||
|
setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
sort(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExamplesListModelFilter::updateFilter()
|
void ExamplesListModelFilter::updateFilter()
|
||||||
@@ -761,48 +690,33 @@ void ExamplesListModelFilter::setFilterStrings(const QStringList &arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool containsSubString(const QStringList &list, const QString &substr, Qt::CaseSensitivity cs)
|
|
||||||
{
|
|
||||||
return Utils::contains(list, [&substr, &cs](const QString &elem) {
|
|
||||||
return elem.contains(substr, cs);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ExamplesListModelFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
bool ExamplesListModelFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||||
{
|
{
|
||||||
if (m_showTutorialsOnly) {
|
const ExampleItem item = sourceModel()->index(sourceRow, 0, sourceParent).data(Qt::UserRole).value<ExampleItem>();
|
||||||
int type = sourceModel()->index(sourceRow, 0, sourceParent).data(Type).toInt();
|
|
||||||
if (type != Tutorial)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_showTutorialsOnly) {
|
if (m_showTutorialsOnly && item.type != Tutorial)
|
||||||
int type = sourceModel()->index(sourceRow, 0, sourceParent).data(Type).toInt();
|
return false;
|
||||||
if (type != Example && type != Demo)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QStringList tags = sourceModel()->index(sourceRow, 0, sourceParent).data(Tags).toStringList();
|
if (!m_showTutorialsOnly && item.type != Example && item.type != Demo)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!m_filterTags.isEmpty()) {
|
if (!m_filterTags.isEmpty()) {
|
||||||
return Utils::allOf(m_filterTags, [tags](const QString &filterTag) {
|
return Utils::allOf(m_filterTags, [&item](const QString &filterTag) {
|
||||||
return tags.contains(filterTag);
|
return item.tags.contains(filterTag);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_filterStrings.isEmpty()) {
|
if (!m_filterStrings.isEmpty()) {
|
||||||
const QString description = sourceModel()->index(sourceRow, 0, sourceParent).data(Description).toString();
|
for (const QString &subString : m_filterStrings) {
|
||||||
const QString name = sourceModel()->index(sourceRow, 0, sourceParent).data(Name).toString();
|
|
||||||
|
|
||||||
foreach (const QString &subString, m_filterStrings) {
|
|
||||||
bool wordMatch = false;
|
bool wordMatch = false;
|
||||||
wordMatch |= (bool)name.contains(subString, Qt::CaseInsensitive);
|
wordMatch |= bool(item.name.contains(subString, Qt::CaseInsensitive));
|
||||||
if (wordMatch)
|
if (wordMatch)
|
||||||
continue;
|
continue;
|
||||||
wordMatch |= containsSubString(tags, subString, Qt::CaseInsensitive);
|
const auto subMatch = [&subString](const QString &elem) { return elem.contains(subString); };
|
||||||
|
wordMatch |= Utils::contains(item.tags, subMatch);
|
||||||
if (wordMatch)
|
if (wordMatch)
|
||||||
continue;
|
continue;
|
||||||
wordMatch |= (bool)description.contains(subString, Qt::CaseInsensitive);
|
wordMatch |= bool(item.description.contains(subString, Qt::CaseInsensitive));
|
||||||
if (!wordMatch)
|
if (!wordMatch)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -823,19 +737,6 @@ QVariant ExamplesListModelFilter::data(const QModelIndex &index, int role) const
|
|||||||
return QSortFilterProxyModel::data(index, role);
|
return QSortFilterProxyModel::data(index, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractItemModel* ExamplesListModelFilter::exampleSetModel()
|
|
||||||
{
|
|
||||||
return m_sourceModel->exampleSetModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExamplesListModelFilter::filterForExampleSet(int index)
|
|
||||||
{
|
|
||||||
if (m_blockIndexUpdate || !m_initalized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_sourceModel->selectExampleSet(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExamplesListModelFilter::setFilterTags(const QStringList &arg)
|
void ExamplesListModelFilter::setFilterTags(const QStringList &arg)
|
||||||
{
|
{
|
||||||
if (m_filterTags != arg) {
|
if (m_filterTags != arg) {
|
||||||
@@ -844,17 +745,9 @@ void ExamplesListModelFilter::setFilterTags(const QStringList &arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExamplesListModelFilter::setShowTutorialsOnly(bool showTutorialsOnly)
|
|
||||||
{
|
|
||||||
m_showTutorialsOnly = showTutorialsOnly;
|
|
||||||
emit showTutorialsOnlyChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExamplesListModelFilter::handleQtVersionsChanged()
|
void ExamplesListModelFilter::handleQtVersionsChanged()
|
||||||
{
|
{
|
||||||
m_blockIndexUpdate = true;
|
|
||||||
m_sourceModel->update();
|
m_sourceModel->update();
|
||||||
m_blockIndexUpdate = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExamplesListModelFilter::qtVersionManagerLoaded()
|
void ExamplesListModelFilter::qtVersionManagerLoaded()
|
||||||
@@ -897,11 +790,6 @@ void ExamplesListModelFilter::delayedUpdateFilter()
|
|||||||
m_timerId = startTimer(320);
|
m_timerId = startTimer(320);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ExamplesListModelFilter::exampleSetIndex() const
|
|
||||||
{
|
|
||||||
return m_sourceModel->selectedExampleSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExamplesListModelFilter::timerEvent(QTimerEvent *timerEvent)
|
void ExamplesListModelFilter::timerEvent(QTimerEvent *timerEvent)
|
||||||
{
|
{
|
||||||
if (m_timerId == timerEvent->timerId()) {
|
if (m_timerId == timerEvent->timerId()) {
|
||||||
@@ -1026,10 +914,5 @@ void ExamplesListModelFilter::setSearchString(const QString &arg)
|
|||||||
delayedUpdateFilter();
|
delayedUpdateFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ExamplesListModelFilter::searchString() const
|
|
||||||
{
|
|
||||||
return m_searchString;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace QtSupport
|
} // namespace QtSupport
|
||||||
|
|||||||
@@ -63,19 +63,9 @@ public:
|
|||||||
int getExtraExampleSetIndex(int index) const;
|
int getExtraExampleSetIndex(int index) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHash<int, QByteArray> roleNames() const;
|
|
||||||
|
|
||||||
ExamplesListModel *examplesModel;
|
ExamplesListModel *examplesModel;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ExampleRoles
|
|
||||||
{
|
|
||||||
Name = Qt::UserRole, ProjectPath, Description, ImageUrl,
|
|
||||||
DocUrl, FilesToOpen, MainFile, Tags, Difficulty, HasSourceCode,
|
|
||||||
Type, Dependencies, IsVideo, VideoUrl, VideoLength, Platforms,
|
|
||||||
IsHighlighted
|
|
||||||
};
|
|
||||||
|
|
||||||
enum InstructionalType
|
enum InstructionalType
|
||||||
{
|
{
|
||||||
Example = 0, Demo, Tutorial
|
Example = 0, Demo, Tutorial
|
||||||
@@ -83,7 +73,6 @@ enum InstructionalType
|
|||||||
|
|
||||||
struct ExampleItem
|
struct ExampleItem
|
||||||
{
|
{
|
||||||
ExampleItem(): difficulty(0), isVideo(false), isHighlighted(false) {}
|
|
||||||
QString name;
|
QString name;
|
||||||
QString projectPath;
|
QString projectPath;
|
||||||
QString description;
|
QString description;
|
||||||
@@ -94,10 +83,10 @@ struct ExampleItem
|
|||||||
QStringList tags;
|
QStringList tags;
|
||||||
QStringList dependencies;
|
QStringList dependencies;
|
||||||
InstructionalType type;
|
InstructionalType type;
|
||||||
int difficulty;
|
int difficulty = 0;
|
||||||
bool hasSourceCode;
|
bool hasSourceCode = false;
|
||||||
bool isVideo;
|
bool isVideo = false;
|
||||||
bool isHighlighted;
|
bool isHighlighted = false;
|
||||||
QString videoUrl;
|
QString videoUrl;
|
||||||
QString videoLength;
|
QString videoLength;
|
||||||
QStringList platforms;
|
QStringList platforms;
|
||||||
@@ -116,9 +105,8 @@ public:
|
|||||||
|
|
||||||
explicit ExamplesListModel(QObject *parent);
|
explicit ExamplesListModel(QObject *parent);
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
int rowCount(const QModelIndex &parent = QModelIndex()) const final;
|
||||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const final;
|
||||||
QHash<int, QByteArray> roleNames() const;
|
|
||||||
|
|
||||||
void beginReset() { beginResetModel(); }
|
void beginReset() { beginResetModel(); }
|
||||||
void endReset() { endResetModel(); }
|
void endReset() { endResetModel(); }
|
||||||
@@ -130,10 +118,10 @@ public:
|
|||||||
|
|
||||||
QList<BaseQtVersion*> qtVersions() const { return m_qtVersions; }
|
QList<BaseQtVersion*> qtVersions() const { return m_qtVersions; }
|
||||||
QList<ExtraExampleSet> extraExampleSets() const { return m_extraExampleSets; }
|
QList<ExtraExampleSet> extraExampleSets() const { return m_extraExampleSets; }
|
||||||
QAbstractItemModel* exampleSetModel() { return m_exampleSetModel; }
|
QStringList exampleSets() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void selectedExampleSetChanged();
|
void selectedExampleSetChanged(int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateQtVersions();
|
void updateQtVersions();
|
||||||
@@ -153,7 +141,7 @@ private:
|
|||||||
QList<BaseQtVersion*> m_qtVersions;
|
QList<BaseQtVersion*> m_qtVersions;
|
||||||
QList<ExtraExampleSet> m_extraExampleSets;
|
QList<ExtraExampleSet> m_extraExampleSets;
|
||||||
QList<ExampleItem> m_exampleItems;
|
QList<ExampleItem> m_exampleItems;
|
||||||
int m_selectedExampleSetIndex;
|
int m_selectedExampleSetIndex = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExamplesListModelFilter : public QSortFilterProxyModel
|
class ExamplesListModelFilter : public QSortFilterProxyModel
|
||||||
@@ -161,40 +149,21 @@ class ExamplesListModelFilter : public QSortFilterProxyModel
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Q_PROPERTY(bool showTutorialsOnly READ showTutorialsOnly WRITE setShowTutorialsOnly NOTIFY showTutorialsOnlyChanged)
|
ExamplesListModelFilter(ExamplesListModel *sourceModel, bool showTutorialsOnly, QObject *parent);
|
||||||
Q_PROPERTY(QStringList filterTags READ filterTags WRITE setFilterTags NOTIFY filterTagsChanged)
|
|
||||||
Q_PROPERTY(QString searchString READ searchString WRITE setSearchString NOTIFY searchStringChanged)
|
|
||||||
|
|
||||||
Q_PROPERTY(int exampleSetIndex READ exampleSetIndex NOTIFY exampleSetIndexChanged)
|
|
||||||
|
|
||||||
explicit ExamplesListModelFilter(ExamplesListModel *sourceModel, QObject *parent);
|
|
||||||
|
|
||||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const final;
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const final;
|
||||||
|
|
||||||
Q_INVOKABLE void setSearchString(const QString &arg);
|
void setSearchString(const QString &arg);
|
||||||
QString searchString() const;
|
|
||||||
|
|
||||||
bool showTutorialsOnly() { return m_showTutorialsOnly; }
|
|
||||||
QStringList filterTags() const { return m_filterTags; }
|
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
|
||||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
|
||||||
QAbstractItemModel* exampleSetModel();
|
|
||||||
|
|
||||||
Q_INVOKABLE void filterForExampleSet(int index);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void setFilterTags(const QStringList &arg);
|
void setFilterTags(const QStringList &arg);
|
||||||
void updateFilter();
|
void updateFilter();
|
||||||
|
|
||||||
void setShowTutorialsOnly(bool showTutorialsOnly);
|
|
||||||
void handleQtVersionsChanged();
|
void handleQtVersionsChanged();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void showTutorialsOnlyChanged();
|
|
||||||
void filterTagsChanged(const QStringList &arg);
|
void filterTagsChanged(const QStringList &arg);
|
||||||
void searchStringChanged(const QString &arg);
|
void searchStringChanged(const QString &arg);
|
||||||
void exampleSetIndexChanged();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setFilterStrings(const QStringList &arg);
|
void setFilterStrings(const QStringList &arg);
|
||||||
@@ -206,20 +175,20 @@ private:
|
|||||||
void tryToInitialize();
|
void tryToInitialize();
|
||||||
void timerEvent(QTimerEvent *event);
|
void timerEvent(QTimerEvent *event);
|
||||||
void delayedUpdateFilter();
|
void delayedUpdateFilter();
|
||||||
int exampleSetIndex() const;
|
|
||||||
|
|
||||||
bool m_showTutorialsOnly;
|
const bool m_showTutorialsOnly;
|
||||||
QString m_searchString;
|
QString m_searchString;
|
||||||
QStringList m_filterTags;
|
QStringList m_filterTags;
|
||||||
QStringList m_filterStrings;
|
QStringList m_filterStrings;
|
||||||
ExamplesListModel *m_sourceModel;
|
ExamplesListModel *m_sourceModel;
|
||||||
int m_timerId;
|
int m_timerId = 0;
|
||||||
bool m_blockIndexUpdate;
|
bool m_qtVersionManagerInitialized = false;
|
||||||
bool m_qtVersionManagerInitialized;
|
bool m_helpManagerInitialized = false;
|
||||||
bool m_helpManagerInitialized;
|
bool m_initalized = false;
|
||||||
bool m_initalized;
|
bool m_exampleDataRequested = false;
|
||||||
bool m_exampleDataRequested;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace QtSupport
|
} // namespace QtSupport
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QtSupport::Internal::ExampleItem)
|
||||||
|
|||||||
@@ -95,11 +95,6 @@ Id ExamplesWelcomePage::id() const
|
|||||||
return m_showExamples ? "Examples" : "Tutorials";
|
return m_showExamples ? "Examples" : "Tutorials";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExamplesWelcomePage::openHelpInExtraWindow(const QUrl &help)
|
|
||||||
{
|
|
||||||
HelpManager::handleHelpRequest(help, HelpManager::ExternalHelpAlways);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileInfo, QStringList &filesToOpen, const QStringList& dependencies)
|
QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileInfo, QStringList &filesToOpen, const QStringList& dependencies)
|
||||||
{
|
{
|
||||||
const QString projectDir = proFileInfo.canonicalPath();
|
const QString projectDir = proFileInfo.canonicalPath();
|
||||||
@@ -186,22 +181,18 @@ QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileI
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExamplesWelcomePage::openProject(const QString &projectFile,
|
void ExamplesWelcomePage::openProject(const ExampleItem &item)
|
||||||
const QStringList &additionalFilesToOpen,
|
|
||||||
const QString &mainFile,
|
|
||||||
const QUrl &help,
|
|
||||||
const QStringList &dependencies,
|
|
||||||
const QStringList &)
|
|
||||||
{
|
{
|
||||||
QString proFile = projectFile;
|
using namespace ProjectExplorer;
|
||||||
|
QString proFile = item.projectPath;
|
||||||
if (proFile.isEmpty())
|
if (proFile.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QStringList filesToOpen = additionalFilesToOpen;
|
QStringList filesToOpen = item.filesToOpen;
|
||||||
if (!mainFile.isEmpty()) {
|
if (!item.mainFile.isEmpty()) {
|
||||||
// ensure that the main file is opened on top (i.e. opened last)
|
// ensure that the main file is opened on top (i.e. opened last)
|
||||||
filesToOpen.removeAll(mainFile);
|
filesToOpen.removeAll(item.mainFile);
|
||||||
filesToOpen.append(mainFile);
|
filesToOpen.append(item.mainFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
QFileInfo proFileInfo(proFile);
|
QFileInfo proFileInfo(proFile);
|
||||||
@@ -213,22 +204,22 @@ void ExamplesWelcomePage::openProject(const QString &projectFile,
|
|||||||
if (!proFileInfo.isWritable()
|
if (!proFileInfo.isWritable()
|
||||||
|| !pathInfo.isWritable() /* path of .pro file */
|
|| !pathInfo.isWritable() /* path of .pro file */
|
||||||
|| !QFileInfo(pathInfo.path()).isWritable() /* shadow build directory */) {
|
|| !QFileInfo(pathInfo.path()).isWritable() /* shadow build directory */) {
|
||||||
proFile = copyToAlternativeLocation(proFileInfo, filesToOpen, dependencies);
|
proFile = copyToAlternativeLocation(proFileInfo, filesToOpen, item.dependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't try to load help and files if loading the help request is being cancelled
|
// don't try to load help and files if loading the help request is being cancelled
|
||||||
if (proFile.isEmpty())
|
if (proFile.isEmpty())
|
||||||
return;
|
return;
|
||||||
ProjectExplorer::ProjectExplorerPlugin::OpenProjectResult result =
|
ProjectExplorerPlugin::OpenProjectResult result = ProjectExplorerPlugin::openProject(proFile);
|
||||||
ProjectExplorer::ProjectExplorerPlugin::instance()->openProject(proFile);
|
|
||||||
if (result) {
|
if (result) {
|
||||||
ICore::openFiles(filesToOpen);
|
ICore::openFiles(filesToOpen);
|
||||||
ModeManager::activateMode(Core::Constants::MODE_EDIT);
|
ModeManager::activateMode(Core::Constants::MODE_EDIT);
|
||||||
if (help.isValid())
|
QUrl docUrl = QUrl::fromUserInput(item.docUrl);
|
||||||
openHelpInExtraWindow(help.toString());
|
if (docUrl.isValid())
|
||||||
|
HelpManager::handleHelpRequest(docUrl, HelpManager::ExternalHelpAlways);
|
||||||
ModeManager::activateMode(ProjectExplorer::Constants::MODE_SESSION);
|
ModeManager::activateMode(ProjectExplorer::Constants::MODE_SESSION);
|
||||||
} else {
|
} else {
|
||||||
ProjectExplorer::ProjectExplorerPlugin::showOpenProjectError(result);
|
ProjectExplorerPlugin::showOpenProjectError(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,11 +367,11 @@ class ExampleDelegate : public QStyledItemDelegate
|
|||||||
public:
|
public:
|
||||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const final
|
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const final
|
||||||
{
|
{
|
||||||
|
const ExampleItem item = index.data(Qt::UserRole).value<ExampleItem>();
|
||||||
const QRect rc = option.rect;
|
const QRect rc = option.rect;
|
||||||
const QString name = index.data(Name).toString();
|
|
||||||
|
|
||||||
// Quick hack for empty items in the last row.
|
// Quick hack for empty items in the last row.
|
||||||
if (name.isEmpty())
|
if (item.name.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const int d = 10;
|
const int d = 10;
|
||||||
@@ -421,54 +412,50 @@ public:
|
|||||||
|
|
||||||
// The pixmap.
|
// The pixmap.
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
const QString imageUrl = index.data(ImageUrl).toString();
|
|
||||||
const bool isVideo = index.data(IsVideo).toBool();
|
|
||||||
const QSize requestSize(188, 145);
|
const QSize requestSize(188, 145);
|
||||||
|
|
||||||
QPixmap pm;
|
QPixmap pm;
|
||||||
if (QPixmap *foundPixmap = m_pixmapCache.find(imageUrl)) {
|
if (QPixmap *foundPixmap = m_pixmapCache.find(item.imageUrl)) {
|
||||||
pm = *foundPixmap;
|
pm = *foundPixmap;
|
||||||
} else {
|
} else {
|
||||||
pm.load(imageUrl);
|
pm.load(item.imageUrl);
|
||||||
if (pm.isNull())
|
if (pm.isNull())
|
||||||
pm.load(resourcePath() + "/welcomescreen/widgets/" + imageUrl);
|
pm.load(resourcePath() + "/welcomescreen/widgets/" + item.imageUrl);
|
||||||
if (pm.isNull()) {
|
if (pm.isNull()) {
|
||||||
// FIXME: Make async
|
// FIXME: Make async
|
||||||
QByteArray fetchedData = HelpManager::fileData(imageUrl);
|
QByteArray fetchedData = HelpManager::fileData(item.imageUrl);
|
||||||
QBuffer imgBuffer(&fetchedData);
|
QBuffer imgBuffer(&fetchedData);
|
||||||
imgBuffer.open(QIODevice::ReadOnly);
|
imgBuffer.open(QIODevice::ReadOnly);
|
||||||
QImageReader reader(&imgBuffer);
|
QImageReader reader(&imgBuffer);
|
||||||
QImage img = reader.read();
|
QImage img = reader.read();
|
||||||
img = ScreenshotCropper::croppedImage(img, imageUrl, requestSize);
|
img = ScreenshotCropper::croppedImage(img, item.imageUrl, requestSize);
|
||||||
pm = QPixmap::fromImage(img);
|
pm = QPixmap::fromImage(img);
|
||||||
}
|
}
|
||||||
m_pixmapCache.insert(imageUrl, pm);
|
m_pixmapCache.insert(item.imageUrl, pm);
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect inner(x + 11, y - offset, requestSize.width(), requestSize.height());
|
QRect inner(x + 11, y - offset, requestSize.width(), requestSize.height());
|
||||||
QRect pixmapRect = inner;
|
QRect pixmapRect = inner;
|
||||||
if (!pm.isNull()) {
|
if (!pm.isNull()) {
|
||||||
painter->setPen(foregroundColor2);
|
painter->setPen(foregroundColor2);
|
||||||
if (isVideo)
|
if (item.isVideo)
|
||||||
pixmapRect = inner.adjusted(6, 10, -6, -25);
|
pixmapRect = inner.adjusted(6, 10, -6, -25);
|
||||||
QPoint pixmapPos = pixmapRect.center();
|
QPoint pixmapPos = pixmapRect.center();
|
||||||
pixmapPos.rx() -= pm.width() / 2;
|
pixmapPos.rx() -= pm.width() / 2;
|
||||||
pixmapPos.ry() -= pm.height() / 2;
|
pixmapPos.ry() -= pm.height() / 2;
|
||||||
painter->drawPixmap(pixmapPos, pm);
|
painter->drawPixmap(pixmapPos, pm);
|
||||||
if (isVideo) {
|
if (item.isVideo) {
|
||||||
painter->setFont(sizedFont(13, option.widget));
|
painter->setFont(sizedFont(13, option.widget));
|
||||||
QRect lenRect(x, y + 120, w, 20);
|
QRect lenRect(x, y + 120, w, 20);
|
||||||
QString videoLen = index.data(VideoLength).toString();
|
QString videoLen = item.videoLength;
|
||||||
lenRect = fm.boundingRect(lenRect, Qt::AlignHCenter, videoLen);
|
lenRect = fm.boundingRect(lenRect, Qt::AlignHCenter, videoLen);
|
||||||
painter->drawText(lenRect.adjusted(0, 0, 5, 0), videoLen);
|
painter->drawText(lenRect.adjusted(0, 0, 5, 0), videoLen);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// The description text as fallback.
|
// The description text as fallback.
|
||||||
QRect descRect = pixmapRect.adjusted(6, 10, -6, -10);
|
|
||||||
QString desc = index.data(Description).toString();
|
|
||||||
painter->setPen(foregroundColor2);
|
painter->setPen(foregroundColor2);
|
||||||
painter->setFont(sizedFont(11, option.widget));
|
painter->setFont(sizedFont(11, option.widget));
|
||||||
painter->drawText(descRect, desc, wrapped);
|
painter->drawText(pixmapRect.adjusted(6, 10, -6, -10), item.description, wrapped);
|
||||||
}
|
}
|
||||||
painter->setPen(foregroundColor1);
|
painter->setPen(foregroundColor1);
|
||||||
painter->drawRect(pixmapRect.adjusted(-1, -1, -1, -1));
|
painter->drawRect(pixmapRect.adjusted(-1, -1, -1, -1));
|
||||||
@@ -479,11 +466,11 @@ public:
|
|||||||
painter->setFont(sizedFont(13, option.widget));
|
painter->setFont(sizedFont(13, option.widget));
|
||||||
QRectF nameRect;
|
QRectF nameRect;
|
||||||
if (offset) {
|
if (offset) {
|
||||||
nameRect = painter->boundingRect(shiftedTextRect, name, wrapped);
|
nameRect = painter->boundingRect(shiftedTextRect, item.name, wrapped);
|
||||||
painter->drawText(nameRect, name, wrapped);
|
painter->drawText(nameRect, item.name, wrapped);
|
||||||
} else {
|
} else {
|
||||||
nameRect = QRect(x, y + nameY, x + w, y + nameY + 20);
|
nameRect = QRect(x, y + nameY, x + w, y + nameY + 20);
|
||||||
QString elidedName = fm.elidedText(name, Qt::ElideRight, w - 20);
|
QString elidedName = fm.elidedText(item.name, Qt::ElideRight, w - 20);
|
||||||
painter->drawText(nameRect, elidedName);
|
painter->drawText(nameRect, elidedName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,10 +485,9 @@ public:
|
|||||||
if (offset) {
|
if (offset) {
|
||||||
int dd = nameRect.height() + 10;
|
int dd = nameRect.height() + 10;
|
||||||
QRect descRect = shiftedTextRect.adjusted(0, dd, 0, dd);
|
QRect descRect = shiftedTextRect.adjusted(0, dd, 0, dd);
|
||||||
QString desc = index.data(Description).toString();
|
|
||||||
painter->setPen(foregroundColor2);
|
painter->setPen(foregroundColor2);
|
||||||
painter->setFont(sizedFont(11, option.widget));
|
painter->setFont(sizedFont(11, option.widget));
|
||||||
painter->drawText(descRect, desc, wrapped);
|
painter->drawText(descRect, item.description, wrapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Separator line between text and 'Tags:' section
|
// Separator line between text and 'Tags:' section
|
||||||
@@ -518,11 +504,10 @@ public:
|
|||||||
painter->drawText(tagsLabelRect, ExamplesWelcomePage::tr("Tags:"));
|
painter->drawText(tagsLabelRect, ExamplesWelcomePage::tr("Tags:"));
|
||||||
|
|
||||||
painter->setPen(themeColor(Theme::Welcome_LinkColor));
|
painter->setPen(themeColor(Theme::Welcome_LinkColor));
|
||||||
const QStringList tags = index.data(Tags).toStringList();
|
|
||||||
m_currentTagRects.clear();
|
m_currentTagRects.clear();
|
||||||
int xx = 0;
|
int xx = 0;
|
||||||
int yy = y + tagsBase;
|
int yy = y + tagsBase;
|
||||||
for (const QString tag : tags) {
|
for (const QString tag : item.tags) {
|
||||||
const int ww = tagsFontMetrics.width(tag) + 5;
|
const int ww = tagsFontMetrics.width(tag) + 5;
|
||||||
if (xx + ww > w - 30) {
|
if (xx + ww > w - 30) {
|
||||||
yy += 15;
|
yy += 15;
|
||||||
@@ -551,6 +536,7 @@ public:
|
|||||||
const QStyleOptionViewItem &option, const QModelIndex &idx) final
|
const QStyleOptionViewItem &option, const QModelIndex &idx) final
|
||||||
{
|
{
|
||||||
if (ev->type() == QEvent::MouseButtonRelease) {
|
if (ev->type() == QEvent::MouseButtonRelease) {
|
||||||
|
const ExampleItem item = idx.data(Qt::UserRole).value<ExampleItem>();
|
||||||
auto mev = static_cast<QMouseEvent *>(ev);
|
auto mev = static_cast<QMouseEvent *>(ev);
|
||||||
if (idx.isValid()) {
|
if (idx.isValid()) {
|
||||||
const QPoint pos = mev->pos();
|
const QPoint pos = mev->pos();
|
||||||
@@ -561,17 +547,13 @@ public:
|
|||||||
emit tagClicked(it.first);
|
emit tagClicked(it.first);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (idx.data(IsVideo).toBool())
|
if (item.isVideo)
|
||||||
QDesktopServices::openUrl(idx.data(VideoUrl).toUrl());
|
QDesktopServices::openUrl(QUrl::fromUserInput(item.videoUrl));
|
||||||
else if (idx.data(HasSourceCode).toBool())
|
else if (item.hasSourceCode)
|
||||||
ExamplesWelcomePage::openProject(idx.data(ProjectPath).toString(),
|
ExamplesWelcomePage::openProject(item);
|
||||||
idx.data(FilesToOpen).toStringList(),
|
|
||||||
idx.data(MainFile).toString(),
|
|
||||||
idx.data(DocUrl).toUrl(),
|
|
||||||
idx.data(Dependencies).toStringList(),
|
|
||||||
idx.data(Platforms).toStringList());
|
|
||||||
else
|
else
|
||||||
ExamplesWelcomePage::openHelpInExtraWindow(idx.data(DocUrl).toUrl());
|
HelpManager::handleHelpRequest(QUrl::fromUserInput(item.docUrl),
|
||||||
|
HelpManager::ExternalHelpAlways);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -604,15 +586,11 @@ public:
|
|||||||
static ExamplesListModel *s_examplesModel = new ExamplesListModel(this);
|
static ExamplesListModel *s_examplesModel = new ExamplesListModel(this);
|
||||||
m_examplesModel = s_examplesModel;
|
m_examplesModel = s_examplesModel;
|
||||||
|
|
||||||
m_filteredModel = new ExamplesListModelFilter(m_examplesModel, this);
|
m_filteredModel = new ExamplesListModelFilter(m_examplesModel, !m_isExamples, this);
|
||||||
m_filteredModel->setDynamicSortFilter(true);
|
|
||||||
m_filteredModel->sort(0);
|
|
||||||
m_filteredModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
|
||||||
|
|
||||||
auto vbox = new QVBoxLayout(this);
|
auto vbox = new QVBoxLayout(this);
|
||||||
vbox->setContentsMargins(30, 27, 20, 20);
|
vbox->setContentsMargins(30, 27, 20, 20);
|
||||||
if (m_isExamples) {
|
if (m_isExamples) {
|
||||||
m_filteredModel->setShowTutorialsOnly(false);
|
|
||||||
m_qtVersionSelector = new QComboBox(this);
|
m_qtVersionSelector = new QComboBox(this);
|
||||||
m_qtVersionSelector->setMinimumWidth(itemWidth);
|
m_qtVersionSelector->setMinimumWidth(itemWidth);
|
||||||
m_qtVersionSelector->setMaximumWidth(itemWidth);
|
m_qtVersionSelector->setMaximumWidth(itemWidth);
|
||||||
@@ -623,9 +601,10 @@ public:
|
|||||||
hbox->addWidget(m_searchBox);
|
hbox->addWidget(m_searchBox);
|
||||||
vbox->addItem(hbox);
|
vbox->addItem(hbox);
|
||||||
connect(m_qtVersionSelector, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
|
connect(m_qtVersionSelector, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
|
||||||
this, &ExamplesPageWidget::updateComboBox);
|
m_examplesModel, &ExamplesListModel::selectExampleSet);
|
||||||
|
connect(m_examplesModel, &ExamplesListModel::selectedExampleSetChanged,
|
||||||
|
this, &ExamplesPageWidget::updateStuff);
|
||||||
} else {
|
} else {
|
||||||
m_filteredModel->setShowTutorialsOnly(true);
|
|
||||||
m_searchBox = new SearchBox(tr("Search in Tutorials..."), this);
|
m_searchBox = new SearchBox(tr("Search in Tutorials..."), this);
|
||||||
vbox->addWidget(m_searchBox);
|
vbox->addWidget(m_searchBox);
|
||||||
}
|
}
|
||||||
@@ -643,9 +622,6 @@ public:
|
|||||||
this, &ExamplesPageWidget::updateStuff);
|
this, &ExamplesPageWidget::updateStuff);
|
||||||
connect(m_filteredModel, &ExamplesListModelFilter::searchStringChanged,
|
connect(m_filteredModel, &ExamplesListModelFilter::searchStringChanged,
|
||||||
this, &ExamplesPageWidget::updateStuff);
|
this, &ExamplesPageWidget::updateStuff);
|
||||||
connect(m_filteredModel, &ExamplesListModelFilter::exampleSetIndexChanged,
|
|
||||||
this, &ExamplesPageWidget::updateStuff);
|
|
||||||
|
|
||||||
connect(m_searchBox->m_lineEdit, &QLineEdit::textChanged,
|
connect(m_searchBox->m_lineEdit, &QLineEdit::textChanged,
|
||||||
m_filteredModel, &ExamplesListModelFilter::setSearchString);
|
m_filteredModel, &ExamplesListModelFilter::setSearchString);
|
||||||
}
|
}
|
||||||
@@ -670,24 +646,12 @@ public:
|
|||||||
void updateStuff()
|
void updateStuff()
|
||||||
{
|
{
|
||||||
if (m_isExamples) {
|
if (m_isExamples) {
|
||||||
QTC_ASSERT(m_examplesModel, return);
|
|
||||||
const QList<BaseQtVersion *> qtVersions = m_examplesModel->qtVersions();
|
|
||||||
const QList<ExamplesListModel::ExtraExampleSet> extraExampleSets = m_examplesModel->extraExampleSets();
|
|
||||||
QStringList list;
|
|
||||||
for (BaseQtVersion *qtVersion : qtVersions)
|
|
||||||
list.append(qtVersion->displayName());
|
|
||||||
m_qtVersionSelector->clear();
|
m_qtVersionSelector->clear();
|
||||||
m_qtVersionSelector->addItems(list);
|
m_qtVersionSelector->addItems(m_examplesModel->exampleSets());
|
||||||
|
m_qtVersionSelector->setCurrentIndex(m_examplesModel->selectedExampleSet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateComboBox(int index)
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_isExamples, return);
|
|
||||||
QTC_ASSERT(m_examplesModel, return);
|
|
||||||
m_examplesModel->selectExampleSet(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool m_isExamples;
|
const bool m_isExamples;
|
||||||
ExampleDelegate m_exampleDelegate;
|
ExampleDelegate m_exampleDelegate;
|
||||||
QPointer<ExamplesListModel> m_examplesModel;
|
QPointer<ExamplesListModel> m_examplesModel;
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ namespace QtSupport {
|
|||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class ExamplesListModel;
|
class ExamplesListModel;
|
||||||
|
class ExampleItem;
|
||||||
|
|
||||||
class ExamplesWelcomePage : public Core::IWelcomePage
|
class ExamplesWelcomePage : public Core::IWelcomePage
|
||||||
{
|
{
|
||||||
@@ -50,10 +51,7 @@ public:
|
|||||||
Core::Id id() const final;
|
Core::Id id() const final;
|
||||||
QWidget *createWidget() const final;
|
QWidget *createWidget() const final;
|
||||||
|
|
||||||
static void openHelpInExtraWindow(const QUrl &help);
|
static void openProject(const ExampleItem &item);
|
||||||
static void openProject(const QString& projectFile, const QStringList& additionalFilesToOpen,
|
|
||||||
const QString &mainFile, const QUrl &help,
|
|
||||||
const QStringList &dependencies, const QStringList &platforms);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QString copyToAlternativeLocation(const QFileInfo &fileInfo, QStringList &filesToOpen, const QStringList &dependencies);
|
static QString copyToAlternativeLocation(const QFileInfo &fileInfo, QStringList &filesToOpen, const QStringList &dependencies);
|
||||||
|
|||||||
Reference in New Issue
Block a user