Merge tag 'upstream/4.0.0.2' into openkylin/yangtze
4.0.0.2-release
This commit is contained in:
commit
375eaf0db9
|
@ -121,6 +121,7 @@ set(SOURCE_FILES
|
|||
src/menu/menu-provider.h
|
||||
src/menu/menu-manager.cpp src/menu/menu-manager.h
|
||||
src/items/theme-icon.h src/items/theme-icon.cpp
|
||||
src/settings/user-config.cpp src/settings/user-config.h
|
||||
)
|
||||
|
||||
# library sources
|
||||
|
|
|
@ -18,3 +18,10 @@ kylin-user-guide.desktop=0
|
|||
ukui-control-center.desktop=0
|
||||
peony.desktop=0
|
||||
engrampa.desktop=0
|
||||
|
||||
[Default Favorite Apps]
|
||||
0=/usr/share/applications/peony.desktop
|
||||
1=/usr/share/applications/ukui-control-center.desktop
|
||||
2=/usr/share/applications/kylin-weather.desktop
|
||||
3=/usr/share/applications/kylin-software-center.desktop
|
||||
4=/usr/share/applications/kylin-screenshot.desktop
|
||||
|
|
|
@ -10,7 +10,7 @@ MouseArea {
|
|||
property bool truncate: false
|
||||
property bool isSelect: false
|
||||
hoverEnabled: true
|
||||
ToolTip.visible: editStatus && truncate && control.containsMouse
|
||||
ToolTip.visible: !editStatus && truncate && control.containsMouse
|
||||
ToolTip.text: name
|
||||
states: State {
|
||||
when: control.activeFocus
|
||||
|
@ -19,6 +19,7 @@ MouseArea {
|
|||
alpha: 0.55
|
||||
}
|
||||
}
|
||||
|
||||
StyleBackground {
|
||||
id: controlBase
|
||||
anchors.fill: parent
|
||||
|
@ -54,7 +55,7 @@ MouseArea {
|
|||
horizontalAlignment: Text.AlignLeft
|
||||
elide: Text.ElideRight
|
||||
text: name
|
||||
Component.onCompleted: {
|
||||
onWidthChanged: {
|
||||
control.truncate = textShow.truncated
|
||||
}
|
||||
}
|
||||
|
@ -84,9 +85,9 @@ MouseArea {
|
|||
selectByMouse: true
|
||||
maximumLength: 14
|
||||
|
||||
onEditingFinished: {
|
||||
modelManager.getAppModel().renameFolder(id, text);
|
||||
function editStatusEnd() {
|
||||
control.editStatus = false;
|
||||
control.focus = true;
|
||||
}
|
||||
|
||||
function updateTextInputColor() {
|
||||
|
@ -94,12 +95,15 @@ MouseArea {
|
|||
selectionColor = themePalette.paletteColor(Palette.Highlight);
|
||||
}
|
||||
|
||||
onEditingFinished: {
|
||||
modelManager.getAppModel().renameFolder(id, text);
|
||||
textChange.editStatusEnd();
|
||||
}
|
||||
Component.onCompleted: {
|
||||
updateTextInputColor();
|
||||
themePalette.styleColorChanged.connect(updateTextInputColor);
|
||||
forceActiveFocus();
|
||||
}
|
||||
|
||||
Component.onDestruction: themePalette.styleColorChanged.disconnect(updateTextInputColor);
|
||||
}
|
||||
|
||||
|
@ -120,12 +124,10 @@ MouseArea {
|
|||
|
||||
onClicked: {
|
||||
textChange.text = name;
|
||||
control.editStatus = false;
|
||||
textChange.editStatusEnd();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loader {
|
||||
|
|
|
@ -66,7 +66,6 @@ Item {
|
|||
StyleText {
|
||||
id: iconText
|
||||
text: root.appName
|
||||
font.pixelSize: 14
|
||||
elide: Text.ElideRight
|
||||
paletteRole: root.textHighLight ? Palette.HighlightedText : Palette.Text
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ MouseArea {
|
|||
|
||||
horizontalAlignment: Qt.AlignLeft
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
font.pixelSize: 14
|
||||
font.bold: true
|
||||
text: name
|
||||
}
|
||||
|
|
|
@ -3,24 +3,31 @@ import org.ukui.menu.core 1.0
|
|||
|
||||
Text {
|
||||
property int paletteRole: Palette.Text
|
||||
property real alpha: 1.0
|
||||
property real alpha: 1
|
||||
property real systemFontSize: 10
|
||||
property real textUltra: 2*systemFontSize
|
||||
|
||||
font.pointSize: systemFontSize
|
||||
function updateColor() {
|
||||
color = themePalette.paletteColorWithCustomTransparency(paletteRole, Palette.Active, alpha)
|
||||
color = themePalette.paletteColorWithCustomTransparency(paletteRole, Palette.Active, alpha);
|
||||
}
|
||||
function updateFontSize() {
|
||||
systemFontSize = themePalette.systemFontSize();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
updateColor()
|
||||
themePalette.styleColorChanged.connect(updateColor)
|
||||
updateColor();
|
||||
updateFontSize();
|
||||
themePalette.styleColorChanged.connect(updateColor);
|
||||
themePalette.systemFontSizeChanged.connect(updateFontSize);
|
||||
}
|
||||
Component.onDestruction: {
|
||||
themePalette.styleColorChanged.disconnect(updateColor)
|
||||
themePalette.styleColorChanged.disconnect(updateColor);
|
||||
themePalette.systemFontSizeChanged.disconnect(updateFontSize);
|
||||
}
|
||||
|
||||
onPaletteRoleChanged: {
|
||||
updateColor()
|
||||
updateColor();
|
||||
}
|
||||
onAlphaChanged: {
|
||||
updateColor()
|
||||
updateColor();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,11 +24,12 @@ import AppControls2 1.0 as AppControls2
|
|||
import org.ukui.menu.core 1.0
|
||||
|
||||
Item {
|
||||
id: appListRoot
|
||||
property string title: ""
|
||||
property string idSelect: ""
|
||||
property bool folderEditStatus: false
|
||||
signal labelItemClicked()
|
||||
signal openFolderPageSignal(string folderId, string folderName);
|
||||
|
||||
signal openFolderPageSignal(string folderId, string folderName)
|
||||
function labelSelection(labelId) {
|
||||
appListView.view.positionViewAtIndex(appListView.model.getLabelIndex(labelId), ListView.Beginning)
|
||||
}
|
||||
|
@ -41,6 +42,16 @@ Item {
|
|||
id: appListView
|
||||
anchors.fill: parent
|
||||
|
||||
// 在listview区域,鼠标进出和移动事件都会清空原有的按键焦点
|
||||
// 鼠标不移动,原有的鼠标悬浮三态会保留
|
||||
onContainsMouseChanged: clearViewFocus()
|
||||
onPositionChanged: clearViewFocus()
|
||||
function clearViewFocus() {
|
||||
if(!folderEditStatus) {
|
||||
appListView.listFocus = false
|
||||
}
|
||||
}
|
||||
|
||||
model: modelManager.getAppModel()
|
||||
delegate: Component {
|
||||
Loader {
|
||||
|
@ -68,6 +79,17 @@ Item {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
view.onContentYChanged: {
|
||||
if (appPageHeaderUtils.currentPluginId() === "all") {
|
||||
return;
|
||||
}
|
||||
|
||||
var obj = view.itemAt(10, view.contentY);
|
||||
if (obj !== null && obj.type === DataType.Label) {
|
||||
appListRoot.title = obj.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
|
@ -90,9 +112,6 @@ Item {
|
|||
}
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
appManager.launchApp(id);
|
||||
if (recentInstall) {
|
||||
appManager.appLaunched(id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -118,9 +137,6 @@ Item {
|
|||
Keys.onPressed: {
|
||||
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
|
||||
appManager.launchApp(id);
|
||||
if (recentInstall) {
|
||||
appManager.appLaunched(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -176,6 +192,7 @@ Item {
|
|||
appListView.model.renameText.disconnect(toEditText);
|
||||
}
|
||||
|
||||
onEditStatusChanged: folderEditStatus = editStatus;
|
||||
function toEditText(idOfIndex){
|
||||
if (id === idOfIndex) {
|
||||
editStatus = true;
|
||||
|
|
|
@ -32,7 +32,7 @@ MouseArea {
|
|||
property int itemHeight: 40
|
||||
hoverEnabled: true
|
||||
clip: true
|
||||
onContainsMouseChanged: listView.focus = false
|
||||
|
||||
AppControls2.StyleBackground {
|
||||
anchors.top: parent.top
|
||||
width: parent.width
|
||||
|
@ -57,6 +57,7 @@ MouseArea {
|
|||
highlightMoveDuration: 0
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
ScrollBar.vertical: listViewScrollBar
|
||||
|
||||
// 焦点切换后,listView按键导航重新开始
|
||||
onActiveFocusChanged: currentIndex = 0
|
||||
onCountChanged: currentIndex = 0
|
||||
|
|
|
@ -37,7 +37,7 @@ AppControls2.StyleBackground {
|
|||
id: appPageHeader
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 40
|
||||
focusToListView: appPageContent
|
||||
focusToPageContent: appPageContent
|
||||
}
|
||||
|
||||
AppPageContent {
|
||||
|
|
|
@ -44,6 +44,9 @@ SwipeView {
|
|||
appList.visible = false;
|
||||
selectionPage.viewShowStart();
|
||||
}
|
||||
onTitleChanged: {
|
||||
appPageHeader.title = title;
|
||||
}
|
||||
}
|
||||
|
||||
SelectionPage {
|
||||
|
|
|
@ -26,13 +26,13 @@ import org.ukui.menu.utils 1.0
|
|||
Item {
|
||||
id: appPageHeaderRoot
|
||||
property string title: ""
|
||||
required property Item focusToListView
|
||||
property Item focusToPageContent
|
||||
property Component content: null
|
||||
clip: true
|
||||
|
||||
function changeToSearch() {
|
||||
function changeToSearch(keyEvent) {
|
||||
if (appPageHeaderRoot.content === null) {
|
||||
loader.item.state = "search";
|
||||
loader.item.changeToSearchState(keyEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,11 @@ Item {
|
|||
Item {
|
||||
id: root
|
||||
|
||||
function changeToSearchState(keyEvent) {
|
||||
state = "search";
|
||||
searchInputBar.text = keyEvent;
|
||||
}
|
||||
|
||||
state: "normal"
|
||||
states: [
|
||||
State {
|
||||
|
@ -128,7 +133,7 @@ Item {
|
|||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
radius: 16
|
||||
keyDownTarget: focusToListView
|
||||
changeFocusTarget: focusToPageContent
|
||||
onTextChanged: {
|
||||
if (text === "") {
|
||||
pluginSelectMenu.model.reactivateProvider();
|
||||
|
@ -145,6 +150,7 @@ Item {
|
|||
activeFocusOnTab: true
|
||||
|
||||
onClicked: {
|
||||
normalUI.focusToFalse();
|
||||
searchInputBar.clear();
|
||||
root.state = "normal";
|
||||
}
|
||||
|
@ -166,7 +172,7 @@ Item {
|
|||
anchors.fill: parent
|
||||
anchors.leftMargin: 16
|
||||
spacing: 12
|
||||
Text {
|
||||
AppControls2.StyleText {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
|
@ -178,6 +184,7 @@ Item {
|
|||
id: searchListView
|
||||
Layout.preferredWidth: childrenRect.width
|
||||
Layout.preferredHeight: 32
|
||||
Layout.minimumWidth: 32
|
||||
Layout.maximumWidth: 68
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
|
@ -209,11 +216,25 @@ Item {
|
|||
Layout.preferredWidth: childrenRect.width
|
||||
Layout.preferredHeight: 32
|
||||
Layout.maximumHeight: 32
|
||||
Layout.minimumWidth: 32
|
||||
Layout.rightMargin: 8
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateTitle(id) {
|
||||
appPageHeaderRoot.title = appPageHeaderUtils.getPluginTitle(id);
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
updateTitle("");
|
||||
appPageHeaderUtils.pluginChanged.connect(updateTitle);
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
appPageHeaderUtils.pluginChanged.disconnect(updateTitle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ Item {
|
|||
property bool editStatus: false
|
||||
property string textEdited: title
|
||||
property bool isFullScreenFolder: false
|
||||
property real textInputSize: 14
|
||||
|
||||
Component {
|
||||
id: unEditText
|
||||
|
@ -39,12 +40,15 @@ Item {
|
|||
text: contain.textEdited
|
||||
paletteRole: isFullScreenFolder ? Palette.HighlightedText : Palette.Text
|
||||
font.bold: !isFullScreenFolder
|
||||
font.pixelSize: isFullScreenFolder ? 32 : 14
|
||||
font.pointSize: isFullScreenFolder ? textUltra : systemFontSize
|
||||
|
||||
MouseArea {
|
||||
id: textArea
|
||||
anchors.fill: parent
|
||||
onDoubleClicked: contain.editStatus = true;
|
||||
onDoubleClicked: {
|
||||
contain.editStatus = true;
|
||||
contain.textInputSize = textShow.font.pointSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +78,7 @@ Item {
|
|||
selectByMouse: true
|
||||
maximumLength: 14
|
||||
font.bold: !isFullScreenFolder
|
||||
font.pixelSize: isFullScreenFolder ? 32 : 14
|
||||
font.pointSize: contain.textInputSize
|
||||
|
||||
onEditingFinished: {
|
||||
modelManager.getFolderModel().renameFolder(text);
|
||||
|
|
|
@ -266,7 +266,6 @@ RowLayout {
|
|||
anchors.bottomMargin: 20
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: name
|
||||
font.pixelSize: 14
|
||||
elide: Text.ElideRight
|
||||
paletteRole: Palette.HighlightedText
|
||||
}
|
||||
|
@ -369,7 +368,6 @@ RowLayout {
|
|||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
elide: Text.ElideRight
|
||||
text: name
|
||||
font.pixelSize: 14
|
||||
paletteRole: Palette.HighlightedText
|
||||
}
|
||||
}
|
||||
|
|
|
@ -268,7 +268,6 @@ Loader {
|
|||
anchors.topMargin: folderIconBase.iconSpacing
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: name
|
||||
font.pixelSize: 14
|
||||
elide: Text.ElideRight
|
||||
paletteRole: Palette.HighlightedText
|
||||
}
|
||||
|
|
|
@ -4,20 +4,21 @@ import AppControls2 1.0 as AppControls2
|
|||
import org.ukui.menu.core 1.0
|
||||
|
||||
FocusScope {
|
||||
id: normalUI
|
||||
anchors.fill: parent
|
||||
function focusToFalse() {
|
||||
focus = false;
|
||||
}
|
||||
function keyPressed(event) {
|
||||
// 任意字符键焦点切换到搜索(0-9 a-z)
|
||||
if ((0x2f < event.key && event.key < 0x3a )||(0x40 < event.key && event.key < 0x5b)) {
|
||||
if ((0x2f < event.key && event.key < 0x3a)||(0x40 < event.key && event.key < 0x5b)) {
|
||||
focus = true;
|
||||
appPage.header.changeToSearch();
|
||||
// 任意方向键切换至搜索结果
|
||||
} else if ( 0x01000011 < event.key && event.key < 0x01000016) {
|
||||
appPage.header.changeToSearch(event.text);
|
||||
// 任意方向键切换至应用列表
|
||||
} else if ((0x01000011 < event.key)&&(event.key < 0x01000016)) {
|
||||
focus = true;
|
||||
appPage.content.resetFocus();
|
||||
appPage.content.focus = true;
|
||||
appPage.content.resetFocus();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,11 @@ RowLayout {
|
|||
id: pluginSelectMenuRoot
|
||||
property var model: appPageHeaderUtils.model(PluginGroup.SortMenuItem)
|
||||
spacing: 2
|
||||
function resetFocus() {
|
||||
if(!mainWindow.isFullScreen) {
|
||||
normalUI.focusToFalse();
|
||||
}
|
||||
}
|
||||
|
||||
AppControls2.RoundButton {
|
||||
id: pluginSelectButton
|
||||
|
@ -39,7 +44,10 @@ RowLayout {
|
|||
highlight: mainWindow.isFullScreen
|
||||
autoHighLight: !mainWindow.isFullScreen
|
||||
buttonIcon: "image://appicon/ukui-selected"
|
||||
onClicked: pluginSelectMenuRoot.model.autoSwitchProvider()
|
||||
onClicked: {
|
||||
resetFocus();
|
||||
pluginSelectMenuRoot.model.autoSwitchProvider();
|
||||
}
|
||||
Keys.onPressed: {
|
||||
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
|
||||
pluginSelectMenuRoot.model.autoSwitchProvider();
|
||||
|
@ -62,6 +70,7 @@ RowLayout {
|
|||
}
|
||||
}
|
||||
onClicked: {
|
||||
resetFocus();
|
||||
sortMenuClicked();
|
||||
}
|
||||
function sortMenuClicked() {
|
||||
|
|
|
@ -23,8 +23,8 @@ import org.ukui.menu.core 1.0
|
|||
import AppControls2 1.0 as AppControls2
|
||||
|
||||
AppControls2.StyleBackground {
|
||||
property Item keyDownTarget
|
||||
readonly property string text: textInput.text;
|
||||
property Item changeFocusTarget
|
||||
property alias text: textInput.text;
|
||||
|
||||
alpha: 0.04
|
||||
useStyleTransparent: false
|
||||
|
@ -68,7 +68,6 @@ AppControls2.StyleBackground {
|
|||
anchors.left: searchIcon.right
|
||||
text: qsTr("Search App")
|
||||
visible: textInput.contentWidth === 0
|
||||
font.pixelSize: 14
|
||||
paletteRole: mainWindow.isFullScreen ? Palette.HighlightedText : Palette.Text
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
alpha: 0.25
|
||||
|
@ -96,11 +95,19 @@ AppControls2.StyleBackground {
|
|||
height: parent.height
|
||||
selectByMouse: true
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
font.pixelSize: 14
|
||||
font.pointSize: defaultText.font.pointSize
|
||||
focus: parent.visible || mainWindow.isFullScreen
|
||||
|
||||
KeyNavigation.down: keyDownTarget
|
||||
onEditingFinished: KeyNavigation.down = keyDownTarget
|
||||
activeFocusOnTab: true
|
||||
function changeFocusToListView() {
|
||||
if (!mainWindow.isFullScreen) {
|
||||
normalUI.focus = true;
|
||||
changeFocusTarget.focus = true;
|
||||
appPage.content.resetFocus();
|
||||
}
|
||||
}
|
||||
onEditingFinished: changeFocusToListView()
|
||||
Keys.onDownPressed: changeFocusToListView()
|
||||
|
||||
//字体选中跟随主题高亮
|
||||
property int textColor: mainWindow.isFullScreen ? Palette.HighlightedText : Palette.Text
|
||||
|
|
|
@ -99,6 +99,9 @@ Item {
|
|||
onLoaded: {
|
||||
item.send.connect(extensionListView.send);
|
||||
}
|
||||
Keys.onTabPressed: {
|
||||
extensionListView.focus = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,6 +173,7 @@ Item {
|
|||
height: ListView.view ? ListView.view.height : 0
|
||||
|
||||
activeFocusOnTab: true
|
||||
KeyNavigation.down: extensionLoader
|
||||
Keys.onPressed: {
|
||||
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
|
||||
ListView.view.currentIndex = model.index;
|
||||
|
@ -194,7 +198,6 @@ Item {
|
|||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.bold: parent.ListView.isCurrentItem
|
||||
wrapMode: Text.ElideRight
|
||||
|
||||
paletteRole: parent.ListView.isCurrentItem ? Palette.Highlight: Palette.Text
|
||||
text: model.name
|
||||
|
@ -203,6 +206,7 @@ Item {
|
|||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
normalUI.focusToFalse();
|
||||
parent.ListView.view.currentIndex = model.index;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,38 @@ UkuiMenuExtension {
|
|||
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++;
|
||||
}
|
||||
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
|
||||
|
@ -73,16 +105,26 @@ UkuiMenuExtension {
|
|||
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
|
||||
}
|
||||
}
|
||||
AppControls2.StyleBackground {
|
||||
id: icon
|
||||
height: favoriteView.itemHeight; width: height
|
||||
property bool hold: false
|
||||
property int visualIndex: 0
|
||||
x: 0; y: 0
|
||||
|
||||
radius: 8
|
||||
useStyleTransparent: false
|
||||
scale: icon.hold ? 1.1 :1.0
|
||||
|
@ -91,7 +133,6 @@ UkuiMenuExtension {
|
|||
Behavior on scale {
|
||||
NumberAnimation { duration: 300; easing.type: Easing.InOutCubic }
|
||||
}
|
||||
|
||||
AppControls2.IconLabel {
|
||||
height: icon.height
|
||||
width: icon.width - 14
|
||||
|
|
|
@ -17,8 +17,11 @@
|
|||
*/
|
||||
|
||||
#include "app-data-manager.h"
|
||||
#include "user-config.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <application-info.h>
|
||||
#include <QDebug>
|
||||
|
||||
#define APP_ICON_PREFIX "image://appicon/"
|
||||
|
||||
|
@ -85,6 +88,13 @@ AppDataWorker::AppDataWorker(AppDataManager *appManager) : QObject(nullptr), m_a
|
|||
|
||||
void AppDataWorker::initAppData()
|
||||
{
|
||||
if (UserConfig::instance()->isFirstStartUp()) {
|
||||
// 默认收藏应用
|
||||
for (const auto &appid : GlobalSetting::instance()->defaultFavoriteApps()) {
|
||||
m_applicationInfo->setAppToFavorites(appid);
|
||||
}
|
||||
}
|
||||
|
||||
m_appProperties << UkuiSearch::ApplicationProperty::Property::Top
|
||||
<< UkuiSearch::ApplicationProperty::Property::Lock
|
||||
<< UkuiSearch::ApplicationProperty::Property::Favorites
|
||||
|
@ -95,6 +105,7 @@ void AppDataWorker::initAppData()
|
|||
<< UkuiSearch::ApplicationProperty::Property::Category
|
||||
<< UkuiSearch::ApplicationProperty::Property::FirstLetterAll
|
||||
<< UkuiSearch::ApplicationProperty::Property::DontDisplay
|
||||
<< UkuiSearch::ApplicationProperty::Property::AutoStart
|
||||
<< UkuiSearch::ApplicationProperty::Property::InsertTime
|
||||
<< UkuiSearch::ApplicationProperty::Property::Launched;
|
||||
m_appPropertyMap.insert(UkuiSearch::ApplicationProperty::Property::DontDisplay, 0);
|
||||
|
@ -111,6 +122,7 @@ void AppDataWorker::initAppData()
|
|||
addInfoToApp(info, app);
|
||||
m_appManager->m_normalApps.insert(app.id(), app);
|
||||
}
|
||||
|
||||
updateFavoriteApps();
|
||||
}
|
||||
|
||||
|
@ -158,13 +170,19 @@ void AppDataWorker::appendApps(const QStringList &infos, QList<DataEntity> &apps
|
|||
{
|
||||
QMutexLocker locker(&m_appManager->m_mutex);
|
||||
for (const QString &info : infos) {
|
||||
UkuiSearch::ApplicationPropertyMap appinfo = m_applicationInfo->getInfo(info, m_appProperties);
|
||||
if (appinfo.value(UkuiSearch::ApplicationProperty::Property::DontDisplay).toInt() == 0) {
|
||||
DataEntity app;
|
||||
addInfoToApp(appinfo, app);
|
||||
m_appManager->m_normalApps.insert(app.id(), app);
|
||||
apps.append(app);
|
||||
const UkuiSearch::ApplicationPropertyMap appInfo = m_applicationInfo->getInfo(info, m_appProperties);
|
||||
if (appInfo.value(UkuiSearch::ApplicationProperty::Property::DontDisplay).toInt() != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (appInfo.value(UkuiSearch::ApplicationProperty::Property::AutoStart).toInt() != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DataEntity app;
|
||||
addInfoToApp(appInfo, app);
|
||||
m_appManager->m_normalApps.insert(app.id(), app);
|
||||
apps.append(app);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -296,6 +314,11 @@ void AppDataWorker::onAppDeleted(QStringList infos)
|
|||
Q_EMIT appDeleted(removedIdList);
|
||||
|
||||
updateFavoriteApps();
|
||||
|
||||
for (const auto &appid : removedIdList) {
|
||||
UserConfig::instance()->removePreInstalledApp(appid);
|
||||
}
|
||||
UserConfig::instance()->sync();
|
||||
}
|
||||
|
||||
void AppDataWorker::fixToFavoriteSlot(const QString &path, const int &num)
|
||||
|
@ -323,7 +346,9 @@ void AppDataWorker::fixToTopSlot(const QString &path, const int &num)
|
|||
|
||||
void AppDataWorker::setAppLaunched(const QString &path)
|
||||
{
|
||||
m_applicationInfo->setAppLaunchedState(path);
|
||||
if (m_appManager->m_normalApps.value(path).launched() == 0) {
|
||||
m_applicationInfo->setAppLaunchedState(path);
|
||||
}
|
||||
}
|
||||
|
||||
void AppDataWorker::removeApps(QStringList &appIdList, QStringList &removedIdList)
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <QMutexLocker>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QSet>
|
||||
|
||||
#include "commons.h"
|
||||
|
||||
|
|
|
@ -129,6 +129,24 @@ QVector<ProviderInfo> DataProviderManager::providers(PluginGroup::Group group) c
|
|||
return infos;
|
||||
}
|
||||
|
||||
ProviderInfo DataProviderManager::providerInfo(const QString &id) const
|
||||
{
|
||||
ProviderInfo info;
|
||||
DataProviderPluginIFace* provider = m_providers.value(id, nullptr);
|
||||
if (provider) {
|
||||
info = {
|
||||
provider->index(),
|
||||
provider->id(),
|
||||
provider->name(),
|
||||
provider->icon(),
|
||||
provider->title(),
|
||||
provider->group()
|
||||
};
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
void DataProviderManager::activateProvider(const QString &id)
|
||||
{
|
||||
if (!m_providers.contains(id) || m_activatedPlugin == id) {
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
|
||||
QStringList providers() const;
|
||||
QVector<ProviderInfo> providers(PluginGroup::Group group) const;
|
||||
ProviderInfo providerInfo(const QString &id) const;
|
||||
QString activatedProvider() const;
|
||||
void activateProvider(const QString &id);
|
||||
QVector<DataEntity> data() const;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "all-app-data-provider.h"
|
||||
#include "app-data-manager.h"
|
||||
#include "app-folder-helper.h"
|
||||
#include "user-config.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDateTime>
|
||||
|
@ -60,7 +61,7 @@ QString AllAppDataProvider::icon()
|
|||
|
||||
QString AllAppDataProvider::title()
|
||||
{
|
||||
return "Recently installed";
|
||||
return tr("All applications");
|
||||
}
|
||||
|
||||
PluginGroup::Group AllAppDataProvider::group()
|
||||
|
@ -151,6 +152,22 @@ void AllAppDataProvider::updateData(const QList<DataEntity> &apps)
|
|||
std::sort(m_appData.begin(), m_appData.end(), appDataSort);
|
||||
}
|
||||
|
||||
void AllAppDataProvider::updateFolderData(QStringList &idList)
|
||||
{
|
||||
QList<Folder> folders = AppFolderHelper::instance()->folderData();
|
||||
if (folders.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (const auto &folder : folders) {
|
||||
for (const auto &app : folder.getApps()) {
|
||||
if (idList.contains(app)) {
|
||||
AppFolderHelper::instance()->removeAppFromFolder(app, folder.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
AppFolderHelper::instance()->forceSync();
|
||||
}
|
||||
|
||||
bool AllAppDataProvider::appDataSort(const DataEntity &a, const DataEntity &b)
|
||||
{
|
||||
if ((a.top() != 0) && (b.top() != 0)) {
|
||||
|
@ -184,13 +201,15 @@ bool AllAppDataProvider::appDataSort(const DataEntity &a, const DataEntity &b)
|
|||
|
||||
void AllAppDataProvider::setRecentState(DataEntity &app)
|
||||
{
|
||||
if (app.launched() == 0) {
|
||||
QDateTime installTime = QDateTime::fromString(app.insertTime(), "yyyy-MM-dd hh:mm:ss");
|
||||
if (installTime.isValid()) {
|
||||
int appTime = installTime.secsTo(QDateTime::currentDateTime());
|
||||
if ((appTime >= 0 ) && (appTime <= 3600*48)) {
|
||||
app.setRecentInstall(true);
|
||||
return;
|
||||
if (!UserConfig::instance()->isPreInstalledApps(app.id())) {
|
||||
if (app.launched() == 0) {
|
||||
QDateTime installTime = QDateTime::fromString(app.insertTime(), "yyyy-MM-dd hh:mm:ss");
|
||||
if (installTime.isValid()) {
|
||||
int appTime = installTime.secsTo(QDateTime::currentDateTime());
|
||||
if ((appTime >= 0 ) && (appTime <= 3600*48)) {
|
||||
app.setRecentInstall(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,6 +253,7 @@ void AllAppDataProvider::onAppDeleted(QStringList idList)
|
|||
{
|
||||
removeApps(idList);
|
||||
reloadFolderData();
|
||||
updateFolderData(idList);
|
||||
sendData();
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ private:
|
|||
void reloadFolderData();
|
||||
void mergeData(QVector<DataEntity> &data);
|
||||
void updateData(const QList<DataEntity>& apps);
|
||||
void updateFolderData(QStringList& idList);
|
||||
static bool appDataSort(const DataEntity &a, const DataEntity &b);
|
||||
static void setRecentState(DataEntity &app);
|
||||
static bool letterSort(const QString &a, const QString &b);
|
||||
|
|
|
@ -84,7 +84,7 @@ QString AppCategoryPlugin::icon()
|
|||
|
||||
QString AppCategoryPlugin::title()
|
||||
{
|
||||
return "Category";
|
||||
return tr("Category");
|
||||
}
|
||||
|
||||
PluginGroup::Group AppCategoryPlugin::group()
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "menu-manager.h"
|
||||
#include "app-manager.h"
|
||||
#include "app-data-manager.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QCursor>
|
||||
|
@ -49,18 +50,11 @@ private:
|
|||
void addToPanelAction(QObject *parent, const QString &appId, QList<QAction *> &list);
|
||||
void addToDesktopAction(QObject *parent, const QString &appId, QList<QAction *> &list);
|
||||
void addUninstall(QObject *parent, const QString &appId, QList<QAction *> &list);
|
||||
private:
|
||||
QStringList m_systemApps;
|
||||
};
|
||||
|
||||
AppMenuProvider::AppMenuProvider()
|
||||
{
|
||||
if (QFile::exists(UKUI_MENU_GLOBAL_CONFIG_FILE)) {
|
||||
QSettings settings(UKUI_MENU_GLOBAL_CONFIG_FILE, QSettings::IniFormat);
|
||||
settings.beginGroup("System Apps");
|
||||
m_systemApps.append(settings.allKeys());
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool AppMenuProvider::isSupport(const MenuProvider::RequestType &type)
|
||||
|
@ -180,9 +174,7 @@ void AppMenuProvider::addToDesktopAction(QObject *parent, const QString &appId,
|
|||
|
||||
void AppMenuProvider::addUninstall(QObject *parent, const QString &appId, QList<QAction *> &list)
|
||||
{
|
||||
bool isSystemApp = std::any_of(m_systemApps.constBegin(), m_systemApps.constEnd(), [&appId](const QString &appName) {
|
||||
return appId.contains(appName);
|
||||
});
|
||||
bool isSystemApp = GlobalSetting::instance()->isSystemApp(appId);
|
||||
if (!isSystemApp) {
|
||||
list << new QAction(QObject::tr("Uninstall"), parent); //QIcon::fromTheme("edit-delete-symbolic")
|
||||
QObject::connect(list.last(), &QAction::triggered, parent, [appId] {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#define UKUI_STYLE_SCHEMA "org.ukui.style"
|
||||
#define UKUI_STYLE_NAME_KEY "styleName"
|
||||
#define UKUI_STYLE_THEME_COLOR_KEY "themeColor"
|
||||
#define UKUI_STYLE_SYSTEM_FONT_SIZE "systemFontSize"
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
|
@ -48,12 +49,14 @@ GlobalSetting *GlobalSetting::instance()
|
|||
GlobalSetting::GlobalSetting(QObject *parent) : QObject(parent)
|
||||
{
|
||||
initStyleSetting();
|
||||
initGlobalSettings();
|
||||
}
|
||||
|
||||
void GlobalSetting::initStyleSetting()
|
||||
{
|
||||
m_cache.insert(StyleName, UKUI_STYLE_VALUE_LIGHT);
|
||||
m_cache.insert(ThemeColor, UKUI_STYLE_THEME_COLOR_KEY);
|
||||
m_cache.insert(SystemFontSize, UKUI_STYLE_SYSTEM_FONT_SIZE);
|
||||
m_cache.insert(Transparency, 1);
|
||||
m_cache.insert(EffectEnabled, false);
|
||||
|
||||
|
@ -67,7 +70,9 @@ void GlobalSetting::initStyleSetting()
|
|||
if (keys.contains(UKUI_STYLE_THEME_COLOR_KEY)) {
|
||||
m_cache.insert(ThemeColor,settings->get(UKUI_STYLE_THEME_COLOR_KEY));
|
||||
}
|
||||
|
||||
if (keys.contains(UKUI_STYLE_SYSTEM_FONT_SIZE)) {
|
||||
m_cache.insert(SystemFontSize,settings->get(UKUI_STYLE_SYSTEM_FONT_SIZE));
|
||||
}
|
||||
connect(settings, &QGSettings::changed, this, [this, settings] (const QString &key) {
|
||||
if (key == UKUI_STYLE_NAME_KEY) {
|
||||
updateData(StyleName, settings->get(key));
|
||||
|
@ -75,6 +80,9 @@ void GlobalSetting::initStyleSetting()
|
|||
} else if (key == UKUI_STYLE_THEME_COLOR_KEY) {
|
||||
updateData(ThemeColor, settings->get(key));
|
||||
Q_EMIT styleChanged(ThemeColor);
|
||||
} else if (key == UKUI_STYLE_SYSTEM_FONT_SIZE) {
|
||||
updateData(SystemFontSize, settings->get(key));
|
||||
Q_EMIT styleChanged(SystemFontSize);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -115,6 +123,47 @@ void GlobalSetting::updateData(const GlobalSetting::Key &key, const QVariant &va
|
|||
m_cache.insert(key, value);
|
||||
}
|
||||
|
||||
bool GlobalSetting::isSystemApp(const QString &appid) const
|
||||
{
|
||||
return std::any_of(m_systemApps.constBegin(), m_systemApps.constEnd(), [&appid](const QString &appName) {
|
||||
return appid.contains(appName);
|
||||
});
|
||||
}
|
||||
|
||||
QStringList GlobalSetting::systemApps() const
|
||||
{
|
||||
return m_systemApps;
|
||||
}
|
||||
|
||||
bool GlobalSetting::isDefaultFavoriteApp(const QString &appid) const
|
||||
{
|
||||
return std::any_of(m_defaultFavoriteApps.constBegin(), m_defaultFavoriteApps.constEnd(), [&appid](const QString &id) {
|
||||
return appid == id;
|
||||
});
|
||||
}
|
||||
|
||||
QStringList GlobalSetting::defaultFavoriteApps() const
|
||||
{
|
||||
return m_defaultFavoriteApps;
|
||||
}
|
||||
|
||||
void GlobalSetting::initGlobalSettings()
|
||||
{
|
||||
if (QFile::exists(UKUI_MENU_GLOBAL_CONFIG_FILE)) {
|
||||
QSettings settings(UKUI_MENU_GLOBAL_CONFIG_FILE, QSettings::IniFormat);
|
||||
settings.beginGroup("System Apps");
|
||||
m_systemApps.append(settings.allKeys());
|
||||
settings.endGroup();
|
||||
|
||||
//=
|
||||
settings.beginGroup("Default Favorite Apps");
|
||||
for (const auto &key : settings.allKeys()) {
|
||||
m_defaultFavoriteApps.append(settings.value(key).toString());
|
||||
}
|
||||
settings.endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
MenuSetting *MenuSetting::instance()
|
||||
{
|
||||
static MenuSetting setting(nullptr);
|
||||
|
|
|
@ -53,7 +53,8 @@ public:
|
|||
StyleName,
|
||||
ThemeColor,
|
||||
Transparency,
|
||||
EffectEnabled
|
||||
EffectEnabled,
|
||||
SystemFontSize
|
||||
};
|
||||
Q_ENUM(Key)
|
||||
|
||||
|
@ -64,17 +65,26 @@ public:
|
|||
|
||||
QVariant get(const GlobalSetting::Key& key);
|
||||
|
||||
bool isSystemApp(const QString &appid) const;
|
||||
QStringList systemApps() const;
|
||||
|
||||
bool isDefaultFavoriteApp(const QString &appid) const;
|
||||
QStringList defaultFavoriteApps() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void styleChanged(const GlobalSetting::Key& key);
|
||||
|
||||
private:
|
||||
explicit GlobalSetting(QObject *parent = nullptr);
|
||||
void initStyleSetting();
|
||||
void initGlobalSettings();
|
||||
void updateData(const GlobalSetting::Key& key, const QVariant &value);
|
||||
|
||||
private:
|
||||
QMutex mutex;
|
||||
QMap<GlobalSetting::Key, QVariant> m_cache;
|
||||
QStringList m_systemApps;
|
||||
QStringList m_defaultFavoriteApps;
|
||||
};
|
||||
|
||||
class MenuSetting : public QObject
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "user-config.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QMutexLocker>
|
||||
|
||||
#define PRE_INSTALLED_APPS_KEY "PreInstalledApps"
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
const QString UserConfig::configFilePath = QDir::homePath() + "/.config/ukui-menu/";
|
||||
const QString UserConfig::configFileName = "config.json";
|
||||
|
||||
UserConfig *UserConfig::instance()
|
||||
{
|
||||
static UserConfig userConfig;
|
||||
return &userConfig;
|
||||
}
|
||||
|
||||
UserConfig::UserConfig(QObject *parent) : QObject(parent)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
bool UserConfig::isFirstStartUp() const
|
||||
{
|
||||
return m_isFirstStartUp;
|
||||
}
|
||||
|
||||
void UserConfig::init()
|
||||
{
|
||||
QFile configFile(configFilePath + configFileName);
|
||||
if ((m_isFirstStartUp = !configFile.exists())) {
|
||||
if (!QDir(configFilePath).exists() && !QDir().mkdir(configFilePath)) {
|
||||
qWarning() << "Could not create the user profile directory";
|
||||
return;
|
||||
}
|
||||
|
||||
initConfigFile();
|
||||
return;
|
||||
}
|
||||
|
||||
// read
|
||||
readConfigFile();
|
||||
}
|
||||
|
||||
void UserConfig::initConfigFile()
|
||||
{
|
||||
QFile configFile(configFilePath + configFileName);
|
||||
configFile.open(QFile::WriteOnly);
|
||||
configFile.close();
|
||||
|
||||
// 已安装应用
|
||||
QStringList defaultPaths;
|
||||
defaultPaths << "/usr/share/applications/";
|
||||
defaultPaths << QDir::homePath() + "/.local/share/applications/";
|
||||
|
||||
for (const auto &path : defaultPaths) {
|
||||
QDir dir(path);
|
||||
QStringList desktopFiles = dir.entryList(QStringList() << "*.desktop", QDir::Files);
|
||||
for (const auto &desktopFile : desktopFiles) {
|
||||
m_preInstalledApps.insert(path + desktopFile);
|
||||
}
|
||||
}
|
||||
|
||||
sync();
|
||||
}
|
||||
|
||||
void UserConfig::sync()
|
||||
{
|
||||
writeConfigFile();
|
||||
}
|
||||
|
||||
QSet<QString> UserConfig::preInstalledApps() const
|
||||
{
|
||||
return m_preInstalledApps;
|
||||
}
|
||||
|
||||
void UserConfig::addPreInstalledApp(const QString &appid)
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
m_preInstalledApps.insert(appid);
|
||||
}
|
||||
|
||||
bool UserConfig::isPreInstalledApps(const QString &appid) const
|
||||
{
|
||||
return m_preInstalledApps.contains(appid);
|
||||
}
|
||||
|
||||
void UserConfig::removePreInstalledApp(const QString &appid)
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
m_preInstalledApps.remove(appid);
|
||||
}
|
||||
|
||||
void UserConfig::readConfigFile()
|
||||
{
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_preInstalledApps.clear();
|
||||
}
|
||||
|
||||
QFile file(configFilePath + configFileName);
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray byteArray = file.readAll();
|
||||
file.close();
|
||||
|
||||
QJsonDocument jsonDocument(QJsonDocument::fromJson(byteArray));
|
||||
if (jsonDocument.isNull() || jsonDocument.isEmpty() || !jsonDocument.isArray()) {
|
||||
qWarning() << "UserConfig: Incorrect configuration files are ignored.";
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonArray jsonArray = jsonDocument.array();
|
||||
for (const auto &value : jsonArray) {
|
||||
QJsonObject object = value.toObject();
|
||||
// 预装app
|
||||
if (object.contains(PRE_INSTALLED_APPS_KEY)) {
|
||||
QJsonArray apps = object.value(QLatin1String(PRE_INSTALLED_APPS_KEY)).toArray();
|
||||
for (const auto &app : apps) {
|
||||
m_preInstalledApps.insert(app.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UserConfig::writeConfigFile()
|
||||
{
|
||||
QFile file(configFilePath + configFileName);
|
||||
if (!file.open(QFile::WriteOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonDocument jsonDocument;
|
||||
QJsonArray configArray;
|
||||
|
||||
{
|
||||
// preInstalledApps
|
||||
QMutexLocker locker(&m_mutex);
|
||||
QJsonObject preInstalledAppsObject;
|
||||
|
||||
QJsonArray apps;
|
||||
for (const auto &appid : m_preInstalledApps) {
|
||||
apps.append(appid);
|
||||
}
|
||||
|
||||
preInstalledAppsObject.insert(PRE_INSTALLED_APPS_KEY, apps);
|
||||
configArray.append(preInstalledAppsObject);
|
||||
}
|
||||
|
||||
jsonDocument.setArray(configArray);
|
||||
|
||||
if (file.write(jsonDocument.toJson()) == -1) {
|
||||
qWarning() << "Error saving configuration file.";
|
||||
}
|
||||
file.flush();
|
||||
file.close();
|
||||
}
|
||||
|
||||
} // UkuiMenu
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UKUI_MENU_USER_CONFIG_H
|
||||
#define UKUI_MENU_USER_CONFIG_H
|
||||
|
||||
#include <QSet>
|
||||
#include <QVector>
|
||||
#include <QObject>
|
||||
#include <QMutex>
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
class UserConfig : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static const QString configFilePath;
|
||||
static const QString configFileName;
|
||||
|
||||
static UserConfig *instance();
|
||||
|
||||
bool isFirstStartUp() const;
|
||||
|
||||
QSet<QString> preInstalledApps() const;
|
||||
void addPreInstalledApp(const QString &appid);
|
||||
void removePreInstalledApp(const QString &appid);
|
||||
bool isPreInstalledApps(const QString &appid) const;
|
||||
|
||||
void sync();
|
||||
|
||||
private:
|
||||
explicit UserConfig(QObject *parent=nullptr);
|
||||
|
||||
void init();
|
||||
void initConfigFile();
|
||||
void readConfigFile();
|
||||
void writeConfigFile();
|
||||
|
||||
private:
|
||||
bool m_isFirstStartUp {false};
|
||||
QMutex m_mutex;
|
||||
|
||||
QSet<QString> m_preInstalledApps;
|
||||
};
|
||||
|
||||
} // UkuiMenu
|
||||
|
||||
#endif //UKUI_MENU_USER_CONFIG_H
|
|
@ -188,7 +188,9 @@ void ThemePalette::initStyleSetting()
|
|||
{
|
||||
GlobalSetting *setting = GlobalSetting::instance();
|
||||
m_transparency = setting->get(GlobalSetting::Transparency).toReal();
|
||||
m_fontSize = setting->get(GlobalSetting::SystemFontSize).toReal();
|
||||
connect(setting, &GlobalSetting::styleChanged, this, &ThemePalette::styleChangedSlot);
|
||||
connect(setting, &GlobalSetting::styleChanged, this, &ThemePalette::systemFontSizeChangedSlot);
|
||||
}
|
||||
|
||||
void ThemePalette::styleChangedSlot(const GlobalSetting::Key& key)
|
||||
|
@ -199,3 +201,17 @@ void ThemePalette::styleChangedSlot(const GlobalSetting::Key& key)
|
|||
|
||||
Q_EMIT styleColorChanged();
|
||||
}
|
||||
|
||||
void ThemePalette::systemFontSizeChangedSlot(const GlobalSetting::Key &key)
|
||||
{
|
||||
if (key & GlobalSetting::SystemFontSize) {
|
||||
m_fontSize = GlobalSetting::instance()->get(GlobalSetting::SystemFontSize).toReal();
|
||||
}
|
||||
|
||||
Q_EMIT systemFontSizeChanged();
|
||||
}
|
||||
|
||||
qreal ThemePalette::systemFontSize() const
|
||||
{
|
||||
return m_fontSize;
|
||||
}
|
||||
|
|
|
@ -92,11 +92,15 @@ public:
|
|||
Q_INVOKABLE QColor highlightedText(Palette::ColorGroup colorGroup = Palette::Active) const;
|
||||
Q_INVOKABLE QColor separator(Palette::ColorGroup colorGroup = Palette::Active) const;
|
||||
|
||||
Q_INVOKABLE qreal systemFontSize() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void styleColorChanged();
|
||||
void systemFontSizeChanged();
|
||||
|
||||
private Q_SLOTS:
|
||||
void styleChangedSlot(const GlobalSetting::Key& key);
|
||||
void systemFontSizeChangedSlot(const GlobalSetting::Key& key);
|
||||
|
||||
private:
|
||||
explicit ThemePalette(QObject *parent = nullptr);
|
||||
|
@ -105,6 +109,7 @@ private:
|
|||
|
||||
private:
|
||||
qreal m_transparency = 1.0;
|
||||
qreal m_fontSize = 12;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@ AppManager::AppManager(QObject *parent) : QObject(parent)
|
|||
bool AppManager::launchApp(const QString &desktopFilePath)
|
||||
{
|
||||
Q_EMIT request(UkuiMenuApplication::Hide);
|
||||
AppDataManager::instance()->appLaunch(desktopFilePath);
|
||||
|
||||
if (launchAppWithDBus(desktopFilePath)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -78,11 +80,6 @@ bool AppManager::launchBinaryApp(const QString &app, const QString &args)
|
|||
return QProcess::startDetached(cmd);
|
||||
}
|
||||
|
||||
void AppManager::appLaunched(const QString &desktopFilePath)
|
||||
{
|
||||
AppDataManager::instance()->appLaunch(desktopFilePath);
|
||||
}
|
||||
|
||||
bool AppManager::launchAppWithDBus(const QString &app)
|
||||
{
|
||||
if (!m_appManagerDbusInterface) {
|
||||
|
|
|
@ -35,7 +35,6 @@ public:
|
|||
|
||||
Q_INVOKABLE bool launchApp(const QString &desktopFilePath);
|
||||
Q_INVOKABLE bool launchBinaryApp(const QString &app, const QString &args = QString());
|
||||
Q_INVOKABLE void appLaunched(const QString &desktopFilePath);
|
||||
|
||||
private:
|
||||
explicit AppManager(QObject *parent = nullptr);
|
||||
|
|
|
@ -196,24 +196,42 @@ AppPageHeaderUtils::AppPageHeaderUtils(QObject *parent) : QObject(parent)
|
|||
|
||||
void AppPageHeaderUtils::onPluginChanged(const QString &id, PluginGroup::Group group)
|
||||
{
|
||||
m_models.value(group)->updateCurrentPId(id);
|
||||
ProviderModel *model = m_models.value(group);
|
||||
if (model) {
|
||||
model->updateCurrentPId(id);
|
||||
Q_EMIT pluginChanged(id);
|
||||
}
|
||||
}
|
||||
|
||||
ProviderModel *AppPageHeaderUtils::model(PluginGroup::Group group)
|
||||
ProviderModel *AppPageHeaderUtils::model(PluginGroup::Group group) const
|
||||
{
|
||||
return m_models.value(group);
|
||||
}
|
||||
|
||||
void AppPageHeaderUtils::activateProvider(const QString &name)
|
||||
void AppPageHeaderUtils::activateProvider(const QString &name) const
|
||||
{
|
||||
DataProviderManager::instance()->activateProvider(name);
|
||||
}
|
||||
|
||||
void AppPageHeaderUtils::startSearch(QString key)
|
||||
void AppPageHeaderUtils::startSearch(QString key) const
|
||||
{
|
||||
DataProviderManager::instance()->forceUpdate(key);
|
||||
}
|
||||
|
||||
QString AppPageHeaderUtils::getPluginTitle(QString id) const
|
||||
{
|
||||
if (id.isEmpty()) {
|
||||
id = DataProviderManager::instance()->activatedProvider();
|
||||
}
|
||||
|
||||
return DataProviderManager::instance()->providerInfo(id).title;
|
||||
}
|
||||
|
||||
QString AppPageHeaderUtils::currentPluginId() const
|
||||
{
|
||||
return DataProviderManager::instance()->activatedProvider();
|
||||
}
|
||||
|
||||
} // UkuiMenu
|
||||
|
||||
#include "app-page-header-utils.moc"
|
||||
|
|
|
@ -35,11 +35,16 @@ public:
|
|||
explicit AppPageHeaderUtils(QObject *parent = nullptr);
|
||||
|
||||
// 激活某插件
|
||||
Q_INVOKABLE void activateProvider(const QString &name);
|
||||
Q_INVOKABLE void activateProvider(const QString &name) const;
|
||||
// 获取不同的model
|
||||
Q_INVOKABLE ProviderModel *model(PluginGroup::Group group);
|
||||
Q_INVOKABLE ProviderModel *model(PluginGroup::Group group) const;
|
||||
|
||||
Q_INVOKABLE void startSearch(QString key);
|
||||
Q_INVOKABLE void startSearch(QString key) const;
|
||||
Q_INVOKABLE QString getPluginTitle(QString id) const;
|
||||
Q_INVOKABLE QString currentPluginId() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void pluginChanged(const QString &id);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPluginChanged(const QString &id, PluginGroup::Group group);
|
||||
|
|
|
@ -88,6 +88,10 @@
|
|||
<source>All</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>All applications</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>UkuiMenu::AppCategoryPlugin</name>
|
||||
|
|
|
@ -96,11 +96,17 @@
|
|||
<source>All</source>
|
||||
<translation>所有应用</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>All applications</source>
|
||||
<translatorcomment>所有应用</translatorcomment>
|
||||
<translation>所有应用</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>UkuiMenu::AppCategoryPlugin</name>
|
||||
<message>
|
||||
<source>Category</source>
|
||||
<translatorcomment>功能排序</translatorcomment>
|
||||
<translation>功能排序</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
Loading…
Reference in New Issue