From 05710490e9e4da45c8c9caaf8a998b851bd99085 Mon Sep 17 00:00:00 2001 From: Yoann Laissus Date: Tue, 17 Aug 2010 12:43:07 +0200 Subject: - 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 --- src/bookmarks/bookmarkstoolbar.cpp | 432 +++++++++++++++++++++++++++++++++++++ 1 file changed, 432 insertions(+) create mode 100644 src/bookmarks/bookmarkstoolbar.cpp (limited to 'src/bookmarks/bookmarkstoolbar.cpp') diff --git a/src/bookmarks/bookmarkstoolbar.cpp b/src/bookmarks/bookmarkstoolbar.cpp new file mode 100644 index 00000000..e9ab8a5a --- /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 +* Copyright (C) 2010 by Yoann Laissus +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +* ============================================================ */ + + +// Self Includes +#include "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(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(sender()); + if (action) + Application::instance()->mainWindow()->notifyMessage(action->bookmark().url().url()); +} + + +// ------------------------------------------------------------------------------------------------------ + +#include + +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(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(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(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(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(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(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(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; +} -- cgit v1.2.1