feat(qml):实现拖拽合并或换位的UI部分功能,添加批量编辑UI

This commit is contained in:
qiqi49 2024-01-08 17:25:27 +08:00 committed by hewenfei
parent 83b4d14306
commit 713ba3d3e0
10 changed files with 519 additions and 200 deletions

View File

@ -1,5 +1,7 @@
import QtQuick 2.0 import QtQuick 2.0
import org.ukui.menu.core 1.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 { Item {
id: root id: root
@ -66,10 +68,10 @@ Item {
cache: false cache: false
} }
StyleText { UkuiItems.StyleText {
id: iconText id: iconText
text: root.appName text: root.appName
elide: Text.ElideRight elide: Text.ElideRight
paletteRole: root.textHighLight ? Palette.HighlightedText : Palette.Text paletteRole: root.textHighLight ? Platform.Theme.HighlightedText : Platform.Theme.Text
} }
} }

View File

@ -28,7 +28,8 @@ Item {
property bool textCenterIn: false property bool textCenterIn: false
property bool editStatus: false property bool editStatus: false
property string textEdited: title property string textEdited: title
property bool isFullScreenFolder: false property bool isFullScreen: false
property bool isFolder: false
property real textInputSize: 14 property real textInputSize: 14
Component { Component {
@ -39,9 +40,13 @@ Item {
horizontalAlignment: contain.textCenterIn ? Text.AlignHCenter : Text.AlignLeft horizontalAlignment: contain.textCenterIn ? Text.AlignHCenter : Text.AlignLeft
elide: Text.ElideRight elide: Text.ElideRight
text: contain.textEdited text: contain.textEdited
paletteRole: isFullScreenFolder ? Platform.Theme.HighlightedText : Platform.Theme.Text paletteRole: isFullScreen ? Platform.Theme.HighlightedText : Platform.Theme.Text
font.bold: !isFullScreenFolder font.bold: !isFolder
font.pointSize: isFullScreenFolder ? textUltra : systemFontSize // AppControls2 StyleText
property real textUltra: 2*systemFontSize
property real systemFontSize: 10
font.pointSize: isFolder ? textUltra : systemFontSize
MouseArea { MouseArea {
id: textArea id: textArea
@ -78,7 +83,7 @@ Item {
text: contain.textEdited text: contain.textEdited
selectByMouse: true selectByMouse: true
maximumLength: 14 maximumLength: 14
font.bold: !isFullScreenFolder font.bold: !isFolder
font.pointSize: contain.textInputSize font.pointSize: contain.textInputSize
onEditingFinished: { onEditingFinished: {
@ -87,7 +92,7 @@ Item {
contain.editStatus = false; contain.editStatus = false;
} }
property int textColor: isFullScreenFolder ? Palette.HighlightedText : Palette.Text property int textColor: isFullScreen ? Palette.HighlightedText : Palette.Text
function updateTextInputColor() { function updateTextInputColor() {
color = themePalette.paletteColor(textColor); color = themePalette.paletteColor(textColor);
selectionColor = themePalette.paletteColor(Palette.Highlight); selectionColor = themePalette.paletteColor(Palette.Highlight);

View File

@ -35,7 +35,8 @@ Loader {
property int viewMaxRow: 0 property int viewMaxRow: 0
property bool isFolderOpened: false property bool isFolderOpened: false
property int margins: 20 property bool isFullScreen: true
property int margins: isFullScreen? 20 : 0
property int animationDuration: 300 property int animationDuration: 300
property bool mouseEnable: false property bool mouseEnable: false
signal turnPageFinished() signal turnPageFinished()
@ -72,17 +73,17 @@ Loader {
name: "folderOpened" name: "folderOpened"
PropertyChanges { PropertyChanges {
target: folderIconBase target: folderIconBase
width: 720 width: isFullScreen ? 720 : 348
height: viewMaxRow * 170 + margins * 2 height: isFullScreen ? (viewMaxRow * 170 + margins * 2) : (viewMaxRow * 85 + margins * 2)
radius: Platform.Theme.maxRadius radius: Platform.Theme.maxRadius
gridViewMargin: margins gridViewMargin: margins
x: (parent.width - width) / 2 x: isFullScreen ? (parent.width - width) / 2 : 56
y: (parent.height - height) / 2 y: isFullScreen ? (parent.height - height) / 2 : 104
// //
folderIconSize: 96 folderIconSize:isFullScreen ? 96 : 48
iconSpacing: 8 iconSpacing: 8
imageX: 37 imageX: isFullScreen ? 37 : 13
imageY: 17 imageY: isFullScreen ? 17 : 8
} }
PropertyChanges { target: folderNameText; opacity: 1 } PropertyChanges { target: folderNameText; opacity: 1 }
}, },
@ -275,7 +276,7 @@ Loader {
} }
onClicked: { onClicked: {
if (mouse.button === Qt.RightButton) { if (mouse.button === Qt.RightButton) {
menuManager.showMenu(id, MenuInfo.FullScreenFolder); menuManager.showMenu(id, MenuInfo.Folder);
return; return;
} }
if (mouse.button === Qt.LeftButton) { if (mouse.button === Qt.LeftButton) {
@ -299,7 +300,8 @@ Loader {
height: 47; width: folderIconBase.width height: 47; width: folderIconBase.width
textEdited: folderName textEdited: folderName
textCenterIn: true textCenterIn: true
isFullScreenFolder: true isFolder: true
isFullScreen: isFullScreen
} }
} }
} }

View File

@ -45,7 +45,7 @@ UkuiItems.StyleBackground {
Component.onDestruction: folderLoader.turnPageFinished.disconnect(contentShowFinished) Component.onDestruction: folderLoader.turnPageFinished.disconnect(contentShowFinished)
} }
FullScreenFolder { Folder {
id: folderLoader id: folderLoader
anchors.fill: parent anchors.fill: parent
Component.onCompleted: fullScreenContent.openFolderSignal.connect(initFolder) Component.onCompleted: fullScreenContent.openFolderSignal.connect(initFolder)

View File

@ -12,3 +12,4 @@ PluginSelectButton 1.0 PluginSelectButton.qml
FullScreenHeader 1.0 FullScreenHeader.qml FullScreenHeader 1.0 FullScreenHeader.qml
FullScreenContent 1.0 FullScreenContent.qml FullScreenContent 1.0 FullScreenContent.qml
FullScreenFooter 1.0 FullScreenFooter.qml FullScreenFooter 1.0 FullScreenFooter.qml
Folder 1.0 Folder.qml

View File

@ -24,17 +24,20 @@ import org.ukui.menu.extension 1.0
import AppControls2 1.0 as AppControls2 import AppControls2 1.0 as AppControls2
import org.ukui.quick.platform 1.0 as Platform import org.ukui.quick.platform 1.0 as Platform
import org.ukui.quick.items 1.0 as UkuiItems import org.ukui.quick.items 1.0 as UkuiItems
import AppUI 1.0 as AppUI
UkuiMenuExtension { UkuiMenuExtension {
Component.onCompleted: {
visualModel.model = extensionData.favoriteAppsModel
}
MouseArea { MouseArea {
id: viewMouseArea id: viewMouseArea
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
onClicked: {
folderLoader.isFolderOpened = false;
favoriteView.visible = true;
favoriteView.isContentShow = true;
}
UkuiItems.StyleBackground { UkuiItems.StyleBackground {
anchors.top: parent.top anchors.top: parent.top
width: parent.width; height: 1 width: parent.width; height: 1
@ -45,187 +48,26 @@ UkuiMenuExtension {
z: 1 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 id: favoriteView
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: 16 anchors.leftMargin: 16
anchors.topMargin: 12 anchors.topMargin: 12
anchors.bottomMargin: 6 anchors.bottomMargin: 6
cellWidth: itemHeight + spacing; cellHeight: cellWidth Component.onCompleted: {
property int exchangedStartIndex: 0 favoriteView.viewModel.model = extensionData.favoriteAppsModel
property int spacing: 4 folderLoader.turnPageFinished.connect(contentShowFinished)
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++;
}
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)
} }
} }
} }

View File

@ -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 <https://www.gnu.org/licenses/>.
*
*/
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;
}
}
}
}
}
}

View File

@ -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 {
}

View File

@ -25,13 +25,15 @@
<file>AppControls2/LabelItem.qml</file> <file>AppControls2/LabelItem.qml</file>
<file>AppControls2/FolderItem.qml</file> <file>AppControls2/FolderItem.qml</file>
<file>extensions/FavoriteExtension.qml</file> <file>extensions/FavoriteExtension.qml</file>
<file>extensions/FavoriteGridView.qml</file>
<file>extensions/FolderGridView.qml</file>
<file>AppControls2/RoundButton.qml</file> <file>AppControls2/RoundButton.qml</file>
<file>AppControls2/FolderIcon.qml</file> <file>AppControls2/FolderIcon.qml</file>
<file>AppUI/SelectionPage.qml</file> <file>AppUI/SelectionPage.qml</file>
<file>AppUI/AppPageContent.qml</file> <file>AppUI/AppPageContent.qml</file>
<file>AppUI/PluginSelectButton.qml</file> <file>AppUI/PluginSelectButton.qml</file>
<file>AppUI/EditText.qml</file> <file>AppUI/EditText.qml</file>
<file>AppUI/FullScreenFolder.qml</file> <file>AppUI/Folder.qml</file>
<file>AppUI/AppPageSearch.qml</file> <file>AppUI/AppPageSearch.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -122,6 +122,10 @@ void AppFavoritesModel::updateFavoritesApps(const DataEntity &app, const QModelI
addFavoriteApp(index); addFavoriteApp(index);
} else if (app.favorite() == 0) { } else if (app.favorite() == 0) {
if (FavoriteFolderHelper::instance()->containApp(app.id())) {
FavoriteFolderHelper::instance()->removeAppFromFolder(app.id());
}
QPersistentModelIndex index(sourceIndex); QPersistentModelIndex index(sourceIndex);
removeFavoriteApp(index); removeFavoriteApp(index);
} }