cmake_minimum_required(VERSION 3.0)
# KDE Application Version, managed by release script
-set (KDE_APPLICATIONS_VERSION_MAJOR "18")
-set (KDE_APPLICATIONS_VERSION_MINOR "12")
-set (KDE_APPLICATIONS_VERSION_MICRO "2")
+set (KDE_APPLICATIONS_VERSION_MAJOR "19")
+set (KDE_APPLICATIONS_VERSION_MINOR "03")
+set (KDE_APPLICATIONS_VERSION_MICRO "70")
set (KDE_APPLICATIONS_VERSION "${KDE_APPLICATIONS_VERSION_MAJOR}.${KDE_APPLICATIONS_VERSION_MINOR}.${KDE_APPLICATIONS_VERSION_MICRO}")
project(Dolphin VERSION ${KDE_APPLICATIONS_VERSION})
set(QT_MIN_VERSION "5.8.0")
-set(KF5_MIN_VERSION "5.43.0")
+set(KF5_MIN_VERSION "5.53.0")
# ECM setup
find_package(ECM ${KF5_MIN_VERSION} CONFIG REQUIRED)
find_package(Phonon4Qt5 CONFIG REQUIRED)
-find_package(KF5Baloo 4.97)
+find_package(KF5Baloo ${KF5_MIN_VERSION})
set_package_properties(KF5Baloo PROPERTIES DESCRIPTION "Baloo Core libraries"
URL "http://www.kde.org"
TYPE OPTIONAL
PURPOSE "For adding desktop-wide search and tagging support to dolphin"
)
-find_package(KF5BalooWidgets 18.07.70)
+find_package(KF5BalooWidgets 18.08.0)
set_package_properties(KF5BalooWidgets PROPERTIES DESCRIPTION "Baloos Widgets"
URL "http://www.kde.org"
TYPE OPTIONAL
)
-find_package(KF5FileMetaData 5.19.0)
+find_package(KF5FileMetaData ${KF5_MIN_VERSION})
set_package_properties(KF5FileMetaData PROPERTIES
URL "https://projects.kde.org/kfilemetadata"
TYPE OPTIONAL
message(WARNING "Baloo packages not found. They are needed for the metadata features of Dolphin (including the information panel).")
endif()
+# TODO: drop HAVE_TERMINAL once we are sure the terminal panel works on Windows too.
+if(WIN32)
+ set(HAVE_TERMINAL FALSE)
+else()
+ set(HAVE_TERMINAL TRUE)
+endif()
+
add_subdirectory(src)
add_subdirectory(doc)
<legalnotice>&FDLNotice;</legalnotice>
-<date>2018-03-26</date>
-<releaseinfo>Applications 18.04</releaseinfo>
+<date>2019-02-17</date>
+<releaseinfo>Applications 19.04</releaseinfo>
<abstract>
<para>
If this option is disabled or several items are selected, a dialog will be displayed for renaming.
</para></listitem>
-<listitem><para><guilabel>Use tab for switching between left and right split view</guilabel>
-allows to switch without using the mouse.
+<listitem><para>Enabling <guilabel>Switch between split views with tab key</guilabel>
+allows to switch split views with the 	 key.
+</para></listitem>
+
+<listitem><para>Disable <guilabel>Turning off split view closes active pane</guilabel>
+to close the inactive pane when you are turning off the split view mode, ⪚ pressing <keycap>F3</keycap>.
</para></listitem>
</itemizedlist>
configure_file(config-dolphin.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-dolphin.h)
+configure_file(config-terminal.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-terminal.h)
+
add_definitions(
-DTRANSLATION_DOMAIN=\"dolphin\"
)
filterbar/filterbar.cpp
panels/places/placespanel.cpp
panels/places/placesitem.cpp
- panels/places/placesitemeditdialog.cpp
panels/places/placesitemlistgroupheader.cpp
panels/places/placesitemlistwidget.cpp
panels/places/placesitemmodel.cpp
+++ /dev/null
-#cmakedefine HAVE_XRENDER 1
--- /dev/null
+#cmakedefine HAVE_TERMINAL
Q_ASSERT(m_context & TrashContext);
Q_ASSERT(m_context & ItemContext);
- QAction* restoreAction = new QAction(i18nc("@action:inmenu", "Restore"), m_mainWindow);
+ QAction* restoreAction = new QAction(QIcon::fromTheme("restoration"), i18nc("@action:inmenu", "Restore"), m_mainWindow);
addAction(restoreAction);
QAction* deleteAction = m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::DeleteFile));
}
// insert 'Properties...' entry
+ addSeparator();
QAction* propertiesAction = m_mainWindow->actionCollection()->action(QStringLiteral("properties"));
addAction(propertiesAction);
addAction(collection->action(KStandardAction::name(KStandardAction::RenameFile)));
// Insert 'Move to Trash' and/or 'Delete'
- if (properties.supportsDeleting()) {
- const bool showDeleteAction = (KSharedConfig::openConfig()->group("KDE").readEntry("ShowDeleteCommand", false) ||
- !properties.isLocal());
- const bool showMoveToTrashAction = (properties.isLocal() &&
- properties.supportsMoving());
-
- if (showDeleteAction && showMoveToTrashAction) {
- delete m_removeAction;
- m_removeAction = nullptr;
- addAction(m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::MoveToTrash)));
- addAction(m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::DeleteFile)));
- } else if (showDeleteAction && !showMoveToTrashAction) {
- addAction(m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::DeleteFile)));
- } else {
- if (!m_removeAction) {
- m_removeAction = new DolphinRemoveAction(this, m_mainWindow->actionCollection());
- }
- addAction(m_removeAction);
- m_removeAction->update();
+ const bool showDeleteAction = (KSharedConfig::openConfig()->group("KDE").readEntry("ShowDeleteCommand", false) ||
+ !properties.isLocal());
+ const bool showMoveToTrashAction = (properties.isLocal() &&
+ properties.supportsMoving());
+
+ if (showDeleteAction && showMoveToTrashAction) {
+ delete m_removeAction;
+ m_removeAction = nullptr;
+ addAction(m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::MoveToTrash)));
+ addAction(m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::DeleteFile)));
+ } else if (showDeleteAction && !showMoveToTrashAction) {
+ addAction(m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::DeleteFile)));
+ } else {
+ if (!m_removeAction) {
+ m_removeAction = new DolphinRemoveAction(this, m_mainWindow->actionCollection());
}
+ addAction(m_removeAction);
+ m_removeAction->update();
}
}
#include "dolphinmainwindow.h"
+#include "config-terminal.h"
#include "global.h"
#include "dolphindockwidget.h"
#include "dolphincontextmenu.h"
#include <KActionMenu>
#include <KAuthorized>
#include <KConfig>
+#include <KDualAction>
#include <KFileItemListProperties>
#include <KHelpMenu>
#include <KIO/JobUiDelegate>
#include <QStandardPaths>
#include <QTimer>
#include <QToolButton>
-#include <kdualaction.h>
namespace {
// Used for GeneralSettings::version() to determine whether
foreach (const KFileItem& item, list) {
const QUrl& url = DolphinView::openItemAsFolderUrl(item);
if (!url.isEmpty()) {
- openNewTab(url);
+ m_tabWidget->openNewTab(url, QUrl(), DolphinTabWidget::AfterCurrentTab);
tabCreated = true;
}
}
// if no new tab has been created from the selection
// open the current directory in a new tab
if (!tabCreated) {
- openNewTab(m_activeViewContainer->url());
+ m_tabWidget->openNewTab(m_activeViewContainer->url(), QUrl(), DolphinTabWidget::AfterCurrentTab);
}
}
bool doNotAskAgainCheckboxResult = false;
- const int result = KMessageBox::createKMessageBox(dialog,
+ const auto result = KMessageBox::createKMessageBox(dialog,
buttons,
QMessageBox::Warning,
i18n("You have multiple tabs open in this window, are you sure you want to quit?"),
}
}
+ if (m_terminalPanel->hasProgramRunning() && GeneralSettings::confirmClosingTerminalRunningProgram() && closedByUser) {
+ // Ask if the user really wants to quit Dolphin with a program that is still running in the Terminal panel
+ // Open a confirmation dialog with 3 buttons:
+ // QDialogButtonBox::Yes -> Quit
+ // QDialogButtonBox::No -> Show Terminal Panel
+ // QDialogButtonBox::Cancel -> do nothing
+ QDialog *dialog = new QDialog(this, Qt::Dialog);
+ dialog->setWindowTitle(i18nc("@title:window", "Confirmation"));
+ dialog->setModal(true);
+ auto standardButtons = QDialogButtonBox::Yes | QDialogButtonBox::Cancel;
+ if (!m_terminalPanel->isVisible()) {
+ standardButtons |= QDialogButtonBox::No;
+ }
+ QDialogButtonBox *buttons = new QDialogButtonBox(standardButtons);
+ KGuiItem::assign(buttons->button(QDialogButtonBox::Yes), KStandardGuiItem::quit());
+ if (!m_terminalPanel->isVisible()) {
+ KGuiItem::assign(
+ buttons->button(QDialogButtonBox::No),
+ KGuiItem(i18n("Show &Terminal Panel"), QIcon::fromTheme(QStringLiteral("utilities-terminal"))));
+ }
+ KGuiItem::assign(buttons->button(QDialogButtonBox::Cancel), KStandardGuiItem::cancel());
+
+ bool doNotAskAgainCheckboxResult = false;
+
+ const auto result = KMessageBox::createKMessageBox(
+ dialog,
+ buttons,
+ QMessageBox::Warning,
+ i18n("The program '%1' is still running in the Terminal panel. Are you sure you want to quit?", m_terminalPanel->runningProgramName()),
+ QStringList(),
+ i18n("Do not ask again"),
+ &doNotAskAgainCheckboxResult,
+ KMessageBox::Dangerous);
+
+ if (doNotAskAgainCheckboxResult) {
+ GeneralSettings::setConfirmClosingTerminalRunningProgram(false);
+ }
+
+ switch (result) {
+ case QDialogButtonBox::Yes:
+ // Quit
+ break;
+ case QDialogButtonBox::No:
+ actionCollection()->action("show_terminal_panel")->trigger();
+ // Do not quit, ignore quit event
+ Q_FALLTHROUGH();
+ default:
+ event->ignore();
+ return;
+ }
+ }
+
GeneralSettings::setVersion(CurrentDolphinVersion);
GeneralSettings::self()->save();
// URL instead of all items of the view
KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
- QLineEdit* lineEdit = urlNavigator->editor()->lineEdit(); // krazy:exclude=qclasses
+ QLineEdit* lineEdit = urlNavigator->editor()->lineEdit();
const bool selectUrl = urlNavigator->isUrlEditable() &&
lineEdit->hasFocus();
if (selectUrl) {
void DolphinMainWindow::replaceLocation()
{
KUrlNavigator* navigator = m_activeViewContainer->urlNavigator();
- navigator->setUrlEditable(true);
- navigator->setFocus();
-
- // select the whole text of the combo box editor
- QLineEdit* lineEdit = navigator->editor()->lineEdit(); // krazy:exclude=qclasses
- lineEdit->selectAll();
+ QLineEdit* lineEdit = navigator->editor()->lineEdit();
+
+ // If the text field currently has focus and everything is selected,
+ // pressing the keyboard shortcut returns the whole thing to breadcrumb mode
+ if (navigator->isUrlEditable()
+ && lineEdit->hasFocus()
+ && lineEdit->selectedText() == lineEdit->text() ) {
+ navigator->setUrlEditable(false);
+ } else {
+ navigator->setUrlEditable(true);
+ navigator->setFocus();
+ lineEdit->selectAll();
+ }
}
void DolphinMainWindow::togglePanelLockState()
void DolphinMainWindow::updateWindowTitle()
{
- setWindowTitle(m_activeViewContainer->caption());
+ const QString newTitle = m_activeViewContainer->caption();
+ if (windowTitle() != newTitle) {
+ setWindowTitle(newTitle);
+ }
}
void DolphinMainWindow::slotStorageTearDownFromPlacesRequested(const QString& mountPath)
compareFiles->setEnabled(false);
connect(compareFiles, &QAction::triggered, this, &DolphinMainWindow::compareFiles);
-#ifndef Q_OS_WIN
+#ifdef HAVE_TERMINAL
if (KAuthorized::authorize(QStringLiteral("shell_access"))) {
QAction* openTerminal = actionCollection()->addAction(QStringLiteral("open_terminal"));
openTerminal->setText(i18nc("@action:inmenu Tools", "Open Terminal"));
this, &DolphinMainWindow::showErrorMessage);
// Setup "Terminal"
-#ifndef Q_OS_WIN
+#ifdef HAVE_TERMINAL
if (KAuthorized::authorize(QStringLiteral("shell_access"))) {
DolphinDockWidget* terminalDock = new DolphinDockWidget(i18nc("@title:window Shell terminal", "Terminal"));
terminalDock->setLocked(lock);
QAction* splitAction = actionCollection()->action(QStringLiteral("split_view"));
const DolphinTabPage* tabPage = m_tabWidget->currentTabPage();
if (tabPage->splitViewEnabled()) {
- if (tabPage->primaryViewActive()) {
+ if (GeneralSettings::closeActiveSplitView() ? tabPage->primaryViewActive() : !tabPage->primaryViewActive()) {
splitAction->setText(i18nc("@action:intoolbar Close left view", "Close"));
splitAction->setToolTip(i18nc("@info", "Close left view"));
splitAction->setIcon(QIcon::fromTheme(QStringLiteral("view-left-close")));
m_secondaryViewContainer->show();
m_secondaryViewContainer->setActive(true);
} else {
- // Close the view which is active.
- DolphinViewContainer* view = activeViewContainer();
- if (m_primaryViewActive) {
- // If the primary view is active, we have to swap the pointers
- // because the secondary view will be the new primary view.
- qSwap(m_primaryViewContainer, m_secondaryViewContainer);
- m_primaryViewActive = false;
+ DolphinViewContainer* view;
+ if (GeneralSettings::closeActiveSplitView()) {
+ view = activeViewContainer();
+ if (m_primaryViewActive) {
+ // If the primary view is active, we have to swap the pointers
+ // because the secondary view will be the new primary view.
+ qSwap(m_primaryViewContainer, m_secondaryViewContainer);
+ m_primaryViewActive = false;
+ }
+ } else {
+ view = m_primaryViewActive ? m_secondaryViewContainer : m_primaryViewContainer;
+ if (!m_primaryViewActive) {
+ // If the secondary view is active, we have to swap the pointers
+ // because the secondary view will be the new primary view.
+ qSwap(m_primaryViewContainer, m_secondaryViewContainer);
+ m_primaryViewActive = true;
+ }
}
m_primaryViewContainer->setActive(true);
view->close();
const DolphinView* newActiveView = activeViewContainer()->view();
- if (newActiveView != oldActiveView) {
- disconnect(oldActiveView, &DolphinView::urlChanged,
- this, &DolphinTabPage::activeViewUrlChanged);
- disconnect(oldActiveView, &DolphinView::redirection,
- this, &DolphinTabPage::slotViewUrlRedirection);
- connect(newActiveView, &DolphinView::urlChanged,
- this, &DolphinTabPage::activeViewUrlChanged);
- connect(newActiveView, &DolphinView::redirection,
- this, &DolphinTabPage::slotViewUrlRedirection);
+ if (newActiveView == oldActiveView) {
+ return;
}
+ disconnect(oldActiveView, &DolphinView::urlChanged,
+ this, &DolphinTabPage::activeViewUrlChanged);
+ disconnect(oldActiveView, &DolphinView::redirection,
+ this, &DolphinTabPage::slotViewUrlRedirection);
+ connect(newActiveView, &DolphinView::urlChanged,
+ this, &DolphinTabPage::activeViewUrlChanged);
+ connect(newActiveView, &DolphinView::redirection,
+ this, &DolphinTabPage::slotViewUrlRedirection);
emit activeViewChanged(activeViewContainer());
emit activeViewUrlChanged(activeViewContainer()->url());
}
// The URL navigator of the new tab should have the same editable state
// as the current tab
- KUrlNavigator* navigator = newActiveViewContainer->urlNavigator();
- navigator->setUrlEditable(isUrlEditable);
+ newActiveViewContainer->urlNavigator()->setUrlEditable(isUrlEditable);
- if (isUrlEditable) {
- // If a new tab is opened and the URL is editable, assure that
- // the user can edit the URL without manually setting the focus
- navigator->setFocus();
- }
+ // Always focus the new tab's view
+ newActiveViewContainer->view()->setFocus();
}
void DolphinTabWidget::openNewActivatedTab(const QUrl& primaryUrl, const QUrl& secondaryUrl)
setCurrentIndex(count() - 1);
}
-void DolphinTabWidget::openNewTab(const QUrl& primaryUrl, const QUrl& secondaryUrl)
+void DolphinTabWidget::openNewTab(const QUrl& primaryUrl, const QUrl& secondaryUrl, TabPlacement tabPlacement)
{
QWidget* focusWidget = QApplication::focusWidget();
this, &DolphinTabWidget::activeViewChanged);
connect(tabPage, &DolphinTabPage::activeViewUrlChanged,
this, &DolphinTabWidget::tabUrlChanged);
- addTab(tabPage, QIcon::fromTheme(KIO::iconNameForUrl(primaryUrl)), tabName(tabPage));
+ int newTabIndex = -1;
+ if (tabPlacement == AfterCurrentTab) {
+ newTabIndex = currentIndex() + 1;
+ }
+ insertTab(newTabIndex, tabPage, QIcon::fromTheme(KIO::iconNameForUrl(primaryUrl)), tabName(tabPage));
if (focusWidget) {
// The DolphinViewContainer grabbed the keyboard focus. As the tab is opened
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
+ };
explicit DolphinTabWidget(QWidget* parent);
/**
/**
* Opens a new tab in the background showing the URL \a primaryUrl and the
- * optional URL \a secondaryUrl.
+ * optional URL \a secondaryUrl. \a tabPlacement controls where the new tab
+ * is placed.
*/
- void openNewTab(const QUrl &primaryUrl, const QUrl &secondaryUrl = QUrl());
+ void openNewTab(const QUrl &primaryUrl, const QUrl &secondaryUrl = QUrl(),
+ TabPlacement tabPlacement = AfterLastTab);
/**
* Opens each directory in \p dirs in a separate tab. If \a splitView is set,
#include <KShell>
#include <KUrlComboBox>
#include <KUrlNavigator>
-#include <kio_version.h>
#include <QDropEvent>
#include <QLoggingCategory>
int count = 0;
const RoleInfoMap* map = rolesInfoMap(count);
for (int i = 0; i < count; ++i) {
+ if (!map[i].roleTranslation) {
+ continue;
+ }
description.insert(map[i].role, i18nc(map[i].roleTranslationContext, map[i].roleTranslation));
}
}
m_groups.clear();
}
-void KFileItemModel::onSortRoleChanged(const QByteArray& current, const QByteArray& previous)
+void KFileItemModel::onSortRoleChanged(const QByteArray& current, const QByteArray& previous, bool resortItems)
{
Q_UNUSED(previous);
m_sortRole = typeForRole(current);
setRoles(newRoles);
}
- resortAllItems();
+ if (resortItems) {
+ resortAllItems();
+ }
}
void KFileItemModel::onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous)
return (sortOrder() == Qt::AscendingOrder) ? result < 0 : result > 0;
}
-void KFileItemModel::sort(QList<KFileItemModel::ItemData*>::iterator begin,
- QList<KFileItemModel::ItemData*>::iterator end) const
+void KFileItemModel::sort(const QList<KFileItemModel::ItemData*>::iterator &begin,
+ const QList<KFileItemModel::ItemData*>::iterator &end) const
{
auto lambdaLessThan = [&] (const KFileItemModel::ItemData* a, const KFileItemModel::ItemData* b)
{
return groups;
}
-QList<QPair<int, QVariant> > KFileItemModel::timeRoleGroups(std::function<QDateTime(const ItemData *)> fileTimeCb) const
+QList<QPair<int, QVariant> > KFileItemModel::timeRoleGroups(const std::function<QDateTime(const ItemData *)> &fileTimeCb) const
{
Q_ASSERT(!m_itemData.isEmpty());
protected:
void onGroupedSortingChanged(bool current) override;
- void onSortRoleChanged(const QByteArray& current, const QByteArray& previous) override;
+ void onSortRoleChanged(const QByteArray& current, const QByteArray& previous, bool resortItems = true) override;
void onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous) override;
private slots:
* Sorts the items between \a begin and \a end using the comparison
* function lessThan().
*/
- void sort(QList<ItemData*>::iterator begin, QList<ItemData*>::iterator end) const;
+ void sort(const QList<ItemData*>::iterator &begin, const QList<ItemData*>::iterator &end) const;
/**
* Helper method for lessThan() and expandedParentsCountCompare(): Compares
QList<QPair<int, QVariant> > nameRoleGroups() const;
QList<QPair<int, QVariant> > sizeRoleGroups() const;
- QList<QPair<int, QVariant> > timeRoleGroups(std::function<QDateTime(const ItemData *)> fileTimeCb) const;
+ QList<QPair<int, QVariant> > timeRoleGroups(const std::function<QDateTime(const ItemData *)> &fileTimeCb) const;
QList<QPair<int, QVariant> > permissionRoleGroups() const;
QList<QPair<int, QVariant> > ratingRoleGroups() const;
QList<QPair<int, QVariant> > genericStringRoleGroups(const QByteArray& typeForRole) const;
}
}
-void KFileItemModelRolesUpdater::slotItemsMoved(const KItemRange& itemRange, QList<int> movedToIndexes)
+void KFileItemModelRolesUpdater::slotItemsMoved(const KItemRange& itemRange, const QList<int> &movedToIndexes)
{
Q_UNUSED(itemRange);
Q_UNUSED(movedToIndexes);
return;
}
applyChangedBalooRolesForItem(item);
+#else
+ Q_UNUSED(file);
#endif
}
private slots:
void slotItemsInserted(const KItemRangeList& itemRanges);
void slotItemsRemoved(const KItemRangeList& itemRanges);
- void slotItemsMoved(const KItemRange& itemRange, QList<int> movedToIndexes);
+ void slotItemsMoved(const KItemRange& itemRange, const QList<int> &movedToIndexes);
void slotItemsChanged(const KItemRangeList& itemRanges,
const QSet<QByteArray>& roles);
void slotSortRoleChanged(const QByteArray& current,
return m_singleClickActivationEnforced;
}
-bool KItemListController::showEvent(QShowEvent* event)
-{
- Q_UNUSED(event);
- return false;
-}
-
-bool KItemListController::hideEvent(QHideEvent* event)
-{
- Q_UNUSED(event);
- return false;
-}
-
bool KItemListController::keyPressEvent(QKeyEvent* event)
{
int index = m_selectionManager->currentItem();
class QGraphicsSceneMouseEvent;
class QGraphicsSceneResizeEvent;
class QGraphicsSceneWheelEvent;
-class QHideEvent;
class QInputMethodEvent;
class QKeyEvent;
-class QShowEvent;
class QTransform;
/**
void setSingleClickActivationEnforced(bool singleClick);
bool singleClickActivationEnforced() const;
- virtual bool showEvent(QShowEvent* event);
- virtual bool hideEvent(QHideEvent* event);
- virtual bool keyPressEvent(QKeyEvent* event);
- virtual bool inputMethodEvent(QInputMethodEvent* event);
- virtual bool mousePressEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform);
- virtual bool mouseMoveEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform);
- virtual bool mouseReleaseEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform);
- virtual bool mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform);
- virtual bool dragEnterEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform);
- virtual bool dragLeaveEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform);
- virtual bool dragMoveEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform);
- virtual bool dropEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform);
- virtual bool hoverEnterEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform);
- virtual bool hoverMoveEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform);
- virtual bool hoverLeaveEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform);
- virtual bool wheelEvent(QGraphicsSceneWheelEvent* event, const QTransform& transform);
- virtual bool resizeEvent(QGraphicsSceneResizeEvent* event, const QTransform& transform);
- virtual bool processEvent(QEvent* event, const QTransform& transform);
+ bool processEvent(QEvent* event, const QTransform& transform);
signals:
/**
*/
void updateExtendedSelectionRegion();
+ bool keyPressEvent(QKeyEvent* event);
+ bool inputMethodEvent(QInputMethodEvent* event);
+ bool mousePressEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform);
+ bool mouseMoveEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform);
+ bool mouseReleaseEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform);
+ bool mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform);
+ bool dragEnterEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform);
+ bool dragLeaveEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform);
+ bool dragMoveEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform);
+ bool dropEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform);
+ bool hoverEnterEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform);
+ bool hoverMoveEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform);
+ bool hoverLeaveEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform);
+ bool wheelEvent(QGraphicsSceneWheelEvent* event, const QTransform& transform);
+ bool resizeEvent(QGraphicsSceneResizeEvent* event, const QTransform& transform);
+
private:
bool m_singleClickActivationEnforced;
bool m_selectionTogglePressed;
return m_groupedSorting;
}
-void KItemModelBase::setSortRole(const QByteArray& role)
+void KItemModelBase::setSortRole(const QByteArray& role, bool resortItems)
{
if (role != m_sortRole) {
const QByteArray previous = m_sortRole;
m_sortRole = role;
- onSortRoleChanged(role, previous);
+ onSortRoleChanged(role, previous, resortItems);
emit sortRoleChanged(role, previous);
}
}
Q_UNUSED(current);
}
-void KItemModelBase::onSortRoleChanged(const QByteArray& current, const QByteArray& previous)
+void KItemModelBase::onSortRoleChanged(const QByteArray& current, const QByteArray& previous, bool resortItems)
{
Q_UNUSED(current);
Q_UNUSED(previous);
+ Q_UNUSED(resortItems);
}
void KItemModelBase::onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous)
* Sets the sort-role to \a role. The method KItemModelBase::onSortRoleChanged() will be
* called so that model-implementations can react on the sort-role change. Afterwards the
* signal sortRoleChanged() will be emitted.
+ * The implementation should resort only if \a resortItems is true.
*/
- void setSortRole(const QByteArray& role);
+ void setSortRole(const QByteArray& role, bool resortItems = true);
QByteArray sortRole() const;
/**
* Usually the most efficient way is to emit a
* itemsRemoved() signal for all items, reorder the items internally and to emit a
* itemsInserted() signal afterwards.
+ * The implementation should resort only if \a resortItems is true.
*/
- virtual void onSortRoleChanged(const QByteArray& current, const QByteArray& previous);
+ virtual void onSortRoleChanged(const QByteArray& current, const QByteArray& previous, bool resortItems = true);
/**
* Is invoked if the sort order has been changed by KItemModelBase::setSortOrder(). Allows
// Change the sort role and reset to the ascending order
const QByteArray previous = m_model->sortRole();
const QByteArray current = m_columns[m_pressedRoleIndex];
- m_model->setSortRole(current);
+ const bool resetSortOrder = m_model->sortOrder() == Qt::DescendingOrder;
+ m_model->setSortRole(current, !resetSortOrder);
emit sortRoleChanged(current, previous);
- if (m_model->sortOrder() == Qt::DescendingOrder) {
+ if (resetSortOrder) {
m_model->setSortOrder(Qt::AscendingOrder);
emit sortOrderChanged(Qt::AscendingOrder, Qt::DescendingOrder);
}
<li xml:lang="gl">Barra de navegación 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 remah) untuk URL-URL, membolehkanmu secara cepat menavigasi melalui hirerarki file-file dan folder-folder.</li>
+ <li xml:lang="id">Bilah navigasi (atau remah) untuk URL-URL, memungkinkanmu secara cepat menavigasi 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="nb">Navigasjonslinje (brødsmulelinje) for URL-er slik at du raskt kan navigere gjennom hierarkiet av filer og mapper.</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 membolehkanmu untuk mengonfigurasi tampilan persis seperti yang kamu inginkan.</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="nb">Støtter flere forskjellige visningsstiler og kan sette opp visningen akkurat slik du vil ha den.</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 pisah, membolehkanmu untuk menyalin atau memindah file antar lokasi dengan mudah.</li>
+ <li xml:lang="id">Tampilan pisah, 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="nb">Delt visning, så du lett kan kopiere eller flytte filer mellom steder.</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, membolehkanmu untuk memindahkannya secara bebas dan menampilkan apa yang kamu inginkan.</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="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>
<screenshots>
<screenshot type="default">
<caption>File management in Dolphin</caption>
+ <caption xml:lang="ast">Xestión de ficheros en Dolphin</caption>
<caption xml:lang="ca">Gestió de fitxers al Dolphin</caption>
<caption xml:lang="ca-valencia">Gestió de fitxers al Dolphin</caption>
<caption xml:lang="cs">Správa souborů v Dolphinu</caption>
<caption xml:lang="de">Dateiverwaltung mit Dolphin</caption>
+ <caption xml:lang="el">Διαχείριση αρχείων στο Dolphin</caption>
<caption xml:lang="en-GB">File management in Dolphin</caption>
<caption xml:lang="es">Gestión de archivos en Dolphin</caption>
<caption xml:lang="fi">Tiedostonhallinta Dolphinissa</caption>
<caption xml:lang="fr">Gestion de fichiers dans Dophin</caption>
<caption xml:lang="gl">Xestión de ficheiros en Dolphin</caption>
+ <caption xml:lang="ia">Gerente de file in Dolphin</caption>
+ <caption xml:lang="id">Pengelolaan file di Dolphin</caption>
<caption xml:lang="it">Gestione dei file in Dolphin</caption>
<caption xml:lang="nl">Bestandsbeheer in Dolphin</caption>
<caption xml:lang="nn">Filhandsaming i Dolphin</caption>
m_controller->view()->editRole(index, "text");
} else {
RenameDialog* dialog = new RenameDialog(this, KFileItemList() << item);
- dialog->show();
- dialog->raise();
- dialog->activateWindow();
+ dialog->open();
}
}
if (item.isNull()) {
// The cursor is above the viewport. If files are selected,
// show information regarding the selection.
- if (m_selection.size() > 0) {
+ if (!m_selection.isEmpty()) {
m_fileItem = KFileItem();
m_infoTimer->start();
}
void PixmapViewer::checkPendingPixmaps()
{
- if (m_pendingPixmaps.count() > 0) {
+ if (!m_pendingPixmaps.isEmpty()) {
QPixmap pixmap = m_pendingPixmaps.dequeue();
m_oldPixmap = m_pixmap.isNull() ? pixmap : m_pixmap;
m_pixmap = pixmap;
/***************************************************************************
* Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com> *
+ * Copyright (C) 2018 by Elvis Angelaccio <elvis.angelaccio@kde.org> *
* *
* Based on KFilePlacesItem from kdelibs: *
* Copyright (C) 2007 Kevin Ottens <ervin@kde.org> *
return dataValue("udi").toString();
}
+void PlacesItem::setApplicationName(const QString &applicationName)
+{
+ setDataValue("applicationName", applicationName);
+}
+
+QString PlacesItem::applicationName() const
+{
+ return dataValue("applicationName").toString();
+}
+
void PlacesItem::setHidden(bool hidden)
{
setDataValue("isHidden", hidden);
m_bookmark.setUrl(url());
} else if (role == "udi") {
m_bookmark.setMetaDataItem(QStringLiteral("UDI"), udi());
+ } else if (role == "applicationName") {
+ m_bookmark.setMetaDataItem(QStringLiteral("OnlyInApp"), applicationName());
} else if (role == "isSystemItem") {
m_bookmark.setMetaDataItem(QStringLiteral("isSystemItem"), isSystemItem() ? QStringLiteral("true") : QStringLiteral("false"));
} else if (role == "isHidden") {
void setUdi(const QString& udi);
QString udi() const;
+ void setApplicationName(const QString& applicationName);
+ QString applicationName() const;
+
void setHidden(bool hidden);
bool isHidden() const;
+++ /dev/null
-/***************************************************************************
- * Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com> *
- * *
- * Based on KFilePlaceEditDialog from kdelibs: *
- * Copyright (C) 2001,2002,2003 Carsten Pfeiffer <pfeiffer@kde.org> *
- * Copyright (C) 2007 Kevin Ottens <ervin@kde.org> * *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
-
-#include "placesitemeditdialog.h"
-
-#include "dolphindebug.h"
-
-#include <KAboutData>
-#include <KFile>
-#include <KIconButton>
-#include <KLocalizedString>
-#include <KUrlRequester>
-
-#include <QCheckBox>
-#include <QDialogButtonBox>
-#include <QEvent>
-#include <QFormLayout>
-#include <QLineEdit>
-#include <QMimeDatabase>
-
-PlacesItemEditDialog::PlacesItemEditDialog(QWidget* parent) :
- QDialog(parent),
- m_icon(),
- m_text(),
- m_url(),
- m_allowGlobal(false),
- m_urlEdit(nullptr),
- m_textEdit(nullptr),
- m_iconButton(nullptr),
- m_appLocal(nullptr),
- m_buttonBox(nullptr)
-{
-}
-
-void PlacesItemEditDialog::setIcon(const QString& icon)
-{
- m_icon = icon;
-}
-
-QString PlacesItemEditDialog::icon() const
-{
- return m_iconButton ? m_iconButton->icon() : m_icon;
-}
-
-void PlacesItemEditDialog::setText(const QString& text)
-{
- m_text = text;
-}
-
-QString PlacesItemEditDialog::text() const
-{
- QString text = m_textEdit->text();
- if (text.isEmpty()) {
- const QUrl url = m_urlEdit->url();
- text = url.fileName().isEmpty() ? url.toDisplayString(QUrl::PreferLocalFile) : url.fileName();
- }
- return text;
-}
-
-void PlacesItemEditDialog::setUrl(const QUrl& url)
-{
- m_url = url;
-}
-
-QUrl PlacesItemEditDialog::url() const
-{
- return m_urlEdit->url();
-}
-
-void PlacesItemEditDialog::setAllowGlobal(bool allow)
-{
- m_allowGlobal = allow;
-}
-
-bool PlacesItemEditDialog::allowGlobal() const
-{
- return m_allowGlobal;
-}
-
-bool PlacesItemEditDialog::event(QEvent* event)
-{
- if (event->type() == QEvent::Polish) {
- initialize();
- }
- return QWidget::event(event);
-}
-
-void PlacesItemEditDialog::slotUrlChanged(const QString& text)
-{
- m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!text.isEmpty());
-}
-
-PlacesItemEditDialog::~PlacesItemEditDialog()
-{
-}
-
-void PlacesItemEditDialog::initialize()
-{
- m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel, this);
- connect(m_buttonBox, &QDialogButtonBox::accepted, this, &PlacesItemEditDialog::accept);
- connect(m_buttonBox, &QDialogButtonBox::rejected, this, &PlacesItemEditDialog::reject);
- setModal(true);
-
- QVBoxLayout *mainLayout = new QVBoxLayout;
- setLayout(mainLayout);
- QWidget* mainWidget = new QWidget(this);
- mainLayout->addWidget(mainWidget);
- mainLayout->addWidget(m_buttonBox);
-
- QVBoxLayout* vBox = new QVBoxLayout(mainWidget);
-
- QFormLayout* formLayout = new QFormLayout();
- vBox->addLayout( formLayout );
-
- m_textEdit = new QLineEdit(mainWidget);
- formLayout->addRow(i18nc("@label", "Label:"), m_textEdit);
- m_textEdit->setText(m_text);
- m_textEdit->setPlaceholderText(i18n("Enter descriptive label here"));
-
- m_urlEdit = new KUrlRequester(m_url, mainWidget);
- m_urlEdit->setMode(KFile::Directory);
- formLayout->addRow(i18nc("@label", "Location:"), m_urlEdit);
- // Provide room for at least 40 chars (average char width is half of height)
- m_urlEdit->setMinimumWidth(m_urlEdit->fontMetrics().height() * (40 / 2));
- connect(m_urlEdit, &KUrlRequester::textChanged, this, &PlacesItemEditDialog::slotUrlChanged);
-
- if (m_url.scheme() != QLatin1String("trash")) {
- m_iconButton = new KIconButton(mainWidget);
- formLayout->addRow(i18nc("@label", "Choose an icon:"), m_iconButton);
- m_iconButton->setIconSize(IconSize(KIconLoader::Desktop));
- m_iconButton->setIconType(KIconLoader::NoGroup, KIconLoader::Place);
- if (m_icon.isEmpty()) {
- QMimeDatabase db;
- m_iconButton->setIcon(db.mimeTypeForUrl(m_url).iconName());
- } else {
- m_iconButton->setIcon(m_icon);
- }
- }
-
- if (m_allowGlobal) {
- const QString appName = KAboutData::applicationData().displayName();
- m_appLocal = new QCheckBox( i18n("&Only show when using this application (%1)", appName ), mainWidget );
- m_appLocal->setChecked(false);
- vBox->addWidget(m_appLocal);
- }
-
- if (m_text.isEmpty()) {
- m_urlEdit->setFocus();
- } else {
- m_textEdit->setFocus();
- }
-
-}
-
+++ /dev/null
-/***************************************************************************
- * Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com> *
- * *
- * Based on KFilePlaceEditDialog from kdelibs: *
- * Copyright (C) 2001,2002,2003 Carsten Pfeiffer <pfeiffer@kde.org> *
- * Copyright (C) 2007 Kevin Ottens <ervin@kde.org> * *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
-
-#ifndef PLACESITEMEDITDIALOG_H
-#define PLACESITEMEDITDIALOG_H
-
-#include <QDialog>
-#include <QUrl>
-
-class KIconButton;
-class KUrlRequester;
-class QLineEdit;
-class QCheckBox;
-class QDialogButtonBox;
-
-class PlacesItemEditDialog: public QDialog
-{
- Q_OBJECT
-
-public:
- explicit PlacesItemEditDialog(QWidget* parent = nullptr);
- ~PlacesItemEditDialog() override;
-
- void setIcon(const QString& icon);
- QString icon() const;
-
- void setText(const QString& text);
- QString text() const;
-
- void setUrl(const QUrl& url);
- QUrl url() const;
-
- void setAllowGlobal(bool allow);
- bool allowGlobal() const;
-
-protected:
- bool event(QEvent* event) override;
-
-private slots:
- void slotUrlChanged(const QString& text);
-
-private:
- void initialize();
-
-private:
- QString m_icon;
- QString m_text;
- QUrl m_url;
- bool m_allowGlobal;
-
- KUrlRequester* m_urlEdit;
- QLineEdit* m_textEdit;
- KIconButton* m_iconButton;
- QCheckBox* m_appLocal;
- QDialogButtonBox *m_buttonBox;
-};
-
-#endif
{
}
-void PlacesItemModel::createPlacesItem(const QString& text,
- const QUrl& url,
- const QString& iconName,
- int after)
+void PlacesItemModel::createPlacesItem(const QString &text, const QUrl &url, const QString &iconName, const QString &appName)
{
- m_sourceModel->addPlace(text, url, iconName, {}, mapToSource(after));
+ createPlacesItem(text, url, iconName, appName, -1);
+}
+
+void PlacesItemModel::createPlacesItem(const QString &text, const QUrl &url, const QString &iconName, const QString &appName, int after)
+{
+ m_sourceModel->addPlace(text, url, iconName, appName, mapToSource(after));
}
PlacesItem* PlacesItemModel::placesItem(int index) const
continue;
}
- createPlacesItem(text, url, KIO::iconNameForUrl(url), qMax(0, index - 1));
+ createPlacesItem(text, url, KIO::iconNameForUrl(url), {}, qMax(0, index - 1));
}
}
// will save bookmark alteration and fix sort if that is broken by the drag/drop operation
* @brief Create a new place entry in the bookmark file
* and add it to the model
*/
- void createPlacesItem(const QString& text,
- const QUrl& url,
- const QString& iconName = QString(),
- int after = -1);
+ void createPlacesItem(const QString& text, const QUrl& url, const QString& iconName = {}, const QString& appName = {});
+ void createPlacesItem(const QString& text, const QUrl& url, const QString& iconName, const QString& appName, int after);
PlacesItem* placesItem(int index) const;
#include "kitemviews/kitemlistselectionmanager.h"
#include "kitemviews/kstandarditem.h"
#include "placesitem.h"
-#include "placesitemeditdialog.h"
#include "placesitemlistgroupheader.h"
#include "placesitemlistwidget.h"
#include "placesitemmodel.h"
#include "trash/dolphintrash.h"
#include "views/draganddrophelper.h"
+#include <KFilePlaceEditDialog>
#include <KFilePlacesModel>
#include <KIO/DropJob>
#include <KIO/EmptyTrashJob>
{
const int index = m_controller->selectionManager()->currentItem();
const QUrl url = m_model->data(index).value("url").toUrl();
+ const QString text = url.fileName().isEmpty() ? url.toDisplayString(QUrl::PreferLocalFile) : url.fileName();
- QPointer<PlacesItemEditDialog> dialog = new PlacesItemEditDialog(this);
- dialog->setWindowTitle(i18nc("@title:window", "Add Places Entry"));
- dialog->setAllowGlobal(true);
- dialog->setUrl(url);
+ QPointer<KFilePlaceEditDialog> dialog = new KFilePlaceEditDialog(true, url, text, QString(), true, false, KIconLoader::SizeMedium, this);
if (dialog->exec() == QDialog::Accepted) {
- m_model->createPlacesItem(dialog->text(), dialog->url(), dialog->icon());
+ const QString appName = dialog->applicationLocal() ? QCoreApplication::applicationName() : QString();
+ m_model->createPlacesItem(dialog->label(), dialog->url(), dialog->icon(), appName);
}
delete dialog;
void PlacesPanel::editEntry(int index)
{
QHash<QByteArray, QVariant> data = m_model->data(index);
+ const QUrl url = data.value("url").toUrl();
+ const QString text = data.value("text").toString();
+ const bool applicationLocal = !data.value("applicationName").toString().isEmpty();
- QPointer<PlacesItemEditDialog> dialog = new PlacesItemEditDialog(this);
- dialog->setWindowTitle(i18nc("@title:window", "Edit Places Entry"));
- dialog->setIcon(data.value("iconName").toString());
- dialog->setText(data.value("text").toString());
- dialog->setUrl(data.value("url").toUrl());
- dialog->setAllowGlobal(true);
+ QPointer<KFilePlaceEditDialog> dialog = new KFilePlaceEditDialog(true, url, text, QString(), true, applicationLocal, KIconLoader::SizeMedium, this);
if (dialog->exec() == QDialog::Accepted) {
PlacesItem* oldItem = m_model->placesItem(index);
if (oldItem) {
- oldItem->setText(dialog->text());
+ const QString appName = dialog->applicationLocal() ? QCoreApplication::applicationName() : QString();
+ oldItem->setApplicationName(appName);
+ oldItem->setText(dialog->label());
oldItem->setUrl(dialog->url());
oldItem->setIcon(dialog->icon());
m_model->refresh();
emit hideTerminalPanel();
}
-bool TerminalPanel::isHiddenInVisibleWindow()
+bool TerminalPanel::isHiddenInVisibleWindow() const
{
return parentWidget()
&& parentWidget()->isHidden()
&& m_terminal
- && (m_terminal->foregroundProcessId() == -1);
+ && !hasProgramRunning();
}
void TerminalPanel::dockVisibilityChanged()
}
}
+QString TerminalPanel::runningProgramName() const
+{
+ return m_terminal ? m_terminal->foregroundProcessName() : QString();
+}
+
+bool TerminalPanel::hasProgramRunning() const
+{
+ return m_terminal && (m_terminal->foregroundProcessId() != -1);
+}
+
bool TerminalPanel::urlChanged()
{
if (!url().isValid()) {
return false;
}
- const bool sendInput = m_terminal && (m_terminal->foregroundProcessId() == -1) && isVisible();
+ const bool sendInput = m_terminal && !hasProgramRunning() && isVisible();
if (sendInput) {
changeDir(url());
}
*/
void goHome();
QString currentWorkingDirectory();
- bool isHiddenInVisibleWindow();
+ bool isHiddenInVisibleWindow() const;
+ bool hasProgramRunning() const;
+ QString runningProgramName() const;
public slots:
void terminalExited();
<label>Ask for confirmation when closing windows with multiple tabs.</label>
<default>true</default>
</entry>
+ <entry name="ConfirmClosingTerminalRunningProgram" type="Bool">
+ <label>Ask for confirmation when closing windows with a program that is still running in the Terminal panel.</label>
+ <default>true</default>
+ </entry>
<entry name="RenameInline" type="Bool">
<label>Rename inline</label>
<default>true</default>
<label>Use tab for switching between right and left split</label>
<default>false</default>
</entry>
+ <entry name="CloseActiveSplitView" type="Bool">
+ <label>Close active view when toggling off</label>
+ <default>true</default>
+ </entry>
<entry name="ShowToolTips" type="Bool">
<label>Show tooltips</label>
<default>false</default>
m_useTabForSplitViewSwitch = new QCheckBox(i18nc("option:check", "Switch between split views with tab key"));
topLayout->addRow(QString(), m_useTabForSplitViewSwitch);
+ // 'Close active view when turning off split view'
+ m_closeActiveSplitView = new QCheckBox(i18nc("option:check", "Turning off split view closes active pane"));
+ topLayout->addRow(QString(), m_closeActiveSplitView);
+ m_closeActiveSplitView->setToolTip(i18n("When deactivated, turning off split view will close the inactive pane"));
+
loadSettings();
connect(m_localViewProps, &QRadioButton::toggled, this, &BehaviorSettingsPage::changed);
connect(m_caseSensitiveSorting, &QRadioButton::toggled, this, &BehaviorSettingsPage::changed);
connect(m_renameInline, &QCheckBox::toggled, this, &BehaviorSettingsPage::changed);
connect(m_useTabForSplitViewSwitch, &QCheckBox::toggled, this, &BehaviorSettingsPage::changed);
+ connect(m_closeActiveSplitView, &QCheckBox::toggled, this, &BehaviorSettingsPage::changed);
}
BehaviorSettingsPage::~BehaviorSettingsPage()
setSortingChoiceValue(settings);
settings->setRenameInline(m_renameInline->isChecked());
settings->setUseTabForSwitchingSplitView(m_useTabForSplitViewSwitch->isChecked());
+ settings->setCloseActiveSplitView(m_closeActiveSplitView->isChecked());
settings->save();
if (useGlobalViewProps) {
m_showSelectionToggle->setChecked(GeneralSettings::showSelectionToggle());
m_renameInline->setChecked(GeneralSettings::renameInline());
m_useTabForSplitViewSwitch->setChecked(GeneralSettings::useTabForSwitchingSplitView());
+ m_closeActiveSplitView->setChecked(GeneralSettings::closeActiveSplitView());
loadSortingChoiceSettings();
}
QCheckBox* m_renameInline;
QCheckBox* m_useTabForSplitViewSwitch;
+ QCheckBox* m_closeActiveSplitView;
};
#endif
m_confirmMoveToTrash(nullptr),
m_confirmEmptyTrash(nullptr),
m_confirmDelete(nullptr),
+
+#ifdef HAVE_TERMINAL
+ m_confirmClosingTerminalRunningProgram(nullptr),
+#endif
+
m_confirmClosingMultipleTabs(nullptr)
{
QVBoxLayout* topLayout = new QVBoxLayout(this);
m_confirmClosingMultipleTabs = new QCheckBox(i18nc("@option:check Ask for confirmation in Dolphin when",
"Closing windows with multiple tabs"), this);
+#ifdef HAVE_TERMINAL
+ m_confirmClosingTerminalRunningProgram = new QCheckBox(i18nc("@option:check Ask for confirmation when",
+ "Closing windows with a program running in the Terminal panel"), this);
+#endif
+
topLayout->addWidget(confirmLabelKde);
topLayout->addWidget(m_confirmMoveToTrash);
topLayout->addWidget(m_confirmEmptyTrash);
topLayout->addSpacing(Dolphin::VERTICAL_SPACER_HEIGHT);
topLayout->addWidget(confirmLabelDolphin);
topLayout->addWidget(m_confirmClosingMultipleTabs);
+
+#ifdef HAVE_TERMINAL
+ topLayout->addWidget(m_confirmClosingTerminalRunningProgram);
+#endif
+
topLayout->addStretch();
loadSettings();
connect(m_confirmDelete, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
connect(m_confirmScriptExecution, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
connect(m_confirmClosingMultipleTabs, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
+
+#ifdef HAVE_TERMINAL
+ connect(m_confirmClosingTerminalRunningProgram, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
+#endif
}
ConfirmationsSettingsPage::~ConfirmationsSettingsPage()
GeneralSettings* settings = GeneralSettings::self();
settings->setConfirmClosingMultipleTabs(m_confirmClosingMultipleTabs->isChecked());
+
+#ifdef HAVE_TERMINAL
+ settings->setConfirmClosingTerminalRunningProgram(m_confirmClosingTerminalRunningProgram->isChecked());
+#endif
+
settings->save();
}
m_confirmScriptExecution->setChecked(value == QLatin1String("alwaysAsk"));
m_confirmClosingMultipleTabs->setChecked(GeneralSettings::confirmClosingMultipleTabs());
+
+#ifdef HAVE_TERMINAL
+ m_confirmClosingTerminalRunningProgram->setChecked(GeneralSettings::confirmClosingTerminalRunningProgram());
+#endif
}
#ifndef CONFIRMATIONSSETTINGSPAGE_H
#define CONFIRMATIONSSETTINGSPAGE_H
+#include "config-terminal.h"
#include "settings/settingspagebase.h"
class QCheckBox;
QCheckBox* m_confirmMoveToTrash;
QCheckBox* m_confirmEmptyTrash;
QCheckBox* m_confirmDelete;
+
+#ifdef HAVE_TERMINAL
+ QCheckBox* m_confirmClosingTerminalRunningProgram;
+#endif
+
QCheckBox* m_confirmClosingMultipleTabs;
QCheckBox* m_confirmScriptExecution;
};
#include <KLocalizedString>
#include <KNS3/KMoreToolsMenuFactory>
-#include <knewstuff_version.h>
#include <QMouseEvent>
*/
struct ViewState {
- ViewState(int current, const KItemSet selection, bool activated = false) :
+ ViewState(int current, const KItemSet &selection, bool activated = false) :
m_current(current),
m_selection(selection),
m_activated(activated)
RenameDialog* dialog = new RenameDialog(this, items);
connect(dialog, &RenameDialog::renamingFinished, this, &DolphinView::slotRenameDialogRenamingFinished);
- dialog->show();
- dialog->raise();
- dialog->activateWindow();
+ dialog->open();
}
// Assure that the current index remains visible when KFileItemModel
}
}
- if (items.count() > 0) {
+ if (!items.isEmpty()) {
const QUrl& url = items.first().first.url();
itemStates.insert(url.adjusted(QUrl::RemoveFilename).path(), items);
}
GeneralSettings* settings = GeneralSettings::self();
const bool useGlobalViewProps = settings->globalViewProps() || url.isEmpty();
bool useDetailsViewWithPath = false;
+ bool useRecentDocumentsView = false;
+ bool useDownloadsView = false;
// We try and save it to the file .directory in the directory being viewed.
// If the directory is not writable by the user or the directory is not local,
} else if (url.scheme() == QLatin1String("trash")) {
m_filePath = destinationDir(QStringLiteral("trash"));
useDetailsViewWithPath = true;
+ } else if (url.scheme() == QLatin1String("recentdocuments")) {
+ m_filePath = destinationDir(QStringLiteral("recentdocuments"));
+ useRecentDocumentsView = true;
} else if (url.isLocalFile()) {
m_filePath = url.toLocalFile();
#endif
m_filePath = destinationDir(QStringLiteral("local")) + m_filePath;
}
+
+ if (m_filePath == QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)) {
+ useDownloadsView = true;
+ }
} else {
m_filePath = destinationDir(QStringLiteral("remote")) + m_filePath;
}
if (useDetailsViewWithPath) {
setViewMode(DolphinView::DetailsView);
setVisibleRoles({"path"});
+ } else if (useRecentDocumentsView || useDownloadsView) {
+ setSortRole(QByteArrayLiteral("modificationtime"));
+ setSortOrder(Qt::DescendingOrder);
+
+ if (useRecentDocumentsView) {
+ setViewMode(DolphinView::DetailsView);
+ setVisibleRoles({QByteArrayLiteral("path")});
+ } else if (useDownloadsView) {
+ setSortFoldersFirst(false);
+ setGroupedSorting(true);
+ }
} else {
// The global view-properties act as default for directories without
// any view-property configuration. Constructing a ViewProperties