m_tabWidget->openNewTab(url, QUrl());
}
+void DolphinMainWindow::openNewTabAndActivate(const QUrl &url)
+{
+ m_tabWidget->openNewActivatedTab(url, QUrl());
+}
+
+void DolphinMainWindow::openNewWindow(const QUrl &url)
+{
+ Dolphin::openNewWindow({url}, this);
+}
+
void DolphinMainWindow::slotSplitViewChanged()
{
m_tabWidget->currentTabPage()->setSplitViewEnabled(GeneralSettings::splitView(), WithAnimation);
foldersPanel, &FoldersPanel::setUrl);
connect(foldersPanel, &FoldersPanel::folderActivated,
this, &DolphinMainWindow::changeUrl);
- connect(foldersPanel, &FoldersPanel::folderMiddleClicked,
+ connect(foldersPanel, &FoldersPanel::folderInNewTab,
this, &DolphinMainWindow::openNewTab);
+ connect(foldersPanel, &FoldersPanel::folderInNewActiveTab,
+ this, &DolphinMainWindow::openNewTabAndActivate);
connect(foldersPanel, &FoldersPanel::errorMessage,
this, &DolphinMainWindow::showErrorMessage);
addDockWidget(Qt::LeftDockWidgetArea, placesDock);
connect(m_placesPanel, &PlacesPanel::placeActivated,
this, &DolphinMainWindow::slotPlaceActivated);
- connect(m_placesPanel, &PlacesPanel::placeMiddleClicked,
+ connect(m_placesPanel, &PlacesPanel::placeActivatedInNewTab,
this, &DolphinMainWindow::openNewTab);
+ connect(m_placesPanel, &PlacesPanel::placeActivatedInNewActiveTab,
+ this, &DolphinMainWindow::openNewTabAndActivate);
connect(m_placesPanel, &PlacesPanel::errorMessage,
this, &DolphinMainWindow::showErrorMessage);
connect(this, &DolphinMainWindow::urlChanged,
this, &DolphinMainWindow::updateSearchAction);
connect(container, &DolphinViewContainer::captionChanged,
this, &DolphinMainWindow::updateWindowTitle);
+ connect(container, &DolphinViewContainer::tabRequested,
+ this, &DolphinMainWindow::openNewTab);
+ connect(container, &DolphinViewContainer::activeTabRequested,
+ this, &DolphinMainWindow::openNewTabAndActivate);
const QAction* toggleSearchAction = actionCollection()->action(QStringLiteral("toggle_search"));
connect(toggleSearchAction, &QAction::triggered, container, &DolphinViewContainer::setSearchModeEnabled);
this, &DolphinMainWindow::fileItemsChanged);
connect(view, &DolphinView::tabRequested,
this, &DolphinMainWindow::openNewTab);
+ connect(view, &DolphinView::activeTabRequested,
+ this, &DolphinMainWindow::openNewTabAndActivate);
+ connect(view, &DolphinView::windowRequested,
+ this, &DolphinMainWindow::openNewWindow);
connect(view, &DolphinView::requestContextMenu,
this, &DolphinMainWindow::openContextMenu);
connect(view, &DolphinView::directoryLoadingStarted,
this, &DolphinMainWindow::slotEditableStateChanged);
connect(navigator, &KUrlNavigator::tabRequested,
this, &DolphinMainWindow::openNewTab);
+ connect(navigator, &KUrlNavigator::activeTabRequested,
+ this, &DolphinMainWindow::openNewTabAndActivate);
+ connect(navigator, &KUrlNavigator::newWindowRequested,
+ this, &DolphinMainWindow::openNewWindow);
}
*/
void openNewTab(const QUrl& url);
+ /**
+ * Opens a new tab showing the URL \a url and activate it.
+ */
+ void openNewTabAndActivate(const QUrl &url);
+
+ /**
+ * Opens a new window showing the URL \a url.
+ */
+ void openNewWindow(const QUrl &url);
+
/** @see GeneralSettings::splitViewChanged() */
void slotSplitViewChanged();
#include <KUrlComboBox>
#include <QDropEvent>
+#include <QGuiApplication>
#include <QLoggingCategory>
#include <QMimeData>
#include <QTimer>
}
}
-void DolphinViewContainer::slotItemActivated(const KFileItem& item)
+void DolphinViewContainer::slotItemActivated(const KFileItem &item)
{
// It is possible to activate items on inactive views by
// drag & drop operations. Assure that activating an item always
const QUrl& url = DolphinView::openItemAsFolderUrl(item, GeneralSettings::browseThroughArchives());
if (!url.isEmpty()) {
- setUrl(url);
+ const auto modifiers = QGuiApplication::keyboardModifiers();
+ // keep in sync with KUrlNavigator::slotNavigatorButtonClicked
+ if (modifiers & Qt::ControlModifier && modifiers & Qt::ShiftModifier) {
+ Q_EMIT activeTabRequested(url);
+ } else if (modifiers & Qt::ControlModifier) {
+ Q_EMIT tabRequested(url);
+ } else if (modifiers & Qt::ShiftModifier) {
+ Dolphin::openNewWindow({KFilePlacesModel::convertedUrl(url)}, this);
+ } else {
+ setUrl(url);
+ }
return;
}
*/
void captionChanged();
+ /**
+ * Is emitted if a new tab should be opened in the background for the URL \a url.
+ */
+ void tabRequested(const QUrl &url);
+
+ /**
+ * Is emitted if a new tab should be opened for the URL \a url and set as active.
+ */
+ void activeTabRequested(const QUrl &url);
+
private Q_SLOTS:
/**
* Updates the number of items (= number of files + number of
* directory is opened in the view. If the item is a file, the file
* gets started by the corresponding application.
*/
- void slotItemActivated(const KFileItem& item);
+ void slotItemActivated(const KFileItem &item);
/**
* Handles activation of multiple files. The files get started by
Q_EMIT itemExpansionToggleClicked(index);
emitItemActivated = false;
- } else if (shiftOrControlPressed) {
- // The mouse click should only update the selection, not trigger the item
+ } else if (shiftOrControlPressed && m_selectionBehavior != SingleSelection) {
+ // The mouse click should only update the selection, not trigger the item, except when
+ // we are in single selection mode
emitItemActivated = false;
- // When Ctrl-clicking an item when in single selection mode
- // i.e. where Ctrl won't change the selection, pretend it was middle clicked
- if (controlPressed && m_selectionBehavior == SingleSelection) {
- Q_EMIT itemMiddleClicked(index);
- }
} else if (!(m_view->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick) || m_singleClickActivationEnforced)) {
if (touch) {
emitItemActivated = true;
* Is emitted if more than one item has been activated by pressing Return/Enter
* when having a selection.
*/
- void itemsActivated(const KItemSet& indexes);
+ void itemsActivated(const KItemSet &indexes);
void itemMiddleClicked(int index);
{
const KFileItem item = m_model->fileItem(index);
if (!item.isNull()) {
- Q_EMIT folderActivated(item.url());
+ const auto modifiers = QGuiApplication::keyboardModifiers();
+ // keep in sync with KUrlNavigator::slotNavigatorButtonClicked
+ if (modifiers & Qt::ControlModifier && modifiers & Qt::ShiftModifier) {
+ Q_EMIT folderInNewActiveTab(item.url());
+ } else if (modifiers & Qt::ControlModifier) {
+ Q_EMIT folderInNewTab(item.url());
+ } else if (modifiers & Qt::ShiftModifier) {
+ // The shift modifier is not considered because it is used to expand the tree view without actually
+ // opening the folder
+ return;
+ } else {
+ Q_EMIT folderActivated(item.url());
+ }
}
}
{
const KFileItem item = m_model->fileItem(index);
if (!item.isNull()) {
- Q_EMIT folderMiddleClicked(item.url());
+ const auto modifiers = QGuiApplication::keyboardModifiers();
+ // keep in sync with KUrlNavigator::slotNavigatorButtonClicked
+ if (modifiers & Qt::ShiftModifier) {
+ Q_EMIT folderInNewActiveTab(item.url());
+ } else {
+ Q_EMIT folderInNewTab(item.url());
+ }
}
}
Q_SIGNALS:
void folderActivated(const QUrl& url);
- void folderMiddleClicked(const QUrl& url);
+ void folderInNewTab(const QUrl &url);
+ void folderInNewActiveTab(const QUrl &url);
void errorMessage(const QString& error);
protected:
#include <KPropertiesDialog>
#include <QActionGroup>
+#include <QApplication>
#include <QGraphicsSceneDragDropEvent>
#include <QIcon>
#include <QMenu>
#include <QToolTip>
PlacesPanel::PlacesPanel(QWidget* parent) :
- Panel(parent),
- m_controller(nullptr),
- m_model(nullptr),
- m_view(nullptr),
- m_storageSetupFailedUrl(),
- m_triggerStorageSetupButton(),
- m_itemDropEventIndex(-1),
- m_itemDropEventMimeData(nullptr),
- m_itemDropEvent(nullptr),
- m_tooltipTimer()
+ Panel(parent),
+ m_controller(nullptr),
+ m_model(nullptr),
+ m_view(nullptr),
+ m_storageSetupFailedUrl(),
+ m_triggerStorageSetupModifier(),
+ m_itemDropEventIndex(-1),
+ m_itemDropEventMimeData(nullptr),
+ m_itemDropEvent(nullptr),
+ m_tooltipTimer()
{
m_tooltipTimer.setInterval(500);
m_tooltipTimer.setSingleShot(true);
void PlacesPanel::slotItemActivated(int index)
{
- triggerItem(index, Qt::LeftButton);
+ const auto modifiers = QGuiApplication::keyboardModifiers();
+ // keep in sync with KUrlNavigator::slotNavigatorButtonClicked
+ if (modifiers & Qt::ControlModifier && modifiers & Qt::ShiftModifier) {
+ triggerItem(index, TriggerItemModifier::ToNewActiveTab);
+ } else if (modifiers & Qt::ControlModifier) {
+ triggerItem(index, TriggerItemModifier::ToNewTab);
+ } else if (modifiers & Qt::ShiftModifier) {
+ triggerItem(index, TriggerItemModifier::ToNewWindow);
+ } else {
+ triggerItem(index, TriggerItemModifier::None);
+ }
}
void PlacesPanel::slotItemMiddleClicked(int index)
{
- triggerItem(index, Qt::MiddleButton);
+ const auto modifiers = QGuiApplication::keyboardModifiers();
+ // keep in sync with KUrlNavigator::slotNavigatorButtonClicked
+ if (modifiers & Qt::ShiftModifier) {
+ triggerItem(index, TriggerItemModifier::ToNewActiveTab);
+ } else {
+ triggerItem(index, TriggerItemModifier::ToNewTab);
+ }
}
void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
} else if (action == openInNewWindowAction) {
Dolphin::openNewWindow({KFilePlacesModel::convertedUrl(m_model->data(index).value("url").toUrl())}, this);
} else if (action == openInNewTabAction) {
- // TriggerItem does set up the storage first and then it will
- // emit the slotItemMiddleClicked signal, because of Qt::MiddleButton.
- triggerItem(index, Qt::MiddleButton);
+ triggerItem(index, TriggerItemModifier::ToNewTab);
} else if (action == mountAction) {
m_model->requestStorageSetup(index);
} else if (action == teardownAction) {
disconnect(m_model, &PlacesItemModel::storageSetupDone,
this, &PlacesPanel::slotStorageSetupDone);
- if (m_triggerStorageSetupButton == Qt::NoButton) {
+ if (m_triggerStorageSetupModifier == TriggerItemModifier::None) {
return;
}
if (success) {
Q_ASSERT(!m_model->storageSetupNeeded(index));
- triggerItem(index, m_triggerStorageSetupButton);
- m_triggerStorageSetupButton = Qt::NoButton;
+ triggerItem(index, m_triggerStorageSetupModifier);
+ m_triggerStorageSetupModifier = TriggerItemModifier::None;
} else {
setUrl(m_storageSetupFailedUrl);
m_storageSetupFailedUrl = QUrl();
}
}
-void PlacesPanel::triggerItem(int index, Qt::MouseButton button)
+void PlacesPanel::triggerItem(int index, TriggerItemModifier modifier)
{
const PlacesItem* item = m_model->placesItem(index);
if (!item) {
}
if (m_model->storageSetupNeeded(index)) {
- m_triggerStorageSetupButton = button;
+ m_triggerStorageSetupModifier = modifier;
m_storageSetupFailedUrl = url();
connect(m_model, &PlacesItemModel::storageSetupDone,
m_model->requestStorageSetup(index);
} else {
- m_triggerStorageSetupButton = Qt::NoButton;
+ m_triggerStorageSetupModifier = TriggerItemModifier::None;
const QUrl url = m_model->data(index).value("url").toUrl();
if (!url.isEmpty()) {
- if (button == Qt::MiddleButton) {
- Q_EMIT placeMiddleClicked(KFilePlacesModel::convertedUrl(url));
- } else {
- Q_EMIT placeActivated(KFilePlacesModel::convertedUrl(url));
+ switch (modifier) {
+ case TriggerItemModifier::ToNewTab:
+ Q_EMIT placeActivatedInNewTab(KFilePlacesModel::convertedUrl(url));
+ break;
+ case TriggerItemModifier::ToNewActiveTab:
+ Q_EMIT placeActivatedInNewActiveTab(KFilePlacesModel::convertedUrl(url));
+ break;
+ case TriggerItemModifier::ToNewWindow:
+ Dolphin::openNewWindow({KFilePlacesModel::convertedUrl(url)}, this);
+ break;
+ case TriggerItemModifier::None:
+ Q_EMIT placeActivated(KFilePlacesModel::convertedUrl(url));
+ break;
}
}
}
Q_SIGNALS:
void placeActivated(const QUrl& url);
- void placeMiddleClicked(const QUrl& url);
+ void placeActivatedInNewTab(const QUrl &url);
+ void placeActivatedInNewActiveTab(const QUrl &url);
void errorMessage(const QString& error);
void storageTearDownRequested(const QString& mountPath);
void storageTearDownExternallyRequested(const QString& mountPath);
void slotStorageSetupDone(int index, bool success);
void slotShowTooltip();
+private:
+ enum class TriggerItemModifier { None, ToNewTab, ToNewActiveTab, ToNewWindow };
+
private:
void addEntry();
void editEntry(int index);
*/
void selectItem();
- void triggerItem(int index, Qt::MouseButton button);
+ void triggerItem(int index, TriggerItemModifier modifier);
QAction* buildGroupContextMenu(QMenu* menu, int index);
PlacesView* m_view;
QUrl m_storageSetupFailedUrl;
- Qt::MouseButton m_triggerStorageSetupButton;
+ TriggerItemModifier m_triggerStorageSetupModifier;
int m_itemDropEventIndex;
QMimeData* m_itemDropEventMimeData;
}
}
-void DolphinView::slotItemsActivated(const KItemSet& indexes)
+void DolphinView::slotItemsActivated(const KItemSet &indexes)
{
Q_ASSERT(indexes.count() >= 2);
abortTwoClicksRenaming();
+ const auto modifiers = QGuiApplication::keyboardModifiers();
+
if (indexes.count() > 5) {
QString question = i18np("Are you sure you want to open 1 item?", "Are you sure you want to open %1 items?", indexes.count());
const int answer = KMessageBox::warningYesNo(this, question);
KFileItem item = m_model->fileItem(index);
const QUrl& url = openItemAsFolderUrl(item);
- if (!url.isEmpty()) { // Open folders in new tabs
- Q_EMIT tabRequested(url);
+ if (!url.isEmpty()) {
+ // Open folders in new tabs or in new windows depending on the modifier
+ // The ctrl+shift behavior is ignored because we are handling multiple items
+ // keep in sync with KUrlNavigator::slotNavigatorButtonClicked
+ if (modifiers & Qt::ShiftModifier && !(modifiers & Qt::ControlModifier)) {
+ Q_EMIT windowRequested(url);
+ } else {
+ Q_EMIT tabRequested(url);
+ }
} else {
items.append(item);
}
{
const KFileItem& item = m_model->fileItem(index);
const QUrl& url = openItemAsFolderUrl(item);
+ const auto modifiers = QGuiApplication::keyboardModifiers();
if (!url.isEmpty()) {
- Q_EMIT tabRequested(url);
+ // keep in sync with KUrlNavigator::slotNavigatorButtonClicked
+ if (modifiers & Qt::ShiftModifier) {
+ Q_EMIT activeTabRequested(url);
+ } else {
+ Q_EMIT tabRequested(url);
+ }
} else if (isTabsForFilesEnabled()) {
- Q_EMIT tabRequested(item.url());
+ // keep in sync with KUrlNavigator::slotNavigatorButtonClicked
+ if (modifiers & Qt::ShiftModifier) {
+ Q_EMIT activeTabRequested(item.url());
+ } else {
+ Q_EMIT tabRequested(item.url());
+ }
}
}
/**
* Is emitted when clicking on an item with the left mouse button.
*/
- void itemActivated(const KFileItem& item);
+ void itemActivated(const KFileItem &item);
/**
* Is emitted when multiple items have been activated by e. g.
* context menu open with.
*/
- void itemsActivated(const KFileItemList& items);
+ void itemsActivated(const KFileItemList &items);
/**
* Is emitted if items have been added or deleted.
*/
void tabRequested(const QUrl& url);
+ /**
+ * Is emitted if a new tab should be opened for the URL \a url and set as active.
+ */
+ void activeTabRequested(const QUrl &url);
+
+ /**
+ * Is emitted if a new window should be opened for the URL \a url.
+ */
+ void windowRequested(const QUrl &url);
+
/**
* Is emitted if the view mode (IconsView, DetailsView,
* PreviewsView) has been changed.
void activate();
void slotItemActivated(int index);
- void slotItemsActivated(const KItemSet& indexes);
+ void slotItemsActivated(const KItemSet &indexes);
void slotItemMiddleClicked(int index);
void slotItemContextMenuRequested(int index, const QPointF& pos);
void slotViewContextMenuRequested(const QPointF& pos);