Code cleanup in Welcome-plugin.

Remove unused page from stacked widget form, move duplicated code
into utility functions, reduce state variables and string comparisons
in RssFetcher, clean out includes. Give WelcomeModeTreeWidget
uniform row height.
This commit is contained in:
Friedemann Kleint
2010-03-31 11:49:06 +02:00
parent d7ca762123
commit f9d2c3ad41
8 changed files with 162 additions and 152 deletions

View File

@@ -50,17 +50,23 @@ void WelcomeModeLabel::setStyledText(const QString &text)
struct WelcomeModeTreeWidgetPrivate struct WelcomeModeTreeWidgetPrivate
{ {
WelcomeModeTreeWidgetPrivate() {} WelcomeModeTreeWidgetPrivate();
QIcon bullet;
const QIcon bullet;
}; };
WelcomeModeTreeWidgetPrivate::WelcomeModeTreeWidgetPrivate() :
bullet(QLatin1String(":/welcome/images/list_bullet_arrow.png"))
{
}
WelcomeModeTreeWidget::WelcomeModeTreeWidget(QWidget *parent) : WelcomeModeTreeWidget::WelcomeModeTreeWidget(QWidget *parent) :
QTreeWidget(parent), m_d(new WelcomeModeTreeWidgetPrivate) QTreeWidget(parent), m_d(new WelcomeModeTreeWidgetPrivate)
{ {
m_d->bullet = QIcon(QLatin1String(":/welcome/images/list_bullet_arrow.png"));
connect(this, SIGNAL(itemClicked(QTreeWidgetItem *, int)), connect(this, SIGNAL(itemClicked(QTreeWidgetItem *, int)),
SLOT(slotItemClicked(QTreeWidgetItem *))); SLOT(slotItemClicked(QTreeWidgetItem *)));
setUniformRowHeights(true);
viewport()->setAutoFillBackground(false); viewport()->setAutoFillBackground(false);
} }

View File

