Intensive work in category manipulations.

This commit is contained in:
Martin Rotter 2014-01-26 17:57:10 +01:00
parent a8e7d9d1c5
commit 659c4f313c
9 changed files with 146 additions and 123 deletions

View File

@ -133,23 +133,6 @@ int FeedsModel::rowCount(const QModelIndex &parent) const {
return parent_item->childCount(); return parent_item->childCount();
} }
bool FeedsModel::addItem(FeedsModelRootItem *item,
FeedsModelRootItem *parent) {
QModelIndex parent_index = indexForItem(parent);
beginInsertRows(parent_index, parent->childCount(), parent->childCount());
// Add item to hierarchy.
parent->appendChild(item);
// Add item to persistent storage.
item->addItself();
endInsertRows();
return true;
}
bool FeedsModel::editItem(const QModelIndex &index) { bool FeedsModel::editItem(const QModelIndex &index) {
// TODO: pokračovat // TODO: pokračovat
return true; return true;
@ -161,20 +144,84 @@ bool FeedsModel::removeItem(const QModelIndex &index) {
FeedsModelRootItem *deleting_item = itemForIndex(index); FeedsModelRootItem *deleting_item = itemForIndex(index);
FeedsModelRootItem *parent_item = itemForIndex(parent_index); FeedsModelRootItem *parent_item = itemForIndex(parent_index);
// Try to persistently remove the item.
if (deleting_item->removeItself()) { if (deleting_item->removeItself()) {
// Item was persistently removed.
// Remove it from the model.
beginRemoveRows(parent_index, index.row(), index.row()); beginRemoveRows(parent_index, index.row(), index.row());
if (parent_item->removeChild(deleting_item)) { if (parent_item->removeChild(deleting_item)) {
// Free deleted item from the memory // Free deleted item (and its children) from the memory.
delete deleting_item; delete deleting_item;
} }
endRemoveRows(); endRemoveRows();
}
return true; return true;
}
} }
// Item was not removed successfully.
return false;
}
bool FeedsModel::addStandardCategory(FeedsModelStandardCategory *category,
FeedsModelRootItem *parent) {
// Get index of parent item (parent standard category).
QModelIndex parent_index = indexForItem(parent);
// Now, add category to persistent storage.
// Children are removed, remove this standard category too.
QSqlDatabase database = DatabaseFactory::instance()->connection(objectName(),
DatabaseFactory::FromSettings);
QSqlQuery query_add(database);
query_add.setForwardOnly(true);
// Remove all messages from this standard feed.
query_add.prepare("INSERT INTO Categories "
"(parent_id, title, description, date_created, icon, type) "
"VALUES (:parent_id, :title, :description, :date_created, :icon, :type);");
query_add.bindValue(":parent_id", parent->id());
query_add.bindValue(":title", category->title());
query_add.bindValue(":description", category->description());
query_add.bindValue(":date_created", category->creationDate().toMSecsSinceEpoch());
query_add.bindValue(":icon", IconFactory::toByteArray(category->icon()));
query_add.bindValue(":type", (int) FeedsModelCategory::Standard);
if (!query_add.exec()) {
// Query failed.
return false;
}
query_add.prepare("SELECT id FROM Categories WHERE date_created = :date_created;");
query_add.bindValue(":date_created", category->creationDate().toMSecsSinceEpoch());
if (query_add.exec() && query_add.next()) {
// New category was added, fetch is primary id
// from the database.
category->setId(query_add.value(0).toInt());
}
else {
// Something failed.
return false;
}
// Category was added to the persistent storage,
// so add it to the model.
beginInsertRows(parent_index, parent->childCount(), parent->childCount());
// Add category to parent's children list.
parent->appendChild(category);
// Everything is completed now.
endInsertRows();
return true;
}
bool FeedsModel::editStandardCategory(FeedsModelStandardCategory *original_category,
FeedsModelStandardCategory *new_category) {
// TODO: implementovat
return false; return false;
} }

View File

@ -47,17 +47,22 @@ class FeedsModel : public QAbstractItemModel {
return m_rootItem->countOfUnreadMessages(); return m_rootItem->countOfUnreadMessages();
} }
// Feed/category manipulators. // Base manipulators.
bool addItem(FeedsModelRootItem *item,
FeedsModelRootItem *parent);
bool editItem(const QModelIndex &index); bool editItem(const QModelIndex &index);
bool removeItem(const QModelIndex &index); bool removeItem(const QModelIndex &index);
// TODO: addItself a removeItself z itemů // Standard category manipulators.
// asi přesunout do modelu a pro každej typ feedů/kanalu bool addStandardCategory(FeedsModelStandardCategory *category,
// napsat skupinu metod na přidavani/upravu/mazani FeedsModelRootItem *parent);
// Standard feed/category manipulators. bool editStandardCategory(FeedsModelStandardCategory *original_category,
//bool addStandardCategory(FeedsModelCategory *category); FeedsModelStandardCategory *new_category);
// Standard feed manipulators.
/*
bool addStandardFeed(FeedsModelStandardFeed *feed,
FeedsModelRootItem *parent);
bool removeStandardFeed(FeedsModelStandardFeed *feed);
*/
// Returns (undeleted) messages for given feeds. // Returns (undeleted) messages for given feeds.
QList<Message> messagesForFeeds(const QList<FeedsModelFeed*> &feeds); QList<Message> messagesForFeeds(const QList<FeedsModelFeed*> &feeds);

