diff --git a/CMakeLists.txt b/CMakeLists.txt index 47c7421..af1ef4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,80 +1,80 @@ cmake_minimum_required(VERSION 3.0) project(plasma-sdk) set(PROJECT_VERSION "5.18.80") set(PROJECT_VERSION_MAJOR 5) set(QT_MIN_VERSION "5.12.0") set(KF5_MIN_VERSION "5.66.0") ################# Disallow in-source build ################# if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") message(FATAL_ERROR "plasmate requires an out of source build. Please create a separate build directory and run 'cmake path_to_plasmate [options]' there.") endif() ################# set KDE specific information ################# find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE) # where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH}) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings NO_POLICY_SCOPE) include(KDEClangFormat) include(FeatureSummary) find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Core DBus Gui Qml Quick Svg Widgets Xml) find_package(Qt5Test ${QT_MIN_VERSION} CONFIG QUIET) set_package_properties(Qt5Test PROPERTIES PURPOSE "Required for tests" TYPE OPTIONAL ) add_feature_info("Qt5Test" Qt5Test_FOUND "Required for building tests") if (NOT Qt5Test_FOUND) set(BUILD_TESTING OFF CACHE BOOL "Build the testing tree.") endif() find_package(KF5Kirigami2 ${KF5_MIN_VERSION}) set_package_properties(KF5Kirigami2 PROPERTIES DESCRIPTION "KDE's lightweight user interface framework for mobile and convergent applications" URL "https://techbase.kde.org/Kirigami" PURPOSE "Required by lookandfeelexplorer" TYPE RUNTIME ) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Archive Completion Config ConfigWidgets CoreAddons DBusAddons Declarative I18n IconThemes - KIO Plasma PlasmaQuick Service TextEditor WidgetsAddons DocTools) + KIO Plasma PlasmaQuick Service TextEditor WidgetsAddons DocTools ConfigWidgets) ######################################################################### if (EXISTS "${CMAKE_SOURCE_DIR}/.git") add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x060000) endif() add_definitions( -DQT_DEPRECATED_WARNINGS -DQT_USE_QSTRINGBUILDER -DQT_NO_CAST_TO_ASCII # -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_FROM_BYTEARRAY -DQT_STRICT_ITERATORS -DQT_NO_URL_CAST_FROM_STRING -DQT_NO_SIGNALS_SLOTS_KEYWORDS ) add_subdirectory(cuttlefish) add_subdirectory(engineexplorer) add_subdirectory(plasmoidviewer) add_subdirectory(themeexplorer) add_subdirectory(lookandfeelexplorer) #add_subdirectory(wallpaperviewer) # add clang-format target for all our real source files file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h) kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES}) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/cuttlefish/autotests/CMakeLists.txt b/cuttlefish/autotests/CMakeLists.txt index 04af868..b809e46 100644 --- a/cuttlefish/autotests/CMakeLists.txt +++ b/cuttlefish/autotests/CMakeLists.txt @@ -1,18 +1,19 @@ include(ECMAddTests) find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED Test) include_directories(../src) ecm_add_test(iconmodeltest.cpp ../src/iconmodel.cpp TEST_NAME iconmodeltest LINK_LIBRARIES Qt5::Gui Qt5::Test KF5::ConfigCore KF5::IconThemes KF5::Package KF5::Service KF5::Plasma + KF5::ConfigWidgets ) diff --git a/cuttlefish/package/contents/ui/Comparison.qml b/cuttlefish/package/contents/ui/Comparison.qml index 1f68ec1..d0ec86a 100644 --- a/cuttlefish/package/contents/ui/Comparison.qml +++ b/cuttlefish/package/contents/ui/Comparison.qml @@ -1,88 +1,83 @@ import QtQuick 2.4 import QtQuick.Controls 2.5 as QQC2 import QtQuick.Layouts 1.3 import org.kde.kirigami 2.8 as Kirigami Kirigami.OverlaySheet { property int comparisonSize background: Rectangle { id:background - color: cuttlefish.viewbgcolor + Kirigami.Theme.colorSet: Kirigami.Theme.View + color: Kirigami.Theme.backgroundColor anchors.fill: parent } onSheetOpenChanged: { if (sheetOpen) { comparisonSize = iconSize; comparisonSlider.value = [8, 16, 22, 32, 48, 64, 128].indexOf(comparisonSize); } } ColumnLayout { - Kirigami.Theme.textColor: cuttlefish.textcolor - Kirigami.Theme.highlightColor: cuttlefish.highlightcolor - Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor - Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor - Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor - Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor RowLayout { Layout.alignment: Qt.AlignHCenter QQC2.Slider { Layout.preferredWidth: comparisonGrid.width * 0.75 id: comparisonSlider to: 6.0 stepSize: 1.0 snapMode: QQC2.Slider.SnapAlways onValueChanged: { comparisonTimer.restart() } Timer { id: comparisonTimer running: false repeat: false interval: 200 onTriggered: comparisonSize = indexToSize(comparisonSlider.value) } } QQC2.Label { text: indexToSize(comparisonSlider.value) } } GridView { Layout.fillWidth: true Layout.preferredHeight: contentHeight id: comparisonGrid cellWidth: 128 cellHeight: 128 + 2 * Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing model: sheetOpen ? iconModel.inOtherThemes(preview.iconName, comparisonSize) : [] delegate: ColumnLayout { id: iconColumn width: comparisonGrid.cellWidth height: comparisonGrid.cellHeight spacing: Kirigami.Units.largeSpacing Item { id: wrapper Layout.preferredWidth: 128 Layout.preferredHeight: 128 Kirigami.Icon { property bool hasIcon : modelData.iconPath anchors.centerIn: parent width: comparisonSize height: width source: hasIcon ? modelData.iconPath : "paint-none" color: hasIcon ? "" : Kirigami.Theme.disabledTextColor isMask: !hasIcon } } QQC2.Label { id: themeName text: modelData.themeName horizontalAlignment: Text.AlignHCenter Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom } } } } } diff --git a/cuttlefish/package/contents/ui/IconGridDelegate.qml b/cuttlefish/package/contents/ui/IconGridDelegate.qml index 9e068e2..3598fec 100644 --- a/cuttlefish/package/contents/ui/IconGridDelegate.qml +++ b/cuttlefish/package/contents/ui/IconGridDelegate.qml @@ -1,118 +1,97 @@ /*************************************************************************** * * * Copyright 2014-2017 Sebastian Kügler * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ import QtQuick 2.5 import QtQuick.Controls 2.5 as QQC2 import QtQuick.Layouts 1.0 import org.kde.kirigami 2.8 as Kirigami MouseArea { id: delegateRoot width: iconSize + Kirigami.Units.gridUnit height: cellWidth + Math.round(Kirigami.Units.gridUnit * 2) acceptedButtons: Qt.LeftButton | Qt.RightButton function setAsPreview() { preview.fullPath = fullPath preview.iconName = iconName preview.fileName = fileName preview.category = category preview.type = type preview.iconTheme = iconTheme preview.sizes = sizes preview.scalable = scalable; } Rectangle { color: Kirigami.Theme.highlightColor opacity: iconGrid.currentIndex == index ? 0.5 : 0.0 visible: opacity != 0.0 Behavior on opacity { NumberAnimation { duration: units.shortDuration } } anchors { fill: parent } - Kirigami.Theme.textColor: cuttlefish.textcolor - Kirigami.Theme.backgroundColor: cuttlefish.bgcolor - Kirigami.Theme.highlightColor: cuttlefish.highlightcolor - Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor - Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor - Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor - Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor } Kirigami.Icon { - Kirigami.Theme.textColor: cuttlefish.textcolor - Kirigami.Theme.backgroundColor: cuttlefish.bgcolor - Kirigami.Theme.highlightColor: cuttlefish.highlightcolor - Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor - Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor - Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor - Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor id: delegateIcon width: iconSize height: width source: iconName anchors { top: parent.top horizontalCenter: parent.horizontalCenter } } QQC2.Label { - Kirigami.Theme.textColor: cuttlefish.textcolor - Kirigami.Theme.backgroundColor: cuttlefish.bgcolor - Kirigami.Theme.highlightColor: cuttlefish.highlightcolor - Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor - Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor - Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor - Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor font.pointSize: iconSize > 96 ? theme.defaultFont.pointSize : theme.smallestFont.pointSize text: iconName wrapMode: Text.Wrap maximumLineCount: 3 horizontalAlignment: Text.AlignHCenter opacity: iconGrid.currentIndex == index ? 1.0 : 0.7 anchors { left: parent.left right: parent.right top: delegateIcon.bottom topMargin: 0 margins: Math.round(-units.gridUnit / 4) } } Connections { target: iconGrid onCurrentIndexChanged: { if (delegateRoot.GridView.isCurrentItem) { delegateRoot.setAsPreview(); } } } onClicked: (mouse) => { iconGrid.currentIndex = index; iconGrid.forceActiveFocus(); if (mouse.button == Qt.RightButton) { cuttlefish.itemRightClicked() } } } diff --git a/cuttlefish/package/contents/ui/Preview.qml b/cuttlefish/package/contents/ui/Preview.qml index eef86d6..deeec4a 100644 --- a/cuttlefish/package/contents/ui/Preview.qml +++ b/cuttlefish/package/contents/ui/Preview.qml @@ -1,261 +1,246 @@ /*************************************************************************** * * * Copyright 2014-2017 Sebastian Kügler * * Copyrihgt 2019 Carson Black * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ import QtQuick 2.2 import QtQuick.Controls 2.5 as QQC2 import QtQuick.Layouts 1.0 import QtQuick.Dialogs 1.3 import org.kde.kirigami 2.8 as Kirigami Rectangle { property alias iconPreview: iconPreview property alias dualMont: dualMont - Kirigami.Theme.textColor: cuttlefish.textcolor - Kirigami.Theme.backgroundColor: cuttlefish.bgcolor - Kirigami.Theme.highlightColor: cuttlefish.highlightcolor - Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor - Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor - Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor - Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor - color: Kirigami.Theme.backgroundColor FileDialog { id: ssPicker selectExisting: false selectMultiple: false selectFolder: false onAccepted: { iconPreview.grabToImage(function(result) { ssPicker.resetColors() res = result.saveToFile(ssPicker.fileUrl.toString().slice(7)) }); } onRejected: { ssPicker.resetColors() } function resetColors() { iconPreview.screenshotting = false iconPreview.Kirigami.Theme.textColor = Kirigami.Theme.textColor iconPreview.Kirigami.Theme.backgroundColor = Kirigami.Theme.backgroundColor iconPreview.Kirigami.Theme.highlightColor = Kirigami.Theme.highlightColor iconPreview.Kirigami.Theme.highlightedTextColor = Kirigami.Theme.highlightedTextColor iconPreview.Kirigami.Theme.positiveTextColor = Kirigami.Theme.positiveTextColor iconPreview.Kirigami.Theme.neutralTextColor = Kirigami.Theme.neutralTextColor iconPreview.Kirigami.Theme.negativeTextColor = Kirigami.Theme.negativeTextColor iconPreview.Kirigami.Theme.inherit = true } nameFilters: [ "PNG screenshot files (*.png)" ] } ColumnLayout { anchors.fill: parent spacing: Kirigami.Units.largeSpacing Kirigami.Heading { level: 1 Layout.fillWidth: true wrapMode: Text.Wrap horizontalAlignment: Text.AlignHCenter elide: Text.ElideRight text: preview.iconName } Kirigami.FormLayout { Layout.fillWidth: true Layout.topMargin: Kirigami.Units.largeSpacing QQC2.Label { Layout.maximumWidth: Kirigami.Units.gridUnit * 15 Kirigami.FormData.label: i18n("File name:") elide: Text.ElideRight text: preview.fileName } QQC2.Label { Kirigami.FormData.label: i18n("Category:") font.capitalization: Font.Capitalize text: preview.category } QQC2.Label { Kirigami.FormData.label: i18n("Scalable:") text: preview.scalable ? i18n("yes") : i18n("no") font.capitalization: Font.Capitalize } } Rectangle { id: iconPreview - Kirigami.Theme.textColor: cuttlefish.textcolor - Kirigami.Theme.backgroundColor: cuttlefish.bgcolor - Kirigami.Theme.highlightColor: cuttlefish.highlightcolor - Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor - Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor - Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor - Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor property bool screenshotting: false color: Kirigami.Theme.backgroundColor Behavior on color { ColorAnimation { duration: Kirigami.Units.longDuration } } Behavior on Layout.preferredHeight { NumberAnimation { duration: Kirigami.Units.longDuration } } Layout.fillWidth: true Layout.preferredHeight: screenshotting ? previewGrid.height + (Kirigami.Units.gridUnit * 4) : previewGrid.height Layout.topMargin: Kirigami.Units.largeSpacing Layout.bottomMargin: Kirigami.Units.largeSpacing * 4 ColumnLayout { id: previewGrid anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter property var sizes: [8, 16, 22, 32, 48, 64] property var largeSizes: [128] GridLayout { Layout.alignment: Qt.AlignHCenter rows: 2 columns: previewGrid.sizes.length Repeater { model: previewGrid.sizes.length delegate: Kirigami.Icon { Layout.alignment: Qt.AlignBottom source: preview.iconName width: previewGrid.sizes[index] height: previewGrid.sizes[index] } } Repeater { model: previewGrid.sizes.length delegate: QQC2.Label { Layout.alignment: Qt.AlignTop | Qt.AlignHCenter text: previewGrid.sizes[index] Behavior on color { ColorAnimation { duration: Kirigami.Units.longDuration } } } } } GridLayout { Layout.alignment: Qt.AlignHCenter rows: 2 columns: previewGrid.largeSizes.length Repeater { model: previewGrid.largeSizes.length delegate: Kirigami.Icon { Layout.alignment: Qt.AlignBottom source: preview.iconName width: previewGrid.largeSizes[index] height: previewGrid.largeSizes[index] } } Repeater { model: previewGrid.largeSizes.length delegate: QQC2.Label { Layout.alignment: Qt.AlignTop | Qt.AlignHCenter text: previewGrid.largeSizes[index] Behavior on color { ColorAnimation { duration: Kirigami.Units.longDuration } } } } } } Row { opacity: iconPreview.screenshotting ? 1 : 0 anchors.top: parent.top anchors.left: parent.left anchors.margins: Kirigami.Units.smallSpacing Kirigami.Icon { height: 32 width: 32 source: "cuttlefish" } QQC2.Label { anchors.verticalCenter: parent.verticalCenter text: "Montage made with Cuttlefish" } Behavior on opacity { OpacityAnimator { duration: Kirigami.Units.longDuration } } } function shot(type) { iconPreview.screenshotting = true if (type == "normal") { iconPreview.Kirigami.Theme.inherit = false iconPreview.Kirigami.Theme.textColor = "#232629" iconPreview.Kirigami.Theme.backgroundColor = "#eff0f1" iconPreview.Kirigami.Theme.highlightColor = "#3daee9" iconPreview.Kirigami.Theme.highlightedTextColor = "#eff0f1" iconPreview.Kirigami.Theme.positiveTextColor = "#27ae60" iconPreview.Kirigami.Theme.neutralTextColor = "#f67400" iconPreview.Kirigami.Theme.negativeTextColor = "#da4453" } else if (type == "dark") { iconPreview.Kirigami.Theme.inherit = false iconPreview.Kirigami.Theme.textColor = "#eff0f1" iconPreview.Kirigami.Theme.backgroundColor = "#31363b" iconPreview.Kirigami.Theme.highlightColor = "#3daee9" iconPreview.Kirigami.Theme.highlightedTextColor = "#eff0f1" iconPreview.Kirigami.Theme.positiveTextColor = "#27ae60" iconPreview.Kirigami.Theme.neutralTextColor = "#f67400" iconPreview.Kirigami.Theme.negativeTextColor = "#da4453" } else if (type == "active") { iconPreview.Kirigami.Theme.inherit = true } ssPicker.open() } } Repeater { model: cuttlefish.actions delegate: QQC2.Button { Layout.alignment: Qt.AlignHCenter action: modelData } } Item { Layout.fillHeight: true } DualMontage { id: dualMont } } Kirigami.Separator { width: 1 anchors { left: parent.left bottom: parent.bottom top: parent.top } } } diff --git a/cuttlefish/package/contents/ui/ResponsivePreview.qml b/cuttlefish/package/contents/ui/ResponsivePreview.qml index 360d205..4e61679 100644 --- a/cuttlefish/package/contents/ui/ResponsivePreview.qml +++ b/cuttlefish/package/contents/ui/ResponsivePreview.qml @@ -1,101 +1,93 @@ /*************************************************************************** * * * Copyright 2019 Carson Black * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ import QtQuick 2.5 import QtQuick.Controls 2.5 as QQC2 import QtQuick.Layouts 1.0 import org.kde.kirigami 2.8 as Kirigami Kirigami.GlobalDrawer { id: root edge: Qt.RightEdge handleOpenIcon.source: "dialog-close" handleClosedIcon.source: "view-preview" - Kirigami.Theme.textColor: cuttlefish.textcolor - Kirigami.Theme.backgroundColor: cuttlefish.bgcolor - Kirigami.Theme.highlightColor: cuttlefish.highlightcolor - Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor - Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor - Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor - Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor - focus: false actions: cuttlefish.actions Kirigami.Heading { level: 1 Layout.fillWidth: true wrapMode: Text.Wrap horizontalAlignment: Text.AlignHCenter elide: Text.ElideRight text: preview.iconName } Kirigami.FormLayout { Layout.fillWidth: true Layout.topMargin: Kirigami.Units.largeSpacing QQC2.Label { Layout.maximumWidth: Kirigami.Units.gridUnit * 10 Kirigami.FormData.label: i18n("File name:") elide: Text.ElideRight text: preview.fileName } QQC2.Label { Kirigami.FormData.label: i18n("Category:") font.capitalization: Font.Capitalize text: preview.category } QQC2.Label { Kirigami.FormData.label: i18n("Scalable:") text: preview.scalable ? i18n("yes") : i18n("no") font.capitalization: Font.Capitalize } } GridLayout { id: grid columns: 2 property var sizes: [8, 16, 22, 32, 48, 64] Layout.alignment: Qt.AlignHCenter Repeater { model: parent.sizes.length delegate: ColumnLayout { Kirigami.Icon { Layout.alignment: Qt.AlignBottom source: preview.iconName width: grid.sizes[index] height: grid.sizes[index] } QQC2.Label { Layout.alignment: Qt.AlignTop | Qt.AlignHCenter text: grid.sizes[index] Behavior on color { ColorAnimation { duration: Kirigami.Units.longDuration } } } } } } } diff --git a/cuttlefish/package/contents/ui/SvgGrid.qml b/cuttlefish/package/contents/ui/SvgGrid.qml index 8dfae62..eadb834 100644 --- a/cuttlefish/package/contents/ui/SvgGrid.qml +++ b/cuttlefish/package/contents/ui/SvgGrid.qml @@ -1,135 +1,114 @@ /*************************************************************************** * * * Copyright 2014-2015 Sebastian Kügler * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ import QtQuick 2.2 import QtQuick.Controls 2.5 as QQC2 import QtQuick.Layouts 1.0 import org.kde.kirigami 2.8 as Kirigami GridView { id: iconGrid focus: true cellWidth: iconSize + units.gridUnit cellHeight: cellWidth + units.gridUnit cacheBuffer: 10000 highlightMoveDuration: 0 model: iconModel.svgIcons highlight: Rectangle { color: theme.highlightColor //height: parent.height + units.gridUnit * 3 anchors.bottomMargin: -units.gridUnit * 2 } delegate: MouseArea { id: delegateRoot width: iconSize height: iconSize + units.gridUnit hoverEnabled: hoveredHighlight function setAsPreview() { print("preview() " + modelData.iconName + " " + modelData.fileName); preview.iconName = modelData.iconName } Rectangle { - Kirigami.Theme.textColor: cuttlefish.textcolor - Kirigami.Theme.backgroundColor: cuttlefish.bgcolor - Kirigami.Theme.highlightColor: cuttlefish.highlightcolor - Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor - Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor - Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor - Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor color: theme.highlightColor opacity: iconGrid.currentIndex == index ? 1.0 : 0 Behavior on opacity { NumberAnimation { duration: units.shortDuration } } anchors { bottomMargin: -units.gridUnit leftMargin: -units.gridUnit / 2 rightMargin: -units.gridUnit / 2 fill: parent } } Kirigami.Icon { - Kirigami.Theme.textColor: cuttlefish.textcolor - Kirigami.Theme.backgroundColor: cuttlefish.bgcolor - Kirigami.Theme.highlightColor: cuttlefish.highlightcolor - Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor - Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor - Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor - Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor id: delegateIcon width: iconSize height: width source: modelData.iconName anchors { top: parent.top horizontalCenter: parent.horizontalCenter } } QQC2.Label { - Kirigami.Theme.textColor: cuttlefish.textcolor - Kirigami.Theme.backgroundColor: cuttlefish.bgcolor - Kirigami.Theme.highlightColor: cuttlefish.highlightcolor - Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor - Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor - Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor - Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor font.pointSize: iconSize > 96 ? theme.defaultFont.pointSize : theme.smallestFont.pointSize text: modelData.fileName + " " + modelData.iconName wrapMode: QQC2.Text.Wrap maximumLineCount: 3 horizontalAlignment: QQC2.Text.AlignHCenter opacity: iconGrid.currentIndex == index ? 1.0 : 0.7 anchors { left: parent.left right: parent.right top: delegateIcon.bottom margins: Math.round(-units.gridUnit / 4) } } Connections { target: iconGrid onCurrentIndexChanged: { if (delegateRoot.GridView.isCurrentItem) { print("index changed" + modelData.iconName + " " + modelData.fileName) delegateRoot.setAsPreview(); } } } onClicked: { iconGrid.currentIndex = index; iconGrid.forceActiveFocus(); } onEntered: { setAsPreview(); } } } diff --git a/cuttlefish/package/contents/ui/Tools.qml b/cuttlefish/package/contents/ui/Tools.qml index 25ed408..691b8f4 100644 --- a/cuttlefish/package/contents/ui/Tools.qml +++ b/cuttlefish/package/contents/ui/Tools.qml @@ -1,151 +1,159 @@ /*************************************************************************** * * * Copyright 2014-2017 Sebastian Kügler * * Copyrihgt 2019 Carson Black * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ import QtQuick 2.5 import QtQuick.Controls 2.5 as QQC2 import QtQuick.Layouts 1.0 import org.kde.kirigami 2.8 as Kirigami +import org.kde.kquickcontrolsaddons 2.0 as KQCAddons Rectangle { id: root width: parent.width color: Kirigami.Theme.backgroundColor signal colorschemeChanged(int index) signal sliderValueChanged(int val) property alias slider: sizeslider property alias currentIndex: colorcombo.currentIndex property alias value: sizeslider.value - Kirigami.Theme.textColor: cuttlefish.textcolor - Kirigami.Theme.backgroundColor: cuttlefish.bgcolor - Kirigami.Theme.highlightColor: cuttlefish.highlightcolor - Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor - Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor - Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor - Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor - RowLayout { anchors.fill: parent anchors.leftMargin: Kirigami.Units.smallSpacing anchors.rightMargin: Kirigami.Units.smallSpacing anchors.verticalCenter: parent.verticalCenter spacing: Kirigami.Units.largeSpacing Kirigami.SearchField { id: filterInput Layout.fillWidth: true onTextChanged: typingtimer.restart() focus: true Timer { id: typingtimer running: false repeat: false interval: 100 onTriggered: { iconModel.filter = filterInput.text } } Component.onCompleted: { filterInput.forceActiveFocus() } } QQC2.ComboBox { id: catsCombo Layout.preferredWidth: units.gridUnit * 6 model: iconModel.categories onActivated: { if (currentText == "all") { iconModel.category = ""; } else if (currentText != "") { iconModel.category = currentText } iconModel.sort() } popup.modal: false } QQC2.Slider { visible: cuttlefish.widescreen id: sizeslider Layout.preferredWidth: preview.width - units.gridUnit * 2 to: 6.0 stepSize: 1.0 snapMode: QQC2.Slider.SnapAlways value: 4.0 onValueChanged: { sizetimer.restart() pixelSizeInput.text = indexToSize(sizeslider.value) root.sliderValueChanged(sizeslider.value) } Timer { id: sizetimer running: false repeat: false interval: 200 onTriggered: iconSize = indexToSize(sizeslider.value) } Component.onCompleted: { pixelSizeInput.text = indexToSize(sizeslider.value); } } QQC2.Label { visible: cuttlefish.widescreen id: pixelSizeInput Layout.preferredWidth: units.gridUnit * 3 } QQC2.Label { visible: cuttlefish.widescreen text: i18n("Color scheme:") } QQC2.ComboBox { id: colorcombo visible: cuttlefish.widescreen - model: ["System Color Scheme", "Breeze (Normal)", "Breeze Dark"] + model: colorSchemes.colorSchemes delegate: QQC2.ItemDelegate { - text: i18n(modelData) + Kirigami.Theme.colorSet: Kirigami.Theme.View width: parent.width + highlighted: colorcombo.highlightedIndex == index + contentItem: RowLayout { + Kirigami.Icon { + source: model.decoration + Layout.preferredHeight: Kirigami.Units.iconSizes.small + Layout.preferredWidth: Kirigami.Units.iconSizes.small + } + QQC2.Label { + text: model.display + color: highlighted ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor + Layout.fillWidth: true + } + } } + textRole: "display" onActivated: (index) => { root.colorschemeChanged(index) + colorSchemes.activateColorScheme(currentText) } popup.modal: false } } Kirigami.Separator { height: 1 anchors { left: parent.left right: parent.right bottom: parent.bottom } } } diff --git a/cuttlefish/package/contents/ui/ToolsResponsive.qml b/cuttlefish/package/contents/ui/ToolsResponsive.qml index 7307053..a5a10ba 100644 --- a/cuttlefish/package/contents/ui/ToolsResponsive.qml +++ b/cuttlefish/package/contents/ui/ToolsResponsive.qml @@ -1,113 +1,120 @@ /*************************************************************************** * * * Copyright 2019 Carson Black * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ import QtQuick 2.5 import QtQuick.Controls 2.5 as QQC2 import QtQuick.Layouts 1.0 import org.kde.kirigami 2.8 as Kirigami Rectangle { id: root width: parent.width color: Kirigami.Theme.backgroundColor - Kirigami.Theme.textColor: cuttlefish.textcolor - Kirigami.Theme.backgroundColor: cuttlefish.bgcolor - Kirigami.Theme.highlightColor: cuttlefish.highlightcolor - Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor - Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor - Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor - Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor - property alias currentIndex: colorcombo.currentIndex property alias value: sizeslider.value signal colorschemeChanged(int index) signal sliderValueChanged(int val) Kirigami.Separator { height: 1 anchors { left: parent.left right: parent.right top: parent.top } } RowLayout { anchors.fill: parent anchors.leftMargin: Kirigami.Units.smallSpacing anchors.rightMargin: Kirigami.Units.smallSpacing anchors.verticalCenter: parent.verticalCenter spacing: Kirigami.Units.largeSpacing QQC2.Slider { visible: !cuttlefish.widescreen id: sizeslider Layout.fillWidth: true to: 6.0 stepSize: 1.0 snapMode: QQC2.Slider.SnapAlways value: 4.0 onValueChanged: { sizetimer.restart() pixelSizeInput.text = indexToSize(sizeslider.value) root.sliderValueChanged(sizeslider.value) } Timer { id: sizetimer running: false repeat: false interval: 200 onTriggered: iconSize = indexToSize(sizeslider.value) } Component.onCompleted: { pixelSizeInput.text = indexToSize(sizeslider.value); } } QQC2.Label { visible: !cuttlefish.widescreen id: pixelSizeInput Layout.preferredWidth: units.gridUnit * 1 } QQC2.ComboBox { id: colorcombo visible: !cuttlefish.widescreen - model: ["System Color Scheme", "Breeze (Normal)", "Breeze Dark"] + model: colorSchemes.colorSchemes delegate: QQC2.ItemDelegate { - text: i18n(modelData) + Kirigami.Theme.colorSet: Kirigami.Theme.View width: parent.width + highlighted: colorcombo.highlightedIndex == index + contentItem: RowLayout { + Kirigami.Icon { + source: model.decoration + Layout.preferredHeight: Kirigami.Units.iconSizes.small + Layout.preferredWidth: Kirigami.Units.iconSizes.small + } + QQC2.Label { + text: model.display + color: highlighted ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor + Layout.fillWidth: true + } + } } + textRole: "display" onActivated: (index) => { root.colorschemeChanged(index) + colorSchemes.activateColorScheme(currentText) } popup.modal: false } Item { width: Kirigami.Units.largeSpacing * 3 } } -} \ No newline at end of file +} diff --git a/cuttlefish/package/contents/ui/cuttlefish.qml b/cuttlefish/package/contents/ui/cuttlefish.qml index a1ad2c5..b12073d 100644 --- a/cuttlefish/package/contents/ui/cuttlefish.qml +++ b/cuttlefish/package/contents/ui/cuttlefish.qml @@ -1,261 +1,190 @@ /*************************************************************************** * * * Copyright 2014-2015 Sebastian Kügler * * Copyrihgt 2019 Carson Black * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ import QtQuick 2.5 import QtQuick.Layouts 1.0 import QtQuick.Controls 2.5 as QQC2 import Qt.labs.settings 1.0 import org.kde.kirigami 2.4 as Kirigami Kirigami.ApplicationWindow { id: cuttlefish objectName: "cuttlefish" signal itemRightClicked() minimumWidth: 400 minimumHeight: 400 property bool widescreen: cuttlefish.width >= 800 property int iconSize: Kirigami.Units.iconSizes.large - property bool darkScheme: false - property bool usesPlasmaTheme: true - property var schemeStash property alias actions: actions.actions - property color textcolor: Kirigami.Theme.textColor - property color bgcolor: Kirigami.Theme.backgroundColor - property color highlightcolor: Kirigami.Theme.highlightColor - property color highlightedtextcolor: Kirigami.Theme.highlightedTextColor - property color positivetextcolor: Kirigami.Theme.positiveTextColor - property color neutraltextcolor: Kirigami.Theme.neutralTextColor - property color negativetextcolor: Kirigami.Theme.negativeTextColor - property color viewbgcolor: Kirigami.Theme.viewBackgroundColor - - Kirigami.Theme.textColor: cuttlefish.textcolor - Kirigami.Theme.backgroundColor: cuttlefish.bgcolor - Kirigami.Theme.highlightColor: cuttlefish.highlightcolor - Kirigami.Theme.highlightedTextColor: cuttlefish.highlightedtextcolor - Kirigami.Theme.positiveTextColor: cuttlefish.positivetextcolor - Kirigami.Theme.neutralTextColor: cuttlefish.neutraltextcolor - Kirigami.Theme.negativeTextColor: cuttlefish.negativetextcolor - Loader { // Use a Loader instead of creating a GMB directly, // so if the GMB errors, it doesn't affect Cuttlefish's operation id: loader source: "GlobalMenuBar.qml" } Actions { id: actions } Menu { id: menu } Settings { property alias x: cuttlefish.x property alias y: cuttlefish.y property alias width: cuttlefish.width property alias height: cuttlefish.height } Connections { target: loader.item onQuit: { cuttlefish.close() } onZoomIn: { tools.slider.value += 1 } onZoomOut: { tools.slider.value -= 1 } onMontage: { switch(type) { case 0: previewPane.iconPreview.shot("active") break; case 1: previewPane.iconPreview.shot("normal") break; case 2: previewPane.iconPreview.shot("dark") break; case 3: previewPane.dualMont.shot() break; } } } - function changeColors(index) { - switch(index) { - case 0: - cuttlefish.Kirigami.Theme.inherit = true - cuttlefish.textcolor = cuttlefish.schemeStash[0] - cuttlefish.bgcolor = cuttlefish.schemeStash[1] - cuttlefish.highlightcolor = cuttlefish.schemeStash[2] - cuttlefish.highlightedtextcolor = cuttlefish.schemeStash[3] - cuttlefish.positivetextcolor = cuttlefish.schemeStash[4] - cuttlefish.neutraltextcolor = cuttlefish.schemeStash[5] - cuttlefish.negativetextcolor = cuttlefish.schemeStash[6] - cuttlefish.viewbgcolor = cuttlefish.schemeStash[7] - break - case 1: - cuttlefish.Kirigami.Theme.inherit = false - cuttlefish.textcolor = "#232629" - cuttlefish.bgcolor = "#eff0f1" - cuttlefish.highlightcolor = "#3daee9" - cuttlefish.highlightedtextcolor = "#eff0f1" - cuttlefish.positivetextcolor = "#27ae60" - cuttlefish.neutraltextcolor = "#f67400" - cuttlefish.negativetextcolor = "#da4453" - cuttlefish.viewbgcolor = "#fcfcfc" - break - case 2: - cuttlefish.Kirigami.Theme.inherit = false - cuttlefish.textcolor = "#eff0f1" - cuttlefish.bgcolor = "#31363b" - cuttlefish.highlightcolor = "#3daee9" - cuttlefish.highlightedtextcolor = "#eff0f1" - cuttlefish.positivetextcolor = "#27ae60" - cuttlefish.neutraltextcolor = "#f67400" - cuttlefish.negativetextcolor = "#da4453" - cuttlefish.viewbgcolor = "#232629" - break - } - } function indexToSize(ix) { var sizes = new Array(); sizes[0] = 8; sizes[1] = 16; sizes[2] = 22; sizes[3] = 32; sizes[4] = 48 sizes[5] = 64; sizes[6] = 128; return sizes[ix]; } Rectangle { Kirigami.Theme.colorSet: Kirigami.Theme.View - color: tools.currentIndex != 0 ? cuttlefish.viewbgcolor : Kirigami.Theme.viewBackgroundColor + color: Kirigami.Theme.backgroundColor anchors.fill: parent } ColumnLayout { Shortcut { sequence: StandardKey.ZoomIn onActivated: tools.slider.value += 1 } Shortcut { sequence: StandardKey.ZoomOut onActivated: tools.slider.value -= 1 } anchors.fill: parent spacing: 0 Tools { id: tools Layout.fillWidth: true Layout.preferredHeight: (Kirigami.Units.gridUnit * 2) + Kirigami.Units.largeSpacing } RowLayout { QQC2.ScrollView { id: grid Layout.fillWidth: true Layout.fillHeight: true QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff IconGrid { id: iconGrid anchors.fill: parent anchors.margins: Kirigami.Units.gridUnit footer: SvgGrid { id: svgGrid interactive: false } } } Preview { visible: cuttlefish.widescreen id: previewPane Layout.preferredWidth: Kirigami.Units.gridUnit * 22 Layout.fillHeight: true } } ToolsResponsive { visible: !cuttlefish.widescreen id: toolsResponsive Layout.fillWidth: true Layout.preferredHeight: (Kirigami.Units.gridUnit * 2) + Kirigami.Units.largeSpacing } } Loader { active: !cuttlefish.widescreen source: "ResponsivePreview.qml" } Comparison { id: comparison } Connections { target: tools onColorschemeChanged: (index) => { - cuttlefish.changeColors(index) toolsResponsive.currentIndex = index } onSliderValueChanged: (val) => { toolsResponsive.value = val } } Connections { target: toolsResponsive onColorschemeChanged: (index) => { - cuttlefish.changeColors(index) tools.currentIndex = index } onSliderValueChanged: (val) => { tools.value = val } } Item { id: preview property string iconName: "plasma" property string fullPath: "" property string category: "" property string fileName: "" property string type: "" property string iconTheme: "" property variant sizes: [] property bool scalable: true } - - Component.onCompleted: { - cuttlefish.schemeStash += Kirigami.Theme.textColor - cuttlefish.schemeStash += Kirigami.Theme.backgroundColor - cuttlefish.schemeStash += Kirigami.Theme.highlightColor - cuttlefish.schemeStash += Kirigami.Theme.highlightedTextColor - cuttlefish.schemeStash += Kirigami.Theme.positiveTextColor - cuttlefish.schemeStash += Kirigami.Theme.neutralTextColor - cuttlefish.schemeStash += Kirigami.Theme.negativeTextColor - cuttlefish.schemeStash += Kirigami.Theme.viewBackgroundColor - console.log(cuttlefish.schemeStash) - } } diff --git a/cuttlefish/src/CMakeLists.txt b/cuttlefish/src/CMakeLists.txt index 00d75eb..b49dc87 100644 --- a/cuttlefish/src/CMakeLists.txt +++ b/cuttlefish/src/CMakeLists.txt @@ -1,25 +1,27 @@ set(cuttlefish_SRCS main.cpp iconmodel.cpp + colorschemes.cpp ) add_executable(cuttlefish ${cuttlefish_SRCS}) target_compile_definitions(cuttlefish PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}") target_link_libraries(cuttlefish Qt5::Quick Qt5::Gui Qt5::Widgets # for QDirModel KF5::Plasma KF5::KIOWidgets KF5::Declarative + KF5::ConfigWidgets KF5::I18n KF5::IconThemes KF5::Package Qt5::DBus ) install(TARGETS cuttlefish ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) add_subdirectory(editorplugin) diff --git a/cuttlefish/src/colorschemes.cpp b/cuttlefish/src/colorschemes.cpp new file mode 100644 index 0000000..8d9a03d --- /dev/null +++ b/cuttlefish/src/colorschemes.cpp @@ -0,0 +1,49 @@ +/*************************************************************************** + * * + * Copyright 2019 David Redondo * + * * + * 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 2 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + * * + ***************************************************************************/ + +#include "colorschemes.h" + +#include + +#include +#include +#include +#include + +using namespace CuttleFish; + +ColorSchemes::ColorSchemes(QObject *parent) + : QObject(parent) + , m_colorManager(new KColorSchemeManager(this)) +{ + QAbstractItemModel *model = m_colorManager->model(); +} + +QAbstractItemModel* CuttleFish::ColorSchemes::colorSchemes() +{ + return m_colorManager->model(); +} + +void ColorSchemes::activateColorScheme(const QString& name) +{ + m_colorManager->activateScheme(m_colorManager->indexForScheme(name)); +} + diff --git a/cuttlefish/src/colorschemes.h b/cuttlefish/src/colorschemes.h new file mode 100644 index 0000000..18a6975 --- /dev/null +++ b/cuttlefish/src/colorschemes.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * * + * Copyright 2019 David Redondo * + * * + * 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 2 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + * * + ***************************************************************************/ + +#ifndef CUTTLEFISHCOLORSCHEMES_H +#define CUTTLEFISHCOLORSCHEMES_H + +#include +#include + +class QAbstractItemModel; + +class KColorSchemeManager; + +namespace CuttleFish { +class ColorSchemes : public QObject { + + Q_OBJECT + + Q_PROPERTY(QAbstractItemModel *colorSchemes READ colorSchemes CONSTANT) + +public: + Q_INVOKABLE void activateColorScheme(const QString &name); + + ColorSchemes(QObject *parent); + + QAbstractItemModel* colorSchemes(); + +private: + KColorSchemeManager* m_colorManager; +}; +} +#endif diff --git a/cuttlefish/src/iconmodel.cpp b/cuttlefish/src/iconmodel.cpp index d774daa..c6c42ed 100644 --- a/cuttlefish/src/iconmodel.cpp +++ b/cuttlefish/src/iconmodel.cpp @@ -1,422 +1,423 @@ /*************************************************************************** * * * Copyright 2014-2015 Sebastian Kügler * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ #include "iconmodel.h" #include #include #include #include #include #include #include #include #include #include #include +#include #include #include #include #include #include #include #include #include using namespace CuttleFish; static QTextStream cout(stdout); IconModel::IconModel(QObject *parent) : QAbstractListModel(parent), m_theme(QStringLiteral("breeze")) , m_loading(false) { m_roleNames.insert(FileName, "fileName"); m_roleNames.insert(IconName, "iconName"); m_roleNames.insert(Icon, "icon"); m_roleNames.insert(FullPath, "fullPath"); m_roleNames.insert(Category, "category"); m_roleNames.insert(Scalable, "scalable"); m_roleNames.insert(Sizes, "sizes"); m_roleNames.insert(Theme, "iconTheme"); m_roleNames.insert(Type, "type"); connect(this, &IconModel::categoryChanged, this, &IconModel::load); KConfigGroup cg(KSharedConfig::openConfig("cuttlefishrc"), "CuttleFish"); const QString themeName = cg.readEntry("theme", "default"); Plasma::Theme theme; // qDebug() << "Setting Plasma theme" << themeName; theme.setUseGlobalSettings(false); theme.setThemeName(themeName); // needs to happen after setUseGlobalSettings, since that clears themeName QList themepackages = KPackage::PackageLoader::self()->listPackages(QString(), "plasma/desktoptheme"); foreach (const KPluginMetaData &pkg, themepackages) { m_plasmathemes << pkg.pluginId(); } m_categories = QStringList() << "all" \ << "actions" << "animations" << "apps" << "categories" << "devices" << "emblems" << "emotes" << "filesystems" << "international" << "mimetypes" << "places" << "status"; load(); } QHash IconModel::roleNames() const { return m_roleNames; } int IconModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) if (m_data.size() <= 0) { return 0; } else { return m_data.size(); } } QVariant IconModel::data(const QModelIndex &index, int role) const { if (index.isValid()) { QString icon = m_icons.at(index.row()); switch (role) { case IconName: return icon; } return m_data[icon][key(role)]; } return QVariant(); } QString IconModel::key(int role) const { return QString::fromLocal8Bit(m_roleNames[role]); } void IconModel::add(const QFileInfo &info, const QString &cat) { QStringList cats; Q_FOREACH (auto c, m_categories) { cats << c.toLower(); } if (!cats.contains(cat)) { m_categories << cat; emit categoriesChanged(); } const QString fname = info.fileName(); bool scalable = false; QString icon = fname; if (fname.endsWith(".png")) { icon.remove(".png"); } else if (fname.endsWith(".svgz")) { icon.remove(".svgz"); scalable = true; } else if (fname.endsWith(".svg")) { icon.remove(".svg"); scalable = true; } QVariantMap &data = m_data[icon]; if (!m_icons.contains(icon)) { data["fullPath"] = info.absoluteFilePath(); data["iconName"] = icon; data["fileName"] = info.fileName(); data["category"] = cat; data["type"] = QStringLiteral("icon"); data["scalable"] = scalable; data["iconTheme"] = QStringLiteral("breeze"); m_icons << icon; } if (scalable && !data["scalable"].toBool()) { data["scalable"] = true; } QStringList _s = info.path().split('/'); if (_s.count() > 2) { QString size = _s[_s.count()-2]; // last but one is size, last is category if (size.indexOf("x") > 1) { size = size.split("x")[0]; QStringList sizes = data["sizes"].toStringList(); if (!sizes.contains(size)) { //qDebug() << "Size added" << sizes << size << data["iconName"]; sizes << size; data["sizes"] = sizes; } } } } QString IconModel::category() const { return m_category; } QStringList IconModel::categories() const { return m_categories; } void IconModel::setCategory(const QString& cat) { if (cat != m_category) { m_category = cat; emit categoryChanged(); } } QString IconModel::filter() const { return m_filter; } void IconModel::setFilter(const QString &filter) { //qDebug() << "Filter: " << filter; if (m_filter != filter) { m_filter = filter; load(); emit filterChanged(); emit svgIconsChanged(); } } void IconModel::load() { //qDebug() << "\n -- Loading (category / filter) : " << m_category << m_filter; m_loading = true; emit loadingChanged(); QElapsedTimer tt; tt.start(); const QDirIterator::IteratorFlags flags = QDirIterator::Subdirectories; const QStringList nameFilters = QStringList(); beginResetModel(); m_data.clear(); m_icons.clear(); //sm_categories.clear(); QString iconTheme; if (KIconLoader::global()) { iconTheme = KIconLoader::global()->theme()->internalName(); } else { return; } QStringList searchPaths; QStringList iconThemePaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("icons/") + iconTheme, QStandardPaths::LocateDirectory); if (iconThemePaths.count() > 0) { searchPaths << iconThemePaths; } QStringList hicolorThemePaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("icons/hicolor"), QStandardPaths::LocateDirectory); if (hicolorThemePaths.count() > 0) { searchPaths << hicolorThemePaths; } foreach (const QString &iconPath, searchPaths) { QDirIterator cats(iconPath, nameFilters, QDir::Dirs, QDirIterator::NoIteratorFlags); while (cats.hasNext()) { cats.next(); const QString fpath = cats.filePath(); const QString category = cats.fileName(); if (category != "." && category != "..") { QDirIterator it(fpath, nameFilters, QDir::Files, flags); while (it.hasNext()) { it.next(); const QFileInfo &info = it.fileInfo(); if (matchIcons(info)) { add(info, categoryFromPath(info.absoluteFilePath())); } } } } } svgIcons(); sort(); endResetModel(); m_loading = false; emit loadingChanged(); } void IconModel::sort() { std::sort(m_icons.begin(), m_icons.end()); } bool IconModel::matchIcons(const QFileInfo& info) { bool ok = false; // Category is empty or all? Skip further matching. bool catmatch = m_category.isEmpty() || m_category == QStringLiteral("all"); // category match? if (!catmatch && m_category == categoryFromPath(info.absoluteFilePath())) { catmatch = true; } // name filter if (m_filter.isEmpty() || info.fileName().indexOf(m_filter) != -1) { if (catmatch) { ok = true; } } return ok; } QStringList IconModel::themes() const { return m_themes; } QString IconModel::theme() const { return m_theme; } void IconModel::setTheme(const QString& theme) { if (theme != m_theme) { m_theme = theme; load(); emit themeChanged(); } } QString IconModel::plasmaTheme() const { return m_plasmatheme; } void IconModel::setPlasmaTheme(const QString& ptheme) { if (m_plasmatheme != ptheme) { m_plasmatheme = ptheme; Plasma::Theme theme; theme.setThemeName(ptheme); load(); emit plasmaThemeChanged(); } } QStringList IconModel::plasmathemes() const { return m_plasmathemes; } void IconModel::svgIcons() { QVariantList out; foreach (const QString &file, m_svgIcons.keys()) { foreach (const QString &icon, m_svgIcons[file].toStringList()) { if (m_filter.isEmpty() || (file.indexOf(m_filter) != -1 || icon.indexOf(m_filter) != -1)) { QVariantMap &data = m_data[icon]; if (!m_icons.contains(icon)) { data["fullPath"] = ""; data["iconName"] = icon; data["fileName"] = file; data["category"] = "system"; data["type"] = QStringLiteral("svg"); data["scalable"] = true; data["iconTheme"] = m_plasmatheme; m_icons << icon; } QVariantMap vm; vm["fileName"] = file; vm["iconName"] = icon; out << vm; } } } sort(); } QString IconModel::categoryFromPath(const QString& path) { QStringList cats; Q_FOREACH (auto c, m_categories) { cats << c.toLower(); } //cats << "actions" << "apps" << "places" << "status"; const QStringList _p1 = path.split("/icons/"); if (_p1.count() > 1) { foreach (const QString &cat, cats) { if (_p1[1].indexOf(cat) != -1) { return cat; } } } return QString(); } bool IconModel::loading() { return m_loading; } void IconModel::output(const QString& text) { cout << text.toLocal8Bit(); cout.flush(); } QVariantList IconModel::inOtherThemes(const QString& name, int iconSize) { QVariantList list; const QStringList themes = KIconTheme::list(); for (const auto& themeName : themes) { const KIconTheme theme(themeName); const QString iconPath = theme.iconPathByName(name, iconSize, KIconLoader::MatchBest); list.append(QVariantMap({{"themeName", themeName}, {"iconPath", iconPath}})); } return list; } diff --git a/cuttlefish/src/iconmodel.h b/cuttlefish/src/iconmodel.h index 8a4fd67..e947ba0 100644 --- a/cuttlefish/src/iconmodel.h +++ b/cuttlefish/src/iconmodel.h @@ -1,131 +1,134 @@ /*************************************************************************** * * * Copyright 2014-2015 Sebastian Kügler * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * * ***************************************************************************/ #ifndef CUTTLEFISHICONMODEL_H #define CUTTLEFISHICONMODEL_H #include #include #include #include #include #include +class KColorSchemeManager; + namespace CuttleFish { class IconModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged) Q_PROPERTY(QString category READ category WRITE setCategory NOTIFY categoryChanged) Q_PROPERTY(QString theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(QStringList themes READ themes CONSTANT) Q_PROPERTY(QStringList plasmathemes READ plasmathemes CONSTANT) Q_PROPERTY(QStringList categories READ categories NOTIFY categoriesChanged) Q_PROPERTY(QString plasmaTheme READ plasmaTheme WRITE setPlasmaTheme NOTIFY plasmaThemeChanged) Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged); public: enum Roles { FileName = Qt::UserRole + 1, IconName, Icon, FullPath, Category, Scalable, Sizes, Type, Theme }; explicit IconModel(QObject *parent = nullptr); Q_INVOKABLE QVariantList inOtherThemes(const QString& iconName, int size); QHash roleNames() const override; int rowCount(const QModelIndex &parent) const override; QVariant data(const QModelIndex &index, int role) const override; QString key(int role) const; bool matchIcons(const QFileInfo &info); void add(const QFileInfo &info, const QString &cat); void addSvgIcon(const QString &file, const QString &icon); void remove(const QString &iconFile); void setCategory(const QString &cat); QString category() const; void setFilter(const QString &filter); QString filter() const; void setTheme(const QString &theme); QString theme() const; QStringList themes() const; void setPlasmaTheme(const QString &ptheme); QString plasmaTheme() const; QStringList plasmathemes() const; QStringList categories() const; + QAbstractItemModel* colorschemes() const; bool loading(); void svgIcons(); void load(); Q_INVOKABLE void output(const QString &text); Q_INVOKABLE void sort(); Q_SIGNALS: void filterChanged(); void categoryChanged(); void categoriesChanged(); void themeChanged(); void svgIconsChanged(); void plasmaThemeChanged(); void loadingChanged(); private: QHash m_roleNames; QStringList m_icons; QString m_category; QStringList m_categories; QString m_theme; QString m_filter; QStringList m_themes; QStringList m_plasmathemes; QString m_plasmatheme; QHash m_data; QHash m_categoryTranslations; QVariantMap m_svgIcons; bool m_loading; QString categoryFromPath(const QString &path); }; } // namespace #endif // CUTTLEFISHICONMODEL_H diff --git a/cuttlefish/src/main.cpp b/cuttlefish/src/main.cpp index a65f663..82061b0 100644 --- a/cuttlefish/src/main.cpp +++ b/cuttlefish/src/main.cpp @@ -1,138 +1,143 @@ /*************************************************************************** * * * Copyright 2014 Sebastian Kügler * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ // Qt #include #include #include #include #include #include #include // Frameworks #include #include #include #include #include // Own +#include "colorschemes.h" #include "iconmodel.h" void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { if ((msg.contains("qt.svg") && msg.contains("Could not resolve property: #linearGradient")) || msg.contains("Could not resolve property: #pattern")) { return; } QByteArray localMsg = msg.toLocal8Bit(); const char *file = context.file ? context.file : ""; const char *function = context.function ? context.function : ""; switch (type) { case QtDebugMsg: fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); break; case QtInfoMsg: fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); break; case QtWarningMsg: fprintf(stderr, "\u001b[33mWarning\u001b[0m: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); break; case QtCriticalMsg: fprintf(stderr, "\u001b[33;1mCritical\u001b[0m: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); break; case QtFatalMsg: fprintf(stderr, "\u001b[31;1mFatal\u001b[0m: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); break; } } int main(int argc, char **argv) { qInstallMessageHandler(messageOutput); QApplication app(argc, argv); KLocalizedString::setApplicationDomain("cuttlefish"); app.setApplicationVersion(PROJECT_VERSION); app.setDesktopFileName(QStringLiteral("org.kde.cuttlefish")); app.setOrganizationName("KDE"); app.setOrganizationDomain("org.kde"); app.setApplicationName("Cuttlefish"); const static auto _category = QStringLiteral("category"); QCommandLineOption category = QCommandLineOption(QStringList() << QStringLiteral("c") << _category, i18n("Start with category"), i18n("category")); const static auto _f = QStringLiteral("fullscreen"); QCommandLineOption fullscreen = QCommandLineOption(QStringList() << QStringLiteral("f") << _f, i18n("Start full-screen")); const static auto _p = QStringLiteral("picker"); QCommandLineOption picker = QCommandLineOption(QStringList() << QStringLiteral("p") << _p, i18n("Run in icon-picker mode")); QCommandLineParser parser; parser.addVersionOption(); parser.setApplicationDescription("Cuttlefish Icon Browser"); parser.addHelpOption(); parser.addOption(category); parser.addOption(fullscreen); parser.addOption(picker); parser.process(app); QString _cc = parser.value(category); QQmlApplicationEngine engine; KDeclarative::KDeclarative kdeclarative; kdeclarative.setDeclarativeEngine(&engine); kdeclarative.setTranslationDomain(QStringLiteral("cuttlefish")); kdeclarative.setupContext(); kdeclarative.setupEngine(&engine); auto package = KPackage::PackageLoader::self()->loadPackage("Plasma/Generic"); package.setPath("org.kde.plasma.cuttlefish"); if (!package.isValid() || !package.metadata().isValid()) { qWarning() << "Could not load package org.kde.plasma.cuttlefish:" << package.path(); return -1; } auto iconModel = new CuttleFish::IconModel(engine.rootContext()); + auto colorSchemes = new CuttleFish::ColorSchemes(engine.rootContext()); engine.rootContext()->setContextProperty("iconModel", iconModel); engine.rootContext()->setContextProperty("pickerMode", parser.isSet("picker")); + engine.rootContext()->setContextProperty("colorSchemes", colorSchemes); engine.load(QUrl::fromLocalFile(package.filePath("mainscript"))); if (engine.rootObjects().isEmpty()) { return -1; } #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) qmlRegisterType(); + qmlRegisterType(); #else qmlRegisterAnonymousType("org.kde.plasma.sdk", 1); + qmlRegisterAnonymousType("org.kde.plasma.sdk", 1); #endif return app.exec(); }