aboutsummaryrefslogtreecommitdiff
path: root/lib/bookmarks/bookmarkmodel.cpp
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2018-09-25 14:44:01 +0200
committerAqua-sama <aqua@iserlohn-fortress.net>2018-09-25 14:44:01 +0200
commit9203de811f049c8e604a9c3065781157fa506155 (patch)
tree96096d8cbeefd58c988ddb97dcd51fa21873ffb6 /lib/bookmarks/bookmarkmodel.cpp
parentBookmarks: add BookmarkItem and BookmarkModel (diff)
downloadsmolbote-9203de811f049c8e604a9c3065781157fa506155.tar.xz
Bookmarks: integrate model/view
- fix addBookmark and search signals - fix drag'n'drop - add xbel::write
Diffstat (limited to 'lib/bookmarks/bookmarkmodel.cpp')
-rw-r--r--lib/bookmarks/bookmarkmodel.cpp165
1 files changed, 123 insertions, 42 deletions
diff --git a/lib/bookmarks/bookmarkmodel.cpp b/lib/bookmarks/bookmarkmodel.cpp
index 3b57fea..b55dcdd 100644
--- a/lib/bookmarks/bookmarkmodel.cpp
+++ b/lib/bookmarks/bookmarkmodel.cpp
@@ -8,6 +8,9 @@
#include "bookmarkmodel.h"
#include "bookmarkitem.h"
+#include "xbel.h"
+#include <QBuffer>
+#include <QMimeData>
BookmarkModel::BookmarkModel(QObject *parent)
: QAbstractItemModel(parent)
@@ -35,12 +38,15 @@ QVariant BookmarkModel::data(const QModelIndex &index, int role) const
if(role == Qt::DecorationRole && index.column() == 0)
return static_cast<BookmarkItem *>(index.internalPointer())->icon();
+
else if(role == Qt::ToolTipRole)
return static_cast<BookmarkItem *>(index.internalPointer())->tooltip();
- else if(role != Qt::DisplayRole)
- return QVariant();
- return static_cast<BookmarkItem *>(index.internalPointer())->data(index.column());
+ else if(role == Qt::DisplayRole)
+ return static_cast<BookmarkItem *>(index.internalPointer())->data(index.column());
+
+ else
+ return QVariant();
}
QVariant BookmarkModel::data(const QModelIndex &index, int column, int role) const
@@ -56,10 +62,15 @@ QVariant BookmarkModel::data(const QModelIndex &index, int column, int role) con
bool BookmarkModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
- if(!index.isValid() || role != Qt::DisplayRole)
+ if(!index.isValid())
return false;
- bool success = static_cast<BookmarkItem *>(index.internalPointer())->setData(static_cast<BookmarkItem::Fields>(index.column()), value);
+ bool success = false;
+
+ if(role == Qt::DisplayRole) {
+ success = static_cast<BookmarkItem *>(index.internalPointer())->setData(static_cast<BookmarkItem::Fields>(index.column()), value);
+ }
+
if(success)
emit dataChanged(index, index, { role });
return success;
@@ -81,7 +92,7 @@ Qt::ItemFlags BookmarkModel::flags(const QModelIndex &index) const
if(getItem(index)->type() == BookmarkItem::Folder)
return QAbstractItemModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
else
- return QAbstractItemModel::flags(index) | Qt::ItemIsDragEnabled;
+ return QAbstractItemModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemNeverHasChildren;
}
bool BookmarkModel::isItemExpanded(const QModelIndex &index) const
@@ -100,24 +111,20 @@ int BookmarkModel::rowCount(const QModelIndex &index) const
return getItem(index)->childCount();
}
-bool BookmarkModel::insertRows(int position, int rows, const QModelIndex &parent)
+bool BookmarkModel::appendBookmark(const QString &title, const QString &url, const QModelIndex &parent)
{
auto *parentItem = getItem(parent);
- // if position is negative, or past the number of children in the item
- if(position < 0 || position > parentItem->childCount())
- return false;
-
- beginInsertRows(parent, position, position + rows - 1);
- for(int i = 0; i < rows; ++i) {
- parentItem->insertChild(position + i, new BookmarkItem({}, BookmarkItem::Bookmark, parentItem));
- }
+ int row = parentItem->childCount();
+ beginInsertRows(parent, row, row);
+ parentItem->appendChild(new BookmarkItem({ title, url }, BookmarkItem::Bookmark, parentItem));
endInsertRows();
return true;
}
bool BookmarkModel::removeRows(int position, int rows, const QModelIndex &parent)
{
+ qDebug("removeRows: pos=%i rows=%i", position, rows);
auto *parentItem = getItem(parent);
beginRemoveRows(parent, position, position + rows - 1);
@@ -126,36 +133,10 @@ bool BookmarkModel::removeRows(int position, int rows, const QModelIndex &parent
return success;
}
-bool BookmarkModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild)
-{
- auto *sourceParentItem = getItem(sourceParent);
- auto *destinationParentItem = getItem(destinationParent);
-
- bool success = true;
- beginMoveRows(sourceParent, sourceRow, sourceRow + count - 1, destinationParent, destinationChild);
- for(int i = 0; i < count; ++i) {
- auto *child = sourceParentItem->takeChild(sourceRow, destinationParentItem);
- if(!destinationParentItem->insertChild(destinationChild, child)) {
- success = false;
- break;
- }
- }
- endMoveRows();
- return success;
-}
-
int BookmarkModel::columnCount(const QModelIndex &index) const
{
+ Q_UNUSED(index);
return 2;
- // if(!index.isValid())
- // return rootItem->columnCount();
- // else
- // return static_cast<BookmarkItem *>(index.internalPointer())->columnCount();
-}
-
-Qt::DropActions BookmarkModel::supportedDropActions() const
-{
- return Qt::MoveAction;
}
QModelIndex BookmarkModel::index(int row, int column, const QModelIndex &parent) const
@@ -184,6 +165,26 @@ QModelIndex BookmarkModel::parent(const QModelIndex &index) const
return createIndex(parentItem->row(), 0, parentItem);
}
+
+inline QStringList searchThrough(const QString &term, BookmarkItem *item)
+{
+ QStringList results;
+ for(int i = 0; i < item->childCount(); ++i) {
+ auto *child = item->child(i);
+ if(child->type() == BookmarkItem::Bookmark && child->data(BookmarkItem::Href).toString().contains(term))
+ results.append(child->data(BookmarkItem::Href).toString());
+ else if(child->type() == BookmarkItem::Folder)
+ results.append(searchThrough(term, child));
+ }
+ return results;
+}
+
+QStringList BookmarkModel::search(const QString &term) const
+{
+ // TODO tag searching
+ return searchThrough(term, rootItem);
+}
+
BookmarkItem *BookmarkModel::getItem(const QModelIndex &index) const
{
if(!index.isValid())
@@ -191,3 +192,83 @@ BookmarkItem *BookmarkModel::getItem(const QModelIndex &index) const
else
return static_cast<BookmarkItem *>(index.internalPointer());
}
+
+/*
+ * Drag'n'Drop implementation
+ * How drag and drop actually works: the view encodes the data of the original
+ * item (through ::mimeData), and then uses ::dropMimeData to create the new
+ * item. If successful, the old item is removed (through ::removeRows).
+ * This means that the encoding and decoding needs to be provided. In this case,
+ * this is done through xbel.
+ */
+
+Qt::DropActions BookmarkModel::supportedDropActions() const
+{
+ return Qt::MoveAction;
+}
+
+QStringList BookmarkModel::mimeTypes() const
+{
+ return { mimeType };
+}
+
+QMimeData *BookmarkModel::mimeData(const QModelIndexList &indexes) const
+{
+ auto *mimeData = new QMimeData();
+ QByteArray data;
+ XbelWriter writer;
+
+ QDataStream stream(&data, QIODevice::WriteOnly);
+ for(const QModelIndex &index : indexes) {
+ if(index.isValid() && index.column() == 0) {
+ QByteArray encodedData;
+ QBuffer buffer(&encodedData);
+ buffer.open(QIODevice::WriteOnly);
+
+ writer.write(&buffer, getItem(index));
+
+ stream << encodedData;
+ }
+ }
+ mimeData->setData(mimeType, data);
+ return mimeData;
+}
+bool BookmarkModel::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent)
+{
+ if(action == Qt::IgnoreAction)
+ return true;
+
+ if(action != Qt::MoveAction)
+ return false;
+
+ if(!mimeData->hasFormat(mimeType) || column > 0)
+ return false;
+
+ QByteArray data = mimeData->data(mimeType);
+ QDataStream stream(&data, QIODevice::ReadOnly);
+ if(stream.atEnd())
+ return false;
+
+ while(!stream.atEnd()) {
+ QByteArray encodedData;
+ stream >> encodedData;
+
+ QBuffer buffer(&encodedData);
+ buffer.open(QIODevice::ReadOnly);
+
+ XbelReader reader(&buffer);
+ auto *fakeRoot = new BookmarkItem({}, BookmarkItem::Folder, nullptr);
+ auto *parentItem = getItem(parent);
+ reader.read(fakeRoot);
+
+ beginInsertRows(parent, row, row + fakeRoot->childCount() - 1);
+ for(int i = 0; i < fakeRoot->childCount(); ++i) {
+ auto *child = fakeRoot->takeChild(0, parentItem);
+ parentItem->insertChild(row, child);
+ }
+ endInsertRows();
+
+ delete fakeRoot;
+ }
+ return true;
+}