Summary:
Make renaming of files/folders faster by clicking a second time on the items text to start renaming.
BUG: 205157
Test Plan:
This feature works as follows:
1. select an item by single-click, or one is already selected
2. wait the "double-click-interval"
3. click on the items text
4. none of the cancellations (see below) happens within the double-click-interval
5. inline-renaming starts
Cancellations:
* open any file/folder
* select different item(s)
* start dragging items
* Dolphin loses focus
This feature is just enabled while "Double-click to open files and folders" in system-settings and "Rename inline" in Dolphin are enabled.
Reviewers: #dolphin, #kde_applications, elvisangelaccio, emmanuelp, ngraham, markg, rkflx
Reviewed By: #dolphin, #kde_applications, elvisangelaccio, ngraham, rkflx
Subscribers: rkflx, markg, funkybomber, sars, elvisangelaccio, ngraham
Differential Revision: https://phabricator.kde.org/D7647
// -> remember that the user pressed an item which had been selected already and
// clear the selection in mouseReleaseEvent(), unless the items are dragged.
m_clearSelectionIfItemsAreNotDragged = true;
// -> remember that the user pressed an item which had been selected already and
// clear the selection in mouseReleaseEvent(), unless the items are dragged.
m_clearSelectionIfItemsAreNotDragged = true;
+
+ if (m_selectionManager->selectedItems().count() == 1 && m_view->isAboveText(m_pressedIndex, m_pressedMousePos)) {
+ emit selectedItemTextPressed(m_pressedIndex);
+ }
void modelChanged(KItemModelBase* current, KItemModelBase* previous);
void viewChanged(KItemListView* current, KItemListView* previous);
void modelChanged(KItemModelBase* current, KItemModelBase* previous);
void viewChanged(KItemListView* current, KItemListView* previous);
+ void selectedItemTextPressed(int index);
+
private slots:
void slotViewScrollOffsetChanged(qreal current, qreal previous);
private slots:
void slotViewScrollOffsetChanged(qreal current, qreal previous);
+bool KItemListView::isAboveText(int index, const QPointF &pos) const
+{
+ const KItemListWidget* widget = m_visibleItems.value(index);
+ if (widget) {
+ const QRectF &textRect = widget->textRect();
+ if (!textRect.isEmpty()) {
+ const QPointF mappedPos = widget->mapFromItem(this, pos);
+ return textRect.contains(mappedPos);
+ }
+ }
+ return false;
+}
+
int KItemListView::firstVisibleIndex() const
{
return m_layouter->firstVisibleIndex();
int KItemListView::firstVisibleIndex() const
{
return m_layouter->firstVisibleIndex();
int itemAt(const QPointF& pos) const;
bool isAboveSelectionToggle(int index, const QPointF& pos) const;
bool isAboveExpansionToggle(int index, const QPointF& pos) const;
int itemAt(const QPointF& pos) const;
bool isAboveSelectionToggle(int index, const QPointF& pos) const;
bool isAboveExpansionToggle(int index, const QPointF& pos) const;
+ bool isAboveText(int index, const QPointF& pos) const;
/**
* @return Index of the first item that is at least partly visible.
/**
* @return Index of the first item that is at least partly visible.
m_selectedUrls(),
m_clearSelectionBeforeSelectingNewItems(false),
m_markFirstNewlySelectedItemAsCurrent(false),
m_selectedUrls(),
m_clearSelectionBeforeSelectingNewItems(false),
m_markFirstNewlySelectedItemAsCurrent(false),
- m_versionControlObserver(0)
+ m_versionControlObserver(0),
+ m_twoClicksRenamingTimer(nullptr)
{
m_topLayout = new QVBoxLayout(this);
m_topLayout->setSpacing(0);
{
m_topLayout = new QVBoxLayout(this);
m_topLayout->setSpacing(0);
connect(controller, &KItemListController::itemDropEvent, this, &DolphinView::slotItemDropEvent);
connect(controller, &KItemListController::escapePressed, this, &DolphinView::stopLoading);
connect(controller, &KItemListController::modelChanged, this, &DolphinView::slotModelChanged);
connect(controller, &KItemListController::itemDropEvent, this, &DolphinView::slotItemDropEvent);
connect(controller, &KItemListController::escapePressed, this, &DolphinView::stopLoading);
connect(controller, &KItemListController::modelChanged, this, &DolphinView::slotModelChanged);
+ connect(controller, &KItemListController::selectedItemTextPressed, this, &DolphinView::slotSelectedItemTextPressed);
connect(m_model, &KFileItemModel::directoryLoadingStarted, this, &DolphinView::slotDirectoryLoadingStarted);
connect(m_model, &KFileItemModel::directoryLoadingCompleted, this, &DolphinView::slotDirectoryLoadingCompleted);
connect(m_model, &KFileItemModel::directoryLoadingStarted, this, &DolphinView::slotDirectoryLoadingStarted);
connect(m_model, &KFileItemModel::directoryLoadingCompleted, this, &DolphinView::slotDirectoryLoadingCompleted);
connect(m_versionControlObserver, &VersionControlObserver::errorMessage, this, &DolphinView::errorMessage);
connect(m_versionControlObserver, &VersionControlObserver::operationCompletedMessage, this, &DolphinView::operationCompletedMessage);
connect(m_versionControlObserver, &VersionControlObserver::errorMessage, this, &DolphinView::errorMessage);
connect(m_versionControlObserver, &VersionControlObserver::operationCompletedMessage, this, &DolphinView::operationCompletedMessage);
+ m_twoClicksRenamingTimer = new QTimer(this);
+ m_twoClicksRenamingTimer->setSingleShot(true);
+ connect(m_twoClicksRenamingTimer, &QTimer::timeout, this, &DolphinView::slotTwoClicksRenamingTimerTimeout);
+
applyViewProperties();
m_topLayout->addWidget(m_container);
applyViewProperties();
m_topLayout->addWidget(m_container);
+void DolphinView::abortTwoClicksRenaming()
+{
+ m_twoClicksRenamingItemUrl.clear();
+ m_twoClicksRenamingTimer->stop();
+}
+
bool DolphinView::eventFilter(QObject* watched, QEvent* event)
{
switch (event->type()) {
bool DolphinView::eventFilter(QObject* watched, QEvent* event)
{
switch (event->type()) {
bool DolphinView::event(QEvent* event)
{
bool DolphinView::event(QEvent* event)
{
- /* See Bug 297355
- * Dolphin leaves file preview tooltips open even when is not visible.
- *
- * Hide tool-tip when Dolphin loses focus.
- */
if (event->type() == QEvent::WindowDeactivate) {
if (event->type() == QEvent::WindowDeactivate) {
+ /* See Bug 297355
+ * Dolphin leaves file preview tooltips open even when is not visible.
+ *
+ * Hide tool-tip when Dolphin loses focus.
+ */
+ abortTwoClicksRenaming();
}
return QWidget::event(event);
}
return QWidget::event(event);
void DolphinView::slotItemActivated(int index)
{
void DolphinView::slotItemActivated(int index)
{
+ abortTwoClicksRenaming();
+
const KFileItem item = m_model->fileItem(index);
if (!item.isNull()) {
emit itemActivated(item);
const KFileItem item = m_model->fileItem(index);
if (!item.isNull()) {
emit itemActivated(item);
{
Q_ASSERT(indexes.count() >= 2);
{
Q_ASSERT(indexes.count() >= 2);
+ abortTwoClicksRenaming();
+
if (indexes.count() > 5) {
QString question = i18np("Are you sure you want to open 1 item?", "Are you sure you want to open %1 items?", indexes.count());
const int answer = KMessageBox::warningYesNo(this, question);
if (indexes.count() > 5) {
QString question = i18np("Are you sure you want to open 1 item?", "Are you sure you want to open %1 items?", indexes.count());
const int answer = KMessageBox::warningYesNo(this, question);
+void DolphinView::slotSelectedItemTextPressed(int index)
+{
+ if (GeneralSettings::renameInline()) {
+ m_twoClicksRenamingItemUrl = m_model->fileItem(index).url();
+ m_twoClicksRenamingTimer->start(QApplication::doubleClickInterval());
+ }
+}
+
void DolphinView::slotItemCreated(const QUrl& url)
{
if (m_markFirstNewlySelectedItemAsCurrent) {
void DolphinView::slotItemCreated(const QUrl& url)
{
if (m_markFirstNewlySelectedItemAsCurrent) {
+void DolphinView::slotTwoClicksRenamingTimerTimeout()
+{
+ const KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
+
+ // verify that only one item is selected and that no item is dragged
+ if (selectionManager->selectedItems().count() == 1 && !m_dragging) {
+ const int index = selectionManager->currentItem();
+ const QUrl fileItemUrl = m_model->fileItem(index).url();
+
+ // check if the selected item was the same item that started the twoClicksRenaming
+ if (fileItemUrl.isValid() && m_twoClicksRenamingItemUrl == fileItemUrl) {
+ renameSelectedItems();
+ }
+ }
+}
+
void DolphinView::slotTrashFileFinished(KJob* job)
{
if (job->error() == 0) {
void DolphinView::slotTrashFileFinished(KJob* job)
{
if (job->error() == 0) {
void slotModelChanged(KItemModelBase* current, KItemModelBase* previous);
void slotMouseButtonPressed(int itemIndex, Qt::MouseButtons buttons);
void slotRenameDialogRenamingFinished(const QList<QUrl>& urls);
void slotModelChanged(KItemModelBase* current, KItemModelBase* previous);
void slotMouseButtonPressed(int itemIndex, Qt::MouseButtons buttons);
void slotRenameDialogRenamingFinished(const QList<QUrl>& urls);
+ void slotSelectedItemTextPressed(int index);
/*
* Is called when new items get pasted or dropped.
/*
* Is called when new items get pasted or dropped.
*/
void calculateItemCount(int& fileCount, int& folderCount, KIO::filesize_t& totalFileSize) const;
*/
void calculateItemCount(int& fileCount, int& folderCount, KIO::filesize_t& totalFileSize) const;
+ void slotTwoClicksRenamingTimerTimeout();
+
private:
void loadDirectory(const QUrl& url, bool reload = false);
private:
void loadDirectory(const QUrl& url, bool reload = false);
*/
void forceUrlsSelection(const QUrl& current, const QList<QUrl>& selected);
*/
void forceUrlsSelection(const QUrl& current, const QList<QUrl>& selected);
+ void abortTwoClicksRenaming();
+
private:
void updatePalette();
private:
void updatePalette();
VersionControlObserver* m_versionControlObserver;
VersionControlObserver* m_versionControlObserver;
+ QTimer* m_twoClicksRenamingTimer;
+ QUrl m_twoClicksRenamingItemUrl;
+
// For unit tests
friend class TestBase;
friend class DolphinDetailsViewTest;
// For unit tests
friend class TestBase;
friend class DolphinDetailsViewTest;