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 += \
src/documenthandler.cpp \
src/linker.cpp \
src/utils/htmlparser.cpp \
src/models/notesmodel.cpp \
src/models/notes.cpp
src/models/notes/notesmodel.cpp \
src/models/notes/notes.cpp \
src/models/links/linksmodel.cpp \
src/models/links/links.cpp
RESOURCES += \
qml.qrc \
......@@ -77,8 +79,10 @@ HEADERS += \
src/documenthandler.h \
src/linker.h \
src/utils/htmlparser.h \
src/models/notesmodel.h \
src/models/notes.h
src/models/notes/notesmodel.h \
src/models/notes/notes.h \
src/models/links/linksmodel.h \
src/models/links/links.h
INCLUDEPATH += \
src/utils/ \
......
......@@ -24,7 +24,7 @@
#include "src/documenthandler.h"
#include "src/linker.h"
#include "models/notesmodel.h"
#include "models/notes/notesmodel.h"
int main(int argc, char *argv[])
{
......@@ -63,6 +63,8 @@ int main(int argc, char *argv[])
context->setContextProperty("linker", &linker);
context->setContextProperty("tag", tag);
qmlRegisterType<DocumentHandler>("org.buho.editor", 1, 0, "DocumentHandler");
qmlRegisterUncreatableMetaObject(OWL::staticMetaObject, "Owl", 1, 0, "KEY", "Error");
qmlRegisterType<NotesModel>("Notes", 1, 0, "NotesModel");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
......
......@@ -117,23 +117,19 @@ Maui.ApplicationWindow
Connections
{
target: owl
onNoteInserted: notesView.append(note)
onLinkInserted: linksView.append(link)
}
NewNoteDialog
{
id: newNoteDialog
onNoteSaved: owl.insertNote(note)
onNoteSaved: notesView.model.insert(note)
}
NewNoteDialog
{
id: editNote
onNoteSaved:
{
notesView.cardsView.currentItem.update(note)
}
onNoteSaved: notesView.cardsView.currentItem.update(note)
}
NewLinkDialog
......
......@@ -25,6 +25,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QSqlQuery>
DB::DB(QObject *parent) : QObject(parent)
{
init();
}
DB::~DB()
{
this->m_db.close();
}
void DB::init()
{
QDir collectionDBPath_dir(OWL::CollectionDBPath);
if (!collectionDBPath_dir.exists())
......@@ -39,9 +49,20 @@ DB::DB(QObject *parent) : QObject(parent)
}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)
......
......@@ -41,23 +41,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
class DB : public QObject
{
Q_OBJECT
private:
QString name;
QSqlDatabase m_db;
public:
explicit DB(QObject *parent = nullptr);
~ DB();
~DB();
void openDB(const QString &name);
/*basic public actions*/
void prepareCollectionDB() const;
static DB* instance;
QString name;
QSqlDatabase m_db;
public:
static DB *getInstance();
/* 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);
protected:
QSqlQuery getQuery(const QString &queryTxt);
bool insert(const QString &tableName, const QVariantMap &insertData);
......@@ -65,6 +62,11 @@ protected:
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);
protected:
void init();
void openDB(const QString &name);
void prepareCollectionDB() const;
signals:
public slots:
......
......@@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QUuid>
#include <QDateTime>
#include "linker.h"
#include "db.h"
#ifdef STATIC_MAUIKIT
#include "tagging.h"
......@@ -31,11 +32,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <MauiKit/tagging.h>
#endif
DBActions::DBActions(QObject *parent) : DB(parent)
DBActions::DBActions(QObject *parent) : QObject(parent)
{
qDebug() << "Getting collectionDB info from: " << OWL::CollectionDBPath;
qDebug()<< "Starting DBActions";
this->db = DB::getInstance();
this->tag = Tagging::getInstance(OWL::App, OWL::version, "org.kde.buho", OWL::comment);
}
......@@ -46,7 +48,7 @@ QVariantList DBActions::get(const QString &queryTxt)
{
QVariantList mapList;
auto query = this->getQuery(queryTxt);
auto query = this->db->getQuery(queryTxt);
if(query.exec())
{
......@@ -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)
this->tag->tagAbstract(tg, OWL::TABLEMAP[OWL::TABLE::LINKS], url, color);
......@@ -124,13 +126,13 @@ bool DBActions::updateLink(const QVariantMap &link)
for(auto tg : tags)
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)
{
return this->remove(OWL::TABLEMAP[OWL::TABLE::LINKS], link);
return this->db->remove(OWL::TABLEMAP[OWL::TABLE::LINKS], link);
}
QVariantList DBActions::getLinks()
......@@ -145,7 +147,7 @@ QVariantList DBActions::getLinkTags(const QString &link)
bool DBActions::execQuery(const QString &queryTxt)
{
auto query = this->getQuery(queryTxt);
auto query = this->db->getQuery(queryTxt);
return query.exec();
}
......
......@@ -22,10 +22,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define DBACTIONS_H
#include <QObject>
#include "db.h"
#include "owl.h"
class DB;
class Tagging;
class DBActions : public DB
class DBActions : public QObject
{
Q_OBJECT
public:
......@@ -45,7 +46,7 @@ protected:
OWL::DB_LIST getDBData(const QString &queryTxt);
bool execQuery(const QString &queryTxt);
Tagging *tag;
DB *db;
void removeAbtractTags(const QString &key, const QString &lot);
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 <QUuid>
#include "db/db.h"
#ifdef STATIC_MAUIKIT
#include "tagging.h"
#else
#include <MauiKit/tagging.h>
#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;
}
void Notes::appendItem()
{
emit preItemAppended();
emit postItemAppended();
this->notes = this->db->getDBData(QString("select * from notes ORDER BY %1 %2").arg(OWL::KEYMAP[key], order));
}
void Notes::removeItem()
OWL::DB_LIST Notes::items() const
{
emit preItemRemoved(0);
emit postItemRemoved();
return this->notes;
}
bool Notes::insertNote(const QVariantMap &note)
......@@ -56,12 +50,23 @@ bool Notes::insertNote(const QVariantMap &note)
{OWL::KEYMAP[OWL::KEY::ADD_DATE], QDateTime::currentDateTime().toString()}
};
if(this->insert(OWL::TABLEMAP[OWL::TABLE::NOTES], note_map))
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->noteInserted(note_map);
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;
}
......@@ -72,15 +77,15 @@ bool Notes::updateNote(const int &index, const QVariant &value, const int &role)
{
if(index < 0 || index >= notes.size())
return false;
const auto oldNote = this->notes[index][static_cast<OWL::KEY>(role)];
if(oldNote == value.toString())
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());
const auto newNote = this->notes[index];
this->updateNote(newNote);
this->updateNote(this->notes[index]);
return true;
}
......@@ -110,18 +115,13 @@ bool Notes::updateNote(const OWL::DB &note)
for(auto tg : tags)
this->tag->tagAbstract(tg, OWL::TABLEMAP[OWL::TABLE::NOTES], id, color);
return this->update(OWL::TABLEMAP[OWL::TABLE::NOTES], note_map, {{OWL::KEYMAP[OWL::KEY::ID], id}} );
return this->db->update(OWL::TABLEMAP[OWL::TABLE::NOTES], note_map, {{OWL::KEYMAP[OWL::KEY::ID], id}} );
}
bool Notes::removeNote(const QVariantMap &note)
{
qDebug()<<note;
return this->remove(OWL::TABLEMAP[OWL::TABLE::NOTES], note);
}
OWL::DB_LIST Notes::getNotes()
{
return this->getDBData("select * from notes ORDER BY updated ASC");
return this->db->remove(OWL::TABLEMAP[OWL::TABLE::NOTES], note);
}
QVariantList Notes::getNoteTags(const QString &id)
......
......@@ -2,40 +2,40 @@
#define NOTES_H
#include <QObject>
#include "db/db.h"
#include "owl.h"
class DB;
class Tagging;
class Notes : public DB
class Notes : public QObject
{
Q_OBJECT
public:
explicit Notes(QObject *parent = nullptr);
OWL::DB_LIST items() const;
void sortBy(const OWL::KEY &key, const QString &order = "DESC");