diff --git a/resources/misc/db_init.sql b/resources/misc/db_init.sql index 4115a8e3a..1d8db6fd1 100644 --- a/resources/misc/db_init.sql +++ b/resources/misc/db_init.sql @@ -21,13 +21,13 @@ DROP TABLE IF EXISTS Feeds; -- ! CREATE TABLE IF NOT EXISTS Feeds ( id INTEGER PRIMARY KEY, - title TEXT NOT NULL UNIQUE CHECK (title != ''), + title TEXT NOT NULL CHECK (title != ''), description TEXT, date_created TEXT NOT NULL CHECK (date_created != ''), icon BLOB, category INTEGER NOT NULL CHECK (category >= -1), encoding TEXT NOT NULL CHECK (encoding != ''), - url TEXT NOT NULL CHECK (url != ''), + url TEXT NOT NULL UNIQUE CHECK (url != ''), type INTEGER NOT NULL ); -- ! @@ -35,16 +35,16 @@ DROP TABLE IF EXISTS Messages; -- ! CREATE TABLE IF NOT EXISTS Messages ( id INTEGER PRIMARY KEY, + feed INTEGER NOT NULL, title TEXT NOT NULL CHECK (title != ''), - owner INTEGER NOT NULL, url TEXT, author TEXT, date_created TEXT NOT NULL CHECK (date_created != ''), date_updated TEXT, - contents TEXT, 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), important INTEGER(1) NOT NULL CHECK (important >= 0 AND important <= 1) DEFAULT (0), + contents TEXT, - FOREIGN KEY (owner) REFERENCES Feeds (id) + FOREIGN KEY (feed) REFERENCES Feeds (id) ); \ No newline at end of file diff --git a/src/core/databasefactory.cpp b/src/core/databasefactory.cpp index afd5bc3d8..c9583b127 100644 --- a/src/core/databasefactory.cpp +++ b/src/core/databasefactory.cpp @@ -110,20 +110,11 @@ QSqlDatabase DatabaseFactory::initialize(const QString &connection_name) { q.finish(); } - m_initialized = true; - return database; } QSqlDatabase DatabaseFactory::addConnection(const QString &connection_name) { - if (!m_initialized) { - // Initialize database file and return connection if it is not - // initialized yet. - return initialize(connection_name); - } - else { - return QSqlDatabase::addDatabase(DATABASE_DRIVER, connection_name); - } + return initialize(connection_name); } QSqlDatabase DatabaseFactory::getConnection(const QString &connection_name) { diff --git a/src/core/databasefactory.h b/src/core/databasefactory.h index 3239d59ea..d8dc74e89 100644 --- a/src/core/databasefactory.h +++ b/src/core/databasefactory.h @@ -22,9 +22,6 @@ class DatabaseFactory : public QObject { // Path to database file. QString m_databasePath; - // True if database file is initialized, otherwise false. - bool m_initialized; - // Private singleton value. static QPointer s_instance; diff --git a/src/core/defs.h.in b/src/core/defs.h.in index c88a1edfc..87cf7bd54 100644 --- a/src/core/defs.h.in +++ b/src/core/defs.h.in @@ -34,9 +34,9 @@ #define APP_DB_INIT_SPLIT "-- !\n" #define APP_DB_PATH "data/database/local" #define APP_DB_FILE "database.db" +#define APP_DB_WEB_PATH "data/database/web" #define APP_CFG_PATH "data/config" -#define APP_CFG_WEB_PATH "data/database/web" #define APP_CFG_FILE "config.ini" #define APP_CFG_GUI "gui" #define APP_CFG_GEN "main" diff --git a/src/core/messagesmodel.cpp b/src/core/messagesmodel.cpp index 1b9ebc4ab..573dcc7b4 100644 --- a/src/core/messagesmodel.cpp +++ b/src/core/messagesmodel.cpp @@ -1,15 +1,35 @@ #include "core/messagesmodel.h" +#include "core/databasefactory.h" -MessagesModel::MessagesModel(QObject *parent) : QSqlTableModel(parent) { +MessagesModel::MessagesModel(QObject *parent) + : QSqlTableModel(parent, + DatabaseFactory::getInstance()->addConnection("MessagesModel")) { setObjectName("MessagesModel"); + setEditStrategy(QSqlTableModel::OnFieldChange); + setupHeaderData(); + + setTable("Messages"); + select(); +} + +MessagesModel::~MessagesModel() { + qDebug("Destroying MessagesModel instance."); } void MessagesModel::setupHeaderData() { // TODO: Enhance this. - m_headerData << tr("aaa") << - tr("bbb"); + m_headerData << tr("Id") << tr("Feed") << tr("Title") << + tr("URL") << tr("Author") << tr("Created on") << + tr("Last updated on") << tr("Read") << tr("Deleted") << + tr("Important") << tr("Contents"); +} + +Qt::ItemFlags MessagesModel::flags(const QModelIndex &index) const { + Q_UNUSED(index); + + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; } QVariant MessagesModel::headerData(int section, diff --git a/src/core/messagesmodel.h b/src/core/messagesmodel.h index cb90bf9e6..ac85aa162 100644 --- a/src/core/messagesmodel.h +++ b/src/core/messagesmodel.h @@ -9,10 +9,13 @@ class MessagesModel : public QSqlTableModel { Q_OBJECT public: + // Constructors and destructors. explicit MessagesModel(QObject *parent = 0); + virtual ~MessagesModel(); - + // Model implementation. QVariant headerData(int section, Qt::Orientation orientation, int role) const; + Qt::ItemFlags flags(const QModelIndex &index) const; private: void setupHeaderData(); diff --git a/src/core/messagesproxymodel.cpp b/src/core/messagesproxymodel.cpp index 39ada9074..b15d43dc0 100644 --- a/src/core/messagesproxymodel.cpp +++ b/src/core/messagesproxymodel.cpp @@ -1,6 +1,19 @@ #include "core/messagesproxymodel.h" +#include "core/messagesmodel.h" MessagesProxyModel::MessagesProxyModel(QObject *parent) : QSortFilterProxyModel(parent) { + m_sourceModel = new MessagesModel(this); + + setObjectName("MessagesProxyModel"); + setSortRole(Qt::EditRole); + setSortCaseSensitivity(Qt::CaseInsensitive); + setFilterCaseSensitivity(Qt::CaseInsensitive); + setFilterKeyColumn(-1); + setSourceModel(m_sourceModel); +} + +MessagesProxyModel::~MessagesProxyModel() { + qDebug("Destroying MessagesProxyModel instance."); } diff --git a/src/core/messagesproxymodel.h b/src/core/messagesproxymodel.h index 44341bef9..8b5ea8e6a 100644 --- a/src/core/messagesproxymodel.h +++ b/src/core/messagesproxymodel.h @@ -4,16 +4,18 @@ #include +class MessagesModel; + class MessagesProxyModel : public QSortFilterProxyModel { Q_OBJECT public: + // Constructors and destructors. explicit MessagesProxyModel(QObject *parent = 0); + virtual ~MessagesProxyModel(); - signals: - - public slots: - + private: + MessagesModel *m_sourceModel; }; #endif // MESSAGESPROXYMODEL_H diff --git a/src/core/settings.cpp b/src/core/settings.cpp index b90e2c1ea..f4e52d06a 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -69,7 +69,7 @@ QSettings::Status Settings::setupSettings() { // TODO: Separate web settings into another unit. // Construct icon cache in the same path. - QString web_path = app_path + QDir::separator() + APP_CFG_WEB_PATH; + QString web_path = app_path + QDir::separator() + APP_DB_WEB_PATH; QDir(web_path).mkpath(web_path); QWebSettings::setIconDatabasePath(web_path); @@ -87,7 +87,7 @@ QSettings::Status Settings::setupSettings() { Settings::NonPortable, qApp); // Construct icon cache in the same path. - QString web_path = home_path + QDir::separator() + APP_CFG_WEB_PATH; + QString web_path = home_path + QDir::separator() + APP_DB_WEB_PATH; QDir(web_path).mkpath(web_path); QWebSettings::setIconDatabasePath(web_path); diff --git a/src/gui/feedmessageviewer.cpp b/src/gui/feedmessageviewer.cpp index f69a9eaec..f5e3fe45b 100644 --- a/src/gui/feedmessageviewer.cpp +++ b/src/gui/feedmessageviewer.cpp @@ -15,8 +15,7 @@ FeedMessageViewer::FeedMessageViewer(QWidget *parent) m_toolBar(new QToolBar(tr("Toolbar for messages"), this)), m_messagesView(new MessagesView(this)), m_feedsView(new FeedsView(this)), - m_messagesBrowser(new WebBrowser(this)) -{ + m_messagesBrowser(new WebBrowser(this)) { initialize(); initializeViews(); } @@ -27,7 +26,7 @@ void FeedMessageViewer::initialize() { m_toolBar->setMovable(false); m_toolBar->setAllowedAreas(Qt::TopToolBarArea); - m_toolBar->addAction(QIcon::fromTheme("application-exit"), "aaa"); + m_toolBar->addAction(QIcon::fromTheme("application-exit"), "aaa"); // Finish web/message browser setup. m_messagesBrowser->setNavigationBarVisible(false); diff --git a/src/gui/formsettings.cpp b/src/gui/formsettings.cpp index 9f5fc8c2c..b981ecbb9 100644 --- a/src/gui/formsettings.cpp +++ b/src/gui/formsettings.cpp @@ -482,8 +482,10 @@ void FormSettings::saveInterface() { IconThemeFactory::getInstance()->setCurrentIconTheme(selected_icon_theme); // Save and activate new skin. - Skin active_skin = m_ui->m_treeSkins->currentItem()->data(0, Qt::UserRole).value(); - SkinFactory::getInstance()->setCurrentSkinName(active_skin.m_baseName); + if (m_ui->m_treeSkins->selectedItems().size() > 0) { + Skin active_skin = m_ui->m_treeSkins->currentItem()->data(0, Qt::UserRole).value(); + SkinFactory::getInstance()->setCurrentSkinName(active_skin.m_baseName); + } // Save tab settings. settings->setValue(APP_CFG_GUI, "tab_close_mid_button", diff --git a/src/gui/iconthemefactory.cpp b/src/gui/iconthemefactory.cpp index 4b3592ac0..57e05f0fe 100644 --- a/src/gui/iconthemefactory.cpp +++ b/src/gui/iconthemefactory.cpp @@ -90,7 +90,6 @@ void IconThemeFactory::loadCurrentIconTheme(bool notify_widgets) { qDebug("Installed icon themes are: %s.", qPrintable(installed_themes.join(", "))); - if (installed_themes.contains(theme_name_from_settings)) { // Desired icon theme is installed and can be loaded. qDebug("Loading icon theme '%s'.", qPrintable(theme_name_from_settings)); diff --git a/src/gui/messagesview.cpp b/src/gui/messagesview.cpp index dbdf6ccea..fcb745171 100644 --- a/src/gui/messagesview.cpp +++ b/src/gui/messagesview.cpp @@ -1,9 +1,23 @@ #include "gui/messagesview.h" +#include "core/messagesproxymodel.h" +#include "core/messagesmodel.h" MessagesView::MessagesView(QWidget *parent) : QTreeView(parent) { + m_proxyModel = new MessagesProxyModel(this); + + setModel(m_proxyModel); + setupAppearance(); } MessagesView::~MessagesView() { qDebug("Destroying MessagesView instance."); } + +void MessagesView::setupAppearance() { + setAcceptDrops(false); + setDragEnabled(false); + setDragDropMode(QAbstractItemView::NoDragDrop); + setExpandsOnDoubleClick(false); + setRootIsDecorated(false); +} diff --git a/src/gui/messagesview.h b/src/gui/messagesview.h index a4b88639b..d4a1297b1 100644 --- a/src/gui/messagesview.h +++ b/src/gui/messagesview.h @@ -4,16 +4,21 @@ #include +class MessagesProxyModel; + class MessagesView : public QTreeView { Q_OBJECT public: + // Constructors and destructors. explicit MessagesView(QWidget *parent = 0); virtual ~MessagesView(); - - signals: - - public slots: + + protected: + void setupAppearance(); + + private: + MessagesProxyModel *m_proxyModel; };