1
0
mirror of https://invent.kde.org/system/dolphin synced 2024-07-07 10:51:45 +00:00

Merge remote-tracking branch 'origin/master' into kf6

This commit is contained in:
Méven Car 2023-09-10 15:24:39 +02:00
commit 4cbeb81b2b
131 changed files with 32217 additions and 28705 deletions

70
.flatpak-manifest.json Normal file
View File

@ -0,0 +1,70 @@
{
"id": "org.kde.dolphin",
"branch": "master",
"runtime": "org.kde.Platform",
"runtime-version": "5.15-22.08",
"sdk": "org.kde.Sdk",
"command": "dolphin",
"tags": ["nightly"],
"desktop-file-name-suffix": " (Nightly)",
"finish-args": ["--share=ipc", "--socket=x11", "--socket=wayland", "--filesystem=host" ],
"modules": [
{
"name": "lmdb",
"sources": [
{
"type": "git",
"url": "https://github.com/LMDB/lmdb.git",
"tag": "LMDB_0.9.29",
"x-checker-data": {
"type": "git",
"tag-pattern": "^LMDB_([\\d.]+)$"
},
"commit": "8ad7be2510414b9506ec9f9e24f24d04d9b04a1a"
}
],
"no-autogen": true,
"make-install-args": ["prefix=/app"],
"subdir" : "libraries/liblmdb"
},
{
"config-opts": ["-DENABLE_TESTING=OFF" , "-DLMDB_DIR=/app"],
"name": "baloo",
"buildsystem": "cmake-ninja",
"builddir": true,
"sources": [
{
"type": "git",
"url": "https://invent.kde.org/frameworks/baloo.git",
"tag": "v5.101.0",
"x-checker-data": {
"type": "git",
"tag-pattern": "^v([\\d.]+)$"
},
"commit": "03246908508ec9086171832e615c36bbaa48b6da"
}
]
},
{
"config-opts": ["-DENABLE_TESTING=OFF" , "-DLMDB_DIR=/app"],
"name": "baloo-widgets",
"buildsystem": "cmake-ninja",
"builddir": true,
"sources": [ { "type": "git", "url": "https://invent.kde.org/libraries/baloo-widgets.git" } ]
},
{
"config-opts": ["-DFLATPAK=ON"],
"name": "dolphin",
"buildsystem": "cmake-ninja",
"builddir": true,
"sources": [ { "type": "dir", "path": "." } ]
},
{
"name": "dolphin-plugins",
"buildsystem": "cmake-ninja",
"builddir": true,
"sources": [ { "type": "git", "url": "https://invent.kde.org/sdk/dolphin-plugins.git" } ]
}
]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: kdeorg\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2023-02-06 01:03+0000\n"
"PO-Revision-Date: 2023-08-02 12:39\n"
"PO-Revision-Date: 2023-09-02 02:56\n"
"Last-Translator: \n"
"Language-Team: Chinese Simplified\n"
"Language: zh_CN\n"

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,6 @@
#include "dolphincontextmenu.h"
#include "dolphin_contextmenusettings.h"
#include "dolphin_generalsettings.h"
#include "dolphinmainwindow.h"
#include "dolphinnewfilemenu.h"
#include "dolphinplacesmodelsingleton.h"
@ -16,7 +15,6 @@
#include "global.h"
#include "trash/dolphintrash.h"
#include "views/dolphinview.h"
#include "views/viewmodecontroller.h"
#include <KActionCollection>
#include <KFileItemListProperties>
@ -76,6 +74,8 @@ void DolphinContextMenu::addAllActions()
m_context |= SearchContext;
} else if (scheme.contains(QLatin1String("timeline"))) {
m_context |= TimelineContext;
} else if (scheme == QStringLiteral("recentlyused")) {
m_context |= RecentlyUsedContext;
}
if (!m_fileInfo.isNull() && !m_selectedItems.isEmpty()) {
@ -164,6 +164,10 @@ void DolphinContextMenu::addDirectoryItemContextMenu()
addAction(m_mainWindow->actionCollection()->action(QStringLiteral("open_in_new_window")));
}
if (ContextMenuSettings::showOpenInSplitView()) {
addAction(m_mainWindow->actionCollection()->action(QStringLiteral("open_in_split_view")));
}
// Insert 'Open With' entries
addOpenWithActions();
@ -183,6 +187,25 @@ void DolphinContextMenu::addDirectoryItemContextMenu()
addSeparator();
}
void DolphinContextMenu::addOpenParentFolderActions()
{
addAction(QIcon::fromTheme(QStringLiteral("document-open-folder")), i18nc("@action:inmenu", "Open Path"), [this]() {
const QUrl url = m_fileInfo.targetUrl();
const QUrl parentUrl = KIO::upUrl(url);
m_mainWindow->changeUrl(parentUrl);
m_mainWindow->activeViewContainer()->view()->markUrlsAsSelected({url});
m_mainWindow->activeViewContainer()->view()->markUrlAsCurrent(url);
});
addAction(QIcon::fromTheme(QStringLiteral("tab-new")), i18nc("@action:inmenu", "Open Path in New Tab"), [this]() {
m_mainWindow->openNewTab(KIO::upUrl(m_fileInfo.targetUrl()));
});
addAction(QIcon::fromTheme(QStringLiteral("window-new")), i18nc("@action:inmenu", "Open Path in New Window"), [this]() {
Dolphin::openNewWindow({m_fileInfo.targetUrl()}, m_mainWindow, Dolphin::OpenNewWindowFlag::Select);
});
}
void DolphinContextMenu::addItemContextMenu()
{
Q_ASSERT(!m_fileInfo.isNull());
@ -195,22 +218,10 @@ void DolphinContextMenu::addItemContextMenu()
// single files
if (m_fileInfo.isDir()) {
addDirectoryItemContextMenu();
} else if (m_context & TimelineContext || m_context & SearchContext) {
} else if (m_context & TimelineContext || m_context & SearchContext || m_context & RecentlyUsedContext) {
addOpenWithActions();
addAction(QIcon::fromTheme(QStringLiteral("document-open-folder")), i18nc("@action:inmenu", "Open Path"), [this]() {
m_mainWindow->changeUrl(KIO::upUrl(m_fileInfo.url()));
m_mainWindow->activeViewContainer()->view()->markUrlsAsSelected({m_fileInfo.url()});
m_mainWindow->activeViewContainer()->view()->markUrlAsCurrent(m_fileInfo.url());
});
addAction(QIcon::fromTheme(QStringLiteral("tab-new")), i18nc("@action:inmenu", "Open Path in New Tab"), [this]() {
m_mainWindow->openNewTab(KIO::upUrl(m_fileInfo.url()));
});
addAction(QIcon::fromTheme(QStringLiteral("window-new")), i18nc("@action:inmenu", "Open Path in New Window"), [this]() {
Dolphin::openNewWindow({m_fileInfo.url()}, m_mainWindow, Dolphin::OpenNewWindowFlag::Select);
});
addOpenParentFolderActions();
addSeparator();
} else {

View File

@ -95,6 +95,9 @@ private:
void addAdditionalActions(const KFileItemListProperties &props);
private:
void addDirectoryItemContextMenu();
void addOpenParentFolderActions();
struct Entry {
int type;
QString name;
@ -110,6 +113,7 @@ private:
TrashContext = 2,
TimelineContext = 4,
SearchContext = 8,
RecentlyUsedContext = 16,
};
DolphinMainWindow *m_mainWindow;
@ -126,7 +130,6 @@ private:
KFileCopyToMenu m_copyToMenu;
DolphinRemoveAction *m_removeAction; // Action that represents either 'Move To Trash' or 'Delete'
void addDirectoryItemContextMenu();
KFileItemActions *m_fileItemActions;
};

View File

@ -506,6 +506,32 @@ void DolphinMainWindow::openInNewWindow()
}
}
void DolphinMainWindow::openInSplitView(const QUrl &url)
{
QUrl newSplitViewUrl = url;
if (newSplitViewUrl.isEmpty()) {
const KFileItemList list = m_activeViewContainer->view()->selectedItems();
if (list.count() == 1) {
const KFileItem &item = list.first();
newSplitViewUrl = DolphinView::openItemAsFolderUrl(item);
}
}
if (newSplitViewUrl.isEmpty()) {
return;
}
DolphinTabPage *tabPage = m_tabWidget->currentTabPage();
if (tabPage->splitViewEnabled()) {
tabPage->switchActiveView();
tabPage->activeViewContainer()->setUrl(newSplitViewUrl);
} else {
tabPage->setSplitViewEnabled(true, WithAnimation, newSplitViewUrl);
updateViewActions();
}
}
void DolphinMainWindow::showTarget()
{
const KFileItem link = m_activeViewContainer->view()->selectedItems().at(0);
@ -895,7 +921,6 @@ void DolphinMainWindow::toggleSplitView()
{
DolphinTabPage *tabPage = m_tabWidget->currentTabPage();
tabPage->setSplitViewEnabled(!tabPage->splitViewEnabled(), WithAnimation);
updateViewActions();
}
@ -1154,7 +1179,8 @@ void DolphinMainWindow::openTerminalHere()
{
QList<QUrl> urls = {};
for (const KFileItem &item : m_activeViewContainer->view()->selectedItems()) {
const auto selectedItems = m_activeViewContainer->view()->selectedItems();
for (const KFileItem &item : selectedItems) {
QUrl url = item.targetUrl();
if (item.isFile()) {
url.setPath(QFileInfo(url.path()).absolutePath());
@ -1172,29 +1198,19 @@ void DolphinMainWindow::openTerminalHere()
if (urls.count() > 5) {
QString question = i18np("Are you sure you want to open 1 terminal window?", "Are you sure you want to open %1 terminal windows?", urls.count());
#if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
const int answer = KMessageBox::warningTwoActions(
const int answer = KMessageBox::warningContinueCancel(
this,
question,
{},
#else
const int answer = KMessageBox::warningYesNo(
this,
question,
{},
#endif
KGuiItem(i18ncp("@action:button", "Open %1 Terminal", "Open %1 Terminals", urls.count()), QStringLiteral("utilities-terminal")),
KStandardGuiItem::cancel());
#if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
if (answer != KMessageBox::PrimaryAction) {
#else
if (answer != KMessageBox::Yes) {
#endif
KStandardGuiItem::cancel(),
QStringLiteral("ConfirmOpenManyTerminals"));
if (answer != KMessageBox::PrimaryAction && answer != KMessageBox::Continue) {
return;
}
}
for (const QUrl &url : urls) {
for (const QUrl &url : std::as_const(urls)) {
openTerminalJob(url);
}
}
@ -2005,6 +2021,13 @@ void DolphinMainWindow::setupActions()
openInNewWindow->setText(i18nc("@action:inmenu", "Open in New Window"));
openInNewWindow->setIcon(QIcon::fromTheme(QStringLiteral("window-new")));
connect(openInNewWindow, &QAction::triggered, this, &DolphinMainWindow::openInNewWindow);
QAction *openInSplitViewAction = actionCollection()->addAction(QStringLiteral("open_in_split_view"));
openInSplitViewAction->setText(i18nc("@action:inmenu", "Open in Split View"));
openInSplitViewAction->setIcon(QIcon::fromTheme(QStringLiteral("view-right-new")));
connect(openInSplitViewAction, &QAction::triggered, this, [this]() {
openInSplitView(QUrl());
});
}
void DolphinMainWindow::setupDockWidgets()
@ -2180,6 +2203,7 @@ void DolphinMainWindow::setupDockWidgets()
connect(m_placesPanel, &PlacesPanel::newWindowRequested, this, [this](const QUrl &url) {
Dolphin::openNewWindow({url}, this);
});
connect(m_placesPanel, &PlacesPanel::openInSplitViewRequested, this, &DolphinMainWindow::openInSplitView);
connect(m_placesPanel, &PlacesPanel::errorMessage, this, &DolphinMainWindow::showErrorMessage);
connect(this, &DolphinMainWindow::urlChanged, m_placesPanel, &PlacesPanel::setUrl);
connect(placesDock, &DolphinDockWidget::visibilityChanged, &DolphinUrlNavigatorsController::slotPlacesPanelVisibilityChanged);

View File

@ -476,6 +476,11 @@ private Q_SLOTS:
*/
void openInNewWindow();
/**
* Opens the selected folder in the other inactive split view, enables split view if necessary.
*/
void openInSplitView(const QUrl &url);
/**
* Show the target of the selected symlink
*/

View File

@ -29,7 +29,7 @@ class DolphinPart : public KParts::ReadOnlyPart
// Used by konqueror. Technically it means "we want undo enabled if
// there are things in the undo history and the current part is a dolphin part".
// Even though it's konqueror doing the undo...
Q_PROPERTY(bool supportsUndo READ supportsUndo)
Q_PROPERTY(bool supportsUndo READ supportsUndo CONSTANT)
Q_PROPERTY(QString currentViewMode READ currentViewMode WRITE setCurrentViewMode)

View File

@ -138,6 +138,8 @@ public:
*/
void setActive(bool active);
void switchActiveView();
Q_SIGNALS:
void activeViewChanged(DolphinViewContainer *viewContainer);
void activeViewUrlChanged(const QUrl &url);
@ -170,8 +172,6 @@ private Q_SLOTS:
*/
void slotViewUrlRedirection(const QUrl &oldUrl, const QUrl &newUrl);
void switchActiveView();
private:
/**
* Creates a new view container and does the default initialization.

View File

@ -123,7 +123,9 @@ public Q_SLOTS:
* Opens a new tab in the background showing the URL \a primaryUrl and the
* optional URL \a secondaryUrl.
*/
void openNewTab(const QUrl &primaryUrl, const QUrl &secondaryUrl = QUrl(), NewTabPosition position = NewTabPosition::FollowSetting);
void openNewTab(const QUrl &primaryUrl,
const QUrl &secondaryUrl = QUrl(),
DolphinTabWidget::NewTabPosition position = DolphinTabWidget::NewTabPosition::FollowSetting);
/**
* Opens each directory in \p dirs in a separate tab unless it is already open.

View File

@ -32,6 +32,7 @@
#include <KMessageWidget>
#include <KProtocolManager>
#include <KShell>
#include <kio_version.h>
#include <QApplication>
#include <QDesktopServices>
@ -83,6 +84,7 @@ DolphinViewContainer::DolphinViewContainer(const QUrl &url, QWidget *parent)
m_searchBox = new DolphinSearchBox(this);
m_searchBox->hide();
connect(m_searchBox, &DolphinSearchBox::activated, this, &DolphinViewContainer::activate);
connect(m_searchBox, &DolphinSearchBox::openRequest, this, &DolphinViewContainer::openSearchBox);
connect(m_searchBox, &DolphinSearchBox::closeRequest, this, &DolphinViewContainer::closeSearchBox);
connect(m_searchBox, &DolphinSearchBox::searchRequest, this, &DolphinViewContainer::startSearching);
connect(m_searchBox, &DolphinSearchBox::focusViewRequest, this, &DolphinViewContainer::requestFocus);
@ -736,17 +738,28 @@ void DolphinViewContainer::slotfileMiddleClickActivated(const KFileItem &item)
{
KService::List services = KApplicationTrader::queryByMimeType(item.mimetype());
if (services.length() >= 2) {
auto service = services.at(1);
int indexOfAppToOpenFileWith = 1;
// executable scripts
auto mimeType = item.currentMimeType();
if (item.isLocalFile() && mimeType.inherits(QStringLiteral("application/x-executable")) && mimeType.inherits(QStringLiteral("text/plain"))
&& QFileInfo(item.localPath()).isExecutable()) {
KConfigGroup cfgGroup(KSharedConfig::openConfig(QStringLiteral("kiorc")), "Executable scripts");
const QString value = cfgGroup.readEntry("behaviourOnLaunch", "alwaysAsk");
// in case KIO::WidgetsOpenOrExecuteFileHandler::promptUserOpenOrExecute would not open the file
if (value != QLatin1String("open")) {
indexOfAppToOpenFileWith = 0;
}
}
if (services.length() >= indexOfAppToOpenFileWith + 1) {
auto service = services.at(indexOfAppToOpenFileWith);
KIO::ApplicationLauncherJob *job = new KIO::ApplicationLauncherJob(service, this);
job->setUrls({item.url()});
#if KIO_VERSION >= QT_VERSION_CHECK(5, 98, 0)
job->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
#else
job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
#endif
connect(job, &KIO::OpenUrlJob::finished, this, &DolphinViewContainer::slotOpenUrlFinished);
job->start();
}
@ -879,6 +892,11 @@ void DolphinViewContainer::startSearching()
}
}
void DolphinViewContainer::openSearchBox()
{
setSearchModeEnabled(true);
}
void DolphinViewContainer::closeSearchBox()
{
setSearchModeEnabled(false);

View File

@ -382,6 +382,7 @@ private Q_SLOTS:
* Gets the search URL from the searchbox and starts searching.
*/
void startSearching();
void openSearchBox();
void closeSearchBox();
/**

View File

@ -326,6 +326,31 @@ void KFileItemListView::resizeEvent(QGraphicsSceneResizeEvent *event)
triggerVisibleIndexRangeUpdate();
}
void KFileItemListView::focusInEvent(QFocusEvent *event)
{
Q_UNUSED(event)
updateSelectedWidgets();
}
void KFileItemListView::focusOutEvent(QFocusEvent *event)
{
Q_UNUSED(event)
updateSelectedWidgets();
}
void KFileItemListView::updateSelectedWidgets()
{
const auto visibleWidgets = visibleItemListWidgets();
for (KItemListWidget *widget : visibleWidgets) {
if (widget->isSelected()) {
auto w = qobject_cast<KFileItemListWidget *>(widget);
if (w) {
w->forceUpdate();
}
}
}
}
void KFileItemListView::slotItemsRemoved(const KItemRangeList &itemRanges)
{
KStandardItemListView::slotItemsRemoved(itemRanges);

View File

@ -98,6 +98,8 @@ protected:
void onTransactionBegin() override;
void onTransactionEnd() override;
void resizeEvent(QGraphicsSceneResizeEvent *event) override;
void focusInEvent(QFocusEvent *event) override;
void focusOutEvent(QFocusEvent *event) override;
protected Q_SLOTS:
void slotItemsRemoved(const KItemRangeList &itemRanges) override;
@ -127,6 +129,8 @@ private:
QSize availableIconSize() const;
private:
void updateSelectedWidgets();
KFileItemModelRolesUpdater *m_modelRolesUpdater;
QTimer *m_updateVisibleIndexRangeTimer;
QTimer *m_updateIconSizeTimer;

View File

@ -203,6 +203,17 @@ void KFileItemListWidget::hoverSequenceStarted()
view->setHoverSequenceState(itemUrl, 0);
}
void KFileItemListWidget::forceUpdate()
{
updateAdditionalInfoTextColor();
// icon layout does not include the icons in the item selection rectangle
// so its icon does not need updating
if (listView()->itemLayout() != KStandardItemListView::ItemLayout::IconsLayout) {
invalidateIconCache();
}
update();
}
void KFileItemListWidget::hoverSequenceIndexChanged(int sequenceIndex)
{
KFileItemListView *view = listView();

View File

@ -35,6 +35,9 @@ public:
static KItemListWidgetInformant *createInformant();
/// Force-update the displayed icon
void forceUpdate();
protected:
virtual void hoverSequenceStarted() override;
virtual void hoverSequenceIndexChanged(int sequenceIndex) override;

Some files were not shown because too many files have changed in this diff Show More