View File

@ -57,10 +57,6 @@ class FeedsModelRootItem {
virtual int countOfUnreadMessages() const; virtual int countOfUnreadMessages() const;
virtual int countOfAllMessages() const; virtual int countOfAllMessages() const;
virtual bool addItself() {
return false;
}
// This method is used to permanently // This method is used to permanently
// "remove" (or "unregister") this item. // "remove" (or "unregister") this item.
// This typically removes item and its // This typically removes item and its
@ -90,21 +86,6 @@ class FeedsModelRootItem {
} }
return false; return false;
/*
parents << root;
while (!parents.isEmpty()) {
foreach (FeedsModelRootItem *root_child, parents.takeFirst()->childItems()) {
if (root_child == this) {
return true;
}
else if (root_child->kind() == FeedsModelRootItem::Category) {
parents << root_child;
}
}
}
return false;*/
} }
// Removes all children from this item. // Removes all children from this item.

View File

@ -91,40 +91,6 @@ QVariant FeedsModelStandardCategory::data(int column, int role) const {
} }
} }
bool FeedsModelStandardCategory::addItself() {
// Children are removed, remove this standard category too.
QSqlDatabase database = DatabaseFactory::instance()->connection("FeedsModelStandardCategory",
DatabaseFactory::FromSettings);
QSqlQuery query_add(database);
query_add.setForwardOnly(true);
// Remove all messages from this standard feed.
query_add.prepare("INSERT INTO Categories "
"(parent_id, title, description, date_created, icon, type) "
"VALUES (:parent_id, :title, :description, :date_created, :icon, :type);");
query_add.bindValue(":parent_id", m_parentItem->id());
query_add.bindValue(":title", m_title);
query_add.bindValue(":description", m_description);
query_add.bindValue(":date_created", m_creationDate.toMSecsSinceEpoch());
query_add.bindValue(":icon", IconFactory::toByteArray(m_icon));
query_add.bindValue(":type", (int) m_type);
if (!query_add.exec()) {
return false;
}
query_add.prepare("SELECT id FROM Categories WHERE date_created = :date_created;");
query_add.bindValue(":date_created", m_creationDate.toMSecsSinceEpoch());
if (query_add.exec() && query_add.next()) {
setId(query_add.value(0).toInt());
return true;
}
else {
return false;
}
}
bool FeedsModelStandardCategory::removeItself() { bool FeedsModelStandardCategory::removeItself() {
bool result = true; bool result = true;

View File

@ -21,9 +21,6 @@ class FeedsModelStandardCategory : public FeedsModelCategory {
// Returns the actual data representation of standard category. // Returns the actual data representation of standard category.
QVariant data(int column, int role) const; QVariant data(int column, int role) const;
// Add itself to persistent database.
bool addItself();
// Removes category and all its children from persistent // Removes category and all its children from persistent
// database. // database.
bool removeItself(); bool removeItself();

View File

@ -86,8 +86,12 @@ QSettings::Status Settings::setupSettings() {
// a upravovat dané vlastnosti // a upravovat dané vlastnosti
// do FOrmSettings Webbrowser & proxy pridat tab "Advanced" a tam // do FOrmSettings Webbrowser & proxy pridat tab "Advanced" a tam
// naflakat vsecky zajimavy attributy // naflakat vsecky zajimavy attributy
QWebSettings::globalSettings()->setAttribute(QWebSettings::DnsPrefetchEnabled, false); QWebSettings::globalSettings()->setAttribute(QWebSettings::DnsPrefetchEnabled,
QWebSettings::globalSettings()->setAttribute(QWebSettings::AutoLoadImages, false); true);
QWebSettings::globalSettings()->setAttribute(QWebSettings::AutoLoadImages,
false);
QWebSettings::globalSettings()->setAttribute(QWebSettings::JavascriptEnabled,
false);
qDebug("Initializing settings in '%s' (non-portable way).", qDebug("Initializing settings in '%s' (non-portable way).",
qPrintable(QDir::toNativeSeparators(home_path_file))); qPrintable(QDir::toNativeSeparators(home_path_file)));

View File

@ -71,15 +71,12 @@ void FeedsView::clearSelectedFeeds() {
void FeedsView::addNewCategory() { void FeedsView::addNewCategory() {
QPointer<FormCategoryDetails> form_pointer = new FormCategoryDetails(m_sourceModel, this); QPointer<FormCategoryDetails> form_pointer = new FormCategoryDetails(m_sourceModel, this);
FormCategoryDetailsAnswer answer = form_pointer.data()->exec(NULL);
if (answer.m_dialogCode == QDialog::Accepted) { if (form_pointer.data()->exec(NULL) == QDialog::Accepted) {
// User submitted some new category and // TODO: nova kategorie pridana
// it now resides in output_item pointer, }
// parent_item contains parent_that user selected for else {
// new category. // TODO: nova kategorie nepridana
// TODO: Add new category to the model and to the database.
} }
delete form_pointer.data(); delete form_pointer.data();
@ -92,6 +89,27 @@ void FeedsView::editSelectedItem() {
if ((category = isCurrentIndexCategory()) != NULL) { if ((category = isCurrentIndexCategory()) != NULL) {
// Category is selected. // Category is selected.
switch (category->type()) {
case FeedsModelCategory::Standard: {
// User wants to edit standard category.
FeedsModelStandardCategory *std_category = static_cast<FeedsModelStandardCategory*>(category);
QPointer<FormCategoryDetails> form_pointer = new FormCategoryDetails(m_sourceModel, this);
if (form_pointer.data()->exec(std_category) == QDialog::Accepted) {
// TODO: kategorie upravena
}
else {
// TODO: kategorie neupravena
}
delete form_pointer.data();
break;
}
default:
break;
}
} }
else if ((feed = isCurrentIndexFeed()) != NULL) { else if ((feed = isCurrentIndexFeed()) != NULL) {
// Feed is selected. // Feed is selected.

View File

@ -13,6 +13,7 @@
#include <QTextEdit> #include <QTextEdit>
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QToolButton> #include <QToolButton>
#include <QPushButton>
FormCategoryDetails::FormCategoryDetails(FeedsModel *model, QWidget *parent) FormCategoryDetails::FormCategoryDetails(FeedsModel *model, QWidget *parent)
@ -40,46 +41,45 @@ void FormCategoryDetails::createConnections() {
this, SLOT(onTitleChanged(QString))); this, SLOT(onTitleChanged(QString)));
} }
void FormCategoryDetails::setEditableCategory(FeedsModelCategory *editable_category) { void FormCategoryDetails::setEditableCategory(FeedsModelStandardCategory *editable_category) {
m_editableCategory = editable_category; m_editableCategory = editable_category;
// TODO: Setup the dialog according to the category. m_ui->m_cmbParentCategory->setCurrentIndex(m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) editable_category->parent())));
// so remove this category from category combobox!!
m_ui->m_txtTitle->lineEdit()->setText(editable_category->title()); m_ui->m_txtTitle->lineEdit()->setText(editable_category->title());
m_ui->m_txtDescription->lineEdit()->setText(editable_category->description()); m_ui->m_txtDescription->lineEdit()->setText(editable_category->description());
m_ui->m_btnIcon->setIcon(editable_category->icon()); m_ui->m_btnIcon->setIcon(editable_category->icon());
} }
FormCategoryDetailsAnswer FormCategoryDetails::exec(FeedsModelCategory *input_category) { int FormCategoryDetails::exec(FeedsModelStandardCategory *input_category) {
FormCategoryDetailsAnswer answer;
if (input_category == NULL) { if (input_category == NULL) {
// User is adding new category. // User is adding new category.
setWindowTitle(tr("Add new category")); setWindowTitle(tr("Add new category"));
} }
else { else {
// This item cannot have set itself as the parent.
m_ui->m_cmbParentCategory->removeItem(m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) input_category)));
// User is editing existing category. // User is editing existing category.
setWindowTitle(tr("Edit existing category")); setWindowTitle(tr("Edit existing category"));
setEditableCategory(input_category); setEditableCategory(input_category);
} }
answer.m_dialogCode = QDialog::exec(); return QDialog::exec();
return answer;
} }
void FormCategoryDetails::apply() { void FormCategoryDetails::apply() {
FeedsModelRootItem *parent = static_cast<FeedsModelRootItem*>(m_ui->m_cmbParentCategory->itemData(m_ui->m_cmbParentCategory->currentIndex()).value<void*>());
FeedsModelStandardCategory *new_category = new FeedsModelStandardCategory();
new_category->setTitle(m_ui->m_txtTitle->lineEdit()->text());
new_category->setCreationDate(QDateTime::currentDateTime());
new_category->setDescription(m_ui->m_txtDescription->lineEdit()->text());
new_category->setIcon(m_ui->m_btnIcon->icon());
new_category->setParent(parent);
if (m_editableCategory == NULL) { if (m_editableCategory == NULL) {
// Add the category. // Add the category.
FeedsModelRootItem *parent = static_cast<FeedsModelRootItem*>(m_ui->m_cmbParentCategory->itemData(m_ui->m_cmbParentCategory->currentIndex()).value<void*>()); if (m_feedsModel->addStandardCategory(new_category, parent)) {
FeedsModelStandardCategory *new_category = new FeedsModelStandardCategory();
new_category->setTitle(m_ui->m_txtTitle->lineEdit()->text());
new_category->setCreationDate(QDateTime::currentDateTime());
new_category->setDescription(m_ui->m_txtDescription->lineEdit()->text());
new_category->setIcon(m_ui->m_btnIcon->icon());
if (m_feedsModel->addItem(new_category, parent)) {
accept(); accept();
} }
else { else {
@ -87,15 +87,23 @@ void FormCategoryDetails::apply() {
} }
} }
else { else {
// edit category // TODO: edit category
if (m_feedsModel->editStandardCategory(m_editableCategory, new_category)) {
accept();
}
else {
// TODO: hlasit chybu
}
} }
} }
void FormCategoryDetails::onTitleChanged(const QString &new_title){ void FormCategoryDetails::onTitleChanged(const QString &new_title){
if (new_title.size() >= MIN_CATEGORY_NAME_LENGTH) { if (new_title.size() >= MIN_CATEGORY_NAME_LENGTH) {
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
m_ui->m_txtTitle->setStatus(LineEditWithStatus::Ok, tr("This category name is ok.")); m_ui->m_txtTitle->setStatus(LineEditWithStatus::Ok, tr("This category name is ok."));
} }
else { else {
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
m_ui->m_txtTitle->setStatus(LineEditWithStatus::Error, tr("This category name is too short.")); m_ui->m_txtTitle->setStatus(LineEditWithStatus::Error, tr("This category name is too short."));
} }
} }
@ -107,6 +115,8 @@ void FormCategoryDetails::initialize() {
// Set flags and attributes. // Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog); setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog);
setWindowIcon(IconThemeFactory::instance()->fromTheme("document-new")); setWindowIcon(IconThemeFactory::instance()->fromTheme("document-new"));
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
} }
void FormCategoryDetails::loadCategories(const QList<FeedsModelCategory *> categories, void FormCategoryDetails::loadCategories(const QList<FeedsModelCategory *> categories,

View File

@ -11,15 +11,10 @@ namespace Ui {
} }
class FeedsModelCategory; class FeedsModelCategory;
class FeedsModelStandardCategory;
class FeedsModel; class FeedsModel;
class FeedsModelRootItem; class FeedsModelRootItem;
class FormCategoryDetailsAnswer {
public:
int m_dialogCode;
FeedsModelCategory *m_outputCategory;
FeedsModelRootItem *m_outputParentItem;
};
class FormCategoryDetails : public QDialog { class FormCategoryDetails : public QDialog {
Q_OBJECT Q_OBJECT
@ -44,7 +39,7 @@ class FormCategoryDetails : public QDialog {
// to the database. // to the database.
// NOTE: Newly EDITED category IS COPY of its original. // NOTE: Newly EDITED category IS COPY of its original.
// SO NO ORIGINAL MODEL DATA ARE EDITED OR CHANGED. // SO NO ORIGINAL MODEL DATA ARE EDITED OR CHANGED.
FormCategoryDetailsAnswer exec(FeedsModelCategory *input_category); int exec(FeedsModelStandardCategory *input_category);
protected slots: protected slots:
void apply(); void apply();
@ -55,7 +50,7 @@ class FormCategoryDetails : public QDialog {
protected: protected:
// Sets the category which will be edited. // Sets the category which will be edited.
// NOTE: This is used for editing categories. // NOTE: This is used for editing categories.
void setEditableCategory(FeedsModelCategory *editable_category); void setEditableCategory(FeedsModelStandardCategory *editable_category);
// Initializes the dialog. // Initializes the dialog.
void initialize(); void initialize();
@ -66,7 +61,7 @@ class FormCategoryDetails : public QDialog {
private: private:
Ui::FormCategoryDetails *m_ui; Ui::FormCategoryDetails *m_ui;
FeedsModelCategory *m_editableCategory; FeedsModelStandardCategory *m_editableCategory;
FeedsModel *m_feedsModel; FeedsModel *m_feedsModel;
}; };