# KDE Application Version, managed by release script
set (RELEASE_SERVICE_VERSION_MAJOR "22")
-set (RELEASE_SERVICE_VERSION_MINOR "03")
-set (RELEASE_SERVICE_VERSION_MICRO "80")
+set (RELEASE_SERVICE_VERSION_MINOR "07")
+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})
Notifications
Crash
WindowSystem
+ WidgetsAddons
)
-find_package(KUserFeedback 1.0.0)
+find_package(KUserFeedback 1.2.0)
set_package_properties(KUserFeedback
PROPERTIES TYPE OPTIONAL
PURPOSE "Used for submission of telemetry data"
find_package(Phonon4Qt${QT_MAJOR_VERSION} CONFIG REQUIRED)
-find_package(PackageKitQt5)
-set_package_properties(PackageKitQt5
+find_package(PackageKitQt${QT_MAJOR_VERSION})
+set_package_properties(PackageKitQt${QT_MAJOR_VERSION}
PROPERTIES DESCRIPTION "Software Manager integration"
TYPE OPTIONAL
PURPOSE "Used in the service menu installer"
)
-if(PackageKitQt5_FOUND)
+if(PackageKitQt${QT_MAJOR_VERSION}_FOUND)
set(HAVE_PACKAGEKIT TRUE)
endif()
target_sources(dolphinprivate PRIVATE
kitemviews/kfileitemlistview.cpp
kitemviews/kfileitemlistwidget.cpp
+ kitemviews/kfileitemlisttostring.cpp
kitemviews/kfileitemmodel.cpp
kitemviews/kfileitemmodelrolesupdater.cpp
kitemviews/kitemlistcontainer.cpp
kitemviews/private/kitemlistviewanimation.cpp
kitemviews/private/kitemlistviewlayouter.cpp
kitemviews/private/kpixmapmodifier.cpp
- kitemviews/private/ktwofingerswipe.cpp
- kitemviews/private/ktwofingertap.cpp
settings/applyviewpropsjob.cpp
settings/viewmodes/viewmodesettings.cpp
settings/viewpropertiesdialog.cpp
KF5::NewStuff
KF5::Parts
KF5::WindowSystem
+ KF5::WidgetsAddons
)
if(HAVE_BALOO)
KF5::KCMUtils
KF5::DBusAddons
KF5::Notifications
- Phonon::phonon4qt5
+ Phonon::phonon4qt${QT_MAJOR_VERSION}
)
if (HAVE_KACTIVITIES)
}
}
+QAction *DolphinMainWindow::urlNavigatorHistoryAction(const KUrlNavigator *urlNavigator, int historyIndex, QObject *parent)
+{
+ const QUrl url = urlNavigator->locationUrl(historyIndex);
+
+ QString text = url.toDisplayString(QUrl::PreferLocalFile);
+
+ if (!urlNavigator->showFullPath()) {
+ const KFilePlacesModel *placesModel = DolphinPlacesModelSingleton::instance().placesModel();
+
+ const QModelIndex closestIdx = placesModel->closestItem(url);
+ if (closestIdx.isValid()) {
+ const QUrl placeUrl = placesModel->url(closestIdx);
+
+ text = placesModel->text(closestIdx);
+
+ QString pathInsidePlace = url.path().mid(placeUrl.path().length());
+
+ if (!pathInsidePlace.isEmpty() && !pathInsidePlace.startsWith(QLatin1Char('/'))) {
+ pathInsidePlace.prepend(QLatin1Char('/'));
+ }
+
+ if (pathInsidePlace != QLatin1Char('/')) {
+ text.append(pathInsidePlace);
+ }
+ }
+ }
+
+ QAction *action = new QAction(QIcon::fromTheme(KIO::iconNameForUrl(url)), text, parent);
+ action->setData(historyIndex);
+ return action;
+}
+
void DolphinMainWindow::slotAboutToShowBackPopupMenu()
{
const KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternalWithHistory();
int entries = 0;
m_backAction->menu()->clear();
for (int i = urlNavigator->historyIndex() + 1; i < urlNavigator->historySize() && entries < MaxNumberOfNavigationentries; ++i, ++entries) {
- QAction* action = new QAction(urlNavigator->locationUrl(i).toDisplayString(QUrl::PreferLocalFile), m_backAction->menu());
+ QAction *action = urlNavigatorHistoryAction(urlNavigator, i, m_backAction->menu());
action->setData(i);
m_backAction->menu()->addAction(action);
}
int entries = 0;
m_forwardAction->menu()->clear();
for (int i = urlNavigator->historyIndex() - 1; i >= 0 && entries < MaxNumberOfNavigationentries; --i, ++entries) {
- QAction* action = new QAction(urlNavigator->locationUrl(i).toDisplayString(QUrl::PreferLocalFile), m_forwardAction->menu());
+ QAction *action = urlNavigatorHistoryAction(urlNavigator, i, m_forwardAction->menu());
action->setData(i);
m_forwardAction->menu()->addAction(action);
}
*/
bool addHamburgerMenuToToolbar();
+ /** Creates an action representing an item in the URL navigator history */
+ static QAction *urlNavigatorHistoryAction(const KUrlNavigator *urlNavigator, int historyIndex, QObject *parent = nullptr);
+
private:
/**
* Implements a custom error handling for the undo manager. This
--- /dev/null
+/*
+ This file is part of the KDE project
+ SPDX-FileCopyrightText: 2022 Felix Ernst <felixernst@zohomail.eu>
+
+ SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
+*/
+
+#include "kfileitemlisttostring.h"
+
+#include <KFileItem>
+#include <KFileItemListProperties>
+#include <KLocalizedString>
+
+#include <QFontMetrics>
+#include <QString>
+
+QString fileItemListToString(KFileItemList items, int maximumTextWidth, QFontMetrics fontMetrics, ItemsState itemsState)
+{
+ QString text;
+ switch (items.count()) {
+ case 1:
+ text = i18nc("Textual representation of a file. %1 is the name of the file/folder.",
+ "\"%1\"", items.first().name());
+ break;
+ case 2:
+ text = i18nc("Textual representation of two files. %1 and %2 are names of files/folders.",
+ "\"%1\" and \"%2\"", items.first().name(), items.last().name());
+ break;
+ case 3:
+ text = i18nc("Textual representation of three files. %1, %2 and %3 are names of files/folders.",
+ "\"%1\", \"%2\" and \"%3\"",
+ items.first().name(), items.at(1).name(), items.last().name());
+ break;
+ case 4:
+ text = i18nc("Textual representation of four files. %1, %2, %3 and %4 are names of files/folders.",
+ "\"%1\", \"%2\", \"%3\" and \"%4\"",
+ items.first().name(), items.at(1).name(), items.at(2).name(), items.last().name());
+ break;
+ case 5:
+ text = i18nc("Textual representation of five files. %1, %2, %3, %4 and %5 are names of files/folders.",
+ "\"%1\", \"%2\", \"%3\", \"%4\" and \"%5\"",
+ items.first().name(), items.at(1).name(), items.at(2).name(), items.at(3).name(), items.last().name());
+ break;
+ default:
+ text = QString();
+ break;
+ }
+
+ // At some point the added clarity from the text starts being less important than the text width.
+ if (!text.isEmpty() && fontMetrics.horizontalAdvance(text) <= maximumTextWidth) {
+ return text;
+ }
+
+ const KFileItemListProperties properties(items);
+ if (itemsState == Selected) {
+ if (properties.isFile()) {
+ text = i18ncp("Textual representation of selected files. %1 is the number of files.",
+ "One Selected File", "%1 Selected Files", items.count());
+ } else if (properties.isDirectory()) {
+ text = i18ncp("Textual representation of selected folders. %1 is the number of folders.",
+ "One Selected Folder", "%1 Selected Folders", items.count());
+ } else {
+ text = i18ncp("Textual representation of selected fileitems. %1 is the number of files/folders.",
+ "One Selected Item", "%1 Selected Items", items.count());
+ }
+
+ if (fontMetrics.horizontalAdvance(text) <= maximumTextWidth) {
+ return text;
+ }
+ }
+
+ if (properties.isFile()) {
+ return i18ncp("Textual representation of files. %1 is the number of files.",
+ "One File", "%1 Files", items.count());
+ } else if (properties.isDirectory()) {
+ return i18ncp("Textual representation of folders. %1 is the number of folders.",
+ "One Folder", "%1 Folders", items.count());
+ } else {
+ return i18ncp("Textual representation of fileitems. %1 is the number of files/folders.",
+ "One Item", "%1 Items", items.count());
+ }
+}
--- /dev/null
+/*
+ This file is part of the KDE project
+ SPDX-FileCopyrightText: 2022 Felix Ernst <felixernst@zohomail.eu>
+
+ SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
+*/
+
+#ifndef KFILEITEMLISTTOSTRING_H
+#define KFILEITEMLISTTOSTRING_H
+
+class KFileItemList;
+class QFontMetrics;
+class QString;
+
+enum ItemsState {
+ None,
+ Selected
+};
+
+/**
+ * @brief Generates a textual representation of the given list of KFileItems.
+ *
+ * This method is especially useful to be very explicit about which items will be affected by an action.
+ * For example can a label for a delete button be enriched to say "Permanantly Delete `picture1` and `picture2`"
+ * but also "Permanently Delete 7 Selected Folders" without requiring a huge amount of new translations for this.
+ *
+ * Unfortunately this doesn't always work.
+ *
+ * For some texts and some languages this wide range of words cannot be inserted into a text while staying
+ * grammatically correct. Because of this you will probably need to write a fallback for these languages.
+ * Something like this:
+ * \code
+ * // i18n: @action:inmenu menu with actions like copy, paste, rename.
+ * // %2 is a textual representation of the currently selected files or folders. This can be the name of
+ * // the file/files like "file1" or "file1, file2 and file3" or an aggregate like "8 Selected Folders".
+ * // If this sort of word puzzle can not be correctly translated in your language, translate it as "NULL" (without the quotes)
+ * // and a fallback will be used.
+ * auto buttonText = i18ncp("@action A more elaborate and clearly worded version of the Delete action", "Permanently Delete %2", "Permanently Delete %2", items.count(), fileItemListToString(items, fontMetrics.averageCharWidth() * 20, fontMetrics));
+ * if (buttonText == QStringLiteral("NULL")) {
+ * buttonText = i18ncp("@action Delete button label. %1 is the number of items to be deleted.",
+ * "Permanently Delete %1 Item", "Permanently Delete %1 Items", items.count())
+ * }
+ * \endcode
+ * (The i18n call should be completely in the line following the i18n: comment without any line breaks within the i18n call or the comment might not be correctly extracted. See: https://commits.kde.org/kxmlgui/a31135046e1b3335b5d7bbbe6aa9a883ce3284c1 )
+ *
+ * @param items The KFileItemList for which a QString should be generated.
+ * @param maximumTextWidth The maximum width/horizontalAdvance the QString should have. Keep scaling in mind.
+ * @param fontMetrics the fontMetrics for the font that is used to calculate the maximumTextWidth.
+ * @param itemsState A state of the @p items that should be spelled out in the returned QString.
+ * @returns the names of the @p items separated by commas if that is below the @p maximumCharacterWidth.
+ * Otherwise returns something like "5 Files", "8 Selected Folders" or "60 Items"
+ * while being as specific as possible.
+ */
+QString fileItemListToString(KFileItemList items, int maximumTextWidth, QFontMetrics fontMetrics, ItemsState itemsState = ItemsState::None);
+
+#endif // KFILEITEMLISTTOSTRING_H
#include <KDirLister>
#include <KIO/Job>
-#include <KIO/kio_version.h>
+#include <kio_version.h>
#include <KLocalizedString>
#include <KLazyLocalizedString>
#include <KUrlMimeData>
#include "kitemlistview.h"
#include "private/kitemlistkeyboardsearchmanager.h"
#include "private/kitemlistrubberband.h"
-#include "private/ktwofingerswipe.h"
-#include "private/ktwofingertap.h"
#include "views/draganddrophelper.h"
+#include <KTwoFingerSwipe>
+#include <KTwoFingerTap>
+
#include <QAccessible>
#include <QApplication>
#include <QDrag>
QString ret = m_customizedFontMetrics.elidedText(text.chopped(extensionLength),
Qt::ElideRight,
elidingWidth - extensionWidth);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
ret.append(text.rightRef(extensionLength));
+#else
+ ret.append(QStringView(text).right(extensionLength));
+#endif
return ret;
}
}
+++ /dev/null
-/*
- * SPDX-FileCopyrightText: 2020 Steffen Hartleib <steffenhartleib@t-online.de>
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-// Self
-#include "ktwofingerswipe.h"
-
-// Qt
-#include <QTouchEvent>
-#include <QLineF>
-
-KTwoFingerSwipeRecognizer::KTwoFingerSwipeRecognizer() :
- QGestureRecognizer(),
- m_touchBeginnTimestamp(0),
- m_gestureAlreadyTriggered(false)
-{
-}
-
-KTwoFingerSwipeRecognizer::~KTwoFingerSwipeRecognizer()
-{
-}
-
-QGesture* KTwoFingerSwipeRecognizer::create(QObject*)
-{
- return static_cast<QGesture*>(new KTwoFingerSwipe());
-}
-
-QGestureRecognizer::Result KTwoFingerSwipeRecognizer::recognize(QGesture* gesture, QObject* watched, QEvent* event)
-{
- Q_UNUSED(watched)
-
- KTwoFingerSwipe* const kTwoFingerSwipe = static_cast<KTwoFingerSwipe*>(gesture);
- const QTouchEvent* touchEvent = static_cast<const QTouchEvent*>(event);
-
- const int maxTimeFrameForSwipe = 90;
- const int minDistanceForSwipe = 30;
-
- switch (event->type()) {
- case QEvent::TouchBegin: {
- m_touchBeginnTimestamp = touchEvent->timestamp();
- m_gestureAlreadyTriggered = false;
- kTwoFingerSwipe->setHotSpot(touchEvent->touchPoints().first().startScreenPos());
- kTwoFingerSwipe->setPos(touchEvent->touchPoints().first().startPos());
- kTwoFingerSwipe->setScreenPos(touchEvent->touchPoints().first().startScreenPos());
- kTwoFingerSwipe->setScenePos(touchEvent->touchPoints().first().startScenePos());
- return MayBeGesture;
- }
-
- case QEvent::TouchUpdate: {
- const qint64 now = touchEvent->timestamp();
- const qint64 elapsedTime = now - m_touchBeginnTimestamp;
- const QPointF distance = touchEvent->touchPoints().first().startPos() - touchEvent->touchPoints().first().pos();
- kTwoFingerSwipe->setHotSpot(touchEvent->touchPoints().first().startScreenPos());
- kTwoFingerSwipe->setPos(touchEvent->touchPoints().first().startPos());
- kTwoFingerSwipe->setScreenPos(touchEvent->touchPoints().first().startScreenPos());
- kTwoFingerSwipe->setScenePos(touchEvent->touchPoints().first().startScenePos());
- const QLineF ql = QLineF(touchEvent->touchPoints().first().startPos(), touchEvent->touchPoints().first().pos());
- kTwoFingerSwipe->setSwipeAngle(ql.angle());
-
- if (touchEvent->touchPoints().size() > 2) {
- return CancelGesture;
- }
-
- if (touchEvent->touchPoints().size() == 2) {
- if ((elapsedTime) > maxTimeFrameForSwipe) {
- return CancelGesture;
- }
-
- if (distance.manhattanLength() >= minDistanceForSwipe &&
- (elapsedTime) <= maxTimeFrameForSwipe && !m_gestureAlreadyTriggered) {
- m_gestureAlreadyTriggered = true;
- return FinishGesture;
- } else if ((elapsedTime) <= maxTimeFrameForSwipe && !m_gestureAlreadyTriggered) {
- return TriggerGesture;
- }
- }
- break;
- }
-
- default:
- return Ignore;
- }
- return Ignore;
-}
-
-KTwoFingerSwipe::KTwoFingerSwipe(QObject* parent) :
- QGesture(parent),
- m_pos(QPointF(-1, -1)),
- m_screenPos(QPointF(-1, -1)),
- m_scenePos(QPointF(-1, -1)),
- m_swipeAngle(0.0)
-{
-}
-
-KTwoFingerSwipe::~KTwoFingerSwipe()
-{
-}
-
-QPointF KTwoFingerSwipe::pos() const
-{
- return m_pos;
-}
-
-void KTwoFingerSwipe::setPos(QPointF _pos)
-{
- m_pos = _pos;
-}
-
-QPointF KTwoFingerSwipe::screenPos() const
-{
- return m_screenPos;
-}
-
-void KTwoFingerSwipe::setScreenPos(QPointF _screenPos)
-{
- m_screenPos = _screenPos;
-}
-
-QPointF KTwoFingerSwipe::scenePos() const
-{
- return m_scenePos;
-}
-
-void KTwoFingerSwipe::setScenePos(QPointF _scenePos)
-{
- m_scenePos = _scenePos;
-}
-
-qreal KTwoFingerSwipe::swipeAngle() const
-{
- return m_swipeAngle;
-}
- void KTwoFingerSwipe::setSwipeAngle(qreal _swipeAngle)
-{
- m_swipeAngle = _swipeAngle;
-}
-
+++ /dev/null
-/*
- * SPDX-FileCopyrightText: 2020 Steffen Hartleib <steffenhartleib@t-online.de>
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#ifndef KTWOFINGERSWIPE_H
-#define KTWOFINGERSWIPE_H
-
-#include "dolphin_export.h"
-// Qt
-#include <QGesture>
-#include <QGestureRecognizer>
-
-class DOLPHIN_EXPORT KTwoFingerSwipe : public QGesture
-{
- Q_OBJECT
- Q_PROPERTY(QPointF pos READ pos WRITE setPos)
- Q_PROPERTY(QPointF screenPos READ screenPos WRITE setScreenPos)
- Q_PROPERTY(QPointF scenePos READ scenePos WRITE setScenePos)
- Q_PROPERTY(qreal swipeAngle READ swipeAngle WRITE setSwipeAngle)
-public:
- explicit KTwoFingerSwipe(QObject* parent = nullptr);
- ~KTwoFingerSwipe() override;
- QPointF pos() const;
- void setPos(QPointF pos);
- QPointF screenPos() const;
- void setScreenPos(QPointF screenPos);
- QPointF scenePos() const;
- void setScenePos(QPointF scenePos);
- qreal swipeAngle() const;
- void setSwipeAngle(qreal swipeAngle);
-private:
- QPointF m_pos;
- QPointF m_screenPos;
- QPointF m_scenePos;
- qreal m_swipeAngle;
-};
-
-class DOLPHIN_EXPORT KTwoFingerSwipeRecognizer : public QGestureRecognizer
-{
-public:
- explicit KTwoFingerSwipeRecognizer();
- ~KTwoFingerSwipeRecognizer() override;
- QGesture* create(QObject*) override;
- Result recognize(QGesture*, QObject*, QEvent*) override;
-private:
- Q_DISABLE_COPY( KTwoFingerSwipeRecognizer )
- qint64 m_touchBeginnTimestamp;
- bool m_gestureAlreadyTriggered;
-};
-
-#endif /* KTWOFINGERSWIPE_H */
-
+++ /dev/null
-/*
- * SPDX-FileCopyrightText: 2020 Steffen Hartleib <steffenhartleib@t-online.de>
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-// Self
-#include "ktwofingertap.h"
-
-// Qt
-#include <QTouchEvent>
-#include <QApplication>
-#include <QGraphicsWidget>
-
-KTwoFingerTapRecognizer::KTwoFingerTapRecognizer() :
- QGestureRecognizer(),
- m_gestureTriggered(false)
-{
-}
-
-KTwoFingerTapRecognizer::~KTwoFingerTapRecognizer()
-{
-}
-
-QGesture* KTwoFingerTapRecognizer::create(QObject*)
-{
- return static_cast<QGesture*>(new KTwoFingerTap());
-}
-
-QGestureRecognizer::Result KTwoFingerTapRecognizer::recognize(QGesture* gesture, QObject* watched, QEvent* event)
-{
- if (qobject_cast<QGraphicsWidget*>(watched)) {
- return Ignore;
- }
-
- KTwoFingerTap* const kTwoFingerTap = static_cast<KTwoFingerTap*>(gesture);
- const QTouchEvent* touchEvent = static_cast<const QTouchEvent*>(event);
-
- switch (event->type()) {
- case QEvent::TouchBegin: {
- kTwoFingerTap->setHotSpot(touchEvent->touchPoints().first().startScreenPos());
- kTwoFingerTap->setPos(touchEvent->touchPoints().first().startPos());
- kTwoFingerTap->setScreenPos(touchEvent->touchPoints().first().startScreenPos());
- kTwoFingerTap->setScenePos(touchEvent->touchPoints().first().startScenePos());
- m_gestureTriggered = false;
- return MayBeGesture;
- }
-
- case QEvent::TouchUpdate: {
-
- if (touchEvent->touchPoints().size() > 2) {
- m_gestureTriggered = false;
- return CancelGesture;
- }
-
- if (touchEvent->touchPoints().size() == 2) {
- if ((touchEvent->touchPoints().first().startPos() - touchEvent->touchPoints().first().pos()).manhattanLength() >= QApplication::startDragDistance()) {
- m_gestureTriggered = false;
- return CancelGesture;
- }
- if ((touchEvent->touchPoints().at(1).startPos() - touchEvent->touchPoints().at(1).pos()).manhattanLength() >= QApplication::startDragDistance()) {
- m_gestureTriggered = false;
- return CancelGesture;
- }
- if (touchEvent->touchPointStates() & Qt::TouchPointPressed) {
- m_gestureTriggered = true;
- }
- if (touchEvent->touchPointStates() & Qt::TouchPointReleased && m_gestureTriggered) {
- m_gestureTriggered = false;
- return FinishGesture;
- }
- }
- break;
- }
-
- default:
- return Ignore;
- }
- return Ignore;
-}
-
-KTwoFingerTap::KTwoFingerTap(QObject* parent) :
- QGesture(parent),
- m_pos(QPointF(-1, -1)),
- m_screenPos(QPointF(-1, -1)),
- m_scenePos(QPointF(-1, -1))
-{
-}
-
-KTwoFingerTap::~KTwoFingerTap()
-{
-}
-
-QPointF KTwoFingerTap::pos() const
-{
- return m_pos;
-}
-
-void KTwoFingerTap::setPos(QPointF _pos)
-{
- m_pos = _pos;
-}
-
-QPointF KTwoFingerTap::screenPos() const
-{
- return m_screenPos;
-}
-
-void KTwoFingerTap::setScreenPos(QPointF _screenPos)
-{
- m_screenPos = _screenPos;
-}
-
-QPointF KTwoFingerTap::scenePos() const
-{
- return m_scenePos;
-}
-
-void KTwoFingerTap::setScenePos(QPointF _scenePos)
-{
- m_scenePos = _scenePos;
-}
+++ /dev/null
-/*
- * SPDX-FileCopyrightText: 2020 Steffen Hartleib <steffenhartleib@t-online.de>
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#ifndef KTWOFINGERTAP_H
-#define KTWOFINGERTAP_H
-
-#include <dolphin_export.h>
-// Qt
-#include <QGesture>
-#include <QGestureRecognizer>
-
-class DOLPHIN_EXPORT KTwoFingerTap : public QGesture
-{
- Q_OBJECT
- Q_PROPERTY(QPointF pos READ pos WRITE setPos)
- Q_PROPERTY(QPointF screenPos READ screenPos WRITE setScreenPos)
- Q_PROPERTY(QPointF scenePos READ scenePos WRITE setScenePos)
-public:
- explicit KTwoFingerTap(QObject* parent = nullptr);
- ~KTwoFingerTap() override;
- QPointF pos() const;
- void setPos(QPointF pos);
- QPointF screenPos() const;
- void setScreenPos(QPointF screenPos);
- QPointF scenePos() const;
- void setScenePos(QPointF scenePos);
-private:
- QPointF m_pos;
- QPointF m_screenPos;
- QPointF m_scenePos;
-};
-
-class DOLPHIN_EXPORT KTwoFingerTapRecognizer : public QGestureRecognizer
-{
-public:
- explicit KTwoFingerTapRecognizer();
- ~KTwoFingerTapRecognizer() override;
- QGesture* create(QObject*) override;
- Result recognize(QGesture*, QObject*, QEvent*) override;
-private:
- Q_DISABLE_COPY(KTwoFingerTapRecognizer)
- bool m_gestureTriggered;
-};
-
-#endif /* KTWOFINGERTAP_H */
Keywords[nl]=bestanden;bestandsbeheer;bladeren in bestanden;samba;netwerk-shares;verkenner;zoeksysteem;
Keywords[nn]=filer;filhandsaming;filutforsking;samba;nettverksressursar;Explorer;Finder;
Keywords[pl]=pliki;zarządzenie plikami;przeglądanie plików;samba;udziały sieciowe;Przeglądarka;Finder;
+Keywords[pt]=ficheiros;gestão de ficheiros;navegação de ficheiros;samba;partilhas de rede;Explorador;Pesquisa;
Keywords[pt_BR]=arquivo;gerenciamento de arquivos;navegação de arquivos;samba;compartilhamentos de rede;explorador;localizador;
Keywords[ro]=fișiere;gestiune fișiere;răsfoire fișiere;samba;partajări de rețea;unități de rețea;Explorer;Finder;
Keywords[ru]=files;file management;file browsing;samba;network shares;Explorer;Finder;файлы,управление файлами,просмотр файлов,сетевые папки
-Keywords[sk]=súbory;správa súborov;prehliadanie súborov;samba;sieťové akcie;Prieskumník;Vyhľadávač;
Keywords[sl]=datoteke;upravljanje z datotekami;brskanje po datotekah;samba;mrežni diski;Raziskovalec;Iskalec;
Keywords[sv]=filer;filhantering;filbläddring;samba;delade nätverksresurser;Utforskare;Finder;
Keywords[tr]=dosyalar;dosya yönetimi;dosya göz at;samba;ağ paylaşımları;Explorer;Finder;
#include <QWidget>
#include <KIO/EmptyTrashJob>
-#include <KIOWidgets/KDirLister>
+#include <KDirLister>
class Trash: public QObject
{
#include "dolphinviewactionhandler.h"
#include "dolphindebug.h"
+#include "kitemviews/kfileitemlisttostring.h"
#include "kitemviews/kfileitemmodel.h"
#include "settings/viewpropertiesdialog.h"
#include "views/zoomlevelinfo.h"
void DolphinViewActionHandler::slotSelectionChanged(const KFileItemList& selection)
{
QString basicActionsMenuText;
- switch (selection.count()) {
- case 0:
+ if (selection.isEmpty()) {
basicActionsMenuText =
i18nc("@action:inmenu menu with actions like copy, paste, rename. The user's selection is empty when this text is shown.",
"Actions for Current View");
- break;
- case 1:
- basicActionsMenuText =
- i18nc("@action:inmenu menu with actions like copy, paste, rename. %1 is the name of the singular selected file/folder.",
- "Actions for \"%1\"", selection.first().name());
- break;
- case 2:
- basicActionsMenuText =
- i18nc("@action:inmenu menu with actions like copy, paste, rename. %1 and %2 are names of files/folders.",
- "Actions for \"%1\" and \"%2\"", selection.first().name(), selection.last().name());
- break;
- case 3:
- basicActionsMenuText =
- i18nc("@action:inmenu menu with actions like copy, paste, rename. %1, %2 and %3 are names of files/folders.",
- "Actions for \"%1\", \"%2\" and \"%3\"",
- selection.first().name(), selection.at(1).name(), selection.last().name());
- break;
- default:
- basicActionsMenuText = QString();
- break;
+ } else {
+ QFontMetrics fontMetrics = QMenu().fontMetrics();
+ // i18n: @action:inmenu menu with actions like copy, paste, rename.
+ // %1 is a textual representation of the currently selected files or folders. This can be the name of
+ // the file/files like "file1" or "file1, file2 and file3" or an aggregate like "8 Selected Folders".
+ // If this sort of word puzzle can not be correctly translated in your language, translate it as "NULL" (without the quotes)
+ // and a fallback will be used.
+ basicActionsMenuText = i18n("Actions for %1", fileItemListToString(selection, fontMetrics.averageCharWidth() * 40, fontMetrics, ItemsState::Selected));
}
- // At some point the added clarity from the text starts being less important than the menu width.
- if (basicActionsMenuText.isEmpty() || basicActionsMenuText.length() > 40) {
+ if (basicActionsMenuText == QStringLiteral("NULL")) {
const KFileItemListProperties properties(selection);
- if (properties.isFile()) {
- basicActionsMenuText =
- i18ncp("@action:inmenu menu with actions like copy, paste, rename. %1 is the amount of selected files/folders.",
- "Actions for One Selected File", "Actions for %1 Selected Files", selection.count());
- } else if (properties.isDirectory()) {
- basicActionsMenuText =
- i18ncp("@action:inmenu menu with actions like copy, paste, rename. %1 is the amount of selected files/folders.",
- "Actions for One Selected Folder", "Actions for %1 Selected Folders", selection.count());
- } else {
- basicActionsMenuText =
- i18ncp("@action:inmenu menu with actions like copy, paste, rename. %1 is the amount of selected files/folders.",
- "Actions for One Selected Item", "Actions for %1 Selected Items", selection.count());
- }
+ basicActionsMenuText =
+ i18ncp("@action:inmenu menu with actions like copy, paste, rename. %1 is the amount of selected files/folders.",
+ "Actions for One Selected Item", "Actions for %1 Selected Items", selection.count());
}
QAction *basicActionsMenu = m_actionCollection->action(QStringLiteral("basic_actions"));
m_showToolTipTimer(nullptr),
m_contentRetrievalTimer(nullptr),
m_transientParent(nullptr),
- m_fileMetaDataWidget(nullptr),
m_toolTipRequested(false),
m_metaDataRequested(false),
m_appliedWaitCursor(false),
ToolTipManager::~ToolTipManager()
{
+ if (!m_fileMetaDatWidgetOwnershipTransferred) {
+ delete m_fileMetaDataWidget;
+ }
}
void ToolTipManager::showToolTip(const KFileItem& item, const QRectF& itemRect, QWindow *transientParent)
{
- hideToolTip();
+ hideToolTip(HideBehavior::Instantly);
m_itemRect = itemRect.toRect();
// Only start the retrieving of the content, when the mouse has been over this
// item for 200 milliseconds. This prevents a lot of useless preview jobs and
// meta data retrieval, when passing rapidly over a lot of items.
- m_fileMetaDataWidget.reset(new DolphinFileMetaDataWidget());
- connect(m_fileMetaDataWidget.data(), &DolphinFileMetaDataWidget::metaDataRequestFinished,
- this, &ToolTipManager::slotMetaDataRequestFinished);
- connect(m_fileMetaDataWidget.data(), &DolphinFileMetaDataWidget::urlActivated,
- this, &ToolTipManager::urlActivated);
+ if (!m_fileMetaDataWidget) {
+ m_fileMetaDataWidget = new DolphinFileMetaDataWidget();
+ connect(m_fileMetaDataWidget, &DolphinFileMetaDataWidget::metaDataRequestFinished, this, &ToolTipManager::slotMetaDataRequestFinished);
+ connect(m_fileMetaDataWidget, &DolphinFileMetaDataWidget::urlActivated, this, &ToolTipManager::urlActivated);
+ }
m_contentRetrievalTimer->start();
m_showToolTipTimer->start();
if (!m_tooltipWidget) {
m_tooltipWidget.reset(new KToolTipWidget());
}
- m_tooltipWidget->showBelow(m_itemRect, m_fileMetaDataWidget.data(), m_transientParent);
+ m_tooltipWidget->showBelow(m_itemRect, m_fileMetaDataWidget, m_transientParent);
+ // At this point KToolTipWidget adopted our parent-less metadata widget.
+ m_fileMetaDatWidgetOwnershipTransferred = true;
+
m_toolTipRequested = false;
}
QWindow* m_transientParent;
QScopedPointer<KToolTipWidget> m_tooltipWidget;
- QScopedPointer<DolphinFileMetaDataWidget> m_fileMetaDataWidget;
+ DolphinFileMetaDataWidget *m_fileMetaDataWidget = nullptr;
+
+ /// Whether ownership of the metadata widget was transferred
+ /// over to the KToolTipWidget (i.e. we should not delete it
+ /// anymore)
+ bool m_fileMetaDatWidgetOwnershipTransferred = false;
bool m_toolTipRequested;
bool m_metaDataRequested;