Commit 0a95bc2a authored by Camilo higuita's avatar Camilo higuita

use custom models to better performance and manipulation

parent 93f62e28
...@@ -46,8 +46,10 @@ SOURCES += \ ...@@ -46,8 +46,10 @@ SOURCES += \
src/documenthandler.cpp \ src/documenthandler.cpp \
src/linker.cpp \ src/linker.cpp \
src/utils/htmlparser.cpp \ src/utils/htmlparser.cpp \
src/models/notesmodel.cpp \ src/models/notes/notesmodel.cpp \
src/models/notes.cpp src/models/notes/notes.cpp \
src/models/links/linksmodel.cpp \
src/models/links/links.cpp
RESOURCES += \ RESOURCES += \
qml.qrc \ qml.qrc \
...@@ -77,8 +79,10 @@ HEADERS += \ ...@@ -77,8 +79,10 @@ HEADERS += \
src/documenthandler.h \ src/documenthandler.h \
src/linker.h \ src/linker.h \
src/utils/htmlparser.h \ src/utils/htmlparser.h \
src/models/notesmodel.h \ src/models/notes/notesmodel.h \
src/models/notes.h src/models/notes/notes.h \
src/models/links/linksmodel.h \
src/models/links/links.h
INCLUDEPATH += \ INCLUDEPATH += \
src/utils/ \ src/utils/ \
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include "src/documenthandler.h" #include "src/documenthandler.h"
#include "src/linker.h" #include "src/linker.h"
#include "models/notesmodel.h" #include "models/notes/notesmodel.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
...@@ -63,6 +63,8 @@ int main(int argc, char *argv[]) ...@@ -63,6 +63,8 @@ int main(int argc, char *argv[])
context->setContextProperty("linker", &linker); context->setContextProperty("linker", &linker);
context->setContextProperty("tag", tag); context->setContextProperty("tag", tag);
qmlRegisterType<DocumentHandler>("org.buho.editor", 1, 0, "DocumentHandler"); qmlRegisterType<DocumentHandler>("org.buho.editor", 1, 0, "DocumentHandler");
qmlRegisterUncreatableMetaObject(OWL::staticMetaObject, "Owl", 1, 0, "KEY", "Error");
qmlRegisterType<NotesModel>("Notes", 1, 0, "NotesModel"); qmlRegisterType<NotesModel>("Notes", 1, 0, "NotesModel");
engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty()) if (engine.rootObjects().isEmpty())
......
...@@ -117,23 +117,19 @@ Maui.ApplicationWindow ...@@ -117,23 +117,19 @@ Maui.ApplicationWindow
Connections Connections
{ {
target: owl target: owl
onNoteInserted: notesView.append(note)
onLinkInserted: linksView.append(link) onLinkInserted: linksView.append(link)
} }
NewNoteDialog NewNoteDialog
{ {
id: newNoteDialog id: newNoteDialog
onNoteSaved: owl.insertNote(note) onNoteSaved: notesView.model.insert(note)
} }
NewNoteDialog NewNoteDialog
{ {
id: editNote id: editNote
onNoteSaved: onNoteSaved: notesView.cardsView.currentItem.update(note)
{
notesView.cardsView.currentItem.update(note)
}
} }
NewLinkDialog NewLinkDialog
......
...@@ -25,6 +25,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -25,6 +25,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QSqlQuery> #include <QSqlQuery>
DB::DB(QObject *parent) : QObject(parent) DB::DB(QObject *parent) : QObject(parent)
{
init();
}
DB::~DB()
{
this->m_db.close();
}
void DB::init()
{ {
QDir collectionDBPath_dir(OWL::CollectionDBPath); QDir collectionDBPath_dir(OWL::CollectionDBPath);
if (!collectionDBPath_dir.exists()) if (!collectionDBPath_dir.exists())
...@@ -39,9 +49,20 @@ DB::DB(QObject *parent) : QObject(parent) ...@@ -39,9 +49,20 @@ DB::DB(QObject *parent) : QObject(parent)
}else this->openDB(this->name); }else this->openDB(this->name);
} }
DB::~DB() DB *DB::instance = nullptr;
DB *DB::getInstance()
{ {
this->m_db.close(); if(!instance)
{
instance = new DB();
qDebug() << "getInstance(): First DB instance\n";
instance->init();
return instance;
} else
{
qDebug()<< "getInstance(): previous DB instance\n";
return instance;
}
} }
void DB::openDB(const QString &name) void DB::openDB(const QString &name)
......
...@@ -41,23 +41,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -41,23 +41,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
class DB : public QObject class DB : public QObject
{ {
Q_OBJECT Q_OBJECT
private: private:
QString name;
QSqlDatabase m_db;
public:
explicit DB(QObject *parent = nullptr); explicit DB(QObject *parent = nullptr);
~ DB(); ~DB();
void openDB(const QString &name); static DB* instance;
QString name;
/*basic public actions*/ QSqlDatabase m_db;
void prepareCollectionDB() const;
public:
static DB *getInstance();
/* utils*/ /* utils*/
Q_INVOKABLE bool checkExistance(const QString &tableName, const QString &searchId, const QString &search); bool checkExistance(const QString &tableName, const QString &searchId, const QString &search);
OWL::DB_LIST getDBData(const QString &queryTxt); OWL::DB_LIST getDBData(const QString &queryTxt);
protected:
QSqlQuery getQuery(const QString &queryTxt); QSqlQuery getQuery(const QString &queryTxt);
bool insert(const QString &tableName, const QVariantMap &insertData); bool insert(const QString &tableName, const QVariantMap &insertData);
...@@ -65,6 +62,11 @@ protected: ...@@ -65,6 +62,11 @@ protected:
bool update(const QString &table, const QString &column, const QVariant &newValue, const QVariant &op, const QString &id); bool update(const QString &table, const QString &column, const QVariant &newValue, const QVariant &op, const QString &id);
bool remove(const QString &tableName, const QVariantMap &removeData); bool remove(const QString &tableName, const QVariantMap &removeData);
protected:
void init();
void openDB(const QString &name);
void prepareCollectionDB() const;
signals: signals:
public slots: public slots:
......
...@@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QUuid> #include <QUuid>
#include <QDateTime> #include <QDateTime>
#include "linker.h" #include "linker.h"
#include "db.h"
#ifdef STATIC_MAUIKIT #ifdef STATIC_MAUIKIT
#include "tagging.h" #include "tagging.h"
...@@ -31,11 +32,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -31,11 +32,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <MauiKit/tagging.h> #include <MauiKit/tagging.h>
#endif #endif
DBActions::DBActions(QObject *parent) : DB(parent) DBActions::DBActions(QObject *parent) : QObject(parent)
{ {
qDebug() << "Getting collectionDB info from: " << OWL::CollectionDBPath; qDebug() << "Getting collectionDB info from: " << OWL::CollectionDBPath;
qDebug()<< "Starting DBActions"; qDebug()<< "Starting DBActions";
this->db = DB::getInstance();
this->tag = Tagging::getInstance(OWL::App, OWL::version, "org.kde.buho", OWL::comment); this->tag = Tagging::getInstance(OWL::App, OWL::version, "org.kde.buho", OWL::comment);
} }
...@@ -46,7 +48,7 @@ QVariantList DBActions::get(const QString &queryTxt) ...@@ -46,7 +48,7 @@ QVariantList DBActions::get(const QString &queryTxt)
{ {
QVariantList mapList; QVariantList mapList;
auto query = this->getQuery(queryTxt); auto query = this->db->getQuery(queryTxt);
if(query.exec()) if(query.exec())
{ {
...@@ -92,7 +94,7 @@ bool DBActions::insertLink(const QVariantMap &link) ...@@ -92,7 +94,7 @@ bool DBActions::insertLink(const QVariantMap &link)
}; };
if(this->insert(OWL::TABLEMAP[OWL::TABLE::LINKS], link_map)) if(this->db->insert(OWL::TABLEMAP[OWL::TABLE::LINKS], link_map))
{ {
for(auto tg : tags) for(auto tg : tags)
this->tag->tagAbstract(tg, OWL::TABLEMAP[OWL::TABLE::LINKS], url, color); this->tag->tagAbstract(tg, OWL::TABLEMAP[OWL::TABLE::LINKS], url, color);
...@@ -124,13 +126,13 @@ bool DBActions::updateLink(const QVariantMap &link) ...@@ -124,13 +126,13 @@ bool DBActions::updateLink(const QVariantMap &link)
for(auto tg : tags) for(auto tg : tags)
this->tag->tagAbstract(tg, OWL::TABLEMAP[OWL::TABLE::LINKS], url, color); this->tag->tagAbstract(tg, OWL::TABLEMAP[OWL::TABLE::LINKS], url, color);
return this->update(OWL::TABLEMAP[OWL::TABLE::LINKS], link_map, {{OWL::KEYMAP[OWL::KEY::LINK], url}} ); return this->db->update(OWL::TABLEMAP[OWL::TABLE::LINKS], link_map, {{OWL::KEYMAP[OWL::KEY::LINK], url}} );
} }
bool DBActions::removeLink(const QVariantMap &link) bool DBActions::removeLink(const QVariantMap &link)
{ {
return this->remove(OWL::TABLEMAP[OWL::TABLE::LINKS], link); return this->db->remove(OWL::TABLEMAP[OWL::TABLE::LINKS], link);
} }
QVariantList DBActions::getLinks() QVariantList DBActions::getLinks()
...@@ -145,7 +147,7 @@ QVariantList DBActions::getLinkTags(const QString &link) ...@@ -145,7 +147,7 @@ QVariantList DBActions::getLinkTags(const QString &link)
bool DBActions::execQuery(const QString &queryTxt) bool DBActions::execQuery(const QString &queryTxt)
{ {
auto query = this->getQuery(queryTxt); auto query = this->db->getQuery(queryTxt);
return query.exec(); return query.exec();
} }
......
...@@ -22,10 +22,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -22,10 +22,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define DBACTIONS_H #define DBACTIONS_H
#include <QObject> #include <QObject>
#include "db.h" #include "owl.h"
class DB;
class Tagging; class Tagging;
class DBActions : public DB class DBActions : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
...@@ -45,7 +46,7 @@ protected: ...@@ -45,7 +46,7 @@ protected:
OWL::DB_LIST getDBData(const QString &queryTxt); OWL::DB_LIST getDBData(const QString &queryTxt);
bool execQuery(const QString &queryTxt); bool execQuery(const QString &queryTxt);
Tagging *tag; Tagging *tag;
DB *db;
void removeAbtractTags(const QString &key, const QString &lot); void removeAbtractTags(const QString &key, const QString &lot);
signals: signals:
......
#include "links.h"
#include <QUuid>
#include "db/db.h"
#ifdef STATIC_MAUIKIT
#include "tagging.h"
#else
#include <MauiKit/tagging.h>
#endif
Links::Links(QObject *parent) : QObject(parent)
{
this->db = DB::getInstance();
this->sortBy(OWL::KEY::UPDATED, "DESC");
}
void Links::sortBy(const OWL::KEY &key, const QString &order)
{
this->notes = this->db->getDBData(QString("select * from notes ORDER BY %1 %2").arg(OWL::KEYMAP[key], order));
}
OWL::DB_LIST Links::items() const
{
return this->notes;
}
bool Links::insertNote(const QVariantMap &note)
{
qDebug()<<"TAGS"<< note[OWL::KEYMAP[OWL::KEY::TAG]].toStringList();
auto title = note[OWL::KEYMAP[OWL::KEY::TITLE]].toString();
auto body = note[OWL::KEYMAP[OWL::KEY::BODY]].toString();
auto color = note[OWL::KEYMAP[OWL::KEY::COLOR]].toString();
auto pin = note[OWL::KEYMAP[OWL::KEY::PIN]].toInt();
auto fav = note[OWL::KEYMAP[OWL::KEY::FAV]].toInt();
auto tags = note[OWL::KEYMAP[OWL::KEY::TAG]].toStringList();
auto id = QUuid::createUuid().toString();
QVariantMap note_map =
{
{OWL::KEYMAP[OWL::KEY::ID], id},
{OWL::KEYMAP[OWL::KEY::TITLE], title},
{OWL::KEYMAP[OWL::KEY::BODY], body},
{OWL::KEYMAP[OWL::KEY::COLOR], color},
{OWL::KEYMAP[OWL::KEY::PIN], pin},
{OWL::KEYMAP[OWL::KEY::FAV], fav},
{OWL::KEYMAP[OWL::KEY::UPDATED], QDateTime::currentDateTime().toString()},
{OWL::KEYMAP[OWL::KEY::ADD_DATE], QDateTime::currentDateTime().toString()}
};
if(this->db->insert(OWL::TABLEMAP[OWL::TABLE::NOTES], note_map))
{
for(auto tg : tags)
this->tag->tagAbstract(tg, OWL::TABLEMAP[OWL::TABLE::NOTES], id, color);
this->notes << OWL::DB
({
{OWL::KEY::ID, id},
{OWL::KEY::TITLE, title},
{OWL::KEY::BODY, body},
{OWL::KEY::COLOR, color},
{OWL::KEY::PIN, QString::number(pin)},
{OWL::KEY::FAV, QString::number(fav)},
{OWL::KEY::UPDATED, QDateTime::currentDateTime().toString()},
{OWL::KEY::ADD_DATE, QDateTime::currentDateTime().toString()}
});
return true;
}
return false;
}
bool Links::updateNote(const int &index, const QVariant &value, const int &role)
{
if(index < 0 || index >= notes.size())
return false;
const auto oldValue = this->notes[index][static_cast<OWL::KEY>(role)];
if(oldValue == value.toString())
return false;
this->notes[index].insert(static_cast<OWL::KEY>(role), value.toString());
this->updateNote(this->notes[index]);
return true;
}
bool Links::updateNote(const OWL::DB &note)
{
auto id = note[OWL::KEY::ID];
auto title = note[OWL::KEY::TITLE];
auto body = note[OWL::KEY::BODY];
auto color = note[OWL::KEY::COLOR];
auto pin = note[OWL::KEY::PIN].toInt();
auto fav = note[OWL::KEY::FAV].toInt();
auto tags = note[OWL::KEY::TAG].split(",", QString::SkipEmptyParts);
auto updated =note[OWL::KEY::UPDATED];
QVariantMap note_map =
{
{OWL::KEYMAP[OWL::KEY::TITLE], title},
{OWL::KEYMAP[OWL::KEY::BODY], body},
{OWL::KEYMAP[OWL::KEY::COLOR], color},
{OWL::KEYMAP[OWL::KEY::PIN], pin},
{OWL::KEYMAP[OWL::KEY::FAV], fav},
{OWL::KEYMAP[OWL::KEY::UPDATED], updated}
};
for(auto tg : tags)
this->tag->tagAbstract(tg, OWL::TABLEMAP[OWL::TABLE::NOTES], id, color);
return this->db->update(OWL::TABLEMAP[OWL::TABLE::NOTES], note_map, {{OWL::KEYMAP[OWL::KEY::ID], id}} );
}
bool Links::removeNote(const QVariantMap &note)
{
qDebug()<<note;
return this->db->remove(OWL::TABLEMAP[OWL::TABLE::NOTES], note);
}
QVariantList Links::getNoteTags(const QString &id)
{
return this->tag->getAbstractTags(OWL::TABLEMAP[OWL::TABLE::NOTES], id);
}
#ifndef NOTES_H
#define NOTES_H
#include <QObject>
#include "owl.h"
class DB;
class Tagging;
class Links : public QObject
{
Q_OBJECT
public:
explicit Links(QObject *parent = nullptr);
OWL::DB_LIST items() const;
void sortBy(const OWL::KEY &key, const QString &order = "DESC");
bool insertNote(const QVariantMap &note);
bool updateNote(const int &index, const QVariant &value, const int &role);
bool updateNote(const OWL::DB &note);
bool removeNote(const QVariantMap &note);
QVariantList getNoteTags(const QString &id);
private:
Tagging *tag;
DB *db;
OWL::DB_LIST notes;
signals:
public slots:
};
#endif // NOTES_H
#include "linksmodel.h"
#include "links.h"
LinksModel::LinksModel(QObject *parent)
: QAbstractListModel(parent)
{
this->mNotes = new Links(this);
}
int LinksModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid() || !mNotes)
return 0;
return mNotes->items().size();
}
QVariant LinksModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || !mNotes)
return QVariant();
return mNotes->items().at(index.row())[static_cast<OWL::KEY>(role)];
}
QVariantMap LinksModel::get(const int &index)
{
QVariantMap res;
const auto note = mNotes->items().at(index);
for(auto key : note.keys())
res.insert(OWL::KEYMAP[key], note[key]);
return res;
}
void LinksModel::sortBy(const int &index, const QString &order)
{
beginResetModel();
mNotes->sortBy(static_cast<OWL::KEY>(index), order);
endResetModel();
}
bool LinksModel::insert(const QVariantMap &note)
{
const int index = mNotes->items().size();
beginInsertRows(QModelIndex(), index, index);
this->mNotes->insertNote(note);
endInsertRows();
return false;
}
bool LinksModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!mNotes)
return false;
if (mNotes->updateNote(index.row(), value, role))
{
emit dataChanged(index, index, QVector<int>() << role);
return true;
}
return false;
}
Qt::ItemFlags LinksModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::NoItemFlags;
return Qt::ItemIsEditable; // FIXME: Implement me!
}
QHash<int, QByteArray> LinksModel::roleNames() const
{
QHash<int, QByteArray> names;
names[OWL::KEY::TITLE] = QString(OWL::KEYMAP[OWL::KEY::TITLE]).toUtf8();
names[OWL::KEY::BODY] = QString(OWL::KEYMAP[OWL::KEY::BODY]).toUtf8();
names[OWL::KEY::UPDATED] = QString(OWL::KEYMAP[OWL::KEY::UPDATED]).toUtf8();
names[OWL::KEY::FAV] = QString(OWL::KEYMAP[OWL::KEY::FAV]).toUtf8();
names[OWL::KEY::PIN] = QString(OWL::KEYMAP[OWL::KEY::PIN]).toUtf8();
names[OWL::KEY::COLOR] = QString(OWL::KEYMAP[OWL::KEY::COLOR]).toUtf8();
names[OWL::KEY::ID] = QString(OWL::KEYMAP[OWL::KEY::ID]).toUtf8();
names[OWL::KEY::IMAGE] = QString(OWL::KEYMAP[OWL::KEY::IMAGE]).toUtf8();
names[OWL::KEY::LINK] = QString(OWL::KEYMAP[OWL::KEY::LINK]).toUtf8();
names[OWL::KEY::PREVIEW] = QString(OWL::KEYMAP[OWL::KEY::PREVIEW]).toUtf8();
names[OWL::KEY::TAG] = QString(OWL::KEYMAP[OWL::KEY::TAG]).toUtf8();
names[OWL::KEY::URL] = QString(OWL::KEYMAP[OWL::KEY::URL]).toUtf8();
names[OWL::KEY::ADD_DATE] = QString(OWL::KEYMAP[OWL::KEY::ADD_DATE]).toUtf8();
names[OWL::KEY::URL] = QString(OWL::KEYMAP[OWL::KEY::ADD_DATE]).toUtf8();
return names;
}
//Notes *NotesModel::notes() const
//{
// return mNotes;
//}
//void NotesModel::setNotes(Notes *value)
//{
// beginResetModel();
// if(mNotes)
// mNotes->disconnect(this);
// mNotes = value;
//// if(mNotes)
//// {
//// connect(mNotes, &Notes::preItemAppended, this, [=]()
//// {
//// const int index = mNotes->items().size();
//// beginInsertRows(QModelIndex(), index, index);
//// });
//// connect(mNotes, &Notes::postItemAppended, this, [=]()
//// {
//// endInsertRows();
//// });
//// connect(mNotes, &Notes::preItemRemoved, this, [=](int index)
//// {
//// beginInsertRows(QModelIndex(), index, index);
//// });
//// connect(mNotes, &Notes::preItemRemoved, this, [=]()
//// {
//// endRemoveRows();
//// });
//// }
// endResetModel();
//}
#ifndef NOTESMODEL_H
#define NOTESMODEL_H
#include <QAbstractListModel>
#include <QList>
#include "owl.h"
class Links;
class LinksModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit LinksModel(QObject *parent = nullptr);
enum
{
title,
body
};
// Basic functionality:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Q_INVOKABLE QVariantMap get(const int &index);
Q_INVOKABLE void sortBy(const int &index, const QString &order);
Q_INVOKABLE bool insert(const QVariantMap &note);
// Editable:
bool setData(const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole) override;
Qt::ItemFlags flags(const QModelIndex& index) const override;
virtual QHash<int, QByteArray> roleNames() const override;
friend bool operator<(const OWL::DB & m1, const OWL::DB & m2)
{
return m1[OWL::KEY::TITLE] < m2[OWL::KEY::TITLE];
}
private:
Links *mNotes;
};
#endif // NOTESMODEL_H
#include "notes.h" #include "notes.h"
#include <QUuid> #include <QUuid>
#include "db/db.h"
#ifdef STATIC_MAUIKIT #ifdef STATIC_MAUIKIT
#include "tagging.h" #include "tagging.h"
#else #else
#include <MauiKit/tagging.h> #include <MauiKit/tagging.h>
#endif #endif
Notes::Notes(QObject *parent) : DB(parent) Notes::Notes(QObject *parent) : QObject(parent)
{ {
this->notes = this->getNotes(); this->db = DB::getInstance();
this->sortBy(OWL::KEY::UPDATED, "DESC");
} }
OWL::DB_LIST Notes::items() const void Notes::sortBy(const OWL::KEY &key, const QString &order)
{ {
return this->notes; this->notes = this->db->getDBData(QString("select * from notes ORDER BY %1 %2").arg(OWL::KEYMAP[key], order));
}
void Notes::appendItem()
{
emit preItemAppended();
emit postItemAppended();
}