diff --git a/qml/AppControls2/IconLabel.qml b/qml/AppControls2/IconLabel.qml index f3ffe53..a4e2245 100644 --- a/qml/AppControls2/IconLabel.qml +++ b/qml/AppControls2/IconLabel.qml @@ -1,5 +1,7 @@ import QtQuick 2.0 import org.ukui.menu.core 1.0 +import org.ukui.quick.platform 1.0 as Platform +import org.ukui.quick.items 1.0 as UkuiItems Item { id: root @@ -66,10 +68,10 @@ Item { cache: false } - StyleText { + UkuiItems.StyleText { id: iconText text: root.appName elide: Text.ElideRight - paletteRole: root.textHighLight ? Palette.HighlightedText : Palette.Text + paletteRole: root.textHighLight ? Platform.Theme.HighlightedText : Platform.Theme.Text } } diff --git a/qml/AppUI/EditText.qml b/qml/AppUI/EditText.qml index 2a91d61..c3d3afd 100644 --- a/qml/AppUI/EditText.qml +++ b/qml/AppUI/EditText.qml @@ -28,7 +28,8 @@ Item { property bool textCenterIn: false property bool editStatus: false property string textEdited: title - property bool isFullScreenFolder: false + property bool isFullScreen: false + property bool isFolder: false property real textInputSize: 14 Component { @@ -39,9 +40,13 @@ Item { horizontalAlignment: contain.textCenterIn ? Text.AlignHCenter : Text.AlignLeft elide: Text.ElideRight text: contain.textEdited - paletteRole: isFullScreenFolder ? Platform.Theme.HighlightedText : Platform.Theme.Text - font.bold: !isFullScreenFolder - font.pointSize: isFullScreenFolder ? textUltra : systemFontSize + paletteRole: isFullScreen ? Platform.Theme.HighlightedText : Platform.Theme.Text + font.bold: !isFolder + // AppControls2 StyleText + property real textUltra: 2*systemFontSize + property real systemFontSize: 10 + + font.pointSize: isFolder ? textUltra : systemFontSize MouseArea { id: textArea @@ -78,7 +83,7 @@ Item { text: contain.textEdited selectByMouse: true maximumLength: 14 - font.bold: !isFullScreenFolder + font.bold: !isFolder font.pointSize: contain.textInputSize onEditingFinished: { @@ -87,7 +92,7 @@ Item { contain.editStatus = false; } - property int textColor: isFullScreenFolder ? Palette.HighlightedText : Palette.Text + property int textColor: isFullScreen ? Palette.HighlightedText : Palette.Text function updateTextInputColor() { color = themePalette.paletteColor(textColor); selectionColor = themePalette.paletteColor(Palette.Highlight); diff --git a/qml/AppUI/FullScreenFolder.qml b/qml/AppUI/Folder.qml similarity index 95% rename from qml/AppUI/FullScreenFolder.qml rename to qml/AppUI/Folder.qml index 26ab7ca..01affd4 100644 --- a/qml/AppUI/FullScreenFolder.qml +++ b/qml/AppUI/Folder.qml @@ -35,7 +35,8 @@ Loader { property int viewMaxRow: 0 property bool isFolderOpened: false - property int margins: 20 + property bool isFullScreen: true + property int margins: isFullScreen? 20 : 0 property int animationDuration: 300 property bool mouseEnable: false signal turnPageFinished() @@ -72,17 +73,17 @@ Loader { name: "folderOpened" PropertyChanges { target: folderIconBase - width: 720 - height: viewMaxRow * 170 + margins * 2 + width: isFullScreen ? 720 : 348 + height: isFullScreen ? (viewMaxRow * 170 + margins * 2) : (viewMaxRow * 85 + margins * 2) radius: Platform.Theme.maxRadius gridViewMargin: margins - x: (parent.width - width) / 2 - y: (parent.height - height) / 2 + x: isFullScreen ? (parent.width - width) / 2 : 56 + y: isFullScreen ? (parent.height - height) / 2 : 104 // 内部图标尺寸和布局 - folderIconSize: 96 + folderIconSize:isFullScreen ? 96 : 48 iconSpacing: 8 - imageX: 37 - imageY: 17 + imageX: isFullScreen ? 37 : 13 + imageY: isFullScreen ? 17 : 8 } PropertyChanges { target: folderNameText; opacity: 1 } }, @@ -275,7 +276,7 @@ Loader { } onClicked: { if (mouse.button === Qt.RightButton) { - menuManager.showMenu(id, MenuInfo.FullScreenFolder); + menuManager.showMenu(id, MenuInfo.Folder); return; } if (mouse.button === Qt.LeftButton) { @@ -299,7 +300,8 @@ Loader { height: 47; width: folderIconBase.width textEdited: folderName textCenterIn: true - isFullScreenFolder: true + isFolder: true + isFullScreen: isFullScreen } } } diff --git a/qml/AppUI/FullScreenUI.qml b/qml/AppUI/FullScreenUI.qml index 91d4438..e048d9c 100644 --- a/qml/AppUI/FullScreenUI.qml +++ b/qml/AppUI/FullScreenUI.qml @@ -45,7 +45,7 @@ UkuiItems.StyleBackground { Component.onDestruction: folderLoader.turnPageFinished.disconnect(contentShowFinished) } - FullScreenFolder { + Folder { id: folderLoader anchors.fill: parent Component.onCompleted: fullScreenContent.openFolderSignal.connect(initFolder) diff --git a/qml/AppUI/qmldir b/qml/AppUI/qmldir index edf547f..bae0b10 100644 --- a/qml/AppUI/qmldir +++ b/qml/AppUI/qmldir @@ -12,3 +12,4 @@ PluginSelectButton 1.0 PluginSelectButton.qml FullScreenHeader 1.0 FullScreenHeader.qml FullScreenContent 1.0 FullScreenContent.qml FullScreenFooter 1.0 FullScreenFooter.qml +Folder 1.0 Folder.qml diff --git a/qml/extensions/FavoriteExtension.qml b/qml/extensions/FavoriteExtension.qml index 31fa758..6cd6b09 100644 --- a/qml/extensions/FavoriteExtension.qml +++ b/qml/extensions/FavoriteExtension.qml @@ -24,17 +24,20 @@ import org.ukui.menu.extension 1.0 import AppControls2 1.0 as AppControls2 import org.ukui.quick.platform 1.0 as Platform import org.ukui.quick.items 1.0 as UkuiItems +import AppUI 1.0 as AppUI UkuiMenuExtension { - Component.onCompleted: { - visualModel.model = extensionData.favoriteAppsModel - } - MouseArea { id: viewMouseArea anchors.fill: parent hoverEnabled: true + onClicked: { + folderLoader.isFolderOpened = false; + favoriteView.visible = true; + favoriteView.isContentShow = true; + } + UkuiItems.StyleBackground { anchors.top: parent.top width: parent.width; height: 1 @@ -45,187 +48,26 @@ UkuiMenuExtension { z: 1 } - GridView { + AppUI.Folder { + id: folderLoader + anchors.fill: parent + + isFullScreen: false + Component.onCompleted: favoriteView.openFolderSignal.connect(initFolder) + Component.onDestruction: favoriteView.openFolderSignal.disconnect(initFolder) + } + + FavoriteGridView { id: favoriteView anchors.fill: parent anchors.leftMargin: 16 anchors.topMargin: 12 anchors.bottomMargin: 6 - cellWidth: itemHeight + spacing; cellHeight: cellWidth - property int exchangedStartIndex: 0 - property int spacing: 4 - property int itemHeight: 104 - property int column: Math.floor(width / cellWidth) - - // 按键导航处理(左右键可以循环) - focus: true - onActiveFocusChanged: currentIndex = 0 - onCountChanged: currentIndex = 0 - Keys.onRightPressed: { - if(currentIndex === count - 1) { - currentIndex = 0; - return; - } - currentIndex++; + Component.onCompleted: { + favoriteView.viewModel.model = extensionData.favoriteAppsModel + folderLoader.turnPageFinished.connect(contentShowFinished) } - Keys.onLeftPressed: { - if(currentIndex === 0) { - currentIndex = count - 1; - return; - } - currentIndex--; - } - Keys.onDownPressed: { - if(currentIndex > count - 1 - column) { - return; - } - currentIndex = currentIndex + column; - } - Keys.onUpPressed: { - if(currentIndex < column) { - return; - } - currentIndex = currentIndex - column; - } - - ScrollBar.vertical: AppControls2.ScrollBar { - id: scrollBar - visible: viewMouseArea.containsMouse - width: 14; height: favoriteView.height - } - - displaced: Transition { - NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad; duration: 200 } - } - - model: DelegateModel { - id: visualModel - delegate: DropArea { - id: delegateRoot - property int visualIndex: DelegateModel.itemsIndex - width: favoriteView.cellWidth; height: favoriteView.cellHeight - onEntered: { - visualModel.items.move(drag.source.visualIndex, icon.visualIndex) - } - Binding { target: icon; property: "visualIndex"; value: visualIndex } - - focus: true - Keys.onReturnPressed: { - var data = {"id": model.id}; - send(data); - } - states: State { - when: delegateRoot.activeFocus - PropertyChanges { - target: icon - alpha: 0.6 - } - } - UkuiItems.StyleBackground { - id: icon - height: favoriteView.itemHeight; width: height - property bool hold: false - property int visualIndex: 0 - x: 0; y: 0 - radius: Platform.Theme.maxRadius - useStyleTransparency: false - scale: icon.hold ? 1.1 :1.0 - alpha: control.containsPress ? 0.75 : control.containsMouse ? 0.6 : 0.40 - - Behavior on scale { - NumberAnimation { duration: 300; easing.type: Easing.InOutCubic } - } - AppControls2.IconLabel { - height: icon.height - width: icon.width - 14 - anchors.centerIn: parent - appName: model.name - appIcon: model.icon - display: Display.TextUnderIcon - scale: (control.containsPress && !icon.hold) ? 1.1 : 1.0 - ToolTip.visible: textTruncated && control.containsMouse - ToolTip.text: model.name - ToolTip.delay: 500 - - Behavior on scale { - NumberAnimation { duration: 300; easing.type: Easing.InOutCubic } - } - } - - MouseArea { - id: control - anchors.fill: parent - hoverEnabled: true - pressAndHoldInterval: 300 - acceptedButtons: Qt.LeftButton | Qt.RightButton - - onClicked: { - if (mouse.button === Qt.RightButton) { - visualModel.model.openMenu(index) - } else if (mouse.button === Qt.LeftButton) { - var data = {"id": model.id}; - send(data); - } - } - onPressAndHold: { - if (mouse.button === Qt.LeftButton) { - drag.target = icon; - icon.hold = true; - favoriteView.exchangedStartIndex = icon.visualIndex; - } - } - onReleased: { - icon.hold = false; - drag.target = null; - } - } - - onHoldChanged: { - if (hold) { - favoriteView.interactive = false; - } else { - favoriteView.interactive = true; - visualModel.model.exchangedAppsOrder(favoriteView.exchangedStartIndex, icon.visualIndex); - } - } - - Drag.active: control.drag.active - Drag.source: icon - Drag.hotSpot.x: icon.width / 2 - Drag.hotSpot.y: icon.height / 2 - - Drag.onActiveChanged: { - if (Drag.active) { - icon.parent = favoriteView; - } else { - iconResetAnimation.start(); - } - } - ParallelAnimation { - id: iconResetAnimation - NumberAnimation { - target: icon - property: "x" - to: delegateRoot.x - easing.type: Easing.OutQuad - duration: 300 - } - NumberAnimation { - target: icon - property: "y" - to: delegateRoot.y - favoriteView.contentY - easing.type: Easing.OutQuad - duration: 300 - } - - onFinished: { - icon.parent = delegateRoot; - icon.x = 0; icon.y = 0; - } - } - } - } - } - } + Component.onDestruction: folderLoader.turnPageFinished.disconnect(contentShowFinished) + } } } diff --git a/qml/extensions/FavoriteGridView.qml b/qml/extensions/FavoriteGridView.qml new file mode 100644 index 0000000..3bb85f6 --- /dev/null +++ b/qml/extensions/FavoriteGridView.qml @@ -0,0 +1,451 @@ +/* + * Copyright (C) 2023, KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +import QtQuick 2.15 +import QtQml.Models 2.1 +import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.15 +import org.ukui.menu.core 1.0 +import org.ukui.menu.extension 1.0 +import org.ukui.quick.platform 1.0 as Platform +import org.ukui.quick.items 1.0 as UkuiItems +import AppControls2 1.0 as AppControls2 + +GridView { + id: favoriteView + cellWidth: itemHeight + spacing; cellHeight: cellWidth + signal openFolderSignal(string folderId, string folderName, int x, int y) + signal contentShowFinished() + property bool isContentShow: true + + property int exchangedStartIndex: 0 + property int spacing: 4 + property int itemHeight: 84 + property int column: Math.floor(width / cellWidth) + property alias viewModel: visualModel + property string mergeToAppId: "" + property bool isMergeToFolder: false + property bool dragTypeIsMerge: false + + state: isContentShow ? "contentShow" : "contentHidden" + states: [ + State { + name: "contentHidden" + PropertyChanges { target: favoriteView; opacity: 0; scale: 0.95 } + }, + State { + name: "contentShow" + PropertyChanges { target: favoriteView; opacity: 1; scale: 1 } + } + ] + + transitions: [ + Transition { + to:"contentHidden" + SequentialAnimation { + PropertyAnimation { properties: "opacity, scale"; duration: 300; easing.type: Easing.InOutCubic } + ScriptAction { script: favoriteView.visible = false } + } + }, + Transition { + to: "contentShow" + PropertyAnimation { properties: "opacity, scale"; duration: 300; easing.type: Easing.InOutCubic } + } + ] + // 按键导航处理(左右键可以循环) + focus: true + onActiveFocusChanged: currentIndex = 0 + onCountChanged: currentIndex = 0 + Keys.onRightPressed: { + if(currentIndex === count - 1) { + currentIndex = 0; + return; + } + currentIndex++; + } + Keys.onLeftPressed: { + if(currentIndex === 0) { + currentIndex = count - 1; + return; + } + currentIndex--; + } + Keys.onDownPressed: { + if(currentIndex > count - 1 - column) { + return; + } + currentIndex = currentIndex + column; + } + Keys.onUpPressed: { + if(currentIndex < column) { + return; + } + currentIndex = currentIndex - column; + } + + ScrollBar.vertical: AppControls2.ScrollBar { + id: scrollBar + visible: viewMouseArea.containsMouse + width: 14; height: favoriteView.height + } + + displaced: Transition { + NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad; duration: 200 } + } + + model: DelegateModel { + id: visualModel + delegate: Item { + id: container + focus: true + width: favoriteView.cellWidth + height: favoriteView.cellHeight + property int visualIndex: DelegateModel.itemsIndex + Binding { target: iconItem; property: "visualIndex"; value: visualIndex } + states: State { + when: activeFocus + PropertyChanges { + target: iconItem + alpha: 0.6 + } + } + Keys.onReturnPressed: { + var data = {"id": model.id}; + send(data); + } + + Timer { + id: delegateDropTimer + property int timeOutCount: 0 + interval: 300 + repeat: true + + onTriggered: { + ++timeOutCount; + if (timeOutCount == 1) { + mergeToAppId = model.id; + isMergeToFolder = (model.type === DataType.Folder); + dragTypeIsMerge = true; + } + } + onRunningChanged:timeOutCount = 0 + } + + DropArea { + id: delegateDropArea + width: 48; height: 48 + anchors.top: parent.top + anchors.topMargin: 8 + anchors.horizontalCenter: parent.horizontalCenter + property string enterSourceId: "" + + onEntered: { + if (drag.source.isFolder) { + return; + } + + enterSourceId = drag.source.sourceId; + delegateDropTimer.running = true; + } + onExited: { + if (delegateDropTimer.timeOutCount < 1) { + dragTypeIsMerge = false; + visualModel.items.move(drag.source.visualIndex, iconItem.visualIndex); + } + + delegateDropTimer.running = false; + enterSourceId = ""; + } + } + + UkuiItems.StyleBackground { + id: iconItem + height: favoriteView.itemHeight; width: height + property bool hold: false + property int visualIndex: 0 + property string sourceId: "" + property bool isFolder: model.type === DataType.Folder + x: 0; y: 0 + radius: 8 + useStyleTransparency: false + paletteRole: Platform.Theme.Text + alpha: hold ? 0 : control.containsPress ? 0.15 : control.containsMouse ? 0.08 : 0 + + Behavior on scale { + NumberAnimation { duration: 300; easing.type: Easing.InOutCubic } + } + + UkuiItems.StyleBackground { + width: 52 + height: width + radius: 14 + anchors.top: parent.top + anchors.margins: 6 + anchors.horizontalCenter: parent.horizontalCenter + paletteRole: Platform.Theme.Text + useStyleTransparency: false + alpha: (delegateDropArea.enterSourceId !== model.id) + && delegateDropArea.containsDrag && dragTypeIsMerge ? 0.15 : 0 + z: -1 + } + + Loader { + id: itemLoader + anchors.centerIn: parent + property int index: model.index + property int type: model.type + property string id: model.id + property string name: model.name + property string icon: model.icon + sourceComponent: { + if (type === DataType.Normal) { + return appItemComponent; + } + if (type === DataType.Folder) { + return folderItemComponent; + } + } + } + Component { + id: appItemComponent + Item { + height: iconItem.height + width: iconItem.width + ToolTip.visible: iconText.truncated && control.containsMouse + ToolTip.text: model.name + ToolTip.delay: 500 + + function itemClicked(mouseButton) { + if (mouseButton === Qt.RightButton) { + visualModel.model.openMenu(index) + } else { + var data = {"id": model.id}; + send(data); + } + } + ColumnLayout { + width: parent.width + anchors.top: parent.top + anchors.topMargin: 8 + anchors.horizontalCenter: parent.horizontalCenter + spacing: 6 + Image { + id: iconImage + Layout.preferredHeight: 48 + Layout.preferredWidth: 48 + sourceSize.height: height + sourceSize.width: width + source: icon + cache: false + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + } + + UkuiItems.StyleText { + id: iconText + Layout.fillWidth: true + text: name + elide: Text.ElideRight + paletteRole: Platform.Theme.Text + horizontalAlignment: Text.AlignHCenter + } + + } + Loader { + id: tag + visible: mainWindow.editMode + anchors.top: parent.top + anchors.right: parent.right + anchors.rightMargin: 10 + Component { + id: editImage + UkuiItems.Button { + width: 28 + height: 28 + icon.width: 16 + icon.height: 16 + background.paletteRole: Platform.Theme.Light + background.alpha: 1 + activeFocusOnTab: false + + onClicked: { + visualModel.model.removeAppFromFavorites(id); + } + + background.radius: width / 2 + icon.source: "ukui-cancel-star-symbolic" + } + } + sourceComponent: mainWindow.editMode ? editImage : null + } + } + } + Component { + id: folderItemComponent + UkuiItems.StyleBackground { + height: iconItem.height + width: iconItem.width - 14 + useStyleTransparency: false + paletteRole: Platform.Theme.Light + radius: 6 + alpha: parent.containsPress ? 0.25 : parent.containsMouse ? 0.15 : 0.00 + + function itemClicked(mouseButton) { + if (mouseButton === Qt.RightButton) { + visualModel.model.openMenu(index); + } else { + var x = mapToGlobal(0,0).x; + var y = mapToGlobal(0,0).y + openFolderSignal(id, name, x, y); + // 执行隐藏动画,并且当前图标消失且鼠标区域不可用 + favoriteView.isContentShow = false; + opacity = 0; + control.enabled = false; + control.hoverEnabled = false; + } + } + + Item { + id: folderItem + property bool isSelect: false + anchors.horizontalCenter: parent.horizontalCenter + height: 40; width: 40 + anchors.top: parent.top + anchors.topMargin: 12 + + UkuiItems.StyleBackground { + anchors.fill: parent + paletteRole: Palette.Text + useStyleTransparency: false + alpha: 0.25 + radius: 24 + visible: folderItem.isSelect + } + + AppControls2.FolderIcon { + id: folderIcon + anchors.fill: parent + rows: 2; columns: 2 + spacing: 2; padding: 2 + icons: icon + radius: 4; alpha: folderItem.isSelect ? 0 : 0.25 + anchors.centerIn: parent + } + } + + UkuiItems.StyleText { + id: folderText + anchors.bottom: parent.bottom + anchors.bottomMargin: 14 + width: parent.width + horizontalAlignment: Text.AlignHCenter + anchors.horizontalCenter: parent.horizontalCenter + elide: Text.ElideRight + text: name + } + } + } + + MouseArea { + id: control + anchors.fill: parent + hoverEnabled: true + pressAndHoldInterval: 300 + acceptedButtons: Qt.LeftButton | Qt.RightButton + + onClicked: { + itemLoader.item.itemClicked(mouse.button); + } + onPressAndHold: { + if (mouse.button === Qt.LeftButton) { + drag.target = iconItem; + iconItem.hold = true; + exchangedStartIndex = iconItem.visualIndex; + iconItem.sourceId = model.id; + } + } + onReleased: { + iconItem.hold = false; + drag.target = null; + } + + } + // folderFunction + function resetOpacity() { + itemLoader.item.opacity = 1; + control.enabled = true; + control.hoverEnabled = true; + } + Component.onCompleted: favoriteView.contentShowFinished.connect(resetOpacity) + Component.onDestruction: favoriteView.contentShowFinished.disconnect(resetOpacity) + + onHoldChanged: { + if (hold) { + favoriteView.interactive = false; + } else { + favoriteView.interactive = true; + if (dragTypeIsMerge && (model.id !== mergeToAppId) && (model.type === DataType.Normal)) { + if (isMergeToFolder) { + visualModel.model.addAppToFolder(model.id, mergeToAppId); + } else { + visualModel.model.addAppsToNewFolder(model.id, mergeToAppId); + } + + } else if (exchangedStartIndex != iconItem.visualIndex) { + visualModel.model.exchangedAppsOrder(exchangedStartIndex, iconItem.visualIndex); + } + } + } + + Drag.active: control.drag.active + Drag.source: iconItem + Drag.hotSpot.x: iconItem.width / 2 + Drag.hotSpot.y: iconItem.height / 2 + + Drag.onActiveChanged: { + if (Drag.active) { + iconItem.parent = favoriteView; + } else { + iconResetAnimation.start(); + } + } + ParallelAnimation { + id: iconResetAnimation + NumberAnimation { + target: iconItem + property: "x" + to: container.x + easing.type: Easing.OutQuad + duration: 300 + } + NumberAnimation { + target: iconItem + property: "y" + to: container.y - favoriteView.contentY + easing.type: Easing.OutQuad + duration: 300 + } + + onFinished: { + iconItem.parent = container; + iconItem.x = 0; iconItem.y = 0; + } + } + } + } + } +} diff --git a/qml/extensions/FolderGridView.qml b/qml/extensions/FolderGridView.qml new file mode 100644 index 0000000..b7de905 --- /dev/null +++ b/qml/extensions/FolderGridView.qml @@ -0,0 +1,10 @@ +import QtQuick 2.12 +import QtQml.Models 2.1 +import QtQuick.Controls 2.5 +import org.ukui.menu.core 1.0 +import org.ukui.menu.extension 1.0 +import AppControls2 1.0 as AppControls2 + +Item { + +} diff --git a/qml/qml.qrc b/qml/qml.qrc index 61faa3d..a0fc9d5 100644 --- a/qml/qml.qrc +++ b/qml/qml.qrc @@ -25,13 +25,15 @@ AppControls2/LabelItem.qml AppControls2/FolderItem.qml extensions/FavoriteExtension.qml + extensions/FavoriteGridView.qml + extensions/FolderGridView.qml AppControls2/RoundButton.qml AppControls2/FolderIcon.qml AppUI/SelectionPage.qml AppUI/AppPageContent.qml AppUI/PluginSelectButton.qml AppUI/EditText.qml - AppUI/FullScreenFolder.qml + AppUI/Folder.qml AppUI/AppPageSearch.qml diff --git a/src/extension/favorite/app-favorite-model.cpp b/src/extension/favorite/app-favorite-model.cpp index ac4edb5..bc28c06 100644 --- a/src/extension/favorite/app-favorite-model.cpp +++ b/src/extension/favorite/app-favorite-model.cpp @@ -122,6 +122,10 @@ void AppFavoritesModel::updateFavoritesApps(const DataEntity &app, const QModelI addFavoriteApp(index); } else if (app.favorite() == 0) { + if (FavoriteFolderHelper::instance()->containApp(app.id())) { + FavoriteFolderHelper::instance()->removeAppFromFolder(app.id()); + } + QPersistentModelIndex index(sourceIndex); removeFavoriteApp(index); }