K_GLOBAL_STATIC(KModifierKeyInfo, m_keyInfo)
DolphinContextMenu::DolphinContextMenu(DolphinMainWindow* parent,
+ const QPoint& pos,
const KFileItem& fileInfo,
const KUrl& baseUrl) :
+ QObject(parent),
+ m_pos(pos),
m_mainWindow(parent),
m_fileInfo(fileInfo),
m_baseUrl(baseUrl),
addShowMenuBarAction();
- QAction *action = m_popup->exec(QCursor::pos());
+ QAction *action = m_popup->exec(m_pos);
if (action == emptyTrashAction) {
KonqOperations::emptyTrash(m_mainWindow);
} else if (action == addToPlacesAction) {
QAction* propertiesAction = m_mainWindow->actionCollection()->action("properties");
m_popup->addAction(propertiesAction);
- if (m_popup->exec(QCursor::pos()) == restoreAction) {
+ if (m_popup->exec(m_pos) == restoreAction) {
KUrl::List selectedUrls;
foreach (const KFileItem &item, m_selectedItems) {
selectedUrls.append(item.url());
QAction* propertiesAction = m_mainWindow->actionCollection()->action("properties");
m_popup->addAction(propertiesAction);
- QAction* activatedAction = m_popup->exec(QCursor::pos());
+ QAction* activatedAction = m_popup->exec(m_pos);
if (activatedAction) {
if (activatedAction == addToPlacesAction) {
const KUrl selectedUrl(m_fileInfo.url());
addShowMenuBarAction();
- QAction* action = m_popup->exec(QCursor::pos());
+ QAction* action = m_popup->exec(m_pos);
if (addToPlacesAction && (action == addToPlacesAction)) {
const KUrl url = m_mainWindow->activeViewContainer()->url();
if (url.isValid()) {
/**
* @parent Pointer to the main window the context menu
* belongs to.
+ * @pos Position in screen coordinates.
* @fileInfo Pointer to the file item the context menu
* is applied. If 0 is passed, the context menu
* is above the viewport.
* should be opened.
*/
DolphinContextMenu(DolphinMainWindow* parent,
+ const QPoint& pos,
const KFileItem& fileInfo,
const KUrl& baseUrl);
TrashContext = 2
};
+ QPoint m_pos;
DolphinMainWindow* m_mainWindow;
KFileItem m_fileInfo;
#endif
}
-void DolphinMainWindow::openContextMenu(const KFileItem& item,
+void DolphinMainWindow::openContextMenu(const QPoint& pos,
+ const KFileItem& item,
const KUrl& url,
const QList<QAction*>& customActions)
{
- QPointer<DolphinContextMenu> contextMenu = new DolphinContextMenu(this, item, url);
- contextMenu->setCustomActions(customActions);
- const DolphinContextMenu::Command command = contextMenu->open();
+ QWeakPointer<DolphinContextMenu> contextMenu = new DolphinContextMenu(this, pos, item, url);
+ contextMenu.data()->setCustomActions(customActions);
+ const DolphinContextMenu::Command command = contextMenu.data()->open();
switch (command) {
case DolphinContextMenu::OpenParentFolderInNewWindow: {
break;
}
- delete contextMenu;
+ delete contextMenu.data();
}
void DolphinMainWindow::updateToolBarMenu()
this, SLOT(toggleActiveView()));
connect(view, SIGNAL(tabRequested(KUrl)),
this, SLOT(openNewTab(KUrl)));
- connect(view, SIGNAL(requestContextMenu(KFileItem,KUrl,QList<QAction*>)),
- this, SLOT(openContextMenu(KFileItem,KUrl,QList<QAction*>)));
+ connect(view, SIGNAL(requestContextMenu(QPoint,KFileItem,KUrl,QList<QAction*>)),
+ this, SLOT(openContextMenu(QPoint,KFileItem,KUrl,QList<QAction*>)));
connect(view, SIGNAL(startedPathLoading(KUrl)),
this, SLOT(enableStopAction()));
connect(view, SIGNAL(finishedPathLoading(KUrl)),
/**
* Opens the context menu on the current mouse position.
+ * @pos Position in screen coordinates.
* @item File item context. If item is null, the context menu
* should be applied to \a url.
* @url URL which contains \a item.
* @customActions Actions that should be added to the context menu,
* if the file item is null.
*/
- void openContextMenu(const KFileItem& item,
+ void openContextMenu(const QPoint& pos,
+ const KFileItem& item,
const KUrl& url,
const QList<QAction*>& customActions);
this, SLOT(slotItemActivated(KFileItem)));
connect(m_view, SIGNAL(tabRequested(KUrl)),
this, SLOT(createNewWindow(KUrl)));
- connect(m_view, SIGNAL(requestContextMenu(KFileItem,KUrl,QList<QAction*>)),
- this, SLOT(slotOpenContextMenu(KFileItem,KUrl,QList<QAction*>)));
+ connect(m_view, SIGNAL(requestContextMenu(QPoint,KFileItem,KUrl,QList<QAction*>)),
+ this, SLOT(slotOpenContextMenu(QPoint,KFileItem,KUrl,QList<QAction*>)));
connect(m_view, SIGNAL(selectionChanged(KFileItemList)),
m_extension, SIGNAL(selectionInfo(KFileItemList)));
connect(m_view, SIGNAL(selectionChanged(KFileItemList)),
emit m_extension->createNewWindow(url);
}
-void DolphinPart::slotOpenContextMenu(const KFileItem& _item,
+void DolphinPart::slotOpenContextMenu(const QPoint& pos,
+ const KFileItem& _item,
const KUrl&,
const QList<QAction*>& customActions)
{
actionGroups.insert("editactions", editActions);
- emit m_extension->popupMenu(QCursor::pos(),
+ emit m_extension->popupMenu(pos,
items,
KParts::OpenUrlArguments(),
KParts::BrowserArguments(),
void createNewWindow(const KUrl& url);
/**
* Opens the context menu on the current mouse position.
+ * @pos Position in screen coordinates.
* @item File item context. If item is null, the context menu
* should be applied to \a url.
* @url URL which contains \a item.
* @customActions Actions that should be added to the context menu,
* if the file item is null.
*/
- void slotOpenContextMenu(const KFileItem& item,
+ void slotOpenContextMenu(const QPoint& pos,
+ const KFileItem& item,
const KUrl& url,
const QList<QAction*>& customActions);
#include <KIconEffect>
#include <KIO/NetAccess>
#include <KIO/PreviewJob>
-#include <KMenu>
#include <KNewFileMenu>
#include <konqmimedata.h>
#include <konq_operations.h>
break;
}
- return true;
- } else {
if (event->buttons() & Qt::RightButton) {
- m_selectionManager->clearSelection();
+ emit itemContextMenuRequested(m_pressedIndex, event->screenPos());
}
- KItemListRubberBand* rubberBand = m_view->rubberBand();
- QPointF startPos = m_pressedMousePos;
- if (m_view->scrollOrientation() == Qt::Vertical) {
- startPos.ry() += m_view->scrollOffset();
- if (m_view->itemSize().width() < 0) {
- // Use a special rubberband for views that have only one column and
- // expand the rubberband to use the whole width of the view.
- startPos.setX(0);
- }
+ return true;
+ }
+
+ if (event->buttons() & Qt::RightButton) {
+ m_selectionManager->clearSelection();
+
+ const QRectF headerBounds = m_view->headerBoundaries();
+ if (headerBounds.contains(event->pos())) {
+ emit headerContextMenuRequested(event->screenPos());
} else {
- startPos.rx() += m_view->scrollOffset();
+ emit viewContextMenuRequested(event->screenPos());
}
+ return true;
+ }
- m_oldSelection = m_selectionManager->selectedItems();
- rubberBand->setStartPosition(startPos);
- rubberBand->setEndPosition(startPos);
- rubberBand->setActive(true);
- connect(rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandChanged()));
- m_view->setAutoScroll(true);
+ KItemListRubberBand* rubberBand = m_view->rubberBand();
+ QPointF startPos = m_pressedMousePos;
+ if (m_view->scrollOrientation() == Qt::Vertical) {
+ startPos.ry() += m_view->scrollOffset();
+ if (m_view->itemSize().width() < 0) {
+ // Use a special rubberband for views that have only one column and
+ // expand the rubberband to use the whole width of the view.
+ startPos.setX(0);
+ }
+ } else {
+ startPos.rx() += m_view->scrollOffset();
}
+ m_oldSelection = m_selectionManager->selectedItems();
+ rubberBand->setStartPosition(startPos);
+ rubberBand->setEndPosition(startPos);
+ rubberBand->setActive(true);
+ connect(rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandChanged()));
+ m_view->setAutoScroll(true);
+
return false;
}
}
} else if (event->button() & Qt::MidButton) {
emit itemMiddleClicked(index);
- } else if (event->button() & Qt::RightButton) {
- emit contextMenuRequested(index, QPointF(event->pos()));
}
} else if (clearSelection) {
m_selectionManager->clearSelection();
signals:
void itemActivated(int index);
void itemMiddleClicked(int index);
- void contextMenuRequested(int index, const QPointF& pos);
+
+ /**
+ * Emitted if a context-menu is requested for the item with
+ * the index \a index. It is assured that the index is valid.
+ */
+ void itemContextMenuRequested(int index, const QPointF& pos);
+
+ /**
+ * Emitted if a context-menu is requested for the KItemListView.
+ */
+ void viewContextMenuRequested(const QPointF& pos);
+
+ /**
+ * Emitted if a context-menu is requested for the header of the KItemListView.
+ */
+ void headerContextMenuRequested(const QPointF& pos);
/**
* Is emitted if the item with the index \p index gets hovered.
#include "kitemlistheader_p.h"
+#include <KAction>
+#include <KMenu>
#include "kitemmodelbase.h"
#include <QApplication>
void KItemListHeader::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
- event->accept();
- updatePressedRoleIndex(event->pos());
- m_pressedMousePos = event->pos();
- m_roleOperation = isAboveRoleGrip(m_pressedMousePos, m_pressedRoleIndex) ?
- ResizeRoleOperation : NoRoleOperation;
+ if (event->button() & Qt::LeftButton) {
+ updatePressedRoleIndex(event->pos());
+ m_pressedMousePos = event->pos();
+ m_roleOperation = isAboveRoleGrip(m_pressedMousePos, m_pressedRoleIndex) ?
+ ResizeRoleOperation : NoRoleOperation;
+ event->accept();
+ } else {
+ event->ignore();
+ }
}
void KItemListHeader::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
return m_activeTransactions > 0;
}
+
+void KItemListView::setHeaderShown(bool show)
+{
+
+ if (show && !m_header) {
+ m_header = new KItemListHeader(this);
+ m_header->setPos(0, 0);
+ m_header->setModel(m_model);
+ m_header->setVisibleRoles(m_visibleRoles);
+ m_header->setVisibleRolesWidths(headerRolesWidths());
+ m_header->setZValue(1);
+
+ m_useHeaderWidths = false;
+
+ connect(m_header, SIGNAL(visibleRoleWidthChanged(QByteArray,qreal,qreal)),
+ this, SLOT(slotVisibleRoleWidthChanged(QByteArray,qreal,qreal)));
+
+ m_layouter->setHeaderHeight(m_header->size().height());
+ } else if (!show && m_header) {
+ delete m_header;
+ m_header = 0;
+ m_useHeaderWidths = false;
+ m_layouter->setHeaderHeight(0);
+ }
+}
+
+bool KItemListView::isHeaderShown() const
+{
+ return m_header != 0;
+}
+
QPixmap KItemListView::createDragPixmap(const QSet<int>& indexes) const
{
Q_UNUSED(indexes);
}
}
-void KItemListView::setHeaderShown(bool show)
-{
- if (show && !m_header) {
- m_header = new KItemListHeader(this);
- m_header->setPos(0, 0);
- m_header->setModel(m_model);
- m_header->setVisibleRoles(m_visibleRoles);
- m_header->setVisibleRolesWidths(headerRolesWidths());
- m_header->setZValue(1);
-
- m_useHeaderWidths = false;
-
- connect(m_header, SIGNAL(visibleRoleWidthChanged(QByteArray,qreal,qreal)),
- this, SLOT(slotVisibleRoleWidthChanged(QByteArray,qreal,qreal)));
-
- m_layouter->setHeaderHeight(m_header->size().height());
- } else if (!show && m_header) {
- delete m_header;
- m_header = 0;
- m_useHeaderWidths = false;
- m_layouter->setHeaderHeight(0);
- }
-}
-
qreal KItemListView::visibleRolesSizesWidthSum() const
{
qreal widthSum = 0;
return heightSum;
}
+QRectF KItemListView::headerBoundaries() const
+{
+ return m_header ? m_header->geometry() : QRectF();
+}
+
int KItemListView::calculateAutoScrollingIncrement(int pos, int range, int oldInc)
{
int inc = 0;
void endTransaction();
bool isTransactionActive() const;
+ /**
+ * Turns on the header if \p show is true. Per default the
+ * header is not shown.
+ */
+ void setHeaderShown(bool show);
+ bool isHeaderShown() const;
+
/**
* @return Pixmap that is used for a drag operation based on the
* items given by \a indexes. The default implementation returns
*/
void updateStretchedVisibleRolesSizes();
- /**
- * Turns on the header if \p show is true. Per default the
- * header is not shown.
- */
- void setHeaderShown(bool show);
-
/**
* @return Sum of the widths of all visible roles.
*/
*/
qreal visibleRolesSizesHeightSum() const;
+ /**
+ * @return Boundaries of the header. An empty rectangle is returned
+ * if no header is shown.
+ */
+ QRectF headerBoundaries() const;
+
/**
* Helper function for triggerAutoScrolling().
* @param pos Logical position of the mouse relative to the range.
connect(controller, SIGNAL(itemActivated(int)),
this, SLOT(slotItemActivated(int)));
connect(controller, SIGNAL(itemMiddleClicked(int)), this, SLOT(slotItemMiddleClicked(int)));
- connect(controller, SIGNAL(contextMenuRequested(int,QPointF)), this, SLOT(slotContextMenuRequested(int,QPointF)));
+ connect(controller, SIGNAL(itemContextMenuRequested(int,QPointF)), this, SLOT(slotItemContextMenuRequested(int,QPointF)));
+ connect(controller, SIGNAL(viewContextMenuRequested(QPointF)), this, SLOT(slotViewContextMenuRequested(QPointF)));
+ connect(controller, SIGNAL(headerContextMenuRequested(QPointF)), this, SLOT(slotHeaderContextMenuRequested(QPointF)));
connect(controller, SIGNAL(itemExpansionToggleClicked(int)), this, SLOT(slotItemExpansionToggleClicked(int)));
connect(controller, SIGNAL(itemHovered(int)), this, SLOT(slotItemHovered(int)));
connect(controller, SIGNAL(itemUnhovered(int)), this, SLOT(slotItemUnhovered(int)));
setActive(true);
}
-void DolphinView::contextMenuEvent(QContextMenuEvent* event)
-{
- Q_UNUSED(event);
-
- const QPoint pos = m_container->mapFromGlobal(QCursor::pos());
- const KItemListView* view = m_container->controller()->view();
- if (view->itemAt(pos) < 0) {
- // Only open the context-menu if the cursor is above the viewport
- // (the context-menu for items is handled in slotContextMenuRequested())
- requestContextMenu(KFileItem(), url(), QList<QAction*>());
- }
-}
-
-void DolphinView::wheelEvent(QWheelEvent* event)
-{
- if (event->modifiers().testFlag(Qt::ControlModifier)) {
- const int numDegrees = event->delta() / 8;
- const int numSteps = numDegrees / 15;
-
- setZoomLevel(zoomLevel() + numSteps);
- event->accept();
- } else {
- event->ignore();
- }
-}
-
void DolphinView::activate()
{
setActive(true);
}
}
-void DolphinView::slotContextMenuRequested(int index, const QPointF& pos)
+void DolphinView::slotItemContextMenuRequested(int index, const QPointF& pos)
{
- Q_UNUSED(pos);
if (GeneralSettings::showToolTips()) {
m_toolTipManager->hideToolTip();
}
const KFileItem item = fileItemModel()->fileItem(index);
- emit requestContextMenu(item, url(), QList<QAction*>());
+ emit requestContextMenu(pos.toPoint(), item, url(), QList<QAction*>());
+}
+
+void DolphinView::slotViewContextMenuRequested(const QPointF& pos)
+{
+ if (GeneralSettings::showToolTips()) {
+ m_toolTipManager->hideToolTip();
+ }
+ emit requestContextMenu(pos.toPoint(), KFileItem(), url(), QList<QAction*>());
+}
+
+void DolphinView::slotHeaderContextMenuRequested(const QPointF& pos)
+{
+ QWeakPointer<KMenu> menu = new KMenu(QApplication::activeWindow());
+
+ KItemListView* view = m_container->controller()->view();
+ const QSet<QByteArray> visibleRolesSet = view->visibleRoles().toSet();
+
+ // Add all roles to the menu that can be shown or hidden by the user
+ const AdditionalInfoAccessor& infoAccessor = AdditionalInfoAccessor::instance();
+ const QList<DolphinView::AdditionalInfo> keys = infoAccessor.keys();
+ foreach (const DolphinView::AdditionalInfo info, keys) {
+ const QByteArray& role = infoAccessor.role(info);
+ if (role != "name") {
+ const QString text = fileItemModel()->roleDescription(role);
+
+ QAction* action = menu.data()->addAction(text);
+ action->setCheckable(true);
+ action->setChecked(visibleRolesSet.contains(role));
+ action->setData(info);
+ }
+ }
+
+ QAction* action = menu.data()->exec(pos.toPoint());
+ if (action) {
+ // Show or hide the selected role
+ const DolphinView::AdditionalInfo info =
+ static_cast<DolphinView::AdditionalInfo>(action->data().toInt());
+
+ const QByteArray selectedRole = infoAccessor.role(info);
+ QList<QByteArray> visibleRoles = view->visibleRoles();
+ if (action->isChecked()) {
+ const int index = keys.indexOf(info);
+ visibleRoles.insert(index + 1, selectedRole);
+ } else {
+ visibleRoles.removeOne(selectedRole);
+ }
+ view->setVisibleRoles(visibleRoles);
+ }
+
+ delete menu.data();
}
void DolphinView::slotItemExpansionToggleClicked(int index)
emit selectionChanged(selectedItems());
}
-void DolphinView::openContextMenu(const QPoint& pos,
- const QList<QAction*>& customActions)
-{
- KFileItem item;
- const int index = m_container->controller()->view()->itemAt(pos);
- if (index >= 0) {
- item = fileItemModel()->fileItem(index);
- }
-
- emit requestContextMenu(item, url(), customActions);
-}
-
void DolphinView::dropUrls(const KFileItem& destItem,
const KUrl& destPath,
QDropEvent* event)
* for the URL should be shown and the custom actions \a customActions
* will be added.
*/
- void requestContextMenu(const KFileItem& item,
+ void requestContextMenu(const QPoint& pos,
+ const KFileItem& item,
const KUrl& url,
const QList<QAction*>& customActions);
protected:
virtual void mouseReleaseEvent(QMouseEvent* event);
- virtual void contextMenuEvent(QContextMenuEvent* event);
- virtual void wheelEvent(QWheelEvent* event);
private slots:
/**
void slotItemActivated(int index);
void slotItemMiddleClicked(int index);
- void slotContextMenuRequested(int index, const QPointF& pos);
+ void slotItemContextMenuRequested(int index, const QPointF& pos);
+ void slotViewContextMenuRequested(const QPointF& pos);
+ void slotHeaderContextMenuRequested(const QPointF& pos);
void slotItemExpansionToggleClicked(int index);
void slotItemHovered(int index);
void slotItemUnhovered(int index);
*/
void emitSelectionChangedSignal();
- /**
- * Opens the context menu on position \a pos. The position
- * is used to check whether the context menu is related to an
- * item or to the viewport.
- */
- void openContextMenu(const QPoint& pos, const QList<QAction*>& customActions);
-
/**
* Drops dragged URLs to the destination path \a destPath. If
* the URLs are dropped above an item inside the destination path,