/*
- * Copyright 2020 Felix Ernst <fe.a.ernst@gmail.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) version 3, or any
- * later version accepted by the membership of KDE e.V. (or its
- * successor approved by the membership of KDE e.V.), which shall
- * act as a proxy defined in Section 6 of version 3 of the license.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <https://www.gnu.org/licenses/>.
- */
+ This file is part of the KDE project
+ SPDX-FileCopyrightText: 2020 Felix Ernst <felixernst@kde.org>
+
+ SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
+*/
#include "dolphinurlnavigator.h"
#include "dolphin_generalsettings.h"
#include "dolphinplacesmodelsingleton.h"
+#include "dolphinurlnavigatorscontroller.h"
#include "global.h"
-#include <KToggleAction>
-#include <KUrlComboBox>
#include <KLocalizedString>
+#include <KUrlComboBox>
+#include <QAbstractButton>
+#include <QKeyEvent>
+#include <QLabel>
+#include <QLayout>
#include <QLineEdit>
-#include <QMenu>
-DolphinUrlNavigator::DolphinUrlNavigator(QWidget *parent) :
- KUrlNavigator(DolphinPlacesModelSingleton::instance().placesModel(), QUrl(), parent)
+DolphinUrlNavigator::DolphinUrlNavigator(QWidget *parent)
+ : DolphinUrlNavigator(QUrl(), parent)
{
- init();
}
-DolphinUrlNavigator::DolphinUrlNavigator(const QUrl &url, QWidget *parent) :
- KUrlNavigator(DolphinPlacesModelSingleton::instance().placesModel(), url, parent)
+DolphinUrlNavigator::DolphinUrlNavigator(const QUrl &url, QWidget *parent)
+ : KUrlNavigator(DolphinPlacesModelSingleton::instance().placesModel(), url, parent)
{
- init();
-}
-
-void DolphinUrlNavigator::init()
-{
- const GeneralSettings* settings = GeneralSettings::self();
+ const GeneralSettings *settings = GeneralSettings::self();
setUrlEditable(settings->editableUrl());
setShowFullPath(settings->showFullPath());
setHomeUrl(Dolphin::homeUrl());
- setPlacesSelectorVisible(s_placesSelectorVisible);
+ setPlacesSelectorVisible(DolphinUrlNavigatorsController::placesSelectorVisible());
editor()->setCompletionMode(KCompletion::CompletionMode(settings->urlCompletionMode()));
- editor()->lineEdit()->installEventFilter(this);
- installEventFilter(this);
setWhatsThis(xi18nc("@info:whatsthis location bar",
- "<para>This line describes the location of the files and folders "
- "displayed below.</para><para>The name of the currently viewed "
- "folder can be read at the very right. To the left of it is the "
- "name of the folder that contains it. The whole line is called "
- "the <emphasis>path</emphasis> to the current location because "
- "following these folders from left to right leads here.</para>"
- "<para>This interactive path "
- "is more powerful than one would expect. To learn more "
- "about the basic and advanced features of the location bar "
- "<link url='help:/dolphin/location-bar.html'>click here</link>. "
- "This will open the dedicated page in the Handbook.</para>"));
-
- s_instances.push_front(this);
-
- connect(this, &DolphinUrlNavigator::returnPressed,
- this, &DolphinUrlNavigator::slotReturnPressed);
- connect(editor(), &KUrlComboBox::completionModeChanged,
- this, DolphinUrlNavigator::setCompletionMode);
+ "<para>This describes the location of the files and folders "
+ "displayed below.</para><para>The name of the currently viewed "
+ "folder can be read at the very right. To the left of it is the "
+ "name of the folder that contains it. The whole line is called "
+ "the <emphasis>path</emphasis> to the current location because "
+ "following these folders from left to right leads here.</para>"
+ "<para>This interactive path "
+ "is more powerful than one would expect. To learn more "
+ "about the basic and advanced features of the location bar "
+ "<link url='help:/dolphin/location-bar.html'>click here</link>. "
+ "This will open the dedicated page in the Handbook.</para>"));
+
+ DolphinUrlNavigatorsController::registerDolphinUrlNavigator(this);
+
+ connect(this, &KUrlNavigator::returnPressed, this, &DolphinUrlNavigator::slotReturnPressed);
+
+ auto readOnlyBadge = new QLabel();
+ readOnlyBadge->setPixmap(QIcon::fromTheme(QStringLiteral("emblem-readonly")).pixmap(12, 12));
+ readOnlyBadge->setToolTip(i18nc("@info:tooltip of a 'locked' symbol in url navigator", "This folder is not writable for you."));
+ readOnlyBadge->hide();
+ setBadgeWidget(readOnlyBadge);
}
DolphinUrlNavigator::~DolphinUrlNavigator()
{
- s_instances.remove(this);
+ DolphinUrlNavigatorsController::unregisterDolphinUrlNavigator(this);
}
-bool DolphinUrlNavigator::eventFilter(QObject* watched, QEvent* event)
+QSize DolphinUrlNavigator::sizeHint() const
{
- Q_UNUSED(watched)
- if (event->type() == QEvent::ChildPolished) {
- QChildEvent *childEvent = static_cast<QChildEvent *>(event);
- QMenu *popup = qobject_cast<QMenu *>(childEvent->child());
- if (popup) {
- // The popups of the "breadcrumb mode" navigation buttons
- // should not get the action added. They can currently be
- // identified by their number of separators: 0 or 1
- // The popups we are interested in have 2 or more separators.
- int separatorCount = 0;
- for (QAction *action : popup->actions()) {
- if (action->isSeparator()) {
- separatorCount++;
- }
- }
- if (separatorCount > 1) {
- q_check_ptr(s_ActionForContextMenu);
- popup->addAction(s_ActionForContextMenu);
- }
+ if (isUrlEditable()) {
+ return editor()->lineEdit()->sizeHint();
+ }
+ int widthHint = 0;
+ for (int i = 0; i < layout()->count(); ++i) {
+ QWidget *widget = layout()->itemAt(i)->widget();
+ const QAbstractButton *button = qobject_cast<QAbstractButton *>(widget);
+ if (button && button->icon().isNull()) {
+ widthHint += widget->minimumSizeHint().width();
}
}
- return false;
+ if (readOnlyBadgeVisible()) {
+ widthHint += badgeWidget()->sizeHint().width();
+ }
+ return QSize(widthHint, KUrlNavigator::sizeHint().height());
}
-void DolphinUrlNavigator::slotReadSettings()
+std::unique_ptr<DolphinUrlNavigator::VisualState> DolphinUrlNavigator::visualState() const
{
- // The startup settings should (only) get applied if they have been
- // modified by the user. Otherwise keep the (possibly) different current
- // settings of the URL navigators and split view.
- if (GeneralSettings::modifiedStartupSettings()) {
- for (DolphinUrlNavigator *urlNavigator : s_instances) {
- urlNavigator->setUrlEditable(GeneralSettings::editableUrl());
- urlNavigator->setShowFullPath(GeneralSettings::showFullPath());
- urlNavigator->setHomeUrl(Dolphin::homeUrl());
+ std::unique_ptr<VisualState> visualState{new VisualState};
+ visualState->isUrlEditable = (isUrlEditable());
+ const QLineEdit *lineEdit = editor()->lineEdit();
+ visualState->hasFocus = lineEdit->hasFocus();
+ visualState->text = lineEdit->text();
+ visualState->cursorPosition = lineEdit->cursorPosition();
+ visualState->selectionStart = lineEdit->selectionStart();
+ visualState->selectionLength = lineEdit->selectionLength();
+ return visualState;
+}
+
+void DolphinUrlNavigator::setVisualState(const VisualState &visualState)
+{
+ setUrlEditable(visualState.isUrlEditable);
+ if (!visualState.isUrlEditable) {
+ return;
+ }
+ editor()->lineEdit()->setText(visualState.text);
+ if (visualState.hasFocus) {
+ editor()->lineEdit()->setFocus();
+ editor()->lineEdit()->setCursorPosition(visualState.cursorPosition);
+ if (visualState.selectionStart != -1) {
+ editor()->lineEdit()->setSelection(visualState.selectionStart, visualState.selectionLength);
}
}
}
-void DolphinUrlNavigator::slotReturnPressed()
+void DolphinUrlNavigator::clearText() const
{
- if (!GeneralSettings::editableUrl()) {
- setUrlEditable(false);
- }
+ editor()->lineEdit()->clear();
}
-void DolphinUrlNavigator::addToContextMenu(QAction* action)
+void DolphinUrlNavigator::setPlaceholderText(const QString &text)
{
- s_ActionForContextMenu = action;
+ editor()->lineEdit()->setPlaceholderText(text);
}
+void DolphinUrlNavigator::setReadOnlyBadgeVisible(bool visible)
+{
+ QWidget *readOnlyBadge = badgeWidget();
+ if (readOnlyBadge) {
+ readOnlyBadge->setVisible(visible);
+ }
+}
-void DolphinUrlNavigator::slotPlacesPanelVisibilityChanged(bool visible)
+bool DolphinUrlNavigator::readOnlyBadgeVisible() const
{
- // The places-selector from the URL navigator should only be shown
- // if the places dock is invisible
- s_placesSelectorVisible = !visible;
+ QWidget *readOnlyBadge = badgeWidget();
+ if (readOnlyBadge) {
+ return readOnlyBadge->isVisible();
+ }
+ return false;
+}
- for (DolphinUrlNavigator *urlNavigator : s_instances) {
- urlNavigator->setPlacesSelectorVisible(s_placesSelectorVisible);
+void DolphinUrlNavigator::slotReturnPressed()
+{
+ if (!GeneralSettings::editableUrl()) {
+ setUrlEditable(false);
}
}
-void DolphinUrlNavigator::setCompletionMode(const KCompletion::CompletionMode completionMode)
+void DolphinUrlNavigator::keyPressEvent(QKeyEvent *keyEvent)
{
- if (completionMode != GeneralSettings::urlCompletionMode())
- {
- GeneralSettings::setUrlCompletionMode(completionMode);
- for (const DolphinUrlNavigator *urlNavigator : s_instances)
- {
- urlNavigator->editor()->setCompletionMode(completionMode);
- }
+ if (keyEvent->key() == Qt::Key_Escape && !isUrlEditable()) {
+ Q_EMIT requestToLoseFocus();
+ return;
}
+ KUrlNavigator::keyPressEvent(keyEvent);
}
-std::forward_list<DolphinUrlNavigator *> DolphinUrlNavigator::s_instances;
-bool DolphinUrlNavigator::s_placesSelectorVisible = true;
-QAction *DolphinUrlNavigator::s_ActionForContextMenu = nullptr;
+#include "moc_dolphinurlnavigator.cpp"