/* ============================================================ * * This file is a part of the rekonq project * * Copyright (C) 2009 by Nils Weigel * Copyright (C) 2010 by Andrea Diamantini * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * ============================================================ */ // Self Includes #include "bookmarkstreemodel.h" #include "bookmarkstreemodel.moc" // Local Includes #include "application.h" #include "bookmarksmanager.h" // Qt Includes #include // KDE includes #include #include BtmItem::BtmItem(const KBookmark &bm) : m_parent(0) , m_kbm(bm) { } BtmItem::~BtmItem() { qDeleteAll(m_children); } QVariant BtmItem::data( int role ) const { if( m_kbm.isNull() ) return QVariant(); // should only happen for root item if( role == Qt::DisplayRole ) return m_kbm.text(); if( role == Qt::DecorationRole ) return KIcon( m_kbm.icon() ); if( role == Qt::UserRole ) return m_kbm.url(); if( role == Qt::ToolTipRole) { QString tooltip = ""; if(!m_kbm.text().isEmpty()) { tooltip += m_kbm.text(); } if(m_kbm.isGroup()) { tooltip += " [" + QString::number(childCount()) + " " + i18n("Items") + "]"; } if(!m_kbm.url().url().isEmpty()) { if(!tooltip.isEmpty()) tooltip += "\n"; tooltip += m_kbm.url().url(); } return tooltip; } return QVariant(); } int BtmItem::row() const { if(m_parent) return m_parent->m_children.indexOf( const_cast< BtmItem* >( this ) ); return 0; } int BtmItem::childCount() const { return m_children.count(); } BtmItem* BtmItem::child( int n ) { Q_ASSERT(n>=0); Q_ASSERT(nm_parent = this; m_children << child; } void BtmItem::clear() { qDeleteAll(m_children); m_children.clear(); } KBookmark BtmItem::getBkm() const { return m_kbm; } // ------------------------------------------------------------------------------------- BookmarksTreeModel::BookmarksTreeModel(QObject *parent) : QAbstractItemModel(parent) , m_root(0) { resetModel(); connect( this, SIGNAL(bookmarksUpdated()), parent, SLOT(loadFoldedState())); connect( Application::bookmarkProvider()->bookmarkManager(), SIGNAL( changed(QString,QString) ), this, SLOT( bookmarksChanged() ) ); connect( parent, SIGNAL(saveOnlyRequested()), this, SLOT(saveOnly()) ); } BookmarksTreeModel::~BookmarksTreeModel() { delete m_root; } int BookmarksTreeModel::rowCount(const QModelIndex &parent) const { BtmItem *parentItem = 0; if( !parent.isValid() ) { parentItem = m_root; } else { parentItem = static_cast< BtmItem* >( parent.internalPointer() ); } return parentItem->childCount(); } int BookmarksTreeModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent) // name return 1; } QVariant BookmarksTreeModel::headerData(int section, Qt::Orientation orientation, int role) const { if( orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0 ) return i18n( "Bookmark" ); return QVariant(); } Qt::ItemFlags BookmarksTreeModel::flags(const QModelIndex &index) const { Qt::ItemFlags flags = QAbstractItemModel::flags(index); if(!index.isValid()) return flags | Qt::ItemIsDropEnabled; flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled; if(bookmarkForIndex(index).isGroup()) flags |= Qt::ItemIsDropEnabled; return flags; } QModelIndex BookmarksTreeModel::index(int row, int column, const QModelIndex &parent) const { if( !hasIndex( row, column, parent ) ) { return QModelIndex(); } BtmItem *parentItem; if( !parent.isValid() ) { parentItem = m_root; } else { parentItem = static_cast< BtmItem* >( parent.internalPointer() ); } BtmItem *childItem = parentItem->child( row ); if( childItem ) { return createIndex( row, column, childItem ); } return QModelIndex(); } QModelIndex BookmarksTreeModel::parent(const QModelIndex &index) const { if( !index.isValid() ) { return QModelIndex(); } BtmItem *childItem = static_cast< BtmItem* >( index.internalPointer() ); BtmItem *parentItem = childItem->parent(); if( parentItem == m_root ) { return QModelIndex(); } return createIndex( parentItem->row(), 0, parentItem ); } QVariant BookmarksTreeModel::data(const QModelIndex &index, int role) const { if( !index.isValid() ) { return QVariant(); } BtmItem *node = static_cast< BtmItem* >( index.internalPointer() ); if( node && node == m_root ) { if( role == Qt::DisplayRole ) return i18n( "Bookmarks" ); if( role == Qt::DecorationRole ) return KIcon( "bookmarks" ); } else { if( node ) return node->data( role ); } return QVariant(); } void BookmarksTreeModel::bookmarksChanged() { resetModel(); emit bookmarksUpdated(); } void BookmarksTreeModel::resetModel() { setRoot(Application::bookmarkProvider()->rootGroup()); } void BookmarksTreeModel::setRoot(KBookmarkGroup bmg) { delete m_root; m_root = new BtmItem(KBookmark()); if( bmg.isNull() ) return; populate( m_root, bmg ); reset(); } void BookmarksTreeModel::populate( BtmItem *node, KBookmarkGroup bmg) { node->clear(); if( bmg.isNull() ) return; KBookmark bm = bmg.first(); while( !bm.isNull() ) { BtmItem *newChild = new BtmItem( bm ); if( bm.isGroup() ) populate( newChild, bm.toGroup() ); node->appendChild( newChild ); bm = bmg.next( bm ); } } KBookmark BookmarksTreeModel::bookmarkForIndex(const QModelIndex index) const { return static_cast(index.internalPointer())->getBkm(); } void BookmarksTreeModel::saveOnly() { disconnect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(QString,QString)), this, SLOT(bookmarksChanged())); connect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(QString,QString)), this, SLOT(reconnectManager())); Application::bookmarkProvider()->bookmarkManager()->emitChanged(); } void BookmarksTreeModel::reconnectManager() { connect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL( changed(QString,QString) ), this, SLOT(bookmarksChanged())); } Qt::DropActions BookmarksTreeModel::supportedDropActions () const { return Qt::MoveAction; } QStringList BookmarksTreeModel::mimeTypes () const { return KBookmark::List::mimeDataTypes(); } QMimeData* BookmarksTreeModel::mimeData( const QModelIndexList & indexes ) const { QMimeData *mimeData = new QMimeData; QByteArray addresse = bookmarkForIndex(indexes.first()).address().toLatin1(); mimeData->setData( "application/rekonq-bookmark", addresse); bookmarkForIndex(indexes.first()).populateMimeData(mimeData); return mimeData; } bool BookmarksTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex & parent) { if(action == Qt::MoveAction) { if(data->hasFormat("application/rekonq-bookmark")) { QByteArray addresses = data->data("application/rekonq-bookmark"); KBookmark bookmark = Application::bookmarkProvider()->bookmarkManager()->findByAddress(QString::fromLatin1(addresses.data())); QModelIndex destIndex = index(row, column, parent); KBookmark dropDestBookmark; if(destIndex.isValid()) dropDestBookmark = bookmarkForIndex(destIndex); KBookmarkGroup root = Application::bookmarkProvider()->rootGroup(); if(parent.isValid()) root = bookmarkForIndex(parent).toGroup(); if(!destIndex.isValid()) { if(!parent.isValid()) // Drop into a blank area { Application::bookmarkProvider()->rootGroup().deleteBookmark(bookmark); Application::bookmarkProvider()->rootGroup().addBookmark(bookmark); } else // Drop at the last item of the group or directly on the main item of the group { root.deleteBookmark(bookmark); root.addBookmark(bookmark); } } else { if(row == -1) { root.deleteBookmark(bookmark); root.addBookmark(bookmark); } else // A classic drop { root.moveBookmark(bookmark, root.previous(dropDestBookmark)); } } Application::bookmarkProvider()->bookmarkManager()->emitChanged(root); } } return true; }