@@ -27,6 +27,9 @@
** **
**************************************************************************/ **************************************************************************/
#include "rssfetcher.h"
#include <coreplugin/coreconstants.h>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtCore/QSysInfo> #include <QtCore/QSysInfo>
#include <QtCore/QLocale> #include <QtCore/QLocale>
@@ -35,10 +38,9 @@
#include <QtNetwork/QNetworkReply> #include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkProxyFactory> #include <QtNetwork/QNetworkProxyFactory>
#include <QtNetwork/QNetworkAccessManager>
#include <coreplugin/coreconstants.h> #include <QtCore/QXmlStreamReader>
#include "rssfetcher.h"
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
#include <sys/utsname.h> #include <sys/utsname.h>
@@ -98,11 +100,13 @@ static const QString getOsString()
} }
#elif defined (Q_OS_UNIX) #elif defined (Q_OS_UNIX)
struct utsname uts; struct utsname uts;
if (uname(&uts) == 0) if (uname(&uts) == 0) {
osString += QString("%1 %2").arg(QLatin1String(uts.sysname)) osString += QLatin1String(uts.sysname);
.arg(QLatin1String(uts.release)); osString += QLatin1Char(' ');
else osString += QLatin1String(uts.release);
} else {
osString += QLatin1String("Unix (Unknown)"); osString += QLatin1String("Unix (Unknown)");
}
#else #else
ossttring = QLatin1String("Unknown OS"); ossttring = QLatin1String("Unknown OS");
#endif #endif
@@ -110,64 +114,103 @@ static const QString getOsString()
} }
RSSFetcher::RSSFetcher(int maxItems, QObject *parent) 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) 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(Core::Constants::IDE_VERSION_LONG).arg(qVersion())
.arg(getOsString()).arg(QLocale::system().name()) .arg(getOsString()).arg(QLocale::system().name())
.arg(QSysInfo::WordSize); .arg(QSysInfo::WordSize);
QNetworkRequest req(url); QNetworkRequest req(url);
req.setRawHeader("User-Agent", agentStr.toLatin1()); 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) void RSSFetcher::fetchingFinished(QNetworkReply *reply)
{ {
bool error = (reply->error() != QNetworkReply::NoError); const bool error = (reply->error() != QNetworkReply::NoError);
if (!error) { if (!error) {
m_xml.addData(reply->readAll()); parseXml(reply);
parseXml();
m_items = 0; m_items = 0;
} }
emit finished(error); emit finished(error);
reply->deleteLater(); reply->deleteLater();
} }
void RSSFetcher::parseXml() RSSFetcher::TagElement RSSFetcher::tagElement(const QStringRef &r)
{ {
while (!m_xml.atEnd()) { if (r == QLatin1String("item"))
m_xml.readNext(); return itemElement;
if (m_xml.isStartElement()) { if (r == QLatin1String("title"))
if (m_xml.name() == "item") { return titleElement;
m_titleString.clear(); if (r == QLatin1String("description"))
m_descriptionString.clear(); return descriptionElement;
m_linkString.clear(); if (r == QLatin1String("link"))
return linkElement;
return otherElement;
} }
m_currentTag = m_xml.name().toString();
} else if (m_xml.isEndElement()) { void RSSFetcher::parseXml(QIODevice *device)
if (m_xml.name() == "item") { {
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();
}
break;
case QXmlStreamReader::EndElement:
if (xmlReader.name() == QLatin1String("item")) {
m_items++; m_items++;
if (m_items > m_maxItems) if (m_items > m_maxItems)
return; return;
emit newsItemReady(m_titleString, m_descriptionString, m_linkString); emit newsItemReady(titleString, descriptionString, linkString);
} }
break;
} else if (m_xml.isCharacters() && !m_xml.isWhitespace()) { case QXmlStreamReader::Characters:
if (m_currentTag == "title") if (!xmlReader.isWhitespace()) {
m_titleString += m_xml.text().toString(); switch (currentTag) {
else if (m_currentTag == "description") case titleElement:
m_descriptionString += m_xml.text().toString(); titleString += xmlReader.text().toString();
else if (m_currentTag == "link") break;
m_linkString += m_xml.text().toString(); 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) { if (xmlReader.error() && xmlReader.error() != QXmlStreamReader::PrematureEndOfDocumentError) {
qWarning() << "XML ERROR:" << m_xml.lineNumber() << ": " << m_xml.errorString(); qWarning() << "XML ERROR:" << xmlReader.lineNumber() << ": " << xmlReader.errorString();
} }
} }

View File

@@ -30,12 +30,14 @@
#ifndef RSSFETCHER_H #ifndef RSSFETCHER_H
#define RSSFETCHER_H #define RSSFETCHER_H
#include <QtCore/QXmlStreamReader> #include <QtCore/QScopedPointer>
#include <QtNetwork/QNetworkAccessManager> #include <QtCore/QObject>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QNetworkReply; class QNetworkReply;
class QNetworkAccessManager;
class QUrl; class QUrl;
class QIODevice;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Welcome { namespace Welcome {
@@ -46,6 +48,7 @@ class RSSFetcher : public QObject
Q_OBJECT Q_OBJECT
public: public:
explicit RSSFetcher(int maxItems, QObject *parent = 0); explicit RSSFetcher(int maxItems, QObject *parent = 0);
virtual ~RSSFetcher();
signals: signals:
void newsItemReady(const QString& title, const QString& desciption, const QString& url); void newsItemReady(const QString& title, const QString& desciption, const QString& url);
@@ -56,17 +59,14 @@ public slots:
void fetch(const QUrl &url); void fetch(const QUrl &url);
private: private:
void parseXml(); enum TagElement { itemElement, titleElement, descriptionElement, linkElement, otherElement };
static TagElement tagElement(const QStringRef &);
void parseXml(QIODevice *);
QXmlStreamReader m_xml; const int m_maxItems;
QString m_currentTag;
QString m_linkString;
QString m_descriptionString;
QString m_titleString;
QNetworkAccessManager m_networkAccessManager; QScopedPointer<QNetworkAccessManager> m_networkAccessManager;
int m_items; int m_items;
int m_maxItems;
}; };
} // namespace Welcome } // namespace Welcome

View File

@@ -28,54 +28,48 @@
**************************************************************************/ **************************************************************************/
#include "welcomemode.h" #include "welcomemode.h"
#include "ui_welcomemode.h"
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/uniqueidmanager.h> #include <coreplugin/uniqueidmanager.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/dialogs/newdialog.h>
#include <utils/styledbar.h> #include <utils/styledbar.h>
#include <utils/welcomemodetreewidget.h> #include <utils/welcomemodetreewidget.h>
#include <utils/iwelcomepage.h> #include <utils/iwelcomepage.h>
#include <QtGui/QMouseEvent>
#include <QtGui/QScrollArea> #include <QtGui/QScrollArea>
#include <QtGui/QButtonGroup>
#include <QtGui/QDesktopServices> #include <QtGui/QDesktopServices>
#include <QtGui/QToolButton> #include <QtGui/QToolButton>
#include <QtCore/QSettings> #include <QtCore/QSettings>
#include <QtCore/QUrl>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtCore/QUrl>
#include <cstdlib> enum { debug = 0 };
#include "ui_welcomemode.h"
using namespace ExtensionSystem; using namespace ExtensionSystem;
using namespace Utils;
static const char currentPageSettingsKeyC[] = "General/WelcomeTab";
namespace Welcome { namespace Welcome {
struct WelcomeModePrivate struct WelcomeModePrivate
{ {
WelcomeModePrivate(); typedef QMap<QToolButton*, QWidget*> ToolButtonWidgetMap;
WelcomeModePrivate() {}
QScrollArea *m_scrollArea; QScrollArea *m_scrollArea;
QWidget *m_widget; QWidget *m_widget;
QWidget *m_welcomePage; QWidget *m_welcomePage;
QMap<QAbstractButton*, QWidget*> buttonMap; ToolButtonWidgetMap buttonMap;
QHBoxLayout * buttonLayout; QHBoxLayout * buttonLayout;
Ui::WelcomeMode ui; Ui::WelcomeMode ui;
int currentTip;
}; };
WelcomeModePrivate::WelcomeModePrivate()
{
}
// --- WelcomeMode // --- WelcomeMode
WelcomeMode::WelcomeMode() : WelcomeMode::WelcomeMode() :
m_d(new WelcomeModePrivate) m_d(new WelcomeModePrivate)
@@ -100,13 +94,12 @@ WelcomeMode::WelcomeMode() :
connect(pluginManager, SIGNAL(objectAdded(QObject*)), SLOT(welcomePluginAdded(QObject*))); connect(pluginManager, SIGNAL(objectAdded(QObject*)), SLOT(welcomePluginAdded(QObject*)));
connect(m_d->ui.feedbackButton, SIGNAL(clicked()), SLOT(slotFeedback())); connect(m_d->ui.feedbackButton, SIGNAL(clicked()), SLOT(slotFeedback()));
} }
WelcomeMode::~WelcomeMode() WelcomeMode::~WelcomeMode()
{ {
QSettings *settings = Core::ICore::instance()->settings(); 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->m_widget;
delete m_d; delete m_d;
} }
@@ -143,77 +136,78 @@ QList<int> WelcomeMode::context() const
return contexts; return contexts;
} }
bool sortFunction(IWelcomePage * a, IWelcomePage *b) bool sortFunction(Utils::IWelcomePage * a, Utils::IWelcomePage *b)
{ {
return a->priority() < b->priority(); 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() void WelcomeMode::initPlugins()
{ {
m_d->buttonLayout = new QHBoxLayout(m_d->ui.navFrame); m_d->buttonLayout = new QHBoxLayout(m_d->ui.navFrame);
m_d->buttonLayout->setMargin(0); m_d->buttonLayout->setMargin(0);
m_d->buttonLayout->setSpacing(0); m_d->buttonLayout->setSpacing(0);
delete m_d->ui.stackedWidget->currentWidget(); QList<Utils::IWelcomePage*> plugins = PluginManager::instance()->getObjects<Utils::IWelcomePage>();
QList<IWelcomePage*> plugins = PluginManager::instance()->getObjects<IWelcomePage>();
qSort(plugins.begin(), plugins.end(), &sortFunction); qSort(plugins.begin(), plugins.end(), &sortFunction);
foreach (IWelcomePage *plugin, plugins) { foreach (Utils::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()));
m_d->ui.stackedWidget->addWidget(plugin->page()); m_d->ui.stackedWidget->addWidget(plugin->page());
m_d->buttonLayout->addWidget(btn); addPageToolButton(plugin);
m_d->buttonMap.insert(btn, plugin->page()); if (debug)
qDebug() << "WelcomeMode::initPlugins" << plugin->title();
} }
m_d->buttonLayout->addSpacing(5); m_d->buttonLayout->addSpacing(5);
QSettings *settings = Core::ICore::instance()->settings(); 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(); const int pluginCount = m_d->ui.stackedWidget->count();
if (tabId < pluginCount) { if (tabId >= 0 && tabId < pluginCount) {
m_d->ui.stackedWidget->setCurrentIndex(tabId); m_d->ui.stackedWidget->setCurrentIndex(tabId);
QMapIterator<QAbstractButton*, QWidget*> it(m_d->buttonMap); if (QToolButton *btn = m_d->buttonMap.key(m_d->ui.stackedWidget->currentWidget()))
while (it.hasNext()) btn->setChecked(true);
if (it.next().value() == m_d->ui.stackedWidget->currentWidget()) {
it.key()->setChecked(true);
break;
} }
} }
}
void WelcomeMode::welcomePluginAdded(QObject *obj) void WelcomeMode::welcomePluginAdded(QObject *obj)
{ {
if (IWelcomePage *plugin = qobject_cast<IWelcomePage*>(obj)) if (Utils::IWelcomePage *plugin = qobject_cast<Utils::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()));
int insertPos = 0; int insertPos = 0;
QList<IWelcomePage*> plugins = PluginManager::instance()->getObjects<IWelcomePage>(); foreach (Utils::IWelcomePage* p, PluginManager::instance()->getObjects<Utils::IWelcomePage>()) {
foreach (IWelcomePage* p, plugins) {
if (plugin->priority() < p->priority()) if (plugin->priority() < p->priority())
insertPos++; insertPos++;
else else
break; break;
} }
m_d->ui.stackedWidget->insertWidget(insertPos, plugin->page()); m_d->ui.stackedWidget->insertWidget(insertPos, plugin->page());
m_d->buttonMap.insert(btn, plugin->page()); addPageToolButton(plugin, insertPos);
m_d->buttonLayout->insertWidget(insertPos, btn); if (debug)
qDebug() << "welcomePluginAdded" << plugin->title() << "at" << insertPos
<< " of " << m_d->buttonMap.size();
} }
} }
void WelcomeMode::showClickedPage() void WelcomeMode::showClickedPage()
{ {
QAbstractButton *btn = qobject_cast<QAbstractButton*>(sender()); QToolButton *btn = qobject_cast<QToolButton*>(sender());
QMap<QAbstractButton*, QWidget*>::iterator it = m_d->buttonMap.find(btn); const WelcomeModePrivate::ToolButtonWidgetMap::const_iterator it = m_d->buttonMap.constFind(btn);
if (it.value()) if (it != m_d->buttonMap.constEnd())
m_d->ui.stackedWidget->setCurrentWidget(it.value()); 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"))); "http://qt.nokia.com/forms/feedback-forms/qt-creator-user-feedback/view")));
} }
} // namespace Welcome } // namespace Welcome

