]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/views/dolphinview.cpp
[DolphinView] Fix "Folder is empty" label showing prematurely
[dolphin.git] / src / views / dolphinview.cpp
index a8624170d965d2dc12bf002dda6c7aeef66e8f44..d03b75ddd8784224770a8ee16787728e4b6e990b 100644 (file)
@@ -48,7 +48,9 @@
 #include <QApplication>
 #include <QClipboard>
 #include <QDropEvent>
+#include <QGraphicsOpacityEffect>
 #include <QGraphicsSceneDragDropEvent>
+#include <QLabel>
 #include <QMenu>
 #include <QMimeDatabase>
 #include <QPixmapCache>
@@ -65,6 +67,7 @@ DolphinView::DolphinView(const QUrl& url, QWidget* parent) :
     m_assureVisibleCurrentIndex(false),
     m_isFolderWritable(true),
     m_dragging(false),
+    m_loading(false),
     m_url(url),
     m_viewPropertiesContext(),
     m_mode(DolphinView::IconsView),
@@ -82,7 +85,8 @@ DolphinView::DolphinView(const QUrl& url, QWidget* parent) :
     m_clearSelectionBeforeSelectingNewItems(false),
     m_markFirstNewlySelectedItemAsCurrent(false),
     m_versionControlObserver(nullptr),
