Bug 226479 - Support reordering of bookmarks by drag and drop in the bookmarks toolbar
Summary: Support reordering of bookmarks by drag and drop in the bookmarks toolbar
Status: RESOLVED FIXED
Alias: None
Product: rekonq
Classification: Applications
Component: general (show other bugs)
Version: 0.4.0
Platform: Unlisted Binaries Linux
: NOR wishlist
Target Milestone: ---
Assignee: Yoann Laissus
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-02-12 09:03 UTC by Eike Hein
Modified: 2013-07-30 15:36 UTC (History)
3 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Eike Hein 2010-02-12 09:03:10 UTC
I'd like to be able to use drag and drop in the bookmarks toolbar to:
- Change the position of bookmark and folder items on the bar.
- Move bookmarks into and out of folders, and between folders.
- Change the position of bookmark and folder items in folder item popups.

Essentially this means that drag and drop has to work on the bar, in popups, between popups and the bar, and between popups.

This is workflow supported at present by Mozilla Firefox, Google Chrome and Apple Safari.
Comment 1 Yoann Laissus 2010-08-19 10:35:54 UTC
	A	 src/bookmarks/bookmarkstoolbar.h	 [License: GPL(v2)]


	A	 src/bookmarks/bookmarkstoolbar.cpp	 [License: GPL(v2)]


	A	 src/bookmarks/bookmarkscontextmenu.h	 [License: GPL(v2)]


	A	 src/bookmarks/bookmarkscontextmenu.cpp	 [License: GPL(v2)]

