This commit is contained in:
Martin Rotter 2013-11-20 21:54:30 +01:00
parent 81c30c504a
commit db5274da66
7 changed files with 138 additions and 85 deletions

View file

@ -1,50 +1,50 @@
DROP TABLE IF EXISTS Information; DROP TABLE IF EXISTS Information;
-- ! -- !
CREATE TABLE IF NOT EXISTS Information ( CREATE TABLE IF NOT EXISTS Information (
key TEXT PRIMARY KEY, key TEXT PRIMARY KEY,
value TEXT NOT NULL value TEXT NOT NULL
); );
-- ! -- !
INSERT INTO Information VALUES ('schema_version', '0.0.1'); INSERT INTO Information VALUES ('schema_version', '0.0.1');
-- ! -- !
DROP TABLE IF EXISTS Categories; DROP TABLE IF EXISTS Categories;
-- ! -- !
CREATE TABLE IF NOT EXISTS Categories ( CREATE TABLE IF NOT EXISTS Categories (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
title TEXT NOT NULL UNIQUE CHECK (title != ''), title TEXT NOT NULL UNIQUE CHECK (title != ''),
description TEXT, description TEXT,
date_created TEXT NOT NULL CHECK (date_created != ''), date_created TEXT NOT NULL CHECK (date_created != ''),
icon BLOB icon BLOB
); );
-- ! -- !
DROP TABLE IF EXISTS Feeds; DROP TABLE IF EXISTS Feeds;
-- ! -- !
CREATE TABLE IF NOT EXISTS Feeds ( CREATE TABLE IF NOT EXISTS Feeds (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
title TEXT NOT NULL CHECK (title != ''), title TEXT NOT NULL CHECK (title != ''),
description TEXT, description TEXT,
date_created TEXT NOT NULL CHECK (date_created != ''), date_created TEXT NOT NULL CHECK (date_created != ''),
icon BLOB, icon BLOB,
category INTEGER NOT NULL CHECK (category >= -1), category INTEGER NOT NULL CHECK (category >= -1),
encoding TEXT NOT NULL CHECK (encoding != ''), encoding TEXT NOT NULL CHECK (encoding != ''),
url TEXT NOT NULL UNIQUE CHECK (url != ''), url TEXT NOT NULL UNIQUE CHECK (url != ''),
type INTEGER NOT NULL type INTEGER NOT NULL
); );
-- ! -- !
DROP TABLE IF EXISTS Messages; DROP TABLE IF EXISTS Messages;
-- ! -- !
CREATE TABLE IF NOT EXISTS Messages ( CREATE TABLE IF NOT EXISTS Messages (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
read INTEGER(1) NOT NULL CHECK (read >= 0 AND read <= 1) DEFAULT (0), read INTEGER(1) NOT NULL CHECK (read >= 0 AND read <= 1) DEFAULT (0),
deleted INTEGER(1) NOT NULL CHECK (deleted >= 0 AND deleted <= 1) DEFAULT (0), deleted INTEGER(1) NOT NULL CHECK (deleted >= 0 AND deleted <= 1) DEFAULT (0),
important INTEGER(1) NOT NULL CHECK (important >= 0 AND important <= 1) DEFAULT (0), important INTEGER(1) NOT NULL CHECK (important >= 0 AND important <= 1) DEFAULT (0),
feed INTEGER NOT NULL, feed INTEGER NOT NULL,
title TEXT NOT NULL CHECK (title != ''), title TEXT NOT NULL CHECK (title != ''),
url TEXT, url TEXT,
author TEXT, author TEXT,
date_created TEXT NOT NULL CHECK (date_created != ''), date_created TEXT NOT NULL CHECK (date_created != ''),
date_updated TEXT, date_updated TEXT,
contents TEXT, contents TEXT,
FOREIGN KEY (feed) REFERENCES Feeds (id) FOREIGN KEY (feed) REFERENCES Feeds (id)
); );

