diff --git a/applet/contents/ui/PopupDialog.qml b/applet/contents/ui/PopupDialog.qml --- a/applet/contents/ui/PopupDialog.qml +++ b/applet/contents/ui/PopupDialog.qml @@ -19,6 +19,8 @@ */ import QtQuick 2.2 +import QtQuick.Layouts 1.2 +import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.extras 2.0 as PlasmaExtras import org.kde.plasma.networkmanagement 0.2 as PlasmaNM @@ -40,40 +42,34 @@ sourceModel: connectionModel } - Toolbar { - id: toolbar + ColumnLayout { + anchors.fill: parent - anchors { - left: parent.left - right: parent.right - top: parent.top - } - } - - PlasmaExtras.ScrollArea { - id: scrollView - - anchors { - bottom: parent.bottom - left: parent.left - right: parent.right - top: toolbar.bottom + Toolbar { + id: toolbar + Layout.fillWidth: true } - ListView { - id: connectionView - - property bool availableConnectionsVisible: false - property int currentVisibleButtonIndex: -1 - - anchors.fill: parent - clip: true - model: appletProxyModel - currentIndex: -1 - boundsBehavior: Flickable.StopAtBounds - section.property: showSections ? "Section" : "" - section.delegate: Header { text: section } - delegate: ConnectionItem { } + PlasmaExtras.ScrollArea { + id: scrollView + Layout.fillWidth: true + Layout.fillHeight: true + + ListView { + id: connectionView + + property bool availableConnectionsVisible: false + property int currentVisibleButtonIndex: -1 + + anchors.fill: parent + clip: true + model: appletProxyModel + currentIndex: -1 + boundsBehavior: Flickable.StopAtBounds + section.property: showSections ? "Section" : "" + section.delegate: Header { text: section } + delegate: ConnectionItem { } + } } } @@ -94,6 +90,7 @@ }); } else { notificationInhibitorLock = undefined; + toolbar.closeSearch() } } } diff --git a/applet/contents/ui/Toolbar.qml b/applet/contents/ui/Toolbar.qml --- a/applet/contents/ui/Toolbar.qml +++ b/applet/contents/ui/Toolbar.qml @@ -19,15 +19,21 @@ */ import QtQuick 2.2 +import QtQuick.Layouts 1.2 import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.networkmanagement 0.2 as PlasmaNM import org.kde.kquickcontrolsaddons 2.0 -Item { +GridLayout { id: toolbar - height: wifiSwitchButton.height + function closeSearch() { + searchToggleButton.checked = false + } + + rows: 2 + columns: 2 PlasmaCore.Svg { id: lineSvg @@ -55,11 +61,7 @@ } Row { - anchors { - bottom: parent.bottom - left: parent.left - top: parent.top - } + Layout.fillWidth: true SwitchButton { id: wifiSwitchButton @@ -111,21 +113,52 @@ } } - PlasmaComponents.ToolButton { - id: openEditorButton + Row { + Layout.column: 1 + + PlasmaComponents.ToolButton { + id: searchToggleButton + iconSource: "search" + tooltip: i18ndc("plasma-nm", "button tooltip", "Search the connections") + checkable: true + } + + PlasmaComponents.ToolButton { + id: openEditorButton + iconSource: "configure" + tooltip: i18n("Configure network connections...") + visible: mainWindow.kcmAuthorized - anchors { - right: parent.right - rightMargin: Math.round(units.gridUnit / 2) - verticalCenter: parent.verticalCenter + onClicked: { + KCMShell.open(mainWindow.kcm) + } } + } + + PlasmaComponents.TextField { + id: searchTextField - iconSource: "configure" - tooltip: i18n("Configure network connections...") - visible: mainWindow.kcmAuthorized + Layout.row: 1 + Layout.columnSpan: 2 + Layout.fillWidth: true + Layout.leftMargin: units.smallSpacing + Layout.rightMargin: units.smallSpacing + Layout.bottomMargin: units.smallSpacing - onClicked: { - KCMShell.open(mainWindow.kcm) + focus: true + clearButtonShown: true + placeholderText: i18ndc("plasma-nm", "text field placeholder text", "Search...") + + visible: searchToggleButton.checked + onVisibleChanged: if (!visible) text = "" + Keys.onEscapePressed: searchToggleButton.checked = false + + onTextChanged: { + // Show search field when starting to type directly + if (text.length && !searchToggleButton.checked) { + searchToggleButton.checked = true + } + appletProxyModel.setFilterRegExp(text) } } } diff --git a/libs/models/appletproxymodel.cpp b/libs/models/appletproxymodel.cpp --- a/libs/models/appletproxymodel.cpp +++ b/libs/models/appletproxymodel.cpp @@ -26,6 +26,7 @@ : QSortFilterProxyModel(parent) { setDynamicSortFilter(true); + setFilterCaseSensitivity(Qt::CaseInsensitive); sort(0, Qt::DescendingOrder); } @@ -37,9 +38,9 @@ { const QModelIndex index = sourceModel()->index(source_row, 0, source_parent); - // slaves are always filtered-out + // slaves are filtered-out when not searching for a connection (makes the state of search results clear) const bool isSlave = sourceModel()->data(index, NetworkModel::SlaveRole).toBool(); - if (isSlave) { + if (isSlave && filterRegExp().isEmpty()) { return false; } @@ -50,12 +51,16 @@ NetworkModelItem::ItemType itemType = (NetworkModelItem::ItemType)sourceModel()->data(index, NetworkModel::ItemTypeRole).toUInt(); - if (itemType == NetworkModelItem::AvailableConnection || - itemType == NetworkModelItem::AvailableAccessPoint) { + if (itemType != NetworkModelItem::AvailableConnection && + itemType != NetworkModelItem::AvailableAccessPoint) { + return false; + } + + if (filterRegExp().isEmpty()) { return true; } - return false; + return sourceModel()->data(index, NetworkModel::ItemUniqueNameRole).toString().contains(filterRegExp()); } bool AppletProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const