summaryrefslogtreecommitdiff
path: root/src/bookmarks
diff options
context:
space:
mode:
Diffstat (limited to 'src/bookmarks')
-rw-r--r--src/bookmarks/bookmarkmanager.cpp313
-rw-r--r--src/bookmarks/bookmarkmanager.h170
-rw-r--r--src/bookmarks/bookmarkowner.cpp428
-rw-r--r--src/bookmarks/bookmarkowner.h159
-rw-r--r--src/bookmarks/bookmarkscontextmenu.cpp162
-rw-r--r--src/bookmarks/bookmarkscontextmenu.h57
-rw-r--r--src/bookmarks/bookmarkstoolbar.cpp609
-rw-r--r--src/bookmarks/bookmarkstoolbar.h111
8 files changed, 2009 insertions, 0 deletions
diff --git a/src/bookmarks/bookmarkmanager.cpp b/src/bookmarks/bookmarkmanager.cpp
new file mode 100644
index 00000000..25c78044
--- /dev/null
+++ b/src/bookmarks/bookmarkmanager.cpp
@@ -0,0 +1,313 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2008-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com>
+* 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
+* 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 "bookmarkmanager.h"
+#include "bookmarkmanager.moc"
+
+// Local Includes
+#include "application.h"
+#include "bookmarkstoolbar.h"
+#include "bookmarkowner.h"
+// #include "iconmanager.h"
+// #include "mainwindow.h"
+// #include "webtab.h"
+
+// KDE Includes
+#include <KActionCollection>
+#include <KStandardDirs>
+
+// Qt Includes
+#include <QtCore/QFile>
+
+
+// ----------------------------------------------------------------------------------------------
+
+
+QWeakPointer<BookmarkManager> BookmarkManager::s_bookmarkManager;
+
+
+BookmarkManager *BookmarkManager::self()
+{
+ if (s_bookmarkManager.isNull())
+ {
+ s_bookmarkManager = new BookmarkManager(qApp);
+ }
+ return s_bookmarkManager.data();
+}
+
+
+// ----------------------------------------------------------------------------------------------
+
+
+BookmarkManager::BookmarkManager(QObject *parent)
+ : QObject(parent)
+ , m_manager(0)
+ , m_owner(0)
+ , m_actionCollection(new KActionCollection(this))
+{
+ m_manager = KBookmarkManager::userBookmarksManager();
+ const QString bookmarksFile = KStandardDirs::locateLocal("data", QString::fromLatin1("konqueror/bookmarks.xml"));
+
+ if (!QFile::exists(bookmarksFile))
+ {
+ kDebug() << "copying of defaultbookmarks.xbel ...";
+
+ QString bookmarksDefaultPath = KStandardDirs::locate("appdata" , "defaultbookmarks.xbel");
+ KBookmarkManager *tempManager = KBookmarkManager::managerForExternalFile(bookmarksDefaultPath);
+
+ copyBookmarkGroup(tempManager->root(), rootGroup());
+ m_manager->emitChanged();
+ delete tempManager;
+ }
+
+ connect(m_manager, SIGNAL(changed(QString, QString)), this, SLOT(slotBookmarksChanged()));
+
+ // setup menu
+ m_owner = new BookmarkOwner(m_manager, this);
+ connect(m_owner, SIGNAL(openUrl(KUrl, Rekonq::OpenType)), this, SIGNAL(openUrl(KUrl, Rekonq::OpenType)));
+
+ // bookmarks loading
+ connect(this, SIGNAL(openUrl(KUrl, Rekonq::OpenType)), rApp, SLOT(loadUrl(KUrl, Rekonq::OpenType)));
+}
+
+
+BookmarkManager::~BookmarkManager()
+{
+ delete m_manager;
+}
+
+
+void BookmarkManager::registerBookmarkBar(BookmarkToolBar *toolbar)
+{
+ if (m_bookmarkToolBars.contains(toolbar))
+ return;
+
+ m_bookmarkToolBars.append(toolbar);
+}
+
+
+void BookmarkManager::removeBookmarkBar(BookmarkToolBar *toolbar)
+{
+ m_bookmarkToolBars.removeOne(toolbar);
+}
+
+
+QAction* BookmarkManager::actionByName(const QString &name)
+{
+ QAction *action = m_actionCollection->action(name);
+ if (action)
+ return action;
+ return new QAction(this);
+}
+
+
+KBookmarkGroup BookmarkManager::rootGroup()
+{
+ return m_manager->root();
+}
+
+
+QList<KBookmark> BookmarkManager::find(const QString &text)
+{
+ QList<KBookmark> list;
+
+ KBookmarkGroup root = rootGroup();
+ if (!root.isNull())
+ for (KBookmark bookmark = root.first(); !bookmark.isNull(); bookmark = root.next(bookmark))
+ find(&list, bookmark, text);
+
+ return list;
+}
+
+
+KBookmark BookmarkManager::bookmarkForUrl(const KUrl &url)
+{
+ KBookmarkGroup root = rootGroup();
+ if (root.isNull())
+ return KBookmark();
+
+ return bookmarkForUrl(root, url);
+}
+
+
+void BookmarkManager::slotBookmarksChanged()
+{
+ Q_FOREACH(BookmarkToolBar * bookmarkToolBar, m_bookmarkToolBars)
+ {
+ if (bookmarkToolBar)
+ {
+ bookmarkToolBar->toolBar()->clear();
+ fillBookmarkBar(bookmarkToolBar);
+ }
+ }
+
+ // NOTE with this signal, we should (eventual) update about:bookmarks page...
+ emit bookmarksUpdated();
+}
+
+
+void BookmarkManager::fillBookmarkBar(BookmarkToolBar *toolBar)
+{
+ KBookmarkGroup root = m_manager->toolbar();
+ if (root.isNull())
+ return;
+
+ for (KBookmark bookmark = root.first(); !bookmark.isNull(); bookmark = root.next(bookmark))
+ {
+ if (bookmark.isGroup())
+ {
+ KBookmarkActionMenu *menuAction = new KBookmarkActionMenu(bookmark.toGroup(), this);
+ menuAction->setDelayed(false);
+ BookmarkMenu *bMenu = new BookmarkMenu(m_manager, m_owner, menuAction->menu(), bookmark.address());
+ bMenu->setParent(menuAction->menu());
+
+ connect(menuAction->menu(), SIGNAL(aboutToShow()), toolBar, SLOT(menuDisplayed()));
+ connect(menuAction->menu(), SIGNAL(aboutToHide()), toolBar, SLOT(menuHidden()));
+
+ toolBar->toolBar()->addAction(menuAction);
+ toolBar->toolBar()->widgetForAction(menuAction)->installEventFilter(toolBar);
+ }
+ else if (bookmark.isSeparator())
+ {
+ toolBar->toolBar()->addSeparator();
+ }
+ else
+ {
+ KBookmarkAction *action = new KBookmarkAction(bookmark, m_owner, this);
+// FIXME action->setIcon(rApp->iconManager()->iconForUrl(KUrl(bookmark.url())));
+ connect(action, SIGNAL(hovered()), toolBar, SLOT(actionHovered()));
+ toolBar->toolBar()->addAction(action);
+ toolBar->toolBar()->widgetForAction(action)->installEventFilter(toolBar);
+ }
+ }
+}
+
+
+void BookmarkManager::find(QList<KBookmark> *list, const KBookmark &bookmark, const QString &text)
+{
+ if (bookmark.isGroup())
+ {
+ KBookmarkGroup group = bookmark.toGroup();
+ for (KBookmark bm = group.first(); !bm.isNull(); bm = group.next(bm))
+ find(list, bm, text);
+ }
+ else
+ {
+ QStringList words = text.split(' ');
+ bool matches = true;
+ Q_FOREACH(const QString & word, words)
+ {
+ if (!bookmark.url().url().contains(word, Qt::CaseInsensitive)
+ && !bookmark.fullText().contains(word, Qt::CaseInsensitive))
+ {
+ matches = false;
+ break;
+ }
+ }
+ if (matches)
+ *list << bookmark;
+ }
+}
+
+
+KBookmark BookmarkManager::bookmarkForUrl(const KBookmark &bookmark, const KUrl &url)
+{
+ KBookmark found;
+
+ if (bookmark.isGroup())
+ {
+ KBookmarkGroup group = bookmark.toGroup();
+ KBookmark bookmark = group.first();
+
+ while (!bookmark.isNull() && found.isNull())
+ {
+ found = bookmarkForUrl(bookmark, url);
+ bookmark = group.next(bookmark);
+ }
+ }
+ else if (!bookmark.isSeparator() && bookmark.url() == url)
+ {
+ found = bookmark;
+ }
+
+ return found;
+}
+
+
+void BookmarkManager::copyBookmarkGroup(const KBookmarkGroup &groupToCopy, KBookmarkGroup destGroup)
+{
+ KBookmark bookmark = groupToCopy.first();
+ while (!bookmark.isNull())
+ {
+ if (bookmark.isGroup())
+ {
+ KBookmarkGroup newDestGroup = destGroup.createNewFolder(bookmark.text());
+ if (bookmark.toGroup().isToolbarGroup())
+ {
+ newDestGroup.internalElement().setAttribute("toolbar", "yes");
+ newDestGroup.setIcon("bookmark-toolbar");
+ }
+ copyBookmarkGroup(bookmark.toGroup(), newDestGroup);
+ }
+ else if (bookmark.isSeparator())
+ {
+ destGroup.createNewSeparator();
+ }
+ else
+ {
+ destGroup.addBookmark(bookmark.text(), bookmark.url());
+ }
+ bookmark = groupToCopy.next(bookmark);
+ }
+}
+
+
+void BookmarkManager::slotEditBookmarks()
+{
+ m_manager->slotEditBookmarks();
+}
+
+
+KBookmark BookmarkManager::findByAddress(const QString &address)
+{
+ return m_manager->findByAddress(address);
+}
+
+
+void BookmarkManager::openFolderinTabs(const KBookmarkGroup &bm)
+{
+ m_owner->openFolderinTabs(bm);
+}
+
+
+void BookmarkManager::emitChanged()
+{
+ m_manager->emitChanged();
+}
diff --git a/src/bookmarks/bookmarkmanager.h b/src/bookmarks/bookmarkmanager.h
new file mode 100644
index 00000000..d842c271
--- /dev/null
+++ b/src/bookmarks/bookmarkmanager.h
@@ -0,0 +1,170 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2008-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com>
+* 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
+* 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 BOOKMARK_MANAGER_H
+#define BOOKMARK_MANAGER_H
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// KDE Includes
+#include <KBookmark>
+
+// Qt Includes
+#include <QObject>
+#include <QWeakPointer>
+
+// Forward Declarations
+class BookmarkToolBar;
+class BookmarkOwner;
+class BookmarkMenu;
+
+class KAction;
+class KActionCollection;
+class KBookmarkGroup;
+class KBookmarkManager;
+class KUrl;
+
+class QAction;
+
+
+/**
+ * This class represent the interface to rekonq bookmarks system.
+ * All rekonq needs (Bookmarks Menu, Bookmarks Toolbar) is provided
+ * from this class.
+ * So it implements code to have each one.
+ */
+class BookmarkManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Entry point.
+ * Access to BookmarkManager class by using
+ * BookmarkManager::self()->thePublicMethodYouNeed()
+ */
+ static BookmarkManager *self();
+
+ ~BookmarkManager();
+
+ /**
+ * @short set the Bookmarks Toolbar Action
+ */
+ void registerBookmarkBar(BookmarkToolBar *toolbar);
+ void removeBookmarkBar(BookmarkToolBar *toolbar);
+
+ /**
+ * @short Get action by name
+ * This method returns poiner bookmark action of given name.
+ * @pre m_actionCollection != NULL
+ * @param name Name of action you want to get
+ * @return It returns actions if one exists or empty object
+ */
+ QAction* actionByName(const QString &name);
+
+ /**
+ * returns Bookmark Manager root group
+ *
+ * @return the root bookmark group
+ */
+ KBookmarkGroup rootGroup();
+
+ inline KBookmarkManager* manager()
+ {
+ return m_manager;
+ }
+
+ inline BookmarkOwner* owner()
+ {
+ return m_owner;
+ }
+
+ QList<KBookmark> find(const QString &text);
+
+ KBookmark bookmarkForUrl(const KUrl &url);
+
+ KBookmark findByAddress(const QString &);
+
+ void openFolderinTabs(const KBookmarkGroup &bm);
+
+ void emitChanged();
+
+ static inline QString bookmark_mime_type()
+ {
+ return QL1S("application/x-rekonq-bookmark");
+ }
+
+private:
+ /**
+ * @short Class constructor.
+ * Connect BookmarksProvider with bookmarks source
+ * (actually konqueror's bookmarks).
+ * @param parent The WebWindow to provide bookmarks objects.
+ */
+ BookmarkManager(QObject *parent = 0);
+
+public Q_SLOTS:
+ /**
+ * @short Waits for signal that the group with the address has been modified by the caller.
+ * Waits for signal that the group (or any of its children) with the address
+ * @p groupAddress (e.g. "/4/5") has been modified by the caller @p caller.
+ * @param groupAddress bookmark group address
+ * @param caller caller that modified the bookmarks
+ * @see KBookmarkManager::changed
+ */
+ void slotBookmarksChanged();
+ void fillBookmarkBar(BookmarkToolBar *toolBar);
+
+ void slotEditBookmarks();
+
+Q_SIGNALS:
+ /**
+ * @short This signal is emitted when an url has to be loaded
+ */
+ void openUrl(const KUrl &, const Rekonq::OpenType &);
+
+ void bookmarksUpdated();
+
+private:
+ void find(QList<KBookmark> *list, const KBookmark &bookmark, const QString &text);
+ KBookmark bookmarkForUrl(const KBookmark &bookmark, const KUrl &url);
+ void copyBookmarkGroup(const KBookmarkGroup &groupToCopy, KBookmarkGroup destGroup);
+
+ KBookmarkManager *m_manager;
+ BookmarkOwner *m_owner;
+ KActionCollection *m_actionCollection;
+ QList<BookmarkToolBar *> m_bookmarkToolBars;
+
+ static QWeakPointer<BookmarkManager> s_bookmarkManager;
+};
+
+
+#endif // BOOKMARK_MANAGER_H
diff --git a/src/bookmarks/bookmarkowner.cpp b/src/bookmarks/bookmarkowner.cpp
new file mode 100644
index 00000000..1c117824
--- /dev/null
+++ b/src/bookmarks/bookmarkowner.cpp
@@ -0,0 +1,428 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2008-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com>
+* 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
+* 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 "bookmarkowner.h"
+#include "bookmarkowner.moc"
+
+// Local Includes
+#include "bookmarkmanager.h"
+
+#include "application.h"
+#include "tabwindow.h"
+#include "webwindow.h"
+
+// KDE Includes
+#include <KBookmarkDialog>
+#include <KLocalizedString>
+#include <KMessageBox>
+
+// Qt Includes
+#include <QClipboard>
+
+// Nepomuk config include
+#include "config-nepomuk.h"
+
+#ifdef HAVE_NEPOMUK
+// Local Nepomuk Includes
+#include "resourcelinkdialog.h"
+
+// Nepomuk Includes
+#include <Nepomuk/Resource>
+#include <Nepomuk/Vocabulary/NFO>
+#endif
+
+
+BookmarkOwner::BookmarkOwner(KBookmarkManager *manager, QObject *parent)
+ : QObject(parent)
+ , KBookmarkOwner()
+ , m_manager(manager)
+{
+}
+
+
+KAction* BookmarkOwner::createAction(const KBookmark &bookmark, const BookmarkAction &bmAction)
+{
+ switch (bmAction)
+ {
+ case OPEN:
+ return createAction(i18n("Open"), "tab-new",
+ i18n("Open bookmark in current tab"), SLOT(openBookmark(KBookmark)), bookmark);
+ case OPEN_IN_TAB:
+ return createAction(i18n("Open in New Tab"), "tab-new",
+ i18n("Open bookmark in new tab"), SLOT(openBookmarkInNewTab(KBookmark)), bookmark);
+ case OPEN_IN_WINDOW:
+ return createAction(i18n("Open in New Window"), "window-new",
+ i18n("Open bookmark in new window"), SLOT(openBookmarkInNewWindow(KBookmark)), bookmark);
+ case OPEN_FOLDER:
+ return createAction(i18n("Open Folder in Tabs"), "tab-new",
+ i18n("Open all the bookmarks in folder in tabs"), SLOT(openBookmarkFolder(KBookmark)), bookmark);
+ case BOOKMARK_PAGE:
+ return createAction(i18n("Add Bookmark"), "bookmark-new",
+ i18n("Bookmark current page"), SLOT(bookmarkCurrentPage(KBookmark)), bookmark);
+ case NEW_FOLDER:
+ return createAction(i18n("New Folder"), "folder-new",
+ i18n("Create a new bookmark folder"), SLOT(newBookmarkFolder(KBookmark)), bookmark);
+ case NEW_SEPARATOR:
+ return createAction(i18n("New Separator"), "edit-clear",
+ i18n("Create a new bookmark separator"), SLOT(newSeparator(KBookmark)), bookmark);
+ case COPY:
+ return createAction(i18n("Copy Link"), "edit-copy",
+ i18n("Copy the bookmark's link address"), SLOT(copyLink(KBookmark)), bookmark);
+ case EDIT:
+ return createAction(i18n("Edit"), "configure",
+ i18n("Edit the bookmark"), SLOT(editBookmark(KBookmark)), bookmark);
+#ifdef HAVE_NEPOMUK
+ case FANCYBOOKMARK:
+ return createAction(i18n("Fancy Bookmark"), "nepomuk",
+ i18n("Link Nepomuk resources"), SLOT(fancyBookmark(KBookmark)), bookmark);
+#endif
+ case DELETE:
+ return createAction(i18n("Delete"), "edit-delete",
+ i18n("Delete the bookmark"), SLOT(deleteBookmark(KBookmark)), bookmark);
+ case SET_TOOLBAR_FOLDER:
+ return createAction(i18n("Set as toolbar folder"), "bookmark-toolbar",
+ "", SLOT(setToolBarFolder(KBookmark)), bookmark);
+ case UNSET_TOOLBAR_FOLDER:
+ return createAction(i18n("Unset this folder as the toolbar folder"), "bookmark-toolbar",
+ "", SLOT(unsetToolBarFolder()), bookmark);
+ default:
+ ASSERT_NOT_REACHED(unknown BookmarkAction);
+ return 0;
+ }
+}
+
+
+QString BookmarkOwner::currentTitle() const
+{
+ return rApp->tabWindow()->currentWebWindow()->title();
+}
+
+
+QString BookmarkOwner::currentUrl() const
+{
+ return rApp->tabWindow()->currentWebWindow()->url().toString();
+}
+
+
+QList< QPair<QString, QString> > BookmarkOwner::currentBookmarkList() const
+{
+ QList< QPair<QString, QString> > bkList;
+ TabWindow *view = rApp->tabWindow();
+ int tabNumber = view->count();
+
+ for (int i = 0; i < tabNumber; ++i)
+ {
+ QPair<QString, QString> item;
+ item.first = view->webWindow(i)->title();
+ item.second = view->webWindow(i)->url().toString();
+ bkList << item;
+ }
+
+ return bkList;
+}
+
+
+void BookmarkOwner::openBookmark(const KBookmark &bookmark,
+ Qt::MouseButtons mouseButtons,
+ Qt::KeyboardModifiers keyboardModifiers)
+{
+ if (keyboardModifiers & Qt::ControlModifier || mouseButtons & Qt::MidButton)
+ openBookmarkInNewTab(bookmark);
+ else
+ openBookmark(bookmark);
+}
+
+
+void BookmarkOwner::openFolderinTabs(const KBookmarkGroup &bkGoup)
+{
+ QList<KUrl> urlList = bkGoup.groupUrlList();
+
+ if (urlList.length() > 8)
+ {
+ if (KMessageBox::warningContinueCancel(
+ rApp->tabWindow(),
+ i18ncp("%1=Number of tabs. Value is always >=8",
+ "You are about to open %1 tabs.\nAre you sure?",
+ "You are about to open %1 tabs.\nAre you sure?", urlList.length()))
+ != KMessageBox::Continue
+ )
+ return;
+ }
+
+ Q_FOREACH(const KUrl & url, urlList)
+ {
+ emit openUrl(url, Rekonq::NewFocusedTab);
+ }
+}
+
+
+void BookmarkOwner::openBookmark(const KBookmark &bookmark)
+{
+ emit openUrl(bookmark.url(), Rekonq::CurrentTab);
+}
+
+
+void BookmarkOwner::openBookmarkInNewTab(const KBookmark &bookmark)
+{
+ emit openUrl(bookmark.url(), Rekonq::NewTab);
+}
+
+
+void BookmarkOwner::openBookmarkInNewWindow(const KBookmark &bookmark)
+{
+ emit openUrl(bookmark.url(), Rekonq::NewWindow);
+}
+
+
+void BookmarkOwner::openBookmarkFolder(const KBookmark &bookmark)
+{
+ Q_ASSERT(bookmark.isGroup());
+ openFolderinTabs(bookmark.toGroup());
+}
+
+
+KBookmark BookmarkOwner::bookmarkCurrentPage(const KBookmark &bookmark)
+{
+ KBookmarkGroup parent;
+
+ if (!bookmark.isNull())
+ {
+ if (bookmark.isGroup())
+ parent = bookmark.toGroup();
+ else
+ parent = bookmark.parentGroup();
+ }
+ else
+ {
+ parent = BookmarkManager::self()->rootGroup();
+#ifdef HAVE_NEPOMUK
+ Nepomuk::Resource nfoResource;
+ nfoResource = ((QUrl)currentUrl());
+ nfoResource.addType(Nepomuk::Vocabulary::NFO::Website());
+ nfoResource.setLabel(currentTitle());
+#endif
+ }
+
+ KBookmark newBk = parent.addBookmark(currentTitle(), KUrl(currentUrl()));
+ if (!bookmark.isNull())
+ parent.moveBookmark(newBk, bookmark);
+
+ m_manager->emitChanged(parent);
+ return newBk;
+}
+
+
+KBookmarkGroup BookmarkOwner::newBookmarkFolder(const KBookmark &bookmark)
+{
+ KBookmarkGroup newBk;
+ KBookmarkDialog *dialog = bookmarkDialog(m_manager, 0);
+ QString folderName = i18n("New folder");
+
+ if (!bookmark.isNull())
+ {
+ if (bookmark.isGroup())
+ {
+ newBk = dialog->createNewFolder(folderName, bookmark);
+ }
+ else
+ {
+ newBk = dialog->createNewFolder(folderName, bookmark.parentGroup());
+ if (!newBk.isNull())
+ {
+ KBookmarkGroup parent = newBk.parentGroup();
+ parent.moveBookmark(newBk, bookmark);
+ m_manager->emitChanged(parent);
+ }
+ }
+ }
+ else
+ {
+ newBk = dialog->createNewFolder(folderName);
+ }
+
+ delete dialog;
+ return newBk;
+}
+
+
+KBookmark BookmarkOwner::newSeparator(const KBookmark &bookmark)
+{
+ KBookmark newBk;
+
+ if (!bookmark.isNull())
+ {
+ if (bookmark.isGroup())
+ {
+ newBk = bookmark.toGroup().createNewSeparator();
+ }
+ else
+ {
+ newBk = bookmark.parentGroup().createNewSeparator();
+ newBk.parentGroup().moveBookmark(newBk, bookmark);
+ }
+ }
+ else
+ {
+ newBk = BookmarkManager::self()->rootGroup().createNewSeparator();
+ }
+
+ newBk.setIcon("edit-clear");
+
+ m_manager->emitChanged(newBk.parentGroup());
+ return newBk;
+}
+
+
+void BookmarkOwner::copyLink(const KBookmark &bookmark)
+{
+ if (bookmark.isNull())
+ return;
+
+ QApplication::clipboard()->setText(bookmark.url().url());
+}
+
+
+void BookmarkOwner::editBookmark(KBookmark bookmark)
+{
+ if (bookmark.isNull())
+ return;
+
+ KBookmarkDialog *dialog = bookmarkDialog(m_manager, 0);
+ dialog->editBookmark(bookmark);
+
+ delete dialog;
+}
+
+
+#ifdef HAVE_NEPOMUK
+void BookmarkOwner::fancyBookmark(KBookmark bookmark)
+{
+ Nepomuk::Resource nfoResource = (KUrl)bookmark.url();
+ Nepomuk::ResourceLinkDialog r(nfoResource);
+ r.exec();
+
+}
+#endif
+
+bool BookmarkOwner::deleteBookmark(const KBookmark &bookmark)
+{
+ if (bookmark.isNull())
+ return false;
+
+ KBookmarkGroup bmg = bookmark.parentGroup();
+ QString dialogCaption, dialogText;
+
+ if (bookmark.isGroup())
+ {
+ dialogCaption = i18n("Bookmark Folder Deletion");
+ dialogText = i18n("Are you sure you wish to remove the bookmark folder\n\"%1\"?", bookmark.fullText());
+ }
+ else if (bookmark.isSeparator())
+ {
+ dialogCaption = i18n("Separator Deletion");
+ dialogText = i18n("Are you sure you wish to remove this separator?");
+ }
+ else
+ {
+ dialogCaption = i18n("Bookmark Deletion");
+ dialogText = i18n("Are you sure you wish to remove the bookmark\n\"%1\"?", bookmark.fullText());
+ }
+
+ if (KMessageBox::warningContinueCancel(
+ 0,
+ dialogText,
+ dialogCaption,
+ KStandardGuiItem::del(),
+ KStandardGuiItem::cancel(),
+ "bookmarkDeletition_askAgain")
+ != KMessageBox::Continue
+ )
+ return false;
+
+ bmg.deleteBookmark(bookmark);
+#ifdef HAVE_NEPOMUK
+ Nepomuk::Resource nfoResource(bookmark.url());
+ nfoResource.remove();
+#endif
+ m_manager->emitChanged(bmg);
+ return true;
+}
+
+
+void BookmarkOwner::setToolBarFolder(KBookmark bookmark)
+{
+ if (!bookmark.isGroup())
+ return;
+
+ unsetToolBarFolder();
+ bookmark.internalElement().setAttribute("toolbar", "yes");
+ bookmark.setIcon("bookmark-toolbar");
+
+ m_manager->emitChanged();
+}
+
+
+void BookmarkOwner::unsetToolBarFolder()
+{
+ KBookmarkGroup toolbar = m_manager->toolbar();
+ if (!toolbar.isNull())
+ {
+ toolbar.internalElement().setAttribute("toolbar", "no");
+ toolbar.setIcon("");
+ }
+ m_manager->emitChanged();
+}
+
+
+KAction* BookmarkOwner::createAction(const QString &text, const QString &icon,
+ const QString &help, const char *slot,
+ const KBookmark &bookmark)
+{
+ CustomBookmarkAction *act = new CustomBookmarkAction(bookmark, KIcon(icon), text, this);
+ act->setHelpText(help);
+ connect(act, SIGNAL(triggered(KBookmark)), this, slot);
+ return act;
+}
+
+
+// -------------------------------------------------------------------------------------------------
+
+
+CustomBookmarkAction::CustomBookmarkAction(const KBookmark &bookmark, const KIcon &icon, const QString &text, QObject *parent)
+ : KAction(icon, text, parent)
+ , m_bookmark(bookmark)
+{
+ connect(this, SIGNAL(triggered()), this, SLOT(onActionTriggered()));
+}
+
+void CustomBookmarkAction::onActionTriggered()
+{
+ emit triggered(m_bookmark);
+}
diff --git a/src/bookmarks/bookmarkowner.h b/src/bookmarks/bookmarkowner.h
new file mode 100644
index 00000000..f0b238b9
--- /dev/null
+++ b/src/bookmarks/bookmarkowner.h
@@ -0,0 +1,159 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2008-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com>
+* 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
+* 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 BOOKMARKOWNER_H
+#define BOOKMARKOWNER_H
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// Nepomuk config include
+#include "config-nepomuk.h"
+
+// KDE Includes
+#include <KAction>
+#include <KBookmarkOwner>
+
+
+/**
+ * This class allows to manage bookmarks as actions.
+ */
+class REKONQ_TESTS_EXPORT BookmarkOwner : public QObject, public KBookmarkOwner
+{
+ Q_OBJECT
+
+public:
+ explicit BookmarkOwner(KBookmarkManager *manager, QObject *parent = 0);
+
+ enum BookmarkAction
+ {
+ OPEN = 0,
+ OPEN_IN_TAB,
+ OPEN_IN_WINDOW,
+ OPEN_FOLDER,
+ BOOKMARK_PAGE,
+ NEW_FOLDER,
+ NEW_SEPARATOR,
+ COPY,
+ EDIT,
+#ifdef HAVE_NEPOMUK
+ FANCYBOOKMARK,
+#endif
+ DELETE,
+ NUM_ACTIONS,
+ SET_TOOLBAR_FOLDER,
+ UNSET_TOOLBAR_FOLDER
+ };
+
+ /**
+ * @return A new action for the given bookmark.
+ */
+ KAction* createAction(const KBookmark &bookmark, const BookmarkAction &bmAction);
+
+ // @{
+ /**
+ * Functions to get current information.
+ */
+ virtual QString currentTitle() const;
+ virtual QString currentUrl() const;
+ virtual QList< QPair<QString, QString> > currentBookmarkList() const;
+ // @}
+
+ virtual bool supportsTabs() const
+ {
+ return true;
+ }
+
+ // @{
+ /**
+ * This functions emit signals that open the selected URLs
+ */
+ virtual void openBookmark(const KBookmark &bookmark,
+ Qt::MouseButtons mouseButtons,
+ Qt::KeyboardModifiers keyboardModifiers);
+ virtual void openFolderinTabs(const KBookmarkGroup &bkGoup);
+ // @}
+
+public Q_SLOTS:
+ void openBookmark(const KBookmark &bookmark);
+ void openBookmarkInNewTab(const KBookmark &bookmark);
+ void openBookmarkInNewWindow(const KBookmark &bookmark);
+ void openBookmarkFolder(const KBookmark &bookmark);
+
+ KBookmark bookmarkCurrentPage(const KBookmark &bookmark = KBookmark());
+ KBookmarkGroup newBookmarkFolder(const KBookmark &bookmark = KBookmark());
+ KBookmark newSeparator(const KBookmark &bookmark = KBookmark());
+
+ void copyLink(const KBookmark &bookmark);
+ void editBookmark(KBookmark bookmark);
+#ifdef HAVE_NEPOMUK
+ void fancyBookmark(KBookmark bookmark);
+#endif
+ bool deleteBookmark(const KBookmark &bookmark);
+ void setToolBarFolder(KBookmark bookmark = KBookmark());
+ void unsetToolBarFolder();
+
+Q_SIGNALS:
+ /**
+ * This signal is emitted when an url has to be loaded
+ * @param url the URL to load
+ */
+ void openUrl(const KUrl &, const Rekonq::OpenType &);
+
+private:
+ KAction* createAction(const QString &text, const QString &icon,
+ const QString &help, const char *slot,
+ const KBookmark &bookmark);
+
+ KBookmarkManager *m_manager;
+};
+
+
+// -----------------------------------------------------------------------------------------------
+
+
+class CustomBookmarkAction : public KAction
+{
+ Q_OBJECT
+
+public:
+ CustomBookmarkAction(const KBookmark &bookmark, const KIcon &icon, const QString &text, QObject *parent);
+
+Q_SIGNALS:
+ void triggered(const KBookmark &);
+
+private Q_SLOTS:
+ void onActionTriggered();
+
+private:
+ KBookmark m_bookmark;
+};
+
+#endif // BOOKMARKOWNER_H
diff --git a/src/bookmarks/bookmarkscontextmenu.cpp b/src/bookmarks/bookmarkscontextmenu.cpp
new file mode 100644
index 00000000..d0907660
--- /dev/null
+++ b/src/bookmarks/bookmarkscontextmenu.cpp
@@ -0,0 +1,162 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com>
+* Copyright (c) 2011-2012 by Phaneendra Hegde <pnh.pes@gmail.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 "bookmarkscontextmenu.h"
+
+// Nepomuk config include
+#include "config-nepomuk.h"
+
+// Local Includes
+#include "bookmarkowner.h"
+#include "bookmarkmanager.h"
+
+// KDE Includes
+#include <KBookmarkManager>
+
+
+BookmarksContextMenu::BookmarksContextMenu(const KBookmark &bookmark,
+ KBookmarkManager *manager,
+ BookmarkOwner *owner,
+ bool nullForced,
+ QWidget *parent)
+ : KBookmarkContextMenu(bookmark, manager, owner, parent)
+ , m_bmOwner(owner)
+ , m_nullForced(nullForced)
+{
+}
+
+
+void BookmarksContextMenu::addBookmarkActions()
+{
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::OPEN_IN_TAB));
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::OPEN_IN_WINDOW));
+
+ addSeparator();
+
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::BOOKMARK_PAGE));
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_FOLDER));
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_SEPARATOR));
+
+ addSeparator();
+
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::COPY));
+
+ addSeparator();
+
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::EDIT));
+#ifdef HAVE_NEPOMUK
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::FANCYBOOKMARK));
+#endif
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::DELETE));
+}
+
+
+void BookmarksContextMenu::addFolderActions()
+{
+ KBookmarkGroup group = bookmark().toGroup();
+
+ if (bookmark().internalElement().attributeNode("toolbar").value() == "yes")
+ {
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::UNSET_TOOLBAR_FOLDER));
+ }
+ else
+ {
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::SET_TOOLBAR_FOLDER));
+ }
+
+ if (!group.first().isNull())
+ {
+ KBookmark child = group.first();
+
+ while (child.isGroup() || child.isSeparator())
+ {
+ child = group.next(child);
+ }
+
+ if (!child.isNull())
+ {
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::OPEN_FOLDER));
+ addSeparator();
+ }
+ }
+
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::BOOKMARK_PAGE));
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_FOLDER));
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_SEPARATOR));
+
+ addSeparator();
+
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::EDIT));
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::DELETE));
+}
+
+
+void BookmarksContextMenu::addSeparatorActions()
+{
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::BOOKMARK_PAGE));
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_FOLDER));
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_SEPARATOR));
+
+ addSeparator();
+
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::DELETE));
+}
+
+
+void BookmarksContextMenu::addNullActions()
+{
+ KBookmarkManager *mngr = manager();
+ if (mngr->toolbar().hasParent())
+ {
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::UNSET_TOOLBAR_FOLDER));
+ }
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::BOOKMARK_PAGE));
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_FOLDER));
+ addAction(m_bmOwner->createAction(bookmark(), BookmarkOwner::NEW_SEPARATOR));
+}
+
+
+void BookmarksContextMenu::addActions()
+{
+ if (bookmark().isNull() || m_nullForced)
+ {
+ addNullActions();
+ }
+ else if (bookmark().isSeparator())
+ {
+ addSeparatorActions();
+ }
+ else if (bookmark().isGroup())
+ {
+ addFolderActions();
+ }
+ else
+ {
+ addBookmarkActions();
+ }
+}
diff --git a/src/bookmarks/bookmarkscontextmenu.h b/src/bookmarks/bookmarkscontextmenu.h
new file mode 100644
index 00000000..c927f3a6
--- /dev/null
+++ b/src/bookmarks/bookmarkscontextmenu.h
@@ -0,0 +1,57 @@
+/* ============================================================
+*
+* 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 BOOKMARKS_CONTEXT_MENU_H
+#define BOOKMARKS_CONTEXT_MENU_H
+
+// KDE Includes
+#include <KBookmarkMenu>
+
+// Forward Declarations
+class BookmarkOwner;
+
+
+class BookmarksContextMenu : public KBookmarkContextMenu
+{
+public:
+ BookmarksContextMenu(const KBookmark &bookmark,
+ KBookmarkManager *manager,
+ BookmarkOwner *owner,
+ bool nullForced = false,
+ QWidget *parent = 0);
+ virtual void addActions();
+
+private:
+ void addFolderActions();
+ void addBookmarkActions();
+ void addSeparatorActions();
+ void addNullActions();
+
+ BookmarkOwner *m_bmOwner;
+ bool m_nullForced;
+};
+
+#endif // BOOKMARKS_CONTEXT_MENU_H
diff --git a/src/bookmarks/bookmarkstoolbar.cpp b/src/bookmarks/bookmarkstoolbar.cpp
new file mode 100644
index 00000000..cb3fe382
--- /dev/null
+++ b/src/bookmarks/bookmarkstoolbar.cpp
@@ -0,0 +1,609 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2008-2012 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
+* 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 "bookmarkstoolbar.h"
+#include "bookmarkstoolbar.moc"
+
+// Local Includes
+#include "bookmarkscontextmenu.h"
+#include "bookmarkmanager.h"
+#include "bookmarkowner.h"
+
+#include "webwindow.h"
+
+// Qt Includes
+#include <QFrame>
+#include <QActionEvent>
+#include <QApplication>
+
+
+BookmarkMenu::BookmarkMenu(KBookmarkManager *manager,
+ KBookmarkOwner *owner,
+ KMenu *menu,
+ KActionCollection* actionCollection)
+ : KBookmarkMenu(manager, owner, menu, actionCollection)
+{
+}
+
+
+BookmarkMenu::BookmarkMenu(KBookmarkManager *manager,
+ KBookmarkOwner *owner,
+ KMenu *parentMenu,
+ const QString &parentAddress)
+ : KBookmarkMenu(manager, owner, parentMenu, parentAddress)
+{
+}
+
+
+BookmarkMenu::~BookmarkMenu()
+{
+ kDebug() << "Deleting BookmarkMenu.. See http://svn.reviewboard.kde.org/r/5606/ about.";
+}
+
+
+KMenu * BookmarkMenu::contextMenu(QAction *act)
+{
+ KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(act);
+ if (!action)
+ return 0;
+ return new BookmarksContextMenu(action->bookmark(), manager(), static_cast<BookmarkOwner*>(owner()));
+}
+
+
+QAction * BookmarkMenu::actionForBookmark(const KBookmark &bookmark)
+{
+ if (bookmark.isGroup())
+ {
+ KBookmarkActionMenu *actionMenu = new KBookmarkActionMenu(bookmark, this);
+ BookmarkMenu *menu = new BookmarkMenu(manager(), owner(), actionMenu->menu(), bookmark.address());
+ // An hack to get rid of bug 219274
+ connect(actionMenu, SIGNAL(hovered()), menu, SLOT(slotAboutToShow()));
+ return actionMenu;
+ }
+ else if (bookmark.isSeparator())
+ {
+ return KBookmarkMenu::actionForBookmark(bookmark);
+ }
+ else
+ {
+ KBookmarkAction *action = new KBookmarkAction(bookmark, owner(), this);
+// FIXME action->setIcon(rApp->iconManager()->iconForUrl(KUrl(bookmark.url())));
+ connect(action, SIGNAL(hovered()), this, SLOT(actionHovered()));
+ return action;
+ }
+}
+
+
+void BookmarkMenu::refill()
+{
+ clear();
+ fillBookmarks();
+
+ if (parentMenu()->actions().count() > 0)
+ parentMenu()->addSeparator();
+
+ if (isRoot())
+ {
+ addAddBookmarksList();
+ addEditBookmarks();
+ }
+ else
+ {
+ addOpenFolderInTabs();
+ addAddBookmarksList();
+ }
+}
+
+
+void BookmarkMenu::addOpenFolderInTabs()
+{
+ 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())
+ {
+ parentMenu()->addAction(BookmarkManager::self()->owner()->createAction(group, BookmarkOwner::OPEN_FOLDER));
+ }
+ }
+}
+
+
+// ------------------------------------------------------------------------------------------------------
+
+
+BookmarkToolBar::BookmarkToolBar(KToolBar *toolBar, QObject *parent)
+ : QObject(parent)
+ , m_toolBar(toolBar)
+ , m_currentMenu(0)
+ , m_dragAction(0)
+ , m_dropAction(0)
+ , m_checkedAction(0)
+ , m_filled(false)
+{
+ toolBar->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(toolBar, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenu(QPoint)));
+ connect(BookmarkManager::self()->manager(), SIGNAL(changed(QString, QString)), this, SLOT(hideMenu()));
+ toolBar->setAcceptDrops(true);
+ toolBar->installEventFilter(this);
+ toolBar->setShortcutEnabled(false);
+
+ if (toolBar->isVisible())
+ {
+ BookmarkManager::self()->fillBookmarkBar(this);
+ m_filled = true;
+ }
+}
+
+
+KToolBar* BookmarkToolBar::toolBar()
+{
+ return m_toolBar;
+}
+
+
+void BookmarkToolBar::contextMenu(const QPoint &point)
+{
+ KBookmarkActionInterface *action = dynamic_cast<KBookmarkActionInterface*>(toolBar()->actionAt(point));
+ KBookmark bookmark = BookmarkManager::self()->manager()->toolbar();
+ bool nullAction = true;
+ if (action)
+ {
+ bookmark = action->bookmark();
+ nullAction = false;
+ }
+
+ BookmarksContextMenu menu(bookmark,
+ BookmarkManager::self()->manager(),
+ BookmarkManager::self()->owner(),
+ nullAction);
+ menu.exec(toolBar()->mapToGlobal(point));
+}
+
+
+void BookmarkToolBar::menuDisplayed()
+{
+ qApp->installEventFilter(this);
+ m_currentMenu = qobject_cast<KMenu*>(sender());
+}
+
+
+void BookmarkToolBar::menuHidden()
+{
+ qApp->removeEventFilter(this);
+ m_currentMenu = 0;
+}
+
+
+void BookmarkToolBar::hideMenu()
+{
+ if (m_currentMenu)
+ m_currentMenu->hide();
+}
+
+
+bool BookmarkToolBar::eventFilter(QObject *watched, QEvent *event)
+{
+ if (m_currentMenu && m_currentMenu->isVisible()
+ && !m_currentMenu->rect().contains(m_currentMenu->mapFromGlobal(QCursor::pos())))
+ {
+ // To switch root folders as in a menubar
+
+ KBookmarkActionMenu* act = dynamic_cast<KBookmarkActionMenu *>(toolBar()->actionAt(toolBar()->mapFromGlobal(QCursor::pos())));
+
+ if (event->type() == QEvent::MouseMove && act && act->menu() != m_currentMenu)
+ {
+ m_currentMenu->hide();
+ QPoint pos = toolBar()->mapToGlobal(toolBar()->widgetForAction(act)->pos());
+ act->menu()->popup(QPoint(pos.x(), pos.y() + toolBar()->widgetForAction(act)->height()));
+ }
+ else if (event->type() == QEvent::MouseButtonPress && act)
+ {
+ m_currentMenu->hide();
+ }
+
+ return QObject::eventFilter(watched, event);
+ }
+
+ switch (event->type())
+ {
+ case QEvent::Show:
+ {
+ if (!m_filled)
+ {
+ BookmarkManager::self()->fillBookmarkBar(this);
+ m_filled = true;
+ }
+ }
+ break;
+
+ case QEvent::ActionRemoved:
+ {
+ QActionEvent *actionEvent = static_cast<QActionEvent*>(event);
+ if (actionEvent && actionEvent->action() != m_dropAction)
+ {
+ QWidget *widget = toolBar()->widgetForAction(actionEvent->action());
+ if (widget)
+ {
+ widget->removeEventFilter(this);
+ }
+ }
+ }
+ break;
+
+ case QEvent::ParentChange:
+ {
+ QActionEvent *actionEvent = static_cast<QActionEvent*>(event);
+ if (actionEvent && actionEvent->action() != m_dropAction)
+ {
+ QWidget *widget = toolBar()->widgetForAction(actionEvent->action());
+ if (widget)
+ {
+ widget->removeEventFilter(this);
+ }
+ }
+ }
+ break;
+
+ case QEvent::DragEnter:
+ {
+ QDragEnterEvent *dragEvent = static_cast<QDragEnterEvent*>(event);
+ if (dragEvent->mimeData()->hasFormat(BookmarkManager::bookmark_mime_type())
+ || dragEvent->mimeData()->hasFormat("text/uri-list")
+ || dragEvent->mimeData()->hasFormat("text/plain"))
+ {
+ QFrame* dropIndicatorWidget = new QFrame(toolBar());
+ dropIndicatorWidget->setFrameShape(QFrame::VLine);
+ m_dropAction = toolBar()->insertWidget(toolBar()->actionAt(dragEvent->pos()), dropIndicatorWidget);
+
+ dragEvent->accept();
+ }
+ }
+ break;
+
+ case QEvent::DragLeave:
+ {
+ QDragLeaveEvent *dragEvent = static_cast<QDragLeaveEvent*>(event);
+
+ if (m_checkedAction)
+ {
+ m_checkedAction->setCheckable(false);
+ m_checkedAction->setChecked(false);
+ }
+
+ delete m_dropAction;
+ m_dropAction = 0;
+ dragEvent->accept();
+ }
+ break;
+
+ case QEvent::DragMove:
+ {
+ QDragMoveEvent *dragEvent = static_cast<QDragMoveEvent*>(event);
+ if (dragEvent->mimeData()->hasFormat(BookmarkManager::bookmark_mime_type())
+ || dragEvent->mimeData()->hasFormat("text/uri-list")
+ || dragEvent->mimeData()->hasFormat("text/plain"))
+ {
+ QAction *overAction = toolBar()->actionAt(dragEvent->pos());
+ KBookmarkActionInterface *overActionBK = dynamic_cast<KBookmarkActionInterface*>(overAction);
+ QWidget *widgetAction = toolBar()->widgetForAction(overAction);
+
+ if (overAction != m_dropAction && overActionBK && widgetAction && m_dropAction)
+ {
+ toolBar()->removeAction(m_dropAction);
+ if (m_checkedAction)
+ {
+ m_checkedAction->setCheckable(false);
+ m_checkedAction->setChecked(false);
+ }
+
+ if (!overActionBK->bookmark().isGroup())
+ {
+ if ((dragEvent->pos().x() - widgetAction->pos().x()) > (widgetAction->width() / 2))
+ {
+ if (toolBar()->actions().count() > toolBar()->actions().indexOf(overAction) + 1)
+ {
+ toolBar()->insertAction(toolBar()->actions().at(toolBar()->actions().indexOf(overAction) + 1), m_dropAction);
+ }
+ else
+ {
+ toolBar()->addAction(m_dropAction);
+ }
+ }
+ else
+ {
+ toolBar()->insertAction(overAction, m_dropAction);
+ }
+ }
+ else
+ {
+ if ((dragEvent->pos().x() - widgetAction->pos().x()) >= (widgetAction->width() * 0.75))
+ {
+ if (toolBar()->actions().count() > toolBar()->actions().indexOf(overAction) + 1)
+ {
+ toolBar()->insertAction(toolBar()->actions().at(toolBar()->actions().indexOf(overAction) + 1), m_dropAction);
+ }
+ else
+ {
+ toolBar()->addAction(m_dropAction);
+ }
+ }
+ else if ((dragEvent->pos().x() - widgetAction->pos().x()) <= (widgetAction->width() * 0.25))
+ {
+ toolBar()->insertAction(overAction, m_dropAction);
+ }
+ else
+ {
+ overAction->setCheckable(true);
+ overAction->setChecked(true);
+ m_checkedAction = overAction;
+ }
+ }
+
+ dragEvent->accept();
+ }
+ }
+ }
+ break;
+
+
+ case QEvent::Drop:
+ {
+ QDropEvent *dropEvent = static_cast<QDropEvent*>(event);
+ KBookmark bookmark;
+ KBookmarkGroup root = BookmarkManager::self()->manager()->toolbar();
+
+ if (m_checkedAction)
+ {
+ m_checkedAction->setCheckable(false);
+ m_checkedAction->setChecked(false);
+ }
+
+ if (dropEvent->mimeData()->hasFormat(BookmarkManager::bookmark_mime_type()))
+ {
+ QByteArray addresses = dropEvent->mimeData()->data(BookmarkManager::bookmark_mime_type());
+ bookmark = BookmarkManager::self()->findByAddress(QString::fromLatin1(addresses.data()));
+ if (bookmark.isNull())
+ return false;
+ }
+ else if (dropEvent->mimeData()->hasFormat("text/uri-list"))
+ {
+ // DROP is URL
+ QString url = dropEvent->mimeData()->urls().at(0).toString();
+ WebWindow *w = qobject_cast<WebWindow *>(parent());
+ QString title = url.contains(w->url().toString())
+ ? w->title()
+ : url;
+ bookmark = root.addBookmark(title, url);
+ }
+ else if (dropEvent->mimeData()->hasFormat("text/plain"))
+ {
+ // DROP is TEXT
+ QString url = dropEvent->mimeData()->text();
+ KUrl u(url);
+ if (u.isValid())
+ {
+ WebWindow *w = qobject_cast<WebWindow *>(parent());
+ QString title = url.contains(w->url().toString())
+ ? w->title()
+ : url;
+ bookmark = root.addBookmark(title, url);
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ QAction *destAction = toolBar()->actionAt(dropEvent->pos());
+ if (destAction && destAction == m_dropAction)
+ {
+ if (toolBar()->actions().indexOf(m_dropAction) > 0)
+ {
+ destAction = toolBar()->actions().at(toolBar()->actions().indexOf(m_dropAction) - 1);
+ }
+ else
+ {
+ destAction = toolBar()->actions().at(1);
+ }
+ }
+
+ if (destAction)
+ {
+ KBookmarkActionInterface *destBookmarkAction = dynamic_cast<KBookmarkActionInterface *>(destAction);
+ QWidget *widgetAction = toolBar()->widgetForAction(destAction);
+
+ if (destBookmarkAction && !destBookmarkAction->bookmark().isNull() && widgetAction
+ && bookmark.address() != destBookmarkAction->bookmark().address())
+ {
+ KBookmark destBookmark = destBookmarkAction->bookmark();
+
+ if (!destBookmark.isGroup())
+ {
+ if ((dropEvent->pos().x() - widgetAction->pos().x()) >= (widgetAction->width() / 2))
+ {
+ root.moveBookmark(bookmark, destBookmark);
+ }
+ else
+ {
+ root.moveBookmark(bookmark, destBookmark.parentGroup().previous(destBookmark));
+ }
+ }
+ else
+ {
+ if ((dropEvent->pos().x() - widgetAction->pos().x()) >= (widgetAction->width() * 0.75))
+ {
+ root.moveBookmark(bookmark, destBookmark);
+ }
+ else if ((dropEvent->pos().x() - widgetAction->pos().x()) <= (widgetAction->width() * 0.25))
+ {
+ root.moveBookmark(bookmark, destBookmark.parentGroup().previous(destBookmark));
+ }
+ else
+ {
+ destBookmark.toGroup().addBookmark(bookmark);
+ }
+ }
+
+
+ BookmarkManager::self()->emitChanged();
+ }
+ }
+ else
+ {
+ root.deleteBookmark(bookmark);
+ bookmark = root.addBookmark(bookmark);
+ if (dropEvent->pos().x() < toolBar()->widgetForAction(toolBar()->actions().first())->pos().x())
+ {
+ root.moveBookmark(bookmark, KBookmark());
+ }
+
+ BookmarkManager::self()->emitChanged();
+ }
+ dropEvent->accept();
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
+
+ // These events need to be handled only for Bookmark actions and not the bar
+ if (watched != toolBar() && mouseEvent)
+ {
+ switch (event->type())
+ {
+ case QEvent::MouseButtonPress: // drag handling
+ {
+ QPoint pos = toolBar()->mapFromGlobal(QCursor::pos());
+ KBookmarkActionInterface *action = dynamic_cast<KBookmarkActionInterface *>(toolBar()->actionAt(pos));
+
+ if (action && mouseEvent->button() != Qt::MidButton)
+ {
+ m_dragAction = toolBar()->actionAt(pos);
+ m_startDragPos = pos;
+
+ // The menu is displayed only when the mouse button is released
+ if (action->bookmark().isGroup())
+ return true;
+ }
+ }
+ break;
+
+ case QEvent::MouseMove:
+ {
+ int distance = (toolBar()->mapFromGlobal(QCursor::pos()) - m_startDragPos).manhattanLength();
+ if (!m_currentMenu && distance >= QApplication::startDragDistance())
+ {
+ startDrag();
+ }
+ }
+ break;
+
+ case QEvent::MouseButtonRelease:
+ {
+ QPoint destPos = toolBar()->mapFromGlobal(QCursor::pos());
+ int distance = (destPos - m_startDragPos).manhattanLength();
+ KBookmarkActionInterface *action = dynamic_cast<KBookmarkActionInterface *>(toolBar()->actionAt(destPos));
+
+ if (action && action->bookmark().isGroup())
+ {
+ if (mouseEvent->button() == Qt::MidButton)
+ {
+ BookmarkManager::self()->owner()->openBookmarkFolder(action->bookmark());
+ }
+ else if (distance < QApplication::startDragDistance())
+ {
+ KBookmarkActionMenu *menu = dynamic_cast<KBookmarkActionMenu *>(toolBar()->actionAt(m_startDragPos));
+ QPoint actionPos = toolBar()->mapToGlobal(toolBar()->widgetForAction(menu)->pos());
+ menu->menu()->popup(QPoint(actionPos.x(), actionPos.y() + toolBar()->widgetForAction(menu)->height()));
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return QObject::eventFilter(watched, event);
+}
+
+
+void BookmarkToolBar::startDrag()
+{
+ KBookmarkActionInterface *action = dynamic_cast<KBookmarkActionInterface *>(m_dragAction);
+ if (action)
+ {
+ QMimeData *mimeData = new QMimeData;
+ KBookmark bookmark = action->bookmark();
+
+ QByteArray address = bookmark.address().toLatin1();
+ mimeData->setData(BookmarkManager::bookmark_mime_type(), address);
+ bookmark.populateMimeData(mimeData);
+
+ QDrag *drag = new QDrag(toolBar());
+ drag->setMimeData(mimeData);
+
+ if (bookmark.isGroup())
+ {
+ drag->setPixmap(KIcon(bookmark.icon()).pixmap(24, 24));
+ }
+// else
+// {
+// drag->setPixmap(rApp->iconManager()->iconForUrl(action->bookmark().url()).pixmap(24, 24));
+// }
+
+ drag->start(Qt::MoveAction);
+ connect(drag, SIGNAL(destroyed()), this, SLOT(dragDestroyed()));
+ }
+}
+
+
+void BookmarkToolBar::dragDestroyed()
+{
+ // A workaround to get rid of the checked state of the dragged action
+ if (m_dragAction)
+ {
+ m_dragAction->setVisible(false);
+ m_dragAction->setVisible(true);
+ m_dragAction = 0;
+ }
+ delete m_dropAction;
+ m_dropAction = 0;
+}
diff --git a/src/bookmarks/bookmarkstoolbar.h b/src/bookmarks/bookmarkstoolbar.h
new file mode 100644
index 00000000..e2ed6e3a
--- /dev/null
+++ b/src/bookmarks/bookmarkstoolbar.h
@@ -0,0 +1,111 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2008-2012 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
+* 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 BOOKMARKSTOOLBAR_H
+#define BOOKMARKSTOOLBAR_H
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// KDE Includes
+#include <KBookmarkMenu>
+
+/**
+ * This class represent the rekonq bookmarks menu.
+ * It's just a simple class inherited from KBookmarkMenu
+ *
+ */
+class BookmarkMenu : public KBookmarkMenu
+{
+ Q_OBJECT
+
+public:
+ BookmarkMenu(KBookmarkManager* manager,
+ KBookmarkOwner* owner,
+ KMenu* menu,
+ KActionCollection* actionCollection);
+ BookmarkMenu(KBookmarkManager *manager,
+ KBookmarkOwner *owner,
+ KMenu *parentMenu,
+ const QString &parentAddress);
+ ~BookmarkMenu();
+
+protected:
+ virtual KMenu * contextMenu(QAction * act);
+ virtual void refill();
+ virtual QAction* actionForBookmark(const KBookmark &bookmark);
+
+private:
+ void addOpenFolderInTabs();
+
+};
+
+
+// ------------------------------------------------------------------------------
+
+
+// KDE Includes
+#include <KToolBar>
+
+
+/**
+ * This class manage the bookmark toolbar.
+ * Some events from the toolbar are handled to allow the drag and drop
+ */
+
+class BookmarkToolBar : public QObject
+{
+ Q_OBJECT
+
+public:
+ BookmarkToolBar(KToolBar *toolBar, QObject *parent);
+
+ KToolBar* toolBar();
+
+protected:
+ bool eventFilter(QObject *watched, QEvent *event);
+
+private Q_SLOTS:
+ void contextMenu(const QPoint &);
+ void menuDisplayed();
+ void menuHidden();
+ void hideMenu();
+ void dragDestroyed();
+
+private:
+ void startDrag();
+
+ KToolBar *m_toolBar;
+ KMenu *m_currentMenu;
+ QPoint m_startDragPos;
+ QAction *m_dragAction;
+ QAction *m_dropAction;
+ QAction *m_checkedAction;
+ bool m_filled;
+};
+
+#endif // BOOKMARKSTOOLBAR_H