View file

@ -6,31 +6,40 @@
<email>rotter.martinos@gmail.com</email> <email>rotter.martinos@gmail.com</email>
</author> </author>
<style/> <style/>
<markup>PGh0bWw+IDxoZWFkPiA8c3R5bGU+cHJle3doaXRlLXNwYWNlOnByZS13cmFwfS5oZWFkZXJ0ZXh0 <markup>PGh0bWw+DQogIDxoZWFkPg0KICAgIDxzdHlsZT4NCiAgICAgIHByZXsNCiAgICAgICAgd2hpdGUt
e2ZvbnQtc2l6ZToxOXB4O21hcmdpbi1ib3R0b206MTBweH0uaGVhZGVye2ZvbnQtc2l6ZToxNXB4 c3BhY2U6cHJlLXdyYXB9DQogICAgICAuaGVhZGVydGV4dHsNCiAgICAgICAgZm9udC1zaXplOjE5
Oy13ZWJraXQtdHJhbnNpdGlvbjpiYWNrZ3JvdW5kIDFzIGVhc2Utb3V0O2JhY2tncm91bmQ6LXdl cHg7DQogICAgICAgIG1hcmdpbi1ib3R0b206MTBweH0NCiAgICAgIC5oZWFkZXJ7DQogICAgICAg
YmtpdC1ncmFkaWVudChsaW5lYXIsbGVmdCB0b3AsbGVmdCBib3R0b20sY29sb3Itc3RvcCgwJSwj IGZvbnQtc2l6ZToxNXB4Ow0KICAgICAgICAtd2Via2l0LXRyYW5zaXRpb246YmFja2dyb3VuZCAx
NDU0ODRkKSxjb2xvci1zdG9wKDEwMCUsIzAwMDAwMCkpO2JhY2tncm91bmQ6LXdlYmtpdC1saW5l cyBlYXNlLW91dDsNCiAgICAgICAgYmFja2dyb3VuZDotd2Via2l0LWdyYWRpZW50KGxpbmVhcixs
YXItZ3JhZGllbnQodG9wLCM0NTQ4NGQgMCwjMDAwMDAwIDEwMCUpOy13ZWJraXQtYm9yZGVyLXJh ZWZ0IHRvcCxsZWZ0IGJvdHRvbSxjb2xvci1zdG9wKDAlLCM0NTQ4NGQpLGNvbG9yLXN0b3AoMTAw
ZGl1czozcHg7dGV4dC1zaGFkb3c6MCAwIDFweCAjZmZmO2ZpbHRlcjpkcm9wc2hhZG93KGNvbG9y JSwjMDAwMDAwKSk7DQogICAgICAgIGJhY2tncm91bmQ6LXdlYmtpdC1saW5lYXItZ3JhZGllbnQo
PSNmZmZmZmYsb2ZmeD0wLG9mZnk9MCk7cGFkZGluZzo4cHg7bWFyZ2luOjVweCBhdXRvIDVweCBh dG9wLCM0NTQ4NGQgMCwjMDAwMDAwIDEwMCUpOw0KICAgICAgICAtd2Via2l0LWJvcmRlci1yYWRp
dXRvO2NvbG9yOndoaXRlfS5oZWFkZXIgYXtjb2xvcjp3aGl0ZX0uY29udGVudHtmb250LXNpemU6 dXM6MXB4Ow0KICAgICAgICB0ZXh0LXNoYWRvdzowIDAgMXB4ICNmZmY7DQogICAgICAgIGZpbHRl
MTRweDtiYWNrZ3JvdW5kOi13ZWJraXQtZ3JhZGllbnQobGluZWFyLGxlZnQgdG9wLGxlZnQgYm90 cjpkcm9wc2hhZG93KGNvbG9yPSNmZmZmZmYsb2ZmeD0wLG9mZnk9MCk7DQogICAgICAgIHBhZGRp
dG9tLGNvbG9yLXN0b3AoMCUscmdiYSgyMzgsMjM4LDIzOCwwLjY2KSksY29sb3Itc3RvcCgxMDAl bmc6OHB4Ow0KICAgICAgICBtYXJnaW46NXB4IGF1dG8gNXB4IGF1dG87DQogICAgICAgIGNvbG9y
LHJnYmEoMjM4LDIzOCwyMzgsMC42NikpKTtiYWNrZ3JvdW5kOi13ZWJraXQtbGluZWFyLWdyYWRp OndoaXRlfQ0KICAgICAgLmhlYWRlciBhew0KICAgICAgICBjb2xvcjp3aGl0ZX0NCiAgICAgIC5j
ZW50KHRvcCxyZ2JhKDIzOCwyMzgsMjM4LDAuNjYpIDAscmdiYSgyMzgsMjM4LDIzOCwwLjY2KSAx b250ZW50ew0KICAgICAgICBmb250LXNpemU6MTRweDsNCiAgICAgICAgYmFja2dyb3VuZDotd2Vi
MDAlKTstd2Via2l0LWJvcmRlci1yYWRpdXM6M3B4O21hcmdpbjo1cHggYXV0byA1cHggYXV0bztw a2l0LWdyYWRpZW50KGxpbmVhcixsZWZ0IHRvcCxsZWZ0IGJvdHRvbSxjb2xvci1zdG9wKDAlLHJn
YWRkaW5nOjhweH0uZm9vdGVye2ZvbnQtc2l6ZToxMnB4O3RleHQtYWxpZ246Y2VudGVyO3ZlcnRp YmEoMjM4LDIzOCwyMzgsMC42NikpLGNvbG9yLXN0b3AoMTAwJSxyZ2JhKDIzOCwyMzgsMjM4LDAu
Y2FsLWFsaWduOm1pZGRsZTstd2Via2l0LXRyYW5zaXRpb246YmFja2dyb3VuZCAxcyBlYXNlLW91 NjYpKSk7DQogICAgICAgIGJhY2tncm91bmQ6LXdlYmtpdC1saW5lYXItZ3JhZGllbnQodG9wLHJn
dDtiYWNrZ3JvdW5kOi13ZWJraXQtZ3JhZGllbnQobGluZWFyLGxlZnQgdG9wLGxlZnQgYm90dG9t YmEoMjM4LDIzOCwyMzgsMC42NikgMCxyZ2JhKDIzOCwyMzgsMjM4LDAuNjYpIDEwMCUpOw0KICAg
LGNvbG9yLXN0b3AoMCUsIzQ1NDg0ZCksY29sb3Itc3RvcCgxMDAlLCMwMDAwMDApKTtiYWNrZ3Jv ICAgICAtd2Via2l0LWJvcmRlci1yYWRpdXM6MXB4Ow0KICAgICAgICBtYXJnaW46NXB4IGF1dG8g
dW5kOi13ZWJraXQtbGluZWFyLWdyYWRpZW50KHRvcCwjNDU0ODRkIDAsIzAwMDAwMCAxMDAlKTst NXB4IGF1dG87DQogICAgICAgIHBhZGRpbmc6OHB4fQ0KICAgICAgLmZvb3RlcnsNCiAgICAgICAg
d2Via2l0LWJvcmRlci1yYWRpdXM6M3B4O3RleHQtc2hhZG93OjAgMCAxcHggI2ZmZjtmaWx0ZXI6 Zm9udC1zaXplOjEycHg7DQogICAgICAgIHRleHQtYWxpZ246Y2VudGVyOw0KICAgICAgICB2ZXJ0
ZHJvcHNoYWRvdyhjb2xvcj0jZmZmZmZmLG9mZng9MCxvZmZ5PTApO3BhZGRpbmc6OHB4O21hcmdp aWNhbC1hbGlnbjptaWRkbGU7DQogICAgICAgIC13ZWJraXQtdHJhbnNpdGlvbjpiYWNrZ3JvdW5k
bjo1cHggYXV0byA1cHggYXV0bztjb2xvcjp3aGl0ZX08L3N0eWxlPiA8dGl0bGU+JTE8L3RpdGxl IDFzIGVhc2Utb3V0Ow0KICAgICAgICBiYWNrZ3JvdW5kOi13ZWJraXQtZ3JhZGllbnQobGluZWFy
PiA8L2hlYWQ+IDxib2R5PiA8ZGl2IGNsYXNzPSJoZWFkZXIiPiA8ZGl2IGNsYXNzPSJoZWFkZXJ0 LGxlZnQgdG9wLGxlZnQgYm90dG9tLGNvbG9yLXN0b3AoMCUsIzQ1NDg0ZCksY29sb3Itc3RvcCgx
ZXh0Ij4lMTwvZGl2PiAlMjxicj4gPGEgaHJlZj0iJTMiPiUzPC9hPiA8L2Rpdj4gPGRpdiBjbGFz MDAlLCMwMDAwMDApKTsNCiAgICAgICAgYmFja2dyb3VuZDotd2Via2l0LWxpbmVhci1ncmFkaWVu
cz0iY29udGVudCI+ICU0IDwvZGl2PiA8ZGl2IGNsYXNzPSJmb290ZXIiPiAlNSA8L2Rpdj4gPC9i dCh0b3AsIzQ1NDg0ZCAwLCMwMDAwMDAgMTAwJSk7DQogICAgICAgIC13ZWJraXQtYm9yZGVyLXJh
b2R5PiA8L2h0bWw+</markup> ZGl1czoxcHg7DQogICAgICAgIHRleHQtc2hhZG93OjAgMCAxcHggI2ZmZjsNCiAgICAgICAgZmls
dGVyOmRyb3BzaGFkb3coY29sb3I9I2ZmZmZmZixvZmZ4PTAsb2ZmeT0wKTsNCiAgICAgICAgcGFk
ZGluZzo4cHg7DQogICAgICAgIG1hcmdpbjo1cHggYXV0byA1cHggYXV0bzsNCiAgICAgICAgY29s
b3I6d2hpdGV9DQogICAgPC9zdHlsZT4NCiAgICA8dGl0bGU+DQogICAgICAlMQ0KICAgIDwvdGl0
bGU+DQogIDwvaGVhZD4NCiAgPGJvZHk+DQogICAgPGRpdiBjbGFzcz0iaGVhZGVyIj4NCiAgICAg
IDxkaXYgY2xhc3M9ImhlYWRlcnRleHQiPg0KICAgICAgICAlMQ0KICAgICAgPC9kaXY+DQogICAg
ICAlMg0KICAgICAgPGJyPg0KICAgICAgPGEgaHJlZj0iJTMiPg0KICAgICAgICAlMw0KICAgICAg
PC9hPg0KICAgIDwvZGl2Pg0KICAgIDxkaXYgY2xhc3M9ImNvbnRlbnQiPg0KICAgICAgJTQgDQog
ICAgPC9kaXY+DQogICAgPGRpdiBjbGFzcz0iZm9vdGVyIj4NCiAgICAgICU1IA0KICAgIDwvZGl2
Pg0KICA8L2JvZHk+DQo8L2h0bWw+</markup>
<data/> <data/>
</skin> </skin>

