diff --git a/src/libs/utils/welcomemodetreewidget.cpp b/src/libs/utils/welcomemodetreewidget.cpp index e606a38cb193482c8f6768dd6189ae3e88540967..2d9ebaa4dd358462f9a3d24bd568d3da4e7cdbc5 100644 --- a/src/libs/utils/welcomemodetreewidget.cpp +++ b/src/libs/utils/welcomemodetreewidget.cpp @@ -50,17 +50,23 @@ void WelcomeModeLabel::setStyledText(const QString &text) struct WelcomeModeTreeWidgetPrivate { - WelcomeModeTreeWidgetPrivate() {} - QIcon bullet; + WelcomeModeTreeWidgetPrivate(); + + const QIcon bullet; }; +WelcomeModeTreeWidgetPrivate::WelcomeModeTreeWidgetPrivate() : + bullet(QLatin1String(":/welcome/images/list_bullet_arrow.png")) +{ +} + WelcomeModeTreeWidget::WelcomeModeTreeWidget(QWidget *parent) : QTreeWidget(parent), m_d(new WelcomeModeTreeWidgetPrivate) { - m_d->bullet = QIcon(QLatin1String(":/welcome/images/list_bullet_arrow.png")); connect(this, SIGNAL(itemClicked(QTreeWidgetItem *, int)), SLOT(slotItemClicked(QTreeWidgetItem *))); + setUniformRowHeights(true); viewport()->setAutoFillBackground(false); } diff --git a/src/plugins/welcome/rssfetcher.cpp b/src/plugins/welcome/rssfetcher.cpp index 96219d7f0e479421156532e7a96297cf378aa3bf..ecd1140910b9ff43991353d859df2a519fbceb38 100644 --- a/src/plugins/welcome/rssfetcher.cpp +++ b/src/plugins/welcome/rssfetcher.cpp @@ -27,6 +27,9 @@ ** **************************************************************************/ +#include "rssfetcher.h" +#include <coreplugin/coreconstants.h> + #include <QtCore/QDebug> #include <QtCore/QSysInfo> #include <QtCore/QLocale> @@ -35,10 +38,9 @@ #include <QtNetwork/QNetworkReply> #include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkProxyFactory> +#include <QtNetwork/QNetworkAccessManager> -#include <coreplugin/coreconstants.h> - -#include "rssfetcher.h" +#include <QtCore/QXmlStreamReader> #ifdef Q_OS_UNIX #include <sys/utsname.h> @@ -98,11 +100,13 @@ static const QString getOsString() } #elif defined (Q_OS_UNIX) struct utsname uts; - if (uname(&uts) == 0) - osString += QString("%1 %2").arg(QLatin1String(uts.sysname)) - .arg(QLatin1String(uts.release)); - else + if (uname(&uts) == 0) { + osString += QLatin1String(uts.sysname); + osString += QLatin1Char(' '); + osString += QLatin1String(uts.release); + } else { osString += QLatin1String("Unix (Unknown)"); + } #else ossttring = QLatin1String("Unknown OS"); #endif @@ -110,64 +114,103 @@ static const QString getOsString() } RSSFetcher::RSSFetcher(int maxItems, QObject *parent) - : QObject(parent), m_items(0), m_maxItems(maxItems) + : QObject(parent), m_maxItems(maxItems), m_items(0) +{ +} + +RSSFetcher::~RSSFetcher() { - connect(&m_networkAccessManager, SIGNAL(finished(QNetworkReply*)), - SLOT(fetchingFinished(QNetworkReply*))); } void RSSFetcher::fetch(const QUrl &url) { - QString agentStr = QString("Qt-Creator/%1 (QHttp %2; %3; %4; %5 bit)") + QString agentStr = QString::fromLatin1("Qt-Creator/%1 (QHttp %2; %3; %4; %5 bit)") .arg(Core::Constants::IDE_VERSION_LONG).arg(qVersion()) .arg(getOsString()).arg(QLocale::system().name()) .arg(QSysInfo::WordSize); QNetworkRequest req(url); req.setRawHeader("User-Agent", agentStr.toLatin1()); - m_networkAccessManager.get(req); + if (m_networkAccessManager.isNull()) { + m_networkAccessManager.reset(new QNetworkAccessManager); + connect(m_networkAccessManager.data(), SIGNAL(finished(QNetworkReply*)), + SLOT(fetchingFinished(QNetworkReply*))); + } + m_networkAccessManager->get(req); } void RSSFetcher::fetchingFinished(QNetworkReply *reply) { - bool error = (reply->error() != QNetworkReply::NoError); + const bool error = (reply->error() != QNetworkReply::NoError); if (!error) { - m_xml.addData(reply->readAll()); - parseXml(); + parseXml(reply); m_items = 0; } emit finished(error); reply->deleteLater(); } -void RSSFetcher::parseXml() +RSSFetcher::TagElement RSSFetcher::tagElement(const QStringRef &r) { - while (!m_xml.atEnd()) { - m_xml.readNext(); - if (m_xml.isStartElement()) { - if (m_xml.name() == "item") { - m_titleString.clear(); - m_descriptionString.clear(); - m_linkString.clear(); + if (r == QLatin1String("item")) + return itemElement; + if (r == QLatin1String("title")) + return titleElement; + if (r == QLatin1String("description")) + return descriptionElement; + if (r == QLatin1String("link")) + return linkElement; + return otherElement; +} + +void RSSFetcher::parseXml(QIODevice *device) +{ + QXmlStreamReader xmlReader(device); + + TagElement currentTag = otherElement; + QString linkString; + QString descriptionString; + QString titleString; + + while (!xmlReader.atEnd()) { + switch (xmlReader.readNext()) { + case QXmlStreamReader::StartElement: + currentTag = tagElement(xmlReader.name()); + if (currentTag == itemElement) { + titleString.clear(); + descriptionString.clear(); + linkString.clear(); } - m_currentTag = m_xml.name().toString(); - } else if (m_xml.isEndElement()) { - if (m_xml.name() == "item") { + break; + case QXmlStreamReader::EndElement: + if (xmlReader.name() == QLatin1String("item")) { m_items++; if (m_items > m_maxItems) return; - emit newsItemReady(m_titleString, m_descriptionString, m_linkString); + emit newsItemReady(titleString, descriptionString, linkString); } - - } else if (m_xml.isCharacters() && !m_xml.isWhitespace()) { - if (m_currentTag == "title") - m_titleString += m_xml.text().toString(); - else if (m_currentTag == "description") - m_descriptionString += m_xml.text().toString(); - else if (m_currentTag == "link") - m_linkString += m_xml.text().toString(); + break; + case QXmlStreamReader::Characters: + if (!xmlReader.isWhitespace()) { + switch (currentTag) { + case titleElement: + titleString += xmlReader.text().toString(); + break; + case descriptionElement: + descriptionString += xmlReader.text().toString(); + break; + case linkElement: + linkString += xmlReader.text().toString(); + break; + default: + break; + } + } // !xmlReader.isWhitespace() + break; + default: + break; } } - if (m_xml.error() && m_xml.error() != QXmlStreamReader::PrematureEndOfDocumentError) { - qWarning() << "XML ERROR:" << m_xml.lineNumber() << ": " << m_xml.errorString(); + if (xmlReader.error() && xmlReader.error() != QXmlStreamReader::PrematureEndOfDocumentError) { + qWarning() << "XML ERROR:" << xmlReader.lineNumber() << ": " << xmlReader.errorString(); } } diff --git a/src/plugins/welcome/rssfetcher.h b/src/plugins/welcome/rssfetcher.h index e046eead0b8067573d542c1524876fcd7575a569..db1fba88b6a6445c653b4a866ff03387660d01df 100644 --- a/src/plugins/welcome/rssfetcher.h +++ b/src/plugins/welcome/rssfetcher.h @@ -30,12 +30,14 @@ #ifndef RSSFETCHER_H #define RSSFETCHER_H -#include <QtCore/QXmlStreamReader> -#include <QtNetwork/QNetworkAccessManager> +#include <QtCore/QScopedPointer> +#include <QtCore/QObject> QT_BEGIN_NAMESPACE class QNetworkReply; +class QNetworkAccessManager; class QUrl; +class QIODevice; QT_END_NAMESPACE namespace Welcome { @@ -46,6 +48,7 @@ class RSSFetcher : public QObject Q_OBJECT public: explicit RSSFetcher(int maxItems, QObject *parent = 0); + virtual ~RSSFetcher(); signals: void newsItemReady(const QString& title, const QString& desciption, const QString& url); @@ -56,17 +59,14 @@ public slots: void fetch(const QUrl &url); private: - void parseXml(); + enum TagElement { itemElement, titleElement, descriptionElement, linkElement, otherElement }; + static TagElement tagElement(const QStringRef &); + void parseXml(QIODevice *); - QXmlStreamReader m_xml; - QString m_currentTag; - QString m_linkString; - QString m_descriptionString; - QString m_titleString; + const int m_maxItems; - QNetworkAccessManager m_networkAccessManager; + QScopedPointer<QNetworkAccessManager> m_networkAccessManager; int m_items; - int m_maxItems; }; } // namespace Welcome diff --git a/src/plugins/welcome/welcomemode.cpp b/src/plugins/welcome/welcomemode.cpp index 3831ea9e2a49bfa606fb30c2a605086dab7f4eca..01afc50316be38548d58d9b03569dc894537383c 100644 --- a/src/plugins/welcome/welcomemode.cpp +++ b/src/plugins/welcome/welcomemode.cpp @@ -28,54 +28,48 @@ **************************************************************************/ #include "welcomemode.h" +#include "ui_welcomemode.h" + #include <extensionsystem/pluginmanager.h> #include <coreplugin/icore.h> #include <coreplugin/coreconstants.h> #include <coreplugin/uniqueidmanager.h> -#include <coreplugin/modemanager.h> -#include <coreplugin/dialogs/newdialog.h> #include <utils/styledbar.h> #include <utils/welcomemodetreewidget.h> #include <utils/iwelcomepage.h> -#include <QtGui/QMouseEvent> #include <QtGui/QScrollArea> -#include <QtGui/QButtonGroup> #include <QtGui/QDesktopServices> #include <QtGui/QToolButton> #include <QtCore/QSettings> -#include <QtCore/QUrl> #include <QtCore/QDebug> +#include <QtCore/QUrl> -#include <cstdlib> - -#include "ui_welcomemode.h" +enum { debug = 0 }; using namespace ExtensionSystem; -using namespace Utils; + +static const char currentPageSettingsKeyC[] = "General/WelcomeTab"; namespace Welcome { struct WelcomeModePrivate { - WelcomeModePrivate(); + typedef QMap<QToolButton*, QWidget*> ToolButtonWidgetMap; + + WelcomeModePrivate() {} QScrollArea *m_scrollArea; QWidget *m_widget; QWidget *m_welcomePage; - QMap<QAbstractButton*, QWidget*> buttonMap; + ToolButtonWidgetMap buttonMap; QHBoxLayout * buttonLayout; Ui::WelcomeMode ui; - int currentTip; }; -WelcomeModePrivate::WelcomeModePrivate() -{ -} - // --- WelcomeMode WelcomeMode::WelcomeMode() : m_d(new WelcomeModePrivate) @@ -100,13 +94,12 @@ WelcomeMode::WelcomeMode() : connect(pluginManager, SIGNAL(objectAdded(QObject*)), SLOT(welcomePluginAdded(QObject*))); connect(m_d->ui.feedbackButton, SIGNAL(clicked()), SLOT(slotFeedback())); - } WelcomeMode::~WelcomeMode() { QSettings *settings = Core::ICore::instance()->settings(); - settings->setValue("General/WelcomeTab", m_d->ui.stackedWidget->currentIndex()); + settings->setValue(QLatin1String(currentPageSettingsKeyC), m_d->ui.stackedWidget->currentIndex()); delete m_d->m_widget; delete m_d; } @@ -143,77 +136,78 @@ QList<int> WelcomeMode::context() const return contexts; } -bool sortFunction(IWelcomePage * a, IWelcomePage *b) +bool sortFunction(Utils::IWelcomePage * a, Utils::IWelcomePage *b) { return a->priority() < b->priority(); } +// Create a QToolButton for a page +QToolButton *WelcomeMode::addPageToolButton(Utils::IWelcomePage *plugin, int position) +{ + QToolButton *btn = new QToolButton; + btn->setCheckable(true); + btn->setText(plugin->title()); + btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + btn->setAutoExclusive(true); + connect (btn, SIGNAL(clicked()), SLOT(showClickedPage())); + m_d->buttonMap.insert(btn, plugin->page()); + if (position >= 0) { + m_d->buttonLayout->insertWidget(position, btn); + } else { + m_d->buttonLayout->addWidget(btn); + } + return btn; +} + void WelcomeMode::initPlugins() { m_d->buttonLayout = new QHBoxLayout(m_d->ui.navFrame); m_d->buttonLayout->setMargin(0); m_d->buttonLayout->setSpacing(0); - delete m_d->ui.stackedWidget->currentWidget(); - QList<IWelcomePage*> plugins = PluginManager::instance()->getObjects<IWelcomePage>(); + QList<Utils::IWelcomePage*> plugins = PluginManager::instance()->getObjects<Utils::IWelcomePage>(); qSort(plugins.begin(), plugins.end(), &sortFunction); - foreach (IWelcomePage *plugin, plugins) { - QToolButton *btn = new QToolButton; - btn->setCheckable(true); - btn->setText(plugin->title()); - btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - btn->setAutoExclusive(true); - connect (btn, SIGNAL(clicked()), SLOT(showClickedPage())); + foreach (Utils::IWelcomePage *plugin, plugins) { m_d->ui.stackedWidget->addWidget(plugin->page()); - m_d->buttonLayout->addWidget(btn); - m_d->buttonMap.insert(btn, plugin->page()); + addPageToolButton(plugin); + if (debug) + qDebug() << "WelcomeMode::initPlugins" << plugin->title(); } m_d->buttonLayout->addSpacing(5); QSettings *settings = Core::ICore::instance()->settings(); - int tabId = settings->value("General/WelcomeTab", 0).toInt(); + const int tabId = settings->value(QLatin1String(currentPageSettingsKeyC), 0).toInt(); - int pluginCount = m_d->ui.stackedWidget->count(); - if (tabId < pluginCount) { + const int pluginCount = m_d->ui.stackedWidget->count(); + if (tabId >= 0 && tabId < pluginCount) { m_d->ui.stackedWidget->setCurrentIndex(tabId); - QMapIterator<QAbstractButton*, QWidget*> it(m_d->buttonMap); - while (it.hasNext()) - if (it.next().value() == m_d->ui.stackedWidget->currentWidget()) { - it.key()->setChecked(true); - break; - } + if (QToolButton *btn = m_d->buttonMap.key(m_d->ui.stackedWidget->currentWidget())) + btn->setChecked(true); } - } void WelcomeMode::welcomePluginAdded(QObject *obj) { - if (IWelcomePage *plugin = qobject_cast<IWelcomePage*>(obj)) - { - QToolButton * btn = new QToolButton; - btn->setCheckable(true); - btn->setAutoExclusive(true); - btn->setText(plugin->title()); - btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - connect (btn, SIGNAL(clicked()), SLOT(showClickedPage())); + if (Utils::IWelcomePage *plugin = qobject_cast<Utils::IWelcomePage*>(obj)) { int insertPos = 0; - QList<IWelcomePage*> plugins = PluginManager::instance()->getObjects<IWelcomePage>(); - foreach (IWelcomePage* p, plugins) { + foreach (Utils::IWelcomePage* p, PluginManager::instance()->getObjects<Utils::IWelcomePage>()) { if (plugin->priority() < p->priority()) insertPos++; else break; } m_d->ui.stackedWidget->insertWidget(insertPos, plugin->page()); - m_d->buttonMap.insert(btn, plugin->page()); - m_d->buttonLayout->insertWidget(insertPos, btn); + addPageToolButton(plugin, insertPos); + if (debug) + qDebug() << "welcomePluginAdded" << plugin->title() << "at" << insertPos + << " of " << m_d->buttonMap.size(); } } void WelcomeMode::showClickedPage() { - QAbstractButton *btn = qobject_cast<QAbstractButton*>(sender()); - QMap<QAbstractButton*, QWidget*>::iterator it = m_d->buttonMap.find(btn); - if (it.value()) + QToolButton *btn = qobject_cast<QToolButton*>(sender()); + const WelcomeModePrivate::ToolButtonWidgetMap::const_iterator it = m_d->buttonMap.constFind(btn); + if (it != m_d->buttonMap.constEnd()) m_d->ui.stackedWidget->setCurrentWidget(it.value()); } @@ -223,5 +217,4 @@ void WelcomeMode::slotFeedback() "http://qt.nokia.com/forms/feedback-forms/qt-creator-user-feedback/view"))); } - } // namespace Welcome diff --git a/src/plugins/welcome/welcomemode.h b/src/plugins/welcome/welcomemode.h index 73f8d18add5c941c1145757e2719e4745b3eb71f..3779bf434bc02c22a2447eba3317b9e6c5ca8fb7 100644 --- a/src/plugins/welcome/welcomemode.h +++ b/src/plugins/welcome/welcomemode.h @@ -34,12 +34,14 @@ #include <coreplugin/imode.h> - QT_BEGIN_NAMESPACE class QWidget; -class QUrl; +class QToolButton; QT_END_NAMESPACE +namespace Utils { + class IWelcomePage; +} namespace Welcome { struct WelcomeModePrivate; @@ -69,6 +71,8 @@ private slots: void showClickedPage(); private: + QToolButton *addPageToolButton(Utils::IWelcomePage *plugin, int position = -1); + WelcomeModePrivate *m_d; }; diff --git a/src/plugins/welcome/welcomemode.ui b/src/plugins/welcome/welcomemode.ui index ae3fd53c5feddb4eb0b8ab54b42a1b1142f75c8f..648ed840292b288e8d2d931d3b3ef04a231b5bc6 100644 --- a/src/plugins/welcome/welcomemode.ui +++ b/src/plugins/welcome/welcomemode.ui @@ -249,18 +249,8 @@ QToolButton:pressed { <item> <widget class="QStackedWidget" name="stackedWidget"> <property name="currentIndex"> - <number>0</number> + <number>-1</number> </property> - <widget class="QWidget" name="widget"> - <layout class="QGridLayout" name="gridLayout_7"> - <property name="margin"> - <number>18</number> - </property> - <property name="spacing"> - <number>24</number> - </property> - </layout> - </widget> </widget> </item> <item> diff --git a/src/plugins/welcome/welcomeplugin.cpp b/src/plugins/welcome/welcomeplugin.cpp index 499a0308b85d3c51ba331c02a30baa7f3d1db100..2056807980e4db6bda0eaf505a4ec8481ace06e0 100644 --- a/src/plugins/welcome/welcomeplugin.cpp +++ b/src/plugins/welcome/welcomeplugin.cpp @@ -28,42 +28,22 @@ **************************************************************************/ #include "welcomeplugin.h" - #include "welcomemode.h" - #include "communitywelcomepage.h" -#include <coreplugin/actionmanager/actionmanager.h> -#include <coreplugin/basemode.h> -#include <coreplugin/coreconstants.h> -#include <coreplugin/icore.h> #include <coreplugin/modemanager.h> -#include <coreplugin/uniqueidmanager.h> -#include <QtCore/QDebug> #include <QtCore/QtPlugin> -#include <QtGui/QAction> -#include <QtGui/QMenu> -#include <QtGui/QMessageBox> -#include <QtGui/QPushButton> using namespace Welcome::Internal; WelcomePlugin::WelcomePlugin() - : m_welcomeMode(0), m_communityWelcomePage(0) + : m_welcomeMode(0) { } WelcomePlugin::~WelcomePlugin() { - if (m_welcomeMode) { - removeObject(m_welcomeMode); - delete m_welcomeMode; - } - if (m_communityWelcomePage) { - removeObject(m_communityWelcomePage); - delete m_communityWelcomePage; - } } /*! Initializes the plugin. Returns true on success. @@ -77,11 +57,10 @@ bool WelcomePlugin::initialize(const QStringList &arguments, QString *error_mess Q_UNUSED(arguments) Q_UNUSED(error_message) - m_communityWelcomePage = new Internal::CommunityWelcomePage; - addObject(m_communityWelcomePage); + addAutoReleasedObject(new Internal::CommunityWelcomePage); m_welcomeMode = new WelcomeMode; - addObject(m_welcomeMode); + addAutoReleasedObject(m_welcomeMode); return true; } diff --git a/src/plugins/welcome/welcomeplugin.h b/src/plugins/welcome/welcomeplugin.h index 950cc43d96d4afc3d93febb0d9b27f8f7ea50776..1095e5ec8e6548a5ff4f594761ca5a5bf02fa683 100644 --- a/src/plugins/welcome/welcomeplugin.h +++ b/src/plugins/welcome/welcomeplugin.h @@ -33,28 +33,23 @@ #include <extensionsystem/iplugin.h> namespace Welcome { - class WelcomeMode; namespace Internal { -class CommunityWelcomePage; -class WelcomePlugin - : public ExtensionSystem::IPlugin +class WelcomePlugin : public ExtensionSystem::IPlugin { Q_OBJECT - public: WelcomePlugin(); - ~WelcomePlugin(); + virtual ~WelcomePlugin(); - bool initialize(const QStringList &arguments, QString *error_message); + virtual bool initialize(const QStringList &arguments, QString *error_message); - void extensionsInitialized(); + virtual void extensionsInitialized(); private: WelcomeMode *m_welcomeMode; - Internal::CommunityWelcomePage *m_communityWelcomePage; }; } // namespace Welcome