mirror of
https://invent.kde.org/system/dolphin
synced 2024-11-05 18:47:12 +00:00
Improve code quality
This commit is contained in:
parent
8e55f2c240
commit
78cffd2979
15 changed files with 147 additions and 79 deletions
|
@ -125,7 +125,7 @@ DolphinMainWindow::DolphinMainWindow() :
|
||||||
setComponentName(QStringLiteral("dolphin"), QGuiApplication::applicationDisplayName());
|
setComponentName(QStringLiteral("dolphin"), QGuiApplication::applicationDisplayName());
|
||||||
setObjectName(QStringLiteral("Dolphin#"));
|
setObjectName(QStringLiteral("Dolphin#"));
|
||||||
|
|
||||||
// setStateConfigGroup("State");
|
setStateConfigGroup("State");
|
||||||
|
|
||||||
connect(&DolphinNewFileMenuObserver::instance(), &DolphinNewFileMenuObserver::errorMessage,
|
connect(&DolphinNewFileMenuObserver::instance(), &DolphinNewFileMenuObserver::errorMessage,
|
||||||
this, &DolphinMainWindow::showErrorMessage);
|
this, &DolphinMainWindow::showErrorMessage);
|
||||||
|
@ -1675,8 +1675,7 @@ void DolphinMainWindow::setupActions()
|
||||||
QAction *toggleSelectionModeAction = actionCollection()->addAction(QStringLiteral("toggle_selection_mode"));
|
QAction *toggleSelectionModeAction = actionCollection()->addAction(QStringLiteral("toggle_selection_mode"));
|
||||||
// i18n: This action toggles a selection mode.
|
// i18n: This action toggles a selection mode.
|
||||||
toggleSelectionModeAction->setText(i18nc("@action:inmenu", "Select Files and Folders"));
|
toggleSelectionModeAction->setText(i18nc("@action:inmenu", "Select Files and Folders"));
|
||||||
// i18n: Opens a selection mode for selecting files/folders and later selecting an action that acts on them.
|
// i18n: Opens a selection mode for selecting files/folders.
|
||||||
// So in a way "Select" here is used to mean both "Select files" and also "Select what to do" but mostly the first.
|
|
||||||
// The text is kept so unspecific because it will be shown on the toolbar where space is at a premium.
|
// The text is kept so unspecific because it will be shown on the toolbar where space is at a premium.
|
||||||
toggleSelectionModeAction->setIconText(i18nc("@action:intoolbar", "Select"));
|
toggleSelectionModeAction->setIconText(i18nc("@action:intoolbar", "Select"));
|
||||||
toggleSelectionModeAction->setWhatsThis(xi18nc("@info:whatsthis", "<para>This application only knows which files or folders should be acted on if they are"
|
toggleSelectionModeAction->setWhatsThis(xi18nc("@info:whatsthis", "<para>This application only knows which files or folders should be acted on if they are"
|
||||||
|
|
|
@ -22,10 +22,13 @@ void ActionTextHelper::registerTextWhenNothingIsSelected(QAction *action, QStrin
|
||||||
void ActionTextHelper::textsWhenNothingIsSelectedEnabled(bool enabled)
|
void ActionTextHelper::textsWhenNothingIsSelectedEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
for (auto i = m_registeredActionTextChanges.begin(); i != m_registeredActionTextChanges.end(); ++i) {
|
for (auto i = m_registeredActionTextChanges.begin(); i != m_registeredActionTextChanges.end(); ++i) {
|
||||||
if (!i->action) {
|
while (!i->action) {
|
||||||
i = m_registeredActionTextChanges.erase(i);
|
i = m_registeredActionTextChanges.erase(i);
|
||||||
continue;
|
if (i == m_registeredActionTextChanges.end()) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (enabled && i->textStateOfRegisteredText == TextWhenNothingIsSelected) {
|
if (enabled && i->textStateOfRegisteredText == TextWhenNothingIsSelected) {
|
||||||
QString textWhenSomethingIsSelected = i->action->text();
|
QString textWhenSomethingIsSelected = i->action->text();
|
||||||
i->action->setText(i->registeredText);
|
i->action->setText(i->registeredText);
|
||||||
|
|
|
@ -17,6 +17,11 @@ namespace SelectionMode
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Helps changing the texts of actions depending on the current selection.
|
* @brief Helps changing the texts of actions depending on the current selection.
|
||||||
|
*
|
||||||
|
* This is useful for actions that directly trigger a change when there is a selection and do something
|
||||||
|
* different when nothing is selected. For example should the copy action read "Copy" when items are
|
||||||
|
* selected but when no items are selected it can read "Copy…" since triggering it will enter selection
|
||||||
|
* mode and ask users to select the files they want to copy first.
|
||||||
*/
|
*/
|
||||||
class ActionTextHelper : QObject
|
class ActionTextHelper : QObject
|
||||||
{
|
{
|
||||||
|
@ -25,7 +30,7 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the text of \a action to \a text whenever textsWhenNothingIsSelectedEnabled(true) is called.
|
* Changes the text of \a action to \a text whenever textsWhenNothingIsSelectedEnabled(true) is called.
|
||||||
* The texts can be changed back by calling textsWhenNothingIsSelectedEnabled(false) is called.
|
* The texts can be changed back by calling textsWhenNothingIsSelectedEnabled(false).
|
||||||
* @see textsWhenNothingIsSelectedEnabled()
|
* @see textsWhenNothingIsSelectedEnabled()
|
||||||
*/
|
*/
|
||||||
void registerTextWhenNothingIsSelected(QAction *action, QString registeredText);
|
void registerTextWhenNothingIsSelected(QAction *action, QString registeredText);
|
||||||
|
|
|
@ -21,6 +21,9 @@ namespace SelectionMode
|
||||||
* @brief Small wrapper/helper class that contains an action and its widget.
|
* @brief Small wrapper/helper class that contains an action and its widget.
|
||||||
*
|
*
|
||||||
* This class takes neither the responsibility for deleting its action() nor its widget().
|
* This class takes neither the responsibility for deleting its action() nor its widget().
|
||||||
|
*
|
||||||
|
* This class is only used from BottomBarContentsContainer currently.
|
||||||
|
* @see BottomBarContentsContainer
|
||||||
*/
|
*/
|
||||||
class ActionWithWidget
|
class ActionWithWidget
|
||||||
{
|
{
|
||||||
|
@ -28,9 +31,9 @@ public:
|
||||||
ActionWithWidget(QAction *action);
|
ActionWithWidget(QAction *action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect @p action and @p button using copyActionDataToButton() and the
|
* Connect @p action and @p button using copyActionDataToButton() and
|
||||||
* wraps the two together in the ActionWithWidget object.
|
* wraps the two together in a ActionWithWidget object.
|
||||||
* ActionWithWidget doesn't take any ownership.
|
* ActionWithWidget doesn't take any ownership over the parameters.
|
||||||
*
|
*
|
||||||
* @see copyActionDataToButton()
|
* @see copyActionDataToButton()
|
||||||
*
|
*
|
||||||
|
@ -38,7 +41,7 @@ public:
|
||||||
*/
|
*/
|
||||||
ActionWithWidget(QAction *action, QAbstractButton *button);
|
ActionWithWidget(QAction *action, QAbstractButton *button);
|
||||||
|
|
||||||
/** @returns the action of this object. Crashes if that action has been deleted elsewhere in the meantime. */
|
/** @returns the action of this object. */
|
||||||
inline QAction *action() {
|
inline QAction *action() {
|
||||||
Q_CHECK_PTR(m_action);
|
Q_CHECK_PTR(m_action);
|
||||||
return m_action;
|
return m_action;
|
||||||
|
@ -69,7 +72,7 @@ private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A small helper method.
|
* A small helper method.
|
||||||
* @return a button with the correct styling for the general mode of the SelectionModeBottomBar which can be added to its layout.
|
* @return a button with the correct styling for the general mode of the BottomBarContentsContainer which can be added to its layout.
|
||||||
*/
|
*/
|
||||||
QAbstractButton *newButtonForAction(QAction *action, QWidget *parent);
|
QAbstractButton *newButtonForAction(QAction *action, QWidget *parent);
|
||||||
|
|
||||||
|
|
|
@ -54,9 +54,11 @@ void BackgroundColorHelper::slotPaletteChanged()
|
||||||
{
|
{
|
||||||
updateBackgroundColor();
|
updateBackgroundColor();
|
||||||
for (auto i = m_colorControlledWidgets.begin(); i != m_colorControlledWidgets.end(); ++i) {
|
for (auto i = m_colorControlledWidgets.begin(); i != m_colorControlledWidgets.end(); ++i) {
|
||||||
if (!*i) {
|
while (!*i) {
|
||||||
i = m_colorControlledWidgets.erase(i);
|
i = m_colorControlledWidgets.erase(i);
|
||||||
continue;
|
if (i == m_colorControlledWidgets.end()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setBackgroundColorForWidget(*i, m_backgroundColor);
|
setBackgroundColorForWidget(*i, m_backgroundColor);
|
||||||
}
|
}
|
||||||
|
@ -83,7 +85,8 @@ void BackgroundColorHelper::updateBackgroundColor()
|
||||||
}
|
}
|
||||||
|
|
||||||
m_backgroundColor = QColor::fromHsv(newHue,
|
m_backgroundColor = QColor::fromHsv(newHue,
|
||||||
// Saturation should be closer to the active color because otherwise the selection mode color might overpower it.
|
// Saturation should be closer to the saturation of the active color
|
||||||
|
// because otherwise the selection mode color might overpower it.
|
||||||
.7 * activeBackgroundColor.saturation() + .3 * positiveBackgroundColor.saturation(),
|
.7 * activeBackgroundColor.saturation() + .3 * positiveBackgroundColor.saturation(),
|
||||||
(activeBackgroundColor.value() + positiveBackgroundColor.value()) / 2,
|
(activeBackgroundColor.value() + positiveBackgroundColor.value()) / 2,
|
||||||
(activeBackgroundColor.alpha() + positiveBackgroundColor.alpha()) / 2);
|
(activeBackgroundColor.alpha() + positiveBackgroundColor.alpha()) / 2);
|
||||||
|
|
|
@ -28,20 +28,30 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the background color of @p widget to a distinct color scheme matching color which makes it clear that the widget belongs to the selection mode.
|
* Changes the background color of @p widget to a distinct color scheme matching color which makes it clear that the widget belongs to the selection mode.
|
||||||
|
* The background color of @p widget will from now on be updated automatically when the palette of the application changes.
|
||||||
*/
|
*/
|
||||||
void controlBackgroundColor(QWidget *widget);
|
void controlBackgroundColor(QWidget *widget);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BackgroundColorHelper();
|
BackgroundColorHelper();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the palette of the application changes.
|
||||||
|
* Triggers updateBackgroundColor() and the updates the background color of m_colorControlledWidgets.
|
||||||
|
* @see updateBackgroundColor
|
||||||
|
*/
|
||||||
void slotPaletteChanged();
|
void slotPaletteChanged();
|
||||||
|
|
||||||
|
/** Calculates a new m_colorControlledWidgets based on the current colour scheme of the application. */
|
||||||
void updateBackgroundColor();
|
void updateBackgroundColor();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// The widgets who have given up control over the background color to BackgroundColorHelper.
|
||||||
std::vector<QPointer<QWidget>> m_colorControlledWidgets;
|
std::vector<QPointer<QWidget>> m_colorControlledWidgets;
|
||||||
|
/// The color to be used for the widgets' backgrounds.
|
||||||
QColor m_backgroundColor;
|
QColor m_backgroundColor;
|
||||||
|
|
||||||
|
/// Singleton object
|
||||||
static BackgroundColorHelper *s_instance;
|
static BackgroundColorHelper *s_instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,6 @@
|
||||||
#include "backgroundcolorhelper.h"
|
#include "backgroundcolorhelper.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
#include <KActionCollection>
|
|
||||||
#include <KFileItem>
|
|
||||||
#include <KFileItemListProperties>
|
|
||||||
#include <KStandardAction>
|
|
||||||
|
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
#include <QResizeEvent>
|
#include <QResizeEvent>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
|
@ -87,7 +82,6 @@ void BottomBar::setVisibleInternal(bool visible, Animated animated)
|
||||||
m_heightAnimation->setDuration(2 *
|
m_heightAnimation->setDuration(2 *
|
||||||
style()->styleHint(QStyle::SH_Widget_Animation_Duration, nullptr, this) *
|
style()->styleHint(QStyle::SH_Widget_Animation_Duration, nullptr, this) *
|
||||||
GlobalConfig::animationDurationFactor());
|
GlobalConfig::animationDurationFactor());
|
||||||
|
|
||||||
m_heightAnimation->setStartValue(height());
|
m_heightAnimation->setStartValue(height());
|
||||||
m_heightAnimation->setEasingCurve(QEasingCurve::OutCubic);
|
m_heightAnimation->setEasingCurve(QEasingCurve::OutCubic);
|
||||||
if (visible) {
|
if (visible) {
|
||||||
|
@ -166,7 +160,7 @@ void BottomBar::resizeEvent(QResizeEvent *resizeEvent)
|
||||||
return QWidget::resizeEvent(resizeEvent);
|
return QWidget::resizeEvent(resizeEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_contentsContainer->updateForNewWidth();
|
m_contentsContainer->adaptToNewBarWidth(width());
|
||||||
|
|
||||||
return QWidget::resizeEvent(resizeEvent);
|
return QWidget::resizeEvent(resizeEvent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
#include <QPropertyAnimation>
|
#include <QPropertyAnimation>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
class KActionCollection;
|
class KActionCollection;
|
||||||
class KFileItemList;
|
class KFileItemList;
|
||||||
class QAction;
|
class QAction;
|
||||||
|
@ -30,7 +28,7 @@ namespace SelectionMode
|
||||||
class BottomBarContentsContainer;
|
class BottomBarContentsContainer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A bar used in selection mode that serves various purposes depending on what the user is currently trying to do.
|
* @brief A bar used in selection mode that serves various purposes depending on what the user is currently trying to do.
|
||||||
*
|
*
|
||||||
* The Contents enum below gives a rough idea about the different states this bar might have.
|
* The Contents enum below gives a rough idea about the different states this bar might have.
|
||||||
* The bar is notified of various changes that make changing or updating the content worthwhile.
|
* The bar is notified of various changes that make changing or updating the content worthwhile.
|
||||||
|
@ -69,11 +67,20 @@ public:
|
||||||
*
|
*
|
||||||
* This bar might also not show itself when setVisible(true), when context menu actions are supposed to be shown
|
* This bar might also not show itself when setVisible(true), when context menu actions are supposed to be shown
|
||||||
* for the selected items but no items have been selected yet. In that case it will only show itself once items were selected.
|
* for the selected items but no items have been selected yet. In that case it will only show itself once items were selected.
|
||||||
|
*
|
||||||
|
* This bar might also ignore a setVisible(false) call, if it has PasteContents because that bar is supposed to stay visible
|
||||||
|
* even outside of selection mode.
|
||||||
|
*
|
||||||
|
* @param visible Whether this bar is supposed to be visible long term
|
||||||
|
* @param animated Whether this should be animated. The animation is skipped if the users' settings are configured that way.
|
||||||
|
*
|
||||||
* @see QWidget::setVisible()
|
* @see QWidget::setVisible()
|
||||||
*/
|
*/
|
||||||
void setVisible(bool visible, Animated animated);
|
void setVisible(bool visible, Animated animated);
|
||||||
using QWidget::setVisible; // Makes sure that the setVisible() declaration above doesn't hide the one from QWidget.
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the contents of the bar to @p contents.
|
||||||
|
*/
|
||||||
void resetContents(Contents contents);
|
void resetContents(Contents contents);
|
||||||
Contents contents() const;
|
Contents contents() const;
|
||||||
|
|
||||||
|
@ -81,6 +88,7 @@ public:
|
||||||
QSize sizeHint() const override;
|
QSize sizeHint() const override;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
|
/** Adapts the contents based on the selection in the related view. */
|
||||||
void slotSelectionChanged(const KFileItemList &selection, const QUrl &baseUrl);
|
void slotSelectionChanged(const KFileItemList &selection, const QUrl &baseUrl);
|
||||||
|
|
||||||
/** Used to notify the m_selectionModeBottomBar that there is no other ViewContainer in the tab. */
|
/** Used to notify the m_selectionModeBottomBar that there is no other ViewContainer in the tab. */
|
||||||
|
@ -102,6 +110,8 @@ protected:
|
||||||
void resizeEvent(QResizeEvent *resizeEvent) override;
|
void resizeEvent(QResizeEvent *resizeEvent) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using QWidget::setVisible; // Makes sure that the setVisible() declaration above doesn't hide the one from QWidget so we can still use it privately.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identical to SelectionModeBottomBar::setVisible() but doesn't change m_allowedToBeVisible.
|
* Identical to SelectionModeBottomBar::setVisible() but doesn't change m_allowedToBeVisible.
|
||||||
* @see SelectionModeBottomBar::setVisible()
|
* @see SelectionModeBottomBar::setVisible()
|
||||||
|
@ -119,7 +129,7 @@ private:
|
||||||
* This is necessary because this bar might have been setVisible(true) but there is no reason to show the bar currently so it was kept hidden.
|
* This is necessary because this bar might have been setVisible(true) but there is no reason to show the bar currently so it was kept hidden.
|
||||||
* @see SelectionModeBottomBar::setVisible() */
|
* @see SelectionModeBottomBar::setVisible() */
|
||||||
bool m_allowedToBeVisible = false;
|
bool m_allowedToBeVisible = false;
|
||||||
/// @see SelectionModeBottomBar::setVisible()
|
/** @see SelectionModeBottomBar::setVisible() */
|
||||||
QPointer<QPropertyAnimation> m_heightAnimation;
|
QPointer<QPropertyAnimation> m_heightAnimation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -69,8 +69,10 @@ void BottomBarContentsContainer::resetContents(BottomBar::Contents contents)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BottomBarContentsContainer::updateForNewWidth()
|
void BottomBarContentsContainer::adaptToNewBarWidth(int newBarWidth)
|
||||||
{
|
{
|
||||||
|
m_barWidth = newBarWidth;
|
||||||
|
|
||||||
if (m_contents == BottomBar::GeneralContents) {
|
if (m_contents == BottomBar::GeneralContents) {
|
||||||
Q_ASSERT(m_overflowButton);
|
Q_ASSERT(m_overflowButton);
|
||||||
if (unusedSpace() < 0) {
|
if (unusedSpace() < 0) {
|
||||||
|
@ -94,7 +96,7 @@ void BottomBarContentsContainer::updateForNewWidth()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We have some unusedSpace(). Let's check if we can maybe add more of the contextual action's widgets.
|
// We have some unusedSpace(). Let's check if we can maybe add more of the contextual actions' widgets.
|
||||||
for (auto i = m_generalBarActions.begin(); i != m_generalBarActions.end(); ++i) {
|
for (auto i = m_generalBarActions.begin(); i != m_generalBarActions.end(); ++i) {
|
||||||
if (i->isWidgetVisible()) {
|
if (i->isWidgetVisible()) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -130,6 +132,7 @@ void BottomBarContentsContainer::slotSelectionChanged(const KFileItemList &selec
|
||||||
auto contextActions = contextActionsFor(selection, baseUrl);
|
auto contextActions = contextActionsFor(selection, baseUrl);
|
||||||
m_generalBarActions.clear();
|
m_generalBarActions.clear();
|
||||||
if (contextActions.empty()) {
|
if (contextActions.empty()) {
|
||||||
|
// We have nothing to show
|
||||||
Q_ASSERT(qobject_cast<BottomBar *>(parentWidget()->parentWidget()->parentWidget()));
|
Q_ASSERT(qobject_cast<BottomBar *>(parentWidget()->parentWidget()->parentWidget()));
|
||||||
if (isVisibleTo(parentWidget()->parentWidget()->parentWidget()->parentWidget())) { // is the bar visible
|
if (isVisibleTo(parentWidget()->parentWidget()->parentWidget()->parentWidget())) { // is the bar visible
|
||||||
Q_EMIT barVisibilityChangeRequested(false);
|
Q_EMIT barVisibilityChangeRequested(false);
|
||||||
|
@ -162,7 +165,7 @@ void BottomBarContentsContainer::addCopyContents()
|
||||||
// We claim to have PasteContents already so triggering the copy action next won't instantly hide the bottom bar.
|
// We claim to have PasteContents already so triggering the copy action next won't instantly hide the bottom bar.
|
||||||
connect(copyButton, &QAbstractButton::clicked, [this]() {
|
connect(copyButton, &QAbstractButton::clicked, [this]() {
|
||||||
if (GeneralSettings::showPasteBarAfterCopying()) {
|
if (GeneralSettings::showPasteBarAfterCopying()) {
|
||||||
m_contents = BottomBar::Contents::PasteContents;
|
m_contents = BottomBar::Contents::PasteContents; // prevents hiding
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Connect the copy action as a second step.
|
// Connect the copy action as a second step.
|
||||||
|
@ -232,7 +235,7 @@ void BottomBarContentsContainer::addCutContents()
|
||||||
// We claim to have PasteContents already so triggering the cut action next won't instantly hide the bottom bar.
|
// We claim to have PasteContents already so triggering the cut action next won't instantly hide the bottom bar.
|
||||||
connect(cutButton, &QAbstractButton::clicked, [this]() {
|
connect(cutButton, &QAbstractButton::clicked, [this]() {
|
||||||
if (GeneralSettings::showPasteBarAfterCopying()) {
|
if (GeneralSettings::showPasteBarAfterCopying()) {
|
||||||
m_contents = BottomBar::Contents::PasteContents;
|
m_contents = BottomBar::Contents::PasteContents; // prevents hiding
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Connect the cut action as a second step.
|
// Connect the cut action as a second step.
|
||||||
|
@ -400,9 +403,9 @@ void BottomBarContentsContainer::addPasteContents()
|
||||||
vBoxLayout->addWidget(pasteButton);
|
vBoxLayout->addWidget(pasteButton);
|
||||||
|
|
||||||
auto *dismissButton = new QToolButton(this);
|
auto *dismissButton = new QToolButton(this);
|
||||||
dismissButton->setText(i18nc("@action Dismisses a bar explaining how to use the Paste action", "Dismiss this Reminder"));
|
dismissButton->setText(i18nc("@action Dismisses a bar explaining how to use the Paste action", "Dismiss This Reminder"));
|
||||||
connect(dismissButton, &QAbstractButton::clicked, this, actuallyLeaveSelectionMode);
|
connect(dismissButton, &QAbstractButton::clicked, this, actuallyLeaveSelectionMode);
|
||||||
auto *dontRemindAgainAction = new QAction(i18nc("@action Dismisses an explanatory area and never shows it again", "Don't remind me again"), this);
|
auto *dontRemindAgainAction = new QAction(i18nc("@action Dismisses an explanatory area and never shows it again", "Don't Remind Me Again"), this);
|
||||||
connect(dontRemindAgainAction, &QAction::triggered, this, []() {
|
connect(dontRemindAgainAction, &QAction::triggered, this, []() {
|
||||||
GeneralSettings::setShowPasteBarAfterCopying(false);
|
GeneralSettings::setShowPasteBarAfterCopying(false);
|
||||||
});
|
});
|
||||||
|
@ -516,9 +519,7 @@ int BottomBarContentsContainer::unusedSpace() const
|
||||||
}
|
}
|
||||||
sumOfPreferredWidths += m_layout->itemAt(i)->sizeHint().width() + m_layout->spacing();
|
sumOfPreferredWidths += m_layout->itemAt(i)->sizeHint().width() + m_layout->spacing();
|
||||||
}
|
}
|
||||||
Q_ASSERT(qobject_cast<BottomBar *>(parentWidget()->parentWidget()->parentWidget()));
|
return m_barWidth - sumOfPreferredWidths - 20; // We consider all space used when there are only 20 pixels left
|
||||||
const int totalBarWidth = parentWidget()->parentWidget()->parentWidget()->width();
|
|
||||||
return totalBarWidth - sumOfPreferredWidths - 20; // We consider all space used when there are only 20 pixels left
|
|
||||||
// so there is some room to breath and not too much wonkyness while resizing.
|
// so there is some room to breath and not too much wonkyness while resizing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,7 +536,7 @@ void BottomBarContentsContainer::updateExplanatoryLabelVisibility()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BottomBarContentsContainer::updateMainActionButton(const KFileItemList& selection)
|
void BottomBarContentsContainer::updateMainActionButton(const KFileItemList& selectedItems)
|
||||||
{
|
{
|
||||||
if (!m_mainAction.widget()) {
|
if (!m_mainAction.widget()) {
|
||||||
return;
|
return;
|
||||||
|
@ -543,45 +544,69 @@ void BottomBarContentsContainer::updateMainActionButton(const KFileItemList& sel
|
||||||
Q_ASSERT(qobject_cast<QAbstractButton *>(m_mainAction.widget()));
|
Q_ASSERT(qobject_cast<QAbstractButton *>(m_mainAction.widget()));
|
||||||
|
|
||||||
// Users are nudged towards selecting items by having the button disabled when nothing is selected.
|
// Users are nudged towards selecting items by having the button disabled when nothing is selected.
|
||||||
m_mainAction.widget()->setEnabled(selection.count() > 0 && m_mainAction.action()->isEnabled());
|
m_mainAction.widget()->setEnabled(selectedItems.count() > 0 && m_mainAction.action()->isEnabled());
|
||||||
QFontMetrics fontMetrics = m_mainAction.widget()->fontMetrics();
|
QFontMetrics fontMetrics = m_mainAction.widget()->fontMetrics();
|
||||||
|
|
||||||
QString buttonText;
|
QString buttonText;
|
||||||
switch (m_contents) {
|
switch (m_contents) {
|
||||||
case BottomBar::CopyContents:
|
case BottomBar::CopyContents:
|
||||||
buttonText = i18ncp("@action A more elaborate and clearly worded version of the Copy action",
|
// i18n: A more elaborate and clearly worded version of the Copy action
|
||||||
"Copy %2 to the Clipboard", "Copy %2 to the Clipboard", selection.count(),
|
// %2 is a textual representation of the currently selected files or folders. This can be the name of
|
||||||
fileItemListToString(selection, fontMetrics.averageCharWidth() * 20, fontMetrics));
|
// 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.
|
||||||
|
buttonText = i18ncp("@action", "Copy %2 to the Clipboard", "Copy %2 to the Clipboard", selectedItems.count(), fileItemListToString(selectedItems, fontMetrics.averageCharWidth() * 20, fontMetrics));
|
||||||
|
// All these long lines can not be broken up with line breaks becaue 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
|
||||||
break;
|
break;
|
||||||
case BottomBar::CopyLocationContents:
|
case BottomBar::CopyLocationContents:
|
||||||
buttonText = i18ncp("@action A more elaborate and clearly worded version of the Copy Location action",
|
// i18n: A more elaborate and clearly worded version of the Copy Location action
|
||||||
"Copy the Location of %2 to the Clipboard", "Copy the Location of %2 to the Clipboard", selection.count(),
|
// %2 is a textual representation of the currently selected files or folders. This can be the name of
|
||||||
fileItemListToString(selection, fontMetrics.averageCharWidth() * 20, fontMetrics));
|
// 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.
|
||||||
|
buttonText = i18ncp("@action", "Copy the Location of %2 to the Clipboard", "Copy the Location of %2 to the Clipboard", selectedItems.count(), fileItemListToString(selectedItems, fontMetrics.averageCharWidth() * 20, fontMetrics));
|
||||||
break;
|
break;
|
||||||
case BottomBar::CutContents:
|
case BottomBar::CutContents:
|
||||||
buttonText = i18ncp("@action A more elaborate and clearly worded version of the Cut action",
|
// i18n: A more elaborate and clearly worded version of the Cut action
|
||||||
"Cut %2 to the Clipboard", "Cut %2 to the Clipboard", selection.count(),
|
// %2 is a textual representation of the currently selected files or folders. This can be the name of
|
||||||
fileItemListToString(selection, fontMetrics.averageCharWidth() * 20, fontMetrics));
|
// 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.
|
||||||
|
buttonText = i18ncp("@action", "Cut %2 to the Clipboard", "Cut %2 to the Clipboard", selectedItems.count(), fileItemListToString(selectedItems, fontMetrics.averageCharWidth() * 20, fontMetrics));
|
||||||
break;
|
break;
|
||||||
case BottomBar::DeleteContents:
|
case BottomBar::DeleteContents:
|
||||||
buttonText = i18ncp("@action A more elaborate and clearly worded version of the Delete action",
|
// i18n: A more elaborate and clearly worded version of the Delete action
|
||||||
"Permanently Delete %2", "Permanently Delete %2", selection.count(),
|
// %2 is a textual representation of the currently selected files or folders. This can be the name of
|
||||||
fileItemListToString(selection, fontMetrics.averageCharWidth() * 20, fontMetrics));
|
// 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.
|
||||||
|
buttonText = i18ncp("@action", "Permanently Delete %2", "Permanently Delete %2", selectedItems.count(), fileItemListToString(selectedItems, fontMetrics.averageCharWidth() * 20, fontMetrics));
|
||||||
break;
|
break;
|
||||||
case BottomBar::DuplicateContents:
|
case BottomBar::DuplicateContents:
|
||||||
buttonText = i18ncp("@action A more elaborate and clearly worded version of the Duplicate action",
|
// i18n: A more elaborate and clearly worded version of the Duplicate action
|
||||||
"Duplicate %2", "Duplicate %2", selection.count(),
|
// %2 is a textual representation of the currently selected files or folders. This can be the name of
|
||||||
fileItemListToString(selection, fontMetrics.averageCharWidth() * 20, fontMetrics));
|
// 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.
|
||||||
|
buttonText = i18ncp("@action", "Duplicate %2", "Duplicate %2", selectedItems.count(), fileItemListToString(selectedItems, fontMetrics.averageCharWidth() * 20, fontMetrics));
|
||||||
break;
|
break;
|
||||||
case BottomBar::MoveToTrashContents:
|
case BottomBar::MoveToTrashContents:
|
||||||
buttonText = i18ncp("@action A more elaborate and clearly worded version of the Trash action",
|
// i18n: A more elaborate and clearly worded version of the Trash action
|
||||||
"Move %2 to the Trash", "Move %2 to the Trash", selection.count(),
|
// %2 is a textual representation of the currently selected files or folders. This can be the name of
|
||||||
fileItemListToString(selection, fontMetrics.averageCharWidth() * 20, fontMetrics));
|
// 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.
|
||||||
|
buttonText = i18ncp("@action", "Move %2 to the Trash", "Move %2 to the Trash", selectedItems.count(), fileItemListToString(selectedItems, fontMetrics.averageCharWidth() * 20, fontMetrics));
|
||||||
break;
|
break;
|
||||||
case BottomBar::RenameContents:
|
case BottomBar::RenameContents:
|
||||||
buttonText = i18ncp("@action A more elaborate and clearly worded version of the Rename action",
|
// i18n: A more elaborate and clearly worded version of the Rename action
|
||||||
"Rename %2", "Rename %2", selection.count(),
|
// %2 is a textual representation of the currently selected files or folders. This can be the name of
|
||||||
fileItemListToString(selection, fontMetrics.averageCharWidth() * 20, fontMetrics));
|
// 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.
|
||||||
|
buttonText = i18ncp("@action", "Rename %2", "Rename %2", selectedItems.count(), fileItemListToString(selectedItems, fontMetrics.averageCharWidth() * 20, fontMetrics));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -43,6 +43,9 @@ public:
|
||||||
*/
|
*/
|
||||||
explicit BottomBarContentsContainer(KActionCollection *actionCollection, QWidget *parent);
|
explicit BottomBarContentsContainer(KActionCollection *actionCollection, QWidget *parent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param contents The kind of contents that should be contained instead.
|
||||||
|
*/
|
||||||
void resetContents(BottomBar::Contents contents);
|
void resetContents(BottomBar::Contents contents);
|
||||||
inline BottomBar::Contents contents() const
|
inline BottomBar::Contents contents() const
|
||||||
{
|
{
|
||||||
|
@ -53,9 +56,14 @@ public:
|
||||||
return contents() != BottomBar::GeneralContents || m_internalContextMenu;
|
return contents() != BottomBar::GeneralContents || m_internalContextMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateForNewWidth();
|
/**
|
||||||
|
* Is called when the BottomBar resizes to let this ContentsContainer know that it should adapt its contents to the new width.
|
||||||
|
* Adapting is done by showing or hiding labels or buttons.
|
||||||
|
*/
|
||||||
|
void adaptToNewBarWidth(int newBarWidth);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
|
/** Adapts the contents based on the selection in the related view. */
|
||||||
void slotSelectionChanged(const KFileItemList &selection, const QUrl &baseUrl);
|
void slotSelectionChanged(const KFileItemList &selection, const QUrl &baseUrl);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
@ -65,8 +73,8 @@ Q_SIGNALS:
|
||||||
void error(const QString &errorMessage);
|
void error(const QString &errorMessage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sometimes the contents see no reason to be visible and request the bar to be hidden instead which emits this signal.
|
* When it does not make sense to show any specific contents, this signal is emitted and the receiver hides the bar.
|
||||||
* This can later change e.g. because the user selected items. Then this signal is used to request showing of the bar.
|
* Later it might sense to show it again e.g. because the user selected items. Then this signal is used to request showing of the bar.
|
||||||
*/
|
*/
|
||||||
void barVisibilityChangeRequested(bool visible);
|
void barVisibilityChangeRequested(bool visible);
|
||||||
|
|
||||||
|
@ -90,15 +98,15 @@ private:
|
||||||
void addRenameContents();
|
void addRenameContents();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes all visible widgets and layouts from the bar.
|
* Deletes every child layout and child widget of this container.
|
||||||
*/
|
*/
|
||||||
void emptyBarContents();
|
void emptyBarContents();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns A vector containing contextual actions for the given \a selection in the \a baseUrl.
|
* @returns A vector containing contextual actions for the given \a selectedItems in the \a baseUrl.
|
||||||
* Cut, Copy, Rename and MoveToTrash are always added. Any further contextual actions depend on
|
* Cut, Copy, Rename and MoveToTrash are always added. Any further contextual actions depend on
|
||||||
* \a selection and \a baseUrl. \a selection and \a baseUrl can be empty/default constructed if
|
* \a selectedItems and \a baseUrl.
|
||||||
* no item- or view-specific actions should be added aside from Cut, Copy, Rename, MoveToTrash.
|
* If there are no \a selectedItems, an empty vector is returned and m_internalContextMenu is deleted.
|
||||||
* @param selectedItems The selected items for which contextual actions should be displayed.
|
* @param selectedItems The selected items for which contextual actions should be displayed.
|
||||||
* @param baseUrl Base URL of the viewport the contextual actions apply to.
|
* @param baseUrl Base URL of the viewport the contextual actions apply to.
|
||||||
*/
|
*/
|
||||||
|
@ -107,7 +115,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* @returns the amount of pixels that can be spared to add more widgets. A negative value might
|
* @returns the amount of pixels that can be spared to add more widgets. A negative value might
|
||||||
* be returned which signifies that some widgets should be hidden or removed from this bar to
|
* be returned which signifies that some widgets should be hidden or removed from this bar to
|
||||||
* make sure that this SelectionModeBottomBar won't stretch the width of its parent.
|
* make sure that this BottomBarContentsContainer can fully fit on the BottomBar.
|
||||||
*/
|
*/
|
||||||
int unusedSpace() const;
|
int unusedSpace() const;
|
||||||
|
|
||||||
|
@ -118,12 +126,12 @@ private:
|
||||||
void updateExplanatoryLabelVisibility();
|
void updateExplanatoryLabelVisibility();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the text and enabled state of the main action button
|
* Changes the text and enabled state of the main action button based on the amount of currently
|
||||||
* based on the amount of currently selected items and the state of the current m_mainAction.
|
* selected items and the state of the current m_mainAction.
|
||||||
* The current main action depends on the current barContents.
|
* The current main action depends on the current barContents.
|
||||||
* @param selection the currently selected fileItems.
|
* @param selectedItems the currently selected fileItems.
|
||||||
*/
|
*/
|
||||||
void updateMainActionButton(const KFileItemList &selection);
|
void updateMainActionButton(const KFileItemList &selectedItems);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// All the actions that should be available from this bar when in general mode.
|
/// All the actions that should be available from this bar when in general mode.
|
||||||
|
@ -141,11 +149,12 @@ private:
|
||||||
KActionCollection *m_actionCollection;
|
KActionCollection *m_actionCollection;
|
||||||
/// Describes the current contents of the bar.
|
/// Describes the current contents of the bar.
|
||||||
BottomBar::Contents m_contents;
|
BottomBar::Contents m_contents;
|
||||||
/** The layout all the buttons and labels are added to.
|
/// The main layout of this ContentsContainer that all the buttons and labels are added to.
|
||||||
* Do not confuse this with layout() because we do have a QScrollView in between this widget and m_layout. */
|
|
||||||
QHBoxLayout *m_layout;
|
QHBoxLayout *m_layout;
|
||||||
|
|
||||||
/// The info label used for some of the BarContents. Is hidden for narrow widths.
|
/// Caches the totalBarWidth as set in adaptToNewWidth(newBarWidth). */
|
||||||
|
int m_barWidth = 0;
|
||||||
|
/// The info label used for some of the Contents. Is hidden for narrow widths.
|
||||||
QPointer<QLabel> m_explanatoryLabel;
|
QPointer<QLabel> m_explanatoryLabel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ TopBar::TopBar(QWidget *parent) :
|
||||||
fillParentLayout->setContentsMargins(0, 0, 0, 0);
|
fillParentLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
// Put the contents into a QScrollArea. This prevents increasing the view width
|
// Put the contents into a QScrollArea. This prevents increasing the view width
|
||||||
// in case that not enough width for the contents is available. (this trick is also used in selectionmodebottombar.cpp.)
|
// in case that not enough width for the contents is available. (this trick is also used in bottombar.cpp.)
|
||||||
auto scrollArea = new QScrollArea(this);
|
auto scrollArea = new QScrollArea(this);
|
||||||
fillParentLayout->addWidget(scrollArea);
|
fillParentLayout->addWidget(scrollArea);
|
||||||
scrollArea->setFrameShape(QFrame::NoFrame);
|
scrollArea->setFrameShape(QFrame::NoFrame);
|
||||||
|
@ -111,9 +111,10 @@ void TopBar::setVisible(bool visible, Animated animated)
|
||||||
m_heightAnimation->start(QAbstractAnimation::DeleteWhenStopped);
|
m_heightAnimation->start(QAbstractAnimation::DeleteWhenStopped);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TopBar::resizeEvent(QResizeEvent */* resizeEvent */)
|
void TopBar::resizeEvent(QResizeEvent *resizeEvent)
|
||||||
{
|
{
|
||||||
updateLabelString();
|
updateLabelString();
|
||||||
|
return QWidget::resizeEvent(resizeEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TopBar::updateLabelString()
|
void TopBar::updateLabelString()
|
||||||
|
|
|
@ -40,15 +40,17 @@ public:
|
||||||
* @see QWidget::setVisible()
|
* @see QWidget::setVisible()
|
||||||
*/
|
*/
|
||||||
void setVisible(bool visible, Animated animated);
|
void setVisible(bool visible, Animated animated);
|
||||||
using QWidget::setVisible; // Makes sure that the setVisible() declaration above doesn't hide the one from QWidget.
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void leaveSelectionModeRequested();
|
void leaveSelectionModeRequested();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent */* resizeEvent */) override;
|
/** Calls updateLabelString() */
|
||||||
|
void resizeEvent(QResizeEvent *resizeEvent) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using QWidget::setVisible; // Makes sure that the setVisible() declaration above doesn't hide the one from QWidget so we can still use it privately.
|
||||||
|
|
||||||
/** Decides whether the m_fullLabelString or m_shortLabelString should be used based on available width. */
|
/** Decides whether the m_fullLabelString or m_shortLabelString should be used based on available width. */
|
||||||
void updateLabelString();
|
void updateLabelString();
|
||||||
|
|
||||||
|
|
|
@ -301,7 +301,6 @@ bool DolphinView::selectionMode() const
|
||||||
return m_container->controller()->selectionMode();
|
return m_container->controller()->selectionMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DolphinView::setPreviewsShown(bool show)
|
void DolphinView::setPreviewsShown(bool show)
|
||||||
{
|
{
|
||||||
if (previewsShown() == show) {
|
if (previewsShown() == show) {
|
||||||
|
|
|
@ -112,6 +112,9 @@ public:
|
||||||
void setViewMode(Mode mode);
|
void setViewMode(Mode mode);
|
||||||
Mode viewMode() const;
|
Mode viewMode() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables or disables a mode for quick and easy selection of items.
|
||||||
|
*/
|
||||||
void setSelectionMode(bool enabled);
|
void setSelectionMode(bool enabled);
|
||||||
bool selectionMode() const;
|
bool selectionMode() const;
|
||||||
|
|
||||||
|
|
|
@ -166,6 +166,7 @@ void DolphinViewActionHandler::createActions(SelectionMode::ActionTextHelper *ac
|
||||||
connect(copyPathAction, &QAction::triggered, this, &DolphinViewActionHandler::slotCopyPath);
|
connect(copyPathAction, &QAction::triggered, this, &DolphinViewActionHandler::slotCopyPath);
|
||||||
|
|
||||||
if (actionTextHelper) {
|
if (actionTextHelper) {
|
||||||
|
// The "…" at the end make clear that they won't trigger their respective actions directly.
|
||||||
actionTextHelper->registerTextWhenNothingIsSelected(trashAction, i18nc("@action:inmenu File", "Move to Trash…"));
|
actionTextHelper->registerTextWhenNothingIsSelected(trashAction, i18nc("@action:inmenu File", "Move to Trash…"));
|
||||||
actionTextHelper->registerTextWhenNothingIsSelected(deleteAction, i18nc("@action:inmenu File", "Delete…"));
|
actionTextHelper->registerTextWhenNothingIsSelected(deleteAction, i18nc("@action:inmenu File", "Delete…"));
|
||||||
actionTextHelper->registerTextWhenNothingIsSelected(duplicateAction, i18nc("@action:inmenu File", "Duplicate Here…"));
|
actionTextHelper->registerTextWhenNothingIsSelected(duplicateAction, i18nc("@action:inmenu File", "Duplicate Here…"));
|
||||||
|
@ -438,6 +439,7 @@ void DolphinViewActionHandler::slotRename()
|
||||||
} else {
|
} else {
|
||||||
Q_EMIT actionBeingHandled();
|
Q_EMIT actionBeingHandled();
|
||||||
m_currentView->renameSelectedItems();
|
m_currentView->renameSelectedItems();
|
||||||
|
// We don't exit selectionMode here because users might want to rename more items.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue