diff --git a/share/qtcreator/examplebrowser/qmlexamples.xml b/share/qtcreator/examplebrowser/qmlexamples.xml new file mode 100644 index 00000000000..c12744fe52e --- /dev/null +++ b/share/qtcreator/examplebrowser/qmlexamples.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/qtcreator/static.pro b/share/qtcreator/static.pro index ddc10bab704..94d49be3ace 100644 --- a/share/qtcreator/static.pro +++ b/share/qtcreator/static.pro @@ -24,6 +24,7 @@ isEmpty(vcproj) { } DATA_DIRS = \ + examplebrowser \ snippets \ templates \ designer \ diff --git a/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.cpp b/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.cpp index eb63ae33150..bd1f95719c4 100644 --- a/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.cpp +++ b/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.cpp @@ -140,11 +140,116 @@ GettingStartedWelcomePageWidget::~GettingStartedWelcomePageWidget() delete ui; } +void GettingStartedWelcomePageWidget::parseXmlFile(QFile *file, QMenuHash &cppSubMenuHash, QMenuHash &qmlSubMenuHash, + const QString &examplePath, const QString &sourcePath) +{ + QMenu *cppSubMenu = 0; + QMenu *qmlSubMenu = 0; + bool inExamples = false; + QString dirName; + + QXmlStreamReader reader(file); + + while (!reader.atEnd()) { + switch (reader.readNext()) { + case QXmlStreamReader::StartElement: + if (reader.name() == QLatin1String("category")) { + QString name = reader.attributes().value(QLatin1String("name")).toString(); + if (name.contains(QLatin1String("Tutorial"))) + break; + dirName = reader.attributes().value(QLatin1String("dirname")).toString(); + if (!cppSubMenuHash.contains(dirName)) { + cppSubMenu = new QMenu(name, this); + cppSubMenu->setObjectName(dirName); + cppSubMenuHash.insert(dirName, cppSubMenu); + } else { + cppSubMenu = cppSubMenuHash.value(dirName); + } + if (!qmlSubMenuHash.contains(dirName)) { + qmlSubMenu = new QMenu(name, this); + qmlSubMenu->setObjectName(dirName); + qmlSubMenuHash.insert(dirName, qmlSubMenu); + } else { + qmlSubMenu = qmlSubMenuHash.value(dirName); + } + inExamples = true; + } + if (inExamples && reader.name() == QLatin1String("example")) { + const QChar slash = QLatin1Char('/'); + const QString name = reader.attributes().value(QLatin1String("name")).toString(); + const bool isQml = reader.attributes().value(QLatin1String("qml")).toString() == "true"; + const QString localDir = reader.attributes().value(QLatin1String("filename")).toString(); + const QString extension = isQml ? QLatin1String(".qmlproject") : QLatin1String(".pro"); + const QString fileName = localDir.section(',', -1); + const QString relativeProPath = slash + dirName + slash + localDir + slash + fileName + extension; + + QString finaleFileName = examplePath + relativeProPath; + if (!QFile::exists(finaleFileName)) + finaleFileName = sourcePath + QLatin1String("/examples") + relativeProPath; + + if (!QFile::exists(finaleFileName)) + break; + + QString dirName1 = dirName; + dirName1.replace(slash, QLatin1Char('-')); + QString helpPath = QLatin1String("qthelp://com.trolltech.qt/qdoc/") + + dirName1 + + QLatin1Char('-') + fileName + QLatin1String(".html"); + + QAction *exampleAction = 0; + QAction *beforeAction = 0; + bool duplicate = false; + QMenu *subMenu; + subMenu = isQml ? qmlSubMenu : cppSubMenu; + + foreach (beforeAction, subMenu->actions()) { + int res = beforeAction->text().compare(name, Qt::CaseInsensitive); + if (res==0) { + duplicate = true; + break; + } else if (res<0) + beforeAction = 0; + else if (res>0) { + break; + } + } + + if (!duplicate) { + exampleAction = new QAction(name, subMenu); + subMenu->insertAction(beforeAction, exampleAction); + connect(exampleAction, SIGNAL(triggered()), SLOT(slotOpenExample())); + exampleAction->setProperty(ExamplePathPropertyName, finaleFileName); + exampleAction->setProperty(HelpPathPropertyName, helpPath); + } + } + break; + case QXmlStreamReader::EndElement: + if (inExamples && reader.name() == QLatin1String("category")) { + if (cppSubMenu->actions().isEmpty()) + delete cppSubMenuHash.take(dirName); + + if (qmlSubMenu->actions().isEmpty()) + delete qmlSubMenuHash.take(dirName); + + inExamples = false; + } + break; + default: + break; + } + } +} + +bool menuEntryCompare(QMenu* first, QMenu* second) +{ + return (QString::localeAwareCompare(first->title(), second->title()) < 0); +} void GettingStartedWelcomePageWidget::updateExamples(const QString &examplePath, const QString &demosPath, const QString &sourcePath) { + QString demoXml = demosPath + "/qtdemo/xml/examples.xml"; if (!QFile::exists(demoXml)) { demoXml = sourcePath + "/demos/qtdemo/xml/examples.xml"; @@ -152,81 +257,47 @@ void GettingStartedWelcomePageWidget::updateExamples(const QString &examplePath, return; } - QFile description(demoXml); - if (!description.open(QFile::ReadOnly)) - return; + QMenuHash cppSubMenuHash; + QMenuHash qmlSubMenuHash; const QString dropDownLabel = tr("Choose an Example..."); - - ui->qmlExamplesButton->setEnabled(true); - ui->qmlExamplesButton->setText(dropDownLabel); - + QMenu *cppMenu = new QMenu(ui->cppExamplesButton); + ui->cppExamplesButton->setMenu(cppMenu); QMenu *qmlMenu = new QMenu(ui->qmlExamplesButton); - ui->qmlExamplesButton->setMenu(qmlMenu); + + + // let Creator's files take precedence + QString localQmlExamplesXml = + Core::ICore::instance()->resourcePath()+QLatin1String("/examplebrowser/qmlexamples.xml"); + + QFile localDescriptions(localQmlExamplesXml); + if (localDescriptions.open(QFile::ReadOnly)) { + parseXmlFile(&localDescriptions, cppSubMenuHash, qmlSubMenuHash, examplePath, sourcePath); + } + + QFile descriptions(demoXml); + if (!descriptions.open(QFile::ReadOnly)) + return; ui->cppExamplesButton->setEnabled(true); ui->cppExamplesButton->setText(dropDownLabel); - QMenu *cppMenu = new QMenu(ui->cppExamplesButton); - ui->cppExamplesButton->setMenu(cppMenu); + parseXmlFile(&descriptions, cppSubMenuHash, qmlSubMenuHash, examplePath, sourcePath); - QScopedPointer subMenu; - bool inExamples = false; - QString dirName; - QXmlStreamReader reader(&description); + QList cppSubMenus = cppSubMenuHash.values(); + qSort(cppSubMenus.begin(), cppSubMenus.end(), menuEntryCompare); + QList qmlSubMenus = qmlSubMenuHash.values(); + qSort(qmlSubMenus.begin(), qmlSubMenus.end(), menuEntryCompare); - while (!reader.atEnd()) { - switch (reader.readNext()) { - case QXmlStreamReader::StartElement: - if (reader.name() == QLatin1String("category")) { - QString name = reader.attributes().value(QLatin1String("name")).toString(); - if (name.contains(QLatin1String("tutorial"))) - break; - dirName = reader.attributes().value(QLatin1String("dirname")).toString(); - subMenu.reset(new QMenu(name)); - inExamples = true; - } - if (inExamples && reader.name() == QLatin1String("example")) { - const QChar slash = QLatin1Char('/'); - const QString name = reader.attributes().value(QLatin1String("name")).toString(); - const bool isQml = reader.attributes().value(QLatin1String("qml")).toString() == "true"; - const QString fn = reader.attributes().value(QLatin1String("filename")).toString(); - const QString extension = isQml ? QLatin1String(".qmlproject") : QLatin1String(".pro"); - const QString relativeProPath = slash + dirName + slash + fn + slash + fn + extension; + foreach (QMenu *menu, cppSubMenus) + cppMenu->addMenu(menu); + foreach (QMenu *menu, qmlSubMenus) + qmlMenu->addMenu(menu); - QString fileName = examplePath + relativeProPath; - if (!QFile::exists(fileName)) - fileName = sourcePath + QLatin1String("/examples") + relativeProPath; - - QString dirName1 = dirName; - dirName1.replace(slash, QLatin1Char('-')); - QString helpPath = QLatin1String("qthelp://com.trolltech.qt/qdoc/") + - dirName1 + - QLatin1Char('-') + fn + QLatin1String(".html"); - - QAction *exampleAction; - if (isQml) - exampleAction = qmlMenu->addAction(name); - else - exampleAction = subMenu->addAction(name); - - connect(exampleAction, SIGNAL(triggered()), SLOT(slotOpenExample())); - - exampleAction->setProperty(ExamplePathPropertyName, fileName); - exampleAction->setProperty(HelpPathPropertyName, helpPath); - - } - break; - case QXmlStreamReader::EndElement: - if (reader.name() == QLatin1String("category")) { - if (!subMenu->actions().isEmpty()) - cppMenu->addMenu(subMenu.take()); - inExamples = false; - } - break; - default: - break; - } + if (!qmlMenu->isEmpty()) { + ui->qmlExamplesButton->setMenu(qmlMenu); + ui->qmlExamplesButton->setEnabled(true); + ui->qmlExamplesButton->setText(dropDownLabel); } } diff --git a/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.h b/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.h index ea0fec1d49a..461d24e88cb 100644 --- a/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.h +++ b/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.h @@ -37,6 +37,8 @@ QT_BEGIN_NAMESPACE class QUrl; class QLabel; +class QFile; +class QMenu; QT_END_NAMESPACE namespace Core { @@ -55,6 +57,8 @@ namespace Ui { class GettingStartedWelcomePageWidget; } +typedef QHash QMenuHash; + class PixmapDownloader : public QNetworkAccessManager { Q_OBJECT public: @@ -101,6 +105,8 @@ signals: void startRssFetching(const QUrl&); private: + void parseXmlFile(QFile *file, QMenuHash &cppSubMenuHash, QMenuHash &qmlSubMenuHash, + const QString &examplePath, const QString &sourcePath); QStringList tipsOfTheDay(); Ui::GettingStartedWelcomePageWidget *ui; int m_currentTip; diff --git a/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.ui b/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.ui index 0de51c8a7e8..e0b8f48e7b5 100644 --- a/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.ui +++ b/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.ui @@ -40,15 +40,6 @@ 0 - - - 250 - 0 - - - - - 12 @@ -76,12 +67,12 @@ - 250 + 230 0 - + @@ -90,7 +81,57 @@ 9 + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + Did You Know? + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + 0 @@ -170,10 +211,10 @@ - + - + 0 0 @@ -195,69 +236,17 @@ - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - Did You Know? - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - + 0 0 - - - 500 - 0 - - - - - 500 - 16777215 - - - - - @@ -324,39 +313,10 @@ - - - - Explore Qt C++ mobile examples: - - - - - - - false - - - - 0 - 0 - - - - - 0 - 30 - - - - Examples Not Installed... - - - - + 6 @@ -408,6 +368,22 @@ + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 40 + + + +