--- /dev/null
+include:
+ - https://invent.kde.org/sysadmin/ci-tooling/raw/master/invent/ci-before.yml
+ - https://invent.kde.org/sysadmin/ci-tooling/raw/master/invent/ci-applications-linux.yml
cmake_minimum_required(VERSION 3.0)
# KDE Application Version, managed by release script
-set (RELEASE_SERVICE_VERSION_MAJOR "20")
-set (RELEASE_SERVICE_VERSION_MINOR "12")
-set (RELEASE_SERVICE_VERSION_MICRO "1")
+set (RELEASE_SERVICE_VERSION_MAJOR "21")
+set (RELEASE_SERVICE_VERSION_MINOR "03")
+set (RELEASE_SERVICE_VERSION_MICRO "70")
set (RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
project(Dolphin VERSION ${RELEASE_SERVICE_VERSION})
set(QT_MIN_VERSION "5.14.0")
-set(KF5_MIN_VERSION "5.73.0")
+set(KF5_MIN_VERSION "5.77.0")
# ECM setup
find_package(ECM ${KF5_MIN_VERSION} CONFIG REQUIRED)
include(ECMSetupVersion)
include(ECMGenerateHeaders)
+include(ECMGenerateDBusServiceFile)
+include(ECMConfiguredInstall)
include(CMakePackageConfigHelpers)
include(GenerateExportHeader)
include(FeatureSummary)
COMPONENT Devel
)
-configure_file(org.kde.dolphin.FileManager1.service.in
- ${CMAKE_CURRENT_BINARY_DIR}/org.kde.dolphin.FileManager1.service)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.dolphin.FileManager1.service
- DESTINATION ${KDE_INSTALL_DBUSSERVICEDIR})
-install(FILES dolphin.categories DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR})
+ecm_generate_dbus_service_file(
+ NAME org.freedesktop.FileManager1
+ EXECUTABLE "${KDE_INSTALL_FULL_BINDIR}/dolphin --daemon"
+ SYSTEMD_SERVICE plasma-dolphin.service
+ DESTINATION ${KDE_INSTALL_DBUSSERVICEDIR}
+ RENAME org.kde.dolphin.FileManager1.service
+)
+
+ecm_install_configured_files(INPUT plasma-dolphin.service.in DESTINATION ${SYSTEMD_USER_UNIT_INSTALL_DIR})
+ecm_qt_install_logging_categories(
+ EXPORT DOLPHIN
+ FILE dolphin.categories
+ DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}
+ )
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
<legalnotice>&FDLNotice;</legalnotice>
-<date>2020-06-10</date>
-<releaseinfo>Applications 20.08</releaseinfo>
+<date>2020-12-29</date>
+<releaseinfo>Applications 21.04</releaseinfo>
<abstract>
<para>
<listitem><para>
A file or folder can be opened by clicking it with the &LMB; (or
-double-clicking, if <guilabel>Double-click to open files and folders</guilabel>
-is enabled in the &systemsettings; in the <menuchoice><guimenu>Input Devices</guimenu>
-<guimenuitem>Mouse</guimenuitem></menuchoice> module.
+double-clicking, if <guilabel>Open by double-clicking instead</guilabel>
+is enabled in the &systemsettings; in the <menuchoice><guimenu>Workspace</guimenu>
+<guimenuitem>General Behavior</guimenuitem></menuchoice> module).
</para></listitem>
<listitem><para>
<menuchoice><guimenuitem>Add to Places</guimenuitem></menuchoice> in the context menu.
</para>
+<note>
+ <para>
+ The corresponding menu item visibility can be toggled via the
+ <link linkend="preferences-dialog-context-menu">&dolphin; context menu settings</link>.
+ </para>
+</note>
+
+</sect2>
+
+<sect2 id="filter-files">
+<title>Filtering Files</title>
+
+<para>
+&dolphin; is capable of filtering files, &ie; showing only those items in the
+view whose name contains a given text. For example, if you wish to show
+only the <acronym>MP3</acronym> files within a folder, you could filter for <quote>.mp3</quote>.
+This would then filter out all files whose name does not contain <quote>.mp3</quote>.
+</para>
+
+<para>
+To filter files, first enable the filter bar, either by pressing <keycombo action="simul">&Ctrl;<keycap>I</keycap></keycombo>
+or via the menu: <menuchoice> <guimenu>Edit</guimenu> <guimenuitem>Filter...</guimenuitem> </menuchoice>.
+You can then enter the text to be filtered for in the filter bar. The filter bar can
+be disabled either by pressing &Esc;, or with a &LMB; click on the
+<guiicon>Hide Filter Bar</guiicon> icon.
+</para>
+
</sect2>
<sect2 id="finding-searching-in-file">
<screeninfo>Search files and for content in files</screeninfo>
<mediaobject>
<imageobject>
-<imagedata fileref="nepomuk-search.png" format="PNG"/>
+<imagedata fileref="baloo-search.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Search files and for content in files</phrase>
<screeninfo>Search with More Options</screeninfo>
<mediaobject>
<imageobject>
-<imagedata fileref="nepomuk-search-more-options.png" format="PNG"/>
+<imagedata fileref="baloo-search-more-options.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Search with More Options</phrase>
</sect2>
-<sect2 id="filter-files">
-<title>Filtering Files</title>
-
-<para>
-&dolphin; is capable of filtering files, &ie; showing only those items in the
-view whose name contains a given text. For example, if you wish to show
-only the <acronym>MP3</acronym> files within a folder, you could filter for <quote>.mp3</quote>.
-This would then filter out all files whose name does not contain <quote>.mp3</quote>.
-</para>
-
-<para>
-To filter files, first enable the filter bar, either by pressing <keycombo action="simul">&Ctrl;<keycap>I</keycap></keycombo>
-or via the menu: <menuchoice> <guimenu>Tools</guimenu> <guimenuitem>Show Filter Bar</guimenuitem> </menuchoice>.
-You can then enter the text to be filtered for in the filter bar. The filter bar can
-be disabled either by pressing &Esc;, or with a &LMB; click on the
-<guiicon>Hide Filter Bar</guiicon> icon.
-</para>
-
-</sect2>
-
</sect1>
</chapter>
<para>
<guilabel>Folder size displays</guilabel> allows defining the property to use then sorting folders by their size. It is possible to sort folders by <guilabel>Number of items</guilabel> or <guilabel>Size of contents</guilabel> and choose a limit to the recursive level (can be useful to constrain unneeded iterations in the deep folder structures or on the slow file systems).
</para>
+<para>
+The <guilabel>Date style</guilabel> option can be used to configure the mode to display dates in &dolphin;. It is possible to choose between <guilabel>Relative</guilabel> (⪚, <quote>Yesterday, 3:00pm</quote>) or <guilabel>Absolute</guilabel> (⪚, <quote>2020-12-23 15:00</quote>).
+</para>
</listitem>
</itemizedlist>
</para>
<listitem><para>
The option to open items with a single or double mouse click is a system wide setting and can be
-changed in the &systemsettings; in the <menuchoice><guimenu>Input Devices</guimenu>
-<guimenuitem>Mouse</guimenuitem></menuchoice> module.</para>
+changed in the &systemsettings; in the <menuchoice><guimenu>Workspace</guimenu>
+<guimenuitem>General Behavior</guimenuitem></menuchoice> module.</para>
</listitem>
<listitem><para>
</sect2>
-<sect2 id="preferences-dialog-services">
-<title>Services</title>
+<sect2 id="preferences-dialog-context-menu">
+<title>Context Menu</title>
<para>
This group offers a selection of services that can be shown in the
</para>
<screenshot>
-<screeninfo>Screenshot of the Services settings in &dolphin;'s preferences dialog</screeninfo>
+<screeninfo>Screenshot of the Context Menu settings in &dolphin;'s preferences dialog</screeninfo>
<mediaobject>
<imageobject>
-<imagedata fileref="preferences-services.png" format="PNG"/>
+<imagedata fileref="preferences-context-menu.png" format="PNG"/>
</imageobject>
<textobject>
-<phrase>Services Settings.</phrase>
+<phrase>Context Menu Settings.</phrase>
</textobject>
-<caption><para>Services Settings in &dolphin;'s Preferences Dialog.</para></caption>
+<caption><para>Context Menu Settings in &dolphin;'s Preferences Dialog.</para></caption>
</mediaobject>
</screenshot>
context menu like commit, update, add, remove &etc;
</para>
<para>
-In the service list you can also choose if the <guimenuitem>Delete</guimenuitem>,
-<guimenuitem>Copy To</guimenuitem>, and <guimenuitem>Move To</guimenuitem>
+In the service list you can also choose if the <guimenuitem>Copy To</guimenuitem>,
+<guimenuitem>Move To</guimenuitem>, <guimenuitem>Add to Places</guimenuitem>,
+<guimenuitem>Sort By</guimenuitem>, <guimenuitem>View Mode</guimenuitem>,
+<guimenuitem>Open in New Tab</guimenuitem>, <guimenuitem>Open in New Window</guimenuitem>,
+<guimenuitem>Copy Location</guimenuitem>, and <guimenuitem>Duplicate Here</guimenuitem>
commands are shown in the context menu.
</para>
<para>
&dolphin; has to be restarted to activate the changes for some of these settings.
-<!--FIXME wrong for Copy To + Move To + Delete, what about the other items?-->
</para>
</sect2>
Is disabled if the current user does not have write permission on the selected item(s).</action></para></listitem>
</varlistentry>
+<varlistentry>
+<term><menuchoice>
+<shortcut>
+<keycombo action="simul">&Ctrl;<keycap>I</keycap></keycombo>
+</shortcut>
+<guimenu>Edit</guimenu>
+<guimenuitem>Filter...</guimenuitem>
+</menuchoice></term>
+<listitem><para><action>Enables and disables the <link linkend="filter-files">filter bar</link>.</action>
+You can also use the alternate shortcut <keycombo action="simul">&Shift;<keycap>/</keycap></keycombo>
+for this action.</para></listitem>
+</varlistentry>
+
<varlistentry>
<term><menuchoice>
<shortcut>
<para>
<variablelist>
-<varlistentry>
-<term><menuchoice>
-<shortcut>
-<keycombo action="simul">&Ctrl;<keycap>I</keycap></keycombo>
-</shortcut>
-<guimenu>Tools</guimenu>
-<guimenuitem>Show Filter Bar</guimenuitem>
-</menuchoice></term>
-<listitem><para><action>Enables and disables the <link linkend="filter-files">filter bar</link>.</action>
-You can also use the alternate shortcut <keycombo action="simul">&Shift;<keycap>/</keycap></keycombo>
-for this action.</para></listitem>
-</varlistentry>
-
<varlistentry>
<term><menuchoice>
<shortcut>
+++ /dev/null
-org.kde.dolphin dolphin IDENTIFIER [DolphinDebug]
+++ /dev/null
-[D-BUS Service]
-Name=org.freedesktop.FileManager1
-Exec=@CMAKE_INSTALL_PREFIX@/bin/dolphin --daemon
--- /dev/null
+[Unit]
+Description=Dolphin file manager
+PartOf=graphical-session.target
+
+[Service]
+ExecStart=@KDE_INSTALL_FULL_BINDIR@/dolphin --daemon
+BusName=org.freedesktop.FileManager1
+Slice=background.slice
dolphinnewfilemenu.cpp
)
-ecm_qt_declare_logging_category(dolphinprivate_LIB_SRCS HEADER dolphindebug.h IDENTIFIER DolphinDebug CATEGORY_NAME org.kde.dolphin)
+ecm_qt_declare_logging_category(dolphinprivate_LIB_SRCS HEADER dolphindebug.h IDENTIFIER DolphinDebug CATEGORY_NAME org.kde.dolphin
+ DESCRIPTION "dolphin" EXPORT DOLPHIN)
if(HAVE_BALOO)
set(dolphinprivate_LIB_SRCS
settings/dolphin_detailsmodesettings.kcfgc
settings/dolphin_iconsmodesettings.kcfgc
settings/dolphin_generalsettings.kcfgc
+ settings/dolphin_contextmenusettings.kcfgc
settings/dolphin_versioncontrolsettings.kcfgc
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/dolphin_export.h DESTINATION ${KDE_INSTALL_INCLUDEDIR} COMPONENT Devel)
##########################################
+configure_file(dolphinpart.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/dolphinpart.desktop @ONLY)
set(dolphinpart_SRCS
dolphinpart.cpp
qt5_add_resources(dolphinpart_SRCS dolphinpart.qrc)
add_library(dolphinpart MODULE ${dolphinpart_SRCS})
+kcoreaddons_desktop_to_json(dolphinpart ${CMAKE_CURRENT_BINARY_DIR}/dolphinpart.desktop)
target_link_libraries(dolphinpart
dolphinprivate
)
-install(TARGETS dolphinpart DESTINATION ${KDE_INSTALL_PLUGINDIR})
+install(TARGETS dolphinpart DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf5/parts)
-install(FILES dolphinpart.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/dolphinpart.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
##########################################
settings/general/statusbarsettingspage.cpp
settings/dolphinsettingsdialog.cpp
settings/navigation/navigationsettingspage.cpp
- settings/services/servicessettingspage.cpp
+ settings/contextmenu/contextmenusettingspage.cpp
settings/settingspagebase.cpp
settings/serviceitemdelegate.cpp
settings/servicemodel.cpp
settings/dolphin_compactmodesettings.kcfgc
settings/dolphin_detailsmodesettings.kcfgc
settings/dolphin_generalsettings.kcfgc
+ settings/dolphin_contextmenusettings.kcfgc
settings/dolphin_iconsmodesettings.kcfgc
search/dolphin_searchsettings.kcfgc
settings/dolphin_versioncontrolsettings.kcfgc
settings/navigation/navigationsettingspage.cpp
settings/settingspagebase.cpp)
-set(kcm_dolphinservices_PART_SRCS
- settings/kcm/kcmdolphinservices.cpp
- settings/services/servicessettingspage.cpp
- settings/settingspagebase.cpp
- settings/serviceitemdelegate.cpp
- settings/servicemodel.cpp)
-
set(kcm_dolphingeneral_PART_SRCS
settings/kcm/kcmdolphingeneral.cpp
settings/general/behaviorsettingspage.cpp
kconfig_add_kcfg_files(kcm_dolphinnavigation_PART_SRCS
settings/dolphin_generalsettings.kcfgc)
-kconfig_add_kcfg_files(kcm_dolphinservices_PART_SRCS
- settings/dolphin_generalsettings.kcfgc
- settings/dolphin_versioncontrolsettings.kcfgc)
-
kconfig_add_kcfg_files(kcm_dolphingeneral_PART_SRCS
settings/dolphin_generalsettings.kcfgc)
# The settings are still accessible from the hamburger menu
add_library(kcm_dolphinviewmodes MODULE ${kcm_dolphinviewmodes_PART_SRCS})
add_library(kcm_dolphinnavigation MODULE ${kcm_dolphinnavigation_PART_SRCS})
- add_library(kcm_dolphinservices MODULE ${kcm_dolphinservices_PART_SRCS})
add_library(kcm_dolphingeneral MODULE ${kcm_dolphingeneral_PART_SRCS})
target_link_libraries(kcm_dolphinviewmodes dolphinprivate)
target_link_libraries(kcm_dolphinnavigation dolphinprivate)
- target_link_libraries(kcm_dolphinservices dolphinprivate)
target_link_libraries(kcm_dolphingeneral dolphinprivate)
install( FILES org.kde.dolphin.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR} )
install( FILES settings/kcm/kcmdolphinviewmodes.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} )
install( FILES settings/kcm/kcmdolphinnavigation.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} )
- install( FILES settings/kcm/kcmdolphinservices.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} )
install( FILES settings/kcm/kcmdolphingeneral.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} )
install(TARGETS kcm_dolphinviewmodes DESTINATION ${KDE_INSTALL_PLUGINDIR} )
install(TARGETS kcm_dolphinnavigation DESTINATION ${KDE_INSTALL_PLUGINDIR} )
- install(TARGETS kcm_dolphinservices DESTINATION ${KDE_INSTALL_PLUGINDIR} )
install(TARGETS kcm_dolphingeneral DESTINATION ${KDE_INSTALL_PLUGINDIR} )
endif()
if(NOT WIN32)
- add_subdirectory(settings/services/servicemenuinstaller)
- install( FILES settings/services/servicemenu.knsrc DESTINATION ${KDE_INSTALL_KNSRCDIR} )
+ add_subdirectory(settings/contextmenu/servicemenuinstaller)
+ install( FILES settings/contextmenu/servicemenu.knsrc DESTINATION ${KDE_INSTALL_KNSRCDIR} )
endif()
########### install files ###############
install( FILES settings/dolphin_directoryviewpropertysettings.kcfg
settings/dolphin_generalsettings.kcfg
+ settings/dolphin_contextmenusettings.kcfg
settings/dolphin_compactmodesettings.kcfg
settings/dolphin_iconsmodesettings.kcfg
settings/dolphin_detailsmodesettings.kcfg
void DolphinBookmarkHandler::openInNewTab(const KBookmark& bookmark)
{
- m_mainWindow->openNewTabAfterCurrentTab(bookmark.url());
+ m_mainWindow->openNewTab(bookmark.url());
}
void DolphinBookmarkHandler::openInNewWindow(const KBookmark& bookmark)
#include "dolphincontextmenu.h"
#include "dolphin_generalsettings.h"
+#include "dolphin_contextmenusettings.h"
#include "dolphinmainwindow.h"
#include "dolphinnewfilemenu.h"
#include "dolphinplacesmodelsingleton.h"
// or the items itself. To increase the performance both lists are cached.
const DolphinView* view = m_mainWindow->activeViewContainer()->view();
m_selectedItems = view->selectedItems();
+
+ installEventFilter(this);
}
DolphinContextMenu::~DolphinContextMenu()
return m_command;
}
-void DolphinContextMenu::keyPressEvent(QKeyEvent *ev)
+void DolphinContextMenu::childEvent(QChildEvent* event)
{
- if (m_removeAction && ev->key() == Qt::Key_Shift) {
- m_removeAction->update(DolphinRemoveAction::ShiftState::Pressed);
+ if(event->added()) {
+ event->child()->installEventFilter(this);
}
- QMenu::keyPressEvent(ev);
+ QMenu::childEvent(event);
}
-void DolphinContextMenu::keyReleaseEvent(QKeyEvent *ev)
+bool DolphinContextMenu::eventFilter(QObject* dest, QEvent* event)
{
- if (m_removeAction && ev->key() == Qt::Key_Shift) {
- m_removeAction->update(DolphinRemoveAction::ShiftState::Released);
+ if(event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
+ QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
+ if(m_removeAction && keyEvent->key() == Qt::Key_Shift) {
+ if(event->type() == QEvent::KeyPress) {
+ m_removeAction->update(DolphinRemoveAction::ShiftState::Pressed);
+ } else {
+ m_removeAction->update(DolphinRemoveAction::ShiftState::Released);
+ }
+ return true;
+ }
}
- QMenu::keyReleaseEvent(ev);
+ return QMenu::eventFilter(dest, event);
}
void DolphinContextMenu::openTrashContextMenu()
void DolphinContextMenu::addDirectoryItemContextMenu(KFileItemActions &fileItemActions)
{
// insert 'Open in new window' and 'Open in new tab' entries
-
const KFileItemListProperties& selectedItemsProps = selectedItemsProperties();
-
- addAction(m_mainWindow->actionCollection()->action(QStringLiteral("open_in_new_tab")));
- addAction(m_mainWindow->actionCollection()->action(QStringLiteral("open_in_new_window")));
+ if (ContextMenuSettings::showOpenInNewTab()) {
+ addAction(m_mainWindow->actionCollection()->action(QStringLiteral("open_in_new_tab")));
+ }
+ if (ContextMenuSettings::showOpenInNewWindow()) {
+ addAction(m_mainWindow->actionCollection()->action(QStringLiteral("open_in_new_window")));
+ }
// Insert 'Open With' entries
addOpenWithActions(fileItemActions);
// set up 'Create New' menu
- DolphinNewFileMenu* newFileMenu = new DolphinNewFileMenu(m_mainWindow->actionCollection(), m_mainWindow);
- const DolphinView* view = m_mainWindow->activeViewContainer()->view();
- newFileMenu->setViewShowsHiddenFiles(view->hiddenFilesShown());
- newFileMenu->checkUpToDate();
- newFileMenu->setPopupFiles(QList<QUrl>() << m_fileInfo.url());
- newFileMenu->setEnabled(selectedItemsProps.supportsWriting());
- connect(newFileMenu, &DolphinNewFileMenu::fileCreated, newFileMenu, &DolphinNewFileMenu::deleteLater);
- connect(newFileMenu, &DolphinNewFileMenu::directoryCreated, newFileMenu, &DolphinNewFileMenu::deleteLater);
-
- QMenu* menu = newFileMenu->menu();
- menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New"));
- menu->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
- addMenu(menu);
-
- addSeparator();
+ DolphinNewFileMenu* newFileMenu = new DolphinNewFileMenu(m_mainWindow->actionCollection(), m_mainWindow);
+ const DolphinView* view = m_mainWindow->activeViewContainer()->view();
+ newFileMenu->setViewShowsHiddenFiles(view->hiddenFilesShown());
+ newFileMenu->checkUpToDate();
+ newFileMenu->setPopupFiles(QList<QUrl>() << m_fileInfo.url());
+ newFileMenu->setEnabled(selectedItemsProps.supportsWriting());
+ connect(newFileMenu, &DolphinNewFileMenu::fileCreated, newFileMenu, &DolphinNewFileMenu::deleteLater);
+ connect(newFileMenu, &DolphinNewFileMenu::directoryCreated, newFileMenu, &DolphinNewFileMenu::deleteLater);
+
+ QMenu* menu = newFileMenu->menu();
+ menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New"));
+ menu->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
+ addMenu(menu);
+
+ addSeparator();
}
void DolphinContextMenu::openItemContextMenu()
}
}
- if (selectionHasOnlyDirs) {
+ if (selectionHasOnlyDirs && ContextMenuSettings::showOpenInNewTab()) {
// insert 'Open in new tab' entry
addAction(m_mainWindow->actionCollection()->action(QStringLiteral("open_in_new_tabs")));
}
insertDefaultItemActions(selectedItemsProps);
- // insert 'Add to Places' entry if appropriate
- if (m_selectedItems.count() == 1) {
- if (m_fileInfo.isDir()) {
- if (!placeExists(m_fileInfo.url())) {
- addAction(m_mainWindow->actionCollection()->action(QStringLiteral("add_to_places")));
- }
- }
- }
-
- addSeparator();
-
- fileItemActions.addServiceActionsTo(this);
- fileItemActions.addPluginActionsTo(this);
-
- addVersionControlPluginActions();
+ addAdditionalActions(fileItemActions, selectedItemsProps);
// insert 'Copy To' and 'Move To' sub menus
- if (GeneralSettings::showCopyMoveMenu()) {
+ if (ContextMenuSettings::showCopyMoveMenu()) {
m_copyToMenu.setUrls(m_selectedItems.urlList());
m_copyToMenu.setReadOnly(!selectedItemsProps.supportsWriting());
m_copyToMenu.setAutoErrorHandlingEnabled(true);
}
// Insert 'Add to Places' entry if it's not already in the places panel
- if (!placeExists(m_mainWindow->activeViewContainer()->url())) {
+ if (ContextMenuSettings::showAddToPlaces() &&
+ !placeExists(m_mainWindow->activeViewContainer()->url())) {
addAction(m_mainWindow->actionCollection()->action(QStringLiteral("add_to_places")));
}
addSeparator();
// Insert 'Sort By' and 'View Mode'
- addAction(m_mainWindow->actionCollection()->action(QStringLiteral("sort")));
- addAction(m_mainWindow->actionCollection()->action(QStringLiteral("view_mode")));
-
- addSeparator();
-
- // Insert service actions
- fileItemActions.addServiceActionsTo(this);
- fileItemActions.addPluginActionsTo(this);
-
- addVersionControlPluginActions();
+ if (ContextMenuSettings::showSortBy()) {
+ addAction(m_mainWindow->actionCollection()->action(QStringLiteral("sort")));
+ }
+ if (ContextMenuSettings::showViewMode()) {
+ addAction(m_mainWindow->actionCollection()->action(QStringLiteral("view_mode")));
+ }
+ if (ContextMenuSettings::showSortBy() || ContextMenuSettings::showViewMode()) {
+ addSeparator();
+ }
+ addAdditionalActions(fileItemActions, baseUrlProperties);
addCustomActions();
addSeparator();
// Insert 'Cut', 'Copy', 'Copy Location' and 'Paste'
addAction(collection->action(KStandardAction::name(KStandardAction::Cut)));
addAction(collection->action(KStandardAction::name(KStandardAction::Copy)));
- QAction* copyPathAction = collection->action(QString("copy_location"));
- copyPathAction->setEnabled(m_selectedItems.size() == 1);
- addAction(copyPathAction);
+ if (ContextMenuSettings::showCopyLocation()) {
+ QAction* copyPathAction = collection->action(QString("copy_location"));
+ copyPathAction->setEnabled(m_selectedItems.size() == 1);
+ addAction(copyPathAction);
+ }
QAction* pasteAction = createPasteAction();
if (pasteAction) {
addAction(pasteAction);
}
- addAction(m_mainWindow->actionCollection()->action(QStringLiteral("duplicate")));
- addSeparator();
+ // Insert 'Duplicate Here'
+ if (ContextMenuSettings::showDuplicateHere()) {
+ addAction(m_mainWindow->actionCollection()->action(QStringLiteral("duplicate")));
+ }
// Insert 'Rename'
addAction(collection->action(KStandardAction::name(KStandardAction::RenameFile)));
+ // Insert 'Add to Places' entry if appropriate
+ if (ContextMenuSettings::showAddToPlaces() &&
+ m_selectedItems.count() == 1 &&
+ m_fileInfo.isDir() &&
+ !placeExists(m_fileInfo.url())) {
+ addAction(m_mainWindow->actionCollection()->action(QStringLiteral("add_to_places")));
+ }
+
+ addSeparator();
+
// Insert 'Move to Trash' and/or 'Delete'
const bool showDeleteAction = (KSharedConfig::openConfig()->group("KDE").readEntry("ShowDeleteCommand", false) ||
!properties.isLocal());
fileItemActions.addOpenWithActionsTo(this, QStringLiteral("DesktopEntryName != '%1'").arg(qApp->desktopFileName()));
}
-void DolphinContextMenu::addVersionControlPluginActions()
+void DolphinContextMenu::addCustomActions()
+{
+ addActions(m_customActions);
+}
+
+void DolphinContextMenu::addAdditionalActions(KFileItemActions &fileItemActions, const KFileItemListProperties &props)
{
+ addSeparator();
+
+ QList<QAction *> additionalActions;
+ if (props.isDirectory() && props.isLocal()) {
+ additionalActions << m_mainWindow->actionCollection()->action(QStringLiteral("open_terminal"));
+ }
+ fileItemActions.addActionsTo(this, KFileItemActions::MenuActionSource::All, additionalActions);
+
const DolphinView* view = m_mainWindow->activeViewContainer()->view();
const QList<QAction*> versionControlActions = view->versionControlActions(m_selectedItems);
if (!versionControlActions.isEmpty()) {
}
}
-void DolphinContextMenu::addCustomActions()
-{
- addActions(m_customActions);
-}
-
Command open();
protected:
- void keyPressEvent(QKeyEvent *ev) override;
- void keyReleaseEvent(QKeyEvent *ev) override;
+ void childEvent(QChildEvent* event) override;
+ bool eventFilter(QObject* dest, QEvent* event) override;
private:
void openTrashContextMenu();
*/
void addOpenWithActions(KFileItemActions& fileItemActions);
- /**
- * Adds actions that are provided by a KVersionControlPlugin.
- */
- void addVersionControlPluginActions();
-
/**
* Adds custom actions e.g. like the "[x] Expandable Folders"-action
* provided in the details view.
void addCustomActions();
private:
+ /**
+ * Add services, custom actions, plugins and version control items to the menu
+ */
+ void addAdditionalActions(KFileItemActions &fileItemActions, const KFileItemListProperties &props);
+
struct Entry
{
int type;
connect(undoManager, &KIO::FileUndoManager::jobRecordingFinished,
this, &DolphinMainWindow::showCommand);
- GeneralSettings* generalSettings = GeneralSettings::self();
- const bool firstRun = (generalSettings->version() < 200);
+ const bool firstRun = (GeneralSettings::version() < 200);
if (firstRun) {
- generalSettings->setViewPropsTimestamp(QDateTime::currentDateTime());
+ GeneralSettings::setViewPropsTimestamp(QDateTime::currentDateTime());
}
setAcceptDrops(true);
connect(clipboard, &QClipboard::dataChanged,
this, &DolphinMainWindow::updatePasteAction);
- QAction* showFilterBarAction = actionCollection()->action(QStringLiteral("show_filter_bar"));
- showFilterBarAction->setChecked(generalSettings->filterBar());
+ QAction* toggleFilterBarAction = actionCollection()->action(QStringLiteral("toggle_filter"));
+ toggleFilterBarAction->setChecked(GeneralSettings::filterBar());
if (firstRun) {
menuBar()->setVisible(false);
void DolphinMainWindow::updateFilterBarAction(bool show)
{
- QAction* showFilterBarAction = actionCollection()->action(QStringLiteral("show_filter_bar"));
- showFilterBarAction->setChecked(show);
+ QAction* toggleFilterBarAction = actionCollection()->action(QStringLiteral("toggle_filter"));
+ toggleFilterBarAction->setChecked(show);
}
void DolphinMainWindow::openNewMainWindow()
void DolphinMainWindow::openNewActivatedTab()
{
+ // keep browsers compatibility, new tab is always after last one
+ auto openNewTabAfterLastTabConfigured = GeneralSettings::openNewTabAfterLastTab();
+ GeneralSettings::setOpenNewTabAfterLastTab(true);
m_tabWidget->openNewActivatedTab();
+ GeneralSettings::setOpenNewTabAfterLastTab(openNewTabAfterLastTabConfigured);
}
void DolphinMainWindow::addToPlaces()
}
}
-void DolphinMainWindow::openNewTab(const QUrl& url, DolphinTabWidget::TabPlacement tabPlacement)
+void DolphinMainWindow::openNewTab(const QUrl& url)
{
- m_tabWidget->openNewTab(url, QUrl(), tabPlacement);
-}
-
-void DolphinMainWindow::openNewTabAfterCurrentTab(const QUrl& url)
-{
- m_tabWidget->openNewTab(url, QUrl(), DolphinTabWidget::AfterCurrentTab);
-}
-
-void DolphinMainWindow::openNewTabAfterLastTab(const QUrl& url)
-{
- m_tabWidget->openNewTab(url, QUrl(), DolphinTabWidget::AfterLastTab);
+ m_tabWidget->openNewTab(url, QUrl());
}
void DolphinMainWindow::openInNewTab()
for (const KFileItem& item : list) {
const QUrl& url = DolphinView::openItemAsFolderUrl(item);
if (!url.isEmpty()) {
- openNewTabAfterCurrentTab(url);
+ openNewTab(url);
tabCreated = true;
}
}
// if no new tab has been created from the selection
// open the current directory in a new tab
if (!tabCreated) {
- openNewTabAfterCurrentTab(m_activeViewContainer->url());
+ openNewTab(m_activeViewContainer->url());
}
}
{
if (action) {
const KUrlNavigator *urlNavigator = activeViewContainer()->urlNavigatorInternalWithHistory();
- openNewTabAfterCurrentTab(urlNavigator->locationUrl(action->data().value<int>()));
+ openNewTab(urlNavigator->locationUrl(action->data().value<int>()));
}
}
void DolphinMainWindow::toggleSplitView()
{
DolphinTabPage* tabPage = m_tabWidget->currentTabPage();
- tabPage->setSplitViewEnabled(!tabPage->splitViewEnabled());
+ tabPage->setSplitViewEnabled(!tabPage->splitViewEnabled(), WithAnimation);
updateViewActions();
}
void DolphinMainWindow::toggleSplitStash()
{
DolphinTabPage* tabPage = m_tabWidget->currentTabPage();
- tabPage->setSplitViewEnabled(false);
- tabPage->setSplitViewEnabled(true, QUrl("stash:/"));
+ tabPage->setSplitViewEnabled(false, WithAnimation);
+ tabPage->setSplitViewEnabled(true, WithAnimation, QUrl("stash:/"));
}
void DolphinMainWindow::reloadView()
m_activeViewContainer->setFilterBarVisible(true);
}
+void DolphinMainWindow::toggleFilterBar()
+{
+ const bool checked = !m_activeViewContainer->isFilterBarVisible();
+ m_activeViewContainer->setFilterBarVisible(checked);
+
+ QAction* toggleFilterBarAction = actionCollection()->action(QStringLiteral("toggle_filter"));
+ toggleFilterBarAction->setChecked(checked);
+}
+
void DolphinMainWindow::toggleEditLocation()
{
clearStatusBar();
{
const KUrlNavigator* urlNavigator = activeViewContainer()->urlNavigatorInternalWithHistory();
const int index = urlNavigator->historyIndex() + 1;
- openNewTabAfterCurrentTab(urlNavigator->locationUrl(index));
+ openNewTab(urlNavigator->locationUrl(index));
}
void DolphinMainWindow::goForwardInNewTab()
{
const KUrlNavigator* urlNavigator = activeViewContainer()->urlNavigatorInternalWithHistory();
const int index = urlNavigator->historyIndex() - 1;
- openNewTabAfterCurrentTab(urlNavigator->locationUrl(index));
+ openNewTab(urlNavigator->locationUrl(index));
}
void DolphinMainWindow::goUpInNewTab()
{
const QUrl currentUrl = activeViewContainer()->urlNavigator()->locationUrl();
- openNewTabAfterCurrentTab(KIO::upUrl(currentUrl));
+ openNewTab(KIO::upUrl(currentUrl));
}
void DolphinMainWindow::goHomeInNewTab()
{
- openNewTabAfterCurrentTab(Dolphin::homeUrl());
+ openNewTab(Dolphin::homeUrl());
}
void DolphinMainWindow::compareFiles()
container->view()->writeSettings();
const QUrl url = container->url();
- DolphinSettingsDialog* settingsDialog = new DolphinSettingsDialog(url, this);
+ DolphinSettingsDialog* settingsDialog = new DolphinSettingsDialog(url, this, actionCollection());
connect(settingsDialog, &DolphinSettingsDialog::settingsChanged, this, &DolphinMainWindow::refreshViews);
connect(settingsDialog, &DolphinSettingsDialog::settingsChanged,
&DolphinUrlNavigatorsController::slotReadSettings);
break;
case DolphinContextMenu::OpenParentFolderInNewTab:
- openNewTabAfterLastTab(KIO::upUrl(item.url()));
+ openNewTab(KIO::upUrl(item.url()));
break;
case DolphinContextMenu::None:
"<emphasis>Tab</emphasis> with the current location and view.<nl/>"
"A tab is an additional view within this window. "
"You can drag and drop items between tabs."));
- actionCollection()->setDefaultShortcuts(newTab, {Qt::CTRL + Qt::Key_T, Qt::CTRL + Qt::SHIFT + Qt::Key_N});
+ actionCollection()->setDefaultShortcuts(newTab, {Qt::CTRL | Qt::Key_T, Qt::CTRL | Qt::SHIFT | Qt::Key_N});
connect(newTab, &QAction::triggered, this, &DolphinMainWindow::openNewActivatedTab);
QAction* addToPlaces = actionCollection()->addAction(QStringLiteral("add_to_places"));
"the <emphasis>active</emphasis> view to the inactive split view."));
copyToOtherViewAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy")));
copyToOtherViewAction->setIconText(i18nc("@action:inmenu Edit", "Copy to Inactive Split View"));
- actionCollection()->setDefaultShortcut(copyToOtherViewAction, Qt::SHIFT + Qt::Key_F5 );
+ actionCollection()->setDefaultShortcut(copyToOtherViewAction, Qt::SHIFT | Qt::Key_F5 );
connect(copyToOtherViewAction, &QAction::triggered, m_tabWidget, &DolphinTabWidget::copyToInactiveSplitView);
QAction* moveToOtherViewAction = actionCollection()->addAction(QStringLiteral("move_to_inactive_split_view"));
"the <emphasis>active</emphasis> view to the inactive split view."));
moveToOtherViewAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-cut")));
moveToOtherViewAction->setIconText(i18nc("@action:inmenu Edit", "Move to Inactive Split View"));
- actionCollection()->setDefaultShortcut(moveToOtherViewAction, Qt::SHIFT + Qt::Key_F6 );
+ actionCollection()->setDefaultShortcut(moveToOtherViewAction, Qt::SHIFT | Qt::Key_F6 );
connect(moveToOtherViewAction, &QAction::triggered, m_tabWidget, &DolphinTabWidget::moveToInactiveSplitView);
+ QAction* showFilterBar = actionCollection()->addAction(QStringLiteral("show_filter_bar"));
+ showFilterBar->setText(i18nc("@action:inmenu Tools", "Filter..."));
+ showFilterBar->setToolTip(i18nc("@info:tooltip", "Toggle Filter Bar"));
+ showFilterBar->setWhatsThis(xi18nc("@info:whatsthis", "This opens the "
+ "<emphasis>Filter Bar</emphasis> at the bottom of the window.<nl/> "
+ "There you can enter a text to filter the files and folders currently displayed. "
+ "Only those that contain the text in their name will be kept in view."));
+ showFilterBar->setIcon(QIcon::fromTheme(QStringLiteral("view-filter")));
+ actionCollection()->setDefaultShortcuts(showFilterBar, {Qt::CTRL | Qt::Key_I, Qt::Key_Slash});
+ connect(showFilterBar, &QAction::triggered, this, &DolphinMainWindow::showFilterBar);
+
+ // toggle_filter acts as a copy of the main showFilterBar to be used mainly
+ // in the toolbar, with no default shortcut attached, to avoid messing with
+ // existing workflows (filter bar always open and Ctrl-I to focus)
+ QAction *toggleFilter = actionCollection()->addAction(QStringLiteral("toggle_filter"));
+ toggleFilter->setText(i18nc("@action:inmenu", "Toggle Filter Bar"));
+ toggleFilter->setIconText(i18nc("@action:intoolbar", "Filter"));
+ toggleFilter->setIcon(showFilterBar->icon());
+ toggleFilter->setToolTip(showFilterBar->toolTip());
+ toggleFilter->setWhatsThis(showFilterBar->whatsThis());
+ toggleFilter->setCheckable(true);
+ connect(toggleFilter, &QAction::triggered, this, &DolphinMainWindow::toggleFilterBar);
+
QAction *searchAction = KStandardAction::find(this, &DolphinMainWindow::find, actionCollection());
searchAction->setText(i18n("Search..."));
searchAction->setToolTip(i18nc("@info:tooltip", "Search for files and folders"));
invertSelection->setWhatsThis(xi18nc("@info:whatsthis invert", "This selects all "
"objects that you have currently <emphasis>not</emphasis> selected instead."));
invertSelection->setIcon(QIcon::fromTheme(QStringLiteral("edit-select-invert")));
- actionCollection()->setDefaultShortcut(invertSelection, Qt::CTRL + Qt::SHIFT + Qt::Key_A);
+ actionCollection()->setDefaultShortcut(invertSelection, Qt::CTRL | Qt::SHIFT | Qt::Key_A);
connect(invertSelection, &QAction::triggered, this, &DolphinMainWindow::invertSelection);
// setup 'View' menu
connect(split, &QAction::triggered, this, &DolphinMainWindow::toggleSplitView);
QAction* stashSplit = actionCollection()->addAction(QStringLiteral("split_stash"));
- actionCollection()->setDefaultShortcut(stashSplit, Qt::CTRL + Qt::Key_S);
+ actionCollection()->setDefaultShortcut(stashSplit, Qt::CTRL | Qt::Key_S);
stashSplit->setText(i18nc("@action:intoolbar Stash", "Stash"));
stashSplit->setToolTip(i18nc("@info", "Opens the stash virtual directory in a split window"));
stashSplit->setIcon(QIcon::fromTheme(QStringLiteral("folder-stash")));
stashSplit->setCheckable(false);
- stashSplit->setVisible(KProtocolInfo::isKnownProtocol("stash"));
+ stashSplit->setVisible(QDBusConnection::sessionBus().interface()->isServiceRegistered(QStringLiteral("org.kde.kio.StashNotifier")));
connect(stashSplit, &QAction::triggered, this, &DolphinMainWindow::toggleSplitStash);
KStandardAction::redisplay(this, &DolphinMainWindow::reloadView, actionCollection());
replaceLocation->setWhatsThis(xi18nc("@info:whatsthis",
"This switches to editing the location and selects it "
"so you can quickly enter a different location."));
- actionCollection()->setDefaultShortcut(replaceLocation, Qt::CTRL + Qt::Key_L);
+ actionCollection()->setDefaultShortcut(replaceLocation, Qt::CTRL | Qt::Key_L);
connect(replaceLocation, &QAction::triggered, this, &DolphinMainWindow::replaceLocation);
// setup 'Go' menu
undoCloseTab->setText(i18nc("@action:inmenu File", "Undo close tab"));
undoCloseTab->setWhatsThis(i18nc("@info:whatsthis undo close tab",
"This returns you to the previously closed tab."));
- actionCollection()->setDefaultShortcut(undoCloseTab, Qt::CTRL + Qt::SHIFT + Qt::Key_T);
+ actionCollection()->setDefaultShortcut(undoCloseTab, Qt::CTRL | Qt::SHIFT | Qt::Key_T);
undoCloseTab->setIcon(QIcon::fromTheme(QStringLiteral("edit-undo")));
undoCloseTab->setEnabled(false);
connect(undoCloseTab, &QAction::triggered, recentTabsMenu, &DolphinRecentTabsMenu::undoCloseTab);
"including folders that contain personal application data."));
// setup 'Tools' menu
- QAction* showFilterBar = actionCollection()->addAction(QStringLiteral("show_filter_bar"));
- showFilterBar->setText(i18nc("@action:inmenu Tools", "Show Filter Bar"));
- showFilterBar->setWhatsThis(xi18nc("@info:whatsthis", "This opens the "
- "<emphasis>Filter Bar</emphasis> at the bottom of the window.<nl/> "
- "There you can enter a text to filter the files and folders currently displayed. "
- "Only those that contain the text in their name will be kept in view."));
- showFilterBar->setIcon(QIcon::fromTheme(QStringLiteral("view-filter")));
- actionCollection()->setDefaultShortcuts(showFilterBar, {Qt::CTRL + Qt::Key_I, Qt::Key_Slash});
- connect(showFilterBar, &QAction::triggered, this, &DolphinMainWindow::showFilterBar);
-
QAction* compareFiles = actionCollection()->addAction(QStringLiteral("compare_files"));
compareFiles->setText(i18nc("@action:inmenu Tools", "Compare Files"));
compareFiles->setIcon(QIcon::fromTheme(QStringLiteral("kompare")));
"<para>This opens a preferred search tool for the viewed location.</para>"
"<para>Use <emphasis>More Search Tools</emphasis> menu to configure it.</para>"));
openPreferredSearchTool->setIcon(QIcon::fromTheme(QStringLiteral("search")));
- actionCollection()->setDefaultShortcut(openPreferredSearchTool, Qt::CTRL + Qt::SHIFT + Qt::Key_F);
+ actionCollection()->setDefaultShortcut(openPreferredSearchTool, Qt::CTRL | Qt::SHIFT | Qt::Key_F);
connect(openPreferredSearchTool, &QAction::triggered, this, &DolphinMainWindow::openPreferredSearchTool);
if (KAuthorized::authorize(QStringLiteral("shell_access"))) {
openTerminal->setWhatsThis(xi18nc("@info:whatsthis",
"<para>This opens a <emphasis>terminal</emphasis> application for the viewed location.</para>"
"<para>To learn more about terminals use the help in the terminal application.</para>"));
- openTerminal->setIcon(QIcon::fromTheme(QStringLiteral("dialog-scripts")));
- actionCollection()->setDefaultShortcut(openTerminal, Qt::SHIFT + Qt::Key_F4);
+ openTerminal->setIcon(QIcon::fromTheme(QStringLiteral("utilities-terminal")));
+ actionCollection()->setDefaultShortcut(openTerminal, Qt::SHIFT | Qt::Key_F4);
connect(openTerminal, &QAction::triggered, this, &DolphinMainWindow::openTerminal);
#ifdef HAVE_TERMINAL
QAction* focusTerminalPanel = actionCollection()->addAction(QStringLiteral("focus_terminal_panel"));
focusTerminalPanel->setText(i18nc("@action:inmenu Tools", "Focus Terminal Panel"));
focusTerminalPanel->setIcon(QIcon::fromTheme(QStringLiteral("swap-panels")));
- actionCollection()->setDefaultShortcut(focusTerminalPanel, Qt::CTRL + Qt::SHIFT + Qt::Key_F4);
+ actionCollection()->setDefaultShortcut(focusTerminalPanel, Qt::CTRL | Qt::SHIFT | Qt::Key_F4);
connect(focusTerminalPanel, &QAction::triggered, this, &DolphinMainWindow::focusTerminalPanel);
#endif
}
// not in menu actions
QList<QKeySequence> nextTabKeys = KStandardShortcut::tabNext();
- nextTabKeys.append(QKeySequence(Qt::CTRL + Qt::Key_Tab));
+ nextTabKeys.append(QKeySequence(Qt::CTRL | Qt::Key_Tab));
QList<QKeySequence> prevTabKeys = KStandardShortcut::tabPrev();
- prevTabKeys.append(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Tab));
+ prevTabKeys.append(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_Tab));
for (int i = 0; i < MaxActivateTabShortcuts; ++i) {
QAction* activateTab = actionCollection()->addAction(QStringLiteral("activate_tab_%1").arg(i));
activateLastTab->setText(i18nc("@action:inmenu", "Activate Last Tab"));
activateLastTab->setEnabled(false);
connect(activateLastTab, &QAction::triggered, m_tabWidget, &DolphinTabWidget::activateLastTab);
- actionCollection()->setDefaultShortcut(activateLastTab, Qt::ALT + Qt::Key_0);
+ actionCollection()->setDefaultShortcut(activateLastTab, Qt::ALT | Qt::Key_0);
QAction* activateNextTab = actionCollection()->addAction(QStringLiteral("activate_next_tab"));
activateNextTab->setIconText(i18nc("@action:inmenu", "Next Tab"));
connect(foldersPanel, &FoldersPanel::folderActivated,
this, &DolphinMainWindow::changeUrl);
connect(foldersPanel, &FoldersPanel::folderMiddleClicked,
- this, &DolphinMainWindow::openNewTabAfterCurrentTab);
+ this, &DolphinMainWindow::openNewTab);
connect(foldersPanel, &FoldersPanel::errorMessage,
this, &DolphinMainWindow::showErrorMessage);
placesDock->setWidget(m_placesPanel);
QAction *placesAction = placesDock->toggleViewAction();
- createPanelAction(QIcon::fromTheme(QStringLiteral("bookmarks")), Qt::Key_F9, placesAction, QStringLiteral("show_places_panel"));
+ createPanelAction(QIcon::fromTheme(QStringLiteral("compass")), Qt::Key_F9, placesAction, QStringLiteral("show_places_panel"));
addDockWidget(Qt::LeftDockWidgetArea, placesDock);
connect(m_placesPanel, &PlacesPanel::placeActivated,
this, &DolphinMainWindow::slotPlaceActivated);
connect(m_placesPanel, &PlacesPanel::placeMiddleClicked,
- this, &DolphinMainWindow::openNewTabAfterCurrentTab);
+ this, &DolphinMainWindow::openNewTab);
connect(m_placesPanel, &PlacesPanel::errorMessage,
this, &DolphinMainWindow::showErrorMessage);
connect(this, &DolphinMainWindow::urlChanged,
{
m_actionHandler->updateViewActions();
- QAction* showFilterBarAction = actionCollection()->action(QStringLiteral("show_filter_bar"));
- showFilterBarAction->setChecked(m_activeViewContainer->isFilterBarVisible());
+ QAction* toggleFilterBarAction = actionCollection()->action(QStringLiteral("toggle_filter"));
+ toggleFilterBarAction->setChecked(m_activeViewContainer->isFilterBarVisible());
updateSplitAction();
}
// The startup settings have been changed by the user (see bug #254947).
// Synchronize the split-view setting with the active view:
const bool splitView = GeneralSettings::splitView();
- m_tabWidget->currentTabPage()->setSplitViewEnabled(splitView);
+ m_tabWidget->currentTabPage()->setSplitViewEnabled(splitView, WithAnimation);
updateSplitAction();
updateWindowTitle();
}
connect(navigator, &KUrlNavigator::editableStateChanged,
this, &DolphinMainWindow::slotEditableStateChanged);
connect(navigator, &KUrlNavigator::tabRequested,
- this, &DolphinMainWindow::openNewTabAfterLastTab);
+ this, &DolphinMainWindow::openNewTab);
disconnect(m_updateHistoryConnection);
m_updateHistoryConnection = connect(
void quit();
/**
- * Opens a new tab and places it after the current tab
- */
- void openNewTabAfterCurrentTab(const QUrl& url);
-
- /**
- * Opens a new tab and places it as the last tab
+ * Opens a new tab in the background showing the URL \a url.
*/
- void openNewTabAfterLastTab(const QUrl& url);
+ void openNewTab(const QUrl& url);
signals:
/**
void disableStopAction();
void showFilterBar();
+ void toggleFilterBar();
/**
* Toggles between edit and browse mode of the navigation bar.
*/
void addToPlaces();
- /**
- * Opens a new tab in the background showing the URL \a url.
- */
- void openNewTab(const QUrl& url, DolphinTabWidget::TabPlacement tabPlacement);
-
/**
* Opens the selected folder in a new tab.
*/
QWidgetAction{parent},
m_splitter{new QSplitter(Qt::Horizontal)},
m_adjustSpacingTimer{new QTimer(this)},
- m_globalXOfSplitter{INT_MIN},
- m_globalXOfPrimary{INT_MIN},
- m_widthOfPrimary{INT_MIN},
- m_globalXOfSecondary{INT_MIN},
- m_widthOfSecondary{INT_MIN}
+ m_viewGeometriesHelper{m_splitter.get(), this}
{
updateText();
setIcon(QIcon::fromTheme(QStringLiteral("dialog-scripts")));
this, &DolphinNavigatorsWidgetAction::adjustSpacing);
}
+void DolphinNavigatorsWidgetAction::adjustSpacing()
+{
+ auto viewGeometries = m_viewGeometriesHelper.viewGeometries();
+ const int widthOfSplitterPrimary = viewGeometries.globalXOfPrimary + viewGeometries.widthOfPrimary - viewGeometries.globalXOfNavigatorsWidget;
+ const QList<int> splitterSizes = {widthOfSplitterPrimary,
+ m_splitter->width() - widthOfSplitterPrimary};
+ m_splitter->setSizes(splitterSizes);
+
+ // primary side of m_splitter
+ int leadingSpacing = viewGeometries.globalXOfPrimary - viewGeometries.globalXOfNavigatorsWidget;
+ if (leadingSpacing < 0) {
+ leadingSpacing = 0;
+ }
+ int trailingSpacing = (viewGeometries.globalXOfNavigatorsWidget + m_splitter->width())
+ - (viewGeometries.globalXOfPrimary + viewGeometries.widthOfPrimary);
+ if (trailingSpacing < 0 || emptyTrashButton(Primary)->isVisible()
+ || networkFolderButton(Primary)->isVisible()
+ ) {
+ trailingSpacing = 0;
+ }
+ const int widthLeftForUrlNavigator = m_splitter->widget(0)->width() - leadingSpacing - trailingSpacing;
+ const int widthNeededForUrlNavigator = primaryUrlNavigator()->sizeHint().width() - widthLeftForUrlNavigator;
+ if (widthNeededForUrlNavigator > 0) {
+ trailingSpacing -= widthNeededForUrlNavigator;
+ if (trailingSpacing < 0) {
+ leadingSpacing += trailingSpacing;
+ trailingSpacing = 0;
+ }
+ if (leadingSpacing < 0) {
+ leadingSpacing = 0;
+ }
+ }
+ spacing(Primary, Leading)->setMinimumWidth(leadingSpacing);
+ spacing(Primary, Trailing)->setFixedWidth(trailingSpacing);
+
+ // secondary side of m_splitter
+ if (viewGeometries.globalXOfSecondary == INT_MIN) {
+ Q_ASSERT(viewGeometries.widthOfSecondary == INT_MIN);
+ return;
+ }
+ spacing(Primary, Trailing)->setFixedWidth(0);
+
+ trailingSpacing = (viewGeometries.globalXOfNavigatorsWidget + m_splitter->width())
+ - (viewGeometries.globalXOfSecondary + viewGeometries.widthOfSecondary);
+ if (trailingSpacing < 0 || emptyTrashButton(Secondary)->isVisible()
+ || networkFolderButton(Secondary)->isVisible()
+ ) {
+ trailingSpacing = 0;
+ } else {
+ const int widthLeftForUrlNavigator2 = m_splitter->widget(1)->width() - trailingSpacing;
+ const int widthNeededForUrlNavigator2 = secondaryUrlNavigator()->sizeHint().width() - widthLeftForUrlNavigator2;
+ if (widthNeededForUrlNavigator2 > 0) {
+ trailingSpacing -= widthNeededForUrlNavigator2;
+ if (trailingSpacing < 0) {
+ trailingSpacing = 0;
+ }
+ }
+ }
+ spacing(Secondary, Trailing)->setMinimumWidth(trailingSpacing);
+}
+
void DolphinNavigatorsWidgetAction::createSecondaryUrlNavigator()
{
Q_ASSERT(m_splitter->count() == 1);
updateText();
}
-void DolphinNavigatorsWidgetAction::followViewContainerGeometry(
- int globalXOfPrimary, int widthOfPrimary)
+void DolphinNavigatorsWidgetAction::followViewContainersGeometry(QWidget *primaryViewContainer,
+ QWidget *secondaryViewContainer)
{
- followViewContainersGeometry(globalXOfPrimary, widthOfPrimary, INT_MIN, INT_MIN);
-}
-
-void DolphinNavigatorsWidgetAction::followViewContainersGeometry(
- int globalXOfPrimary, int widthOfPrimary,
- int globalXOfSecondary, int widthOfSecondary)
-{
- if (QApplication::layoutDirection() == Qt::LeftToRight) {
- m_globalXOfSplitter = m_splitter->mapToGlobal(QPoint(0,0)).x();
- m_globalXOfPrimary = globalXOfPrimary;
- m_globalXOfSecondary = globalXOfSecondary;
- } else {
- // When the direction is reversed, globalX does not change.
- // For the adjustSpacing() code to work we need globalX to measure from right to left
- // and to measure up to the rightmost point of a widget instead of the leftmost.
- m_globalXOfSplitter = (-1) * (m_splitter->mapToGlobal(QPoint(0,0)).x() + m_splitter->width());
- m_globalXOfPrimary = (-1) * (globalXOfPrimary + widthOfPrimary);
- m_globalXOfSecondary = (globalXOfSecondary == INT_MIN) ? INT_MIN :
- (-1) * (globalXOfSecondary + widthOfSecondary);
- }
- m_widthOfPrimary = widthOfPrimary;
- m_widthOfSecondary = widthOfSecondary;
+ m_viewGeometriesHelper.setViewContainers(primaryViewContainer, secondaryViewContainer);
adjustSpacing();
}
m_splitter->setParent(nullptr);
}
-void DolphinNavigatorsWidgetAction::adjustSpacing()
-{
- Q_ASSERT(m_globalXOfSplitter != INT_MIN);
- Q_ASSERT(m_globalXOfPrimary != INT_MIN);
- Q_ASSERT(m_widthOfPrimary != INT_MIN);
- const int widthOfSplitterPrimary = m_globalXOfPrimary + m_widthOfPrimary - m_globalXOfSplitter;
- const QList<int> splitterSizes = {widthOfSplitterPrimary,
- m_splitter->width() - widthOfSplitterPrimary};
- m_splitter->setSizes(splitterSizes);
-
- // primary side of m_splitter
- int leadingSpacing = m_globalXOfPrimary - m_globalXOfSplitter;
- if (leadingSpacing < 0) {
- leadingSpacing = 0;
- }
- int trailingSpacing = (m_globalXOfSplitter + m_splitter->width())
- - (m_globalXOfPrimary + m_widthOfPrimary);
-#if KIO_VERSION < QT_VERSION_CHECK(5, 78, 0)
- if (trailingSpacing < 0 || emptyTrashButton(Primary)->isVisible()) {
-#else
- if (trailingSpacing < 0 || emptyTrashButton(Primary)->isVisible()
- || networkFolderButton(Primary)->isVisible()
- ) {
-#endif
- trailingSpacing = 0;
- }
- const int widthLeftForUrlNavigator = m_splitter->widget(0)->width() - leadingSpacing - trailingSpacing;
- const int widthNeededForUrlNavigator = primaryUrlNavigator()->sizeHint().width() - widthLeftForUrlNavigator;
- if (widthNeededForUrlNavigator > 0) {
- trailingSpacing -= widthNeededForUrlNavigator;
- if (trailingSpacing < 0) {
- leadingSpacing += trailingSpacing;
- trailingSpacing = 0;
- }
- if (leadingSpacing < 0) {
- leadingSpacing = 0;
- }
- }
- spacing(Primary, Leading)->setMinimumWidth(leadingSpacing);
- spacing(Primary, Trailing)->setFixedWidth(trailingSpacing);
-
- // secondary side of m_splitter
- if (m_globalXOfSecondary == INT_MIN) {
- Q_ASSERT(m_widthOfSecondary == INT_MIN);
- return;
- }
- spacing(Primary, Trailing)->setFixedWidth(0);
-
- trailingSpacing = (m_globalXOfSplitter + m_splitter->width())
- - (m_globalXOfSecondary + m_widthOfSecondary);
-#if KIO_VERSION < QT_VERSION_CHECK(5, 78, 0)
- if (trailingSpacing < 0 || emptyTrashButton(Secondary)->isVisible()) {
-#else
- if (trailingSpacing < 0 || emptyTrashButton(Secondary)->isVisible()
- || networkFolderButton(Secondary)->isVisible()
- ) {
-#endif
- trailingSpacing = 0;
- } else {
- const int widthLeftForUrlNavigator2 = m_splitter->widget(1)->width() - trailingSpacing;
- const int widthNeededForUrlNavigator2 = secondaryUrlNavigator()->sizeHint().width() - widthLeftForUrlNavigator2;
- if (widthNeededForUrlNavigator2 > 0) {
- trailingSpacing -= widthNeededForUrlNavigator2;
- if (trailingSpacing < 0) {
- trailingSpacing = 0;
- }
- }
- }
- spacing(Secondary, Trailing)->setMinimumWidth(trailingSpacing);
-}
-
QWidget *DolphinNavigatorsWidgetAction::createNavigatorWidget(Side side) const
{
auto navigatorWidget = new QWidget(m_splitter.get());
auto emptyTrashButton = newEmptyTrashButton(urlNavigator, navigatorWidget);
layout->addWidget(emptyTrashButton);
-#if !(KIO_VERSION < QT_VERSION_CHECK(5, 78, 0))
auto networkFolderButton = newNetworkFolderButton(urlNavigator, navigatorWidget);
layout->addWidget(networkFolderButton);
-#endif
- connect(urlNavigator, &KUrlNavigator::urlChanged, this, [this]() {
+ connect(urlNavigator, &KUrlNavigator::urlChanged, this, [urlNavigator, this]() {
+ // Update URL navigator to show a server URL entry placeholder text if we
+ // just loaded the remote:/ page, to make it easier for users to figure out
+ // that they can enter arbitrary remote URLs. See bug 414670
+ if (urlNavigator->locationUrl().scheme() == QLatin1String("remote")) {
+ if (!urlNavigator->isUrlEditable()) {
+ urlNavigator->setUrlEditable(true);
+ }
+ urlNavigator->clearText();
+ urlNavigator->setPlaceholderText(i18n("Enter server URL (e.g. smb://[ip address])"));
+ } else {
+ urlNavigator->setPlaceholderText(QString());
+ }
+
// We have to wait for DolphinUrlNavigator::sizeHint() to update which
// happens a little bit later than when urlChanged is emitted.
this->m_adjustSpacingTimer->start();
- });
+ }, Qt::QueuedConnection);
auto trailingSpacing = new QWidget{navigatorWidget};
layout->addWidget(trailingSpacing);
return emptyTrashButton;
}
-#if !(KIO_VERSION < QT_VERSION_CHECK(5, 78, 0))
QPushButton *DolphinNavigatorsWidgetAction::networkFolderButton(DolphinNavigatorsWidgetAction::Side side)
{
int sideIndex = (side == Primary ? 0 : 1);
auto networkFolderButton = new QPushButton(QIcon::fromTheme(QStringLiteral("folder-add")),
i18nc("@action:button", "Add Network Folder"), parent);
networkFolderButton->setFlat(true);
+ KService::Ptr service = KService::serviceByDesktopName(QStringLiteral("org.kde.knetattach"));
connect(networkFolderButton, &QPushButton::clicked,
- this, [networkFolderButton]() {
- KService::Ptr service = KService::serviceByDesktopName(QStringLiteral("org.kde.knetattach"));
+ this, [networkFolderButton, service]() {
auto *job = new KIO::ApplicationLauncherJob(service, networkFolderButton);
auto *delegate = new KNotificationJobUiDelegate;
delegate->setAutoErrorHandlingEnabled(true);
job->start();
});
networkFolderButton->hide();
- connect(urlNavigator, &KUrlNavigator::urlChanged, this, [networkFolderButton, urlNavigator]() {
- networkFolderButton->setVisible(urlNavigator->locationUrl().scheme() == QLatin1String("remote"));
+ connect(urlNavigator, &KUrlNavigator::urlChanged, this, [networkFolderButton, urlNavigator, service]() {
+ networkFolderButton->setVisible(service && urlNavigator->locationUrl().scheme() == QLatin1String("remote"));
});
return networkFolderButton;
}
-#endif
QWidget *DolphinNavigatorsWidgetAction::spacing(Side side, Position position) const
{
return m_splitter->widget(sideIndex)->layout()->itemAt(0)->widget();
}
if (side == Primary) {
-#if KIO_VERSION < QT_VERSION_CHECK(5, 78, 0)
- return m_splitter->widget(sideIndex)->layout()->itemAt(3)->widget();
-#else
return m_splitter->widget(sideIndex)->layout()->itemAt(4)->widget();
-#endif
}
-#if KIO_VERSION < QT_VERSION_CHECK(5, 78, 0)
- return m_splitter->widget(sideIndex)->layout()->itemAt(2)->widget();
-#else
return m_splitter->widget(sideIndex)->layout()->itemAt(3)->widget();
-#endif
}
void DolphinNavigatorsWidgetAction::updateText()
{
const int urlNavigatorsAmount = m_splitter->count() > 1 && m_splitter->widget(1)->isVisible() ?
2 : 1;
- setText(i18ncp("@action:inmenu", "Url Navigator", "Url Navigators", urlNavigatorsAmount));
+ setText(i18ncp("@action:inmenu", "Location Bar", "Location Bars", urlNavigatorsAmount));
+}
+
+DolphinNavigatorsWidgetAction::ViewGeometriesHelper::ViewGeometriesHelper
+ (QWidget *navigatorsWidget, DolphinNavigatorsWidgetAction *navigatorsWidgetAction) :
+ m_navigatorsWidget{navigatorsWidget},
+ m_navigatorsWidgetAction{navigatorsWidgetAction}
+{
+ Q_CHECK_PTR(navigatorsWidget);
+ Q_CHECK_PTR(navigatorsWidgetAction);
+}
+
+bool DolphinNavigatorsWidgetAction::ViewGeometriesHelper::eventFilter(QObject *watched, QEvent *event)
+{
+ if (event->type() == QEvent::Resize) {
+ m_navigatorsWidgetAction->adjustSpacing();
+ return false;
+ }
+ return QObject::eventFilter(watched, event);
+}
+
+void DolphinNavigatorsWidgetAction::ViewGeometriesHelper::setViewContainers(QWidget *primaryViewContainer,
+ QWidget *secondaryViewContainer)
+{
+ Q_CHECK_PTR(primaryViewContainer);
+ if (m_primaryViewContainer) {
+ m_primaryViewContainer->removeEventFilter(this);
+ }
+ primaryViewContainer->installEventFilter(this);
+ m_primaryViewContainer = primaryViewContainer;
+
+ // It is not possible to resize the secondaryViewContainer without simultaneously
+ // resizing the primaryViewContainer so we don't have to installEventFilter() here.
+ m_secondaryViewContainer = secondaryViewContainer;
+}
+
+DolphinNavigatorsWidgetAction::ViewGeometriesHelper::Geometries
+ DolphinNavigatorsWidgetAction::ViewGeometriesHelper::viewGeometries()
+{
+ Q_ASSERT(m_primaryViewContainer);
+ Geometries geometries;
+
+ // width
+ geometries.widthOfPrimary = m_primaryViewContainer->width();
+ if (m_secondaryViewContainer) {
+ geometries.widthOfSecondary = m_secondaryViewContainer->width();
+ } else {
+ geometries.widthOfSecondary = INT_MIN;
+ }
+
+ // globalX
+ if (QApplication::layoutDirection() == Qt::LeftToRight) {
+ geometries.globalXOfNavigatorsWidget = m_navigatorsWidget->mapToGlobal(QPoint(0,0)).x();
+ geometries.globalXOfPrimary = m_primaryViewContainer->mapToGlobal(QPoint(0,0)).x();
+ geometries.globalXOfSecondary = !m_secondaryViewContainer ? INT_MIN :
+ m_secondaryViewContainer->mapToGlobal(QPoint(0,0)).x();
+ } else {
+ // When the direction is reversed, globalX does not change.
+ // For the adjustSpacing() code to work we need globalX to measure from right to left
+ // and to measure up to the rightmost point of a widget instead of the leftmost.
+ geometries.globalXOfNavigatorsWidget =
+ (-1) * (m_navigatorsWidget->mapToGlobal(QPoint(0,0)).x() + m_navigatorsWidget->width());
+ geometries.globalXOfPrimary =
+ (-1) * (m_primaryViewContainer->mapToGlobal(QPoint(0,0)).x() + geometries.widthOfPrimary);
+ geometries.globalXOfSecondary = !m_secondaryViewContainer ? INT_MIN :
+ (-1) * (m_secondaryViewContainer->mapToGlobal(QPoint(0,0)).x() + geometries.widthOfSecondary);
+ }
+ return geometries;
}
#include "dolphinurlnavigator.h"
-#include <kio_version.h>
+#include <QPointer>
#include <QSplitter>
#include <QTimer>
#include <QWidgetAction>
* createSecondaryUrlNavigator() when necessary.
* - Each side is a QWidget which I call NavigatorWidget with a QHBoxLayout.
* - Each NavigatorWidget consists an UrlNavigator, an emptyTrashButton, a
- * networkFolderButton (for frameworks >= 5.78), and spacing.
+ * networkFolderButton, and spacing.
* - Only the primary navigatorWidget has leading spacing. Both have trailing spacing.
* The spacing is there to align the UrlNavigator with its DolphinViewContainer.
*/
public:
DolphinNavigatorsWidgetAction(QWidget *parent = nullptr);
+ /**
+ * Adjusts the width of the spacings used to align the UrlNavigators with ViewContainers.
+ * This can only work nicely if up-to-date geometry of ViewContainers is cached so
+ * followViewContainersGeometry() has to have been called at least once before.
+ */
+ void adjustSpacing();
+
/**
* The secondary UrlNavigator is only created on-demand. Such an action is not necessary
* for the primary UrlNavigator which is created preemptively.
*/
void createSecondaryUrlNavigator();
- /**
- * Notify the primary UrlNavigator of changes in geometry of the ViewContainer it tries to be
- * aligned with. Only call this method if there is no secondary UrlNavigator.
- */
- void followViewContainerGeometry(int globalXOfPrimary, int widthOfPrimary);
/**
* Notify this widget of changes in geometry of the ViewContainers it tries to be
* aligned with.
*/
- void followViewContainersGeometry(int globalXOfPrimary, int widthOfPrimary,
- int globalXOfSecondary, int widthOfSecondary);
+ void followViewContainersGeometry(QWidget *primaryViewContainer,
+ QWidget *secondaryViewContainer = nullptr);
bool isInToolbar() const;
void deleteWidget(QWidget *widget) override;
private:
- /**
- * Adjusts the width of the spacings used to align the UrlNavigators with ViewContainers.
- * This can only work nicely if up-to-date geometry of ViewContainers is cached so
- * followViewContainersGeometry() has to have been called at least once before.
- */
- void adjustSpacing();
-
/**
* In Left-to-right languages the Primary side will be the left one.
*/
/**
* Creates a new empty trash button.
* @param urlNavigator Only when this UrlNavigator shows the trash directory
- * will the the button be visible.
+ * will the button be visible.
* @param parent Aside from the usual QObject deletion mechanisms,
* this parameter influences the positioning of dialog windows
* pertaining to this trash button.
*/
QPushButton *newEmptyTrashButton(const DolphinUrlNavigator *urlNavigator, QWidget *parent) const;
-#if !(KIO_VERSION < QT_VERSION_CHECK(5, 78, 0))
/**
* Used to retrieve the networkFolderButtons for the navigatorWidgets on
* both sides.
* @param parent The object that should be the button's parent.
*/
QPushButton *newNetworkFolderButton(const DolphinUrlNavigator *urlNavigator, QWidget *parent) const;
-#endif
enum Position {
Leading,
*/
std::unique_ptr<QTimer> m_adjustSpacingTimer;
- // cached values
- int m_globalXOfSplitter;
- int m_globalXOfPrimary;
- int m_widthOfPrimary;
- int m_globalXOfSecondary;
- int m_widthOfSecondary;
+ /**
+ * Extracts the geometry information needed by adjustSpacing() from
+ * ViewContainers. They are also monitored for size changes which
+ * will lead to adjustSpacing() calls.
+ */
+ class ViewGeometriesHelper : public QObject
+ {
+ public:
+ /**
+ * @param navigatorsWidget The QWidget of the navigatorsWidgetAction.
+ * @param navigatorsWidgetAction is only used to call adjustSpacing() whenever that is
+ * deemed necessary.
+ */
+ ViewGeometriesHelper(QWidget *navigatorsWidget, DolphinNavigatorsWidgetAction *navigatorsWidgetAction);
+
+ /**
+ * Calls m_navigatorsWidgetAction::adjustSpacing() when a watched object is resized.
+ */
+ bool eventFilter(QObject *watched, QEvent *event) override;
+
+ /**
+ * Sets the ViewContainers whose geometry is obtained when viewGeometries() is called.
+ */
+ void setViewContainers(QWidget *primaryViewContainer,
+ QWidget *secondaryViewContainer = nullptr);
+
+ struct Geometries {
+ int globalXOfNavigatorsWidget;
+ int globalXOfPrimary;
+ int widthOfPrimary;
+ int globalXOfSecondary;
+ int widthOfSecondary;
+ };
+ /**
+ * @return a Geometries struct that contains values adjustSpacing() requires.
+ */
+ Geometries viewGeometries();
+
+ private:
+ QWidget *m_navigatorsWidget;
+ /** Is only used to call adjustSpacing() whenever that is deemed necessary. */
+ DolphinNavigatorsWidgetAction *m_navigatorsWidgetAction;
+
+ QPointer<QWidget> m_primaryViewContainer;
+ QPointer<QWidget> m_secondaryViewContainer;
+ };
+
+ ViewGeometriesHelper m_viewGeometriesHelper;
};
#endif // DOLPHINNAVIGATORSWIDGETACTION_H
#include "views/dolphinview.h"
#include "views/dolphinviewactionhandler.h"
-#include <KAboutData>
+#include <KPluginMetaData>
#include <KActionCollection>
#include <KAuthorized>
#include <KConfigGroup>
#include <QStandardPaths>
#include <QTextDocument>
-K_PLUGIN_FACTORY(DolphinPartFactory, registerPlugin<DolphinPart>();)
+K_PLUGIN_CLASS_WITH_JSON(DolphinPart, "dolphinpart.json")
-DolphinPart::DolphinPart(QWidget* parentWidget, QObject* parent, const QVariantList& args)
+DolphinPart::DolphinPart(QWidget* parentWidget, QObject* parent,
+ const KPluginMetaData& metaData, const QVariantList& args)
: KParts::ReadOnlyPart(parent)
,m_openTerminalAction(nullptr)
,m_removeAction(nullptr)
{
Q_UNUSED(args)
- setComponentData(*createAboutData(), false);
+ setMetaData(metaData);
+
m_extension = new DolphinPartBrowserExtension(this);
// make sure that other apps using this part find Dolphin's view-file-columns icons
// TODO there was a "always open a new window" (when clicking on a directory) setting in konqueror
// (sort of spacial navigation)
- loadPlugins(this, this, componentData());
+ loadPlugins(this, this, componentName());
}
DolphinPart::~DolphinPart()
QAction* selectItemsMatching = actionCollection()->addAction(QStringLiteral("select_items_matching"));
selectItemsMatching->setText(i18nc("@action:inmenu Edit", "Select Items Matching..."));
- actionCollection()->setDefaultShortcut(selectItemsMatching, Qt::CTRL + Qt::Key_S);
+ actionCollection()->setDefaultShortcut(selectItemsMatching, Qt::CTRL | Qt::Key_S);
connect(selectItemsMatching, &QAction::triggered, this, &DolphinPart::slotSelectItemsMatchingPattern);
QAction* unselectItemsMatching = actionCollection()->addAction(QStringLiteral("unselect_items_matching"));
QAction* invertSelection = actionCollection()->addAction(QStringLiteral("invert_selection"));
invertSelection->setText(i18nc("@action:inmenu Edit", "Invert Selection"));
- actionCollection()->setDefaultShortcut(invertSelection, Qt::CTRL + Qt::SHIFT + Qt::Key_A);
+ actionCollection()->setDefaultShortcut(invertSelection, Qt::CTRL | Qt::SHIFT | Qt::Key_A);
connect(invertSelection, &QAction::triggered, m_view, &DolphinView::invertSelection);
// View menu: all done by DolphinViewActionHandler
Q_EMIT m_extension->setActionText( "paste", pasteInfo.second );
}
-KAboutData* DolphinPart::createAboutData()
+QString DolphinPart::urlToLocalFilePath(const QUrl &url)
{
- return new KAboutData(QStringLiteral("dolphinpart"), i18nc("@title", "Dolphin Part"), QStringLiteral("0.1"));
+ KIO::StatJob* statJob = KIO::mostLocalUrl(url);
+ KJobWidgets::setWindow(statJob, widget());
+ statJob->exec();
+ QUrl localUrl = statJob->mostLocalUrl();
+ if (localUrl.isLocalFile()) {
+ return localUrl.toLocalFile();
+ }
+ return QString();
}
bool DolphinPart::openUrl(const QUrl &url)
if (m_view->url() == url && !reload) { // DolphinView won't do anything in that case, so don't emit started
return true;
}
- setUrl(url); // remember it at the KParts level
+ setUrl(url); // remember url at the KParts level
+ setLocalFilePath(urlToLocalFilePath(url)); // remember local path at the KParts level
QUrl visibleUrl(url);
if (!m_nameFilter.isEmpty()) {
visibleUrl.setPath(visibleUrl.path() + '/' + m_nameFilter);
m_view->reload();
// Disable "Find File" and "Open Terminal" actions for non-file URLs,
// e.g. ftp, smb, etc. #279283
- const bool isLocalUrl = url.isLocalFile();
+ const bool isLocalUrl = !(localFilePath().isEmpty());
m_findFileAction->setEnabled(isLocalUrl);
if (m_openTerminalAction) {
m_openTerminalAction->setEnabled(isLocalUrl);
// TODO save/restore name filter in saveState/restoreState like KonqDirPart did in kde3?
}
+QString DolphinPart::localFilePathOrHome() const
+{
+ const QString localPath = localFilePath();
+ if (!localPath.isEmpty()) {
+ return localPath;
+ }
+ return QDir::homePath();
+}
+
void DolphinPart::slotOpenTerminal()
{
- KToolInvocation::invokeTerminal(QString(), KParts::ReadOnlyPart::localFilePath());
+ KToolInvocation::invokeTerminal(QString(), localFilePathOrHome());
}
void DolphinPart::slotFindFile()
{
QMenu searchTools;
KMoreToolsMenuFactory("dolphin/search-tools").fillMenuFromGroupingNames(
- &searchTools, { "files-find" }, QUrl::fromLocalFile(KParts::ReadOnlyPart::localFilePath())
+ &searchTools, { "files-find" }, QUrl::fromLocalFile(localFilePathOrHome())
);
QList<QAction*> actions = searchTools.actions();
if (!(actions.isEmpty())) {
Name[zh_TW]=Dolphin 檢視
MimeType=inode/directory;
X-KDE-ServiceTypes=KParts/ReadOnlyPart,Browser/View
-X-KDE-Library=dolphinpart
+X-KDE-Library=kf5/parts/dolphinpart
#X-KDE-BrowserView-Args=Icon
X-KDE-BrowserView-HideFromMenus=true
X-KDE-BrowserView-Built-Into=konqueror
-Icon=view-icon
+Icon=view-list-icons
InitialPreference=7
+X-KDE-PluginInfo-Name=dolphinpart
+X-KDE-PluginInfo-Version=@DOLPHIN_VERSION@
+X-KDE-PluginInfo-License=LGPL v2+
+
+
# Provide info about the view modes using the Actions mechanism so that KService parses it.
# Konqueror then queries KService to get hold of the translated texts for the view modes
Actions=icons;details;compact;
class DolphinRemoteEncoding;
class KDirLister;
class DolphinView;
-class KAboutData;
class DolphinRemoveAction;
class DolphinPart : public KParts::ReadOnlyPart
Q_PROPERTY( QList<QUrl> filesToSelect READ filesToSelect WRITE setFilesToSelect )
public:
- explicit DolphinPart(QWidget* parentWidget, QObject* parent, const QVariantList& args);
+ explicit DolphinPart(QWidget* parentWidget, QObject* parent,
+ const KPluginMetaData& metaData, const QVariantList& args);
~DolphinPart() override;
- static KAboutData* createAboutData();
-
/**
* Standard KParts::ReadOnlyPart openUrl method.
* Called by Konqueror to view a directory in DolphinPart.
void openSelectionDialog(const QString& title, const QString& text,
bool selectItems);
+ QString urlToLocalFilePath(const QUrl &url);
+ QString localFilePathOrHome() const;
private:
DolphinView* m_view;
-<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="dolphinpart" version="15" translationDomain="dolphin">
+<?xml version="1.0"?>
+<!DOCTYPE gui SYSTEM "kpartgui.dtd">
+<gui name="dolphinpart" version="15" translationDomain="dolphin">
<MenuBar>
<Menu name="edit"><text>&Edit</text>
<Action name="new_menu"/>
<Action name="deletefile" />
</disable>
</State>
-</kpartgui>
+</gui>
/*
* SPDX-FileCopyrightText: 2014 Emmanuel Pescosta <emmanuelpescosta099@gmail.com>
+ * SPDX-FileCopyrightText: 2020 Felix Ernst <fe.a.ernst@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "dolphin_generalsettings.h"
#include "dolphinviewcontainer.h"
+#include "global.h"
+#include <QVariantAnimation>
#include <QSplitter>
#include <QGridLayout>
#include <QWidgetAction>
+#include <QStyle>
DolphinTabPage::DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl, QWidget* parent) :
QWidget(parent),
+ m_expandingContainer{nullptr},
m_primaryViewActive(true),
m_splitViewEnabled(false),
m_active(true)
this, &DolphinTabPage::slotViewUrlRedirection);
m_splitter->addWidget(m_primaryViewContainer);
- m_primaryViewContainer->installEventFilter(this);
m_primaryViewContainer->show();
if (secondaryUrl.isValid() || GeneralSettings::splitView()) {
const QUrl& url = secondaryUrl.isValid() ? secondaryUrl : primaryUrl;
m_secondaryViewContainer = createViewContainer(url);
m_splitter->addWidget(m_secondaryViewContainer);
- m_secondaryViewContainer->installEventFilter(this);
m_secondaryViewContainer->show();
}
return m_splitViewEnabled;
}
-void DolphinTabPage::setSplitViewEnabled(bool enabled, const QUrl &secondaryUrl)
+void DolphinTabPage::setSplitViewEnabled(bool enabled, Animated animated, const QUrl &secondaryUrl)
{
if (m_splitViewEnabled != enabled) {
m_splitViewEnabled = enabled;
+ if (animated == WithAnimation && (
+ style()->styleHint(QStyle::SH_Widget_Animation_Duration, nullptr, this) < 1 ||
+ GlobalConfig::animationDurationFactor() <= 0.0)) {
+ animated = WithoutAnimation;
+ }
+ if (m_expandViewAnimation) {
+ m_expandViewAnimation->stop(); // deletes because of QAbstractAnimation::DeleteWhenStopped.
+ if (animated == WithoutAnimation) {
+ slotAnimationFinished();
+ }
+ }
if (enabled) {
+ QList<int> splitterSizes = m_splitter->sizes();
const QUrl& url = (secondaryUrl.isEmpty()) ? m_primaryViewContainer->url() : secondaryUrl;
m_secondaryViewContainer = createViewContainer(url);
}
m_secondaryViewContainer->connectUrlNavigator(secondaryNavigator);
m_navigatorsWidget->setSecondaryNavigatorVisible(true);
+ m_navigatorsWidget->followViewContainersGeometry(m_primaryViewContainer,
+ m_secondaryViewContainer);
m_splitter->addWidget(m_secondaryViewContainer);
- m_secondaryViewContainer->installEventFilter(this);
- m_secondaryViewContainer->show();
m_secondaryViewContainer->setActive(true);
+
+ if (animated == WithAnimation) {
+ m_secondaryViewContainer->setMinimumWidth(1);
+ splitterSizes.append(1);
+ m_splitter->setSizes(splitterSizes);
+ startExpandViewAnimation(m_secondaryViewContainer);
+ }
+ m_secondaryViewContainer->show();
} else {
m_navigatorsWidget->setSecondaryNavigatorVisible(false);
m_secondaryViewContainer->disconnectUrlNavigator();
}
}
m_primaryViewContainer->setActive(true);
- view->close();
- view->deleteLater();
+ m_navigatorsWidget->followViewContainersGeometry(m_primaryViewContainer, nullptr);
+
+ if (animated == WithoutAnimation) {
+ view->close();
+ view->deleteLater();
+ } else {
+ // Kill it but keep it as a zombie for the closing animation.
+ m_secondaryViewContainer = nullptr;
+ view->blockSignals(true);
+ view->view()->blockSignals(true);
+ view->setDisabled(true);
+ startExpandViewAnimation(m_primaryViewContainer);
+ }
}
}
}
auto secondaryNavigator = navigatorsWidget->secondaryUrlNavigator();
m_secondaryViewContainer->connectUrlNavigator(secondaryNavigator);
}
- resizeNavigators();
+ m_navigatorsWidget->followViewContainersGeometry(m_primaryViewContainer,
+ m_secondaryViewContainer);
}
void DolphinTabPage::disconnectNavigators()
}
}
-bool DolphinTabPage::eventFilter(QObject *watched, QEvent *event)
-{
- if (event->type() == QEvent::Resize && m_navigatorsWidget) {
- resizeNavigators();
- return false;
- }
- return QWidget::eventFilter(watched, event);
-}
-
void DolphinTabPage::insertNavigatorsWidget(DolphinNavigatorsWidgetAction* navigatorsWidget)
{
QGridLayout *gridLayout = static_cast<QGridLayout *>(layout());
}
}
-
-void DolphinTabPage::resizeNavigators() const
-{
- if (!m_splitViewEnabled) {
- m_navigatorsWidget->followViewContainerGeometry(
- m_primaryViewContainer->mapToGlobal(QPoint(0,0)).x(),
- m_primaryViewContainer->width());
- } else {
- m_navigatorsWidget->followViewContainersGeometry(
- m_primaryViewContainer->mapToGlobal(QPoint(0,0)).x(),
- m_primaryViewContainer->width(),
- m_secondaryViewContainer->mapToGlobal(QPoint(0,0)).x(),
- m_secondaryViewContainer->width());
- }
-}
-
void DolphinTabPage::markUrlsAsSelected(const QList<QUrl>& urls)
{
m_primaryViewContainer->view()->markUrlsAsSelected(urls);
bool isSplitViewEnabled = false;
stream >> isSplitViewEnabled;
- setSplitViewEnabled(isSplitViewEnabled);
+ setSplitViewEnabled(isSplitViewEnabled, WithoutAnimation);
QUrl primaryUrl;
stream >> primaryUrl;
bool isSplitViewEnabled = false;
stream >> isSplitViewEnabled;
- setSplitViewEnabled(isSplitViewEnabled);
+ setSplitViewEnabled(isSplitViewEnabled, WithoutAnimation);
QUrl primaryUrl;
stream >> primaryUrl;
activeViewContainer()->setActive(active);
}
+void DolphinTabPage::slotAnimationFinished()
+{
+ for (int i = 0; i < m_splitter->count(); ++i) {
+ QWidget *viewContainer = m_splitter->widget(i);
+ if (viewContainer != m_primaryViewContainer &&
+ viewContainer != m_secondaryViewContainer) {
+ viewContainer->close();
+ viewContainer->deleteLater();
+ }
+ }
+ for (int i = 0; i < m_splitter->count(); ++i) {
+ QWidget *viewContainer = m_splitter->widget(i);
+ viewContainer->setMinimumWidth(viewContainer->minimumSizeHint().width());
+ }
+ m_expandingContainer = nullptr;
+}
+
+void DolphinTabPage::slotAnimationValueChanged(const QVariant& value)
+{
+ Q_CHECK_PTR(m_expandingContainer);
+ const int indexOfExpandingContainer = m_splitter->indexOf(m_expandingContainer);
+ int indexOfNonExpandingContainer = -1;
+ if (m_expandingContainer == m_primaryViewContainer) {
+ indexOfNonExpandingContainer = m_splitter->indexOf(m_secondaryViewContainer);
+ } else {
+ indexOfNonExpandingContainer = m_splitter->indexOf(m_primaryViewContainer);
+ }
+ std::vector<QWidget *> widgetsToRemove;
+ const QList<int> oldSplitterSizes = m_splitter->sizes();
+ QList<int> newSplitterSizes{oldSplitterSizes};
+ int expansionWidthNeeded = value.toInt() - oldSplitterSizes.at(indexOfExpandingContainer);
+
+ // Reduce the size of the other widgets to make space for the expandingContainer.
+ for (int i = m_splitter->count() - 1; i >= 0; --i) {
+ if (m_splitter->widget(i) == m_primaryViewContainer ||
+ m_splitter->widget(i) == m_secondaryViewContainer) {
+ continue;
+ }
+ newSplitterSizes[i] = oldSplitterSizes.at(i) - expansionWidthNeeded;
+ expansionWidthNeeded = 0;
+ if (indexOfNonExpandingContainer != -1) {
+ // Make sure every zombie container is at least slightly reduced in size
+ // so it doesn't seem like they are here to stay.
+ newSplitterSizes[i]--;
+ newSplitterSizes[indexOfNonExpandingContainer]++;
+ }
+ if (newSplitterSizes.at(i) <= 0) {
+ expansionWidthNeeded -= newSplitterSizes.at(i);
+ newSplitterSizes[i] = 0;
+ widgetsToRemove.emplace_back(m_splitter->widget(i));
+ }
+ }
+ if (expansionWidthNeeded > 1 && indexOfNonExpandingContainer != -1) {
+ Q_ASSERT(m_splitViewEnabled);
+ newSplitterSizes[indexOfNonExpandingContainer] -= expansionWidthNeeded;
+ }
+ newSplitterSizes[indexOfExpandingContainer] = value.toInt();
+ m_splitter->setSizes(newSplitterSizes);
+ while (!widgetsToRemove.empty()) {
+ widgetsToRemove.back()->close();
+ widgetsToRemove.back()->deleteLater();
+ widgetsToRemove.pop_back();
+ }
+}
+
+
void DolphinTabPage::slotViewActivated()
{
const DolphinView* oldActiveView = activeViewContainer()->view();
return container;
}
+
+void DolphinTabPage::startExpandViewAnimation(DolphinViewContainer *expandingContainer)
+{
+ Q_CHECK_PTR(expandingContainer);
+ Q_ASSERT(expandingContainer == m_primaryViewContainer ||
+ expandingContainer == m_secondaryViewContainer);
+ m_expandingContainer = expandingContainer;
+
+ m_expandViewAnimation = new QVariantAnimation(m_splitter);
+ m_expandViewAnimation->setDuration(2 *
+ style()->styleHint(QStyle::SH_Widget_Animation_Duration, nullptr, this) *
+ GlobalConfig::animationDurationFactor());
+ for (int i = 0; i < m_splitter->count(); ++i) {
+ m_splitter->widget(i)->setMinimumWidth(1);
+ }
+ connect(m_expandViewAnimation, &QAbstractAnimation::finished,
+ this, &DolphinTabPage::slotAnimationFinished);
+ connect(m_expandViewAnimation, &QVariantAnimation::valueChanged,
+ this, &DolphinTabPage::slotAnimationValueChanged);
+
+ m_expandViewAnimation->setStartValue(expandingContainer->width());
+ if (m_splitViewEnabled) { // A new viewContainer is being opened.
+ m_expandViewAnimation->setEndValue(m_splitter->width() / 2);
+ m_expandViewAnimation->setEasingCurve(QEasingCurve::OutCubic);
+ } else { // A viewContainer is being closed.
+ m_expandViewAnimation->setEndValue(m_splitter->width());
+ m_expandViewAnimation->setEasingCurve(QEasingCurve::InCubic);
+ }
+ m_expandViewAnimation->start(QAbstractAnimation::DeleteWhenStopped);
+}
/*
* SPDX-FileCopyrightText: 2014 Emmanuel Pescosta <emmanuelpescosta099@gmail.com>
+ * SPDX-FileCopyrightText: 2020 Felix Ernst <fe.a.ernst@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
class DolphinNavigatorsWidgetAction;
class DolphinViewContainer;
class QSplitter;
+class QVariantAnimation;
class KFileItemList;
+enum Animated {
+ WithAnimation,
+ WithoutAnimation
+};
+
class DolphinTabPage : public QWidget
{
Q_OBJECT
/**
* Enables or disables the split view mode.
*
- * If \a enabled is true, it creates a secondary view with the url of the primary view.
+ * @param enabled If true, creates a secondary viewContainer in this tab.
+ * Otherwise deletes it.
+ * @param animated Decides wether the effects of this method call should
+ * happen instantly or be transitioned to smoothly.
+ * @param secondaryUrl If \p enabled is true, the new viewContainer will be opened at this
+ * parameter. The default value will set the Url of the new viewContainer
+ * to be the same as the existing one.
*/
- void setSplitViewEnabled(bool enabled, const QUrl &secondaryUrl = QUrl());
+ void setSplitViewEnabled(bool enabled, Animated animated, const QUrl &secondaryUrl = QUrl());
/**
* @return The primary view container.
*/
void disconnectNavigators();
- /**
- * Calls resizeNavigators() when a watched object is resized.
- */
- bool eventFilter(QObject *watched, QEvent *event) override;
-
void insertNavigatorsWidget(DolphinNavigatorsWidgetAction *navigatorsWidget);
/**
void splitterMoved(int pos, int index);
private slots:
+ /**
+ * Deletes all zombie viewContainers that were used for the animation
+ * and resets the minimum size of the others to a sane value.
+ */
+ void slotAnimationFinished();
+
+ /**
+ * This method is called for every frame of the m_expandViewAnimation.
+ */
+ void slotAnimationValueChanged(const QVariant &value);
+
/**
* Handles the view activated event.
*
*/
DolphinViewContainer* createViewContainer(const QUrl& url) const;
+ /**
+ * Starts an animation that transitions between split view mode states.
+ *
+ * One of the viewContainers is always being expanded when toggling so
+ * this method can animate both opening and closing of viewContainers.
+ * @param expandingContainer The container that will increase in size
+ * over the course of the animation.
+ */
+ void startExpandViewAnimation(DolphinViewContainer *expandingContainer);
+
private:
QSplitter* m_splitter;
QPointer<DolphinViewContainer> m_primaryViewContainer;
QPointer<DolphinViewContainer> m_secondaryViewContainer;
+ DolphinViewContainer *m_expandingContainer;
+ QPointer<QVariantAnimation> m_expandViewAnimation;
+
bool m_primaryViewActive;
bool m_splitViewEnabled;
bool m_active;
void DolphinTabWidget::openNewActivatedTab(const QUrl& primaryUrl, const QUrl& secondaryUrl)
{
openNewTab(primaryUrl, secondaryUrl);
- setCurrentIndex(count() - 1);
+ if (GeneralSettings::openNewTabAfterLastTab()) {
+ setCurrentIndex(count() - 1);
+ } else {
+ setCurrentIndex(currentIndex() + 1);
+ }
}
-void DolphinTabWidget::openNewTab(const QUrl& primaryUrl, const QUrl& secondaryUrl, TabPlacement tabPlacement)
+void DolphinTabWidget::openNewTab(const QUrl& primaryUrl, const QUrl& secondaryUrl)
{
QWidget* focusWidget = QApplication::focusWidget();
connect(tabPage, &DolphinTabPage::activeViewUrlChanged,
this, &DolphinTabWidget::tabUrlChanged);
int newTabIndex = -1;
- if (tabPlacement == AfterCurrentTab) {
+ if (!GeneralSettings::openNewTabAfterLastTab()) {
newTabIndex = currentIndex() + 1;
}
insertTab(newTabIndex, tabPage, QIcon() /* loaded in tabInserted */, tabName(tabPage));
Q_OBJECT
public:
- /**
- * @brief Controls where tabs are placed
- */
- enum TabPlacement {
- /**
- * The new tab is placed after the current tab
- */
- AfterCurrentTab,
- /**
- * The new tab is placed after the last tab
- */
- AfterLastTab
- };
/**
* @param navigatorsWidget The navigatorsWidget which is always going to be connected
/**
* Opens a new tab in the background showing the URL \a primaryUrl and the
- * optional URL \a secondaryUrl. \a tabPlacement controls where the new tab
- * is placed.
+ * optional URL \a secondaryUrl.
*/
- void openNewTab(const QUrl &primaryUrl, const QUrl &secondaryUrl = QUrl(),
- DolphinTabWidget::TabPlacement tabPlacement = AfterLastTab);
+ void openNewTab(const QUrl &primaryUrl, const QUrl &secondaryUrl = QUrl());
/**
* Opens each directory in \p dirs in a separate tab. If \a splitView is set,
-<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="dolphin" version="33">
+<?xml version="1.0"?>
+<!DOCTYPE gui SYSTEM "kpartgui.dtd">
+<gui name="dolphin" version="33">
<MenuBar>
<Menu name="file">
<Action name="new_menu" />
<Action name="copy_location" />
<Action name="edit_paste" />
<Separator />
+ <Action name="show_filter_bar" />
<Action name="edit_find" />
<Separator />
<Action name="copy_to_inactive_split_view" />
<Action name="closed_tabs" />
</Menu>
<Menu name="tools">
- <Action name="show_filter_bar" />
<Action name="open_preferred_search_tool" />
<Action name="open_terminal" />
<Action name="focus_terminal_panel"/>
<Action name="split_view" />
<Action name="split_stash" />
<Action name="toggle_search" />
+ <Action name="toggle_filter" />
</ToolBar>
<ActionProperties scheme="Default">
<Action priority="0" name="go_back"/>
<Action priority="0" name="edit_copy"/>
<Action priority="0" name="edit_paste"/>
<Action priority="0" name="toggle_search"/>
+ <Action priority="0" name="toggle_filter"/>
</ActionProperties>
-</kpartgui>
+</gui>
}
}
+void DolphinUrlNavigator::clearText() const
+{
+ editor()->lineEdit()->clear();
+}
+
+void DolphinUrlNavigator::setPlaceholderText(const QString &text)
+{
+ editor()->lineEdit()->setPlaceholderText(text);
+}
+
void DolphinUrlNavigator::slotReturnPressed()
{
if (!GeneralSettings::editableUrl()) {
*/
void setVisualState(const VisualState &visualState);
+ /**
+ * Clears the text in the text field
+ */
+ void clearText() const;
+
+ /**
+ * Displays placeholder text in the URL navigator
+ */
+ void setPlaceholderText(const QString &text);
+
public slots:
/**
* Switches to "breadcrumb" mode if the editable mode is not set to be
#include "dolphindebug.h"
#include "dolphinmainwindowinterface.h"
+#include <KConfigWatcher>
#include <KDialogJobUiDelegate>
#include <KIO/ApplicationLauncherJob>
#include <KService>
return dolphinInterfaces;
}
+
+double GlobalConfig::animationDurationFactor()
+{
+ if (s_animationDurationFactor >= 0.0) {
+ return s_animationDurationFactor;
+ }
+ // This is the first time this method is called.
+ auto kdeGlobalsConfig = KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("KDE"));
+ updateAnimationDurationFactor(kdeGlobalsConfig, {"AnimationDurationFactor"});
+
+ KConfigWatcher::Ptr configWatcher = KConfigWatcher::create(KSharedConfig::openConfig());
+ connect(configWatcher.data(), &KConfigWatcher::configChanged,
+ &GlobalConfig::updateAnimationDurationFactor);
+ return s_animationDurationFactor;
+}
+
+void GlobalConfig::updateAnimationDurationFactor(const KConfigGroup &group, const QByteArrayList &names)
+{
+ if (group.name() == QLatin1String("KDE") &&
+ names.contains(QByteArrayLiteral("AnimationDurationFactor"))) {
+ s_animationDurationFactor = std::max(0.0,
+ group.readEntry("AnimationDurationFactor", 1.0));
+ }
+}
+
+double GlobalConfig::s_animationDurationFactor = -1.0;
#include <QUrl>
#include <QWidget>
+class KConfigGroup;
class OrgKdeDolphinMainWindowInterface;
namespace Dolphin {
const int LAYOUT_SPACING_SMALL = 2;
}
+class GlobalConfig : public QObject
+{
+ Q_OBJECT
+
+public:
+ GlobalConfig() = delete;
+
+ /**
+ * @return a value from the global KDE config that should be
+ * multiplied with every animation duration once.
+ * 0.0 is returned if animations are globally turned off.
+ * 1.0 is the default value.
+ */
+ static double animationDurationFactor();
+
+private:
+ static void updateAnimationDurationFactor(const KConfigGroup &group, const QByteArrayList &names);
+
+private:
+ static double s_animationDurationFactor;
+};
+
#endif //GLOBAL_H
{
QString text;
const QVariant roleValue = values.value(role);
+ QLocale local;
+ KFormat formatter(local);
// Implementation note: In case if more roles require a custom handling
// use a hash + switch for a linear runtime.
+ auto formatDate = [formatter, local](const QDateTime& time) {
+ if (DetailsModeSettings::useShortRelativeDates()) {
+ return formatter.formatRelativeDateTime(time, QLocale::ShortFormat);
+ } else {
+ return local.toString(time, QLocale::ShortFormat);
+ }
+ };
+
if (role == "size") {
if (values.value("isDir").toBool()) {
- // The item represents a directory.
- if (!roleValue.isNull()) {
- const int count = values.value("count").toInt();
- if (count > 0) {
- if (DetailsModeSettings::directorySizeCount()) {
- // Show the number of sub directories instead of the file size of the directory.
- text = i18ncp("@item:intable", "%1 item", "%1 items", count);
- } else {
- // if we have directory size available
- if (roleValue != -1) {
- const KIO::filesize_t size = roleValue.value<KIO::filesize_t>();
- text = KFormat().formatByteSize(size);
- }
- }
+ if (!roleValue.isNull() && roleValue != -1) {
+ // The item represents a directory.
+ if (DetailsModeSettings::directorySizeCount()) {
+ // Show the number of sub directories instead of the file size of the directory.
+ const int count = values.value("count").toInt();
+ text = i18ncp("@item:intable", "%1 item", "%1 items", count);
+ } else {
+ // if we have directory size available
+ const KIO::filesize_t size = roleValue.value<KIO::filesize_t>();
+ text = formatter.formatByteSize(size);
}
}
} else {
const KIO::filesize_t size = roleValue.value<KIO::filesize_t>();
- text = KFormat().formatByteSize(size);
+ text = formatter.formatByteSize(size);
}
} else if (role == "modificationtime" || role == "creationtime" || role == "accesstime") {
bool ok;
const long long time = roleValue.toLongLong(&ok);
if (ok && time != -1) {
- return QLocale().toString(QDateTime::fromSecsSinceEpoch(time), QLocale::ShortFormat);
+ const QDateTime dateTime = QDateTime::fromSecsSinceEpoch(time);
+ text = formatDate(dateTime);
}
} else if (role == "deletiontime" || role == "imageDateTime") {
const QDateTime dateTime = roleValue.toDateTime();
- text = QLocale().toString(dateTime, QLocale::ShortFormat);
+ if (dateTime.isValid()) {
+ text = formatDate(dateTime);
+ }
} else {
text = KStandardItemListWidgetInformant::roleText(role, values);
}
if (getSizeRole) {
data.insert("count", count);
- if (size != -1) {
- data.insert("size", QVariant::fromValue(size));
- }
+ data.insert("size", QVariant::fromValue(size));
}
if (getIsExpandableRole) {
data.insert("isExpandable", count > 0);
return true;
}
+ const bool controlPressed = modifiers & Qt::ControlModifier;
const bool shiftOrControlPressed = modifiers & Qt::ShiftModifier ||
- modifiers & Qt::ControlModifier;
+ controlPressed;
KItemListRubberBand* rubberBand = m_view->rubberBand();
if (rubberBand->isActive()) {
} else if (shiftOrControlPressed) {
// The mouse click should only update the selection, not trigger the item
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;
#include <QPropertyAnimation>
#include <QStyleOptionRubberBand>
#include <QTimer>
+#include <QVariantAnimation>
namespace {
// Delay in ms for triggering the next autoscroll
const int RepeatingAutoScrollDelay = 1000 / 60;
+
+ // Copied from the Kirigami.Units.shortDuration
+ const int RubberFadeSpeed = 150;
+
+ const char* RubberPropertyName = "_kitemviews_rubberBandPosition";
}
#ifndef QT_NO_ACCESSIBILITY
{
QGraphicsWidget::paint(painter, option, widget);
+ for (auto animation : qAsConst(m_rubberBandAnimations)) {
+ QRectF rubberBandRect = animation->property(RubberPropertyName).toRectF();
+
+ const QPointF topLeft = rubberBandRect.topLeft();
+ if (scrollOrientation() == Qt::Vertical) {
+ rubberBandRect.moveTo(topLeft.x(), topLeft.y() - scrollOffset());
+ } else {
+ rubberBandRect.moveTo(topLeft.x() - scrollOffset(), topLeft.y());
+ }
+
+ QStyleOptionRubberBand opt;
+ initStyleOption(&opt);
+ opt.shape = QRubberBand::Rectangle;
+ opt.opaque = false;
+ opt.rect = rubberBandRect.toRect();
+
+ painter->save();
+
+ painter->setOpacity(animation->currentValue().toReal());
+ style()->drawControl(QStyle::CE_RubberBand, &opt, painter);
+
+ painter->restore();
+ }
+
if (m_rubberBand->isActive()) {
QRectF rubberBandRect = QRectF(m_rubberBand->startPosition(),
m_rubberBand->endPosition()).normalized();
connect(m_rubberBand, &KItemListRubberBand::endPositionChanged, this, &KItemListView::slotRubberBandPosChanged);
m_skipAutoScrollForRubberBand = true;
} else {
+ QRectF rubberBandRect = QRectF(m_rubberBand->startPosition(),
+ m_rubberBand->endPosition()).normalized();
+
+ auto animation = new QVariantAnimation(this);
+ animation->setStartValue(1.0);
+ animation->setEndValue(0.0);
+ animation->setDuration(RubberFadeSpeed);
+ animation->setProperty(RubberPropertyName, rubberBandRect);
+
+ QEasingCurve curve;
+ curve.setType(QEasingCurve::BezierSpline);
+ curve.addCubicBezierSegment(QPointF(0.4, 0.0), QPointF(1.0, 1.0), QPointF(1.0, 1.0));
+ animation->setEasingCurve(curve);
+
+ connect(animation, &QVariantAnimation::valueChanged, this, [=](const QVariant&) {
+ update();
+ });
+ connect(animation, &QVariantAnimation::finished, this, [=]() {
+ m_rubberBandAnimations.removeAll(animation);
+ delete animation;
+ });
+ animation->start();
+ m_rubberBandAnimations << animation;
+
disconnect(m_rubberBand, &KItemListRubberBand::startPositionChanged, this, &KItemListView::slotRubberBandPosChanged);
disconnect(m_rubberBand, &KItemListRubberBand::endPositionChanged, this, &KItemListView::slotRubberBandPosChanged);
m_skipAutoScrollForRubberBand = false;
class KItemListWidgetCreatorBase;
class QTimer;
class QPropertyAnimation;
+class QVariantAnimation;
/**
* @brief Represents the view of an item-list.
// by KItemListView::showDropIndicator() and KItemListView::hideDropIndicator().
QRectF m_dropIndicator;
+ QList<QVariantAnimation*> m_rubberBandAnimations;
+
friend class KItemListContainer; // Accesses scrollBarRequired()
friend class KItemListHeader; // Accesses m_headerWidget
friend class KItemListController;
#include <Baloo/File>
#include <KFileMetaData/PropertyInfo>
#include <KFileMetaData/UserMetaData>
-#include <KFormat>
-#include <KLocalizedString>
#include <QCollator>
#include <QDebug>
#include <QTime>
+namespace {
+ QString tagsFromValues(const QStringList& values)
+ {
+ if (values.size() == 1) {
+ return values.at(0);
+ }
+
+ QStringList alphabeticalOrderTags = values;
+ QCollator coll;
+ coll.setNumericMode(true);
+ std::sort(alphabeticalOrderTags.begin(), alphabeticalOrderTags.end(), [&](const QString& s1, const QString& s2){ return coll.compare(s1, s2) < 0; });
+ return alphabeticalOrderTags.join(QLatin1String(", "));
+ }
+
+ using Property = KFileMetaData::Property::Property;
+ // Mapping from the KFM::Property to the KFileItemModel roles.
+ const QHash<Property, QByteArray> propertyRoleMap() {
+ static const auto map = QHash<Property, QByteArray> {
+ { Property::Rating, QByteArrayLiteral("rating") },
+ { Property::Comment, QByteArrayLiteral("comment") },
+ { Property::Title, QByteArrayLiteral("title") },
+ { Property::WordCount, QByteArrayLiteral("wordCount") },
+ { Property::LineCount, QByteArrayLiteral("lineCount") },
+ { Property::Width, QByteArrayLiteral("width") },
+ { Property::Height, QByteArrayLiteral("height") },
+ { Property::ImageDateTime, QByteArrayLiteral("imageDateTime") },
+ { Property::ImageOrientation, QByteArrayLiteral("orientation") },
+ { Property::Artist, QByteArrayLiteral("artist") },
+ { Property::Genre, QByteArrayLiteral("genre") },
+ { Property::Album, QByteArrayLiteral("album") },
+ { Property::Duration, QByteArrayLiteral("duration") },
+ { Property::BitRate, QByteArrayLiteral("bitrate") },
+ { Property::AspectRatio, QByteArrayLiteral("aspectRatio") },
+ { Property::FrameRate, QByteArrayLiteral("frameRate") },
+ { Property::ReleaseYear, QByteArrayLiteral("releaseYear") },
+ { Property::TrackNumber, QByteArrayLiteral("track") }
+ };
+ return map;
+ }
+}
+
struct KBalooRolesProviderSingleton
{
KBalooRolesProvider instance;
while (rangeBegin != propMap.constKeyValueEnd()) {
auto key = (*rangeBegin).first;
- const KFileMetaData::PropertyInfo propertyInfo(key);
- const QByteArray role = roleForProperty(propertyInfo.name());
auto rangeEnd = std::find_if(rangeBegin, propMap.constKeyValueEnd(),
[key](const entry& e) { return e.first != key; });
+ const QByteArray role = propertyRoleMap().value(key);
if (role.isEmpty() || !roles.contains(role)) {
rangeBegin = rangeEnd;
continue;
}
+ const KFileMetaData::PropertyInfo propertyInfo(key);
auto distance = std::distance(rangeBegin, rangeEnd);
if (distance > 1) {
QVariantList list;
rangeBegin = rangeEnd;
}
- KFileMetaData::UserMetaData md(file.path());
+ KFileMetaData::UserMetaData::Attributes attributes;
if (roles.contains("tags")) {
- values.insert("tags", tagsFromValues(md.tags()));
+ attributes |= KFileMetaData::UserMetaData::Tags;
}
if (roles.contains("rating")) {
- values.insert("rating", QString::number(md.rating()));
+ attributes |= KFileMetaData::UserMetaData::Rating;
}
if (roles.contains("comment")) {
- values.insert("comment", md.userComment());
+ attributes |= KFileMetaData::UserMetaData::Comment;
}
if (roles.contains("originUrl")) {
+ attributes |= KFileMetaData::UserMetaData::OriginUrl;
+ }
+
+ if (attributes == KFileMetaData::UserMetaData::None) {
+ return values;
+ }
+
+ KFileMetaData::UserMetaData md(file.path());
+ attributes = md.queryAttributes(attributes);
+
+ if (attributes & KFileMetaData::UserMetaData::Tags) {
+ values.insert("tags", tagsFromValues(md.tags()));
+ }
+ if (attributes & KFileMetaData::UserMetaData::Rating) {
+ values.insert("rating", QString::number(md.rating()));
+ }
+ if (attributes & KFileMetaData::UserMetaData::Comment) {
+ values.insert("comment", md.userComment());
+ }
+ if (attributes & KFileMetaData::UserMetaData::OriginUrl) {
values.insert("originUrl", md.originUrl());
}
return values;
}
-QByteArray KBalooRolesProvider::roleForProperty(const QString& property) const
-{
- return m_roleForProperty.value(property);
-}
-
-KBalooRolesProvider::KBalooRolesProvider() :
- m_roles(),
- m_roleForProperty()
+KBalooRolesProvider::KBalooRolesProvider()
{
- struct PropertyInfo
- {
- const char* const property;
- const char* const role;
- };
-
- // Mapping from the URIs to the KFileItemModel roles. Note that this must not be
- // a 1:1 mapping: One role may contain several URI-values
- static const PropertyInfo propertyInfoList[] = {
- { "rating", "rating" },
- { "tag", "tags" },
- { "comment", "comment" },
- { "title", "title" },
- { "wordCount", "wordCount" },
- { "lineCount", "lineCount" },
- { "width", "width" },
- { "height", "height" },
- { "imageDateTime", "imageDateTime"},
- { "imageOrientation", "orientation", },
- { "artist", "artist" },
- { "genre", "genre" },
- { "album", "album" },
- { "duration", "duration" },
- { "bitRate", "bitrate" },
- { "aspectRatio", "aspectRatio" },
- { "frameRate", "frameRate" },
- { "releaseYear", "releaseYear" },
- { "trackNumber", "track" },
- { "originUrl", "originUrl" }
- };
-
- for (unsigned int i = 0; i < sizeof(propertyInfoList) / sizeof(PropertyInfo); ++i) {
- m_roleForProperty.insert(propertyInfoList[i].property, propertyInfoList[i].role);
- m_roles.insert(propertyInfoList[i].role);
+ // Display roles filled from Baloo property cache
+ for (const auto& role : propertyRoleMap()) {
+ m_roles.insert(role);
}
-}
-QString KBalooRolesProvider::tagsFromValues(const QStringList& values) const
-{
- QStringList alphabeticalOrderTags = values;
- QCollator coll;
- coll.setNumericMode(true);
- std::sort(alphabeticalOrderTags.begin(), alphabeticalOrderTags.end(), [&](const QString& s1, const QString& s2){ return coll.compare(s1, s2) < 0; });
- return alphabeticalOrderTags.join(QLatin1String(", "));
+ // Display roles provided by UserMetaData
+ m_roles.insert(QByteArrayLiteral("tags"));
+ m_roles.insert(QByteArrayLiteral("rating"));
+ m_roles.insert(QByteArrayLiteral("comment"));
+ m_roles.insert(QByteArrayLiteral("originUrl"));
}
+
QHash<QByteArray, QVariant> roleValues(const Baloo::File& file,
const QSet<QByteArray>& roles) const;
- QByteArray roleForProperty(const QString& property) const;
-
protected:
KBalooRolesProvider();
-private:
- /**
- * @return User visible string for the given tag-values.
- * The tag-values are sorted in alphabetical order.
- */
- QString tagsFromValues(const QStringList& values) const;
-
private:
QSet<QByteArray> m_roles;
- QHash<QString, QByteArray> m_roleForProperty;
friend struct KBalooRolesProviderSingleton;
};
auto dir = QT_OPENDIR(QFile::encodeName(dirPath));
if (dir) {
count = 0;
+ size = 0;
QT_STATBUF buf;
while ((dirEntry = QT_READDIR(dir))) {
<summary xml:lang="zh-CN">文件管理器</summary>
<summary xml:lang="zh-TW">檔案管理員</summary>
<description>
- <p>Dolphin is a lightweight file manager. It has been designed with ease of use and simplicity in mind, while still allowing flexibility and customisation. This means that you can do your file management exactly the way you want to do it.</p>
- <p xml:lang="ar">دولفين هو مدير ملفات خفيف. صُمِّم دولفين مع أخذ سهولة الاستخدام والبساطة بعين الاعتبار، مع السماح بالمرونة والتخصيص. يعني هذا أنه يمكنك إدارة ملفاتك كما تريد تمامًا.</p>
- <p xml:lang="ast">Dolphin ye un xestor de ficheros llixeru. Diseñóse cola cenciellez y facilidá d'usu en mente, al empar que permite flexibilidá y personalización. Esto quier dicir que pues facer la xestión de ficheros del mou exautu que quieras.</p>
- <p xml:lang="az">Dolphin yüngül bir fayl meneceridir. Bu tətbiq istifadə rahatlığı və sadələiyi ilə bərabər çevik və fərdi ayarlana bilmə üstünlükləri nəzərə alınaraq hazırlanmışdır. Bu o deməkdir ki, siz faylları istədiyiniz kimi idarə edə bilərsiniz.</p>
- <p xml:lang="bs">Dolphinje lagan file manager. On je bio dizajniran sa lakoćom korišćenja i jednostavnosti u vidu, još omogućavajući fleksibilnost i prilagođavanje. To znači da možete da radite svoje upravljanje datotekama onako kako želite da to uradi.</p>
- <p xml:lang="ca">El Dolphin és un gestor de fitxers lleuger. S'ha dissenyat pensant a facilitar el seu ús i que sigui simple, permetent la flexibilitat i la personalització. Això vol dir que podeu fer la gestió dels vostres fitxers de la manera exacta com ho vulgueu fer.</p>
- <p xml:lang="ca-valencia">El Dolphin és un gestor de fitxers lleuger. S'ha dissenyat pensant a facilitar el seu ús i que siga simple, permetent la flexibilitat i la personalització. Això vol dir que podeu fer la gestió dels vostres fitxers de la manera exacta com ho vulgueu fer.</p>
- <p xml:lang="da">Dolphin er letvægtsfilhåndtering. Den er blevet designet med henblik på brugervenlighed og simpelhed, mens fleksibilitet og tilpasning stadig er muligt. Det betyder at du klare din filhåndtering nøjagtig på den måde du vil gøre det.</p>
- <p xml:lang="de">Dolphin ist ein schlankes Programm zur Dateiverwaltung. Es wurde mit dem Ziel entwickelt, einfach in der Anwendung, dabei aber auch flexibel und anpassungsfähig zu sein. Sie können daher Ihre Dateiverwaltungsaufgaben genau nach Ihren Bedürfnissen ausführen.</p>
- <p xml:lang="el">Το Dolphin είναι ένας ελαφρύς διαχειριστής αρχείων. Έχει σχεδιαστεί με φιλοσοφία την απλότητα για ευκολία στη χρήση, ενώ επιτρέπει ευελιξία και προσαρμογές. Αυτό σημαίνει ότι μπορείτε να διαχειριστείτε τα αρχεία σας με τον τρόπο που εσείς θέλετε.</p>
- <p xml:lang="en-GB">Dolphin is a lightweight file manager. It has been designed with ease of use and simplicity in mind, while still allowing flexibility and customisation. This means that you can do your file management exactly the way you want to do it.</p>
- <p xml:lang="es">Dolphin es un administrador de archivos ligero. Se ha diseñado teniendo en cuenta la facilidad de uso y la simplicidad, así como la flexibilidad y la personalización. Esto significa que el usuario puede administrar los archivos exactamente de la manera que prefiera.</p>
- <p xml:lang="et">Dolphin on vähest koormust tekitav failihaldur. Selle loomisel on peetud silmas kasutamise hõlpsust ja lihtsust, ometi pakub see suurt paindlikkust ja oma käe järgi kohandamise võimalusi. Sel moel saab faile hallata just, nagu ise soovid.</p>
- <p xml:lang="eu">Dolphin pisu arineko fitxategi-kudeatzaile bat da. Erabilera erraza eta sinpletasuna gogoan diseinatua izan da, ordea, malgutasuna eta norbere nahietara egokitzea onartzen du. Honek esan nahi du fitxategi-kudeatzea zuk nahi duzun eran egin dezakezula.</p>
- <p xml:lang="fi">Dolphin on kevyt tiedostonhallinta. Se on suunniteltu helppokäyttöiseksi ja yksinkertaiseksi, mutta silti joustavaksi ja mukautettavaksi. Voit siis hallita tiedostojasi juuri niin kuin haluat.</p>
- <p xml:lang="fr">Dolphin est un gestionnaire de fichiers léger. Il a été conçu en gardant à l'esprit la simplicité et l'aisance à l'usage, tout en permettant flexibilité et personnalisation. Cela signifie que vous pouvez gérer vos fichiers de la manière exacte que vous voulez.</p>
- <p xml:lang="gl">Dolphin é un xestor de ficheiros lixeiro. Deseñouse pensando na facilidade de uso e a simplicidade, pero permitindo flexibilidade e personalización. Noutras palabras, permítelle xestionar os seus ficheiros do xeito que máis lle agrade.</p>
- <p xml:lang="he">Dolphin הוא מנהל קבצים קליל. הוא עוצב לקלות שימוש ופשטות, תוך כדי אפשור גמישות והתאמה אישית. זה אומר שניתן לנהל את הקבצים שלך כרצונך.</p>
- <p xml:lang="hu">A Dolphin egy pehelysúlyú fájlkezelő. Az egyszerű használatot és az egyszerűséget szem előtt tartva tervezték, miközben továbbra is lehetővé teszi a rugalmasságot és a testre szabhatóságot. Ez azt jelenti, hogy pontosan oly módon végezheti a fájlkezelést, ahogy csak akarja.</p>
- <p xml:lang="ia">Dolphin es un gerente de file legier. Il ha essite designate con facilitate de uso e simplicitate in le mente, mentre il permitte ancora flexibilitate e personalisation. Isto significa que tu pote facer le gerente de file exactemente como tu lo vole.</p>
- <p xml:lang="id">Dolphin adalah pengelola file yang ringan. Ini telah dirancang dengan kemudahan penggunaan dan kesederhanaan dalam hal, sementara masih memungkinkan fleksibilitas dan kustomisasi. Ini berarti kamu bisa melakukan pengelolaan file-mu persis seperti yang kamu inginkan.</p>
- <p xml:lang="it">Dolphin è un gestore file leggero. È stato progettato per essere facile da utilizzare e pensando alla semplicità, garantendo al contempo flessibilità e personalizzazione. Ciò significa che puoi gestire i tuoi file come meglio desideri.</p>
- <p xml:lang="ko">Dolphin은 가벼운 파일 관리자입니다. 사용 편의성과 단순함을 염두에 두고 설계되었으며, 유연성과 사용자 정의를 여전히 허용합니다. 즉, 파일 관리를 원하는 방식으로 정확하게 수행할 수 있습니다.</p>
- <p xml:lang="lt">Dolphin yra supaprastinta failų tvarkytuvė. Ji buvo sukurta taip, kad ją būtų lengva naudoti, susitelkiant į paprastumą, tačiau įgalinant lankstumą ir tinkinimą. Tai reiškia, kad galite tvarkyti failus būtent taip, kaip norite.</p>
- <p xml:lang="ml">ഡോൾഫിൻ ഒരു ഭാരം കുറഞ്ഞ ഫയൽ മാനേജറാണ്. ഇത് നിർമ്മിച്ചിരിക്കുന്നത് ഉപയോഗിക്കുന്നതിനുള്ള എളുപ്പത്തിനും , മാനസികമായിയുള്ള എളുപ്പത്തിനുമാണ്, ഒപ്പം തന്നെ അഭിരുചിക്കനുസൃതമാക്കുന്നതിനും വഴക്കം നൽകുന്നതിനും അനുവദിക്കുന്നു. അതായത് നിങ്ങൾക്ക് നിങ്ങളുടെ ഫയലുകൾ എങ്ങനെയൊക്കെ കൈകാര്യം ചെയ്യണോ അങ്ങനെ കൈകാര്യം ചെയ്യാവുന്നതാണ്.</p>
- <p xml:lang="nb">Dolphin er en lettvekts filbehandler. Den er laget for å være enkel og lett å bruke, samtidig som den er fleksibel og kan tilpasses. Det betyr at du kan utføre dine filbehandlingsoppgaver akkurat slik du vil gjøre det.</p>
- <p xml:lang="nds">Dolphin is en slank Dateipleger. Dat wöör buut mit de Idee vun't eenfache Bedenen vör Ogen, bides dat liekers flexibel un topassbor wesen schull. Du kannst Dien Dateien also jüst so plegen, as Du dat wullt.</p>
- <p xml:lang="nl">Dolphin is een lichtgewicht bestandsbeheerder. Het is ontworpen met gebruiksgemak en eenvoud in gedachte en staat toch flexibiliteit en aan te passen toe. Dit betekent dat u uw bestandsbeheer kunt doen precies op de manier zoals u dat wilt.</p>
- <p xml:lang="nn">Dolphin er ein lettvekts filhandsamar. Han er laga for å vera enkel å bruka, samtidig som han er fleksibel og kan tilpassast, slik at du kan gjera filhandsamingsoppgåvene nett slik du ønskjer.</p>
- <p xml:lang="pl">Dolphin jest lekkim programem do zarządzania plikami. Został on opracowany mając na uwadze łatwość i prostotę obsługi, zapewniając jednocześnie elastyczność i możliwość dostosowania. Oznacza to, że można urządzić zarządzanie plikami w dokładnie taki sposób w jaki jest to pożądane.</p>
- <p xml:lang="pt">O Dolphin é um gestor de ficheiros leve. Foi desenhado com a facilidade de uso e simplicidade em mente, permitindo à mesma a flexibilidade e personalização. Isto significa que poderá fazer a sua gestão de ficheiros exactamente da forma que deseja.</p>
- <p xml:lang="pt-BR">Dolphin é um gerenciador de arquivos leve e fácil de usar. Foi projetado para ser simples e ao mesmo tempo manter a flexibilidade e personalização. Isso significa que você poderá gerenciar seus arquivos da forma que desejar.</p>
- <p xml:lang="ro">Dolphin e un gestionar de fișiere simplu. A fost proiectat cu ușurința la utilizare și simplitatea în minte, în același timp permițând flexibilitate și personalizare. Aceasta înseamnă vă puteți gestiona fișierele exact așa cum vă doriți s-o faceți.</p>
- <p xml:lang="ru">Dolphin — это упрощённый диспетчер файлов. Он создавался как лёгкий в использовании, но в то же время является гибким и расширяемым.</p>
- <p xml:lang="sk">Dolphin je odľahčený správca súborov. Bol navrhnutý na jednoduché použitie a jednoduchosť, ale s možnosťami flexibility a prispôsobenia. To znamená, že môžete vykonávať správu súborov presne tak, ako chcete.</p>
- <p xml:lang="sl">Dolphin je enostaven upravljalnik datotek. Bil je zasnovan kot enostaven in preprost, vseeno pa ostaja prilagodljiv. To pomeni, da lahko upravljanje datotek izvajate točno tako kot želite.</p>
- <p xml:lang="sr">Делфин је лагани менаџер фајлова. Пројектован је да буде лак за употребу и једноставан, а да ипак омогућава флексибилност и прилагођавање. То значи да ће моћи да баратате фајловима тачно онако како бисте желели.</p>
- <p xml:lang="sr-Latn">Dolphin je lagani menadžer fajlova. Projektovan je da bude lak za upotrebu i jednostavan, a da ipak omogućava fleksibilnost i prilagođavanje. To znači da će moći da baratate fajlovima tačno onako kako biste želeli.</p>
- <p xml:lang="sr-ijekavian">Делфин је лагани менаџер фајлова. Пројектован је да буде лак за употребу и једноставан, а да ипак омогућава флексибилност и прилагођавање. То значи да ће моћи да баратате фајловима тачно онако како бисте желели.</p>
- <p xml:lang="sr-ijekavianlatin">Dolphin je lagani menadžer fajlova. Projektovan je da bude lak za upotrebu i jednostavan, a da ipak omogućava fleksibilnost i prilagođavanje. To znači da će moći da baratate fajlovima tačno onako kako biste želeli.</p>
- <p xml:lang="sv">Dolphin är en lättviktig filhanterare. Den har konstruerats med användbarhet och enkelhet i åtanke, men ändå tillåta flexibilitet och anpassning. Det betyder att du kan hantera filer exakt på det sätt som du vill göra det.</p>
- <p xml:lang="tr">Dolphin hafif bir dosya yöneticisidir. Kolay kullanım ve basitliğin yanı sıra esneklik ve özelleştirilebilme de akılda tutularak geliştirilmiştir. Bu da dosya yöneticisini tam da istediğiniz gibi kullanabileceğiniz anlamına gelir.</p>
- <p xml:lang="uk">Dolphin — невибаглива до ресурсів програма для керування файлами. Її створено простою у користуванні і гнучкою у налаштовуванні. Це означає, що ви можете зробити керування файлами саме таким, як вам потрібно.</p>
- <p xml:lang="vi">Dolphin là một trình quản lí tệp nhẹ. Nó được thiết kế với lưu ý đến tính dễ dùng và sự đơn giản, đồng thời vẫn cho phép tính linh hoạt và sự tuỳ biến. Điều này nghĩa là bạn có thể quản lí tệp theo đúng cách bạn muốn.</p>
- <p xml:lang="x-test">xxDolphin is a lightweight file manager. It has been designed with ease of use and simplicity in mind, while still allowing flexibility and customisation. This means that you can do your file management exactly the way you want to do it.xx</p>
- <p xml:lang="zh-CN">Dolphin 是一个轻量的文件管理器。它设计时考虑了简单易用,但仍然保持了灵活性和定制性。这意味着您可以用完全属于您的方式来管理文件。</p>
- <p xml:lang="zh-TW">Dolphin 是一套輕量級的檔案管理員。它設計的理念是易用與簡單,但仍然保持足夠的彈性。這表示您可以用您想要使用的方式來管理您的檔案。</p>
- <p>Features:</p>
- <p xml:lang="ar">المزايا:</p>
- <p xml:lang="ast">Carauterístiques:</p>
- <p xml:lang="az">Xüsusiyyətləri:</p>
- <p xml:lang="bs">Svojstva:</p>
- <p xml:lang="ca">Característiques:</p>
- <p xml:lang="ca-valencia">Característiques:</p>
- <p xml:lang="cs">Vlastnosti:</p>
- <p xml:lang="da">Funktioner:</p>
- <p xml:lang="de">Funktionen:</p>
- <p xml:lang="el">Χαρακτηριστικά:</p>
- <p xml:lang="en-GB">Features:</p>
- <p xml:lang="es">Características:</p>
- <p xml:lang="et">Omadused:</p>
- <p xml:lang="eu">Eginbideak:</p>
- <p xml:lang="fi">Ominaisuudet:</p>
- <p xml:lang="fr">Fonctionnalités :</p>
- <p xml:lang="gl">Funcionalidades:</p>
- <p xml:lang="he">תכונות:</p>
- <p xml:lang="hu">Szolgáltatások:</p>
- <p xml:lang="ia">Characteristicas:</p>
- <p xml:lang="id">Fitur:</p>
- <p xml:lang="it">Funzionalità:</p>
- <p xml:lang="ko">기능:</p>
- <p xml:lang="lt">Ypatybės:</p>
- <p xml:lang="ml">വിശേഷതകൾ:</p>
- <p xml:lang="nb">Egenskaper:</p>
- <p xml:lang="nds">Markmalen:</p>
- <p xml:lang="nl">Mogelijkheden:</p>
- <p xml:lang="nn">Funksjonar:</p>
- <p xml:lang="pa">ਲੱਛਣ:</p>
- <p xml:lang="pl">Możliwości:</p>
- <p xml:lang="pt">Funcionalidades:</p>
- <p xml:lang="pt-BR">Funcionalidades:</p>
- <p xml:lang="ro">Caracteristici:</p>
- <p xml:lang="ru">Возможности:</p>
- <p xml:lang="sk">Funkcie:</p>
- <p xml:lang="sl">Zmožnosti:</p>
- <p xml:lang="sr">Могућности:</p>
- <p xml:lang="sr-Latn">Mogućnosti:</p>
- <p xml:lang="sr-ijekavian">Могућности:</p>
- <p xml:lang="sr-ijekavianlatin">Mogućnosti:</p>
- <p xml:lang="sv">Funktioner:</p>
- <p xml:lang="tr">Özellikler:</p>
- <p xml:lang="uk">Можливості:</p>
- <p xml:lang="vi">Tính năng:</p>
- <p xml:lang="x-test">xxFeatures:xx</p>
- <p xml:lang="zh-CN">功能:</p>
- <p xml:lang="zh-TW">功能:</p>
- <ul>
- <li>Navigation (or breadcrumb) bar for URLs, allowing you to quickly navigate through the hierarchy of files and folders.</li>
- <li xml:lang="az">Ünvan sətri qovluqlar üzrə cəld hərəkət etməyə imkan verir.</li>
- <li xml:lang="bs">Navigacijska (ili mrvična) traka za URL, dopušta vam da se brzo krećete kroz hijerarhiju datoteka i direktorija.</li>
- <li xml:lang="ca">Barra de navegació (o fil d'Ariadna) pels URL, permetent una navegació ràpida per la jerarquia dels fitxers i carpetes.</li>
- <li xml:lang="ca-valencia">Barra de navegació (o fil d'Ariadna) pels URL, permetent una navegació ràpida per la jerarquia dels fitxers i carpetes.</li>
- <li xml:lang="da">Navigationsbjælke (eller brødkrumme-bjælke) til URL'er, lader dig navigere hurtigt igennem hierarkiet af filer og mapper.</li>
- <li xml:lang="de">Navigationsleiste für Adressen (auch editierbar), mit der Sie schnell durch die Hierarchie der Dateien und Ordner navigieren können.</li>
- <li xml:lang="el">Η γραμμή πλοήγησης (ή ιχνηλάτησης) για URL, σας επιτρέπει να πλοηγηθείτε γρήγορα μέσα από την ιεραρχία αρχείων και φακέλων.</li>
- <li xml:lang="en-GB">Navigation (or breadcrumb) bar for URLs, allowing you to quickly navigate through the hierarchy of files and folders.</li>
- <li xml:lang="es">barra de navegación (o de ruta completa) para URL que permite navegar rápidamente a través de la jerarquía de archivos y carpetas.</li>
- <li xml:lang="et">Liikumisriba URL-idele, mis lubab kiiresti liigelda failide ja kataloogide hierarhias.</li>
- <li xml:lang="eu">Nabigatzeko (edo ogi-apurren) barra URLentzako, fitxategi eta karpeten hierarkian zehar azkar nabigatzeko aukera ematen dizuna.</li>
- <li xml:lang="fi">Osoiterivi, jonka avulla siirtyminen tiedostojen ja kansioiden hierarkiassa on nopeaa.</li>
- <li xml:lang="fr">Barre de navigation (ou fil d'Ariane) permettant de naviguer rapidement dans la hiérarchie de fichiers et de dossiers.</li>
- <li xml:lang="gl">Barra de navegación (ou ronsel) para enderezos URL, que lle permite navegar rapidamente pola xerarquía de ficheiros e cartafoles.</li>
- <li xml:lang="hu">Navigációs (vagy webmorzsa) sáv az URL-ekhez, amely lehetővé teszi a fájlok és mappák hierarchiáján keresztüli gyors navigációt.</li>
- <li xml:lang="ia">Barra de navigation (o "breadcrumb") pro URLs, que il permitte te navigar rapidemente a transverso del hierarchia de files e dossieres.</li>
- <li xml:lang="id">Bilah navigasi (atau breadcrumb) untuk URL-URL, memungkinkan kamu secara cepat bernavigasi melalui hirerarki file-file dan folder-folder.</li>
- <li xml:lang="it">La barra di navigazione per gli URL, che ti consente di navigare rapidamente attraverso la struttura di file e cartelle.</li>
- <li xml:lang="ko">URL에 대한 탐색(또는 이동 경로) 표시줄을 사용하면 파일 및 폴더의 계층 구조를 빠르게 탐색할 수 있습니다.</li>
- <li xml:lang="lt">Naršymo (arba trupinių) juosta, skirta URL adresams, leidžianti greitai naršyti per failų ar aplankų hierarchiją.</li>
- <li xml:lang="ml">ഫയലുകളുടെയും അറകളുടെയും ശ്രേണി കണ്ടുപിടിക്കുന്നതിന് URL കൾക്ക് നാവിഗേഷൻ (അല്ലെങ്കിൽ വഴി കാട്ടുന്നതിനുള്ള) സ്ഥലം.</li>
- <li xml:lang="nb">Navigasjonslinje (brødsmulelinje) for URL-er slik at du raskt kan navigere gjennom hierarkiet av filer og mapper.</li>
- <li xml:lang="nds">Steed- (oder Krömelspoor-)Balken för URLs, mit de Du Di fix dör de Hierarchie ut Dateien un Ornern bewegen kannst</li>
- <li xml:lang="nl">Navigatie- (of broodkruimel)balk voor URL's, waarmee u snel kunt navigeren door de hiërarchie van bestanden en mappen.</li>
- <li xml:lang="nn">Navigasjonslinje (brødsmulelinje), slik at du raskt kan navigera gjennom hierarkiet av filer og mapper.</li>
- <li xml:lang="pl">Pasek nawigacji (lub okruchy chleba) dla adresów URL, umożliwiające szybkie przechodzenie w hierarchii plików i katalogów.</li>
- <li xml:lang="pt">Barra de navegação dos URL's, que lhe permite navegar rapidamente pela hierarquia de ficheiros e pastas.</li>
- <li xml:lang="pt-BR">Barra de navegação de URLs, permitindo-lhe navegar rapidamente pela hierarquia de arquivos e pastas.</li>
- <li xml:lang="ro">Bară de navigare (sau firimituri) pentru URL-uri, ceea ce vă permite să navigați rapid prin ierarhia de fișiere și dosare.</li>
- <li xml:lang="ru">Адресная строка позволяет быстро перемещаться по дереву папок;</li>
- <li xml:lang="sk">Navigačná lišta pre URL, umožňujúca vám rýchlu navigáciu cez hierarchiu súborov a priečinkov.</li>
- <li xml:lang="sl">Vrstica za krmarjenje po naslovih URL, ki omogoča hitro krmarjenje po hierarhiji datotek in map.</li>
- <li xml:lang="sr">Навигациона трака (или мрвице) за УРЛ‑ове, преко које се можете брзо кретати кроз стабло фајлова и фасцикли.</li>
- <li xml:lang="sr-Latn">Navigaciona traka (ili mrvice) za URL‑ove, preko koje se možete brzo kretati kroz stablo fajlova i fascikli.</li>
- <li xml:lang="sr-ijekavian">Навигациона трака (или мрвице) за УРЛ‑ове, преко које се можете брзо кретати кроз стабло фајлова и фасцикли.</li>
- <li xml:lang="sr-ijekavianlatin">Navigaciona traka (ili mrvice) za URL‑ove, preko koje se možete brzo kretati kroz stablo fajlova i fascikli.</li>
- <li xml:lang="sv">Navigeringsrad (eller länkstig) för webbadresser, som låter dig snabbt navigera igenom hierarkin av filer och kataloger.</li>
- <li xml:lang="tr">Dosya ve dizinlerin sıralı dizilerinde hızlıca gezinmenize imkan veren adresler için gezinti (veya işaret) çubuğu.</li>
- <li xml:lang="uk">Панель навігації (звичайний режим і режим послідовної навігації) для адрес надає вам змогу швидко пересуватися ієрархією файлів та каталогів.</li>
- <li xml:lang="vi">Thanh điều hướng (hay "vụn bánh") cho URL, cho phép bạn điều hướng nhanh chóng qua hệ thống cây tệp và thư mục.</li>
- <li xml:lang="x-test">xxNavigation (or breadcrumb) bar for URLs, allowing you to quickly navigate through the hierarchy of files and folders.xx</li>
- <li xml:lang="zh-CN">URL 的导航栏(面包屑导航),允许您快速地在文件和文件夹的层次结构间跳转。</li>
- <li xml:lang="zh-TW">網址導覽列讓您可以快速瀏覽檔案與資料夾。</li>
- <li>Supports several different kinds of view styles and properties and allows you to configure the view exactly how you want it.</li>
- <li xml:lang="ar">يدعم العديد من الأنواع المختلفة من الخصائص وأنماط العرض ويسمح لك بضبط العرض كما تريد تمامًا.</li>
- <li xml:lang="ast">Sofita estilos y propiedaes de vista diferentes, y permítete configurar la vista exautamente como quieras.</li>
- <li xml:lang="az">Bir neçə fərqli görünüş tərzi və xüsusiyyətlərini dəstəkləyir və görünüşü tam olaraq istədiyiniz kimi tənzimləməyə imkan verir.</li>
- <li xml:lang="bs">Dopušta vište vrsta stilova pogleda i svojstava i dopšta vam da konfigurišete pogled baš kako želite.</li>
- <li xml:lang="ca">Accepta diferents classes diverses d'estils de visualització i propietats i us permet configurar la visualització exactament com la vulgueu.</li>
- <li xml:lang="ca-valencia">Accepta diferents classes diverses d'estils de visualització i propietats i vos permet configurar la visualització exactament com la vulgueu.</li>
- <li xml:lang="da">Understøtter flere forskellige slags visninger og egenskaber og lader dig konfigurere visningen nøjagtig som du vil have den.</li>
- <li xml:lang="de">Unterstützt mehrere unterschiedliche Arten von Ansichtsstilen und Eigenschaften und erlaubt es Ihnen, die Ansichten genau nach Ihren Bedürfnissen einzustellen.</li>
- <li xml:lang="el">Υποστηρίζει πολλά διαφορετικά είδη στιλ και ιδιότητες επισκόπησης και σας επιτρέπει να διαμορφώσετε την επισκόπηση ακριβώς όπως τη θέλετε.</li>
- <li xml:lang="en-GB">Supports several different kinds of view styles and properties and allows you to configure the view exactly how you want it.</li>
- <li xml:lang="es">Admite varios tipos diferentes de estilos de vista y propiedades y permite configurar la vista exactamente como prefiera el usuario.</li>
- <li xml:lang="et">Võimalus kasutada mitut laadi vaatestiile ja -omadusi ning neid igati enda käe järgi seadistada.</li>
- <li xml:lang="eu">Hainbat mota desberdineko ikuspegi estilo eta propietate onartzen ditu eta ikuspegia zehazki zuk nahi duzun gisan konfiguratzeko aukera ematen dizu. </li>
- <li xml:lang="fi">Tukee useita erilaisia näkymätyylejä ja -ominaisuuksia, ja mahdollistaa näkymän muokkaamisen mieleisekseen.</li>
- <li xml:lang="fr">Prend en charge plusieurs types de styles d'affichage et de propriété et vous permet de configurer l'affichage de la manière exacte que vous voulez.</li>
- <li xml:lang="gl">É compatíbel con varios estilos e propiedades de vista distintos, e permítelle configurar a vista como mellor lle pareza.</li>
- <li xml:lang="hu">Számos különféle nézetstílus fajtát és tulajdonságot támogat, valamint lehetővé teszi a nézet beállítását pontosan olyanra, ahogy azt látni szeretné.</li>
- <li xml:lang="ia">Il supporta multe differente typos de stilos de vista e proprietates e il permitte te configurar le vista exactemente como tu vole.</li>
- <li xml:lang="id">Mendukung beberapa jenis gaya tampilan dan properti yang berbeda dan memungkinkanmu untuk mengonfigurasi tampilan persis seperti yang kamu inginkan.</li>
- <li xml:lang="it">Supporta diversi stili di visualizzazione e proprietà e ti consente di configurare la vista come desideri.</li>
- <li xml:lang="ko">여러 종류의 보기 스타일 및 속성을 지원하며 원하는 방식으로 보기를 구성할 수 있습니다.</li>
- <li xml:lang="lt">Palaiko kelias įvairias stilių ir savybių rūšis ir leidžia konfigūruoti rodinį būtent taip, kaip norite.</li>
- <li xml:lang="ml">നിങ്ങൾക്ക് ഇഷ്ടമുള്ള രീതിയിൽ കാണുന്നതിന് ആവശ്യമായിട്ടുള്ള വിവിധ അലങ്കാര രീതികള്ക്ക് പിന്തുണ നൽകുന്നു.</li>
- <li xml:lang="nb">Støtter flere forskjellige visningsstiler og kan sette opp visningen akkurat slik du vil ha den.</li>
- <li xml:lang="nds">Ünnerstütt en Reeg verscheden Ansichtstilen un -egenschappen un lett Di de Ansicht jüst so topassen, as Du dat bruukst.</li>
- <li xml:lang="nl">Ondersteunt een aantal verschillende soorten stijlen van weergave en eigenschappen en biedt u de mogelijkheid de weergave in te stellen precies zoals u dat wilt.</li>
- <li xml:lang="nn">Støttar fleire ulike visingsstilar, og du kan setja opp visinga nett slik du vil ha ho.</li>
- <li xml:lang="pl">Obsługa wielu różnych rodzajów stylów widoków i właściwości oraz możliwość ustawienia widoku dopasowanego do potrzeb.</li>
- <li xml:lang="pt">Suposta diferentes tipos de vistas e propriedades e permite-lhe configurar cada vista exactamente como a deseja.</li>
- <li xml:lang="pt-BR">Suporte a diferentes tipos de visualização, permitindo-lhe configurar cada modo de exibição da forma que desejar.</li>
- <li xml:lang="ro">Susține câteva feluri de stiluri și proprietăți de vizualizare, ceea ce vă permite să configurați vizualizarea exact așa cum vă doriți.</li>
- <li xml:lang="ru">Несколько различных визуальных представлений папок, каждое из которых можно настроить по своему вкусу;</li>
- <li xml:lang="sk">Podporuje niekoľko rôznych typov štýlov zobrazenia a vlastností a umožňuje vám nastaviť pohľad presne tak, ako chcete.</li>
- <li xml:lang="sl">Podpira številne vrste slogov in lastnosti pogledov ter omogoča, da pogled nastavite točno tako kot vam ustreza.</li>
- <li xml:lang="sr">Неколико начина приказа, са својствима које можете подесити по жељи.</li>
- <li xml:lang="sr-Latn">Nekoliko načina prikaza, sa svojstvima koje možete podesiti po želji.</li>
- <li xml:lang="sr-ijekavian">Неколико начина приказа, са својствима које можете подесити по жељи.</li>
- <li xml:lang="sr-ijekavianlatin">Nekoliko načina prikaza, sa svojstvima koje možete podesiti po želji.</li>
- <li xml:lang="sv">Stöder flera olika sorters visningsstilar och egenskaper och låter dig anpassa visningen exakt som du vill ha den.</li>
- <li xml:lang="tr">Bir çok farklı görünüm tipini ve özelliğini destekler ve görünümü tam istediğiniz gibi yapılandırmanıza izin verir.</li>
- <li xml:lang="uk">Підтримка декількох різних типів та параметрів перегляду надає вам змогу налаштувати перегляд каталогів саме так, як вам це потрібно.</li>
- <li xml:lang="vi">Hỗ trợ nhiều loại kiểu cách và thuộc tính xem khác nhau, và cho phép bạn cấu hình khung xem đúng với cách bạn muốn.</li>
- <li xml:lang="x-test">xxSupports several different kinds of view styles and properties and allows you to configure the view exactly how you want it.xx</li>
- <li xml:lang="zh-CN">支持多种不同的视图风格和属性并且允许您用您想要的方式配置视图。</li>
- <li xml:lang="zh-TW">網址導覽列讓您可以快速瀏覽檔案與資料夾。</li>
- <li>Split view, allowing you to easily copy or move files between locations.</li>
- <li xml:lang="ar">العرض المقسوم، يسمح لك بنسخ ونقل الملفات بين مكانين بسهولة.</li>
- <li xml:lang="ast">La vista dixebrada permítete copiar o mover ficheros de mou fácil ente allugamientos.</li>
- <li xml:lang="az">İkipanelli rejimdə faylları müxtəlif qovluqlar arasında cəld kopyalamq və köçürmək daha rahatdır.</li>
- <li xml:lang="bs">Razdvaja pogled, dopuštajući lako kopiranje ili pomijeranje datoteka između lokacija</li>
- <li xml:lang="ca">Divisió de visualització, permetent copiar o moure fitxers fàcilment entre les ubicacions.</li>
- <li xml:lang="ca-valencia">Divisió de visualització, permetent copiar o moure fitxers fàcilment entre les ubicacions.</li>
- <li xml:lang="da">Opdelt visning lader dig kopiere filer mellem placeringer på en nem måde.</li>
- <li xml:lang="de">Geteilte Ansichten, damit können Sie einfach Daten zwischen Orten kopieren oder verschieben.</li>
- <li xml:lang="el">Η διαίρεση επισκόπησης, σάς επιτρέπει με ευκολία να αντιγράφετε ή να μετακινείτε αρχεία μεταξύ διαφορετικών θέσεων.</li>
- <li xml:lang="en-GB">Split view, allowing you to easily copy or move files between locations.</li>
- <li xml:lang="es">Dividir vista, para poder copiar o mover archivos fácilmente entre distintas ubicaciones.</li>
- <li xml:lang="et">Vaate poolitamise võimalus, mis muudab väga lihtsaks failide ühest kohast teise kopeerimise või liigutamise.</li>
- <li xml:lang="eu">Ikuspegi zatitua, fitxategiak kokapen batetik bestera erraz kopiatu edo mugitzeko.</li>
- <li xml:lang="fi">Näkymän puolitus, joka helpottaa tiedostojen kopiointia ja siirtämistä paikasta toiseen.</li>
- <li xml:lang="fr">Affichage divisé, permettant de facilement copier ou déplacer des fichiers dans les différents emplacements.</li>
- <li xml:lang="gl">Vista dividida, que lle permite copiar ou mover ficheiros facilmente entre dous lugares.</li>
- <li xml:lang="hu">Osztott nézet, amely lehetővé teszi a fájlok könnyű másolását és áthelyezését a helyek között.</li>
- <li xml:lang="ia">Scinde vista, il permitte te copiar o mover facilemente files inter locationes.</li>
- <li xml:lang="id">Tampilan belah, memungkinkanmu untuk menyalin atau memindah file antar lokasi dengan mudah.</li>
- <li xml:lang="it">La vista divisa, che ti consente di copiare o spostare i file tra le diverse posizioni in maniera semplice.</li>
- <li xml:lang="ko">분할 보기를 통해 위치간에 파일을 쉽게 복사하거나 이동할 수 있습니다.</li>
- <li xml:lang="lt">Padalytas rodinys, leidžiantis lengvai kopijuoti ar perkelti failus tarp įvairių vietų.</li>
- <li xml:lang="ml">എളുപ്പത്തിൽ ഫയലുകൾ പകർത്തുന്നതിനും നീക്കുന്നതിനും സഹായിക്കുന്ന വേർതിരിച്ച കാഴ്ച</li>
- <li xml:lang="nb">Delt visning, så du lett kan kopiere eller flytte filer mellom steder.</li>
- <li xml:lang="nds">Deelt Ansicht, mit De Du Dateien eenfach twischen Steden koperen oder bewegen kannst.</li>
- <li xml:lang="nl">Gesplitst beeld, waarmee u gemakkelijk bestanden kunt kopiëren of verplaatsen tussen locaties.</li>
- <li xml:lang="nn">Delt vising, så du lett kan kopiera eller flytta filer mellom mapper.</li>
- <li xml:lang="pl">Widok podzielony, umożliwiający łatwe kopiowane lub przenoszenie plików pomiędzy położeniami.</li>
- <li xml:lang="pt">Uma vista dividida, que lhe permite facilmente copiar ou mover os ficheiros entre locais.</li>
- <li xml:lang="pt-BR">Um modo de exibição dividido, permitindo-lhe copiar ou mover arquivos facilmente entre locais.</li>
- <li xml:lang="ro">Desparte vizualizarea, ceea ce vă permite să copiați sau mutați ușor fișiere între amplasări.</li>
- <li xml:lang="ru">Двухпанельный режим, в котором удобно копировать и перемещать файлы между разными папками;</li>
- <li xml:lang="sk">Rozdelený pohľad, umožňuje vám jednoducho kopírovať alebo presúvať súbory medzi umiestneniami.</li>
- <li xml:lang="sl">Razdeljeni pogled vam omogoča enostavno kopiranje ali premikanje datotek med mesti.</li>
- <li xml:lang="sr">Подељени приказ, за лако копирање и премештање фајлова између локација.</li>
- <li xml:lang="sr-Latn">Podeljeni prikaz, za lako kopiranje i premeštanje fajlova između lokacija.</li>
- <li xml:lang="sr-ijekavian">Подељени приказ, за лако копирање и премештање фајлова између локација.</li>
- <li xml:lang="sr-ijekavianlatin">Podeljeni prikaz, za lako kopiranje i premeštanje fajlova između lokacija.</li>
- <li xml:lang="sv">Delad visning, som låter dig enkelt kopiera eller flytta filer mellan platser.</li>
- <li xml:lang="tr">Dosyaları farklı konumlar arasında kolayca kopyalamaya ve taşımaya izin veren ayrık görünüm.</li>
- <li xml:lang="uk">За допомогою режиму двопанельного розділеного перегляду ви зможе без проблем копіювати або пересувати файли між каталогами.</li>
- <li xml:lang="vi">Khung xem chia đôi, cho phép bạn dễ dàng chép hay di chuyển tệp giữa các địa điểm.</li>
- <li xml:lang="x-test">xxSplit view, allowing you to easily copy or move files between locations.xx</li>
- <li xml:lang="zh-CN">拆分视图,让您可以方便地在不同位置间复制和移动文件。</li>
- <li xml:lang="zh-TW">支援數個檢視模式,您也可以調整檢視模式的屬性。</li>
- <li>Additional information and shortcuts are available as dock-able panels, allowing you to move them around freely and display exactly what you want.</li>
- <li xml:lang="ar">تتوفر معلومات واختصارات إضافية كلوحات قابلة للرصف، مما يسمح لك بنقلها بحريّة وعرضها بالضبط كما تريد.</li>
- <li xml:lang="ast">La información adicional y los atayos tán disponibles como paneles anclables que pues mover ande quieras y amosar como exautamente quieras.</li>
- <li xml:lang="az">Əlavə məlumatlar və yarlıqlar yeri dəyişdirilə bilən panellər kimidir və bu sizə onları istədiyiniz yerə daşımağa və görünüşünü istədiyiniz kimi dəyişməyə imkan verir.</li>
- <li xml:lang="bs">Dodatne informacije i kratice su dostupne kao usidreni paneli, dopuštajući vam da se krećete slobodno i prikažete šta želite.</li>
- <li xml:lang="ca">Hi ha informació addicional i dreceres disponibles com a plafons que es poden acoblar, permetent moure'ls lliurement i mostrar exactament el què vulgueu.</li>
- <li xml:lang="ca-valencia">Hi ha informació addicional i dreceres disponibles com a plafons que es poden acoblar, permetent moure'ls lliurement i mostrar exactament el què vulgueu.</li>
- <li xml:lang="da">Yderligere information og genveje er tilgængelige som dokbare paneler, som lader dig flytte dem frit omkring og vise nøjagtigt det du vil have.</li>
- <li xml:lang="de">Zusätzliche Informationen und Kurzbefehle sind als andockbare Seitenleisten vorhanden, diese Leisten können Sie beliebig verschieben und in ihnen die gewünschten Informationen anzeigen lassen.</li>
- <li xml:lang="el">Πρόσθετες πληροφορίες και συντομεύσεις είναι διαθέσιμα ως προσαρτήσιμοι πίνακες, που σας επιτρέπουν να τα μετακινείτε ελεύθερα και να παρουσιάζετε ακριβώς αυτό που θέλετε.</li>
- <li xml:lang="en-GB">Additional information and shortcuts are available as dock-able panels, allowing you to move them around freely and display exactly what you want.</li>
- <li xml:lang="es">Hay disponible información adicional y accesos rápidos en forma de paneles separables para que se puedan mover libremente a la vez que muestran exactamente lo que prefiera el usuario.</li>
- <li xml:lang="et">Lisateave ja otseteed dokitavate paneelidena, mida saab vabalt vajalikku kohta tõsta ja panna näitama just vajalikku teavet.</li>
- <li xml:lang="eu">Informazio eta lasterbide osagarriak erabilgarri daude panel ainguragarrien bidez, haiek askatasun osoz mugitu ditzakezu eta zehazki nahi duzuna bistaratu.</li>
- <li xml:lang="fi">Lisätiedoille ja oikoteille on paneelit, joita voi siirtää sekä näyttää ja piilottaa vapaasti.</li>
- <li xml:lang="fr">Des informations supplémentaires et des raccourcis sont disponibles comme des panneaux ancrables, librement déplaçable et affichant exactement ce que vous voulez.</li>
- <li xml:lang="gl">Información adicional e atallos dispoñíbeis como paneis acoplábeis que pode colocar en calquera parte e mostrar como prefira.</li>
- <li xml:lang="hu">További információk és gyorsbillentyűk érhetők el dokkolható panelekként, lehetővé téve azok szabad mozgatását, illetve pontosan úgy megjelenítve, ahogy szeretné.</li>
- <li xml:lang="ia">Information additional e vias breve es disponibile como pannellos de basin (dock-panels), il permitte mover los liberemente e monstrar los exactemente como tu vole.</li>
- <li xml:lang="id">Informasi tambahan dan pintasan tersedia sebagai panel yang bisa di-dock, memungkinkanmu untuk memindahkannya secara bebas dan menampilkan apa yang kamu inginkan.</li>
- <li xml:lang="it">Informazioni aggiuntive e scorciatoie sono disponibili come pannelli agganciabili, che possono essere spostati liberamente e visualizzare esattamente ciò che desideri.</li>
- <li xml:lang="ko">추가 정보 및 바로 가기는 도킹 가능한 패널로 제공되므로 자유롭게 이동할 수 있고 원하는 대로 정확히 표시할 수 있습니다.</li>
- <li xml:lang="lt">Papildoma informacija ir šaukiniai yra prieinami kaip pritvirtinami skydeliai, leidžiantys juos laisvai perkelinėti ir atvaizduoti būtent tai, ką norite.</li>
- <li xml:lang="ml">നിങ്ങൾക്ക് ആവശ്യമായിട്ടുള്ള കുറുക്കുവഴികളും വിവരങ്ങളും എളുപ്പത്തിൽ തുറക്കാവുന്ന ഭാഗങ്ങളായി ലഭ്യമാണ്.</li>
- <li xml:lang="nb">Mer informasjon og snarveier er tilgjengelige som dokkbare ruter, som du kan flytte fritt rundt og bruke til å vise akkurat hva du vil.</li>
- <li xml:lang="nds">Bito-Infos un Leestekens laat sik as Paneels andocken, Du kannst ehr verschuven un se jüst dat wiesen laten, wat Du weten wullt.</li>
- <li xml:lang="nl">Extra informatie en sneltoetsen zijn beschikbaar als vast te zetten panelen, die u vrij kunt verplaatsen en precies kunt tonen wat u wilt.</li>
- <li xml:lang="nn">Tilleggsinformasjon og snarvegar er tilgjengelege som dokkpanel, som du kan flytta fritt rundt og bruka til å visa det du ønskjer.</li>
- <li xml:lang="pl">Dodatkowe szczegóły i skróty dostępne jako dokowalne panele, umożliwiające ich dowolne przenoszenie i wyświetlanie dopasowane do potrzeb.</li>
- <li xml:lang="pt">Estão disponíveis informações e atalhos adicionais como painéis acopláveis, permitindo-lhe movê-los à vontade e apresentar como desejar.</li>
- <li xml:lang="pt-BR">As informações e atalhos adicionais estão disponíveis na forma de painéis acopláveis, permitindo-lhe movê-los à vontade e apresentar como desejar.</li>
- <li xml:lang="ro">Informații suplimentare și scurtături sunt disponibile ca panouri andocabile, ceea ce vă permite să le mutați liber și să afișați exact ceea ce doriți.</li>
- <li xml:lang="ru">Дополнительные сведения об элементах и ярлыки быстрого доступа в виде отдельных перемещаемых панелей;</li>
- <li xml:lang="sk">Dodatočné informácie a skratky sú dostupné ako dokovateľné panely, umožňujúce vám ich voľný presun a zobrazenie presne tak, ako chcete.</li>
- <li xml:lang="sl">Dodatne podrobnosti in bližnjice lahko vklopite kot sidrne pulte, ki jih lahko poljubno premikate in prikazujete.</li>
- <li xml:lang="sr">Допунски подаци и пречице доступни су као усидриви панели, које можете поставити где вам одговара и подесити да приказују тачно оно што желите.</li>
- <li xml:lang="sr-Latn">Dopunski podaci i prečice dostupni su kao usidrivi paneli, koje možete postaviti gde vam odgovara i podesiti da prikazuju tačno ono što želite.</li>
- <li xml:lang="sr-ijekavian">Допунски подаци и пречице доступни су као усидриви панели, које можете поставити где вам одговара и подесити да приказују тачно оно што желите.</li>
- <li xml:lang="sr-ijekavianlatin">Dopunski podaci i prečice dostupni su kao usidrivi paneli, koje možete postaviti gde vam odgovara i podesiti da prikazuju tačno ono što želite.</li>
- <li xml:lang="sv">Ytterligare information och genvägar är tillgängliga som dockningsbara paneler, vilket låter dig flytta omkring dem fritt och visa exakt vad du vill.</li>
- <li xml:lang="tr">Ek bilgi ve kısayollar kilitlenebilen panolar olarak kullanılabilirler, bu sayede onları istediğiniz gibi taşıyabilir ve tam istediğiniz gibi görüntülenmelerini sağlayabilirsiniz.</li>
- <li xml:lang="uk">За допомогою бічних пересувних панелей ви зможете отримувати додаткову інформацію та пересуватися каталогами. Ви можете розташувати ці панелі так, як вам це зручно, і наказати програмі показувати на них саме те, що вам потрібно.</li>
- <li xml:lang="vi">Thông tin bổ sung và các lối tắt hiện có dưới dạng các bảng lắp ghép được, cho phép bạn di chuyển chúng khắp nơi một cách tự do và hiển thị đúng những gì bạn muốn.</li>
- <li xml:lang="x-test">xxAdditional information and shortcuts are available as dock-able panels, allowing you to move them around freely and display exactly what you want.xx</li>
- <li xml:lang="zh-CN">额外信息,快捷键,可停靠面板,允许您自由地移动它们并且完全按照您想要的方式来显示。</li>
- <li xml:lang="zh-TW">分割檢視讓您可以輕鬆複製或移動檔案。</li>
- <li>Multiple tab support</li>
- <li xml:lang="ar">دعم تعدّد الألسنة</li>
- <li xml:lang="ast">Sofitu pa munches llingüetes</li>
- <li xml:lang="az">Birdən çox vərəqi dəstəkləyir</li>
- <li xml:lang="bs">Podrška za više kartica</li>
- <li xml:lang="ca">Admet pestanyes múltiples</li>
- <li xml:lang="ca-valencia">Admet pestanyes múltiples</li>
- <li xml:lang="cs">Podpora vícero karet</li>
- <li xml:lang="da">Understøttelse af flere faneblade</li>
- <li xml:lang="de">Unterstützung für Unterfenster</li>
- <li xml:lang="el">Υποστήριξη πολλαπλών καρτελών</li>
- <li xml:lang="en-GB">Multiple tab support</li>
- <li xml:lang="es">Admite varias pestañas</li>
- <li xml:lang="et">Mitme kaardi kasutamise toetus.</li>
- <li xml:lang="eu">Fitxen erabilera onartzen du</li>
- <li xml:lang="fi">Useiden välilehtien tuki</li>
- <li xml:lang="fr">Prise en charge des onglets multiples</li>
- <li xml:lang="gl">Permite abrir varios separadores</li>
- <li xml:lang="he">תמיכה בלשוניות מרובות</li>
- <li xml:lang="hu">Több lap támogatása</li>
- <li xml:lang="ia">Supporto de scheda multiple</li>
- <li xml:lang="id">Dukungan multipel tab</li>
- <li xml:lang="it">Supporto di schede multiple</li>
- <li xml:lang="ko">다중 탭 지원</li>
- <li xml:lang="lt">Daugelio kortelių palaikymas</li>
- <li xml:lang="ml">അനേക ടാബുകളുടെ പിൻതുണ</li>
- <li xml:lang="nb">Støtte for flere faner</li>
- <li xml:lang="nds">Ünnerstütten för Paneels</li>
- <li xml:lang="nl">Ondersteuning voor meerdere tabbladen</li>
- <li xml:lang="nn">Støtte for fleire faner</li>
- <li xml:lang="pa">ਬਹੁ ਟੈਬ ਸਹਿਯੋਗ</li>
- <li xml:lang="pl">Obsługa wielu kart</li>
- <li xml:lang="pt">Suporte para várias páginas</li>
- <li xml:lang="pt-BR">Suporte a várias abas</li>
- <li xml:lang="ro">Suport pentru file multiple</li>
- <li xml:lang="ru">Поддержка нескольких вкладок;</li>
- <li xml:lang="sk">Podpora viacerých kariet</li>
- <li xml:lang="sl">Podpora več zavihkom</li>
- <li xml:lang="sr">Вишеструки језичци.</li>
- <li xml:lang="sr-Latn">Višestruki jezičci.</li>
- <li xml:lang="sr-ijekavian">Вишеструки језичци.</li>
- <li xml:lang="sr-ijekavianlatin">Višestruki jezičci.</li>
- <li xml:lang="sv">Stöd för flera flikar</li>
- <li xml:lang="tr">Çoklu sekme desteği</li>
- <li xml:lang="uk">Підтримка роботи з вкладками.</li>
- <li xml:lang="vi">Hỗ trợ đa thẻ</li>
- <li xml:lang="x-test">xxMultiple tab supportxx</li>
- <li xml:lang="zh-CN">多标签支持</li>
- <li xml:lang="zh-TW">額外資訊與嵌入式面板捷徑讓您可以輕易顯示您常用的項目。</li>
- <li>Informational dialogues are displayed in an unobtrusive way.</li>
- <li xml:lang="ar">حواريات المعلومات تُعرَض بطريقة غير مُزعجة.</li>
- <li xml:lang="ast">Los diálogos informativos amuésense d'un mou non intrusivu.</li>
- <li xml:lang="az">İnformasiya pəncərələri maneə olmadan görünür.</li>
- <li xml:lang="bs">Informativni dijalozi su prikazani na nenametljiv način.</li>
- <li xml:lang="ca">Els diàlegs informatius es mostren d'una manera no molesta.</li>
- <li xml:lang="ca-valencia">Els diàlegs informatius es mostren d'una manera no molesta.</li>
- <li xml:lang="da">Informationsdialoger vises på en ikke-forstyrrende måde.</li>
- <li xml:lang="de">Informationen werden unaufdringlich angezeigt.</li>
- <li xml:lang="el">Ενημερωτικοί διάλογοι εμφανίζονται με μη παρεμβατικό τρόπο.</li>
- <li xml:lang="en-GB">Informational dialogues are displayed in an unobtrusive way.</li>
- <li xml:lang="es">Los diálogos informativos se muestran de manera discreta.</li>
- <li xml:lang="et">Teavitavate dialoogide näitamine kasutajat liigselt ärritamata.</li>
- <li xml:lang="eu">Informatzeko elkarrizketa-koadroak trabarik ez sortzeko eran bistaratzen dira.</li>
- <li xml:lang="fi">Informatiiviset valintaikkunat näytetään niin, että ne eivät keskeytä kaikkea muuta toimintaa.</li>
- <li xml:lang="fr">Les dialogues d'information sont affiché de manière discrète.</li>
- <li xml:lang="gl">Os diálogos de información móstranse dunha maneira non intrusiva.</li>
- <li xml:lang="hu">Az információs párbeszédablakok szerény módon vannak megjelenítve.</li>
- <li xml:lang="ia">Dialogos de information es monstrate de modo non importun.</li>
- <li xml:lang="id">Dialog informasi ditampilkan dengan cara yang tidak mengganggu.</li>
- <li xml:lang="it">Le finestre informative sono visualizzate in modo molto discreto.</li>
- <li xml:lang="ko">정보 대화 상자는 눈에 거슬리지 않는 방식으로 표시됩니다.</li>
- <li xml:lang="lt">Informaciniai dialogai yra rodomi neįkyriai.</li>
- <li xml:lang="ml">വിവരങ്ങൾ അച്ചടക്കമുള്ള രീതിയിൽ ദൃശ്യമാകുന്നു.</li>
- <li xml:lang="nb">Informasjonsdialoger vises på en lite påtrengende måte.</li>
- <li xml:lang="nds">Informatschoondialogen kaamt Di nich in'n Weg.</li>
- <li xml:lang="nl">Informatiedialogen worden op een prettige manier getoond.</li>
- <li xml:lang="nn">Informasjonsdialogar vert viste på ein lite påtrengjande måte.</li>
- <li xml:lang="pl">Pokazywanie informacyjnych okien dialogowych w nienatrętny sposób.</li>
- <li xml:lang="pt">As janelas informativas são apresentadas de forma não-intrusiva.</li>
- <li xml:lang="pt-BR">As janelas informativas são apresentadas de forma não-intrusiva.</li>
- <li xml:lang="ro">Dialogurile informaționale sunt afișate într-un mod discret.</li>
- <li xml:lang="ru">Ненавязчивый способ показа информационных диалогов;</li>
- <li xml:lang="sk">Informačné dialógy sú zobrazené nevtieravým spôsobom.</li>
- <li xml:lang="sl">Pogovorna okna s podrobnostmi so prikazana na nevsiljiv način.</li>
- <li xml:lang="sr">Информативни дијалози који се ненаметљиво појављују.</li>
- <li xml:lang="sr-Latn">Informativni dijalozi koji se nenametljivo pojavljuju.</li>
- <li xml:lang="sr-ijekavian">Информативни дијалози који се ненаметљиво појављују.</li>
- <li xml:lang="sr-ijekavianlatin">Informativni dijalozi koji se nenametljivo pojavljuju.</li>
- <li xml:lang="sv">Dialogrutor med information visas på ett diskret sätt.</li>
- <li xml:lang="tr">Bilgi pencereleri rahatsız etmeyecek şekilde görüntülenir.</li>
- <li xml:lang="uk">Показ інформаційних панелей у зручний спосіб, що не заважає роботі.</li>
- <li xml:lang="vi">Các hộp thoại thông tin được hiển thị một cách không gây phiền nhiễu.</li>
- <li xml:lang="x-test">xxInformational dialogues are displayed in an unobtrusive way.xx</li>
- <li xml:lang="zh-CN">信息对话框采用了非侵入式的方式来呈现。</li>
- <li xml:lang="zh-TW">支援多分頁</li>
- <li>Undo/redo support</li>
- <li xml:lang="ar">دعم التراجع والإعادة</li>
- <li xml:lang="ast">Sofitu pa la desfechura/refechura</li>
- <li xml:lang="az">Geri qaytarmaq və təkrarlamaq dəstəyi</li>
- <li xml:lang="bs">Podrška za poništavanje/ponavljanje akcija</li>
- <li xml:lang="ca">Admet desfer/refer</li>
- <li xml:lang="ca-valencia">Admet desfer/refer</li>
- <li xml:lang="cs">Podpora zpět/vpřed</li>
- <li xml:lang="da">Understøttelse af fortryd/gendan</li>
- <li xml:lang="de">Unterstützung für Rückgängig/Wiederherstellen</li>
- <li xml:lang="el">Υποστήριξη αναίρεσης/επανάληψης</li>
- <li xml:lang="en-GB">Undo/redo support</li>
- <li xml:lang="es">Admite las operaciones de deshacer y rehacer</li>
- <li xml:lang="et">Tagasivõtmise ja uuestitegemise toetus.</li>
- <li xml:lang="eu">Desegin/berregin onartzen du</li>
- <li xml:lang="fi">Tuki muutosten kumoamiselle ja tekemiselle uudelleen</li>
- <li xml:lang="fr">Prise en charge d'annulation et recommencement</li>
- <li xml:lang="gl">Permite desfacer e refacer.</li>
- <li xml:lang="he">תמיכה בביטול וביצוע חוזר</li>
- <li xml:lang="hu">Visszavonás/ismétlés támogatás</li>
- <li xml:lang="ia">Supporto de annulla/reface</li>
- <li xml:lang="id">Dukungan urungkan/lanjurkan</li>
- <li xml:lang="it">Supporto di annulla/rifai</li>
- <li xml:lang="ko">실행 취소/다시 실행 지원</li>
- <li xml:lang="lt">Atšaukimo/grąžinimo palaikymas</li>
- <li xml:lang="ml">നിഷ്ക്രിയമാക്കുക/വീണ്ടും ചെയ്യുക പിന്തുണയ്ക്കുന്നു</li>
- <li xml:lang="nb">Støtte for angring/omgjøring</li>
- <li xml:lang="nds">Ünnerstütten för Torüchnehmen un Wedderherstellen</li>
- <li xml:lang="nl">Ondersteuning ongedaan maken/opnieuw</li>
- <li xml:lang="nn">Støtte for angring/omgjering</li>
- <li xml:lang="pa">ਵਾਪਿਸ ਕਰੋ/ਪਰਤਾਉਣ ਸਹਿਯੋਗ</li>
- <li xml:lang="pl">Obsługa cofnij/ponów</li>
- <li xml:lang="pt">Suporte para desfazer/refazer</li>
- <li xml:lang="pt-BR">Suporte para desfazer/refazer</li>
- <li xml:lang="ro">Suport pentru desfacere/refacere</li>
- <li xml:lang="ru">Отмена и возврат действий;</li>
- <li xml:lang="sk">Podpora Späť/Znova</li>
- <li xml:lang="sl">Podpora razveljavitvam/uveljavitvam</li>
- <li xml:lang="sr">Опозивање и понављање.</li>
- <li xml:lang="sr-Latn">Opozivanje i ponavljanje.</li>
- <li xml:lang="sr-ijekavian">Опозивање и понављање.</li>
- <li xml:lang="sr-ijekavianlatin">Opozivanje i ponavljanje.</li>
- <li xml:lang="sv">Stöd för ångra och gör om</li>
- <li xml:lang="tr">Geri alma/tekrarlama desteği</li>
- <li xml:lang="uk">Підтримка скасовування та повторення дій.</li>
- <li xml:lang="vi">Hỗ trợ đảo ngược/làm lại</li>
- <li xml:lang="x-test">xxUndo/redo supportxx</li>
- <li xml:lang="zh-CN">撤销/重做支持</li>
- <li xml:lang="zh-TW">以不唐突的方式顯示資訊對話框。</li>
- <li>Transparent network access through the KIO system.</li>
- <li xml:lang="ar">اتصال شبكيّ مباشر باستخدام نظام KIO.</li>
- <li xml:lang="ast">Accesu tresparente a la rede pente'l sistema KIO.</li>
- <li xml:lang="az">KİO vasitəsi ilə şəbəkə fayl sisteminə şəffaf giriş.</li>
- <li xml:lang="bs">Transparentni mrežni pristup kroz KIO sistem.</li>
- <li xml:lang="ca">Accés transparent a la xarxa a través del sistema KIO.</li>
- <li xml:lang="ca-valencia">Accés transparent a la xarxa a través del sistema KIO.</li>
- <li xml:lang="cs">Transparentní přístup k síti pomocí systému KIO.</li>
- <li xml:lang="da">Transparent netværksadgang igennem KIO-systemet</li>
- <li xml:lang="de">Transparenter Netzwerkzugriff durch das KIO-System.</li>
- <li xml:lang="el">Διαφανής δικτυακή πρόσβαση με το σύστημα KIO.</li>
- <li xml:lang="en-GB">Transparent network access through the KIO system.</li>
- <li xml:lang="es">Acceso transparente a la red a través del sistema KIO.</li>
- <li xml:lang="et">Võrgu läbipaistev kasutamine KIO-moodulite süsteemi vahendusel.</li>
- <li xml:lang="eu">Sare-atzipen gardena KIO sistemen bitartez.</li>
- <li xml:lang="fi">Läpinäkyvä verkon käyttö KIO-järjestelmän välityksellä.</li>
- <li xml:lang="fr">Accès au réseau transparent grâce au système des KIO.</li>
- <li xml:lang="gl">Ofrece acceso transparente á rede mediante o sistema KIO.</li>
- <li xml:lang="hu">Átlátszó hálózati hozzáférés a KIO rendszeren keresztül.</li>
- <li xml:lang="ia">Accesso de rete transparente a transverso del systema KIO.</li>
- <li xml:lang="id">Akses jaringan transparan melalui sistem KIO.</li>
- <li xml:lang="it">Accesso trasparente alla rete tramite il sistema KIO.</li>
- <li xml:lang="ko">KIO 시스템을 통한 투명한 네트워크 액세스.</li>
- <li xml:lang="lt">Skaidri tinklo prieiga per KIO sistemą.</li>
- <li xml:lang="ml">KIO സിസ്റ്റത്തിലൂടെ ശൃംഖലയെ സമീപിക്കുന്നു.</li>
- <li xml:lang="nb">Gjennomsiktig nettverkstilgang via KIO-systemet.</li>
- <li xml:lang="nds">Direkt Nettwarktogriep över dat KDE-In-/Utgaav-(KIO-)Moduulsysteem</li>
- <li xml:lang="nl">Transparante toegang tot het netwerk via het KIO systeem.</li>
- <li xml:lang="nn">Direkte nettverkstilgang via KIO-systemet.</li>
- <li xml:lang="pl">Przezroczysty dostęp do sieci przez system KIO.</li>
- <li xml:lang="pt">Acesso transparente à rede através do sistema KIO.</li>
- <li xml:lang="pt-BR">Acesso transparente à rede através do sistema KIO.</li>
- <li xml:lang="ro">Acces transparent la rețea prin sistemul KIO.</li>
- <li xml:lang="ru">Прозрачный доступ к сетевым файловым системам при помощи KIO.</li>
- <li xml:lang="sk">Transparentný prístup na sieť cez KIO systém.</li>
- <li xml:lang="sl">Enostaven dostop do omrežja preko sistema KIO.</li>
- <li xml:lang="sr">Прозиран мрежни приступ кроз систем К‑У/И.</li>
- <li xml:lang="sr-Latn">Proziran mrežni pristup kroz sistem K‑U/I.</li>
- <li xml:lang="sr-ijekavian">Прозиран мрежни приступ кроз систем К‑У/И.</li>
- <li xml:lang="sr-ijekavianlatin">Proziran mrežni pristup kroz sistem K‑U/I.</li>
- <li xml:lang="sv">Transparent nätverksåtkomst via I/O-slavsystemet.</li>
- <li xml:lang="tr">KIO sistemi üzerinden şeffaf ağ erişimi.</li>
- <li xml:lang="uk">Прозорий доступ до ресурсів у мережі за допомогою системи KIO.</li>
- <li xml:lang="vi">Truy cập tệp mạng như tệp cục bộ thông qua hệ thống KIO.</li>
- <li xml:lang="x-test">xxTransparent network access through the KIO system.xx</li>
- <li xml:lang="zh-CN">通过 KIO 系统支持透明的网络访问。</li>
- <li xml:lang="zh-TW">復原支援</li>
- </ul>
+ <p>Dolphin is KDE's file manager that lets you navigate and browse the contents of your hard drives, USB sticks, SD cards, and more. Creating, moving, or deleting files and folders is simple and fast.</p>
+ <p xml:lang="az">Dolphin sizin sərt disklərinizin, USB yaddaş qurğularınızın, SD katlarınızın və s. tərkibindəkiləri nəzərdən keçirmənizə imkan verən fayl meneceridir. Faylların və qovluqların yaradılması, Köçürülməsi və ya silinməsi sadə, rahat və cəld icra edilir.</p>
+ <p xml:lang="ca">El Dolphin és el gestor de fitxers del KDE que permet navegar i explorar el contingut dels discs durs, memòries USB, targetes SD i més. Crear, moure o suprimir fitxers i carpetes és senzill i ràpid.</p>
+ <p xml:lang="el">Το Dolphin είναι ο διαχειριστής αρχείων του KDE για την πλοήγηση και την περιήγηση στο περιεχόμενο δίσκων, USB, SD καρτών και άλλων αποθηκευτικών μέσων. Η δημιουργία, η μεταφορά, η διαγραφή αρχείων και φακέλων είναι διαδικασίες απλές και γρήγορες.</p>
+ <p xml:lang="en-GB">Dolphin is KDE's file manager that lets you navigate and browse the contents of your hard drives, USB sticks, SD cards, and more. Creating, moving, or deleting files and folders is simple and fast.</p>
+ <p xml:lang="es">Dolphin es el gestor de archivos de KDE que le permite explorar el contenido de sus discos duros, memorias USB, tarjetas SD y más. Crear, mover o eliminar archivos y carpetas es simple y rápido.</p>
+ <p xml:lang="eu">Dolphin zure disko zurrun, USB memoria, SD txartel, eta gehiagoren edukian nabigatu eta arakatzen uzten dizun KDEren fitxategi-kudeatzailea da. Fitxategi eta karpetak sortzea, mugitzea, edo ezabatzea erraza eta azkarra da.</p>
+ <p xml:lang="fi">Dolphin on KDE:n tiedostonhallinta, jolla voit selata kiintolevyjen, USB-tikkujen, SD-korttien ja muiden tallennusvälineiden sisältöä. Tiedostojen ja kansioiden luominen, siirtäminen ja poistaminen on yksinkertaista ja helppoa.</p>
+ <p xml:lang="fr">Dolphin est le gestionnaire de fichiers de KDE, vous permettant de naviguer et d'explorer le contenu de vos disques durs, vos clés USB et bien plus. La création, le déplacement ou la suppression de fichiers et de dossiers sont simples et rapides.</p>
+ <p xml:lang="hu">A Dolphin a KDE fájlkezelője, amely lehetővé teszi a merevlemezei, USB-kulcsai, SD-kártyái és más adathordozói tartalmának böngészését. Gyorsan és egyszerűen hozhat létre, helyezhet át vagy törölhet vele fájlokat és mappákat.</p>
+ <p xml:lang="id">Dolphin adalah pengelola file KDE yang memungkinkan kamu menavigasi dan menelusuri konten hard drive, stik USB, kartu SD, dan lainnya. Membuat, memindahkan, atau menghapus file dan folder itu sederhana dan cepat.</p>
+ <p xml:lang="it">Dolphin è il gestore file di KDE che ti consente di navigare e sfogliare i contenuti dei tuoi dischi fissi, chiavette USB, schede SD e altro. Creare, spostare o eliminare file e cartelle è semplice e veloce.</p>
+ <p xml:lang="nl">Dolphin is de bestandsbeheerder van KDE die u laat navigeren en bladeren de inhoud van uw vaste schijven, USB-sticks, SD-cards en meer. Aanmaken, verplaatsen of verwijderen van bestanden en mappen is eenvoudig en snel.</p>
+ <p xml:lang="nn">Dolphin er KDEs filhandsamar, som du kan bruka til å bla gjennom innhaldet på harddiskar, minnepinnar/-kort og liknande. Han gjer det svært kjapt og enkelt å oppretta, flytta og sletta filer og mapper.</p>
+ <p xml:lang="pl">Dolphin jest programem do zarządzania plikami w KDE, który umożliwia przeglądanie zawartości twoich dysków twardych, pendrajwów, kart SD oraz więcej. Tworzenie, przenoszenie, czy usuwanie plików za jego pomocą jest proste i szybkie.</p>
+ <p xml:lang="pt">O Dolphin é o gestor de ficheiros do KDE que lhe permite navegar e percorrer o conteúdo dos seus discos rígidos, unidades USB, cartões SD, entre outros. A criação, movimentação ou remoção de ficheiros e pastas é simples e rápida.</p>
+ <p xml:lang="ru">Dolphin — диспетчер файлов, разработанный KDE. Он позволяет управлять содержимым, расположенным на разных носителях: жёстких и USB-дисках, SD-картах и прочих. Операции создания, перемещения и удаления файлов и папок выполняются в Dolphin просто и быстро.</p>
+ <p xml:lang="sk">Dolphin je správca súborov KDE, ktorý vám umožní prechádzať a prehľadávať obsah vašich pevných diskov, USB kľúčov, SD kariet a ďalších. Vytváranie, presúvanie alebo mazanie súborov a priečinkov je jednoduché a rýchle.</p>
+ <p xml:lang="sl">Dolphin je upravitelj datotek KDE, ki vam omogoča krmarjenje in brskanje po vsebini trdih diskov, USB ključkov, SD kartic in še več. Ustvarjanje, premikanje ali brisanje datotek in map je preprosto in hitro.</p>
+ <p xml:lang="sv">Dolphin är KDE:s filhanterare som låter dig navigera och bläddra i innehållet på hårddiskar, USB-minnen, SD-kort, med mera. Skapa, flytta eller ta bort filer och kataloger är enkelt och går snabbt.</p>
+ <p xml:lang="uk">Dolphin — програма для керування файлами KDE, за допомогою якої ви можете пересуватися та переглядати вміст дисків, флешок USB, SD-карток тощо. Створення, пересування або вилучення файлів та тек є простим і швидким завданням.</p>
+ <p xml:lang="vi">Dolphin là trình quản lí tệp của KDE, nó cho phép bạn điều hướng và duyệt nội dung các ổ cứng, các thẻ USB, thẻ SD và các thiết bị khác của bạn. Việc tạo, chuyển, hay xoá tệp và thư mục đều đơn giản và nhanh chóng.</p>
+ <p xml:lang="x-test">xxDolphin is KDE's file manager that lets you navigate and browse the contents of your hard drives, USB sticks, SD cards, and more. Creating, moving, or deleting files and folders is simple and fast.xx</p>
+ <p xml:lang="zh-CN">Dolphin 是 KDE 的文件管理器,您可以使用它来浏览硬盘、U 盘、SD 卡和其他存储设备中的内容,也可以方便快捷地创建、移动、删除文件和文件夹。</p>
+ <p>Dolphin contains plenty of productivity features that will save you time. The multiple tabs and split view features allow navigating multiple folders at the same time, and you can easily drag and drop files between views to move or copy them. Dolphin's right-click menu provides with many quick actions that let you compress, share, and duplicate files, among many other things. You can also add your own custom actions.</p>
+ <p xml:lang="az">Dolphin, səmərəliyi artıracaq bir çox funksiyalardan ibarətdir və bu da sizə vaxtınıza qənaət edəcəkdir. Birdən çox vərəq və bölünmə funksiyaları, qovluqlar arasında rahat hərəkət etməyə imkan verir, həmçinin, siz faylları, həmin görünən qovluqlar arasında tutub yerini dəyişməklə köçürə və kopyalaya bilərsiniz. Siçanın sağ düyməsi ilə açılan Dolpin menyusunda faylları sıxmağa, paylaşmağa, yeni surətini yaratmağa və bu kimi başqa bir çox cəld əməlləri təqdim edir. Bundan başqa siz həmçinin öz fərdi əməlinizi də bu menyuya daxil edə bilərsiniz.</p>
+ <p xml:lang="ca">El Dolphin conté moltes característiques de productivitat que us estalviaran temps. Les característiques de múltiples pestanyes i de vista dividida permeten navegar per diverses carpetes al mateix temps, i poder arrossegar i deixar anar els fitxers amb facilitat entre les vistes per a moure'ls o copiar-los. El menú contextual del Dolphin ofereix moltes accions ràpides que us permeten comprimir, compartir i duplicar els fitxers, entre moltes altres coses. També podreu afegir-hi les vostres pròpies accions personalitzades.</p>
+ <p xml:lang="el">Το Dolphin περιέχει ένα πλήθος χαρακτηριστικών παραγωγικότητας με τα οποία κερδίζετε χρόνο. Οι πολλαπλές καρτέλες και τα χαρακτηριστικά διαίρεσηςς της προβολής επιτρέπουν την ταυτόχρονη πλοήγηση σε πολλούς φακέλους και μπορείτε εύκολα να αντιγράψετε ή να μεταφέρετε με έλξη και απόθεση αρχεία μεταξύ προβολών. Το μενού του Dolphin με δεξί κλικ παρέχει πολλές και γρήγορες ενέργειες π.χ. για συμπίεση, διαμοιρασμό και αντιγραφή αρχείων. Μπορείτε επίσης να προσθέσετε τις δικές σας προσαρμοσμένες ενέργειες.</p>
+ <p xml:lang="en-GB">Dolphin contains plenty of productivity features that will save you time. The multiple tabs and split view features allow navigating multiple folders at the same time, and you can easily drag and drop files between views to move or copy them. Dolphin's right-click menu provides with many quick actions that let you compress, share, and duplicate files, among many other things. You can also add your own custom actions.</p>
+ <p xml:lang="es">Dolphin contiene muchas funciones de productividad que le ahorrarán tiempo. Las pestañas múltiples y las funciones de vista dividida permiten explorar varias carpetas al mismo tiempo, y puede arrastrar y soltar archivos fácilmente entre las vistas para moverlos o copiarlos. El menú de contexto de Dolphin ofrece muchas acciones rápidas que le permiten comprimir, compartir y duplicar archivos, entre otras muchas cosas. También puede añadir sus propias acciones personalizadas.</p>
+ <p xml:lang="eu">Dolphin-ek denbora aurreztuko dizuten produktibitate-ezaugarri ugari ditu. Fitxa anitzen eta ikuspegi zatituen ezaugarriek aldi berean karpeta anitz nabigatzen uzten dute, eta fitxategiak ikuspegien artean arrastatu eta jaregin ditzakezu haiek erraz mugitu edo kopiatzeko. Dolphin-en eskuin-klik laster-menuak, besteak beste, fitxategiak konprimatzeko, partekatzeko, eta bikoizteko ekintza azkarrak eskaintzen ditu. Zuk nahi dituzun ekintzak ere erants ditzakezu.</p>
+ <p xml:lang="fi">Dolphinin monet tuottavuusominaisuudet säästävät aikaasi. Välilehdet ja jaetut näkyvät mahdollistavat useamman kansion tarkastelun yhtä aikaa, jolloin tiedostoja voi helposti kopioida tai siirtää näkymästä toiseen vetämällä ja pudottamalla. Dolphinin kontekstivalikon tarjoamin pikatoiminnoin tiedostoja voi muun muassa pakata, jakaa ja monistaa. Myös omia mukautettuja toimintoja voi luoda.</p>
+ <p xml:lang="fr">Dolphin contient de nombreuses fonctionnalités pour la productivité vous permettant de gagner du temps. Les fonctionnalités d'onglets multiples et d'affichage scindé vous permettent de naviguer dans plusieurs dossiers en même temps. Vous pouvez aussi réaliser facilement des glisser et déposer entre les affichages pour les déplacer ou les copier. Le menu de Dolphin accessible par un clic droit fournit plusieurs actions rapides vous permettant de compresser, partager et dupliquer des fichiers, entre autres actions. Vous pouvez aussi ajouter votre propres actions personnalisées.</p>
+ <p xml:lang="hu">A Dolphin számos olyan funkcióval bír, amelyek időt spórolnak Önnek. A lapokkal és osztott nézetekkel egyszerre navigálhat több mappában egyszerre, és könnyen húzhat át fájlokat az egyik nézetből a másikba, átmásolva vagy áthelyezve azokat. A Dolphin jobb gombos menüje rengeteg gyors műveletet biztosít, például tömörítést, megosztást vagy fájlduplikálást. Akár saját műveletekkel is bővítheti azt.</p>
+ <p xml:lang="id">Dolphin mengandung banyak fitur produktivitas yang akan menghemat waktumu. Fitur multi tab dan tampilan terpisah memungkinkan navigasi beberapa folder secara bersamaan, dan kamu bisa dengan mudah menyeret dan meletakkan file antar tampilan untuk memindahkan atau menyalinnya. Menu klik kanan pada dolphin menyediakan banyak tindakan cepat yang memungkinkan kamu mengompres, berbagi, dan menggandakan file, di antara banyak hal lainnya. Kamu juga bisa menambahkan tindakan kustom milikmu sendiri.</p>
+ <p xml:lang="it">Dolphin contiene molte funzionalità di produttività che ti faranno risparmiare tempo.Le schede multiple e le funzioni di visualizzazione divisa consentono di navigare in più cartelle contemporaneamente e puoi facilmente trascinare e rilasciare i file tra le visualizzazioni per spostarli o copiarli. Il menu di scelta rapida di Dolphin fornisce molte azioni rapide che ti consentono di comprimere, condividere e duplicare file, tra molte altre cose. Puoi anche aggiungere le tue azioni personalizzate.</p>
+ <p xml:lang="nl">Dolphin bevat veel functies voor productiviteit die u tijd zal besparen. De vele tabbladen en gesplitste weergeeffuncties bieden het tegelijk navigeren in meerdere mappen en u kunt gemakkelijk bestanden slepen en loslaten tussen weergaven om ze te verplaatsen of te kopiëren. Het rechtsklikmenu van Dolphin biedt met veel snelle acties dat u bestanden kan comprimeren, delen en dupliceren, naast vele andere dingen. U kunt ook uw eigen aangepaste acties toevoegen.</p>
+ <p xml:lang="nn">Dolphin inneheld mange funksjonar laga for å spara deg tid. Med faner og delt vising kan du arbeida med fleire mapper samtidig, og du kan enkelt flytta eller kopiera filene ved å dra og sleppa dei mellom mappevisingane. Og med høgreklikkmenyen får du kjapp tilgang til vanlege handlingar, for eksempel komprimering, deling og duplisering av filer. Du kan òg leggja til eigne handlingar her.</p>
+ <p xml:lang="pl">Dolphin zawiera wiele możliwości, zwiększających twoją sprawność i oszczędzających czas. Możliwość posiadania wielu kart i podzielonych widoków umożliwia poruszanie się po wielu katalogach w tym samym czasie, a także łatwe przeciąganie i upuszczanie plików pomiędzy widokami w celu ich przeniesienia lub skopiowania. Menu podręczne Dolphina dostępna pod prawym przyciskiem myszy otwiera menu szybkich działań, umożliwiające pakowanie, udostępnianie i powielanie plików. Istnieje także możliwość dodawania własnych działań.</p>
+ <p xml:lang="pt">O Dolphin contém diversas funcionalidades de produtividade que lhe pouparão tempo. As funcionalidades de várias páginas e áreas divididas permitem-lhe navegar em várias pastas ao mesmo tempo, podendo arrastar e largar ficheiros entre essas áreas para os copiar ou mover. O menu do botão direito do Dolphin oferece muitas acções rápidas que lhe permitem comprimir, partilhar e duplicar os ficheiros, entre muitas outras coisas. Também poderá adicionar as suas próprias acções personalizadas.</p>
+ <p xml:lang="ru">Приложение содержит множество функций, позволяющих экономить время. Использование вкладок и двухпанельный режим позволяют просматривать содержимое нескольких папок одновременно, а также копировать и перемещать файлы между ними простым перетаскиванием. Контекстное меню содержит набор действий, позволяющих управлять архивами, публиковать и копировать файлы, а также выполнять множество других операций. В контекстное меню возможно добавлять собственные действия.</p>
+ <p xml:lang="sk">Dolphin obsahuje množstvo funkcií produktivity, ktoré vám ušetria čas. Viaceré karty a funkcie rozdeleného zobrazenia umožňujú navigáciu vo viacerých priečinkoch súčasne. Medzi jednotlivými zobrazeniami môžete súbory jednoducho presúvať a presúvať alebo kopírovať. Ponuka pravým tlačidlom myši Dolphin ponúka mnoho rýchlych akcií, ktoré vám okrem iného umožňujú kompresiu, zdieľanie a duplikovanie súborov. Môžete tiež pridať svoje vlastné vlastné akcie.</p>
+ <p xml:lang="sl">Dolphin vsebuje veliko produktivnih funkcij, s katerimi boste prihranili čas. Več zavihkov in funkcij razdeljenega pogleda omogočajo sočasno krmarjenje po več mapah, tako da lahko datoteke enostavno vlečete in spustite med pogledi, da jih premaknete ali kopirate. Dolphinov meni z desnim klikom nudi veliko hitrih dejanj, ki vam med drugim omogočajo stiskanje, skupno rabo in podvajanje datotek. Dodate lahko tudi svoja dejanja po meri.</p>
+ <p xml:lang="sv">Dolphin innehåller mängder av produktivitetsfunktioner som sparar tid. Funktionerna för flera flikar och delad vy tillåter att flera kataloger navigeras samtidigt, och du kan enkelt dra och släppa filer mellan vyer för att flytta eller kopiera dem. Dolphins högerklicksmeny tillhandahåller många snabbåtgärder som låter dig bland annat komprimera, dela och duplicera filer. Du kan också lägga till egna åtgärder.</p>
+ <p xml:lang="uk">У Dolphin передбачено багато можливостей, які роблять вашу роботу продуктивнішою та заощаджують час. За допомогою можливостей використання декількох вкладок та поділу панелей перегляду ви можете переглядати вміст декількох тек одночасно і без проблем перетягувати і скидати пункти файлів і тек між різними панелями з метою копіювання або пересування. У контекстному меню Dolphin, яке можна викликати клацанням правою кнопкою миші, серед іншого, передбачено багато пунктів для швидкого доступу до стискання, оприлюднення та дублювання файлів. Крім того, ви можете додавати туди власні нетипові пункти дій.</p>
+ <p xml:lang="vi">Dolphin bao gồm nhiều tính năng năng suất sẽ giúp bạn tiết kiệm thời gian. Các tính năng đa thẻ và khung xem chia đôi cho phép điều hướng nhiều thư mục cùng lúc, và bạn có thể dễ dàng kéo thả tệp giữa các khung xem để chuyển hay chép chúng. Trình đơn chuột phải của Dolphin cung cấp nhiều hành động nhanh gọn cho phép bạn nén, chia sẻ, và tạo bản sao cho các tệp, cùng nhiều việc khác nữa. Bạn cũng có thể thêm các hành động tự chọn của mình.</p>
+ <p xml:lang="x-test">xxDolphin contains plenty of productivity features that will save you time. The multiple tabs and split view features allow navigating multiple folders at the same time, and you can easily drag and drop files between views to move or copy them. Dolphin's right-click menu provides with many quick actions that let you compress, share, and duplicate files, among many other things. You can also add your own custom actions.xx</p>
+ <p xml:lang="zh-CN">Dolphin 内建了许多有助于提高生产力的功能,助您省时省力。多标签页窗口、拆分视图等功能可以让您同时浏览多个文件夹,还可以在标签页和拆分的视图之间拖放、复制、移动文件。Dolphin 的右键菜单内建了许多快捷操作功能,例如压缩、分享、创建文件的副本等。您还可以将自定义操作添加到右键菜单。</p>
+ <p>Dolphin is very lightweight, but at the same time, you can adapt it to your specific needs. This means that you can carry out your file management exactly the way you want to. Dolphin supports three different view modes: a classic grid view of all the files, a more detailed view, and a tree view. You can also configure most of Dolphin's behavior.</p>
+ <p xml:lang="az">Dolphin çox yüngüldür, bununla belə siz onu öz ehtiyaclarınıza uyğunlaşdıra bilərsiniz. Bu o deməkdir ki, siz fayllarınızı istədiyiniz kimi idarə edə bilərsiniz. Dolphin üç müxtəlif baxış rejimini dəstəkləyir: bütün faylları üçün şəbəkə formasında klassik görünüş, budaqlanan şəkildə daha təfərrüatlı baxış forması. Siz həmçinin daha çox Dolphin davranışlarını tənzimləyə bilərsiniz.</p>
+ <p xml:lang="ca">El Dolphin és molt lleuger, però al mateix temps, podreu adaptar-lo a les vostres necessitats específiques. Això significa que podreu realitzar la gestió de fitxers exactament de la manera que vulgueu. El Dolphin admet tres modes de vista diferents: una vista de quadrícula clàssica amb tots els fitxers, una vista més detallada i una vista en arbre. També podreu configurar la major part del comportament del Dolphin.</p>
+ <p xml:lang="el">Το Dolphin είναι πολύ ελαφρύ, αλλά ταυτόχρονα και προσαρμόσιμο στις ανάγκες σας. Αυτό σημαίνει ότι μπορείτε να διεκπεραιώσετε τη διαχείριση αρχείων ακριβώς με τον τρόπο που θέλετε. Το Dolphin υποστηρίζει τρεις διαφορετικές λειτουργίες προβολής: το κλασικό πλέγμα με όλα τα αρχεία, μια λεπτομερή άποψη και μια δενδρική προβολή. Μπορείτε επίσης να διαμορφώσετε στο Dolphin το μεγαλύτερο τμήμα της συμπεριφοράς του.</p>
+ <p xml:lang="en-GB">Dolphin is very lightweight, but at the same time, you can adapt it to your specific needs. This means that you can carry out your file management exactly the way you want to. Dolphin supports three different view modes: a classic grid view of all the files, a more detailed view, and a tree view. You can also configure most of Dolphin's behaviour.</p>
+ <p xml:lang="es">Dolphin es muy ligero, aunque también se puede adaptar a sus necesidades específicas. Esto significa que puede realizar la gestión de sus archivos exactamente de la forma que desee. Dolphin admite tres modos de vista diferentes: una vista de cuadrícula clásica de todos los archivos, una vista más detallada y una vista de árbol. También puede configurar la mayor parte del comportamiento de Dolphin.</p>
+ <p xml:lang="eu">Dolphin oso arina da, baina, aldi berean, zure beharretara egoki dezakezu. Horrek esan nahi du fitxategien kudeaketa zuk nahi duzun modura egin dezakezula. Dolphin-ek hiru ikuspegi modu ezberdin onartzen ditu: fitxategi guztien sareta-ikuspegi klasiko bat, xehetasun gehiago dituen ikuspegi bat, eta zuhaitz-ikuspegi bat. Dolphin-en jokabide gehienak ere konfigura ditzakezu.</p>
+ <p xml:lang="fi">Dolphin on hyvin kevyt mutta samalla sovitettavissa tarpeisiisi, joten voit hallita tiedostojasi juuri kuten haluat. Dolphin tukee kolmea eri näkymää: perinteistä ruudukkoa, yksityiskohtaisempaa tilanäkymää ja puunäkymää. Useimpia Dolphinin toiminta-asetuksia voi säätää.</p>
+ <p xml:lang="fr">Dolphin est peu consommateur de ressources mais, en même temps, vous pouvez l'adapter à vos besoins spécifiques. Cela signifie que vous pouvez configurer votre gestion de fichiers, exactement comme vous le souhaitez. Dolphin prend en charge trois modes différents d'affichage : un affichage classique en grille pour tous vos fichiers, un affichage plus détaillé et un affichage en arborescence. Vous pouvez configurer la plupart des comportement de Dolphin.</p>
+ <p xml:lang="hu">A Dolphin pehelysúlyú, ugyanakkor a saját igényeire is szabhatja, vagyis a fájlkezelést teljesen a saját szája íze szerint végezheti. A Dolphin három nézetmódot támogat: a klasszikus rácsnézetet, a részletes nézetet és a fastruktúra nézetet. A legtöbb funkciót módosíthatja.</p>
+ <p xml:lang="id">Dolphin sangat ringan, tetapi pada saat yang sama, kamu bisa menyesuaikannya dengan kebutuhan spesifikmu. Ini berarti kamu bisa menjalankan pengelola file-mu persis seperti yang kamu inginkan. Dolphin mendukung tiga mode tampilan yang berbeda: tampilan kisi klasik dari semua file, tampilan yang lebih detail, dan tampilan ranting. Kamu juga bisa mengkonfigurasi sebagian besar perilaku Dolphin.</p>
+ <p xml:lang="it">Dolphin è molto leggero, ma allo stesso tempo puoi adattarlo alle tue esigenze specifiche. Ciò significa che puoi eseguire la gestione dei file esattamente come desideri. Dolphin supporta tre diverse modalità di visualizzazione: una classica visualizzazione a griglia di tutti i file, una visualizzazione più dettagliata e una visualizzazione ad albero. Puoi anche configurare la maggior parte del comportamento di Dolphin.</p>
+ <p xml:lang="nl">Dolphin is erg lichtgewicht, maar tegelijkertijd kunt u het aanpassen aan uw specifieke behoeften. Dit betekent dat u uw bestandsbeheer kunt uitvoeren exact op de manier die u wilt. Dolphin ondersteunt drie verschillende weergavemodi: een klassieke rasterweergave van alle bestanden, een meer gedetailleerde weergave en een boomstructuurweergave. U kunt het meeste van het gedrag van Dolphin ook configureren.</p>
+ <p xml:lang="nn">Dolpin krev få systemressursar og kan tilpassast måten du arbeider på. Programmet støttar tre ulike visingsmodusar – klassisk rutenettvising av filer, detaljvising med metadata og trevising. Du kan òg finjustera det meste av funksjonaliteten i programmet.</p>
+ <p xml:lang="pl">Dolphin jest bardzo lekki, a zarazem może dostosować się do szczególnych wymagań. Oznacz to, że możesz działać na swoich plikach tak, jak chcesz. W Dolphinie można ustawić trzy różne tryby widoku: klasyczny siatkowy widok wszystkich plików, bardziej szczegółowy widok oraz widok drzewa. Możesz także zmienić ustawienia większości zachowań Dolphina.</p>
+ <p xml:lang="pt">O Dolphin é bastante leve mas, ao mesmo tempo, poderá adaptá-lo de acordo com as suas necessidades específicas. Isto significa que poderá desempenhar a sua gestão de ficheiros da forma exacta que necessita. O Dolphin suporta três modos de visualização diferentes: uma grelha clássica com todos os ficheiros, uma área mais detalhada e uma vista em árvore. Poderá também configurar a maioria do comportamento do Dolphin.</p>
+ <p xml:lang="ru">Dolphin не занимает много места и быстро работает, но при этом может быть настрое в соответствии с потребностями. Приложение поддерживает три режима просмотра: классический режим просмотра значков, более подробный режим и режим иерархического просмотра. Поведение приложения также может быть гибко настроено.</p>
+ <p xml:lang="sk">Delfín je veľmi ľahký, ale zároveň ho môžete prispôsobiť svojim konkrétnym potrebám. To znamená, že správu súborov môžete vykonávať presne tak, ako chcete. Dolphin podporuje tri rôzne režimy zobrazenia: klasické zobrazenie všetkých súborov v mriežke, podrobnejšie zobrazenie a stromové zobrazenie. Môžete tiež nakonfigurovať väčšinu správania Dolphin.</p>
+ <p xml:lang="sl">Dolphin je zelo lahek, hkrati pa ga lahko prilagodite svojim posebnim potrebam. To pomeni, da lahko izvajate upravljanje datotek natanko tako, kot želite. Dolphin podpira tri različne načine pogleda: klasičen mrežni pogled vseh datotek, podrobnejši pogled in drevesni pogled. Večino vedenja Dolphina lahko tudi nastavljate.</p>
+ <p xml:lang="sv">Dolphin är mycket lättviktigt, men samtidigt kan du anpassa det för dina specifika behov. Det betyder att du kan utföra filhantering precis på det sätt du vill. Dolphin stöder tre olika visningsmetoder: en klassisk rutnätsvy av alla filer, en mer detaljerad vy och en trädvy. Du kan också anpassa det mesta av Dolphins beteende.</p>
+ <p xml:lang="uk">Dolphin є дуже невибагливим до ресурсів. Втім, ви можете адаптувати програму до ваших потреб. Це означає, що ви можете здійснювати керування файлами саме так, як вам того хочеться. У Dolphin передбачено три різних режими перегляду: класичний перегляд таблицею усіх файлів, режим докладного перегляду та ієрархічний перегляд. Більшу частину характеристик роботи програми можна налаштувати Dolphin.</p>
+ <p xml:lang="vi">Dolphin rất nhẹ, nhưng đồng thời bạn có thể điều chỉnh nó theo các nhu cầu cụ thể của mình. Điều này nghĩa là bạn có thể thực hiện việc quản lí tệp đúng như cách bạn muốn. Dolphin hỗ trợ ba chế độ xem khác nhau: một khung xem tất cả các tệp ở dạng lưới cổ điển, một khung xem chi tiết hơn, và một khung xem dạng cây. Bạn cũng có thể cấu hình hầu hết tất cả các ứng xử của Dolphin.</p>
+ <p xml:lang="x-test">xxDolphin is very lightweight, but at the same time, you can adapt it to your specific needs. This means that you can carry out your file management exactly the way you want to. Dolphin supports three different view modes: a classic grid view of all the files, a more detailed view, and a tree view. You can also configure most of Dolphin's behavior.xx</p>
+ <p xml:lang="zh-CN">Dolphin 是一个体积轻巧的应用程序,您还可以按照自己的需要对其进行调整,让文件管理操作更加得心应手。Dolphin 的文件视图有三种模式:图标网格、简洁单栏、多栏详情。您还可以对 Dolphin 的程序行为进行配置。</p>
+ <p>Dolphin can display files and folders from many Internet cloud services and other remote machines as if they were right there on your desktop.</p>
+ <p xml:lang="az">Dolphin, bir çox İnternet və digər uzaq maşınların bulud xidmətindən faylları və qovluqları birbaşa sizin İş Masanızdakı kimi göstərəcəkdir.</p>
+ <p xml:lang="ca">El Dolphin pot mostrar els fitxers i carpetes de molts serveis en el núvol d'Internet i altres màquines remotes com si hi estiguessin al vostre escriptori.</p>
+ <p xml:lang="el">Το Dolphin εμφανίζει αρχεία και φακέλους από πολλές υπηρεσίες νέφους στο Διαδίκτυο και από άλλες απομακρυσμένες συσκευές σαν να βρίσκονταν στον υπολογιστή σας.</p>
+ <p xml:lang="en-GB">Dolphin can display files and folders from many Internet cloud services and other remote machines as if they were right there on your desktop.</p>
+ <p xml:lang="es">Dolphin puede mostrar archivos y carpetas de muchos servicios en la nube de Internet y otras máquinas remotas como si estuvieran directamente en el escritorio.</p>
+ <p xml:lang="eu">Dolphin-ek Interneteko hodei-zerbitzu askotako eta urruneko beste makina batzuetako fitxategi eta karpetak zure mahaigainean egongo balira bezala erakuts ditzake.</p>
+ <p xml:lang="fi">Dolphin osaa näyttää tiedostot ja kansiot monista internetin pilvipalveluista sekä etäkoneilta kuin ne olisivat välittömästi työpöydälläsi.</p>
+ <p xml:lang="fr">Dolphin peut afficher des fichiers et des dossiers à partir de nombreux services de stockage sur Internet (Cloud) et d'ordinateurs distants, comme s'ils étaient directement sur votre ordinateur.</p>
+ <p xml:lang="hu">A Dolphin úgy képes fájlokat megjeleníteni számos felhőszolgáltatásból vagy távoli gépekről, mintha azok a saját számítógépén lennének.</p>
+ <p xml:lang="id">Dolphin bisa menampilkan file dan folder dari banyak layanan cloud Internet dan mesin jarak jauh lainnya seolah-olah mereka ada di desktop-mu.</p>
+ <p xml:lang="it">Dolphin può visualizzare file e cartelle da molti servizi cloud Internet e altre macchine remote come se fossero direttamente sul tuo desktop.</p>
+ <p xml:lang="nl">Dolphin kan bestanden en mappen uit vele Internet-cloudservices en andere machines op afstand tonen alsof ze direct op uw bureaublad staan.</p>
+ <p xml:lang="nn">Dolphin kan visa filer og mapper frå mange skytenester og andre eksterne maskiner på same måte som om dei var lokale filer og mapper.</p>
+ <p xml:lang="pl">Dolphin może wyświetlać pliki i katalogi z wielu usług chmury w internecie oraz zdalnych komputerów tak, jakby były na twoim własnym komputerze.</p>
+ <p xml:lang="pt">O Dolphin consegue mostrar ficheiros e pastas de muitos serviços na 'cloud' da Internet e de outras máquinas remotas, como se estivesse na sua máquina local.</p>
+ <p xml:lang="ru">Dolphin поддерживает работу с облачными хранилищами и папками, размещёнными на сетевых устройствах, позволяя работать с ними как с локальными.</p>
+ <p xml:lang="sk">Dolphin dokáže zobraziť súbory a priečinky z mnohých internetových cloudových služieb a iných vzdialených počítačov, akoby sa nachádzali priamo na vašej pracovnej ploche.</p>
+ <p xml:lang="sl">Dolphin lahko prikazuje datoteke in mape iz številnih internetnih storitev v oblaku in druge oddaljene računalnike, kot da bi bili na namizju.</p>
+ <p xml:lang="sv">Dolphin kan visa filer och kataloger från många molntjänster på Internet och från andra datorer, som om de fanns direkt på ditt eget skrivbord.</p>
+ <p xml:lang="uk">Dolphin здатен показувати файли і теки із багатьох «хмарних» служб інтернету та віддалених комп'ютерів так, наче усі ці дані зберігаються на вашому робочому комп'ютері.</p>
+ <p xml:lang="vi">Dolphin có thể hiển thị tệp và thư mục từ nhiều dịch vụ đám mây Liên Mạng và các máy ở xa khác như thể chúng ở ngay trên máy tính của bạn vậy.</p>
+ <p xml:lang="x-test">xxDolphin can display files and folders from many Internet cloud services and other remote machines as if they were right there on your desktop.xx</p>
+ <p xml:lang="zh-CN">Dolphin 可以显示多种云存储服务和远程计算机中的文件和文件夹,与本机文件的体验完全一致。</p>
+ <p>Dolphin also comes with an integrated terminal that allows you to run commands on the current folder. You can extend the capabilities of Dolphin even further with powerful plugins to adapt it to your workflow. You can use the git integration plugin to interact with git repositories, or the Nextcloud plugin to synchronize your files online, and much more.</p>
+ <p xml:lang="az">Dolphin həmçinin daxilə quraşdırılmış terminalla təmin olunur ki, bu da cari qovluqda əmrləri başlatmağa imkan verir. Siz, Dolphinin imkanlarını iş prosesinizə uyğunlaşdıracaq, güclü qoşmaların köməyi ilə daha da genişləndirə bilərsiniz. Sİz git repazitoriyaları ilə işləmək üçün, qoşulmuş git inteqrasiya modulundan və ya fayllarınızı internet üzərindən sinxronlaşdırmaq üçün Nextcloud qoşmasından və s. istifadə edə bilərsiniz.</p>
+ <p xml:lang="ca">El Dolphin també ve amb un terminal integrat que permet executar ordres a la carpeta actual. Podreu estendre encara més les capacitats de Dolphin amb potents connectors per a que s'adapti al vostre flux de treball. Podreu utilitzar el connector d'integració amb el Git per a interactuar amb els repositoris de Git, o el connector de Nextcloud per a sincronitzar els vostres fitxers en línia, i molt més.</p>
+ <p xml:lang="el">Το Dolphin επίσης συνοδεύεται από ένα ενσωματωμένο τερματικό για να εκτελείτε εντολές στον τρέχοντα φάκελο. Μπορείτε να επεκτείνετε τις δυνατότητες του Dolphin ακόμη περισσότερο με ισχυρά πρόσθετα για να το προσαρμόσετε στη ροή των εργασιών σας. Μπορείτε να χρησιμοποιήσετε το ενσωματωμένο πρόσθετο του git για να αλληλεπιδράτε με αποθετήρια git, ή το πρόσθετο για το Nextcloud για να συγχρονίζετε τα επιγραμμικά αρχεία σας και υπάρχουν ακόμη πολλές δυνατότητες.</p>
+ <p xml:lang="en-GB">Dolphin also comes with an integrated terminal that allows you to run commands on the current folder. You can extend the capabilities of Dolphin even further with powerful plugins to adapt it to your workflow. You can use the git integration plugin to interact with git repositories, or the Nextcloud plugin to synchronise your files online, and much more.</p>
+ <p xml:lang="es">Dolphin también proporciona un terminal integrado que le permite ejecutar órdenes en la carpeta actual. Puede ampliar aún más las capacidades de Dolphin con potentes complementos para adaptarlo a su forma de trabajar. Puede usar el complemento de integración de git para interactuar con repositorios de git, o el complemento de Nextcloud para sincronizar archivos en línea, entre otras cosas.</p>
+ <p xml:lang="eu">Dolphin-ek terminal bat ere badu, uneko karpetan komandoak erabiltzeko aukera ematen duena. Dolphin-en gaitasunak are gehiago hedatu ditzakezu zure lan egiteko modura egokitzeko plugin ahaltsuak erabiliz. Git bateratzeko plugina erabil dezakezu Git gordetegiekin elkarreragiteko, edo Nextcloud plugina zure fitxategiak lerroan sinkronizatzeko, eta askoz gehiago.</p>
+ <p xml:lang="fi">Dolphinissa on myös sisään rakennettu pääte komentojen suorittamiseksi nykyisessä kansiossa. Dolphinin ominaisuuksia voi myös laajentaa sopimaan työtapaasi tehokkain laajennuksin. Git-integrointiliitännäinen auttaa toimimaan Git-lähteiden kanssa, Nextcloud-liitännäisellä voi synkronoida tiedostot verkkoon jne.</p>
+ <p xml:lang="fr">Dolphin est aussi livré avec un terminal intégré, vous permettant d'exécuter des commandes sur votre dossier courant. Vous pouvez étendre les fonctionnalités de Dolphin encore plus avec de puissants modules externes pour s'adapter à vos processus de travail. Vous pouvez utiliser le module externe « git » pour interagir avec les dépôts « git » ou le module externe « Nextcloud » pour synchroniser vos fichiers en ligne et bien d'autres choses encore.</p>
+ <p xml:lang="hu">A Dolphin tovább tartalmaz egy integrált terminálemulátort, amely lehetővé teszi parancsok futtatását az aktuális mappában. Bővítményekkel még jobban kiterjesztheti a Dolphin képességeinek határait. A git integrációs bővítménnyek git tárolókat kezelhet, a Nextcloud bővítménnyel szinkronizálhatja fájljait, és így tovább.</p>
+ <p xml:lang="id">Dolphin juga dilengkapi dengan terminal terintegrasi yang memungkinkan kamu menjalankan perintah di folder saat ini. Kamu bisa memperluas kemampuan Dolphin lebih jauh dengan plugin yang hebat untuk menyesuaikannya dengan alur kerja kamu. Kamu bisa menggunakan plugin integrasi git untuk berinteraksi dengan repositori git, atau plugin Nextcloud untuk menyinkronkan file-mu secara online, dan banyak lagi.</p>
+ <p xml:lang="it">Dolphin è inoltre dotato di un terminale integrato che ti consente di eseguire comandi nella cartella attuale. Puoi estendere ulteriormente le capacità di Dolphin con potenti estensioni per adattarlo al tuo flusso di lavoro. Puoi utilizzare l'estensione di integrazione con git per interagire con i depositi git o l'estensione Nextcloud per sincronizzare i tuoi file in linea e molto altro ancora.</p>
+ <p xml:lang="nl">Dolphin komt ook met een geïntegreerde terminal die u commando's laat uitvoeren in de huidige map. U kunt de mogelijkheden van Dolphin zelfs nog verder uitbreiden met krachtige plug-ins om deze aan uw werkmethode aan te passen. U kunt de git-integratie-plug-in gebruiken om met git-opslagruimten interacties uit te voeren of met de Nextcloud-plug-in om uw bestanden online te synchroniseren en nog veel meer.</p>
+ <p xml:lang="nn">Dolphin kjem med ein innebygd terminal som lèt deg køyra kommandoar frå gjeldande mappe. Du kan òg leggja til meir funksjonalitet i programmet ved hjelp av programtillegg. Det finst blant anna eit tillegg for Git-integrasjon for å arbeida med Git-depot og tillegg for Nextcloud for å synkronisera filene dine via nettet.</p>
+ <p xml:lang="pl">Dolphin dostarczany jest także z wbudowanym terminalem, który umożliwia wykonywanie poleceń w bieżącym katalogu. Możliwości Dolphina można rozszerzyć jeszcze bardziej dzięki złożonym wtyczkom. Możesz użyć wtyczki wbudowującej git, aby działać na repozytoriach git lub wtyczkę Nextcloud, aby synchronizować swoje pliki będąc na łączach, a także wiele innych.</p>
+ <p xml:lang="pt">O Dolphin também tem um terminal integrado que lhe permite executar comandos na pasta actual. Poderá alargar ainda mais as capacidades do Dolphin com os 'plugins' poderosos existentes, de forma a adaptá-lo à sua forma de trabalhar. Poderá usar o 'plugin' de integração com o Git para interagir com os repositórios de Git ou o 'plugin' do Nextcloud para sincronizar os seus ficheiros na rede, entre muitos outros.</p>
+ <p xml:lang="ru">В приложение также встроен эмулятор терминала, который позволяет выполнять команды в текущей папке. Возможности Dolphin могут быть расширены в соответствии с потребностями использованием подключаемых внешних модулей. Такие модули позволяют, например, работать с репозиториями git, синхронизировать файлы с облачным хранилищем Nextcloud, а также многое другое.</p>
+ <p xml:lang="sk">Dolphin tiež prichádza s integrovaným terminálom, ktorý umožňuje spúšťať príkazy v aktuálnom priečinku. Možnosti Dolphinu môžete ešte rozšíriť pomocou výkonných doplnkov, ktoré ho prispôsobia vášmu pracovnému toku. Integračný doplnok git môžete použiť na interakciu s úložiskami git, alebo doplnok Nextcloud na synchronizáciu súborov online a oveľa viac.</p>
+ <p xml:lang="sl">Dolphin ima tudi integriran terminal, ki vam omogoča zagon ukazov v trenutni mapi. Zmogljivosti Dolphina lahko razširite še močnimi vtičniki, ki ga prilagodijo vašemu delovnemu toku. Lahko uporabite git integracijski vtičnik za interakcijo s skladišči git ali vtičnik Nextcloud za sinhronizacijo datotek v spletu in še veliko več.</p>
+ <p xml:lang="sv">Dolphin levereras också med en integrerad terminal som låter dig köra kommandon i den aktuella katalogen. Du kan utöka Dolphins funktioner ytterligare med kraftfulla insticksprogram för att anpassa programmet till ditt arbetsflöde. Du kan använda insticksprogrammet git-integrering för att komma åt git-arkiv, eller insticksprogrammet Nextcloud för att synkronisera filer på nätet, med mera.</p>
+ <p xml:lang="uk">Також до Dolphin вбудовано термінал, за допомогою якого ви можете виконувати команди у поточній теці. Ви можете розширити можливості Dolphin за допомогою потужних додатків з метою пристосування програми до ваших робочих процедур. Ви можете скористатися додатком інтеграції із git для роботи зі сховищами git або додатком Nextcloud для синхронізації ваших файлів зі сховищами даних в інтернеті тощо.</p>
+ <p xml:lang="vi">Dolphin còn đi kèm với một dòng lệnh tích hợp, cho phép bạn chạy lệnh ở thư mục hiện tại. Bạn thậm chí có thể mở rộng khả năng của Dolphin thêm nữa bằng các phần cài cắm mạnh mẽ để đáp ứng với cách làm việc của bạn. Bạn có thể dùng phần cài cắm tích hợp git để tương tác với các kho git, hay phần cài cắm Nextcloud để đồng bộ trực tuyến các tệp của bạn, và còn nhiều nữa.</p>
+ <p xml:lang="x-test">xxDolphin also comes with an integrated terminal that allows you to run commands on the current folder. You can extend the capabilities of Dolphin even further with powerful plugins to adapt it to your workflow. You can use the git integration plugin to interact with git repositories, or the Nextcloud plugin to synchronize your files online, and much more.xx</p>
+ <p xml:lang="zh-CN">Dolphin 还整合了命令行终端,可以在当前文件夹中执行命令行指令。您还可以通过插件来进一步增强 Dolphin 的功能,适应您的使用习惯。例如您可以使用 git 整合插件来与 git 源代码仓库进行交互,或者使用 Nextcloud 插件来在线同步文件等。</p>
</description>
<url type="homepage">https://kde.org/applications/en/dolphin</url>
<url type="bugtracker">https://bugs.kde.org/enter_bug.cgi?format=guided&product=dolphin</url>
<caption xml:lang="sk">Správa súborov v Dolphin</caption>
<caption xml:lang="sl">Upravljanje datotek v Dolphinu</caption>
<caption xml:lang="sv">Filhantering i Dolphin</caption>
+ <caption xml:lang="tr">Dolphin'de dosya yönetimi</caption>
<caption xml:lang="uk">Керування файлами у Dolphin</caption>
<caption xml:lang="vi">Quản lí tệp trong Dolphin</caption>
<caption xml:lang="x-test">xxFile management in Dolphinxx</caption>
m_facetsWidget->layout()->setSpacing(Dolphin::LAYOUT_SPACING_SMALL);
connect(m_facetsWidget, &DolphinFacetsWidget::facetChanged, this, &DolphinSearchBox::slotFacetChanged);
+ // Put the options into a QScrollArea. This prevents increasing the view width
+ // in case that not enough width for the options is available.
+ QWidget* optionsContainer = new QWidget(this);
+
// Apply layout for the options
- QHBoxLayout* optionsLayout = new QHBoxLayout();
+ QHBoxLayout* optionsLayout = new QHBoxLayout(optionsContainer);
optionsLayout->setContentsMargins(0, 0, 0, 0);
optionsLayout->setSpacing(Dolphin::LAYOUT_SPACING_SMALL);
optionsLayout->addWidget(m_fileNameButton);
optionsLayout->addWidget(moreSearchToolsButton);
optionsLayout->addStretch(1);
- // Put the options into a QScrollArea. This prevents increasing the view width
- // in case that not enough width for the options is available.
- QWidget* optionsContainer = new QWidget(this);
- optionsContainer->setLayout(optionsLayout);
-
m_optionsScrollArea = new QScrollArea(this);
m_optionsScrollArea->setFrameShape(QFrame::NoFrame);
m_optionsScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
* SPDX-License-Identifier: GPL-2.0-or-later
*/
-#include "servicessettingspage.h"
+#include "contextmenusettingspage.h"
#include "dolphin_generalsettings.h"
#include "dolphin_versioncontrolsettings.h"
+#include "dolphin_contextmenusettings.h"
#include "settings/serviceitemdelegate.h"
#include "settings/servicemodel.h"
const char CopyToMoveToService[] ="_copy_to_move_to";
}
-ServicesSettingsPage::ServicesSettingsPage(QWidget* parent) :
+ContextMenuSettingsPage::ContextMenuSettingsPage(QWidget* parent,
+ const KActionCollection* actions,
+ const QStringList& actionIds) :
SettingsPageBase(parent),
m_initialized(false),
m_serviceModel(nullptr),
m_sortModel(nullptr),
m_listView(nullptr),
- m_enabledVcsPlugins()
+ m_enabledVcsPlugins(),
+ m_actions(actions),
+ m_actionIds(actionIds)
{
QVBoxLayout* topLayout = new QVBoxLayout(this);
m_listView->setModel(m_sortModel);
m_listView->setItemDelegate(delegate);
m_listView->setVerticalScrollMode(QListView::ScrollPerPixel);
- connect(m_listView, &QListView::clicked, this, &ServicesSettingsPage::changed);
+ connect(m_listView, &QListView::clicked, this, &ContextMenuSettingsPage::changed);
#ifndef Q_OS_WIN
auto *downloadButton = new KNS3::Button(i18nc("@action:button", "Download New Services..."),
std::sort(m_enabledVcsPlugins.begin(), m_enabledVcsPlugins.end());
}
-ServicesSettingsPage::~ServicesSettingsPage() = default;
+ContextMenuSettingsPage::~ContextMenuSettingsPage() {
+}
+
+bool ContextMenuSettingsPage::entryVisible(const QString& id)
+{
+ if (id == "add_to_places") {
+ return ContextMenuSettings::showAddToPlaces();
+ } else if (id == "sort") {
+ return ContextMenuSettings::showSortBy();
+ } else if (id == "view_mode") {
+ return ContextMenuSettings::showViewMode();
+ } else if (id == "open_in_new_tab") {
+ return ContextMenuSettings::showOpenInNewTab();
+ } else if (id == "open_in_new_window") {
+ return ContextMenuSettings::showOpenInNewWindow();
+ } else if (id == "copy_location") {
+ return ContextMenuSettings::showCopyLocation();
+ } else if (id == "duplicate") {
+ return ContextMenuSettings::showDuplicateHere();
+ }
+ return false;
+}
+
+void ContextMenuSettingsPage::setEntryVisible(const QString& id, bool visible)
+{
+ if (id == "add_to_places") {
+ ContextMenuSettings::setShowAddToPlaces(visible);
+ } else if (id == "sort") {
+ ContextMenuSettings::setShowSortBy(visible);
+ } else if (id == "view_mode") {
+ ContextMenuSettings::setShowViewMode(visible);
+ } else if (id == "open_in_new_tab") {
+ ContextMenuSettings::setShowOpenInNewTab(visible);
+ } else if (id == "open_in_new_window") {
+ ContextMenuSettings::setShowOpenInNewWindow(visible);
+ } else if (id == "copy_location") {
+ ContextMenuSettings::setShowCopyLocation(visible);
+ } else if (id == "duplicate") {
+ ContextMenuSettings::setShowDuplicateHere(visible);
+ }
+}
-void ServicesSettingsPage::applySettings()
+void ContextMenuSettingsPage::applySettings()
{
if (!m_initialized) {
return;
configGroup.writeEntry("ShowDeleteCommand", checked);
configGroup.sync();
} else if (service == QLatin1String(CopyToMoveToService)) {
- GeneralSettings::setShowCopyMoveMenu(checked);
- GeneralSettings::self()->save();
+ ContextMenuSettings::setShowCopyMoveMenu(checked);
+ ContextMenuSettings::self()->save();
+ } else if (m_actionIds.contains(service)) {
+ setEntryVisible(service, checked);
+ ContextMenuSettings::self()->save();
} else {
showGroup.writeEntry(service, checked);
}
}
}
-void ServicesSettingsPage::restoreDefaults()
+void ContextMenuSettingsPage::restoreDefaults()
{
QAbstractItemModel* model = m_listView->model();
for (int i = 0; i < model->rowCount(); ++i) {
}
}
-void ServicesSettingsPage::showEvent(QShowEvent* event)
+void ContextMenuSettingsPage::showEvent(QShowEvent* event)
{
if (!event->spontaneous() && !m_initialized) {
loadServices();
addRow(QStringLiteral("edit-copy"),
i18nc("@option:check", "'Copy To' and 'Move To' commands"),
CopyToMoveToService,
- GeneralSettings::showCopyMoveMenu());
+ ContextMenuSettings::showCopyMoveMenu());
+
+ // Add other built-in actions
+ for (const QString& id : m_actionIds) {
+ const QAction* action = m_actions->action(id);
+ if (action) {
+ addRow(action->icon().name(), action->text(), id, entryVisible(id));
+ }
+ }
m_sortModel->sort(Qt::DisplayRole);
SettingsPageBase::showEvent(event);
}
-void ServicesSettingsPage::loadServices()
+void ContextMenuSettingsPage::loadServices()
{
const KConfig config(QStringLiteral("kservicemenurc"), KConfig::NoGlobals);
const KConfigGroup showGroup = config.group("Show");
m_searchLineEdit->setFocus(Qt::OtherFocusReason);
}
-void ServicesSettingsPage::loadVersionControlSystems()
+void ContextMenuSettingsPage::loadVersionControlSystems()
{
const QStringList enabledPlugins = VersionControlSettings::enabledPlugins();
m_sortModel->sort(Qt::DisplayRole);
}
-bool ServicesSettingsPage::isInServicesList(const QString &service) const
+bool ContextMenuSettingsPage::isInServicesList(const QString &service) const
{
for (int i = 0; i < m_serviceModel->rowCount(); ++i) {
const QModelIndex index = m_serviceModel->index(i, 0);
return false;
}
-void ServicesSettingsPage::addRow(const QString &icon,
- const QString &text,
- const QString &value,
- bool checked)
+void ContextMenuSettingsPage::addRow(const QString &icon,
+ const QString &text,
+ const QString &value,
+ bool checked)
{
m_serviceModel->insertRow(0);
m_serviceModel->setData(index, value, ServiceModel::DesktopEntryNameRole);
m_serviceModel->setData(index, checked, Qt::CheckStateRole);
}
-
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
-#ifndef SERVICESSETTINGSPAGE_H
-#define SERVICESSETTINGSPAGE_H
+#ifndef CONTEXTMENUSETTINGSPAGE_H
+#define CONTEXTMENUSETTINGSPAGE_H
#include "settings/settingspagebase.h"
+#include <KActionCollection>
+
#include <QString>
class QListView;
class QLineEdit;
/**
- * @brief Page for the 'Services' settings of the Dolphin settings dialog.
+ * @brief Configurations for services in the context menu.
*/
-class ServicesSettingsPage : public SettingsPageBase
+class ContextMenuSettingsPage : public SettingsPageBase
{
Q_OBJECT
public:
- explicit ServicesSettingsPage(QWidget* parent);
- ~ServicesSettingsPage() override;
+ explicit ContextMenuSettingsPage(QWidget* parent,
+ const KActionCollection* actions,
+ const QStringList& actionIds);
+ ~ContextMenuSettingsPage() override;
/** @see SettingsPageBase::applySettings() */
void applySettings() override;
const QString &text,
const QString &value,
bool checked);
+ bool entryVisible(const QString& id);
+ void setEntryVisible(const QString& id, bool visible);
private:
bool m_initialized;
QListView* m_listView;
QLineEdit *m_searchLineEdit;
QStringList m_enabledVcsPlugins;
+ const KActionCollection* m_actions;
+ const QStringList m_actionIds;
};
#endif
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE kcfg SYSTEM "http://www.kde.org/standards/kcfg/1.0/kcfg.dtd">
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd">
+ <kcfgfile name="dolphinrc"/>
+ <group name="ContextMenu">
+ <entry name="ShowCopyMoveMenu" type="Bool">
+ <label>Show 'Copy To' and 'Move To' commands in context menu</label>
+ <default>false</default>
+ </entry>
+ <entry name="ShowAddToPlaces" type="Bool">
+ <label>Show 'Add to Places' in context menu.</label>
+ <default>true</default>
+ </entry>
+ <entry name="ShowSortBy" type="Bool">
+ <label>Show 'Sort By' in context menu.</label>
+ <default>true</default>
+ </entry>
+ <entry name="ShowViewMode" type="Bool">
+ <label>Show 'View Mode' in context menu.</label>
+ <default>true</default>
+ </entry>
+ <entry name="ShowOpenInNewTab" type="Bool">
+ <label>Show 'Open in New Tab' and 'Open in New Tabs' in context menu.</label>
+ <default>true</default>
+ </entry>
+ <entry name="ShowOpenInNewWindow" type="Bool">
+ <label>Show 'Open in New Window' in context menu.</label>
+ <default>true</default>
+ </entry>
+ <entry name="ShowCopyLocation" type="Bool">
+ <label>Show 'Copy Location' in context menu.</label>
+ <default>true</default>
+ </entry>
+ <entry name="ShowDuplicateHere" type="Bool">
+ <label>Show 'Duplicate Here' in context menu.</label>
+ <default>true</default>
+ </entry>
+ </group>
+</kcfg>
--- /dev/null
+File=dolphin_contextmenusettings.kcfg
+ClassName=ContextMenuSettings
+Singleton=yes
+Mutators=true
<label>Recursive directory size limit</label>
<default>10</default>
</entry>
+ <entry name="UseShortRelativeDates" type="Bool">
+ <label>if true we use short relative dates, if not short dates</label>
+ <default>true</default>
+ </entry>
</group>
</kcfg>
<label>Close active pane when toggling off split view</label>
<default>true</default>
</entry>
- <entry name="ShowToolTips" type="Bool">
- <label>Show tooltips</label>
+ <entry name="OpenNewTabAfterLastTab" type="Bool">
+ <label>New tab will be open after last one</label>
<default>false</default>
</entry>
- <entry name="ShowCopyMoveMenu" type="Bool">
- <label>Show 'Copy To' and 'Move To' commands in context menu</label>
+ <entry name="ShowToolTips" type="Bool">
+ <label>Show tooltips</label>
<default>false</default>
</entry>
<entry name="ViewPropsTimestamp" type="DateTime" >
#include "dolphinmainwindow.h"
#include "general/generalsettingspage.h"
#include "navigation/navigationsettingspage.h"
-#include "services/servicessettingspage.h"
+#include "contextmenu/contextmenusettingspage.h"
#include "startup/startupsettingspage.h"
#include "trash/trashsettingspage.h"
#include "viewmodes/viewsettingspage.h"
#include <QCloseEvent>
#include <QPushButton>
-DolphinSettingsDialog::DolphinSettingsDialog(const QUrl& url, QWidget* parent) :
+DolphinSettingsDialog::DolphinSettingsDialog(const QUrl& url, QWidget* parent, KActionCollection* actions) :
KPageDialog(parent),
m_pages(),
m_unsavedChanges(false)
navigationSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-navigation")));
connect(navigationSettingsPage, &NavigationSettingsPage::changed, this, &DolphinSettingsDialog::enableApply);
- // Services
- ServicesSettingsPage* servicesSettingsPage = new ServicesSettingsPage(this);
- KPageWidgetItem* servicesSettingsFrame = addPage(servicesSettingsPage,
- i18nc("@title:group", "Services"));
- servicesSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("preferences-system-services")));
- connect(servicesSettingsPage, &ServicesSettingsPage::changed, this, &DolphinSettingsDialog::enableApply);
+ // Context Menu
+ auto contextMenuSettingsPage = new ContextMenuSettingsPage(this, actions, {
+ QStringLiteral("add_to_places"),
+ QStringLiteral("sort"),
+ QStringLiteral("view_mode"),
+ QStringLiteral("open_in_new_tab"),
+ QStringLiteral("open_in_new_window"),
+ QStringLiteral("copy_location"),
+ QStringLiteral("duplicate")
+ });
+ KPageWidgetItem* contextMenuSettingsFrame = addPage(contextMenuSettingsPage,
+ i18nc("@title:group", "Context Menu"));
+ contextMenuSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("application-menu")));
+ connect(contextMenuSettingsPage, &ContextMenuSettingsPage::changed, this, &DolphinSettingsDialog::enableApply);
// Trash
SettingsPageBase* trashSettingsPage = nullptr;
m_pages.append(startupSettingsPage);
m_pages.append(viewSettingsPage);
m_pages.append(navigationSettingsPage);
- m_pages.append(servicesSettingsPage);
+ m_pages.append(contextMenuSettingsPage);
if (trashSettingsPage) {
m_pages.append(trashSettingsPage);
}
#define DOLPHINSETTINGSDIALOG_H
#include <KPageDialog>
+#include <KActionCollection>
class QUrl;
class SettingsPageBase;
Q_OBJECT
public:
- explicit DolphinSettingsDialog(const QUrl& url, QWidget* parent = nullptr);
+ explicit DolphinSettingsDialog(const QUrl& url, QWidget* parent = nullptr, KActionCollection* actions = {});
~DolphinSettingsDialog() override;
signals:
setMinimumWidth(400);
auto layout = new QVBoxLayout(this);
- setLayout(layout);
if (previewPlugin) {
auto configurationWidget = previewPlugin->createConfigurationWidget();
layout->addWidget(buttonBox);
auto okButton = buttonBox->button(QDialogButtonBox::Ok);
- okButton->setShortcut(Qt::CTRL + Qt::Key_Return);
+ okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
okButton->setDefault(true);
}
#include <KLocalizedString>
#include <KPluginFactory>
-#include <KPluginLoader>
#include <kconfigwidgets_version.h>
#include <QTabWidget>
#include <kconfigwidgets_version.h>
#include <KPluginFactory>
-#include <KPluginLoader>
#include <QVBoxLayout>
+++ /dev/null
-/*
- * SPDX-FileCopyrightText: 2009 Peter Penz <peter.penz19@gmail.com>
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#include "kcmdolphinservices.h"
-
-#include "settings/services/servicessettingspage.h"
-
-#include <kconfigwidgets_version.h>
-#include <KPluginFactory>
-#include <KPluginLoader>
-
-#include <QVBoxLayout>
-
-K_PLUGIN_FACTORY(KCMDolphinServicesConfigFactory, registerPlugin<DolphinServicesConfigModule>(QStringLiteral("dolphinservices"));)
-
-DolphinServicesConfigModule::DolphinServicesConfigModule(QWidget* parent, const QVariantList& args) :
- KCModule(parent, args),
- m_services(nullptr)
-{
- setButtons(KCModule::Default | KCModule::Help);
-
- QVBoxLayout* topLayout = new QVBoxLayout(this);
- topLayout->setContentsMargins(0, 0, 0, 0);
-
- m_services = new ServicesSettingsPage(this);
- connect(m_services, &ServicesSettingsPage::changed, this, &DolphinServicesConfigModule::markAsChanged);
- topLayout->addWidget(m_services, 0, {});
-}
-
-DolphinServicesConfigModule::~DolphinServicesConfigModule()
-{
-}
-
-void DolphinServicesConfigModule::save()
-{
- m_services->applySettings();
-}
-
-void DolphinServicesConfigModule::defaults()
-{
- m_services->restoreDefaults();
-}
-
-#include "kcmdolphinservices.moc"
+++ /dev/null
-Name=Dolphin Services
-Name[ar]=خدمات دولفين
-Name[ast]=Servicios de Dolphin
-Name[az]=Dolphin xidmətləri
-Name[ca]=Serveis del Dolphin
-Name[ca@valencia]=Serveis del Dolphin
-Name[cs]=Služby Dolphinu
-Name[da]=Dolphin-tjenester
-Name[de]=Dolphin-Dienste
-Name[el]=Dolphin Υπηρεσίες
-Name[en_GB]=Dolphin Services
-Name[es]=Servicios de Dolphin
-Name[et]=Dolphini teenused
-Name[eu]=Dolphin zerbitzuak
-Name[fi]=Dolphin – palvelut
-Name[fr]=Services de Dolphin
-Name[gl]=Servizos de Dolphin
-Name[he]=שרותי Dolphin
-Name[hu]=Dolphin szolgáltatások
-Name[ia]=Servicios de Dolphin
-Name[id]=Layanan Dolphin
-Name[it]=Servizi di Dolphin
-Name[ja]=Dolphin サービス
-Name[ko]=Dolphin 서비스
-Name[lt]=Dolphin paslaugos
-Name[lv]=Dolphin servisi
-Name[ml]=ഡോള്ഫിന് സേവനങ്ങള്
-Name[nb]=Dolphin-tjenester
-Name[nl]=Dolphin-services
-Name[nn]=Dolphin-tenester
-Name[pa]=ਡਾਲਫਿਨ ਸੇਵਾਵਾਂ
-Name[pl]=Usługi Dolphina
-Name[pt]=Serviços do Dolphin
-Name[pt_BR]=Serviços do Dolphin
-Name[ro]=Dolphin – Servicii
-Name[ru]=Действия Dolphin
-Name[sk]=Služby Dolphinu
-Name[sl]=Dolphin - storitve
-Name[sr]=Делфинови сервиси
-Name[sr@ijekavian]=Делфинови сервиси
-Name[sr@ijekavianlatin]=Dolphinovi servisi
-Name[sr@latin]=Dolphinovi servisi
-Name[sv]=Dolphin tjänster
-Name[tr]=Dolphin Servisleri
-Name[uk]=Служби Dolphin
-Name[vi]=Các dịch vụ Dolphin
-Name[x-test]=xxDolphin Servicesxx
-Name[zh_CN]=Dolphin 服务
-Name[zh_TW]=Dolphin 服務
-
-[Desktop Entry]
-Icon=preferences-system-services
-Type=Service
-X-KDE-ServiceTypes=KCModule
-
-X-KDE-Library=kcm_dolphinservices
-X-KDE-PluginKeyword=dolphinservices
-X-DocPath=dolphin/index.html#preferences-dialog-services
-Name=Services
-Name[ar]=الخدمات
-Name[ast]=Servicios
-Name[az]=Xidmətlər
-Name[ca]=Serveis
-Name[ca@valencia]=Serveis
-Name[cs]=Služby
-Name[da]=Tjenester
-Name[de]=KDE-Dienste
-Name[el]=Υπηρεσίες
-Name[en_GB]=Services
-Name[es]=Servicios
-Name[et]=Teenused
-Name[eu]=Zerbitzuak
-Name[fi]=Palvelut
-Name[fr]=Services
-Name[gl]=Servizos
-Name[he]=שירותים
-Name[hu]=Szolgáltatások
-Name[ia]=Servicios
-Name[id]=Layanan
-Name[it]=Servizi
-Name[ja]=サービス
-Name[ko]=서비스
-Name[lt]=Paslaugos
-Name[lv]=Servisi
-Name[ml]=സേവനങ്ങള്
-Name[nb]=Tjenester
-Name[nl]=Services
-Name[nn]=Tenester
-Name[pa]=ਸੇਵਾਵਾਂ
-Name[pl]=Usługi
-Name[pt]=Serviços
-Name[pt_BR]=Serviços
-Name[ro]=Servicii
-Name[ru]=Действия
-Name[sk]=Služby
-Name[sl]=Storitve
-Name[sr]=Сервиси
-Name[sr@ijekavian]=Сервиси
-Name[sr@ijekavianlatin]=Servisi
-Name[sr@latin]=Servisi
-Name[sv]=Tjänster
-Name[tr]=Servisler
-Name[uk]=Служби
-Name[vi]=Các dịch vụ
-Name[x-test]=xxServicesxx
-Name[zh_CN]=服务
-Name[zh_TW]=服務
-Comment=Configure file manager services
-Comment[ar]=اضبط خدمات مدير الملفّات
-Comment[ast]=Configura los servicios del xestor de ficheros
-Comment[az]=Fayl meneceri xidmətlərini tənzimləmək
-Comment[ca]=Configura els serveis del gestor de fitxers
-Comment[ca@valencia]=Configura els serveis del gestor de fitxers
-Comment[cs]=Nastavení služeb správce souborů
-Comment[da]=Indstil filhåndteringstjenester
-Comment[de]=Dateiverwaltungs-Dienste einrichten
-Comment[el]=Διαμόρφωση υπηρεσιών του διαχειριστή αρχείων
-Comment[en_GB]=Configure file manager services
-Comment[es]=Configurar los servicios del gestor de archivos
-Comment[et]=Failihalduri teenuste seadistamine
-Comment[eu]=Konfiguratu fitxategi-kudeatzailearen zerbitzuak
-Comment[fi]=Tiedostonhallinnan palveluasetukset
-Comment[fr]=Configuration des services du gestionnaire de fichiers
-Comment[gl]=Configurar servizos de xestores de ficheiros.
-Comment[hu]=A fájlkezelő szolgáltatásainak beállítása
-Comment[ia]=Configura servicios del gerente de file
-Comment[id]=Konfigurasikan layanan pengelola file
-Comment[it]=Configura i servizi del gestore dei file
-Comment[ja]=ファイルマネージャのサービスを設定します
-Comment[ko]=파일 관리자 서비스 구성
-Comment[lt]=Konfigūruoti failų tvarkytuvės paslaugas
-Comment[lv]=Konfigurēt datņu pārvaldnieka servisus
-Comment[ml]=ഫയല് മാനേജർ സേവനങ്ങള് ക്രമീകരിയ്ക്കുക
-Comment[nb]=Sett opp tjenester i filbehandleren
-Comment[nl]=Bestandsbeheerderservices configureren
-Comment[nn]=Set opp tenester i filhandsamaren
-Comment[pa]=ਫਾਇਲ ਮੈਨੇਜਰ ਦੀਆਂ ਸਰਵਿਸਾਂ ਦੀ ਸੰਰਚਨਾ
-Comment[pl]=Ustawienia usług zarządzania plikami
-Comment[pt]=Configurar os serviços do gestor de ficheiros
-Comment[pt_BR]=Configura os serviços do gerenciador de arquivos
-Comment[ro]=Configurează serviciile gestionarului de fișiere
-Comment[ru]=Настройка действий в диспетчере файлов
-Comment[sk]=Nastavenie služieb správcu súborov
-Comment[sl]=Nastavitve storitev upravljalnika datotek
-Comment[sr]=Подешавање сервиса менаџера фајлова
-Comment[sr@ijekavian]=Подешавање сервиса менаџера фајлова
-Comment[sr@ijekavianlatin]=Podešavanje servisa menadžera fajlova
-Comment[sr@latin]=Podešavanje servisa menadžera fajlova
-Comment[sv]=Anpassa filhanterarens tjänster
-Comment[tr]=Dosya yöneticisi servislerini yapılandır
-Comment[uk]=Налаштувати служби менеджера файлів
-Comment[vi]=Cấu hình các dịch vụ trình quản lí tệp
-Comment[x-test]=xxConfigure file manager servicesxx
-Comment[zh_CN]=配置文件管理器服务
-Comment[zh_TW]=設定檔案管理員服務
-X-KDE-Keywords=file manager
-X-KDE-Keywords[ar]=مدير ملفّات ملفات الملفّات الملفات
-X-KDE-Keywords[ast]=xestor de ficheros
-X-KDE-Keywords[az]=fayl meneceri
-X-KDE-Keywords[ca]=gestor de fitxers
-X-KDE-Keywords[ca@valencia]=gestor de fitxers
-X-KDE-Keywords[cs]=správce souborů
-X-KDE-Keywords[da]=filhåndtering
-X-KDE-Keywords[de]=Dateiverwaltung
-X-KDE-Keywords[el]=διαχειριστής αρχείων
-X-KDE-Keywords[en_GB]=file manager
-X-KDE-Keywords[es]=gestor de archivos
-X-KDE-Keywords[et]=failihaldur
-X-KDE-Keywords[eu]=Fitxategi-kudeatzailea
-X-KDE-Keywords[fi]=tiedostonhallinta
-X-KDE-Keywords[fr]=gestionnaire de fichiers
-X-KDE-Keywords[gl]=xestor de ficheiros
-X-KDE-Keywords[he]=מנהל קבצים
-X-KDE-Keywords[hu]=fájlkezelő
-X-KDE-Keywords[ia]=gerente de file
-X-KDE-Keywords[id]=pengelola file
-X-KDE-Keywords[it]=gestore dei file
-X-KDE-Keywords[ja]=ファイルマネージャ
-X-KDE-Keywords[ko]=파일 관리자
-X-KDE-Keywords[lt]=failų tvarkytuvė
-X-KDE-Keywords[lv]=datņu pārvaldnieks
-X-KDE-Keywords[ml]=ഫയൽ മാനേജർ
-X-KDE-Keywords[nb]=filbehandler
-X-KDE-Keywords[nl]=bestandsbeheerder
-X-KDE-Keywords[nn]=filhandsamar
-X-KDE-Keywords[pa]=ਫਾਇਲ ਮੈਨੇਜਰ
-X-KDE-Keywords[pl]=zarządzanie plikami
-X-KDE-Keywords[pt]=gestor de ficheiros
-X-KDE-Keywords[pt_BR]=gerenciador de arquivos
-X-KDE-Keywords[ro]=gestionar de fișiere
-X-KDE-Keywords[ru]=диспетчер файлов
-X-KDE-Keywords[sk]=správca súborov
-X-KDE-Keywords[sl]=upravljalnik datotek
-X-KDE-Keywords[sr]=file manager,менаџер фајлова
-X-KDE-Keywords[sr@ijekavian]=file manager,менаџер фајлова
-X-KDE-Keywords[sr@ijekavianlatin]=file manager,menadžer fajlova
-X-KDE-Keywords[sr@latin]=file manager,menadžer fajlova
-X-KDE-Keywords[sv]=filhanterare
-X-KDE-Keywords[tr]=dosya yöneticisi
-X-KDE-Keywords[uk]=менеджер,керування,файл,файли
-X-KDE-Keywords[vi]=file manager,trình quản lí tệp
-X-KDE-Keywords[x-test]=xxfile managerxx
-X-KDE-Keywords[zh_CN]=文件管理器
-X-KDE-Keywords[zh_TW]=檔案管理員
+++ /dev/null
-/*
- * SPDX-FileCopyrightText: 2009 Peter Penz <peter.penz19@gmail.com>
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#ifndef KCMDOLPHINSERVICES_H
-#define KCMDOLPHINSERVICES_H
-
-#include <KCModule>
-
-class ServicesSettingsPage;
-
-/**
- * @brief Allow to configure the Dolphin services.
- */
-class DolphinServicesConfigModule : public KCModule
-{
- Q_OBJECT
-
-public:
- DolphinServicesConfigModule(QWidget* parent, const QVariantList& args);
- ~DolphinServicesConfigModule() override;
-
- void save() override;
- void defaults() override;
-
-private:
- ServicesSettingsPage *m_services;
-};
-
-#endif
#include <KLocalizedString>
#include <KPluginFactory>
-#include <KPluginLoader>
#include <QDBusConnection>
#include <QDBusMessage>
#include "navigationsettingspage.h"
+#include "global.h"
#include "dolphin_generalsettings.h"
#include <KLocalizedString>
+#include <QButtonGroup>
#include <QCheckBox>
+#include <QFormLayout>
+#include <QRadioButton>
#include <QVBoxLayout>
NavigationSettingsPage::NavigationSettingsPage(QWidget* parent) :
SettingsPageBase(parent),
m_openArchivesAsFolder(nullptr),
- m_autoExpandFolders(nullptr)
+ m_autoExpandFolders(nullptr),
+ m_openNewTabAfterLastTab(nullptr),
+ m_openNewTabAfterCurrentTab(nullptr)
{
- QVBoxLayout* topLayout = new QVBoxLayout(this);
- QWidget* vBox = new QWidget(this);
- QVBoxLayout *vBoxLayout = new QVBoxLayout(vBox);
- vBoxLayout->setContentsMargins(0, 0, 0, 0);
- vBoxLayout->setAlignment(Qt::AlignTop);
+ QFormLayout* topLayout = new QFormLayout(this);
- m_openArchivesAsFolder = new QCheckBox(i18nc("@option:check", "Open archives as folder"), vBox);
- vBoxLayout->addWidget(m_openArchivesAsFolder);
+ // Tabs properties
+ m_openNewTabAfterCurrentTab = new QRadioButton(i18nc("option:radio", "After current tab"));
+ m_openNewTabAfterLastTab = new QRadioButton(i18nc("option:radio", "At end of tab bar"));
+ QButtonGroup* tabsBehaviorGroup = new QButtonGroup(this);
+ tabsBehaviorGroup->addButton(m_openNewTabAfterCurrentTab);
+ tabsBehaviorGroup->addButton(m_openNewTabAfterLastTab);
+ topLayout->addRow(i18nc("@title:group", "Open new tabs: "), m_openNewTabAfterCurrentTab);
+ topLayout->addRow(QString(), m_openNewTabAfterLastTab);
- m_autoExpandFolders = new QCheckBox(i18nc("option:check", "Open folders during drag operations"), vBox);
- vBoxLayout->addWidget(m_autoExpandFolders);
+ topLayout->addItem(new QSpacerItem(0, Dolphin::VERTICAL_SPACER_HEIGHT, QSizePolicy::Fixed, QSizePolicy::Fixed));
- topLayout->addWidget(vBox);
+ m_openArchivesAsFolder = new QCheckBox(i18nc("@option:check", "Open archives as folder"));
+ m_autoExpandFolders = new QCheckBox(i18nc("option:check", "Open folders during drag operations"));
+ topLayout->addRow(i18nc("@title:group", "General: "), m_openArchivesAsFolder);
+ topLayout->addRow(QString(), m_autoExpandFolders);
loadSettings();
connect(m_openArchivesAsFolder, &QCheckBox::toggled, this, &NavigationSettingsPage::changed);
connect(m_autoExpandFolders, &QCheckBox::toggled, this, &NavigationSettingsPage::changed);
+ connect(m_openNewTabAfterCurrentTab, &QRadioButton::toggled, this, &NavigationSettingsPage::changed);
+ connect(m_openNewTabAfterLastTab, &QRadioButton::toggled, this, &NavigationSettingsPage::changed);
}
NavigationSettingsPage::~NavigationSettingsPage()
GeneralSettings* settings = GeneralSettings::self();
settings->setBrowseThroughArchives(m_openArchivesAsFolder->isChecked());
settings->setAutoExpandFolders(m_autoExpandFolders->isChecked());
+ settings->setOpenNewTabAfterLastTab(m_openNewTabAfterLastTab->isChecked());
settings->save();
}
{
m_openArchivesAsFolder->setChecked(GeneralSettings::browseThroughArchives());
m_autoExpandFolders->setChecked(GeneralSettings::autoExpandFolders());
+ m_openNewTabAfterLastTab->setChecked(GeneralSettings::openNewTabAfterLastTab());
+ m_openNewTabAfterCurrentTab->setChecked(!m_openNewTabAfterLastTab->isChecked());
}
#include "settings/settingspagebase.h"
class QCheckBox;
+class QRadioButton;
/**
* @brief Page for the 'Navigation' settings of the Dolphin settings dialog.
private:
QCheckBox* m_openArchivesAsFolder;
QCheckBox* m_autoExpandFolders;
+ QRadioButton* m_openNewTabAfterLastTab;
+ QRadioButton* m_openNewTabAfterCurrentTab;
};
#endif
#include <KLocalizedString>
#include <KMessageBox>
+#include <KProtocolManager>
#include <QButtonGroup>
#include <QCheckBox>
GeneralSettings* settings = GeneralSettings::self();
const QUrl url(QUrl::fromUserInput(m_homeUrl->text(), QString(), QUrl::AssumeLocalFile));
- KFileItem fileItem(url);
- if ((url.isValid() && fileItem.isDir()) || (url.scheme() == QLatin1String("timeline"))) {
- settings->setHomeUrl(url.toDisplayString(QUrl::PreferLocalFile));
+ if (url.isValid() && KProtocolManager::supportsListing(url)) {
+ KIO::StatJob* job = KIO::statDetails(url, KIO::StatJob::SourceSide, KIO::StatDetail::StatBasic, KIO::JobFlag::HideProgressInfo);
+ connect(job, &KJob::result, this, [this, settings, url](KJob* job) {
+ if (job->error() == 0 && qobject_cast<KIO::StatJob*>(job)->statResult().isDir()) {
+ settings->setHomeUrl(url.toDisplayString(QUrl::PreferLocalFile));
+ } else {
+ showSetDefaultDirectoryError();
+ }
+ });
} else {
- KMessageBox::error(this, i18nc("@info", "The location for the home folder is invalid or does not exist, it will not be applied."));
+ showSetDefaultDirectoryError();
}
// Remove saved state if "remember open tabs" has been turned off
m_showFullPathInTitlebar->setChecked(GeneralSettings::showFullPathInTitlebar());
m_openExternallyCalledFolderInNewTab->setChecked(GeneralSettings::openExternallyCalledFolderInNewTab());
}
+
+void StartupSettingsPage::showSetDefaultDirectoryError()
+{
+ KMessageBox::error(this, i18nc("@info", "The location for the home folder is invalid or does not exist, it will not be applied."));
+}
private:
void loadSettings();
+ void showSetDefaultDirectoryError();
private:
QUrl m_url;
#include "views/zoomlevelinfo.h"
#include <KLocalizedString>
+#include <KFormat>
#include <QApplication>
#include <QCheckBox>
m_widthBox(nullptr),
m_maxLinesBox(nullptr),
m_expandableFolders(nullptr),
- m_recursiveDirectorySizeLimit(nullptr)
+ m_recursiveDirectorySizeLimit(nullptr),
+ m_useRelatetiveDates(nullptr),
+ m_useShortDates(nullptr)
{
QFormLayout* topLayout = new QFormLayout(this);
topLayout->addRow(i18nc("@title:group", "Folder size displays:"), m_numberOfItems);
topLayout->addRow(QString(), contentsSizeLayout);
#endif
+
+ QDateTime thirtyMinutesAgo = QDateTime::currentDateTime().addSecs(-30 * 60);
+ QLocale local;
+ KFormat formatter(local);
+
+ m_useRelatetiveDates = new QRadioButton(i18nc(
+ "option:radio as in relative date", "Relative (e.g. '%1')", formatter.formatRelativeDateTime(thirtyMinutesAgo, QLocale::ShortFormat))
+ );
+ m_useShortDates = new QRadioButton(
+ i18nc("option:radio as in absolute date", "Absolute (e.g. '%1')", local.toString(thirtyMinutesAgo, QLocale::ShortFormat))
+ );
+
+ QButtonGroup* dateFormatGroup = new QButtonGroup(this);
+ dateFormatGroup->addButton(m_useRelatetiveDates);
+ dateFormatGroup->addButton(m_useShortDates);
+
+ topLayout->addRow(i18nc("@title:group", "Date style:"), m_useRelatetiveDates);
+ topLayout->addRow(QString(), m_useShortDates);
+
break;
}
m_recursiveDirectorySizeLimit->setEnabled(m_sizeOfContents->isChecked());
});
#endif
+ connect(m_useRelatetiveDates, &QRadioButton::toggled, this, &ViewSettingsTab::changed);
+ connect(m_useShortDates, &QRadioButton::toggled, this, &ViewSettingsTab::changed);
break;
default:
break;
DetailsModeSettings::setDirectorySizeCount(m_numberOfItems->isChecked());
DetailsModeSettings::setRecursiveDirectorySizeLimit(m_recursiveDirectorySizeLimit->value());
#endif
+ DetailsModeSettings::setUseShortRelativeDates(m_useRelatetiveDates->isChecked());
break;
default:
break;
}
m_recursiveDirectorySizeLimit->setValue(DetailsModeSettings::recursiveDirectorySizeLimit());
#endif
+ m_useRelatetiveDates->setChecked(DetailsModeSettings::useShortRelativeDates());
+ m_useShortDates->setChecked(!DetailsModeSettings::useShortRelativeDates());
break;
default:
break;
QRadioButton* m_numberOfItems;
QRadioButton* m_sizeOfContents;
QSpinBox* m_recursiveDirectorySizeLimit;
+ QRadioButton* m_useRelatetiveDates;
+ QRadioButton* m_useShortDates;
};
#endif
auto layout = new QFormLayout(this);
// Otherwise the dialog won't resize when we collapse the KCollapsibleGroupBox.
layout->setSizeConstraint(QLayout::SetFixedSize);
- setLayout(layout);
// create 'Properties' group containing view mode, sorting, sort order and show hidden files
m_viewMode = new QComboBox();
auto additionalInfoBox = new KCollapsibleGroupBox();
additionalInfoBox->setTitle(i18nc("@title:group", "Additional Information"));
- auto innerLayout = new QVBoxLayout();
+ auto innerLayout = new QVBoxLayout(additionalInfoBox);
{
QList<QByteArray> visibleRoles = m_viewProps->visibleRoles();
innerLayout->addWidget(m_listWidget);
}
- additionalInfoBox->setLayout(innerLayout);
-
QHBoxLayout* sortingLayout = new QHBoxLayout();
sortingLayout->setContentsMargins(0, 0, 0, 0);
sortingLayout->addWidget(m_sortOrder);
layout->addWidget(buttonBox);
auto okButton = buttonBox->button(QDialogButtonBox::Ok);
- okButton->setShortcut(Qt::CTRL + Qt::Key_Return);
+ okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
okButton->setDefault(true);
auto applyButton = buttonBox->button(QDialogButtonBox::Apply);
m_viewProps->setAutoSaveEnabled(false);
auto layout = new QVBoxLayout(this);
- setLayout(layout);
m_label = new QLabel(i18nc("@info:progress", "Counting folders: %1", 0), this);
layout->addWidget(m_label);
m_text(),
m_defaultText(),
m_label(nullptr),
+ m_zoomLabel(nullptr),
m_spaceInfo(nullptr),
m_zoomSlider(nullptr),
m_progressBar(nullptr),
m_label->setWordWrap(true);
m_label->setTextFormat(Qt::PlainText);
+ // Initialize zoom slider's explanatory label
+ m_zoomLabel = new QLabel(i18nc("Used as a noun, i.e. 'Here is the zoom level:'","Zoom:"), this);
+
// Initialize zoom widget
m_zoomSlider = new QSlider(Qt::Horizontal, this);
m_zoomSlider->setAccessibleName(i18n("Zoom"));
m_label->setFixedHeight(contentHeight);
m_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- m_zoomSlider->setMaximumWidth(fontMetrics.averageCharWidth() * 25);
+ m_zoomSlider->setMaximumWidth(fontMetrics.averageCharWidth() * 15);
m_spaceInfo->setFixedHeight(contentHeight);
m_spaceInfo->setMaximumWidth(fontMetrics.averageCharWidth() * 25);
m_spaceInfo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_progressBar->setFixedHeight(zoomSliderHeight);
- m_progressBar->setMaximumWidth(fontMetrics.averageCharWidth() * 25);
+ m_progressBar->setMaximumWidth(fontMetrics.averageCharWidth() * 20);
QHBoxLayout* topLayout = new QHBoxLayout(this);
topLayout->setContentsMargins(2, 0, 2, 0);
topLayout->setSpacing(4);
topLayout->addWidget(m_label, 1);
+ topLayout->addWidget(m_zoomLabel);
topLayout->addWidget(m_zoomSlider, 1);
topLayout->addWidget(m_spaceInfo, 1);
topLayout->addWidget(m_stopButton);
m_spaceInfo->setShown(showSpaceInfo);
m_spaceInfo->setVisible(showSpaceInfo);
m_zoomSlider->setVisible(showZoomSlider);
+ m_zoomLabel->setVisible(showZoomSlider);
}
QString m_text;
QString m_defaultText;
KSqueezedTextLabel* m_label;
+ QLabel* m_zoomLabel;
StatusBarSpaceInfo* m_spaceInfo;
QSlider* m_zoomSlider;
ecm_add_test(draganddrophelpertest.cpp LINK_LIBRARIES dolphinprivate Qt5::Test)
# PlacesItemModelTest
-if (KF5_VERSION VERSION_GREATER_EQUAL 5.63.0)
- ecm_add_test(placesitemmodeltest.cpp
- TEST_NAME placesitemmodeltest
- LINK_LIBRARIES dolphinprivate dolphinstatic Qt5::Test)
-endif()
+ecm_add_test(placesitemmodeltest.cpp
+TEST_NAME placesitemmodeltest
+LINK_LIBRARIES dolphinprivate dolphinstatic Qt5::Test)
find_gem(test-unit)
set_package_properties(Gem:test-unit PROPERTIES
DESCRIPTION "Ruby gem 'test-unit' required for testing of servicemenu helpers.")
if (Gem:test-unit_FOUND)
add_test(NAME servicemenutest
- COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../settings/services/test/test_run.rb)
+ COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../settings/contextmenu/test/test_run.rb)
endif()
#include <QApplication>
#include <QClipboard>
#include <QDropEvent>
+#include <QGraphicsOpacityEffect>
#include <QGraphicsSceneDragDropEvent>
+#include <QLabel>
#include <QMenu>
#include <QMimeDatabase>
#include <QPixmapCache>
m_assureVisibleCurrentIndex(false),
m_isFolderWritable(true),
m_dragging(false),
+ m_loading(false),
m_url(url),
m_viewPropertiesContext(),
m_mode(DolphinView::IconsView),
m_clearSelectionBeforeSelectingNewItems(false),
m_markFirstNewlySelectedItemAsCurrent(false),
m_versionControlObserver(nullptr),
- m_twoClicksRenamingTimer(nullptr)
+ m_twoClicksRenamingTimer(nullptr),
+ m_placeholderLabel(nullptr)
{
m_topLayout = new QVBoxLayout(this);
m_topLayout->setSpacing(0);
connect(m_container->horizontalScrollBar(), &QScrollBar::valueChanged, this, [=] { hideToolTip(); });
connect(m_container->verticalScrollBar(), &QScrollBar::valueChanged, this, [=] { hideToolTip(); });
+ // Show some placeholder text for empty folders
+ // This is made using a heavily-modified QLabel rather than a KTitleWidget
+ // because KTitleWidget can't be told to turn off mouse-selectable text
+ m_placeholderLabel = new QLabel(this);
+ QFont placeholderLabelFont;
+ // To match the size of a level 2 Heading/KTitleWidget
+ placeholderLabelFont.setPointSize(qRound(placeholderLabelFont.pointSize() * 1.3));
+ m_placeholderLabel->setFont(placeholderLabelFont);
+ m_placeholderLabel->setTextInteractionFlags(Qt::NoTextInteraction);
+ m_placeholderLabel->setWordWrap(true);
+ m_placeholderLabel->setAlignment(Qt::AlignCenter);
+ // Match opacity of QML placeholder label component
+ auto *effect = new QGraphicsOpacityEffect(m_placeholderLabel);
+ effect->setOpacity(0.5);
+ m_placeholderLabel->setGraphicsEffect(effect);
+ // Set initial text and visibility
+ updatePlaceholderLabel();
+
+ auto *centeringLayout = new QVBoxLayout(m_container);
+ centeringLayout->addWidget(m_placeholderLabel);
+ centeringLayout->setAlignment(m_placeholderLabel, Qt::AlignCenter);
+
controller->setSelectionBehavior(KItemListController::MultiSelection);
connect(controller, &KItemListController::itemActivated, this, &DolphinView::slotItemActivated);
connect(controller, &KItemListController::itemsActivated, this, &DolphinView::slotItemsActivated);
connect(m_model, &KFileItemModel::directoryLoadingStarted, this, &DolphinView::slotDirectoryLoadingStarted);
connect(m_model, &KFileItemModel::directoryLoadingCompleted, this, &DolphinView::slotDirectoryLoadingCompleted);
- connect(m_model, &KFileItemModel::directoryLoadingCanceled, this, &DolphinView::directoryLoadingCanceled);
+ connect(m_model, &KFileItemModel::directoryLoadingCanceled, this, &DolphinView::slotDirectoryLoadingCanceled);
connect(m_model, &KFileItemModel::directoryLoadingProgress, this, &DolphinView::directoryLoadingProgress);
connect(m_model, &KFileItemModel::directorySortingProgress, this, &DolphinView::directorySortingProgress);
connect(m_model, &KFileItemModel::itemsChanged,
connect(m_model, &KFileItemModel::directoryRedirection, this, &DolphinView::slotDirectoryRedirection);
connect(m_model, &KFileItemModel::urlIsFileError, this, &DolphinView::urlIsFileError);
+ connect(this, &DolphinView::itemCountChanged,
+ this, &DolphinView::updatePlaceholderLabel);
+
m_view->installEventFilter(this);
connect(m_view, &DolphinItemListView::sortOrderChanged,
this, &DolphinView::slotSortOrderChangedByHeader);
const QUrl& url = openItemAsFolderUrl(item);
if (!url.isEmpty()) { // Open folders in new tabs
- Q_EMIT tabRequested(url, DolphinTabWidget::AfterLastTab);
+ Q_EMIT tabRequested(url);
} else {
items.append(item);
}
const KFileItem& item = m_model->fileItem(index);
const QUrl& url = openItemAsFolderUrl(item);
if (!url.isEmpty()) {
- Q_EMIT tabRequested(url, DolphinTabWidget::AfterCurrentTab);
+ Q_EMIT tabRequested(url);
} else if (isTabsForFilesEnabled()) {
- Q_EMIT tabRequested(item.url(), DolphinTabWidget::AfterCurrentTab);
+ Q_EMIT tabRequested(item.url());
}
}
void DolphinView::slotDirectoryLoadingStarted()
{
+ m_loading = true;
+ updatePlaceholderLabel();
+
// Disable the writestate temporary until it can be determined in a fast way
// in DolphinView::slotDirectoryLoadingCompleted()
if (m_isFolderWritable) {
void DolphinView::slotDirectoryLoadingCompleted()
{
+ m_loading = false;
+
// Update the view-state. This has to be done asynchronously
// because the view might not be in its final state yet.
QTimer::singleShot(0, this, &DolphinView::updateViewState);
+ // Update the placeholder label in case we found that the folder was empty
+ // after loading it
+
Q_EMIT directoryLoadingCompleted();
+ updatePlaceholderLabel();
updateWritableState();
}
+void DolphinView::slotDirectoryLoadingCanceled()
+{
+ m_loading = false;
+
+ updatePlaceholderLabel();
+
+ Q_EMIT directoryLoadingCanceled();
+}
+
void DolphinView::slotItemsChanged()
{
m_assureVisibleCurrentIndex = false;
{
Q_EMIT goUpRequested();
}
+
+void DolphinView::updatePlaceholderLabel()
+{
+ if (m_loading || itemsCount() > 0) {
+ m_placeholderLabel->setVisible(false);
+ return;
+ }
+
+ if (!nameFilter().isEmpty()) {
+ m_placeholderLabel->setText(i18n("No items matching the filter"));
+ } else if (m_url.scheme() == QLatin1String("baloosearch") || m_url.scheme() == QLatin1String("filenamesearch")) {
+ m_placeholderLabel->setText(i18n("No items matching the search"));
+ } else if (m_url.scheme() == QLatin1String("trash")) {
+ m_placeholderLabel->setText(i18n("Trash is empty"));
+ } else if (m_url.scheme() == QLatin1String("tags")) {
+ m_placeholderLabel->setText(i18n("No tags"));
+ } else if (m_url.scheme() == QLatin1String("recentlyused")) {
+ m_placeholderLabel->setText(i18n("No recently used items"));
+ } else if (m_url.scheme() == QLatin1String("smb")) {
+ m_placeholderLabel->setText(i18n("No shared folders found"));
+ } else if (m_url.scheme() == QLatin1String("network")) {
+ m_placeholderLabel->setText(i18n("No relevant network resources found"));
+ } else if (m_url.scheme() == QLatin1String("mtp")) {
+ m_placeholderLabel->setText(i18n("No MTP-compatible devices found"));
+ } else if (m_url.scheme() == QLatin1String("bluetooth")) {
+ m_placeholderLabel->setText(i18n("No Bluetooth devices found"));
+ } else {
+ m_placeholderLabel->setText(i18n("Folder is empty"));
+ }
+
+ m_placeholderLabel->setVisible(true);
+}
class ToolTipManager;
class VersionControlObserver;
class ViewProperties;
+class QLabel;
class QGraphicsSceneDragDropEvent;
class QRegularExpression;
/**
* Is emitted if a new tab should be opened for the URL \a url.
*/
- void tabRequested(const QUrl& url, DolphinTabWidget::TabPlacement tabPlacement);
+ void tabRequested(const QUrl& url);
/**
* Is emitted if the view mode (IconsView, DetailsView,
*/
void slotDirectoryLoadingCompleted();
+ /**
+ * Invoked when the file item model indicates that the loading of a directory has
+ * been canceled.
+ */
+ void slotDirectoryLoadingCanceled();
+
/**
* Is invoked when items of KFileItemModel have been changed.
*/
void abortTwoClicksRenaming();
+ void updatePlaceholderLabel();
+
private:
void updatePalette();
bool m_isFolderWritable;
bool m_dragging; // True if a dragging is done. Required to be able to decide whether a
// tooltip may be shown when hovering an item.
+ bool m_loading;
QUrl m_url;
QString m_viewPropertiesContext;
QTimer* m_twoClicksRenamingTimer;
QUrl m_twoClicksRenamingItemUrl;
+ QLabel* m_placeholderLabel;
// For unit tests
friend class TestBase;
#include "kitemviews/kfileitemmodel.h"
#include "settings/viewpropertiesdialog.h"
#include "views/zoomlevelinfo.h"
+#include "kconfig_version.h"
#ifdef HAVE_BALOO
#include <Baloo/IndexerConfig>
// KNewFileMenu takes care of the GUI stuff.
QAction* newDirAction = m_actionCollection->addAction(QStringLiteral("create_dir"));
newDirAction->setText(i18nc("@action", "Create Folder..."));
- m_actionCollection->setDefaultShortcut(newDirAction, Qt::Key_F10);
+ m_actionCollection->setDefaultShortcuts(newDirAction, KStandardShortcut::createFolder());
newDirAction->setIcon(QIcon::fromTheme(QStringLiteral("folder-new")));
newDirAction->setEnabled(false); // Will be enabled in slotWriteStateChanged(bool) if the current URL is writable
connect(newDirAction, &QAction::triggered, this, &DolphinViewActionHandler::createDirectoryTriggered);
"You can configure advanced options there like managing "
"read- and write-permissions."));
propertiesAction->setIcon(QIcon::fromTheme(QStringLiteral("document-properties")));
- m_actionCollection->setDefaultShortcuts(propertiesAction, {Qt::ALT + Qt::Key_Return, Qt::ALT + Qt::Key_Enter});
+ m_actionCollection->setDefaultShortcuts(propertiesAction, {Qt::ALT | Qt::Key_Return, Qt::ALT | Qt::Key_Enter});
connect(propertiesAction, &QAction::triggered, this, &DolphinViewActionHandler::slotProperties);
QAction *copyPathAction = m_actionCollection->addAction( QStringLiteral("copy_location") );
zoomResetAction->setToolTip(i18n("Zoom To Default"));
zoomResetAction->setWhatsThis(i18nc("@info:whatsthis zoom reset", "This resets the icon size to default."));
zoomResetAction->setIcon(QIcon::fromTheme(QStringLiteral("zoom-original")));
- m_actionCollection->setDefaultShortcuts(zoomResetAction, {Qt::CTRL + Qt::Key_0});
+ m_actionCollection->setDefaultShortcuts(zoomResetAction, {Qt::CTRL | Qt::Key_0});
connect(zoomResetAction, &QAction::triggered, this, &DolphinViewActionHandler::zoomReset);
QAction* zoomOutAction = KStandardAction::zoomOut(this,
KToggleAction* iconsView = m_actionCollection->add<KToggleAction>(QStringLiteral("icons"));
iconsView->setText(i18nc("@action:inmenu View Mode", "Icons"));
iconsView->setToolTip(i18nc("@info", "Icons view mode"));
- m_actionCollection->setDefaultShortcut(iconsView, Qt::CTRL + Qt::Key_1);
+ m_actionCollection->setDefaultShortcut(iconsView, Qt::CTRL | Qt::Key_1);
iconsView->setIcon(QIcon::fromTheme(QStringLiteral("view-list-icons")));
iconsView->setData(QVariant::fromValue(DolphinView::IconsView));
return iconsView;
KToggleAction* iconsView = m_actionCollection->add<KToggleAction>(QStringLiteral("compact"));
iconsView->setText(i18nc("@action:inmenu View Mode", "Compact"));
iconsView->setToolTip(i18nc("@info", "Compact view mode"));
- m_actionCollection->setDefaultShortcut(iconsView, Qt::CTRL + Qt::Key_2);
+ m_actionCollection->setDefaultShortcut(iconsView, Qt::CTRL | Qt::Key_2);
iconsView->setIcon(QIcon::fromTheme(QStringLiteral("view-list-details"))); // TODO: discuss with Oxygen-team the wrong (?) name
iconsView->setData(QVariant::fromValue(DolphinView::CompactView));
return iconsView;
KToggleAction* detailsView = m_actionCollection->add<KToggleAction>(QStringLiteral("details"));
detailsView->setText(i18nc("@action:inmenu View Mode", "Details"));
detailsView->setToolTip(i18nc("@info", "Details view mode"));
- m_actionCollection->setDefaultShortcut(detailsView, Qt::CTRL + Qt::Key_3);
+ m_actionCollection->setDefaultShortcut(detailsView, Qt::CTRL | Qt::Key_3);
detailsView->setIcon(QIcon::fromTheme(QStringLiteral("view-list-tree")));
detailsView->setData(QVariant::fromValue(DolphinView::DetailsView));
return detailsView;
KVersionControlPlugin::~KVersionControlPlugin()
{
}
+
+QString KVersionControlPlugin::localRepositoryRoot(const QString &/*directory*/) const
+{
+ return QString();
+}
*/
virtual QString fileName() const = 0;
+ /**
+ * Returns the path of the local repository root for the versionned directory
+ * Returns an emtpy QString when directory is not part of a working copy
+ */
+ virtual QString localRepositoryRoot(const QString& directory) const;
+
/**
* Is invoked whenever the version control
* information will get retrieved for the directory
* @return List of actions that are available for the out of version control
* items \p items. It's opposed to the \p versionedActions. Common usage
* is for clone/checkout actions.
+ * @since 21.04
*/
virtual QList<QAction*> outOfVersionControlActions(const KFileItemList& items) const = 0;
VersionControlObserver::VersionControlObserver(QObject* parent) :
QObject(parent),
m_pendingItemStatesUpdate(false),
- m_versionedDirectory(false),
m_silentUpdate(false),
m_view(nullptr),
m_model(nullptr),
return m_plugin->versionControlActions(items);
} else {
QList<QAction*> actions;
- for (const auto &plugin : qAsConst(m_plugins)) {
- actions << plugin.first->outOfVersionControlActions(items);
+ for (const QPointer<KVersionControlPlugin> &plugin : qAsConst(m_plugins)) {
+ actions << plugin->outOfVersionControlActions(items);
}
return actions;
}
return;
}
- m_plugin = searchPlugin(rootItem.url());
- if (m_plugin) {
- if (!m_versionedDirectory) {
- m_versionedDirectory = true;
+ if (m_plugin != nullptr) {
+ if (!rootItem.url().path().startsWith(m_localRepoRoot) || !QFile::exists(m_localRepoRoot + '/' + m_plugin->fileName())) {
+ m_plugin = nullptr;
- // The directory is versioned. Assume that the user will further browse through
- // versioned directories and decrease the verification timer.
- m_dirVerificationTimer->setInterval(100);
+ // The directory is not versioned. Reset the verification timer to a higher
+ // value, so that browsing through non-versioned directories is not slown down
+ // by an immediate verification.
+ m_dirVerificationTimer->setInterval(500);
+ } else {
+ // View was versionned but should not be anymore
+ updateItemStates();
}
+ } else if ((m_plugin = searchPlugin(rootItem.url()))) {
+ // The directory is versioned. Assume that the user will further browse through
+ // versioned directories and decrease the verification timer.
+ m_dirVerificationTimer->setInterval(100);
updateItemStates();
- } else if (m_versionedDirectory) {
- m_versionedDirectory = false;
-
- // The directory is not versioned. Reset the verification timer to a higher
- // value, so that browsing through non-versioned directories is not slown down
- // by an immediate verification.
- m_dirVerificationTimer->setInterval(500);
}
}
return index - firstIndex; // number of processed items
}
-KVersionControlPlugin* VersionControlObserver::searchPlugin(const QUrl& directory)
+void VersionControlObserver::initPlugins()
{
if (!m_pluginsInitialized) {
// No searching for plugins has been done yet. Query the KServiceTypeTrader for
connect(plugin, &KVersionControlPlugin::operationCompletedMessage,
this, &VersionControlObserver::operationCompletedMessage);
- m_plugins.append( qMakePair(plugin, plugin->fileName()) );
+ m_plugins.append(plugin);
}
}
}
m_pluginsInitialized = true;
}
+}
- if (m_plugins.empty()) {
- // A searching for plugins has already been done, but no
- // plugins are installed
- return nullptr;
- }
+KVersionControlPlugin* VersionControlObserver::searchPlugin(const QUrl& directory)
+{
+ initPlugins();
- // We use the number of upUrl() calls to find the best matching plugin
- // for the given directory. The smaller value, the better it is (0 is best).
- KVersionControlPlugin* bestPlugin = nullptr;
- int bestScore = INT_MAX;
+ // Verify whether the current directory is under a version system
+ for (const QPointer<KVersionControlPlugin> &plugin : qAsConst(m_plugins)) {
+ if (!plugin) {
+ continue;
+ }
- // Verify whether the current directory contains revision information
- // like .svn, .git, ...
- for (const auto &it : qAsConst(m_plugins)) {
- const QString fileName = directory.path() + '/' + it.second;
+ // first naively check if we are at working copy root
+ const QString fileName = directory.path() + '/' + plugin->fileName();
if (QFile::exists(fileName)) {
- // The score of this plugin is 0 (best), so we can just return this plugin,
- // instead of going through the plugin scoring procedure, we can't find a better one ;)
- return it.first;
+ m_localRepoRoot = directory.path();
+ return plugin;
}
-
- // Version control systems like Git provide the version information
- // file only in the root directory. Check whether the version information file can
- // be found in one of the parent directories. For performance reasons this
- // step is only done, if the previous directory was marked as versioned by
- // m_versionedDirectory. Drawback: Until e. g. Git is recognized, the root directory
- // must be shown at least once.
- if (m_versionedDirectory) {
- QUrl dirUrl(directory);
- QUrl upUrl = KIO::upUrl(dirUrl);
- int upUrlCounter = 1;
- while ((upUrlCounter < bestScore) && (upUrl != dirUrl)) {
- const QString fileName = dirUrl.path() + '/' + it.second;
- if (QFile::exists(fileName)) {
- if (upUrlCounter < bestScore) {
- bestPlugin = it.first;
- bestScore = upUrlCounter;
- }
- break;
- }
- dirUrl = upUrl;
- upUrl = KIO::upUrl(dirUrl);
- ++upUrlCounter;
- }
+ const QString root = plugin->localRepositoryRoot(directory.path());
+ if (!root.isEmpty()) {
+ m_localRepoRoot = root;
+ return plugin;
}
}
-
- return bestPlugin;
+ return nullptr;
}
bool VersionControlObserver::isVersionControlled() const
{
- return m_versionedDirectory && m_plugin;
+ return m_plugin != nullptr;
}
private:
typedef QPair<KFileItem, KVersionControlPlugin::ItemVersion> ItemState;
- typedef QPair<KVersionControlPlugin*, QString> VCSPlugin;
void updateItemStates();
bool isVersionControlled() const;
private:
+ void initPlugins();
+
bool m_pendingItemStatesUpdate;
- bool m_versionedDirectory;
bool m_silentUpdate; // if true, no messages will be send during the update
// of version states
+ QString m_localRepoRoot;
DolphinView* m_view;
KFileItemModel* m_model;
bool m_pluginsInitialized;
KVersionControlPlugin* m_plugin;
- QList<VCSPlugin> m_plugins;
+ QList<QPointer<KVersionControlPlugin>> m_plugins;
UpdateItemStatesThread* m_updateItemStatesThread;
friend class UpdateItemStatesThread;