KWindowSystem::activateWindow(window()->effectiveWinId());
}
+bool DolphinMainWindow::isActiveWindow()
+{
+ return window()->isActiveWindow();
+}
+
void DolphinMainWindow::showCommand(CommandType command)
{
DolphinStatusBar* statusBar = m_activeViewContainer->statusBar();
return m_tabWidget->isUrlOpen(QUrl::fromUserInput(url));
}
+bool DolphinMainWindow::isUrlOrParentOpen(const QString &url)
+{
+ return m_tabWidget->isUrlOrParentOpen(QUrl::fromUserInput(url));
+}
*/
void activateWindow();
+ bool isActiveWindow();
+
/**
* Determines if a URL is open in any tab.
* @note Use of QString instead of QUrl is required to be callable via DBus.
*/
bool isUrlOpen(const QString &url);
+ /**
+ * Determines if a URL or it's parent is open in any tab.
+ * @note Use of QString instead of QUrl is required to be callable via DBus.
+ *
+ * @param url URL to look for
+ * @returns true if url or it's parent is currently open in a tab, false otherwise.
+ */
+ bool isUrlOrParentOpen(const QString &url);
+
/**
* Pastes the clipboard data into the currently selected folder
return indexByUrl(url).first >= 0;
}
+bool DolphinTabWidget::isUrlOrParentOpen(const QUrl &url) const
+{
+ return indexByUrl(url, ReturnIndexForOpenedParentAlso).first >= 0;
+}
+
void DolphinTabWidget::openNewActivatedTab()
{
std::unique_ptr<DolphinUrlNavigator::VisualState> oldNavigatorState;
}
}
-void DolphinTabWidget::openDirectories(const QList<QUrl>& dirs, bool splitView)
+void DolphinTabWidget::openDirectories(const QList<QUrl>& dirs, bool splitView, bool skipChildUrls)
{
Q_ASSERT(dirs.size() > 0);
QList<QUrl>::const_iterator it = dirs.constBegin();
while (it != dirs.constEnd()) {
const QUrl& primaryUrl = *(it++);
- const QPair<int, bool> indexInfo = indexByUrl(primaryUrl);
+ const QPair<int, bool> indexInfo = indexByUrl(primaryUrl, skipChildUrls ? ReturnIndexForOpenedParentAlso : ReturnIndexForOpenedUrlOnly);
const int index = indexInfo.first;
const bool isInPrimaryView = indexInfo.second;
- // When the user asks for a URL that's already open, activate it instead
- // of opening a second copy
+ // When the user asks for a URL that's already open (or it's parent is open if skipChildUrls is set),
+ // activate it instead of opening a new tab
if (index >= 0) {
somethingWasAlreadyOpen = true;
activateTab(index);
}
const int oldTabCount = count();
- openDirectories(dirs, splitView);
+ openDirectories(dirs, splitView, true);
const int tabCount = count();
// Select the files. Although the files can be split between several
return name.replace('&', QLatin1String("&&"));
}
-QPair<int, bool> DolphinTabWidget::indexByUrl(const QUrl& url) const
+QPair<int, bool> DolphinTabWidget::indexByUrl(const QUrl& url, ChildUrlBehavior childUrlBehavior) const
{
- for (int i = 0; i < count(); i++) {
+ int i = currentIndex();
+ if (i < 0) {
+ return qMakePair(-1, false);
+ }
+ // loop over the tabs starting from the current one
+ do {
const auto tabPage = tabPageAt(i);
- if (url == tabPage->primaryViewContainer()->url()) {
+ if (tabPage->primaryViewContainer()->url() == url ||
+ childUrlBehavior == ReturnIndexForOpenedParentAlso && tabPage->primaryViewContainer()->url().isParentOf(url)) {
return qMakePair(i, true);
}
- if (tabPage->splitViewEnabled() && url == tabPage->secondaryViewContainer()->url()) {
+ if (tabPage->splitViewEnabled() &&
+ (url == tabPage->secondaryViewContainer()->url() ||
+ childUrlBehavior == ReturnIndexForOpenedParentAlso && tabPage->secondaryViewContainer()->url().isParentOf(url))) {
return qMakePair(i, false);
}
+
+ i = (i + 1) % count();
}
+ while (i != currentIndex());
+
return qMakePair(-1, false);
}
void refreshViews();
/**
- * @return Whether any of the tab pages contains @p url in their primary
- * or secondary view.
+ * @return Whether any of the tab pages has @p url opened
+ * in their primary or secondary view.
*/
bool isUrlOpen(const QUrl& url) const;
+ /**
+ * @return Whether any of the tab pages has @p url or it's parent opened
+ * in their primary or secondary view.
+ */
+ bool isUrlOrParentOpen(const QUrl& url) const;
+
Q_SIGNALS:
/**
* Is emitted when the active view has been changed, by changing the current
void openNewTab(const QUrl &primaryUrl, const QUrl &secondaryUrl = QUrl());
/**
- * Opens each directory in \p dirs in a separate tab. If \a splitView is set,
- * 2 directories are collected within one tab.
+ * Opens each directory in \p dirs in a separate tab unless it is already open.
+ * If \a splitView is set, 2 directories are collected within one tab.
+ * If \a skipChildUrls is set, do not open a directory if it's parent is already open.
* \pre \a dirs must contain at least one url.
*/
- void openDirectories(const QList<QUrl>& dirs, bool splitView);
+ void openDirectories(const QList<QUrl>& dirs, bool splitView, bool skipChildUrls = false);
/**
* Opens the directories which contain the files \p files and selects all files.
*/
QString tabName(DolphinTabPage* tabPage) const;
+ enum ChildUrlBehavior {
+ ReturnIndexForOpenedUrlOnly,
+ ReturnIndexForOpenedParentAlso
+ };
+
/**
* @param url The URL that we would like
- * @return a QPair with first containing the index of the tab with the
- * desired URL or -1 if not found. Second says true if URL is in primary
- * view container, false otherwise. False means the URL is in the secondary
- * view container, unless first == -1. In that case the value of second
- * is meaningless.
- */
- QPair<int, bool> indexByUrl(const QUrl& url) const;
+ * @param childUrlBehavior Whether a tab with opened parent of the URL can be returned too
+ * @return a QPair with:
+ * First containing the index of the tab with the desired URL or -1 if not found.
+ * Second says true if URL is in primary view container, false otherwise.
+ * False means the URL is in the secondary view container, unless first == -1.
+ * In that case the value of second is meaningless.
+ */
+ QPair<int, bool> indexByUrl(const QUrl& url, ChildUrlBehavior childUrlBehavior = ReturnIndexForOpenedUrlOnly) const;
private:
QPointer<DolphinTabPage> m_lastViewedTab;
return false;
}
- QStringList newUrls;
+ int activeWindowIndex = -1;
+ for (const auto& interface: qAsConst(dolphinInterfaces)) {
+ ++activeWindowIndex;
+
+ auto isActiveWindowReply = interface.first->isActiveWindow();
+ isActiveWindowReply.waitForFinished();
+ if (!isActiveWindowReply.isError() && isActiveWindowReply.value()) {
+ break;
+ }
+ }
- // check to see if any instances already have any of the given URLs open
+ // check to see if any instances already have any of the given URLs or their parents open
const auto urls = QUrl::toStringList(inputUrls);
for (const QString& url : urls) {
bool urlFound = false;
- for (auto& interface: dolphinInterfaces) {
- auto isUrlOpenReply = interface.first->isUrlOpen(url);
+
+ // looping through the windows starting from the active one
+ int i = activeWindowIndex;
+ do {
+ auto &interface = dolphinInterfaces[i];
+
+ auto isUrlOpenReply = openFiles ? interface.first->isUrlOrParentOpen(url) : interface.first->isUrlOpen(url);
isUrlOpenReply.waitForFinished();
if (!isUrlOpenReply.isError() && isUrlOpenReply.value()) {
interface.second.append(url);
urlFound = true;
break;
}
+
+ i = (i + 1) % dolphinInterfaces.size();
}
+ while (i != activeWindowIndex);
+
if (!urlFound) {
- newUrls.append(url);
+ dolphinInterfaces[activeWindowIndex].second.append(url);
}
}
for (const auto& interface: qAsConst(dolphinInterfaces)) {
- auto reply = openFiles ? interface.first->openFiles(newUrls, splitView) : interface.first->openDirectories(newUrls, splitView);
+ if (interface.second.isEmpty()) {
+ continue;
+ }
+ auto reply = openFiles ?
+ interface.first->openFiles(interface.second, splitView) :
+ interface.first->openDirectories(interface.second, splitView);
reply.waitForFinished();
if (!reply.isError()) {
interface.first->activateWindow();
attached = true;
- break;
}
}
return attached;