diff options
Diffstat (limited to 'src/bookmarks')
-rw-r--r-- | src/bookmarks/bookmarkcontextmenu.cpp | 325 | ||||
-rw-r--r-- | src/bookmarks/bookmarkcontextmenu.h | 65 | ||||
-rw-r--r-- | src/bookmarks/bookmarksmanager.cpp | 293 | ||||
-rw-r--r-- | src/bookmarks/bookmarksmanager.h | 54 | ||||
-rw-r--r-- | src/bookmarks/bookmarkspanel.cpp | 154 | ||||
-rw-r--r-- | src/bookmarks/bookmarkspanel.h | 32 | ||||
-rw-r--r-- | src/bookmarks/bookmarksproxy.cpp | 19 | ||||
-rw-r--r-- | src/bookmarks/bookmarksproxy.h | 16 | ||||
-rw-r--r-- | src/bookmarks/bookmarkstreemodel.cpp | 364 | ||||
-rw-r--r-- | src/bookmarks/bookmarkstreemodel.h | 64 |
10 files changed, 1130 insertions, 256 deletions
diff --git a/src/bookmarks/bookmarkcontextmenu.cpp b/src/bookmarks/bookmarkcontextmenu.cpp new file mode 100644 index 00000000..df8bf5e0 --- /dev/null +++ b/src/bookmarks/bookmarkcontextmenu.cpp @@ -0,0 +1,325 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> +* +* +* 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 <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +// Self Includes +#include "bookmarkcontextmenu.h" +#include "bookmarkcontextmenu.moc" + +// Local Includes +#include "application.h" +#include "bookmarksmanager.h" + +// KDE Includes +#include <KMessageBox> +#include <KActionCollection> +#include <KBookmarkDialog> + +// Qt Includes +#include <QClipboard> + + +BookmarkContextMenu::BookmarkContextMenu(const KBookmark & bookmark, KBookmarkManager *manager, KBookmarkOwner *owner, QWidget *parent) + : KBookmarkContextMenu(bookmark, manager, owner, parent) + , m_ac(new KActionCollection(this)) +{ + setupActions(); +} + + +void BookmarkContextMenu::setupActions() +{ + KAction* action; + + action = new KAction(KIcon("tab-new"), i18n("Open"), this); + connect(action, SIGNAL(triggered()), this, SLOT(openInCurrentTab())); + m_ac->addAction("open", action); + + action = new KAction(KIcon("tab-new"), i18n("Open in New Tab"), this); + connect(action, SIGNAL(triggered()), this, SLOT(openInNewTab())); + m_ac->addAction("open_tab", action); + + action = new KAction(KIcon("window-new"), i18n("Open in New Window"), this); + connect(action, SIGNAL(triggered()), this, SLOT(openInNewWindow())); + m_ac->addAction("open_window", action); + + action = new KAction(KIcon("bookmark-new"), i18n("Add Bookmark Here"), this); + connect(action, SIGNAL(triggered()), this, SLOT(bookmarkCurrentPage())); + m_ac->addAction("bookmark_page", action); + + action = new KAction(KIcon("folder-new"), i18n("New Bookmark Folder"), this); + connect(action, SIGNAL(triggered()), this, SLOT(newBookmarkGroup())); + m_ac->addAction("folder_new", action); + + action = new KAction(KIcon("edit-clear"), i18n("New Separator"), this); + connect(action, SIGNAL(triggered()), this, SLOT(newSeparator())); + m_ac->addAction("separator_new", action); + + action = new KAction(KIcon("edit-copy"), i18n("Copy Link Address"), this); + connect(action, SIGNAL(triggered()), this, SLOT(copyToClipboard())); + m_ac->addAction("copy", action); + + action = new KAction(KIcon("edit-delete"), i18n("Delete Bookmark"), this); + connect(action, SIGNAL(triggered()), this, SLOT(deleteBookmark())); + m_ac->addAction("delete", action); + + action = new KAction(KIcon("configure"), i18n("Properties"), this); + connect(action, SIGNAL(triggered()), this, SLOT(editBookmark())); + m_ac->addAction("properties", action); + + action = new KAction(KIcon("tab-new"), i18n("Open Folder in Tabs"), this); + connect(action, SIGNAL(triggered()), this, SLOT(openFolderInTabs())); + m_ac->addAction("open_all", action); +} + + +void BookmarkContextMenu::addBookmarkActions() +{ + addAction(m_ac->action("open")); + addAction(m_ac->action("open_tab")); + addAction(m_ac->action("open_window")); + + addSeparator(); + + addAction(m_ac->action("bookmark_page")); + addAction(m_ac->action("folder_new")); + addAction(m_ac->action("separator_new")); + + addSeparator(); + + addAction(m_ac->action("copy")); + + addSeparator(); + + addAction(m_ac->action("delete")); + addAction(m_ac->action("properties")); +} + + +void BookmarkContextMenu::addFolderActions() +{ + if (!bookmark().toGroup().first().isNull()) + { + addAction(m_ac->action("open_all")); + addSeparator(); + } + + addAction(m_ac->action("bookmark_page")); + addAction(m_ac->action("folder_new")); + addAction(m_ac->action("separator_new")); + + addSeparator(); + + addAction(m_ac->action("delete")); + addAction(m_ac->action("properties")); +} + + +void BookmarkContextMenu::addSeparatorActions() +{ + addAction(m_ac->action("bookmark_page")); + addAction(m_ac->action("folder_new")); + addAction(m_ac->action("separator_new")); + + addSeparator(); + + addAction(m_ac->action("delete")); +} + + +void BookmarkContextMenu::addActions() +{ + if (bookmark().isGroup()) + { + addFolderActions(); + } + + else if (bookmark().isSeparator()) + { + addSeparatorActions(); + } + + else if (bookmark().isNull()) + { + addAction(m_ac->action("bookmark_page")); + addAction(m_ac->action("folder_new")); + addAction(m_ac->action("separator_new")); + } + + else + { + addBookmarkActions(); + } +} + + +void BookmarkContextMenu::openInCurrentTab() +{ + Application::instance()->loadUrl(bookmark().url()); +} + + +void BookmarkContextMenu::openInNewTab() +{ + Application::instance()->loadUrl(bookmark().url(), Rekonq::SettingOpenTab); +} + + +void BookmarkContextMenu::openInNewWindow() +{ + Application::instance()->loadUrl(bookmark().url(), Rekonq::NewWindow); +} + + +void BookmarkContextMenu::copyToClipboard() +{ + if (bookmark().isNull()) + return; + + QClipboard *cb = QApplication::clipboard(); + cb->setText(bookmark().url().url()); +} + + +void BookmarkContextMenu::deleteBookmark() +{ + KBookmark bm = bookmark(); + bool folder = bm.isGroup(); + + if (KMessageBox::warningContinueCancel( + QApplication::activeWindow(), + folder ? i18n("Are you sure you wish to remove the bookmark folder\n\"%1\"?", bm.text()) + : i18n("Are you sure you wish to remove the bookmark\n\"%1\"?", bm.text()), + folder ? i18n("Bookmark Folder Deletion") + : i18n("Bookmark Deletion"), + KStandardGuiItem::del()) + != KMessageBox::Continue + ) + return; + + bm.parentGroup().deleteBookmark(bm); + manager()->emitChanged(); +} + + +void BookmarkContextMenu::editBookmark() +{ + KBookmark selected = bookmark(); + + KBookmarkDialog *dialog = owner()->bookmarkDialog(manager(), QApplication::activeWindow()); + dialog->editBookmark(selected); + delete dialog; +} + + +void BookmarkContextMenu::openFolderInTabs() +{ + if (bookmark().isGroup()) + owner()->openFolderinTabs(bookmark().toGroup()); +} + + +void BookmarkContextMenu::newBookmarkGroup() +{ + KBookmark selected = bookmark(); + KBookmarkDialog *dialog = owner()->bookmarkDialog(manager(), QApplication::activeWindow()); + + if (!selected.isNull()) + { + if (selected.isGroup()) + { + dialog->createNewFolder("New folder", selected); + } + + else + { + KBookmark newBk; + newBk = dialog->createNewFolder("New folder", selected.parentGroup()); + selected.parentGroup().moveBookmark(newBk, selected); + manager()->emitChanged(); + } + } + else + { + dialog->createNewFolder("New folder"); + } + + delete dialog; +} + + +void BookmarkContextMenu::newSeparator() +{ + KBookmark selected = bookmark(); + KBookmark newBk; + + if (!selected.isNull()) + { + if (selected.isGroup()) + newBk = selected.toGroup().createNewSeparator(); + else + newBk = selected.parentGroup().createNewSeparator(); + } + + else + { + newBk = Application::bookmarkProvider()->rootGroup().createNewSeparator(); + } + + KBookmarkGroup parent = newBk.parentGroup(); + newBk.setIcon(("edit-clear")); + parent.addBookmark(newBk); + + if (!selected.isNull()) + parent.moveBookmark(newBk, selected); + + manager()->emitChanged(); +} + + +void BookmarkContextMenu::bookmarkCurrentPage() +{ + KBookmarkGroup parent = Application::bookmarkProvider()->rootGroup(); + KBookmark selected = bookmark(); + + if (!selected.isNull()) + { + parent = selected.parentGroup(); + + if (selected.isGroup()) + parent = selected.toGroup(); + + KBookmark newBk = parent.addBookmark(owner()->currentTitle(), KUrl(owner()->currentUrl()), "text-html"); + parent.moveBookmark(newBk, selected.parentGroup().previous(selected)); + } + + else + { + parent.addBookmark(owner()->currentTitle(), KUrl(owner()->currentUrl()), "text-html"); + } + + manager()->emitChanged(); +} + diff --git a/src/bookmarks/bookmarkcontextmenu.h b/src/bookmarks/bookmarkcontextmenu.h new file mode 100644 index 00000000..c8c903d8 --- /dev/null +++ b/src/bookmarks/bookmarkcontextmenu.h @@ -0,0 +1,65 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> +* +* +* 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 <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +#ifndef BOOKMARKCONTEXTMENU_H +#define BOOKMARKCONTEXTMENU_H + +// Local Includes +#include "application.h" + +// Qt Includes +#include <KBookmarkMenu> + + +class BookmarkContextMenu : public KBookmarkContextMenu +{ + Q_OBJECT + +public: + BookmarkContextMenu(const KBookmark & bk, KBookmarkManager * manager, KBookmarkOwner *owner, QWidget * parent = 0); + virtual void addActions(); + +private slots: + void openInCurrentTab(); + void openInNewTab(); + void openInNewWindow(); + void copyToClipboard(); + void deleteBookmark(); + void openFolderInTabs(); + void editBookmark(); + void newBookmarkGroup(); + void newSeparator(); + void bookmarkCurrentPage(); + +private: + void setupActions(); + void addFolderActions(); + void addBookmarkActions(); + void addSeparatorActions(); + KActionCollection *m_ac; +}; + +#endif // BOOKMARKCONTEXTMENU_H diff --git a/src/bookmarks/bookmarksmanager.cpp b/src/bookmarks/bookmarksmanager.cpp index 6442192a..73127257 100644 --- a/src/bookmarks/bookmarksmanager.cpp +++ b/src/bookmarks/bookmarksmanager.cpp @@ -2,9 +2,10 @@ * * This file is a part of the rekonq project * -* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com> * Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com> -* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> * * * This program is free software; you can redistribute it and/or @@ -12,9 +13,9 @@ * 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 +* 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 @@ -34,25 +35,24 @@ #include "mainwindow.h" #include "webtab.h" #include "webview.h" +#include "mainview.h" +#include "bookmarkcontextmenu.h" // KDE Includes #include <KActionCollection> -#include <KBookmark> #include <KBookmarkAction> #include <KBookmarkGroup> -#include <KBookmarkMenu> #include <KToolBar> -#include <KDebug> #include <KMenu> #include <KStandardDirs> #include <KUrl> +#include <KMessageBox> // Qt Includes #include <QtCore/QFile> #include <QtGui/QActionGroup> - BookmarkOwner::BookmarkOwner(QObject *parent) : QObject(parent) , KBookmarkOwner() @@ -66,7 +66,7 @@ void BookmarkOwner::openBookmark(const KBookmark & bookmark, { if (keyboardModifiers & Qt::ControlModifier || mouseButtons == Qt::MidButton) { - emit openUrl(bookmark.url(), Rekonq::NewCurrentTab); + emit openUrl(bookmark.url(), Rekonq::SettingOpenTab); } else { @@ -93,17 +93,40 @@ QString BookmarkOwner::currentTitle() const } -void BookmarkOwner::openFolderinTabs(const KBookmarkGroup &bm) +void BookmarkOwner::openFolderinTabs(const KBookmarkGroup &bookmark) { - QList<KUrl> urlList = bm.groupUrlList(); + QList<KUrl> urlList = bookmark.groupUrlList(); + + if (urlList.length() > 8) + { + if (!(KMessageBox::warningContinueCancel(Application::instance()->mainWindow(), i18n("You are about to open %1 tabs.\nAre you sure ?", QString::number(urlList.length()))) == KMessageBox::Continue)) + return; + } + QList<KUrl>::iterator url; for (url = urlList.begin(); url != urlList.end(); ++url) { - Application::instance()->loadUrl(*url, Rekonq::NewCurrentTab); + emit openUrl(*url, Rekonq::NewCurrentTab); } } +QList< QPair<QString, QString> > BookmarkOwner::currentBookmarkList() const +{ + QList< QPair<QString, QString> > bkList; + int tabNumber = Application::instance()->mainWindow()->mainView()->count(); + + for (int i = 0; i < tabNumber; i++) + { + QPair<QString, QString> item; + item.first = Application::instance()->mainWindow()->mainView()->webTab(i)->view()->title(); + item.second = Application::instance()->mainWindow()->mainView()->webTab(i)->url().url(); + bkList += item; + } + return bkList; +} + + // ------------------------------------------------------------------------------------------------------ @@ -112,26 +135,35 @@ BookmarkMenu::BookmarkMenu(KBookmarkManager *manager, KMenu *menu, KActionCollection* actionCollection) : KBookmarkMenu(manager, owner, menu, actionCollection) - { KAction *a = KStandardAction::addBookmark(this, SLOT(slotAddBookmark()), this); -// a->setText(i18n("Bookmark this Page")); - actionCollection->addAction(QLatin1String("rekonq_add_bookmark"),a); + actionCollection->addAction(QL1S("rekonq_add_bookmark"), a); + refill(); +} + + +BookmarkMenu::BookmarkMenu(KBookmarkManager *manager, + KBookmarkOwner *owner, + KMenu *parentMenu, + const QString &parentAddress) + : KBookmarkMenu(manager, owner, parentMenu, parentAddress) +{ + refill(); } + BookmarkMenu::~BookmarkMenu() { } -KMenu *BookmarkMenu::viewContextMenu(QAction *action) +KMenu * BookmarkMenu::contextMenu(QAction *act) { - // contextMenu() returns an invalid KMenu (seg fault) for the folders in the toolbar - KMenu *menu = contextMenu(action); - if(menu) - return menu; - return 0; // new KMenu(); + KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(act); + if (!action) + return 0; + return new BookmarkContextMenu(action->bookmark(), manager(), owner()); } @@ -151,6 +183,76 @@ void BookmarkMenu::slotAddBookmark() } +QAction * BookmarkMenu::actionForBookmark(const KBookmark &bookmark) +{ + if (bookmark.isGroup()) + { + KBookmarkActionMenu *actionMenu = new KBookmarkActionMenu(bookmark, this); + new BookmarkMenu(manager(), owner(), actionMenu->menu(), bookmark.address()); + return actionMenu; + } + else if (bookmark.isSeparator()) + { + return KBookmarkMenu::actionForBookmark(bookmark); + } + else + { + Application::bookmarkProvider()->completionObject()->addItem(bookmark.url().url()); + return new KBookmarkAction(bookmark, owner(), this); + } +} + + +void BookmarkMenu::refill() +{ + fillBookmarks(); + + if (parentMenu()->actions().count() > 0) + parentMenu()->addSeparator(); + + if (isRoot()) + { + addAddBookmark(); + addAddBookmarksList(); + addNewFolder(); + addEditBookmarks(); + + } + else + { + addOpenFolderInTabs(); + addAddBookmark(); + addAddBookmarksList(); + addNewFolder(); + } +} + + +void BookmarkMenu::addOpenFolderInTabs() +{ + KAction *action; + KBookmarkGroup group = manager()->findByAddress(parentAddress()).toGroup(); + + if (!group.first().isNull()) + { + KBookmark bookmark = group.first(); + + while (bookmark.isGroup() || bookmark.isSeparator()) + { + bookmark = group.next(bookmark); + } + + if (!bookmark.isNull()) + { + action = new KAction(KIcon("tab-new"), i18n("Open Folder in Tabs"), this); + action->setHelpText(i18n("Open all bookmarks in this folder as a new tab.")); + connect(action, SIGNAL(triggered(bool)), this, SLOT(slotOpenFolderInTabs())); + parentMenu()->addAction(action); + } + } +} + + // ------------------------------------------------------------------------------------------------------ @@ -160,8 +262,12 @@ BookmarkProvider::BookmarkProvider(QObject *parent) , m_owner(0) , m_actionCollection(new KActionCollection(this)) , m_bookmarkMenu(0) - , m_bookmarkToolBar(0) + , m_completion(0) { + // take care of the completion object + m_completion = new KCompletion; + m_completion->setOrder(KCompletion::Weighted); + KUrl bookfile = KUrl("~/.kde/share/apps/konqueror/bookmarks.xml"); // share konqueror bookmarks if (!QFile::exists(bookfile.path())) @@ -178,7 +284,9 @@ BookmarkProvider::BookmarkProvider(QObject *parent) bookfile = KUrl(bookmarksPath); } } - m_manager = KBookmarkManager::managerForExternalFile(bookfile.path()); + + m_manager = KBookmarkManager::managerForFile(bookfile.path(), "rekonq"); + connect(m_manager, SIGNAL(changed(const QString &, const QString &)), this, SLOT(slotBookmarksChanged(const QString &, const QString &))); @@ -197,37 +305,37 @@ BookmarkProvider::~BookmarkProvider() } -void BookmarkProvider::setupBookmarkBar(KToolBar *t) +void BookmarkProvider::setupBookmarkBar(KToolBar *toolbar) { - m_bookmarkToolBar = t; - connect(m_bookmarkToolBar, SIGNAL(customContextMenuRequested(const QPoint &)), + KToolBar *bookmarkToolBar = toolbar; + m_bookmarkToolBars.append(bookmarkToolBar); + bookmarkToolBar->setContextMenuPolicy(Qt::CustomContextMenu); + connect(bookmarkToolBar, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(contextMenu(const QPoint &))); slotBookmarksChanged("", ""); } +void BookmarkProvider::removeToolBar(KToolBar *toolbar) +{ + m_bookmarkToolBars.removeOne(toolbar); +} + + void BookmarkProvider::slotBookmarksChanged(const QString &group, const QString &caller) { Q_UNUSED(group) Q_UNUSED(caller) - if (!m_bookmarkToolBar) - return; - - KBookmarkGroup toolBarGroup = m_manager->toolbar(); - if (toolBarGroup.isNull()) - return; + m_completion->clear(); - if(m_bookmarkToolBar) + foreach(KToolBar *bookmarkToolBar, m_bookmarkToolBars) { - m_bookmarkToolBar->clear(); // FIXME CRASH - - KBookmark bookmark = toolBarGroup.first(); - while (!bookmark.isNull()) + if (bookmarkToolBar) { - m_bookmarkToolBar->addAction(fillBookmarkBar(bookmark)); - bookmark = toolBarGroup.next(bookmark); + bookmarkToolBar->clear(); + fillBookmarkBar(bookmarkToolBar); } } } @@ -244,13 +352,22 @@ QAction *BookmarkProvider::actionByName(const QString &name) void BookmarkProvider::contextMenu(const QPoint &point) { - KAction* action = dynamic_cast<KAction*>(m_bookmarkToolBar->actionAt(point)); + if (m_bookmarkToolBars.isEmpty()) + return; + + KToolBar *bookmarkToolBar = m_bookmarkToolBars.at(0); + if (!bookmarkToolBar) + return; + + KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(bookmarkToolBar->actionAt(point)); if (!action) return; - KMenu *menu = m_bookmarkMenu->viewContextMenu(action); + + KMenu *menu = new BookmarkContextMenu(action->bookmark(), bookmarkManager(), bookmarkOwner()); if (!menu) return; - menu->popup(m_bookmarkToolBar->mapToGlobal(point)); + + menu->popup(bookmarkToolBar->mapToGlobal(point)); } @@ -265,36 +382,90 @@ KActionMenu* BookmarkProvider::bookmarkActionMenu(QWidget *parent) } -KAction *BookmarkProvider::fillBookmarkBar(const KBookmark &bookmark) +void BookmarkProvider::fillBookmarkBar(KToolBar *toolBar) { - if (bookmark.isGroup()) + KBookmarkGroup root = m_manager->toolbar(); + if (root.isNull()) + return; + + for (KBookmark bookmark = root.first(); !bookmark.isNull(); bookmark = root.next(bookmark)) { - KBookmarkGroup group = bookmark.toGroup(); - KBookmark bm = group.first(); - KActionMenu *menuAction = new KActionMenu(KIcon(bookmark.icon()), bookmark.text(), this); - menuAction->setDelayed(false); - while (!bm.isNull()) + if (bookmark.isGroup()) { - menuAction->addAction(fillBookmarkBar(bm)); - bm = group.next(bm); + KBookmarkActionMenu *menuAction = new KBookmarkActionMenu(bookmark.toGroup(), this); + menuAction->setDelayed(false); + new BookmarkMenu(bookmarkManager(), bookmarkOwner(), menuAction->menu(), bookmark.address()); + + toolBar->addAction(menuAction); } - return menuAction; + + else if (bookmark.isSeparator()) + { + toolBar->addSeparator(); + } + + else + { + toolBar->addAction(new KBookmarkAction(bookmark, m_owner, this)); + } + } +} + + +KBookmarkGroup BookmarkProvider::rootGroup() +{ + return m_manager->root(); +} + + +KCompletion *BookmarkProvider::completionObject() const +{ + return m_completion; +} + + +QString BookmarkProvider::titleForBookmarkUrl(QString url) +{ + QString title = ""; + KBookmarkGroup bookGroup = Application::bookmarkProvider()->rootGroup(); + if (bookGroup.isNull()) + { + return title; } - - if(bookmark.isSeparator()) + + KBookmark bookmark = bookGroup.first(); + while (!bookmark.isNull() && title.isEmpty()) { - KAction *a = new KAction(this); - a->setSeparator(true); - return a; + title = titleForBookmarkUrl(bookmark, url); + bookmark = bookGroup.next(bookmark); } - else + + if (title.isEmpty()) { - return new KBookmarkAction(bookmark, m_owner, this); + title = url; } + + return title; } -KBookmarkGroup BookmarkProvider::rootGroup() +QString BookmarkProvider::titleForBookmarkUrl(const KBookmark &bookmark, QString url) { - return m_manager->root(); + QString title = ""; + if (bookmark.isGroup()) + { + KBookmarkGroup group = bookmark.toGroup(); + KBookmark bm = group.first(); + while (!bm.isNull() && title.isEmpty()) + { + title = titleForBookmarkUrl(bm, url); // it is .bookfolder + bm = group.next(bm); + } + } + else if (!bookmark.isSeparator() && bookmark.url() == url) + { + title = bookmark.fullText(); + } + + return title; } diff --git a/src/bookmarks/bookmarksmanager.h b/src/bookmarks/bookmarksmanager.h index febac234..ae12280b 100644 --- a/src/bookmarks/bookmarksmanager.h +++ b/src/bookmarks/bookmarksmanager.h @@ -2,9 +2,10 @@ * * This file is a part of the rekonq project * -* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com> * Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com> -* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> * * * This program is free software; you can redistribute it and/or @@ -30,6 +31,9 @@ #define BOOKMARKS_H +// Rekonq Includes +#include "rekonq_defines.h" + // Local Includes #include "application.h" @@ -38,6 +42,7 @@ // KDE Includes #include <KBookmarkOwner> +#include <KCompletion> // Forward Declarations class BookmarkProvider; @@ -55,7 +60,7 @@ class KBookmarkManager; * bookmarks as actions * */ -class BookmarkOwner : public QObject , public KBookmarkOwner +class REKONQ_TESTS_EXPORT BookmarkOwner : public QObject , public KBookmarkOwner { Q_OBJECT @@ -110,7 +115,9 @@ public: * The default implementation does nothing. * This is only called if supportsTabs() returns true */ - virtual void openFolderinTabs(const KBookmarkGroup &bm); + virtual void openFolderinTabs(const KBookmarkGroup &bookmark); + + virtual QList< QPair<QString, QString> > currentBookmarkList() const; signals: /** @@ -128,7 +135,6 @@ signals: // KDE Includes #include <KBookmarkMenu> - /** * This class represent the rekonq bookmarks menu. * It's just a simple class inherited from KBookmarkMenu @@ -143,13 +149,23 @@ public: KBookmarkOwner* owner, KMenu* menu, KActionCollection* actionCollection); + BookmarkMenu(KBookmarkManager *manager, + KBookmarkOwner *owner, + KMenu *parentMenu, + const QString &parentAddress); ~BookmarkMenu(); - virtual KMenu *viewContextMenu(QAction* action); +protected: + virtual KMenu * contextMenu(QAction * act); + virtual void refill(); + virtual QAction* actionForBookmark(const KBookmark &bookmark); protected slots: void slotAddBookmark(); +private: + void addOpenFolderInTabs(); + }; @@ -192,6 +208,7 @@ public: */ void setupBookmarkBar(KToolBar *); + void removeToolBar(KToolBar*); /** * @short Get action by name @@ -209,7 +226,22 @@ public: */ KBookmarkGroup rootGroup(); - KBookmarkManager *bookmarkManager() { return m_manager; } + KBookmarkManager *bookmarkManager() + { + return m_manager; + } + BookmarkOwner *bookmarkOwner() + { + return m_owner; + } + + /** + * @returns the KCompletion object. + */ + KCompletion *completionObject() const; + + QString titleForBookmarkUrl(QString url); + signals: /** * @short This signal is emitted when an url has to be loaded @@ -236,14 +268,18 @@ public slots: */ void slotBookmarksChanged(const QString &group, const QString &caller); + private: - KAction *fillBookmarkBar(const KBookmark &bookmark); + void fillBookmarkBar(KToolBar *toolBar); + QString titleForBookmarkUrl(const KBookmark &bookmark, QString url); KBookmarkManager *m_manager; BookmarkOwner *m_owner; KActionCollection *m_actionCollection; BookmarkMenu *m_bookmarkMenu; - KToolBar *m_bookmarkToolBar; + QList<KToolBar*> m_bookmarkToolBars; + KCompletion *m_completion; }; + #endif diff --git a/src/bookmarks/bookmarkspanel.cpp b/src/bookmarks/bookmarkspanel.cpp index 9164dbb6..0f4e64b8 100644 --- a/src/bookmarks/bookmarkspanel.cpp +++ b/src/bookmarks/bookmarkspanel.cpp @@ -3,7 +3,8 @@ * This file is a part of the rekonq project * * Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com> -* +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -29,8 +30,10 @@ #include "bookmarkspanel.moc" // Local Includes +#include "bookmarksmanager.h" #include "bookmarkstreemodel.h" #include "bookmarksproxy.h" +#include "bookmarkcontextmenu.h" // Auto Includes #include "rekonq.h" @@ -38,16 +41,19 @@ // Qt includes #include <QHBoxLayout> #include <QLabel> -#include <QTreeView> #include <QHeaderView> // KDE includes #include <KLineEdit> #include <KLocalizedString> +#include <KMenu> +#include <KMessageBox> BookmarksPanel::BookmarksPanel(const QString &title, QWidget *parent, Qt::WindowFlags flags) - : QDockWidget(title, parent, flags) + : QDockWidget(title, parent, flags) + , m_treeView(new PanelTreeView(this)) + , m_loadingState(false) { setup(); setShown(ReKonfig::showBookmarksPanel()); @@ -60,13 +66,6 @@ BookmarksPanel::~BookmarksPanel() } -void BookmarksPanel::bookmarkActivated( const QModelIndex &index ) -{ - if( index.isValid() ) - emit openUrl( qVariantValue< KUrl >( index.data( Qt::UserRole ) ) ); -} - - void BookmarksPanel::setup() { setObjectName("bookmarksPanel"); @@ -82,32 +81,139 @@ void BookmarksPanel::setup() KLineEdit *search = new KLineEdit; search->setClearButtonShown(true); searchLayout->addWidget(search); - searchLabel->setBuddy( search ); + searchLabel->setBuddy(search); // setup tree view - QTreeView *treeView = new QTreeView(ui); - treeView->setUniformRowHeights(true); - treeView->setSelectionBehavior(QAbstractItemView::SelectRows); - treeView->setTextElideMode(Qt::ElideMiddle); - treeView->setAlternatingRowColors(true); - treeView->header()->hide(); - treeView->setRootIsDecorated( false ); + m_treeView->setUniformRowHeights(true); + m_treeView->setTextElideMode(Qt::ElideMiddle); + m_treeView->setAlternatingRowColors(true); + m_treeView->header()->hide(); + m_treeView->setDragEnabled(true); + m_treeView->setAutoExpandDelay(750); + m_treeView->setDefaultDropAction(Qt::MoveAction); + m_treeView->viewport()->setAcceptDrops(true); // put everything together QVBoxLayout *vBoxLayout = new QVBoxLayout; vBoxLayout->setContentsMargins(0, 0, 0, 0); vBoxLayout->addLayout(searchLayout); - vBoxLayout->addWidget(treeView); + vBoxLayout->addWidget(m_treeView); // add it to the UI ui->setLayout(vBoxLayout); setWidget(ui); - BookmarksTreeModel *model = new BookmarksTreeModel( this ); + BookmarksTreeModel *model = new BookmarksTreeModel(this); BookmarksProxy *proxy = new BookmarksProxy(ui); - proxy->setSourceModel( model ); - treeView->setModel( proxy ); + proxy->setSourceModel(model); + m_treeView->setModel(proxy); + + connect(m_treeView, SIGNAL(contextMenuItemRequested(const QPoint &)), this, SLOT(contextMenu(const QPoint &))); + connect(m_treeView, SIGNAL(contextMenuGroupRequested(const QPoint &)), this, SLOT(contextMenu(const QPoint &))); + connect(m_treeView, SIGNAL(contextMenuEmptyRequested(const QPoint &)), this, SLOT(contextMenu(const QPoint &))); + connect(m_treeView, SIGNAL(delKeyPressed()), this, SLOT(deleteBookmark())); + connect(m_treeView, SIGNAL(collapsed(const QModelIndex &)), this, SLOT(onCollapse(const QModelIndex &))); + connect(m_treeView, SIGNAL(expanded(const QModelIndex &)), this, SLOT(onExpand(const QModelIndex &))); + connect(search, SIGNAL(textChanged(const QString &)), proxy, SLOT(setFilterFixedString(const QString &))); + loadFoldedState(); +} + + +KBookmark BookmarksPanel::bookmarkForIndex(const QModelIndex &index) +{ + if (!index.isValid()) + return KBookmark(); + + const QAbstractProxyModel* proxyModel = dynamic_cast< const QAbstractProxyModel* >(index.model()); + QModelIndex originalIndex = proxyModel->mapToSource(index); + + BtmItem *node = static_cast< BtmItem* >(originalIndex.internalPointer()); + return node->getBkm(); +} + + +void BookmarksPanel::onCollapse(const QModelIndex &index) +{ + if (m_loadingState) + return; + + KBookmark bookmark = bookmarkForIndex(index); + bookmark.internalElement().setAttribute("folded", "yes"); + emit saveOnlyRequested(); +} + + +void BookmarksPanel::onExpand(const QModelIndex &index) +{ + if (m_loadingState) + return; - connect(search, SIGNAL(textChanged(QString)), proxy, SLOT(setFilterFixedString(QString))); - connect(treeView, SIGNAL( activated(QModelIndex) ), this, SLOT( bookmarkActivated(QModelIndex) ) ); + KBookmark bookmark = bookmarkForIndex(index); + bookmark.internalElement().setAttribute("folded", "no"); + emit saveOnlyRequested(); +} + + +void BookmarksPanel::loadFoldedState() +{ + m_loadingState = true; + loadFoldedState(QModelIndex()); + m_loadingState = false; +} + + +void BookmarksPanel::loadFoldedState(const QModelIndex &root) +{ + + int count = m_treeView->model()->rowCount(root); + QModelIndex index; + + for (int i = 0; i < count; i++) + { + index = m_treeView->model()->index(i, 0, root); + if (index.isValid() && bookmarkForIndex(index).isGroup()) + { + m_treeView->setExpanded(index, bookmarkForIndex(index).toGroup().isOpen()); + loadFoldedState(index); + } + } +} + + +void BookmarksPanel::contextMenu(const QPoint &pos) +{ + QModelIndex index = m_treeView->indexAt(pos); + if (m_loadingState) + return; + + KBookmark selected = bookmarkForIndex(index); + + BookmarkContextMenu *menu = new BookmarkContextMenu(selected, Application::bookmarkProvider()->bookmarkManager(), Application::bookmarkProvider()->bookmarkOwner(), this); + menu->popup(m_treeView->mapToGlobal(pos)); +} + + +void BookmarksPanel::deleteBookmark() +{ + QModelIndex index = m_treeView->currentIndex(); + if (!index.isValid()) + return; + + KBookmark bm = bookmarkForIndex(index); + bool folder = bm.isGroup(); + + if (KMessageBox::warningContinueCancel( + QApplication::activeWindow(), + folder ? i18n("Are you sure you wish to remove the bookmark folder\n\"%1\"?", bm.text()) + : i18n("Are you sure you wish to remove the bookmark\n\"%1\"?", bm.text()), + folder ? i18n("Bookmark Folder Deletion") + : i18n("Bookmark Deletion"), + KStandardGuiItem::del()) + != KMessageBox::Continue + ) + return; + + + bm.parentGroup().deleteBookmark(bm); + Application::instance()->bookmarkProvider()->bookmarkManager()->emitChanged(); } diff --git a/src/bookmarks/bookmarkspanel.h b/src/bookmarks/bookmarkspanel.h index 6c0e153f..b2a9f264 100644 --- a/src/bookmarks/bookmarkspanel.h +++ b/src/bookmarks/bookmarkspanel.h @@ -3,6 +3,8 @@ * This file is a part of the rekonq project * * Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> * * * This program is free software; you can redistribute it and/or @@ -27,15 +29,26 @@ #ifndef BOOKMARKSPANEL_H #define BOOKMARKSPANEL_H + +// Rekonq Includes +#include "rekonq_defines.h" + +// Local Includes +#include "application.h" +#include "paneltreeview.h" + // Qt Includes #include <QDockWidget> +// KDE Includes +#include <KBookmark> + // Forward Declarations class KUrl; class QModelIndex; -class BookmarksPanel : public QDockWidget +class REKONQ_TESTS_EXPORT BookmarksPanel : public QDockWidget { Q_OBJECT @@ -44,13 +57,26 @@ public: ~BookmarksPanel(); signals: - void openUrl(const KUrl &); + void openUrl(const KUrl &, const Rekonq::OpenType &); + void itemHovered(const QString &); + void saveOnlyRequested(); private slots: - void bookmarkActivated( const QModelIndex &index ); + void contextMenu(const QPoint &pos); + + void deleteBookmark(); + void onCollapse(const QModelIndex &index); + void onExpand(const QModelIndex &index); + void loadFoldedState(const QModelIndex &root); + void loadFoldedState(); + private: void setup(); + KBookmark bookmarkForIndex(const QModelIndex &index); + + PanelTreeView *m_treeView; + bool m_loadingState; }; #endif // BOOKMARKSPANEL_H diff --git a/src/bookmarks/bookmarksproxy.cpp b/src/bookmarks/bookmarksproxy.cpp index e94fbeff..4e4b4f06 100644 --- a/src/bookmarks/bookmarksproxy.cpp +++ b/src/bookmarks/bookmarksproxy.cpp @@ -3,6 +3,7 @@ * This file is a part of the rekonq project * * Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com> * * * This program is free software; you can redistribute it and/or @@ -29,27 +30,27 @@ #include "bookmarksproxy.moc" -BookmarksProxy::BookmarksProxy( QObject *parent ) - : QSortFilterProxyModel( parent ) +BookmarksProxy::BookmarksProxy(QObject *parent) + : QSortFilterProxyModel(parent) { } -bool BookmarksProxy::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const +bool BookmarksProxy::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { - QModelIndex idx = sourceModel()->index( source_row, 0, source_parent ); - return recursiveMatch( idx ); + QModelIndex idx = sourceModel()->index(source_row, 0, source_parent); + return recursiveMatch(idx); } -bool BookmarksProxy::recursiveMatch( const QModelIndex &index ) const +bool BookmarksProxy::recursiveMatch(const QModelIndex &index) const { - if( index.data().toString().contains( filterRegExp() ) ) + if (index.data().toString().contains(filterRegExp())) return true; - for( int childRow = 0; childRow < sourceModel()->rowCount( index ); ++childRow ) + for (int childRow = 0; childRow < sourceModel()->rowCount(index); ++childRow) { - if( recursiveMatch( sourceModel()->index( childRow, 0, index ) ) ) + if (recursiveMatch(sourceModel()->index(childRow, 0, index))) return true; } return false; diff --git a/src/bookmarks/bookmarksproxy.h b/src/bookmarks/bookmarksproxy.h index 99483331..e7b50d8e 100644 --- a/src/bookmarks/bookmarksproxy.h +++ b/src/bookmarks/bookmarksproxy.h @@ -3,6 +3,7 @@ * This file is a part of the rekonq project * * Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com> * * * This program is free software; you can redistribute it and/or @@ -27,22 +28,27 @@ #ifndef BOOKMARKSPROXY_H #define BOOKMARKSPROXY_H + +// Rekonq Includes +#include "rekonq_defines.h" + // Qt Includes #include <QSortFilterProxyModel> -class BookmarksProxy : public QSortFilterProxyModel + +class REKONQ_TESTS_EXPORT BookmarksProxy : public QSortFilterProxyModel { Q_OBJECT Q_DISABLE_COPY(BookmarksProxy) public: - BookmarksProxy( QObject *parent = 0 ); + BookmarksProxy(QObject *parent = 0); protected: - virtual bool filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const; + virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; - // returns true if any child(or childs-child...) matches filter - bool recursiveMatch( const QModelIndex &index ) const; + // returns true if any child(or children-child...) matches filter + bool recursiveMatch(const QModelIndex &index) const; }; #endif // BOOKMARKSPROXY_H diff --git a/src/bookmarks/bookmarkstreemodel.cpp b/src/bookmarks/bookmarkstreemodel.cpp index 140fa9c8..654069c2 100644 --- a/src/bookmarks/bookmarkstreemodel.cpp +++ b/src/bookmarks/bookmarkstreemodel.cpp @@ -3,6 +3,7 @@ * This file is a part of the rekonq project * * Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com> * * * This program is free software; you can redistribute it and/or @@ -32,105 +33,124 @@ #include "application.h" #include "bookmarksmanager.h" +// Qt Includes +#include <QMimeData> + // KDE includes #include <KBookmarkGroup> #include <KLocalizedString> -class BookmarksTreeModel::BtmItem -{ -public: - BtmItem(const KBookmark &bm) +BtmItem::BtmItem(const KBookmark &bm) : m_parent(0) , m_kbm(bm) - { - } - - - ~BtmItem() - { - qDeleteAll(m_children); - } +{ +} - QVariant data( int role = Qt::DisplayRole ) const - { - if( m_kbm.isNull() ) - return QVariant(); // should only happen for root item +BtmItem::~BtmItem() +{ + qDeleteAll(m_children); +} - 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(); - return QVariant(); +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 row() const - { - if(m_parent) - return m_parent->m_children.indexOf( const_cast< BtmItem* >( this ) ); - return 0; - } +int BtmItem::row() const +{ + if (m_parent) + return m_parent->m_children.indexOf(const_cast< BtmItem* >(this)); + return 0; +} - int childCount() const - { - return m_children.count(); - } +int BtmItem::childCount() const +{ + return m_children.count(); +} - BtmItem* child( int n ) - { - Q_ASSERT(n>=0); - Q_ASSERT(n<childCount()); - return m_children.at(n); - } +BtmItem* BtmItem::child(int n) +{ + Q_ASSERT(n >= 0); + Q_ASSERT(n < childCount()); + return m_children.at(n); +} - BtmItem* parent() const - { - return m_parent; - } +BtmItem* BtmItem::parent() const +{ + return m_parent; +} - void appendChild(BtmItem *child) - { - if( !child ) - return; - child->m_parent = this; - m_children << child; - } +void BtmItem::appendChild(BtmItem *child) +{ + if (!child) + return; + child->m_parent = this; + m_children << child; +} - void clear() - { - qDeleteAll(m_children); - m_children.clear(); - } -private: - BtmItem *m_parent; - QList< BtmItem* > m_children; - KBookmark m_kbm; -}; +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) + : QAbstractItemModel(parent) + , m_root(0) { resetModel(); - connect( Application::bookmarkProvider()->bookmarkManager(), SIGNAL( changed(QString,QString) ), this, SLOT( bookmarksChanged(QString) ) ); - connect( Application::bookmarkProvider()->bookmarkManager(), SIGNAL( bookmarksChanged(QString) ), this, SLOT( bookmarksChanged(QString) ) ); + 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())); } @@ -143,13 +163,13 @@ BookmarksTreeModel::~BookmarksTreeModel() int BookmarksTreeModel::rowCount(const QModelIndex &parent) const { BtmItem *parentItem = 0; - if( !parent.isValid() ) + if (!parent.isValid()) { parentItem = m_root; } - else + else { - parentItem = static_cast< BtmItem* >( parent.internalPointer() ); + parentItem = static_cast< BtmItem* >(parent.internalPointer()); } return parentItem->childCount(); @@ -166,11 +186,11 @@ int BookmarksTreeModel::columnCount(const QModelIndex &parent) const QVariant BookmarksTreeModel::headerData(int section, Qt::Orientation orientation, int role) const { - if( orientation == Qt::Horizontal - && role == Qt::DisplayRole - && section == 0 - ) - return i18n( "Bookmark" ); + if (orientation == Qt::Horizontal + && role == Qt::DisplayRole + && section == 0 + ) + return i18n("Bookmark"); return QVariant(); } @@ -178,33 +198,42 @@ QVariant BookmarksTreeModel::headerData(int section, Qt::Orientation orientation Qt::ItemFlags BookmarksTreeModel::flags(const QModelIndex &index) const { - Q_UNUSED(index) - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + 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 ) ) + if (!hasIndex(row, column, parent)) { return QModelIndex(); } BtmItem *parentItem; - if( !parent.isValid() ) + if (!parent.isValid()) { parentItem = m_root; } - else + else { - parentItem = static_cast< BtmItem* >( parent.internalPointer() ); + parentItem = static_cast< BtmItem* >(parent.internalPointer()); } - BtmItem *childItem = parentItem->child( row ); - if( childItem ) + BtmItem *childItem = parentItem->child(row); + if (childItem) { - return createIndex( row, column, childItem ); + return createIndex(row, column, childItem); } return QModelIndex(); @@ -213,74 +242,52 @@ QModelIndex BookmarksTreeModel::index(int row, int column, const QModelIndex &pa QModelIndex BookmarksTreeModel::parent(const QModelIndex &index) const { - if( !index.isValid() ) + if (!index.isValid()) { return QModelIndex(); } - BtmItem *childItem = static_cast< BtmItem* >( index.internalPointer() ); + BtmItem *childItem = static_cast< BtmItem* >(index.internalPointer()); BtmItem *parentItem = childItem->parent(); - if( parentItem == m_root ) + if (parentItem == m_root) { return QModelIndex(); } - return createIndex( parentItem->row(), 0, parentItem ); + return createIndex(parentItem->row(), 0, parentItem); } QVariant BookmarksTreeModel::data(const QModelIndex &index, int role) const { - if( !index.isValid() ) + if (!index.isValid()) { return QVariant(); } - BtmItem *node = static_cast< BtmItem* >( index.internalPointer() ); - if( node && node == m_root ) + 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" ); + if (role == Qt::DisplayRole) + return i18n("Bookmarks"); + if (role == Qt::DecorationRole) + return KIcon("bookmarks"); } - else + else { - if( node ) - return node->data( role ); + if (node) + return node->data(role); } return QVariant(); } -void BookmarksTreeModel::bookmarksChanged( const QString &groupAddress ) +void BookmarksTreeModel::bookmarksChanged() { - if( groupAddress.isEmpty() ) - { - resetModel(); - return; - } - - BtmItem *node = m_root; - QModelIndex nodeIndex; - - QStringList indexChain( groupAddress.split( '/', QString::SkipEmptyParts) ); - foreach( QString sIndex, indexChain ) - { - bool ok; - int i = sIndex.toInt( &ok ); - if( !ok ) - break; - - if( i < 0 || i >= node->childCount() ) - break; - - node = node->child( i ); - nodeIndex = index( i, 0, nodeIndex ); - } - emit dataChanged( index( 0, 0, nodeIndex ), index( node->childCount(), 0, nodeIndex ) ); + resetModel(); + emit bookmarksUpdated(); } @@ -295,29 +302,126 @@ void BookmarksTreeModel::setRoot(KBookmarkGroup bmg) delete m_root; m_root = new BtmItem(KBookmark()); - if( bmg.isNull() ) + if (bmg.isNull()) return; - populate( m_root, bmg ); + populate(m_root, bmg); reset(); } -void BookmarksTreeModel::populate( BtmItem *node, KBookmarkGroup bmg) +void BookmarksTreeModel::populate(BtmItem *node, KBookmarkGroup bmg) { node->clear(); - if( bmg.isNull() ) + if (bmg.isNull()) return; KBookmark bm = bmg.first(); - while( !bm.isNull() ) + while (!bm.isNull()) { - BtmItem *newChild = new BtmItem( bm ); - if( bm.isGroup() ) - populate( newChild, bm.toGroup() ); + 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<BtmItem*>(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); - node->appendChild( newChild ); - bm = bmg.next( bm ); + 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; } diff --git a/src/bookmarks/bookmarkstreemodel.h b/src/bookmarks/bookmarkstreemodel.h index 9753999c..d066e137 100644 --- a/src/bookmarks/bookmarkstreemodel.h +++ b/src/bookmarks/bookmarkstreemodel.h @@ -3,6 +3,7 @@ * This file is a part of the rekonq project * * Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com> +* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com> * * * This program is free software; you can redistribute it and/or @@ -27,13 +28,38 @@ #ifndef BOOKMARKSTREEMODEL_H #define BOOKMARKSTREEMODEL_H -// Qt Includes -#include <QAbstractItemModel> + +// Rekonq Includes +#include "rekonq_defines.h" // KDE includes #include <KBookmark> -class BookmarksTreeModel : public QAbstractItemModel +// Qt Includes +#include <QAbstractItemModel> + +class BtmItem +{ +public: + BtmItem(const KBookmark &bm); + ~BtmItem(); + QVariant data(int role = Qt::DisplayRole) const; + int row() const; + int childCount() const; + BtmItem* child(int n); + BtmItem* parent() const; + void appendChild(BtmItem *child); + void clear(); + KBookmark getBkm() const; + +private: + BtmItem *m_parent; + QList< BtmItem* > m_children; + KBookmark m_kbm; +}; + + +class REKONQ_TESTS_EXPORT BookmarksTreeModel : public QAbstractItemModel { Q_OBJECT Q_DISABLE_COPY(BookmarksTreeModel) @@ -42,28 +68,36 @@ public: explicit BookmarksTreeModel(QObject *parent = 0); ~BookmarksTreeModel(); - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; - virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; virtual QModelIndex parent(const QModelIndex &index) const; - virtual QVariant data(const QModelIndex &index, int role) const; -// virtual bool setData(const QModelIndex &index, const QVariant &value, int role); + virtual QVariant data(const QModelIndex &index, int role) const; + + virtual QStringList mimeTypes() const; + virtual bool dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent); + virtual Qt::DropActions supportedDropActions() const; + virtual QMimeData *mimeData(const QModelIndexList & indexes) const; private slots: - void bookmarksChanged( const QString &groupAddress ); + void bookmarksChanged(); + void saveOnly(); + void reconnectManager(); -private: - class BtmItem; - BtmItem *m_root; +signals: + void bookmarksUpdated(); - void resetModel(); +private: + BtmItem *m_root; + void resetModel(); void setRoot(KBookmarkGroup bmg); - void populate( BtmItem *node, KBookmarkGroup bmg); + void populate(BtmItem *node, KBookmarkGroup bmg); + KBookmark bookmarkForIndex(const QModelIndex index) const; }; #endif // BOOKMARKSTREEMODEL_H |