Introduce QML-based welcome screen using desktop components

Implements new XML-based format for examples, demos & tutorials

Done-with: Primrose Mbanefo <ext-primrose.mbanefo@nokia.com>
Change-Id: I42c0afdb419cffe5637cd4f298e828d09e0fb15a
Reviewed-on: http://codereview.qt.nokia.com/840
Reviewed-by: Eike Ziller <eike.ziller@nokia.com>
This commit is contained in:
Daniel Molkentin
2010-11-11 16:49:17 +01:00
committed by Eike Ziller
parent b23aa10890
commit 497dd323ea
150 changed files with 10887 additions and 1761 deletions

View File

@@ -84,14 +84,15 @@ SOURCES += mainwindow.cpp \
outputpanemanager.cpp \
navigationsubwidget.cpp \
sidebarwidget.cpp \
rssfetcher.cpp \
externaltool.cpp \
dialogs/externaltoolconfig.cpp \
toolsettings.cpp \
variablechooser.cpp \
mimetypemagicdialog.cpp \
mimetypesettings.cpp \
dialogs/promptoverwritedialog.cpp
dialogs/promptoverwritedialog.cpp \
multifeedrssmodel.cpp \
networkaccessmanager.cpp
HEADERS += mainwindow.h \
editmode.h \
@@ -177,14 +178,15 @@ HEADERS += mainwindow.h \
outputpanemanager.h \
navigationsubwidget.h \
sidebarwidget.h \
rssfetcher.h \
externaltool.h \
dialogs/externaltoolconfig.h \
toolsettings.h \
variablechooser.h \
mimetypemagicdialog.h \
mimetypesettings.h \
dialogs/promptoverwritedialog.h
dialogs/promptoverwritedialog.h \
multifeedrssmodel.h \
networkaccessmanager.h
FORMS += dialogs/newdialog.ui \
actionmanager/commandmappings.ui \

View File

