Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions resources.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<file>src/gui/WindowAccountHeader.qml</file>
<file>src/gui/ActivitiesWindow.qml</file>
<file>src/gui/AssistantWindow.qml</file>
<file>src/gui/search/qml/SearchWindow.qml</file>
<file>src/gui/UserStatusWindowStatusRow.qml</file>
<file>src/gui/UserStatusWindowPredefinedStatusRow.qml</file>
<file>src/gui/UserStatusSelectorPage.qml</file>
Expand Down Expand Up @@ -37,16 +38,16 @@
<file>src/gui/tray/ActivityList.qml</file>
<file>src/gui/tray/CurrentAccountHeaderButton.qml</file>
<file>src/gui/tray/TrayWindowHeader.qml</file>
<file>src/gui/tray/UnifiedSearchInputContainer.qml</file>
<file>src/gui/tray/UnifiedSearchResultFetchMoreTrigger.qml</file>
<file>src/gui/tray/UnifiedSearchResultItem.qml</file>
<file>src/gui/tray/UnifiedSearchResultItemSkeleton.qml</file>
<file>src/gui/tray/UnifiedSearchResultItemSkeletonContainer.qml</file>
<file>src/gui/tray/UnifiedSearchResultItemSkeletonGradientRectangle.qml</file>
<file>src/gui/tray/UnifiedSearchResultListItem.qml</file>
<file>src/gui/tray/UnifiedSearchResultNothingFound.qml</file>
<file>src/gui/tray/UnifiedSearchPlaceholderView.qml</file>
<file>src/gui/tray/UnifiedSearchResultSectionItem.qml</file>
<file>src/gui/search/qml/UnifiedSearchInputContainer.qml</file>
<file>src/gui/search/qml/UnifiedSearchResultFetchMoreTrigger.qml</file>
<file>src/gui/search/qml/UnifiedSearchResultItem.qml</file>
<file>src/gui/search/qml/UnifiedSearchResultItemSkeleton.qml</file>
<file>src/gui/search/qml/UnifiedSearchResultItemSkeletonContainer.qml</file>
<file>src/gui/search/qml/UnifiedSearchResultItemSkeletonGradientRectangle.qml</file>
<file>src/gui/search/qml/UnifiedSearchResultListItem.qml</file>
<file>src/gui/search/qml/UnifiedSearchResultNothingFound.qml</file>
<file>src/gui/search/qml/UnifiedSearchPlaceholderView.qml</file>
<file>src/gui/search/qml/UnifiedSearchResultSectionItem.qml</file>
<file>src/gui/tray/ActivityItemContextMenu.qml</file>
<file>src/gui/tray/ActivityItemActions.qml</file>
<file>src/gui/tray/ActivityItemContent.qml</file>
Expand Down
8 changes: 4 additions & 4 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -216,14 +216,14 @@ set(client_SRCS
tray/activitydata.cpp
tray/activitylistmodel.h
tray/activitylistmodel.cpp
tray/unifiedsearchresult.h
search/unifiedsearchresult.h
tray/asyncimageresponse.cpp
tray/unifiedsearchresult.cpp
tray/unifiedsearchresultslistmodel.h
search/unifiedsearchresult.cpp
search/unifiedsearchresultslistmodel.h
tray/trayimageprovider.cpp
tray/trayaccountappsmodel.h
tray/trayaccountappsmodel.cpp
tray/unifiedsearchresultslistmodel.cpp
search/unifiedsearchresultslistmodel.cpp
tray/usermodel.h
tray/usermodel.cpp
tray/notificationhandler.h
Expand Down
4 changes: 2 additions & 2 deletions src/gui/macOS/trayaccountpopup/ncaccountactionspopup.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#pragma once

#import <Cocoa/Cocoa.h>

Check failure on line 8 in src/gui/macOS/trayaccountpopup/ncaccountactionspopup.h

View workflow job for this annotation

GitHub Actions / build

src/gui/macOS/trayaccountpopup/ncaccountactionspopup.h:8:9 [clang-diagnostic-error]

'Cocoa/Cocoa.h' file not found

#include <QVariantList>

Expand All @@ -14,8 +14,8 @@
/**
* @brief The submenu shown for a single account.
*
* Lists the user status, "Reveal in Finder", the Assistant and Apps shortcuts,
* pending notifications and recent activity. Owns the apps and
* Lists the user status, "Reveal in Finder", the Assistant, Search and Apps
* shortcuts, pending notifications and recent activity. Owns the apps and
* notification-actions sub-popups.
*/
@interface NCAccountActionsPopup : NSPanel
Expand Down
9 changes: 9 additions & 0 deletions src/gui/macOS/trayaccountpopup/ncaccountactionspopup.mm
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ - (void)populateForUserIndex:(int)userIndex owner:(NCTrayPopup *)owner refreshAc
appsModel->setUserId(userIndex);
const auto appsEnabled = appsModel->rowCount() > 0;
const auto assistantEnabled = model->data(userModelIndex, OCC::UserModel::AssistantEnabledRole).toBool();
const auto searchEnabled = model->data(userModelIndex, OCC::UserModel::IsConnectedRole).toBool();
addOwnedArrangedSubview(_stack, [[NCSpacerView alloc] initWithHeight:kActionVerticalPadding width:kAccountActionsPopupWidth]);
if (serverHasUserStatus) {
const auto status = model->data(userModelIndex, OCC::UserModel::StatusRole).value<OCC::UserStatus::OnlineStatus>();
Expand Down Expand Up @@ -275,6 +276,14 @@ - (void)populateForUserIndex:(int)userIndex owner:(NCTrayPopup *)owner refreshAc
[weakSelf hideAppsPopup];
}]);
}
addOwnedArrangedSubview(_stack, [[NCActionRow alloc] initWithTitle:QCoreApplication::translate("TrayAccountPopup", "Search").toNSString()
width:kAccountActionsPopupWidth
enabled:searchEnabled
action:^{
[weakOwner openSearchForIndex:userIndex];
} hoverAction:^(NSView *) {
[weakSelf hideAppsPopup];
}]);
addOwnedArrangedSubview(_stack, [[NCActionRow alloc] initWithTitle:QCoreApplication::translate("TrayWindowHeader", "Apps").toNSString()
icon:nil
width:kAccountActionsPopupWidth
Expand Down
2 changes: 2 additions & 0 deletions src/gui/macOS/trayaccountpopup/nctraypopup.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#pragma once

#import <Cocoa/Cocoa.h>

Check failure on line 8 in src/gui/macOS/trayaccountpopup/nctraypopup.h

View workflow job for this annotation

GitHub Actions / build

src/gui/macOS/trayaccountpopup/nctraypopup.h:8:9 [clang-diagnostic-error]

'Cocoa/Cocoa.h' file not found

#import "ncaccountrow.h"

Expand All @@ -31,6 +31,8 @@
- (void)openLocalFolderForIndex:(int)index;
/** @brief Closes the popups and opens the Assistant window for the given account. */
- (void)openAssistantForIndex:(int)index;
/** @brief Closes the popups and opens the Search window for the given account. */
- (void)openSearchForIndex:(int)index;
/** @brief Closes the popups and opens the user-status window for the given account. */
- (void)openOnlineStatusForIndex:(int)index;
@end
7 changes: 7 additions & 0 deletions src/gui/macOS/trayaccountpopup/nctraypopup.mm
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,13 @@ - (void)openAssistantForIndex:(int)index
OCC::Systray::instance()->showAssistantWindow(index);
}

- (void)openSearchForIndex:(int)index
{
[_accountActionsPopup orderOut:nil];
[self orderOut:nil];
OCC::Systray::instance()->showSearchWindow(index);
}

- (void)openOnlineStatusForIndex:(int)index
{
[_accountActionsPopup orderOut:nil];
Expand Down
2 changes: 1 addition & 1 deletion src/gui/owncloudgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
#include "tray/sortedactivitylistmodel.h"
#include "tray/syncstatussummary.h"
#include "tray/trayaccountappsmodel.h"
#include "tray/unifiedsearchresultslistmodel.h"
#include "search/unifiedsearchresultslistmodel.h"
#include "integration/fileactionsmodel.h"
#include "filesystem.h"

Expand Down Expand Up @@ -254,7 +254,7 @@
// or SSL error dialog also comes to front.
}

void ownCloudGui::slotSyncStateChange(Folder *folder)

Check warning on line 257 in src/gui/owncloudgui.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

This function should be declared "const".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9Lo4dJ_KZ1mwbGinP1&open=AZ9Lo4dJ_KZ1mwbGinP1&pullRequest=10331
{
if (!folder) {
return; // Valid, just a general GUI redraw was needed.
Expand Down
177 changes: 177 additions & 0 deletions src/gui/search/qml/SearchWindow.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/*
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: GPL-2.0-or-later
*/

import QtQuick
import QtQuick.Controls.Basic
import QtQuick.Layouts

import Style
import com.nextcloud.desktopclient
import "../.."

WizardStyledWindow {
id: root

property var account: null
property var searchModel: null
readonly property string headline: qsTr("Search")
readonly property int searchState: searchModel
? searchModel.searchState
: UnifiedSearchResultsListModel.Placeholder
readonly property bool isSearchInProgress: searchModel !== null && searchModel.isSearchInProgress
readonly property bool canEditSearch: searchModel !== null && searchModel.canEditSearch
readonly property bool isAccountConnected: searchModel !== null && searchModel.isAccountConnected

title: ""
width: Style.searchWindowWidth
height: Style.searchWindowHeight
minimumWidth: Style.wizardStandaloneWindowMinimumWidth
minimumHeight: Style.wizardStandaloneWindowMinimumHeight

function focusSearchInput() {
if (visible && searchInput.enabled) {
searchInput.forceActiveFocus()
}
}

Shortcut {
sequences: [StandardKey.Cancel]
onActivated: root.close()
}

Component.onCompleted: Qt.callLater(focusSearchInput)
onVisibleChanged: {
if (visible) {
Qt.callLater(focusSearchInput)
}
}

ColumnLayout {
anchors.fill: parent
anchors.leftMargin: Style.wizardWindowMargin
anchors.rightMargin: Style.wizardWindowMargin
anchors.topMargin: Style.wizardWindowTopMargin
anchors.bottomMargin: Style.wizardWindowMargin
spacing: Style.wizardSectionSpacing

WindowAccountHeader {
Layout.fillWidth: true
title: root.headline
user: root.account
}

UnifiedSearchInputContainer {
id: searchInput

Layout.fillWidth: true
Layout.preferredHeight: Style.unifiedSearchInputContainerHeight
enabled: root.searchModel !== null
readOnly: !root.canEditSearch
text: root.searchModel ? root.searchModel.searchTerm : ""
placeholderText: root.account !== null && !root.isAccountConnected
? qsTr("Search is available when this account is connected")
: qsTr("Search files, messages, events …")
isSearchInProgress: root.isSearchInProgress
onTextEdited: {
if (root.searchModel) {
root.searchModel.searchTerm = searchInput.text
}
}
onClearText: {
if (root.searchModel) {
root.searchModel.searchTerm = ""
}
}
}

Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: Style.normalBorderWidth
color: Style.wizardRowBorder
}

Item {
Layout.fillWidth: true
Layout.fillHeight: true

ErrorBox {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
visible: root.searchState === UnifiedSearchResultsListModel.SearchError
text: root.searchModel ? root.searchModel.errorString : ""
}

UnifiedSearchPlaceholderView {
anchors.fill: parent
visible: root.searchState === UnifiedSearchResultsListModel.Placeholder
}

UnifiedSearchResultNothingFound {
anchors.fill: parent
visible: root.searchState === UnifiedSearchResultsListModel.NothingFound
text: root.searchModel ? root.searchModel.searchTerm : ""
}

Loader {
anchors.fill: parent
anchors.margins: Style.smallSpacing
active: root.searchState === UnifiedSearchResultsListModel.Skeleton
asynchronous: true

sourceComponent: UnifiedSearchResultItemSkeletonContainer {
anchors.fill: parent
spacing: searchResultsListView.spacing
animationRectangleWidth: root.width
}
}

ScrollView {
id: searchResultsScrollView

anchors.fill: parent
contentWidth: availableWidth
visible: root.searchState === UnifiedSearchResultsListModel.Results

ScrollBar.horizontal.policy: ScrollBar.AlwaysOff

ListView {
id: searchResultsListView

spacing: Style.smallSpacing
clip: true
keyNavigationEnabled: true
reuseItems: true
model: root.searchModel

Accessible.role: Accessible.List
Accessible.name: qsTr("Search results list")

delegate: UnifiedSearchResultListItem {
width: searchResultsListView.width
isSearchInProgress: root.isSearchInProgress
currentFetchMoreInProgressProviderId: root.searchModel
? root.searchModel.currentFetchMoreInProgressProviderId
: ""
fetchMoreTriggerClicked: root.searchModel
? root.searchModel.fetchMoreTriggerClicked
: function() {}
resultClicked: root.searchModel
? root.searchModel.resultClicked
: function() {}
ListView.onPooled: isPooled = true
ListView.onReused: isPooled = false
}

section.property: "providerName"
section.criteria: ViewSection.FullString
section.delegate: UnifiedSearchResultSectionItem {
width: searchResultsListView.width
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Qt5Compat.GraphicalEffects
import Style

import com.nextcloud.desktopclient
import "../../tray"

TextField {
id: root
Expand Down Expand Up @@ -44,7 +45,7 @@ TextField {
top: root.top
topMargin: Style.extraSmallSpacing
bottom: root.bottom
bottomMargin: Style.extraSmallSpacing
bottomMargin: Style.extraSmallSpacing
}

fillMode: Image.PreserveAspectFit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Style
import "../../tray"

ColumnLayout {
id: root
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Style
import "../../tray"

ColumnLayout {
id: unifiedSearchResultItemFetchMore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import QtQuick.Layouts
import Qt5Compat.GraphicalEffects

import Style
import "../../tray"

RowLayout {
id: unifiedSearchResultItemDetails
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Style
import "../../tray"

ColumnLayout {
id: unifiedSearchResultNothingFoundContainer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import Style
import com.nextcloud.desktopclient
import "../../tray"

EnforcedPlainTextLabel {
required property string section
Expand Down
Loading
Loading