mirror of
https://invent.kde.org/system/dolphin
synced 2024-08-22 01:40:02 +00:00
do not open excessive tab
even if directory of the file to be created is not the top-most opened in TreeView BUG: 440663
This commit is contained in:
parent
0b208fd990
commit
73ff57bef4
|
@ -285,6 +285,11 @@ void DolphinMainWindow::activateWindow()
|
|||
KWindowSystem::activateWindow(window()->effectiveWinId());
|
||||
}
|
||||
|
||||
bool DolphinMainWindow::isActiveWindow()
|
||||
{
|
||||
return window()->isActiveWindow();
|
||||
}
|
||||
|
||||
void DolphinMainWindow::showCommand(CommandType command)
|
||||
{
|
||||
DolphinStatusBar* statusBar = m_activeViewContainer->statusBar();
|
||||
|
@ -2627,3 +2632,7 @@ bool DolphinMainWindow::isUrlOpen(const QString &url)
|
|||
return m_tabWidget->isUrlOpen(QUrl::fromUserInput(url));
|
||||
}
|
||||
|
||||
bool DolphinMainWindow::isUrlOrParentOpen(const QString &url)
|
||||
{
|
||||
return m_tabWidget->isUrlOrParentOpen(QUrl::fromUserInput(url));
|
||||
}
|
||||
|
|
|
@ -138,6 +138,8 @@ public Q_SLOTS:
|
|||
*/
|
||||
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.
|
||||
|
@ -147,6 +149,15 @@ public Q_SLOTS:
|
|||
*/
|
||||
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
|
||||
|
|
|
@ -117,6 +117,11 @@ bool DolphinTabWidget::isUrlOpen(const QUrl &url) const
|
|||
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;
|
||||
|
@ -182,7 +187,7 @@ void DolphinTabWidget::openNewTab(const QUrl& primaryUrl, const QUrl& secondaryU
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -191,12 +196,12 @@ void DolphinTabWidget::openDirectories(const QList<QUrl>& dirs, bool splitView)
|
|||
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);
|
||||
|
@ -243,7 +248,7 @@ void DolphinTabWidget::openFiles(const QList<QUrl>& files, bool splitView)
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -475,17 +480,29 @@ QString DolphinTabWidget::tabName(DolphinTabPage* tabPage) const
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -60,11 +60,17 @@ public:
|
|||
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
|
||||
|
@ -110,11 +116,12 @@ public Q_SLOTS:
|
|||
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.
|
||||
|
@ -205,15 +212,21 @@ private:
|
|||
*/
|
||||
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.
|
||||
* @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) const;
|
||||
QPair<int, bool> indexByUrl(const QUrl& url, ChildUrlBehavior childUrlBehavior = ReturnIndexForOpenedUrlOnly) const;
|
||||
|
||||
private:
|
||||
QPointer<DolphinTabPage> m_lastViewedTab;
|
||||
|
|
|
@ -71,33 +71,55 @@ bool Dolphin::attachToExistingInstance(const QList<QUrl>& inputUrls, bool openFi
|
|||
return false;
|
||||
}
|
||||
|
||||
QStringList newUrls;
|
||||
int activeWindowIndex = -1;
|
||||
for (const auto& interface: qAsConst(dolphinInterfaces)) {
|
||||
++activeWindowIndex;
|
||||
|
||||
// check to see if any instances already have any of the given URLs open
|
||||
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 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;
|
||||
|
|
Loading…
Reference in a new issue