-    m_twoClicksRenamingTimer(nullptr)
+    m_twoClicksRenamingTimer(nullptr),
+    m_placeholderLabel(nullptr)
 {
     m_topLayout = new QVBoxLayout(this);
     m_topLayout->setSpacing(0);
@@ -120,6 +124,28 @@ DolphinView::DolphinView(const QUrl& url, QWidget* parent) :
     connect(m_container->horizontalScrollBar(), &QScrollBar::valueChanged, this, [=] { hideToolTip(); });
     connect(m_container->verticalScrollBar(), &QScrollBar::valueChanged, this, [=] { hideToolTip(); });
 
+    // Show some placeholder text for empty folders
+    // This is made using a heavily-modified QLabel rather than a KTitleWidget
+    // because KTitleWidget can't be told to turn off mouse-selectable text
+    m_placeholderLabel = new QLabel(this);
+    QFont placeholderLabelFont;
+    // To match the size of a level 2 Heading/KTitleWidget
+    placeholderLabelFont.setPointSize(qRound(placeholderLabelFont.pointSize() * 1.3));
+    m_placeholderLabel->setFont(placeholderLabelFont);
+    m_placeholderLabel->setTextInteractionFlags(Qt::NoTextInteraction);
+    m_placeholderLabel->setWordWrap(true);
+    m_placeholderLabel->setAlignment(Qt::AlignCenter);
+    // Match opacity of QML placeholder label component
+    auto *effect = new QGraphicsOpacityEffect(m_placeholderLabel);
+    effect->setOpacity(0.5);
+    m_placeholderLabel->setGraphicsEffect(effect);
+    // Set initial text and visibility
+    updatePlaceholderLabel();
+
+    auto *centeringLayout = new QVBoxLayout(m_container);
+    centeringLayout->addWidget(m_placeholderLabel);
+    centeringLayout->setAlignment(m_placeholderLabel, Qt::AlignCenter);
+
     controller->setSelectionBehavior(KItemListController::MultiSelection);
     connect(controller, &KItemListController::itemActivated, this, &DolphinView::slotItemActivated);
     connect(controller, &KItemListController::itemsActivated, this, &DolphinView::slotItemsActivated);
@@ -140,7 +166,7 @@ DolphinView::DolphinView(const QUrl& url, QWidget* parent) :
 
     connect(m_model, &KFileItemModel::directoryLoadingStarted,       this, &DolphinView::slotDirectoryLoadingStarted);
     connect(m_model, &KFileItemModel::directoryLoadingCompleted,     this, &DolphinView::slotDirectoryLoadingCompleted);
-    connect(m_model, &KFileItemModel::directoryLoadingCanceled,      this, &DolphinView::directoryLoadingCanceled);
+    connect(m_model, &KFileItemModel::directoryLoadingCanceled,      this, &DolphinView::slotDirectoryLoadingCanceled);
     connect(m_model, &KFileItemModel::directoryLoadingProgress,   this, &DolphinView::directoryLoadingProgress);
     connect(m_model, &KFileItemModel::directorySortingProgress,   this, &DolphinView::directorySortingProgress);
     connect(m_model, &KFileItemModel::itemsChanged,
@@ -152,6 +178,9 @@ DolphinView::DolphinView(const QUrl& url, QWidget* parent) :
     connect(m_model, &KFileItemModel::directoryRedirection, this, &DolphinView::slotDirectoryRedirection);
     connect(m_model, &KFileItemModel::urlIsFileError,            this, &DolphinView::urlIsFileError);
 
+    connect(this, &DolphinView::itemCountChanged,
+            this, &DolphinView::updatePlaceholderLabel);
+
     m_view->installEventFilter(this);
     connect(m_view, &DolphinItemListView::sortOrderChanged,
             this, &DolphinView::slotSortOrderChangedByHeader);
@@ -847,10 +876,10 @@ bool DolphinView::eventFilter(QObject* watched, QEvent* event)
 void DolphinView::wheelEvent(QWheelEvent* event)
 {
     if (event->modifiers().testFlag(Qt::ControlModifier)) {
-        const int numDegrees = event->delta() / 8;
-        const int numSteps = numDegrees / 15;
+        const QPoint numDegrees = event->angleDelta() / 8;
+        const QPoint numSteps = numDegrees / 15;
 
-        setZoomLevel(zoomLevel() + numSteps);
+        setZoomLevel(zoomLevel() + numSteps.y());
         event->accept();
     } else {
         event->ignore();
@@ -915,7 +944,7 @@ void DolphinView::slotItemsActivated(const KItemSet& indexes)
         const QUrl& url = openItemAsFolderUrl(item);
 
         if (!url.isEmpty()) { // Open folders in new tabs
-            Q_EMIT tabRequested(url, DolphinTabWidget::AfterLastTab);
+            Q_EMIT tabRequested(url);
         } else {
             items.append(item);
         }
@@ -933,9 +962,9 @@ void DolphinView::slotItemMiddleClicked(int index)
     const KFileItem& item = m_model->fileItem(index);
     const QUrl& url = openItemAsFolderUrl(item);
     if (!url.isEmpty()) {
-        Q_EMIT tabRequested(url, DolphinTabWidget::AfterCurrentTab);
+        Q_EMIT tabRequested(url);
     } else if (isTabsForFilesEnabled()) {
-        Q_EMIT tabRequested(item.url(), DolphinTabWidget::AfterCurrentTab);
+        Q_EMIT tabRequested(item.url());
     }
 }
 
@@ -1594,6 +1623,9 @@ void DolphinView::slotRenamingResult(KJob* job)
 
 void DolphinView::slotDirectoryLoadingStarted()
 {
+    m_loading = true;
+    updatePlaceholderLabel();
+
     // Disable the writestate temporary until it can be determined in a fast way
     // in DolphinView::slotDirectoryLoadingCompleted()
     if (m_isFolderWritable) {
@@ -1606,15 +1638,30 @@ void DolphinView::slotDirectoryLoadingStarted()
 
 void DolphinView::slotDirectoryLoadingCompleted()
 {
+    m_loading = false;
+
     // Update the view-state. This has to be done asynchronously
     // because the view might not be in its final state yet.
     QTimer::singleShot(0, this, &DolphinView::updateViewState);
 
+    // Update the placeholder label in case we found that the folder was empty
+    // after loading it
+
     Q_EMIT directoryLoadingCompleted();
 
+    updatePlaceholderLabel();
     updateWritableState();
 }
 
+void DolphinView::slotDirectoryLoadingCanceled()
+{
+    m_loading = false;
+
+    updatePlaceholderLabel();
+
+    Q_EMIT directoryLoadingCanceled();
+}
+
 void DolphinView::slotItemsChanged()
 {
     m_assureVisibleCurrentIndex = false;
@@ -1976,3 +2023,35 @@ void DolphinView::slotSwipeUp()
 {
     Q_EMIT goUpRequested();
 }
+
+void DolphinView::updatePlaceholderLabel()
+{
+    if (m_loading || itemsCount() > 0) {
+        m_placeholderLabel->setVisible(false);
+        return;
+    }
+
+    if (!nameFilter().isEmpty()) {
+        m_placeholderLabel->setText(i18n("No items matching the filter"));
+    } else if (m_url.scheme() == QLatin1String("baloosearch") || m_url.scheme() == QLatin1String("filenamesearch")) {
+        m_placeholderLabel->setText(i18n("No items matching the search"));
+    } else if (m_url.scheme() == QLatin1String("trash")) {
+        m_placeholderLabel->setText(i18n("Trash is empty"));
+    } else if (m_url.scheme() == QLatin1String("tags")) {
+        m_placeholderLabel->setText(i18n("No tags"));
+    } else if (m_url.scheme() == QLatin1String("recentlyused")) {
+        m_placeholderLabel->setText(i18n("No recently used items"));
+    } else if (m_url.scheme() == QLatin1String("smb")) {
+        m_placeholderLabel->setText(i18n("No shared folders found"));
+    } else if (m_url.scheme() == QLatin1String("network")) {
+        m_placeholderLabel->setText(i18n("No relevant network resources found"));
+    } else if (m_url.scheme() == QLatin1String("mtp")) {
+        m_placeholderLabel->setText(i18n("No MTP-compatible devices found"));
+    } else if (m_url.scheme() == QLatin1String("bluetooth")) {
+        m_placeholderLabel->setText(i18n("No Bluetooth devices found"));
+    } else {
+        m_placeholderLabel->setText(i18n("Folder is empty"));
+    }
+
+    m_placeholderLabel->setVisible(true);
+}