@@ -432,6 +432,10 @@ FancyTabWidget::FancyTabWidget(QWidget *parent)
connect(m_tabBar, SIGNAL(currentChanged(int)), this, SLOT(showWidget(int)));
}
void FancyTabWidget::setSelectionWidgetHidden(bool hidden) {
m_selectionWidget->setHidden(hidden);
}
void FancyTabWidget::insertTab(int index, QWidget *tab, const QIcon &icon, const QString &label)
{
m_modesStack->insertWidget(index, tab);

View File

@@ -168,6 +168,7 @@ signals:
public slots:
void setCurrentIndex(int index);
void setSelectionWidgetHidden(bool hidden);
private slots:
void showWidget(int index);

View File

@@ -331,6 +331,11 @@ void ModeManager::setFocusToCurrentMode()
}
}
void ModeManager::setModeBarHidden(bool hidden)
{
d->m_modeStack->setSelectionWidgetHidden(hidden);
}
ModeManager *ModeManager::instance()
{
return ModeManagerPrivate::m_instance;

View File

@@ -70,6 +70,7 @@ public:
void addWidget(QWidget *widget);
void activateModeType(const QString &type);
void setModeBarHidden(bool hidden);
signals:
void currentModeAboutToChange(Core::IMode *mode);

View File

@@ -0,0 +1,190 @@
#include "multifeedrssmodel.h"
#include <QtCore/QTimer>
#include <QtCore/QThread>
#include <QtCore/QXmlStreamReader>
#include <QtCore/QCoreApplication>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include "networkaccessmanager.h"
#include <QDebug>
namespace Core {
namespace Internal {
QString shortenHtml(QString html)
{
html.replace(QLatin1String("<a"), QLatin1String("<i"));
html.replace(QLatin1String("</a"), QLatin1String("</i"));
uint firstParaEndXhtml = (uint) html.indexOf(QLatin1String("</p>"));
uint firstParaEndHtml = (uint) html.indexOf(QLatin1String("<p>"), html.indexOf(QLatin1String("<p>"))+1);
uint firstParaEndBr = (uint) html.indexOf(QLatin1String("<br"));
uint firstParaEnd = qMin(firstParaEndXhtml, firstParaEndHtml);
firstParaEnd = qMin(firstParaEnd, firstParaEndBr);
return html.left(firstParaEnd);
}
class RssReader {
public:
Internal::RssItem parseItem() {
RssItem item;
item.source = requestUrl;
item.blogIcon = blogIcon;
item.blogName = blogName;
while (!streamReader.atEnd()) {
switch (streamReader.readNext()) {
case QXmlStreamReader::StartElement:
if (streamReader.name() == QLatin1String("title"))
item.title = streamReader.readElementText();
else if (streamReader.name() == QLatin1String("link"))
item.link = streamReader.readElementText();
else if (streamReader.name() == QLatin1String("pubDate")) {
QString dateStr = streamReader.readElementText();
// fixme: honor time zone!
dateStr = dateStr.left(dateStr.indexOf('+')-1);
item.pubDate = QDateTime::fromString(dateStr, "ddd, dd MMM yyyy HH:mm:ss");
}
else if (streamReader.name() == QLatin1String("description"))
item.description = shortenHtml(streamReader.readElementText());
break;
case QXmlStreamReader::EndElement:
if (streamReader.name() == QLatin1String("item"))
return item;
break;
default:
break;
}
}
return RssItem();
}
Internal::RssItemList parse(QNetworkReply *reply) {
QUrl source = reply->request().url();
requestUrl = source.toString();
streamReader.setDevice(reply);
Internal::RssItemList list;
while (!streamReader.atEnd()) {
switch (streamReader.readNext()) {
case QXmlStreamReader::StartElement:
if (streamReader.name() == QLatin1String("item"))
list.append(parseItem());
else if (streamReader.name() == QLatin1String("title"))
blogName = streamReader.readElementText();
else if (streamReader.name() == QLatin1String("link")) {
if (!streamReader.namespaceUri().isEmpty())
break;
QString favIconString(streamReader.readElementText());
QUrl favIconUrl(favIconString);
favIconUrl.setPath(QLatin1String("favicon.ico"));
blogIcon = favIconUrl.toString();
}
break;
default:
break;
}
}
return list;
}
private:
QXmlStreamReader streamReader;
QString requestUrl;
QString blogIcon;
QString blogName;
};
} // namespace Internal
MultiFeedRssModel::MultiFeedRssModel(QObject *parent) :
QAbstractListModel(parent),
m_networkAccessManager(new NetworkAccessManager),
m_articleCount(0)
{
//m_namThread = new QThread;
//m_networkAccessManager->moveToThread(m_namThread);
connect(m_networkAccessManager, SIGNAL(finished(QNetworkReply*)),
SLOT(appendFeedData(QNetworkReply*)), Qt::QueuedConnection);
//m_namThread->start();
//qDebug() << "MainThread" << QThread::currentThread();
QHash<int, QByteArray> roleNames;
roleNames[TitleRole] = "title";
roleNames[DescriptionRole] = "description";
roleNames[PubDateRole] = "pubDate";
roleNames[LinkRole] = "link";
roleNames[BlogNameRole] = "blogName";
roleNames[BlogIconRole] = "blogIcon";
setRoleNames(roleNames);
}
MultiFeedRssModel::~MultiFeedRssModel()
{
//m_namThread->exit();
//delete m_namThread;
}
void MultiFeedRssModel::addFeed(const QString& feed)
{
QMetaObject::invokeMethod(m_networkAccessManager, "getUrl",
Qt::QueuedConnection, Q_ARG(QUrl, feed));
}
bool sortForPubDate(const Internal::RssItem& item1, const Internal::RssItem& item2)
{
return item1.pubDate > item2.pubDate;
}
void MultiFeedRssModel::appendFeedData(QNetworkReply *reply)
{
Internal::RssReader reader;
m_aggregatedFeed.append(reader.parse(reply));
qSort(m_aggregatedFeed.begin(), m_aggregatedFeed.end(), sortForPubDate);
setArticleCount(m_aggregatedFeed.size());
reset();
}
void MultiFeedRssModel::removeFeed(const QString &feed)
{
QMutableListIterator<Internal::RssItem> it(m_aggregatedFeed);
while (it.hasNext()) {
Internal::RssItem item = it.next();
if (item.source == feed)
it.remove();
}
setArticleCount(m_aggregatedFeed.size());
}
int MultiFeedRssModel::rowCount(const QModelIndex &) const
{
return m_aggregatedFeed.size();
}
QVariant MultiFeedRssModel::data(const QModelIndex &index, int role) const
{
Internal::RssItem item = m_aggregatedFeed.at(index.row());
switch (role) {
case Qt::DisplayRole: // fall through
case TitleRole:
return item.title;
case DescriptionRole:
return item.description;
case PubDateRole:
return item.pubDate;
case LinkRole:
return item.link;
case BlogNameRole:
return item.blogName;
case BlogIconRole:
return item.blogIcon;
}
return QVariant();
}
} // namespace Utils

View File

@@ -0,0 +1,79 @@
#ifndef MULTIFEEDRSSMODEL_H
#define MULTIFEEDRSSMODEL_H
#include "core_global.h"
#include <QtCore/QAbstractListModel>
#include <QtCore/QStringList>
#include <QtCore/QDateTime>
QT_BEGIN_NAMESPACE
class QThread;
class QNetworkReply;
QT_END_NAMESPACE
namespace Core {
namespace Internal {
struct RssItem {
QString source;
QString title;
QString link;
QString description;
QString blogName;
QString blogIcon;
QDateTime pubDate;
};
typedef QList<RssItem> RssItemList;
} // namespace Internal
class NetworkAccessManager;
enum RssRoles { TitleRole = Qt::UserRole+1, DescriptionRole, LinkRole,
PubDateRole, BlogNameRole, BlogIconRole };
class CORE_EXPORT MultiFeedRssModel : public QAbstractListModel {
Q_OBJECT
Q_PROPERTY(int articleCount READ articleCount WRITE setArticleCount NOTIFY articleCountChanged)
public:
explicit MultiFeedRssModel(QObject *parent);
~MultiFeedRssModel();
void addFeed(const QString& feed);
void removeFeed(const QString& feed);
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
int articleCount() const { return m_articleCount; }
public slots:
void setArticleCount(int arg)
{
if (m_articleCount != arg) {
m_articleCount = arg;
emit articleCountChanged(arg);
}
}
signals:
void articleCountChanged(int arg);
private slots:
void appendFeedData(QNetworkReply *reply);
private:
QStringList m_sites;
Internal::RssItemList m_aggregatedFeed;
NetworkAccessManager *m_networkAccessManager;
QThread *m_namThread;
int m_articleCount;
};
} // namespace Utils
#endif // MULTIFEEDRSSMODEL_H

View File

@@ -0,0 +1,113 @@
#include "networkaccessmanager.h"
#include <QtCore/QLocale>
#include <QtNetwork/QNetworkReply>
#ifdef Q_OS_UNIX
#include <sys/utsname.h>
#endif
#include "coreconstants.h"
/*!
\class Core::NetworkManager
\brief Network Access Manager for use with Qt Creator.
Common initialization, Qt Creator User Agent
*/
namespace Core {
static const QString getOsString()
{
QString osString;
#if defined(Q_OS_WIN)
switch (QSysInfo::WindowsVersion) {
case (QSysInfo::WV_4_0):
osString += QLatin1String("WinNT4.0");
break;
case (QSysInfo::WV_5_0):
osString += QLatin1String("Windows NT 5.0");
break;
case (QSysInfo::WV_5_1):
osString += QLatin1String("Windows NT 5.1");
break;
case (QSysInfo::WV_5_2):
osString += QLatin1String("Windows NT 5.2");
break;
case (QSysInfo::WV_6_0):
osString += QLatin1String("Windows NT 6.0");
break;
case (QSysInfo::WV_6_1):
osString += QLatin1String("Windows NT 6.1");
break;
default:
osString += QLatin1String("Windows NT (Unknown)");
break;
}
#elif defined (Q_OS_MAC)
if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
osString += QLatin1String("PPC ");
else
osString += QLatin1String("Intel ");
osString += QLatin1String("Mac OS X ");
switch (QSysInfo::MacintoshVersion) {
case (QSysInfo::MV_10_3):
osString += QLatin1String("10_3");
break;
case (QSysInfo::MV_10_4):
osString += QLatin1String("10_4");
break;
case (QSysInfo::MV_10_5):
osString += QLatin1String("10_5");
break;
case (QSysInfo::MV_10_6):
osString += QLatin1String("10_6");
break;
default:
osString += QLatin1String("(Unknown)");
break;
}
#elif defined (Q_OS_UNIX)
struct utsname uts;
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
return osString;
}
NetworkAccessManager::NetworkAccessManager(QObject *parent)
: QNetworkAccessManager(parent)
{
}
void NetworkAccessManager::getUrl(const QUrl &url)
{
QNetworkRequest req;
req.setUrl(url);
get(req);
}
QNetworkReply* NetworkAccessManager::createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData)
{
QString agentStr = QString::fromLatin1("Qt-Creator/%1 (QNetworkAccessManager %2; %3; %4; %5 bit)")
.arg(Core::Constants::IDE_VERSION_LONG).arg(qVersion())
.arg(getOsString()).arg(QLocale::system().name())
.arg(QSysInfo::WordSize);
QNetworkRequest req(request);
req.setRawHeader("User-Agent", agentStr.toLatin1());
return QNetworkAccessManager::createRequest(op, req, outgoingData);
}
} // namespace utils

View File

@@ -0,0 +1,22 @@
#include "core_global.h"
#include <QtCore/QUrl>
#include <QtNetwork/QNetworkAccessManager>
namespace Core {
class CORE_EXPORT NetworkAccessManager : public QNetworkAccessManager
{
Q_OBJECT
public:
NetworkAccessManager(QObject *parent = 0);
public slots:
void getUrl(const QUrl &url);
protected:
virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData);
};
} // namespace utils