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();
}
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) {
// TODO: pokračovat
return true;
@ -161,20 +144,84 @@ bool FeedsModel::removeItem(const QModelIndex &index) {
FeedsModelRootItem *deleting_item = itemForIndex(index);
FeedsModelRootItem *parent_item = itemForIndex(parent_index);
// Try to persistently remove the item.
if (deleting_item->removeItself()) {
// Item was persistently removed.
// Remove it from the model.
beginRemoveRows(parent_index, index.row(), index.row());
if (parent_item->removeChild(deleting_item)) {
// Free deleted item from the memory
// Free deleted item (and its children) from the memory.
delete deleting_item;
}
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;
}

View File

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

View File

@ -57,10 +57,6 @@ class FeedsModelRootItem {
virtual int countOfUnreadMessages() const;
virtual int countOfAllMessages() const;
virtual bool addItself() {
return false;
}
// This method is used to permanently
// "remove" (or "unregister") this item.
// This typically removes item and its
@ -90,21 +86,6 @@ class FeedsModelRootItem {
}
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.

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 result = true;

View File

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

View File

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

View File

@ -71,15 +71,12 @@ void FeedsView::clearSelectedFeeds() {
void FeedsView::addNewCategory() {
QPointer<FormCategoryDetails> form_pointer = new FormCategoryDetails(m_sourceModel, this);
FormCategoryDetailsAnswer answer = form_pointer.data()->exec(NULL);
if (answer.m_dialogCode == QDialog::Accepted) {
// User submitted some new category and
// it now resides in output_item pointer,
// parent_item contains parent_that user selected for
// new category.
// TODO: Add new category to the model and to the database.
if (form_pointer.data()->exec(NULL) == QDialog::Accepted) {
// TODO: nova kategorie pridana
}
else {
// TODO: nova kategorie nepridana
}
delete form_pointer.data();
@ -92,6 +89,27 @@ void FeedsView::editSelectedItem() {
if ((category = isCurrentIndexCategory()) != NULL) {
// 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) {
// Feed is selected.

View File

@ -13,6 +13,7 @@
#include <QTextEdit>
#include <QDialogButtonBox>
#include <QToolButton>
#include <QPushButton>
FormCategoryDetails::FormCategoryDetails(FeedsModel *model, QWidget *parent)
@ -40,46 +41,45 @@ void FormCategoryDetails::createConnections() {
this, SLOT(onTitleChanged(QString)));
}
void FormCategoryDetails::setEditableCategory(FeedsModelCategory *editable_category) {
void FormCategoryDetails::setEditableCategory(FeedsModelStandardCategory *editable_category) {
m_editableCategory = editable_category;
// TODO: Setup the dialog according to the category.
// so remove this category from category combobox!!
m_ui->m_cmbParentCategory->setCurrentIndex(m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) editable_category->parent())));
m_ui->m_txtTitle->lineEdit()->setText(editable_category->title());
m_ui->m_txtDescription->lineEdit()->setText(editable_category->description());
m_ui->m_btnIcon->setIcon(editable_category->icon());
}
FormCategoryDetailsAnswer FormCategoryDetails::exec(FeedsModelCategory *input_category) {
FormCategoryDetailsAnswer answer;
int FormCategoryDetails::exec(FeedsModelStandardCategory *input_category) {
if (input_category == NULL) {
// User is adding new category.
setWindowTitle(tr("Add new category"));
}
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.
setWindowTitle(tr("Edit existing category"));
setEditableCategory(input_category);
}
answer.m_dialogCode = QDialog::exec();
return answer;
return QDialog::exec();
}
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) {
// Add the category.
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());
if (m_feedsModel->addItem(new_category, parent)) {
if (m_feedsModel->addStandardCategory(new_category, parent)) {
accept();
}
else {
@ -87,15 +87,23 @@ void FormCategoryDetails::apply() {
}
}
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){
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."));
}
else {
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
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.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog);
setWindowIcon(IconThemeFactory::instance()->fromTheme("document-new"));
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
}
void FormCategoryDetails::loadCategories(const QList<FeedsModelCategory *> categories,

View File

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