View file

@ -20,7 +20,7 @@ MessagesModel::MessagesModel(QObject *parent)
setupHeaderData(); setupHeaderData();
// Set desired table and edit strategy. // Set desired table and edit strategy.
setEditStrategy(QSqlTableModel::OnFieldChange); setEditStrategy(QSqlTableModel::OnManualSubmit);
setTable("Messages"); setTable("Messages");
loadMessages(QList<int>()); loadMessages(QList<int>());
@ -50,7 +50,11 @@ void MessagesModel::setupFonts() {
} }
void MessagesModel::loadMessages(const QList<int> feed_ids) { void MessagesModel::loadMessages(const QList<int> feed_ids) {
// Submit changes first.
submitAll();
// Conversion of parameter. // Conversion of parameter.
m_currentFeeds = feed_ids;
QStringList stringy_ids; QStringList stringy_ids;
stringy_ids.reserve(feed_ids.count()); stringy_ids.reserve(feed_ids.count());
@ -68,6 +72,7 @@ Message MessagesModel::messageAt(int row_index) const {
QSqlRecord rec = record(row_index); QSqlRecord rec = record(row_index);
Message message; Message message;
// Fill Message object with details.
message.m_author = rec.value(MSG_DB_AUTHOR_INDEX).toString(); message.m_author = rec.value(MSG_DB_AUTHOR_INDEX).toString();
message.m_contents = rec.value(MSG_DB_CONTENTS_INDEX).toString(); message.m_contents = rec.value(MSG_DB_CONTENTS_INDEX).toString();
message.m_title = rec.value(MSG_DB_TITLE_INDEX).toString(); message.m_title = rec.value(MSG_DB_TITLE_INDEX).toString();
@ -95,6 +100,10 @@ Qt::ItemFlags MessagesModel::flags(const QModelIndex &idx) const {
} }
} }
QVariant MessagesModel::data(int row, int column, int role) const {
return data(index(row, column), role);
}
QVariant MessagesModel::data(const QModelIndex &idx, int role) const { QVariant MessagesModel::data(const QModelIndex &idx, int role) const {
switch (role) { switch (role) {
// //
@ -142,10 +151,6 @@ QVariant MessagesModel::data(const QModelIndex &idx, int role) const {
} }
bool MessagesModel::setData(const QModelIndex &idx, const QVariant &value, int role) { bool MessagesModel::setData(const QModelIndex &idx, const QVariant &value, int role) {
if (!idx.isValid()) {
return false;
}
m_isInEditingMode = true; m_isInEditingMode = true;
bool set_data_result = QSqlTableModel::setData(idx, value, role); bool set_data_result = QSqlTableModel::setData(idx, value, role);
m_isInEditingMode = false; m_isInEditingMode = false;
@ -153,6 +158,25 @@ bool MessagesModel::setData(const QModelIndex &idx, const QVariant &value, int r
return set_data_result; return set_data_result;
} }
bool MessagesModel::setMessageRead(int row_index, int read) {
return setData(index(row_index, MSG_DB_READ_INDEX),
read);
}
bool MessagesModel::setMessageDeleted(int row_index, int deleted) {
return setData(index(row_index, MSG_DB_DELETED_INDEX),
deleted);
}
bool MessagesModel::switchMessageImportance(int row_index) {
QModelIndex target_index = index(row_index, MSG_DB_IMPORTANT_INDEX);
int current_importance = data(target_index).toInt();
return current_importance == 1 ?
setData(target_index, 0) :
setData(target_index, 1);
}
QVariant MessagesModel::headerData(int section, QVariant MessagesModel::headerData(int section,
Qt::Orientation orientation, Qt::Orientation orientation,
int role) const { int role) const {

View file

@ -35,7 +35,8 @@ class MessagesModel : public QSqlTableModel {
// Model implementation. // Model implementation.
bool setData(const QModelIndex &idx, const QVariant &value, int role = Qt::EditRole); bool setData(const QModelIndex &idx, const QVariant &value, int role = Qt::EditRole);
QVariant data(const QModelIndex &idx, int role) const; QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const;
QVariant data(int row, int column, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const;
Qt::ItemFlags flags(const QModelIndex &idx) const; Qt::ItemFlags flags(const QModelIndex &idx) const;
@ -43,12 +44,17 @@ class MessagesModel : public QSqlTableModel {
// Sets up all icons which are used directly by this model. // Sets up all icons which are used directly by this model.
void setupIcons(); void setupIcons();
// Returns const reference to message at given index. // Returns message at given index.
Message messageAt(int row_index) const; Message messageAt(int row_index) const;
public slots: public slots:
// Message manipulators.
bool switchMessageImportance(int row_index);
bool setMessageDeleted(int row_index, int deleted);
bool setMessageRead(int row_index, int read);
// Fetches ALL available data to the model. // Fetches ALL available data to the model.
// NOTE: This is almost needed when sorting // NOTE: This is almost always needed when sorting
// and makes the model more predictable. // and makes the model more predictable.
void fetchAll(); void fetchAll();
@ -63,6 +69,7 @@ class MessagesModel : public QSqlTableModel {
void setupFonts(); void setupFonts();
private: private:
QList<int> m_currentFeeds;
QList<QString> m_headerData; QList<QString> m_headerData;
bool m_isInEditingMode; bool m_isInEditingMode;

View file

@ -3,11 +3,13 @@
#include <QToolBar> #include <QToolBar>
#include <QApplication> #include <QApplication>
#include <QLineEdit> #include <QLineEdit>
#include <QAction>
#include "gui/feedmessageviewer.h" #include "gui/feedmessageviewer.h"
#include "gui/webbrowser.h" #include "gui/webbrowser.h"
#include "gui/messagesview.h" #include "gui/messagesview.h"
#include "gui/feedsview.h" #include "gui/feedsview.h"
#include "core/messagesproxymodel.h"
FeedMessageViewer::FeedMessageViewer(QWidget *parent) FeedMessageViewer::FeedMessageViewer(QWidget *parent)
@ -31,7 +33,11 @@ void FeedMessageViewer::initialize() {
m_toolBar->setMovable(false); m_toolBar->setMovable(false);
m_toolBar->setAllowedAreas(Qt::TopToolBarArea); m_toolBar->setAllowedAreas(Qt::TopToolBarArea);
// TODO: testovaci
m_toolBar->addAction(QIcon::fromTheme("application-exit"), "aaa"); m_toolBar->addAction(QIcon::fromTheme("application-exit"), "aaa");
QAction *ac = m_toolBar->actions().at(0);
connect(ac, SIGNAL(triggered()),
m_messagesView->model()->sourceModel(), SLOT(submitAll()));
// Finish web/message browser setup. // Finish web/message browser setup.
m_messagesBrowser->setNavigationBarVisible(false); m_messagesBrowser->setNavigationBarVisible(false);

View file

@ -89,7 +89,7 @@ void MessagesView::currentChanged(const QModelIndex &current,
current.row(), current.column(), current.row(), current.column(),
ind.row(), ind.column()); ind.row(), ind.column());
m_sourceModel->setData(m_sourceModel->index(ind.row(), 1), 1, Qt::EditRole); m_sourceModel->setMessageRead(ind.row(), 1);
emit currentMessageChanged(m_sourceModel->messageAt(ind.row())); emit currentMessageChanged(m_sourceModel->messageAt(ind.row()));

View file

@ -22,6 +22,14 @@ class MessagesView : public QTreeView {
MessagesProxyModel *model(); MessagesProxyModel *model();
MessagesModel *sourceModel(); MessagesModel *sourceModel();
public slots:
// Message manipulators.
// TODO: sem pridat metody jako
// setSelectedMessagesRead....
// setSelectedMessagesUnread.....
// deleteSelectedMessages....
// ......
protected: protected:
void setupAppearance(); void setupAppearance();
@ -34,7 +42,6 @@ class MessagesView : public QTreeView {
const QItemSelection &deselected); const QItemSelection &deselected);
signals: signals:
// TODO: dodělat signál.
void currentMessageChanged(const Message &message); void currentMessageChanged(const Message &message);
void currentMessageRemoved(); void currentMessageRemoved();