commit 05710490e9e4da45c8c9caaf8a998b851bd99085
Author: Yoann Laissus <yoann.laissus@gmail.com>
Date:   Tue Aug 17 12:43:07 2010 +0200

        - Drag and drop in the bookmark toolbar between root items only (for the moment)
        - Drag accepted from the panel
        - Move two classes to a separate file
    
        Partially fixed :
        CCBUG: 226479

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 5d06243..8c78c5a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -48,7 +48,8 @@ SET( rekonq_KDEINIT_SRCS
     bookmarks/bookmarkspanel.cpp
     bookmarks/bookmarkstreemodel.cpp
     bookmarks/bookmarksproxy.cpp
-    bookmarks/bookmarkcontextmenu.cpp
+    bookmarks/bookmarkscontextmenu.cpp
+    bookmarks/bookmarkstoolbar.cpp
     #----------------------------------------
     adblock/adblockmanager.cpp
     adblock/adblocknetworkreply.cpp
diff --git a/src/bookmarks/bookmarkcontextmenu.cpp b/src/bookmarks/bookmarkcontextmenu.cpp
deleted file mode 100644
index 714c8b5..0000000
--- a/src/bookmarks/bookmarkcontextmenu.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-/* ============================================================
-*
-* 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();
-}
-
-
-BookmarkContextMenu::~BookmarkContextMenu()
-{
-    delete m_ac;
-}
-
-
-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::NewTab);
-}
-
-
-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();
-    Application::bookmarkProvider()->bookmarkOwner()->deleteBookmark(bm);
-}
-
-
-void BookmarkContextMenu::editBookmark()
-{
-    KBookmark selected = bookmark();
-    selected.setFullText(selected.fullText().replace("&&", "&"));
-    KBookmarkDialog *dialog = owner()->bookmarkDialog(manager(), QApplication::activeWindow());
-    dialog->editBookmark(selected);
-    selected.setFullText(selected.fullText().replace('&', "&&"));
-    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());
-            if (!newBk.isNull())
-            {
-                selected.parentGroup().moveBookmark(newBk, selected);
-                manager()->emitChanged(newBk.parentGroup());
-            }
-        }
-    }
-    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(newBk.parentGroup());
-}
-
-
-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().replace('&', "&&"), KUrl(owner()->currentUrl()));
-        parent.moveBookmark(newBk, selected.parentGroup().previous(selected));
-    }
-
-    else
-    {
-        parent.addBookmark(owner()->currentTitle(), KUrl(owner()->currentUrl()));
-    }
-
-    manager()->emitChanged(parent);
-}
-
diff --git a/src/bookmarks/bookmarkcontextmenu.h b/src/bookmarks/bookmarkcontextmenu.h
deleted file mode 100644
index ebbfd6e..0000000
--- a/src/bookmarks/bookmarkcontextmenu.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* ============================================================
-*
-* 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);
-    ~BookmarkContextMenu();
-    
-    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/bookmarkscontextmenu.cpp b/src/bookmarks/bookmarkscontextmenu.cpp
new file mode 100644
index 0000000..c448d29
--- /dev/null
+++ b/src/bookmarks/bookmarkscontextmenu.cpp
@@ -0,0 +1,321 @@
+/* ============================================================
+*
+* 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 "bookmarkscontextmenu.h"
+#include "bookmarkscontextmenu.moc"
+
+// Local Includes
+#include "application.h"
+#include "bookmarksmanager.h"
+
+// KDE Includes
+#include <KMessageBox>
+#include <KActionCollection>
+#include <KBookmarkDialog>
+
+// Qt Includes
+#include <QClipboard>
+
+
+BookmarksContextMenu::BookmarksContextMenu(const KBookmark & bookmark, KBookmarkManager *manager, KBookmarkOwner *owner, QWidget *parent)
+        : KBookmarkContextMenu(bookmark, manager, owner, parent)
+        , m_ac(new KActionCollection(this))
+{
+    setupActions();
+}
+
+
+BookmarksContextMenu::~BookmarksContextMenu()
+{
+    delete m_ac;
+}
+
+
+void BookmarksContextMenu::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 BookmarksContextMenu::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 BookmarksContextMenu::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 BookmarksContextMenu::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 BookmarksContextMenu::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 BookmarksContextMenu::openInCurrentTab()
+{
+    Application::instance()->loadUrl(bookmark().url());
+}
+
+
+void BookmarksContextMenu::openInNewTab()
+{
+    Application::instance()->loadUrl(bookmark().url(), Rekonq::NewTab);
+}
+
+
+void BookmarksContextMenu::openInNewWindow()
+{
+    Application::instance()->loadUrl(bookmark().url(), Rekonq::NewWindow);
+}
+
+
+void BookmarksContextMenu::copyToClipboard()
+{
+    if (bookmark().isNull())
+        return;
+
+    QClipboard *cb = QApplication::clipboard();
+    cb->setText(bookmark().url().url());
+}
+
+
+void BookmarksContextMenu::deleteBookmark()
+{
+    KBookmark bm = bookmark();
+    Application::bookmarkProvider()->bookmarkOwner()->deleteBookmark(bm);
+}
+
+
+void BookmarksContextMenu::editBookmark()
+{
+    KBookmark selected = bookmark();
+    selected.setFullText(selected.fullText().replace("&&", "&"));
+    KBookmarkDialog *dialog = owner()->bookmarkDialog(manager(), QApplication::activeWindow());
+    dialog->editBookmark(selected);
+    selected.setFullText(selected.fullText().replace('&', "&&"));
+    delete dialog;
+}
+
+
+void BookmarksContextMenu::openFolderInTabs()
+{
+    if (bookmark().isGroup())
+        owner()->openFolderinTabs(bookmark().toGroup());
+}
+
+
+void BookmarksContextMenu::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());
+            if (!newBk.isNull())
+            {
+                selected.parentGroup().moveBookmark(newBk, selected);
+                manager()->emitChanged(newBk.parentGroup());
+            }
+        }
+    }
+    else
+    {
+        dialog->createNewFolder("New folder");
+    }
+
+    delete dialog;
+}
+
+
+void BookmarksContextMenu::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(newBk.parentGroup());
+}
+
+
+void BookmarksContextMenu::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().replace('&', "&&"), KUrl(owner()->currentUrl()));
+        parent.moveBookmark(newBk, selected.parentGroup().previous(selected));
+    }
+
+    else
+    {
+        parent.addBookmark(owner()->currentTitle(), KUrl(owner()->currentUrl()));
+    }
+
+    manager()->emitChanged(parent);
+}
+
diff --git a/src/bookmarks/bookmarkscontextmenu.h b/src/bookmarks/bookmarkscontextmenu.h
new file mode 100644
index 0000000..2ef8e5a
--- /dev/null
+++ b/src/bookmarks/bookmarkscontextmenu.h
@@ -0,0 +1,68 @@
+/* ============================================================
+*
+* 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 BookmarksContextMenu : public KBookmarkContextMenu
+{
+    Q_OBJECT
+
+public:
+    BookmarksContextMenu(const KBookmark & bk, KBookmarkManager * manager, KBookmarkOwner *owner, QWidget * parent = 0);
+    ~BookmarksContextMenu();
+    
+    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 cade77b..221a6db 100644
--- a/src/bookmarks/bookmarksmanager.cpp
+++ b/src/bookmarks/bookmarksmanager.cpp
@@ -36,7 +36,7 @@
 #include "webtab.h"
 #include "webview.h"
 #include "mainview.h"
-#include "bookmarkcontextmenu.h"
+#include "bookmarkscontextmenu.h"
 
 // KDE Includes
 #include <KActionCollection>
@@ -179,202 +179,6 @@ QList< QPair<QString, QString> > BookmarkOwner::currentBookmarkList() const
 // ------------------------------------------------------------------------------------------------------
 
 
-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()
-{
-}
-
-
-KMenu * BookmarkMenu::contextMenu(QAction *act)
-{
-
-    KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(act);
-    if (!action)
-        return 0;
-    return new BookmarkContextMenu(action->bookmark(), manager(), 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());
-        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);
-        connect(action, SIGNAL(hovered()), this, SLOT(actionHovered()));
-        return action;
-    }
-}
-
-
-void BookmarkMenu::refill()
-{
-    clear();
-    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 new tabs."));
-            connect(action, SIGNAL(triggered(bool)), this, SLOT(slotOpenFolderInTabs()));
-            parentMenu()->addAction(action);
-        }
-    }
-}
-
-
-void BookmarkMenu::actionHovered()
-{
-    KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(sender());
-    if (action)
-        Application::instance()->mainWindow()->notifyMessage(action->bookmark().url().url());
-}
-
-
-// ------------------------------------------------------------------------------------------------------
-
-
-BookmarkToolBar::BookmarkToolBar( const QString &objectName,
-                                  QMainWindow *parentWindow,
-                                  Qt::ToolBarArea area,
-                                  bool newLine,
-                                  bool isMainToolBar,
-                                  bool readConfig
-                                )
-    : KToolBar(objectName, parentWindow, area, newLine, isMainToolBar, readConfig)
-    , m_filled(false)
-    , m_currentMenu(0)
-{
-    connect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(QString,QString)), this, SLOT(hideMenu()));
-}
-
-
-BookmarkToolBar::~BookmarkToolBar()
-{
-}
-
-
-void BookmarkToolBar::setVisible(bool visible)
-{
-    if (visible && !m_filled)
-    {
-        m_filled = true;
-        Application::bookmarkProvider()->fillBookmarkBar(this);
-    }
-    KToolBar::setVisible(visible);
-}
-
-
-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)
-{
-    // To switch root folders as in a menubar
-    if (event->type() == QEvent::MouseMove && m_currentMenu)
-    {
-        KBookmarkActionMenu* act = dynamic_cast<KBookmarkActionMenu *>(this->actionAt(this->mapFromGlobal(QCursor::pos())));
-        if (act && act->menu() != m_currentMenu)
-        {
-            m_currentMenu->hide();
-            QPoint pos = mapToGlobal(widgetForAction(act)->pos());
-            act->menu()->popup(QPoint(pos.x(), pos.y() + widgetForAction(act)->height()));
-        }
-    }
-    return KToolBar::eventFilter(watched, event);
-}
-
-
-void BookmarkToolBar::actionHovered()
-{
-    KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(sender());
-    if (action)
-    Application::instance()->mainWindow()->notifyMessage(action->bookmark().url().url());
-}
-
-// ------------------------------------------------------------------------------------------------------
-
-
-
 BookmarkProvider::BookmarkProvider(QObject *parent)
         : QObject(parent)
         , m_manager(0)
@@ -484,7 +288,7 @@ void BookmarkProvider::contextMenu(const QPoint &point)
     if (!action)
         return;
 
-    BookmarkContextMenu menu(action->bookmark(), bookmarkManager(), bookmarkOwner());
+    BookmarksContextMenu menu(action->bookmark(), bookmarkManager(), bookmarkOwner());
     menu.exec(bookmarkToolBar->mapToGlobal(point));
 }
 
diff --git a/src/bookmarks/bookmarksmanager.h b/src/bookmarks/bookmarksmanager.h
index b084b8e..6f97e4e 100644
--- a/src/bookmarks/bookmarksmanager.h
+++ b/src/bookmarks/bookmarksmanager.h
@@ -38,6 +38,7 @@
 #include "application.h"
 #include "urlresolver.h"
 #include "bookmarkspanel.h"
+#include "bookmarkstoolbar.h"
 
 // Qt Includes
 #include <QWidget>
@@ -137,79 +138,6 @@ signals:
     void openUrl(const KUrl &, const Rekonq::OpenType &);
 };
 
-// ------------------------------------------------------------------------------
-
-
-// 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 slots:
-    void actionHovered();
-
-private:
-    void addOpenFolderInTabs();
-
-};
-
-
-// ------------------------------------------------------------------------------
-
-#include <KToolBar>
-
-class BookmarkToolBar : public KToolBar
-{
-    Q_OBJECT
-
-public:
-BookmarkToolBar(const QString &objectName,
-                QMainWindow *parentWindow,
-                Qt::ToolBarArea area,
-                bool newLine = false,
-                bool isMainToolBar = false,
-                bool readConfig = true);
-~BookmarkToolBar();
-
-virtual void setVisible(bool visible);
-
-protected:
-    bool eventFilter(QObject *watched, QEvent *event);
-
-private slots:
-    void actionHovered();
-    void menuDisplayed();
-    void menuHidden();
-    void hideMenu();
-
-private:
-    bool m_filled;
-    KMenu *m_currentMenu;
-};
-
 
 // ------------------------------------------------------------------------------
 
diff --git a/src/bookmarks/bookmarkspanel.cpp b/src/bookmarks/bookmarkspanel.cpp
index b49d4f5..72778f7 100644
--- a/src/bookmarks/bookmarkspanel.cpp
+++ b/src/bookmarks/bookmarkspanel.cpp
@@ -33,7 +33,7 @@
 #include "bookmarksmanager.h"
 #include "bookmarkstreemodel.h"
 #include "bookmarksproxy.h"
-#include "bookmarkcontextmenu.h"
+#include "bookmarkscontextmenu.h"
 
 // Auto Includes
 #include "rekonq.h"
@@ -201,7 +201,7 @@ void BookmarksPanel::contextMenu(const QPoint &pos)
 
     KBookmark selected = bookmarkForIndex(index);
 
-    BookmarkContextMenu menu( selected,
+    BookmarksContextMenu menu( selected,
                               Application::bookmarkProvider()->bookmarkManager(),
                               Application::bookmarkProvider()->bookmarkOwner(),
                               this
diff --git a/src/bookmarks/bookmarkstoolbar.cpp b/src/bookmarks/bookmarkstoolbar.cpp
new file mode 100644
index 0000000..e9ab8a5
--- /dev/null
+++ b/src/bookmarks/bookmarkstoolbar.cpp
@@ -0,0 +1,432 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2008-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
+* 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 "mainwindow.h"
+#include "application.h"
+#include "bookmarksmanager.h"
+
+
+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()
+{
+}
+
+
+KMenu * BookmarkMenu::contextMenu(QAction *act)
+{
+
+    KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(act);
+    if (!action)
+        return 0;
+    return new BookmarksContextMenu(action->bookmark(), manager(), 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);
+        connect(action, SIGNAL(hovered()), this, SLOT(actionHovered()));
+        return action;
+    }
+}
+
+
+void BookmarkMenu::refill()
+{
+    clear();
+    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 new tabs."));
+            connect(action, SIGNAL(triggered(bool)), this, SLOT(slotOpenFolderInTabs()));
+            parentMenu()->addAction(action);
+        }
+    }
+}
+
+
+void BookmarkMenu::actionHovered()
+{
+    KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(sender());
+    if (action)
+        Application::instance()->mainWindow()->notifyMessage(action->bookmark().url().url());
+}
+
+
+// ------------------------------------------------------------------------------------------------------
+
+#include <QActionEvent>
+
+BookmarkToolBar::BookmarkToolBar( const QString &objectName,
+                                  QMainWindow *parentWindow,
+                                  Qt::ToolBarArea area,
+                                  bool newLine,
+                                  bool isMainToolBar,
+                                  bool readConfig
+                                )
+    : KToolBar(objectName, parentWindow, area, newLine, isMainToolBar, readConfig)
+    , m_filled(false)
+    , m_currentMenu(0)
+    , m_dragAction(0)
+    , m_dropAction(0)
+{
+    connect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(QString, QString)), this, SLOT(hideMenu()));
+    setAcceptDrops(true);
+}
+
+
+BookmarkToolBar::~BookmarkToolBar()
+{
+}
+
+
+void BookmarkToolBar::setVisible(bool visible)
+{
+    if (visible && !m_filled)
+    {
+        m_filled = true;
+        Application::bookmarkProvider()->fillBookmarkBar(this);
+    }
+    KToolBar::setVisible(visible);
+}
+
+
+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())
+    {
+        // To switch root folders as in a menubar
+        KBookmarkActionMenu* act = dynamic_cast<KBookmarkActionMenu *>(this->actionAt(this->mapFromGlobal(QCursor::pos())));
+        if (event->type() == QEvent::MouseMove && act && m_currentMenu && act->menu() != m_currentMenu)
+        {
+            m_currentMenu->hide();
+            QPoint pos = mapToGlobal(widgetForAction(act)->pos());
+            act->menu()->popup(QPoint(pos.x(), pos.y() + widgetForAction(act)->height()));
+        }
+    }
+    else
+    {
+        // Drag handling
+        if (event->type() == QEvent::MouseButtonPress)
+        {
+            QPoint pos = mapFromGlobal(QCursor::pos());
+            KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(actionAt(pos));
+
+            if (action && !action->bookmark().isGroup())
+            {
+                m_dragAction = actionAt(pos);
+                m_startDragPos = pos;
+            }
+        }
+        else if (event->type() == QEvent::MouseMove)
+        {
+            int distance = (mapFromGlobal(QCursor::pos()) - m_startDragPos).manhattanLength();
+            if (distance >= QApplication::startDragDistance())
+            {
+                startDrag();
+            }
+        }
+    }
+    return KToolBar::eventFilter(watched, event);
+}
+
+
+void BookmarkToolBar::actionHovered()
+{
+    KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(sender());
+    if (action)
+        Application::instance()->mainWindow()->notifyMessage(action->bookmark().url().url());
+}
+
+
+void BookmarkToolBar::actionEvent(QActionEvent *event)
+{
+    KToolBar::actionEvent(event);
+
+    QWidget *widget = widgetForAction(event->action());
+    if (!widget || event->action() == m_dropAction)
+        return;
+
+    if (event->type() == QEvent::ActionAdded)
+    {
+        widget->installEventFilter(this);
+    }
+    else if (event->type() == QEvent::ActionRemoved)
+    {
+        widget->removeEventFilter(this);
+    }
+    else if (event->type() == QEvent::ParentChange)
+    {
+        widget->removeEventFilter(this);
+    }
+}
+
+
+void BookmarkToolBar::startDrag()
+{
+    KBookmarkActionInterface *action = dynamic_cast<KBookmarkActionInterface *>(m_dragAction);
+    if (action && !action->bookmark().isGroup())
+    {
+        QMimeData *mimeData = new QMimeData;
+
+        QByteArray address = action->bookmark().address().toLatin1();
+        mimeData->setData("application/rekonq-bookmark", address);
+        action->bookmark().populateMimeData(mimeData);
+
+        QDrag *drag = new QDrag(this);
+        drag->setMimeData(mimeData);
+        drag->setPixmap(KIcon(action->bookmark().icon()).pixmap(24, 24));
+
+        drag->start(Qt::MoveAction);
+        connect(drag, SIGNAL(destroyed()), this, SLOT(dragDestroyed()));
+    }
+}
+
+
+void BookmarkToolBar::dragEnterEvent(QDragEnterEvent *event)
+{
+    if (event->mimeData()->hasFormat("application/rekonq-bookmark"))
+    {
+        QByteArray addresses = event->mimeData()->data("application/rekonq-bookmark");
+        KBookmark bookmark = Application::bookmarkProvider()->bookmarkManager()->findByAddress(QString::fromLatin1(addresses.data()));
+
+        if (!bookmark.isNull())
+        {
+            QFrame* dropIndicatorWidget = new QFrame(this);
+            dropIndicatorWidget->setFrameShape(QFrame::VLine);
+            m_dropAction = insertWidget(actionAt(event->pos()), dropIndicatorWidget);
+
+            event->accept();
+        }
+    }
+
+    KToolBar::dragEnterEvent(event);
+}
+
+
+void BookmarkToolBar::dragMoveEvent(QDragMoveEvent *event)
+{
+    if (event->mimeData()->hasFormat("application/rekonq-bookmark"))
+    {
+        QByteArray addresses = event->mimeData()->data("application/rekonq-bookmark");
+        KBookmark bookmark = Application::bookmarkProvider()->bookmarkManager()->findByAddress(QString::fromLatin1(addresses.data()));
+        QAction *overAction = actionAt(event->pos());
+        KBookmarkActionInterface *overActionBK = dynamic_cast<KBookmarkActionInterface*>(overAction);
+        QWidget *widgetAction = widgetForAction(overAction);
+
+        if (!bookmark.isNull() && overAction != m_dropAction && overActionBK && widgetAction && m_dropAction)
+        {
+            removeAction(m_dropAction);
+
+            if ((event->pos().x() - widgetAction->pos().x()) > (widgetAction->width() / 2))
+            {
+                if (actions().count() >  actions().indexOf(overAction) + 1)
+                {
+                    insertAction(actions().at(actions().indexOf(overAction) + 1), m_dropAction);
+                }
+                else
+                {
+                    addAction(m_dropAction);
+                }
+            }
+            else
+            {
+                insertAction(overAction, m_dropAction);
+            }
+
+            event->accept();
+        }
+    }
+
+    KToolBar::dragMoveEvent(event);
+}
+
+
+void BookmarkToolBar::dragLeaveEvent(QDragLeaveEvent *event)
+{
+    delete m_dropAction;
+    m_dropAction = 0;
+    event->accept();
+    KToolBar::dragLeaveEvent(event);
+}
+
+
+void BookmarkToolBar::dropEvent(QDropEvent *event)
+{
+    if (event->mimeData()->hasFormat("application/rekonq-bookmark"))
+    {
+        QByteArray addresses = event->mimeData()->data("application/rekonq-bookmark");
+        KBookmark bookmark = Application::bookmarkProvider()->bookmarkManager()->findByAddress(QString::fromLatin1(addresses.data()));
+
+        QAction *destAction = actionAt(event->pos());
+        if (destAction && destAction == m_dropAction)
+        {
+            if (actions().indexOf(m_dropAction) > 0)
+            {
+                destAction = actions().at(actions().indexOf(m_dropAction) - 1);
+            }
+            else
+            {
+                destAction = actions().at(1);
+            }
+        }
+
+        KBookmarkActionInterface *destBookmarkAction = dynamic_cast<KBookmarkActionInterface *>(destAction);
+        QWidget *widgetAction = widgetForAction(destAction);
+
+        if (!bookmark.isNull() && destBookmarkAction && !destBookmarkAction->bookmark().isNull() && widgetAction)
+        {
+            KBookmarkGroup root = Application::bookmarkProvider()->rootGroup();
+            KBookmark destBookmark = destBookmarkAction->bookmark();
+            // To fix an issue with panel's drags
+            root.deleteBookmark(bookmark);
+
+            if ((event->pos().x() - widgetAction->pos().x()) > (widgetAction->width() / 2))
+            {
+                root.moveBookmark(bookmark, destBookmark);
+            }
+            else
+            {
+                root.moveBookmark(bookmark, destBookmark.parentGroup().previous(destBookmark));
+            }
+
+            Application::bookmarkProvider()->bookmarkManager()->emitChanged();
+            event->accept();
+        }
+    }
+
+    KToolBar::dropEvent(event);
+}
+
+
+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 0000000..cf7b62c
--- /dev/null
+++ b/src/bookmarks/bookmarkstoolbar.h
@@ -0,0 +1,120 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2008-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
+* 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
+
+// Local Includes
+
+
+// Qt Includes
+
+
+// KDE Includes
+#include <KBookmarkMenu>
+#include <KToolBar>
+
+
+
+/**
+ * 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 slots:
+    void actionHovered();
+
+private:
+    void addOpenFolderInTabs();
+
+};
+
+
+// ------------------------------------------------------------------------------
+
+#include <KToolBar>
+
+class BookmarkToolBar : public KToolBar
+{
+    Q_OBJECT
+
+public:
+BookmarkToolBar(const QString &objectName,
+                QMainWindow *parentWindow,
+                Qt::ToolBarArea area,
+                bool newLine = false,
+                bool isMainToolBar = false,
+                bool readConfig = true);
+~BookmarkToolBar();
+
+virtual void setVisible(bool visible);
+
+protected:
+    bool eventFilter(QObject *watched, QEvent *event);
+    void dragEnterEvent(QDragEnterEvent *event);
+    void dragMoveEvent(QDragMoveEvent *event);
+    void dragLeaveEvent(QDragLeaveEvent *event);
+    void dropEvent(QDropEvent *event);
+    void actionEvent(QActionEvent *event);
+
+private slots:
+    void actionHovered();
+    void menuDisplayed();
+    void menuHidden();
+    void hideMenu();
+    void dragDestroyed();
+
+private:
+    void startDrag();
+
+    bool m_filled;
+    KMenu *m_currentMenu;
+    QPoint m_startDragPos;
+    QAction *m_dragAction;
+    QAction *m_dropAction;
+};
+
+#endif // BOOKMARKSTOOLBAR_H
Comment 2 Yoann Laissus 2010-12-20 20:53:05 UTC
commit 03c624f2b2e718ca6164402d55b5dca8c3a819dd
branch master
Author: Yoann Laissus <yoann.laissus@gmail.com>
Date:   Mon Dec 20 20:48:18 2010 +0100

    - Bookmark folders can now be dragged and dropped in the toolbar.
    - Drop a bookmark folder in the WebView no longer crash rekonq but open this folder in new tabs
    - Fix some crash when a single bookmark is dropped in the WebView (incorrect URL)
    - Port the drag icon to IconManager
    
    CCBUG: 226479

diff --git a/src/bookmarks/bookmarkprovider.cpp b/src/bookmarks/bookmarkprovider.cpp
index fe038b2..2a9dbe2 100644
--- a/src/bookmarks/bookmarkprovider.cpp
+++ b/src/bookmarks/bookmarkprovider.cpp
@@ -231,6 +231,7 @@ void BookmarkProvider::fillBookmarkBar(BookmarkToolBar *toolBar)
             connect(menuAction->menu(), SIGNAL(aboutToHide()), toolBar, SLOT(menuHidden()));
 
             toolBar->toolBar()->addAction(menuAction);
+            toolBar->toolBar()->widgetForAction(menuAction)->installEventFilter(toolBar);
         }
         else if (bookmark.isSeparator())
         {
@@ -239,8 +240,6 @@ void BookmarkProvider::fillBookmarkBar(BookmarkToolBar *toolBar)
         else
         {
             KBookmarkAction *action = new KBookmarkAction(bookmark, m_owner, this);
-            //action->s
-            //action->setIconText(action->iconText().replace('&', "&&&"));
             action->setIcon(Application::iconManager()->iconForUrl( KUrl(bookmark.url()) ));
             connect(action, SIGNAL(hovered()), toolBar, SLOT(actionHovered()));
             toolBar->toolBar()->addAction(action);
diff --git a/src/bookmarks/bookmarkstoolbar.cpp b/src/bookmarks/bookmarkstoolbar.cpp
index 63092b8..e239e23 100644
--- a/src/bookmarks/bookmarkstoolbar.cpp
+++ b/src/bookmarks/bookmarkstoolbar.cpp
@@ -328,27 +328,24 @@ bool BookmarkToolBar::eventFilter(QObject *watched, QEvent *event)
         {
             QDropEvent *dropEvent = static_cast<QDropEvent*>(event);
             KBookmark bookmark;
-            QUrl url;
-            QString title;
+            KBookmarkGroup root = Application::bookmarkProvider()->rootGroup();
 
             if (dropEvent->mimeData()->hasFormat("application/rekonq-bookmark"))
             {
                 QByteArray addresses = dropEvent->mimeData()->data("application/rekonq-bookmark");
                 bookmark =  Application::bookmarkProvider()->bookmarkManager()->findByAddress(QString::fromLatin1(addresses.data()));
                 if (bookmark.isNull())
-                    return QObject::eventFilter(watched, event);
-
-                url = bookmark.url();
-                title = bookmark.fullText();
+                    return false;
             }
             else if (dropEvent->mimeData()->hasFormat("text/uri-list"))
             {
-                title = dropEvent->mimeData()->text();
-                url = dropEvent->mimeData()->urls().at(0).toString();
+                QString title = dropEvent->mimeData()->text();
+                QString url = dropEvent->mimeData()->urls().at(0).toString();
+                bookmark = root.addBookmark(title, url);
             }
             else
             {
-                return QObject::eventFilter(watched, event);
+                return false;
             }
 
             QAction *destAction = toolBar()->actionAt(dropEvent->pos());
@@ -364,8 +361,6 @@ bool BookmarkToolBar::eventFilter(QObject *watched, QEvent *event)
                 }
             }
 
-            KBookmarkGroup root = Application::bookmarkProvider()->rootGroup();
-
             if (destAction)
             {
                 KBookmarkActionInterface *destBookmarkAction = dynamic_cast<KBookmarkActionInterface *>(destAction);
@@ -375,8 +370,6 @@ bool BookmarkToolBar::eventFilter(QObject *watched, QEvent *event)
                     && bookmark.address() != destBookmarkAction->bookmark().address())
                 {
                     KBookmark destBookmark = destBookmarkAction->bookmark();
-                    root.deleteBookmark(bookmark);
-                    bookmark = root.addBookmark(title, url);
 
                     if ((dropEvent->pos().x() - widgetAction->pos().x()) > (widgetAction->width() / 2))
                     {
@@ -393,7 +386,7 @@ bool BookmarkToolBar::eventFilter(QObject *watched, QEvent *event)
             else
             {
                 root.deleteBookmark(bookmark);
-                bookmark = root.addBookmark(title, url);
+                bookmark = root.addBookmark(bookmark);
                 if (dropEvent->pos().x() < toolBar()->widgetForAction(toolBar()->actions().first())->pos().x())
                 {
                     root.moveBookmark(bookmark, KBookmark());
@@ -410,22 +403,38 @@ bool BookmarkToolBar::eventFilter(QObject *watched, QEvent *event)
         if (event->type() == QEvent::MouseButtonPress)
         {
             QPoint pos = toolBar()->mapFromGlobal(QCursor::pos());
-            KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(toolBar()->actionAt(pos));
+            KBookmarkActionInterface *action = dynamic_cast<KBookmarkActionInterface *>(toolBar()->actionAt(pos));
 
-            if (action && !action->bookmark().isGroup())
+            if (action)
             {
                 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;
             }
         }
         else if (event->type() == QEvent::MouseMove)
         {
             int distance = (toolBar()->mapFromGlobal(QCursor::pos()) - m_startDragPos).manhattanLength();
-            if (distance >= QApplication::startDragDistance())
+            if (!m_currentMenu && distance >= QApplication::startDragDistance())
             {
                 startDrag();
             }
         }
+        else if (event->type() == QEvent::MouseButtonRelease)
+        {
+            int distance = (toolBar()->mapFromGlobal(QCursor::pos()) - m_startDragPos).manhattanLength();
+            KBookmarkActionInterface *action = dynamic_cast<KBookmarkActionInterface *>(toolBar()->actionAt(m_startDragPos));
+
+            if (action && action->bookmark().isGroup() && 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()));
+            }
+        }
     }
 
     return QObject::eventFilter(watched, event);
@@ -443,17 +452,26 @@ void BookmarkToolBar::actionHovered()
 void BookmarkToolBar::startDrag()
 {
     KBookmarkActionInterface *action = dynamic_cast<KBookmarkActionInterface *>(m_dragAction);
-    if (action && !action->bookmark().isGroup())
+    if (action)
     {
         QMimeData *mimeData = new QMimeData;
+        KBookmark bookmark = action->bookmark();
 
-        QByteArray address = action->bookmark().address().toLatin1();
+        QByteArray address = bookmark.address().toLatin1();
         mimeData->setData("application/rekonq-bookmark", address);
-        action->bookmark().populateMimeData(mimeData);
+        bookmark.populateMimeData(mimeData);
 
         QDrag *drag = new QDrag(toolBar());
         drag->setMimeData(mimeData);
-        drag->setPixmap(KIcon(action->bookmark().icon()).pixmap(24, 24));
+
+        if (bookmark.isGroup())
+        {
+            drag->setPixmap(KIcon(bookmark.icon()).pixmap(24, 24));
+        }
+        else
+        {
+            drag->setPixmap(Application::iconManager()->iconForUrl(action->bookmark().url()).pixmap(24, 24));
+        }
 
         drag->start(Qt::MoveAction);
         connect(drag, SIGNAL(destroyed()), this, SLOT(dragDestroyed()));
diff --git a/src/webview.cpp b/src/webview.cpp
index aeaf92b..2c0b59e 100644
--- a/src/webview.cpp
+++ b/src/webview.cpp
@@ -35,6 +35,7 @@
 // Local Includes
 #include "application.h"
 #include "bookmarkprovider.h"
+#include "bookmarkowner.h"
 #include "iconmanager.h"
 #include "mainview.h"
 #include "mainwindow.h"
@@ -453,6 +454,27 @@ void WebView::mouseMoveEvent(QMouseEvent *event)
 }
 
 
+void WebView::dropEvent(QDropEvent *event)
+{
+    if (event->mimeData()->hasFormat("application/rekonq-bookmark"))
+    {
+        QByteArray addresses = event->mimeData()->data("application/rekonq-bookmark");
+        KBookmark bookmark =  Application::bookmarkProvider()->bookmarkManager()->findByAddress(QString::fromLatin1(addresses.data()));
+        if (bookmark.isGroup())
+        {
+            Application::bookmarkProvider()->bookmarkOwner()->openFolderinTabs(bookmark.toGroup());
+        }
+        else
+        {
+            emit loadUrl(bookmark.url(), Rekonq::CurrentTab);
+        }
+    }
+    else
+    {
+        KWebView::dropEvent(event);
+    }
+}
+
 void WebView::search()
 {
     KAction *a = qobject_cast<KAction*>(sender());
diff --git a/src/webview.h b/src/webview.h
index 9518b74..acd7eae 100644
--- a/src/webview.h
+++ b/src/webview.h
@@ -60,6 +60,7 @@ protected:
     void mouseMoveEvent(QMouseEvent *event);
     void keyPressEvent(QKeyEvent *event);
     void wheelEvent(QWheelEvent *event);
+    void dropEvent(QDropEvent *event);
 
 private slots:
     void search();
Comment 3 Bernd Oliver Sünderhauf 2013-07-30 13:43:02 UTC
Thanks Yoann! IMHO this feature request is fully implemented, so marking RESOLVED-FIXED.

If something remains missing or should be further improved, I'd propose filing a new followup issue.