This commit is contained in:
Martin Rotter 2013-11-17 20:42:02 +01:00
parent e8fbb1707b
commit d7dd476af8
8 changed files with 120 additions and 53 deletions

View File

@ -14,11 +14,22 @@ MessagesModel::MessagesModel(QObject *parent)
: QAbstractItemModel(parent) { : QAbstractItemModel(parent) {
setObjectName("MessagesModel"); setObjectName("MessagesModel");
// TODO: Separovat do samostatné skupiny metod.
// Bude potřeba metoda "loadFeed(int feed_id)"
// a v te se bude volat SELECT .... FROM Messages WHERE id IN (feed_id,feed_id2)
// a tak dále.
QSqlDatabase d = DatabaseFactory::getInstance()->addConnection("MessagesModel2"); QSqlDatabase d = DatabaseFactory::getInstance()->addConnection("MessagesModel2");
QSqlQuery prikaz = d.exec("SELECT id, read, deleted, important, " QSqlQuery prikaz = d.exec("SELECT id, read, deleted, important, feed, "
"title, url, author, date_created, " "title, url, author, date_created, "
"date_updated, contents FROM Messages;"); "date_updated, contents FROM Messages;");
// TODO: Oddělit toto do samostatné metody setupIcons(),
// aby bylo možno měnit ikony dynamicky.
m_favoriteIcon = IconThemeFactory::getInstance()->fromTheme("mail-mark-important");
m_readIcon = IconThemeFactory::getInstance()->fromTheme("mail-mark-read");
m_unreadIcon = IconThemeFactory::getInstance()->fromTheme("mail-mark-unread");
// Prepare correct columns mappings.
m_columnMappings.insert(MSG_MODEL_READ_INDEX, MSG_DB_READ_INDEX); m_columnMappings.insert(MSG_MODEL_READ_INDEX, MSG_DB_READ_INDEX);
m_columnMappings.insert(MSG_MODEL_IMPORTANT_INDEX, MSG_DB_IMPORTANT_INDEX); m_columnMappings.insert(MSG_MODEL_IMPORTANT_INDEX, MSG_DB_IMPORTANT_INDEX);
m_columnMappings.insert(MSG_MODEL_TITLE_INDEX, MSG_DB_TITLE_INDEX); m_columnMappings.insert(MSG_MODEL_TITLE_INDEX, MSG_DB_TITLE_INDEX);
@ -34,6 +45,7 @@ MessagesModel::MessagesModel(QObject *parent)
mess.m_data.append(prikaz.value(MSG_DB_READ_INDEX).toInt()); mess.m_data.append(prikaz.value(MSG_DB_READ_INDEX).toInt());
mess.m_data.append(prikaz.value(MSG_DB_DELETED_INDEX).toInt()); mess.m_data.append(prikaz.value(MSG_DB_DELETED_INDEX).toInt());
mess.m_data.append(prikaz.value(MSG_DB_IMPORTANT_INDEX).toInt()); mess.m_data.append(prikaz.value(MSG_DB_IMPORTANT_INDEX).toInt());
mess.m_data.append(prikaz.value(MSG_DB_FEED_INDEX).toInt());
mess.m_data.append(prikaz.value(MSG_DB_TITLE_INDEX).toString()); mess.m_data.append(prikaz.value(MSG_DB_TITLE_INDEX).toString());
mess.m_data.append(prikaz.value(MSG_DB_URL_INDEX).toString()); mess.m_data.append(prikaz.value(MSG_DB_URL_INDEX).toString());
mess.m_data.append(prikaz.value(MSG_DB_AUTHOR_INDEX).toString()); mess.m_data.append(prikaz.value(MSG_DB_AUTHOR_INDEX).toString());
@ -106,15 +118,39 @@ QVariant MessagesModel::headerData(int section,
switch (role) { switch (role) {
case Qt::DisplayRole: case Qt::DisplayRole:
if (section > MSG_MODEL_IMPORTANT_INDEX) {
return m_headerData.at(section);
}
else {
return QVariant();
}
case Qt::ToolTipRole: case Qt::ToolTipRole:
case Qt::EditRole: case Qt::EditRole:
return m_headerData.at(section); return m_headerData.at(section);
case Qt::DecorationRole: {
switch (section) {
case MSG_MODEL_READ_INDEX:
return m_readIcon;
case MSG_MODEL_IMPORTANT_INDEX:
return m_favoriteIcon;
default:
return QVariant();
}
}
default: default:
return QVariant(); return QVariant();
} }
} }
QVariant MessagesModel::data(int row, int column, int role) const {
return data(index(row, column), role);
}
QVariant MessagesModel::data(const QModelIndex &index, int role) const { QVariant MessagesModel::data(const QModelIndex &index, int role) const {
// TODO: Return ISO date on EditRole and human readable date on // TODO: Return ISO date on EditRole and human readable date on
// DisplayRole. EditRole is used for sorting (and ISO date can be // DisplayRole. EditRole is used for sorting (and ISO date can be
@ -125,30 +161,44 @@ QVariant MessagesModel::data(const QModelIndex &index, int role) const {
// Just return RAW data. // Just return RAW data.
return m_messages.at(index.row()).m_data.at(m_columnMappings[index.column()]); return m_messages.at(index.row()).m_data.at(m_columnMappings[index.column()]);
case Qt::ToolTipRole:
case Qt::DisplayRole: { case Qt::DisplayRole: {
int real_column = m_columnMappings[index.column()]; int index_column = index.column();
if (real_column != MSG_DB_IMPORTANT_INDEX) { if (index_column > MSG_MODEL_IMPORTANT_INDEX) {
return m_messages.at(index.row()).m_data.at(real_column); return m_messages.at(index.row()).m_data.at(m_columnMappings[index_column]);
} }
else { else {
return QVariant(); return QVariant();
} }
} }
case Qt::FontRole: case Qt::FontRole:
return m_messages.at(index.row()).m_data.at(m_columnMappings[MSG_MODEL_READ_INDEX]).toInt() == 1 ? return m_messages.at(index.row()).m_data.at(m_columnMappings[MSG_MODEL_READ_INDEX]).toInt() == 1 ?
m_normalFont : m_normalFont :
m_boldFont; m_boldFont;
case Qt::DecorationRole:/* case Qt::DecorationRole: {
if (index.column() == 0 && m_messages[index.row()].m_important == 1) { int index_column = index.column();
return IconThemeFactory::getInstance()->fromTheme("zoom-fit-best");
switch (index_column) {
case MSG_MODEL_READ_INDEX:
if (m_messages.at(index.row()).m_data.at(m_columnMappings[index_column]).toInt() == 1) {
return m_readIcon;
}
else {
return m_unreadIcon;
}
case MSG_MODEL_IMPORTANT_INDEX:
if (m_messages.at(index.row()).m_data.at(m_columnMappings[index_column]).toInt() == 1) {
return m_favoriteIcon;
}
default:
return QVariant();
} }
else { }
return QVariant();
}*/
default: default:
return QVariant(); return QVariant();
@ -172,12 +222,16 @@ bool MessagesModel::setData(int row, int column, const QVariant &value) {
return setData(index(row, column), value); return setData(index(row, column), value);
} }
const Message &MessagesModel::messageAt(int row_index) const {
return m_messages.at(row_index);
}
void MessagesModel::setMessageRead(int row_index, int read) { void MessagesModel::setMessageRead(int row_index, int read) {
//int read_column = fieldIndex("read"); //int read_column = fieldIndex("read");
//blockSignals(true); //blockSignals(true);
if (m_messages.at(row_index).m_data.at(MSG_DB_READ_INDEX).toInt() != read) { if (data(row_index, MSG_MODEL_READ_INDEX).toInt() != read) {
// Old "read" status of this message differs from // Old "read" status of this message differs from
// the new status, update it. // the new status, update it.
setData(row_index, MSG_MODEL_READ_INDEX, read); setData(row_index, MSG_MODEL_READ_INDEX, read);

View File

@ -3,25 +3,16 @@
#include <QAbstractItemModel> #include <QAbstractItemModel>
#include <QFont> #include <QFont>
#include <QIcon>
// Representation of ONE message. // Representation of ONE message.
class Message { class Message {
private: private:
QList<QVariant> m_data; QList<QVariant> m_data;
/*
int m_id;
int m_read;
int m_deleted;
int m_important;
QString m_title;
QString m_url;
QString m_author;
QString m_dateCreated;
QString m_dateUpdate;
QString m_contents;
*/
friend class MessagesModel; friend class MessagesModel;
friend class WebBrowser;
}; };
class MessagesModel : public QAbstractItemModel { class MessagesModel : public QAbstractItemModel {
@ -37,6 +28,7 @@ class MessagesModel : public QAbstractItemModel {
// Data accessors/manipulators. // Data accessors/manipulators.
QVariant headerData(int section, Qt::Orientation orientation, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QVariant data(const QModelIndex &index, int role) const; QVariant data(const QModelIndex &index, int role) const;
QVariant data(int row, int column, int role = Qt::EditRole) const;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
bool setData(int row, int column, const QVariant &value); bool setData(int row, int column, const QVariant &value);
Qt::ItemFlags flags(const QModelIndex &index) const; Qt::ItemFlags flags(const QModelIndex &index) const;
@ -49,6 +41,8 @@ class MessagesModel : public QAbstractItemModel {
QModelIndex parent(const QModelIndex &child) const; QModelIndex parent(const QModelIndex &child) const;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
const Message &messageAt(int row_index) const;
public slots: public slots:
// Sets "read" status of message with given row index. // Sets "read" status of message with given row index.
void setMessageRead(int row_index, int read); void setMessageRead(int row_index, int read);
@ -65,6 +59,9 @@ class MessagesModel : public QAbstractItemModel {
QFont m_normalFont; QFont m_normalFont;
QFont m_boldFont; QFont m_boldFont;
QIcon m_favoriteIcon;
QIcon m_readIcon;
QIcon m_unreadIcon;
QList<QString> m_headerData; QList<QString> m_headerData;
}; };

View File

@ -18,6 +18,11 @@ FeedMessageViewer::FeedMessageViewer(QWidget *parent)
m_messagesBrowser(new WebBrowser(this)) { m_messagesBrowser(new WebBrowser(this)) {
initialize(); initialize();
initializeViews(); initializeViews();
// TODO: oddělit do createConnections();
connect(m_messagesView, SIGNAL(currentMessageChanged(Message)),
m_messagesBrowser, SLOT(navigateToMessage(Message)));
} }
void FeedMessageViewer::initialize() { void FeedMessageViewer::initialize() {

View File

@ -17,46 +17,30 @@ MessagesView::~MessagesView() {
qDebug("Destroying MessagesView instance."); qDebug("Destroying MessagesView instance.");
} }
MessagesModel *MessagesView::sourceModel() {
return m_sourceModel;
}
MessagesProxyModel *MessagesView::model() {
return m_proxyModel;
}
void MessagesView::setupAppearance() { void MessagesView::setupAppearance() {
header()->setStretchLastSection(true);
setAcceptDrops(false); setAcceptDrops(false);
setDragEnabled(false); setDragEnabled(false);
setDragDropMode(QAbstractItemView::NoDragDrop); setDragDropMode(QAbstractItemView::NoDragDrop);
setExpandsOnDoubleClick(false); setExpandsOnDoubleClick(false);
setRootIsDecorated(false); setRootIsDecorated(false);
setItemsExpandable(false); setItemsExpandable(false);
setSortingEnabled(true); setSortingEnabled(false);
setAllColumnsShowFocus(true); setAllColumnsShowFocus(true);
setSelectionMode(QAbstractItemView::ExtendedSelection); setSelectionMode(QAbstractItemView::ExtendedSelection);
} }
void MessagesView::selectionChanged(const QItemSelection &selected, void MessagesView::selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected) { const QItemSelection &deselected) {
/*
if (selected.indexes().size() > 0) {
QModelIndex ind = m_proxyModel->mapToSource(selected.indexes().at(0));
QModelIndex a = selected.indexes().at(0);
qDebug("SelectionChanged %d %d source %d %d",
selected.indexes().at(0).row(), selected.indexes().at(0).column(),
ind.row(), ind.column());
m_sourceModel->setMessageRead(1, ind.row());
sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
QModelIndex new_index = m_proxyModel->mapFromSource(ind);
// TODO: Buď tady obnovovat celý předchozí výběr nějak
// nebo použít starší kod a optimalizovat ho.
selectionModel()->clearSelection();
selectionModel()->blockSignals(true);
setCurrentIndex(new_index);
scrollTo(new_index);
selectionModel()->select(new_index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows | QItemSelectionModel::Current );
selectionModel()->blockSignals(false);
}*/
QTreeView::selectionChanged(selected, deselected); QTreeView::selectionChanged(selected, deselected);
} }
@ -71,5 +55,7 @@ void MessagesView::currentChanged(const QModelIndex &current,
m_sourceModel->setMessageRead(ind.row(), 1); m_sourceModel->setMessageRead(ind.row(), 1);
emit currentMessageChanged(m_sourceModel->messageAt(ind.row()));
QTreeView::currentChanged(current, previous); QTreeView::currentChanged(current, previous);
} }

View File

@ -16,6 +16,9 @@ class MessagesView : public QTreeView {
explicit MessagesView(QWidget *parent = 0); explicit MessagesView(QWidget *parent = 0);
virtual ~MessagesView(); virtual ~MessagesView();
MessagesProxyModel *model();
MessagesModel *sourceModel();
protected: protected:
void setupAppearance(); void setupAppearance();

View File

@ -40,7 +40,8 @@ void SkinFactory::loadCurrentSkin() {
qDebug("Skin '%s' loaded.", qPrintable(skin_name_from_settings)); qDebug("Skin '%s' loaded.", qPrintable(skin_name_from_settings));
} }
else { else {
qDebug("Skin '%s' not loaded because its data are corrupted. No skin is loaded now!", // TODO: změnit toto na qFatal v produkčním kodu.
qWarning("Skin '%s' not loaded because its data are corrupted. No skin is loaded now!",
qPrintable(skin_name_from_settings)); qPrintable(skin_name_from_settings));
} }
} }

View File

@ -11,9 +11,11 @@
#include <QMessageBox> #include <QMessageBox>
#include <QToolButton> #include <QToolButton>
#include "core/defs.h"
#include "core/basenetworkaccessmanager.h" #include "core/basenetworkaccessmanager.h"
#include "core/webbrowsernetworkaccessmanager.h" #include "core/webbrowsernetworkaccessmanager.h"
#include "core/basewebpage.h" #include "core/basewebpage.h"
#include "gui/skinfactory.h"
#include "gui/basewebview.h" #include "gui/basewebview.h"
#include "gui/webbrowser.h" #include "gui/webbrowser.h"
#include "gui/formmain.h" #include "gui/formmain.h"
@ -165,6 +167,22 @@ void WebBrowser::navigateToUrl(const QUrl &url) {
} }
} }
void WebBrowser::navigateToMessage(const Message &message) {
// TODO: dodělat.
m_webView->setHtml(SkinFactory::getInstance()->getCurrentMarkup().arg(message.m_data.at(MSG_DB_TITLE_INDEX).toString(),
tr("Check your internet connection or website address"),
QString(),
tr("This failure can be caused by:<br><ul>"
"<li>non-functional internet connection,</li>"
"<li>incorrect website address,</li>"
"<li>bad proxy server settings,</li>"
"<li>target destination outage,</li>"
"<li>many other things.</li>"
"</ul>"),
"aa"));
}
void WebBrowser::updateZoomGui() { void WebBrowser::updateZoomGui() {
m_btnResetZoom->setText(QString("%1%").arg(QString::number(m_webView->zoomFactor() * 100, m_btnResetZoom->setText(QString("%1%").arg(QString::number(m_webView->zoomFactor() * 100,
'f', 'f',

View File

@ -5,6 +5,7 @@
#include <QPointer> #include <QPointer>
#include <QUrl> #include <QUrl>
#include "core/messagesmodel.h"
#include "gui/tabcontent.h" #include "gui/tabcontent.h"
@ -59,13 +60,15 @@ class WebBrowser : public TabContent {
void navigateToUrl(const QString &url); void navigateToUrl(const QString &url);
void navigateToUrl(const QUrl &url); void navigateToUrl(const QUrl &url);
// Navigates to message.
void navigateToMessage(const Message &message);
// Zoom manipulators. // Zoom manipulators.
void increaseZoom(); void increaseZoom();
void decreaseZoom(); void decreaseZoom();
void resetZoom(); void resetZoom();
protected: protected:
// Creates necessary connections. // Creates necessary connections.
void createConnections(); void createConnections();