X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/0a6257bce3de877e4ae869f974df645c428d32c9..33a0d17ea8d4de81322ca51a5acc1356f37798ed:/src/dolphinviewcontainer.cpp diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index 14bc4b7bc..e21262977 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -18,63 +18,70 @@ ***************************************************************************/ #include "dolphinviewcontainer.h" -#include -#include -#include -#include +#include "dolphin_generalsettings.h" +#include "dolphinplacesmodelsingleton.h" +#include "dolphindebug.h" +#include "filterbar/filterbar.h" +#include "global.h" +#include "search/dolphinsearchbox.h" +#include "statusbar/dolphinstatusbar.h" +#include "trash/dolphintrash.h" +#include "views/viewmodecontroller.h" +#include "views/viewproperties.h" +#ifdef HAVE_KACTIVITIES +#include +#endif #include #include -#include -#include #include +#include #include -#include +#include +#include #include -#include #include #include -#include -#ifdef KActivities_FOUND -#endif - -#include "dolphin_generalsettings.h" -#include "filterbar/filterbar.h" -#include "search/dolphinsearchbox.h" -#include "statusbar/dolphinstatusbar.h" -#include "views/draganddrophelper.h" -#include "views/viewmodecontroller.h" -#include "views/viewproperties.h" +#include +#include +#include +#include +#include +#include -DolphinViewContainer::DolphinViewContainer(const KUrl& url, QWidget* parent) : +DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) : QWidget(parent), - m_topLayout(0), - m_urlNavigator(0), - m_searchBox(0), - m_messageWidget(0), - m_view(0), - m_filterBar(0), - m_statusBar(0), - m_statusBarTimer(0), + m_topLayout(nullptr), + m_navigatorWidget(nullptr), + m_urlNavigator(nullptr), + m_emptyTrashButton(nullptr), + m_searchBox(nullptr), + m_searchModeEnabled(false), + m_messageWidget(nullptr), + m_view(nullptr), + m_filterBar(nullptr), + m_statusBar(nullptr), + m_statusBarTimer(nullptr), m_statusBarTimestamp(), - m_autoGrabFocus(true), - m_dropDestination(), - m_dropEvent(0) -#ifdef KActivities_FOUND - , m_activityResourceInstance(0) + m_autoGrabFocus(true) +#ifdef HAVE_KACTIVITIES + , m_activityResourceInstance(nullptr) #endif { hide(); m_topLayout = new QVBoxLayout(this); m_topLayout->setSpacing(0); - m_topLayout->setMargin(0); + m_topLayout->setContentsMargins(0, 0, 0, 0); + + m_navigatorWidget = new QWidget(this); + QHBoxLayout* navigatorLayout = new QHBoxLayout(m_navigatorWidget); + navigatorLayout->setSpacing(0); + navigatorLayout->setContentsMargins(0, 0, 0, 0); - m_urlNavigator = new KUrlNavigator(new KFilePlacesModel(this), url, this); - connect(m_urlNavigator, &KUrlNavigator::urlsDropped, - this, &DolphinViewContainer::dropUrls); + m_urlNavigator = new KUrlNavigator(DolphinPlacesModelSingleton::instance().placesModel(), url, this); connect(m_urlNavigator, &KUrlNavigator::activated, this, &DolphinViewContainer::activate); connect(m_urlNavigator->editor(), &KUrlComboBox::completionModeChanged, @@ -83,10 +90,17 @@ DolphinViewContainer::DolphinViewContainer(const KUrl& url, QWidget* parent) : const GeneralSettings* settings = GeneralSettings::self(); m_urlNavigator->setUrlEditable(settings->editableUrl()); m_urlNavigator->setShowFullPath(settings->showFullPath()); - m_urlNavigator->setHomeUrl(KUrl(settings->homeUrl())); + m_urlNavigator->setHomeUrl(Dolphin::homeUrl()); KUrlComboBox* editor = m_urlNavigator->editor(); editor->setCompletionMode(KCompletion::CompletionMode(settings->urlCompletionMode())); + m_emptyTrashButton = new QPushButton(QIcon::fromTheme(QStringLiteral("user-trash")), i18nc("@action:button", "Empty Trash"), this); + m_emptyTrashButton->setFlat(true); + connect(m_emptyTrashButton, &QPushButton::clicked, this, [this]() { Trash::empty(this); }); + connect(&Trash::instance(), &Trash::emptinessChanged, m_emptyTrashButton, &QPushButton::setDisabled); + m_emptyTrashButton->setDisabled(Trash::isEmpty()); + m_emptyTrashButton->hide(); + m_searchBox = new DolphinSearchBox(this); m_searchBox->hide(); connect(m_searchBox, &DolphinSearchBox::activated, this, &DolphinViewContainer::activate); @@ -98,13 +112,19 @@ DolphinViewContainer::DolphinViewContainer(const KUrl& url, QWidget* parent) : m_messageWidget->setCloseButtonVisible(true); m_messageWidget->hide(); +#ifndef Q_OS_WIN + if (getuid() == 0) { + + // We must be logged in as the root user; show a big scary warning + showMessage(i18n("Running Dolphin as root can be dangerous. Please be careful."), Warning); + } +#endif + m_view = new DolphinView(url, this); connect(m_view, &DolphinView::urlChanged, - m_urlNavigator, &KUrlNavigator::setUrl); + m_urlNavigator, &KUrlNavigator::setLocationUrl); connect(m_view, &DolphinView::urlChanged, m_messageWidget, &KMessageWidget::hide); - connect(m_view, &DolphinView::directoryLoadingCompleted, - m_messageWidget, &KMessageWidget::hide); connect(m_view, &DolphinView::writeStateChanged, this, &DolphinViewContainer::writeStateChanged); connect(m_view, &DolphinView::requestItemInfo, @@ -129,8 +149,6 @@ DolphinViewContainer::DolphinViewContainer(const KUrl& url, QWidget* parent) : this, &DolphinViewContainer::updateDirectorySortingProgress); connect(m_view, &DolphinView::selectionChanged, this, &DolphinViewContainer::delayedStatusBarUpdate); - connect(m_view, &DolphinView::urlAboutToBeChanged, - this, &DolphinViewContainer::slotViewUrlAboutToBeChanged); connect(m_view, &DolphinView::errorMessage, this, &DolphinViewContainer::showErrorMessage); connect(m_view, &DolphinView::urlIsFileError, @@ -142,10 +160,17 @@ DolphinViewContainer::DolphinViewContainer(const KUrl& url, QWidget* parent) : this, &DolphinViewContainer::slotUrlNavigatorLocationAboutToBeChanged); connect(m_urlNavigator, &KUrlNavigator::urlChanged, this, &DolphinViewContainer::slotUrlNavigatorLocationChanged); - connect(m_urlNavigator, &KUrlNavigator::historyChanged, - this, &DolphinViewContainer::slotHistoryChanged); + connect(m_urlNavigator, &KUrlNavigator::urlSelectionRequested, + this, &DolphinViewContainer::slotUrlSelectionRequested); connect(m_urlNavigator, &KUrlNavigator::returnPressed, this, &DolphinViewContainer::slotReturnPressed); + connect(m_urlNavigator, &KUrlNavigator::urlsDropped, this, [=](const QUrl &destination, QDropEvent *event) { + m_view->dropUrls(destination, event, m_urlNavigator->dropWidget()); + }); + + connect(m_view, &DolphinView::directoryLoadingCompleted, this, [this]() { + m_emptyTrashButton->setVisible(m_view->url().scheme() == QLatin1String("trash")); + }); // Initialize status bar m_statusBar = new DolphinStatusBar(this); @@ -185,7 +210,10 @@ DolphinViewContainer::DolphinViewContainer(const KUrl& url, QWidget* parent) : connect(m_view, &DolphinView::urlChanged, m_filterBar, &FilterBar::slotUrlChanged); - m_topLayout->addWidget(m_urlNavigator); + navigatorLayout->addWidget(m_urlNavigator); + navigatorLayout->addWidget(m_emptyTrashButton); + + m_topLayout->addWidget(m_navigatorWidget); m_topLayout->addWidget(m_searchBox); m_topLayout->addWidget(m_messageWidget); m_topLayout->addWidget(m_view); @@ -196,18 +224,17 @@ DolphinViewContainer::DolphinViewContainer(const KUrl& url, QWidget* parent) : // Initialize kactivities resource instance - #ifdef KActivities_FOUND - m_activityResourceInstance = new KActivities::ResourceInstance( - window()->winId(), url); +#ifdef HAVE_KACTIVITIES + m_activityResourceInstance = new KActivities::ResourceInstance(window()->winId(), url); m_activityResourceInstance->setParent(this); - #endif +#endif } DolphinViewContainer::~DolphinViewContainer() { } -KUrl DolphinViewContainer::url() const +QUrl DolphinViewContainer::url() const { return m_view->url(); } @@ -218,13 +245,13 @@ void DolphinViewContainer::setActive(bool active) m_urlNavigator->setActive(active); m_view->setActive(active); - #ifdef KActivities_FOUND +#ifdef HAVE_KACTIVITIES if (active) { m_activityResourceInstance->notifyFocusedIn(); } else { m_activityResourceInstance->notifyFocusedOut(); } - #endif +#endif } bool DolphinViewContainer::isActive() const @@ -243,6 +270,11 @@ bool DolphinViewContainer::autoGrabFocus() const return m_autoGrabFocus; } +QString DolphinViewContainer::currentSearchText() const +{ + return m_searchBox->text(); +} + const DolphinStatusBar* DolphinViewContainer::statusBar() const { return m_statusBar; @@ -281,6 +313,10 @@ void DolphinViewContainer::showMessage(const QString& msg, MessageType type) m_messageWidget->setText(msg); + // TODO: wrap at arbitrary character positions once QLabel can do this + // https://bugreports.qt.io/browse/QTBUG-1276 + m_messageWidget->setWordWrap(true); + switch (type) { case Information: m_messageWidget->setMessageType(KMessageWidget::Information); break; case Warning: m_messageWidget->setMessageType(KMessageWidget::Warning); break; @@ -308,7 +344,7 @@ void DolphinViewContainer::readSettings() // settings of the URL navigator and the filterbar. m_urlNavigator->setUrlEditable(GeneralSettings::editableUrl()); m_urlNavigator->setShowFullPath(GeneralSettings::showFullPath()); - m_urlNavigator->setHomeUrl(KUrl(GeneralSettings::homeUrl())); + m_urlNavigator->setHomeUrl(Dolphin::homeUrl()); setFilterBarVisible(GeneralSettings::filterBar()); } @@ -332,27 +368,29 @@ void DolphinViewContainer::setSearchModeEnabled(bool enabled) } m_searchBox->setVisible(enabled); - m_urlNavigator->setVisible(!enabled); + m_navigatorWidget->setVisible(!enabled); if (enabled) { - const KUrl& locationUrl = m_urlNavigator->locationUrl(); + const QUrl& locationUrl = m_urlNavigator->locationUrl(); m_searchBox->fromSearchUrl(locationUrl); } else { m_view->setViewPropertiesContext(QString()); // Restore the URL for the URL navigator. If Dolphin has been // started with a search-URL, the home URL is used as fallback. - KUrl url = m_searchBox->searchPath(); + QUrl url = m_searchBox->searchPath(); if (url.isEmpty() || !url.isValid() || isSearchUrl(url)) { - url = GeneralSettings::self()->homeUrl(); + url = Dolphin::homeUrl(); } m_urlNavigator->setLocationUrl(url); } + + m_searchModeEnabled = enabled; } bool DolphinViewContainer::isSearchModeEnabled() const { - return m_searchBox->isVisible(); + return m_searchModeEnabled; } QString DolphinViewContainer::placesText() const @@ -360,26 +398,82 @@ QString DolphinViewContainer::placesText() const QString text; if (isSearchModeEnabled()) { - text = m_searchBox->searchPath().fileName() + QLatin1String(": ") + m_searchBox->text(); + text = i18n("Search for %1 in %2", m_searchBox->text(), m_searchBox->searchPath().fileName()); } else { text = url().fileName(); if (text.isEmpty()) { text = url().host(); } + if (text.isEmpty()) { + text = url().scheme(); + } } return text; } -void DolphinViewContainer::setUrl(const KUrl& newUrl) +void DolphinViewContainer::reload() +{ + view()->reload(); + m_messageWidget->hide(); +} + +QString DolphinViewContainer::caption() const +{ + if (GeneralSettings::showFullPathInTitlebar()) { + if (!url().isLocalFile()) { + return url().adjusted(QUrl::StripTrailingSlash).toString(); + } + return url().adjusted(QUrl::StripTrailingSlash).path(); + } + + KFilePlacesModel *placesModel = DolphinPlacesModelSingleton::instance().placesModel(); + const auto& matchedPlaces = placesModel->match(placesModel->index(0,0), KFilePlacesModel::UrlRole, url(), 1, Qt::MatchExactly); + + if (!matchedPlaces.isEmpty()) { + return placesModel->text(matchedPlaces.first()); + } + + if (isSearchModeEnabled()) { + if (currentSearchText().isEmpty()){ + return i18n("Search"); + } else { + return i18n("Search for %1", currentSearchText()); + } + } + + if (!url().isLocalFile()) { + QUrl adjustedUrl = url().adjusted(QUrl::StripTrailingSlash); + QString caption; + if (!adjustedUrl.fileName().isEmpty()) { + caption = adjustedUrl.fileName(); + } else if (!adjustedUrl.path().isEmpty() && adjustedUrl.path() != "/") { + caption = adjustedUrl.path(); + } else if (!adjustedUrl.host().isEmpty()) { + caption = adjustedUrl.host(); + } else { + caption = adjustedUrl.toString(); + } + return caption; + } + + QString fileName = url().adjusted(QUrl::StripTrailingSlash).fileName(); + if (fileName.isEmpty()) { + fileName = '/'; + } + + return fileName; +} + +void DolphinViewContainer::setUrl(const QUrl& newUrl) { if (newUrl != m_urlNavigator->locationUrl()) { m_urlNavigator->setLocationUrl(newUrl); } - #ifdef KActivities_FOUND +#ifdef HAVE_KACTIVITIES m_activityResourceInstance->setUri(newUrl); - #endif +#endif } void DolphinViewContainer::setFilterBarVisible(bool visible) @@ -476,16 +570,16 @@ void DolphinViewContainer::slotDirectoryLoadingCanceled() m_statusBar->setText(QString()); } -void DolphinViewContainer::slotUrlIsFileError(const KUrl& url) +void DolphinViewContainer::slotUrlIsFileError(const QUrl& url) { - const KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url); + const KFileItem item(url); // Find out if the file can be opened in the view (for example, this is the // case if the file is an archive). The mime type must be known for that. item.determineMimeType(); - const KUrl& folderUrl = DolphinView::openItemAsFolderUrl(item, true); + const QUrl& folderUrl = DolphinView::openItemAsFolderUrl(item, true); if (!folderUrl.isEmpty()) { - m_view->setUrl(folderUrl); + setUrl(folderUrl); } else { slotItemActivated(item); } @@ -498,13 +592,14 @@ void DolphinViewContainer::slotItemActivated(const KFileItem& item) // results in an active view. m_view->setActive(true); - const KUrl& url = DolphinView::openItemAsFolderUrl(item, GeneralSettings::browseThroughArchives()); + const QUrl& url = DolphinView::openItemAsFolderUrl(item, GeneralSettings::browseThroughArchives()); if (!url.isEmpty()) { - m_view->setUrl(url); + setUrl(url); return; } - new KRun(item.targetUrl(), this); + KRun *run = new KRun(item.targetUrl(), this); + run->setShowScriptExecutionPrompt(true); } void DolphinViewContainer::slotItemsActivated(const KFileItemList& items) @@ -542,52 +637,34 @@ void DolphinViewContainer::activate() setActive(true); } -void DolphinViewContainer::slotViewUrlAboutToBeChanged(const KUrl& url) +void DolphinViewContainer::slotUrlNavigatorLocationAboutToBeChanged(const QUrl&) { - // URL changes of the view can happen in two ways: - // 1. The URL navigator gets changed and will trigger the view to update its URL - // 2. The URL of the view gets changed and will trigger the URL navigator to update - // its URL (e.g. by clicking on an item) - // In this scope the view-state may only get saved in case 2: - if (url != m_urlNavigator->locationUrl()) { - saveViewState(); - } -} - -void DolphinViewContainer::slotUrlNavigatorLocationAboutToBeChanged(const KUrl& url) -{ - // URL changes of the view can happen in two ways: - // 1. The URL navigator gets changed and will trigger the view to update its URL - // 2. The URL of the view gets changed and will trigger the URL navigator to update - // its URL (e.g. by clicking on an item) - // In this scope the view-state may only get saved in case 1: - if (url != m_view->url()) { - saveViewState(); - } + saveViewState(); } -void DolphinViewContainer::slotUrlNavigatorLocationChanged(const KUrl& url) +void DolphinViewContainer::slotUrlNavigatorLocationChanged(const QUrl& url) { slotReturnPressed(); if (KProtocolManager::supportsListing(url)) { setSearchModeEnabled(isSearchUrl(url)); m_view->setUrl(url); + tryRestoreViewState(); if (m_autoGrabFocus && isActive() && !isSearchUrl(url)) { // When an URL has been entered, the view should get the focus. // The focus must be requested asynchronously, as changing the URL might create // a new view widget. - QTimer::singleShot(0, this, SLOT(requestFocus())); + QTimer::singleShot(0, this, &DolphinViewContainer::requestFocus); } } else if (KProtocolManager::isSourceProtocol(url)) { - QString app = "konqueror"; - if (url.protocol().startsWith(QLatin1String("http"))) { + QString app = QStringLiteral("konqueror"); + if (url.scheme().startsWith(QLatin1String("http"))) { showMessage(i18nc("@info:status", // krazy:exclude=qmethods "Dolphin does not support web pages, the web browser has been launched"), Information); - const KConfigGroup config(KSharedConfig::openConfig("kdeglobals"), "General"); + const KConfigGroup config(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), "General"); const QString browser = config.readEntry("BrowserApplication"); if (!browser.isEmpty()) { app = browser; @@ -602,7 +679,7 @@ void DolphinViewContainer::slotUrlNavigatorLocationChanged(const KUrl& url) Information); } - const QString secureUrl = KShell::quoteArg(url.pathOrUrl()); + const QString secureUrl = KShell::quoteArg(url.toDisplayString(QUrl::PreferLocalFile)); const QString command = app + ' ' + secureUrl; KRun::runCommand(command, app, app, this); } else { @@ -610,42 +687,13 @@ void DolphinViewContainer::slotUrlNavigatorLocationChanged(const KUrl& url) } } -void DolphinViewContainer::dropUrls(const KUrl& destination, QDropEvent* event) -{ - m_dropDestination = destination; - - const QMimeData* mimeData = event->mimeData(); - QMimeData* mimeDataCopy = new QMimeData; - foreach (const QString& format, mimeData->formats()) { - mimeDataCopy->setData(format, mimeData->data(format)); - } - - m_dropEvent.reset(new QDropEvent(event->pos(), - event->possibleActions(), - mimeDataCopy, - event->mouseButtons(), - event->keyboardModifiers())); - - QTimer::singleShot(0, this, SLOT(dropUrlsDelayed())); -} - -void DolphinViewContainer::dropUrlsDelayed() +void DolphinViewContainer::slotUrlSelectionRequested(const QUrl& url) { - if (m_dropEvent.isNull()) { - return; - } - - QString error; - DragAndDropHelper::dropUrls(KFileItem(), m_dropDestination, m_dropEvent.data(), error); - if (!error.isEmpty()) { - showMessage(error, Error); - } - - delete m_dropEvent->mimeData(); - m_dropEvent.reset(); + m_view->markUrlsAsSelected({url}); + m_view->markUrlAsCurrent(url); // makes the item scroll into view } -void DolphinViewContainer::redirect(const KUrl& oldUrl, const KUrl& newUrl) +void DolphinViewContainer::redirect(const QUrl& oldUrl, const QUrl& newUrl) { Q_UNUSED(oldUrl); const bool block = m_urlNavigator->signalsBlocked(); @@ -671,15 +719,6 @@ void DolphinViewContainer::saveUrlCompletionMode(KCompletion::CompletionMode com GeneralSettings::setUrlCompletionMode(completion); } -void DolphinViewContainer::slotHistoryChanged() -{ - QByteArray locationState = m_urlNavigator->locationState(); - if (!locationState.isEmpty()) { - QDataStream stream(&locationState, QIODevice::ReadOnly); - m_view->restoreState(stream); - } -} - void DolphinViewContainer::slotReturnPressed() { if (!GeneralSettings::editableUrl()) { @@ -689,9 +728,9 @@ void DolphinViewContainer::slotReturnPressed() void DolphinViewContainer::startSearching() { - const KUrl url = m_searchBox->urlForSearching(); + const QUrl url = m_searchBox->urlForSearching(); if (url.isValid() && !url.isEmpty()) { - m_view->setViewPropertiesContext("search"); + m_view->setViewPropertiesContext(QStringLiteral("search")); m_urlNavigator->setLocationUrl(url); } } @@ -717,10 +756,9 @@ void DolphinViewContainer::showErrorMessage(const QString& msg) showMessage(msg, Error); } -bool DolphinViewContainer::isSearchUrl(const KUrl& url) const +bool DolphinViewContainer::isSearchUrl(const QUrl& url) const { - const QString protocol = url.protocol(); - return protocol.contains("search"); + return url.scheme().contains(QStringLiteral("search")); } void DolphinViewContainer::saveViewState() @@ -731,3 +769,11 @@ void DolphinViewContainer::saveViewState() m_urlNavigator->saveLocationState(locationState); } +void DolphinViewContainer::tryRestoreViewState() +{ + QByteArray locationState = m_urlNavigator->locationState(); + if (!locationState.isEmpty()) { + QDataStream stream(&locationState, QIODevice::ReadOnly); + m_view->restoreState(stream); + } +}