View File

@@ -34,12 +34,14 @@
#include <coreplugin/imode.h> #include <coreplugin/imode.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QWidget; class QWidget;
class QUrl; class QToolButton;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Utils {
class IWelcomePage;
}
namespace Welcome { namespace Welcome {
struct WelcomeModePrivate; struct WelcomeModePrivate;
@@ -69,6 +71,8 @@ private slots:
void showClickedPage(); void showClickedPage();
private: private:
QToolButton *addPageToolButton(Utils::IWelcomePage *plugin, int position = -1);
WelcomeModePrivate *m_d; WelcomeModePrivate *m_d;
}; };

View File

@@ -249,18 +249,8 @@ QToolButton:pressed {
<item> <item>
<widget class="QStackedWidget" name="stackedWidget"> <widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>-1</number>
</property> </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> </widget>
</item> </item>
<item> <item>

View File

@@ -28,42 +28,22 @@
**************************************************************************/ **************************************************************************/
#include "welcomeplugin.h" #include "welcomeplugin.h"
#include "welcomemode.h" #include "welcomemode.h"
#include "communitywelcomepage.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/modemanager.h>
#include <coreplugin/uniqueidmanager.h>
#include <QtCore/QDebug>
#include <QtCore/QtPlugin> #include <QtCore/QtPlugin>
#include <QtGui/QAction>
#include <QtGui/QMenu>
#include <QtGui/QMessageBox>
#include <QtGui/QPushButton>
using namespace Welcome::Internal; using namespace Welcome::Internal;
WelcomePlugin::WelcomePlugin() WelcomePlugin::WelcomePlugin()
: m_welcomeMode(0), m_communityWelcomePage(0) : m_welcomeMode(0)
{ {
} }
WelcomePlugin::~WelcomePlugin() 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. /*! 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(arguments)
Q_UNUSED(error_message) Q_UNUSED(error_message)
m_communityWelcomePage = new Internal::CommunityWelcomePage; addAutoReleasedObject(new Internal::CommunityWelcomePage);
addObject(m_communityWelcomePage);
m_welcomeMode = new WelcomeMode; m_welcomeMode = new WelcomeMode;
addObject(m_welcomeMode); addAutoReleasedObject(m_welcomeMode);
return true; return true;
} }

View File

@@ -33,28 +33,23 @@
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
namespace Welcome { namespace Welcome {
class WelcomeMode; class WelcomeMode;
namespace Internal { namespace Internal {
class CommunityWelcomePage;
class WelcomePlugin class WelcomePlugin : public ExtensionSystem::IPlugin
: public ExtensionSystem::IPlugin
{ {
Q_OBJECT Q_OBJECT
public: public:
WelcomePlugin(); 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: private:
WelcomeMode *m_welcomeMode; WelcomeMode *m_welcomeMode;
Internal::CommunityWelcomePage *m_communityWelcomePage;
}; };
} // namespace Welcome } // namespace Welcome