├── .gitignore
├── install
├── reinstall
├── run
├── package
├── contents
│ ├── config
│ │ ├── config.qml
│ │ └── main.xml
│ ├── ui
│ │ ├── libconfig
│ │ │ ├── Label.qml
│ │ │ ├── RadioButtonGroup.qml
│ │ │ ├── Heading.qml
│ │ │ ├── IconField.qml
│ │ │ └── AppletIconField.qml
│ │ ├── UnityThemeDetector.qml
│ │ ├── lib
│ │ │ ├── ExecUtil.qml
│ │ │ ├── AppletIcon.qml
│ │ │ ├── KPackageModel.qml
│ │ │ └── DesktopEffectToggle.qml
│ │ ├── Unity7Workspaces.qml
│ │ ├── Main.qml
│ │ └── config
│ │ │ └── ConfigGeneral.qml
│ └── icons
│ │ ├── presentwindows-16px.svg
│ │ ├── presentwindows-22px.svg
│ │ ├── presentwindows-24px.svg
│ │ └── unity7selectedworkspace.svg
├── metadata.desktop
└── translate
│ ├── build
│ ├── ReadMe.md
│ ├── template.pot
│ ├── pl.po
│ ├── nl.po
│ ├── plasmoidlocaletest
│ └── merge
├── ReadMe.md
└── Changelog.md
/.gitignore:
--------------------------------------------------------------------------------
1 | *.plasmoid
2 | *.qmlc
3 | *.jsc
4 | *.mo
5 |
--------------------------------------------------------------------------------
/install:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Version 2
3 |
4 | kpackagetool5 -t Plasma/Applet -i package
5 |
--------------------------------------------------------------------------------
/reinstall:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Version 2
3 |
4 | kpackagetool5 -t Plasma/Applet -u package
5 | killall plasmashell
6 | kstart5 plasmashell
7 |
--------------------------------------------------------------------------------
/run:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Version 5
3 |
4 | # Clear SVG cache
5 | # rm ~/.cache/plasma-svgelements-*
6 |
7 | killall plasmoidviewer
8 | QML_DISABLE_DISK_CACHE=true plasmoidviewer -a package -l topedge -f horizontal -x 0 -y 0
9 |
--------------------------------------------------------------------------------
/package/contents/config/config.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 | import org.kde.plasma.configuration 2.0
3 |
4 | ConfigModel {
5 | ConfigCategory {
6 | name: i18n("General")
7 | icon: "configure"
8 | source: "config/ConfigGeneral.qml"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/ReadMe.md:
--------------------------------------------------------------------------------
1 | # Present Windows Button
2 |
3 | https://store.kde.org/p/1181039/
4 |
5 | A simple button that'll trigger the "Present Windows" desktop effect. It uses the same icon as Windows 10s "Task View" icon.
6 |
7 | ## Screenshots
8 |
9 | 
10 |
11 | 
12 |
--------------------------------------------------------------------------------
/package/contents/ui/libconfig/Label.qml:
--------------------------------------------------------------------------------
1 | // Version 2
2 |
3 | import QtQuick 2.0
4 | import QtQuick.Controls 2.0 as QQC2
5 | import QtQuick.Layouts 1.0
6 | import org.kde.kirigami 2.0 as Kirigami
7 |
8 | QQC2.Label {
9 | Layout.fillWidth: true
10 | wrapMode: Text.Wrap
11 | linkColor: Kirigami.Theme.highlightColor
12 | onLinkActivated: Qt.openUrlExternally(link)
13 | MouseArea {
14 | anchors.fill: parent
15 | acceptedButtons: Qt.NoButton // we don't want to eat clicks on the Text
16 | cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/package/metadata.desktop:
--------------------------------------------------------------------------------
1 | [Desktop Entry]
2 | Name=Present Windows Button
3 | Comment=Trigger the Present Windows desktop effect's shortcut with a click.
4 |
5 | Type=Service
6 | Icon=window
7 | X-KDE-ServiceTypes=Plasma/Applet
8 |
9 | X-Plasma-API=declarativeappletscript
10 | X-Plasma-MainScript=ui/Main.qml
11 |
12 | X-KDE-PluginInfo-Author=Chris Holland
13 | X-KDE-PluginInfo-Email=zrenfire@gmail.com
14 | X-KDE-PluginInfo-Name=com.github.zren.presentwindows
15 | X-KDE-PluginInfo-Version=9
16 | X-KDE-PluginInfo-Website=https://github.com/Zren/plasma-applet-presentwindows
17 | X-KDE-PluginInfo-Category=Windows and Tasks
18 |
--------------------------------------------------------------------------------
/package/contents/ui/UnityThemeDetector.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 | import org.kde.plasma.core 2.0 as PlasmaCore
3 |
4 | QtObject {
5 | readonly property bool shouldUseUnityTheme: {
6 | return PlasmaCore.Theme.themeName == 'UnityAmbiance'
7 | }
8 | readonly property int configState: plasmoid.configuration.useUnityTheme
9 | readonly property bool useUnityTheme: {
10 | // console.log('useUnityTheme', configState, shouldUseUnityTheme)
11 | if (configState == 0) { // Never
12 | return false
13 | } else if (configState == 1) { // DependsOnPlasmaStyle
14 | return shouldUseUnityTheme
15 | } else { // configState == 2 Always
16 | return true
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/package/contents/icons/presentwindows-16px.svg:
--------------------------------------------------------------------------------
1 |
19 |
--------------------------------------------------------------------------------
/package/contents/ui/lib/ExecUtil.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 | import org.kde.plasma.core 2.0 as PlasmaCore
3 |
4 | PlasmaCore.DataSource {
5 | id: executable
6 | engine: "executable"
7 | connectedSources: []
8 | onNewData: {
9 | var exitCode = data["exit code"]
10 | var exitStatus = data["exit status"]
11 | var stdout = data["stdout"]
12 | var stderr = data["stderr"]
13 | exited(sourceName, exitCode, exitStatus, stdout, stderr)
14 | disconnectSource(sourceName) // cmd finished
15 | }
16 | function exec(cmd) {
17 | connectSource(cmd)
18 | }
19 | signal exited(string command, int exitCode, int exitStatus, string stdout, string stderr)
20 |
21 | function trimOutput(stdout) {
22 | return stdout.replace('\n', ' ').trim()
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/package/contents/icons/presentwindows-22px.svg:
--------------------------------------------------------------------------------
1 |
19 |
--------------------------------------------------------------------------------
/package/contents/icons/presentwindows-24px.svg:
--------------------------------------------------------------------------------
1 |
19 |
--------------------------------------------------------------------------------
/package/contents/config/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 | ExposeAll
11 |
12 |
13 | presentwindows-24px
14 |
15 |
16 |
17 | 1
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Changelog.md:
--------------------------------------------------------------------------------
1 | ## v9 - April 24 2020
2 |
3 | * Add Parachute (KWin Script) support (Issue #9)
4 | * Added Dutch translations by @Vistaus (Pull Request #3)
5 |
6 | ## v8 - September 16 2018
7 |
8 | * Show preset values for the 22px and 16px icon in the config icon dropdown menu.
9 | * Fix the Desktop Effect toggle buttons not persisting accross reboots (Issue #1).
10 |
11 | ## v7 - August 4 2018
12 |
13 | * Add a 22px icon, with pathing done by @andreyorst.
14 | * Make sure the bundled icon is always smooth, even on older versions of plasma.
15 |
16 | ## v6 - April 14 2018
17 |
18 | * Force Latte Dock v0.7.5+ to not hide this widget.
19 |
20 | ## v5 - April 11 2018
21 |
22 | * Add Unity 7 virtual desktop indicator style for use with the Unity Ambiance desktop theme (used in the United Look and Feel).
23 |
24 | ## v4 - July 8 2017
25 |
26 | * Add ability to change the panel icon.
27 |
28 | ## v3 - June 22 2017
29 |
30 | * Add option to toggle the Desktop Grid Effect.
31 |
32 | ## v2 - June 15 2017
33 |
34 | * Provide checkbox in the config to quickly enabled the "Present Windows" desktop effect.
35 |
36 | ## v1 - June 15 2017
37 |
38 | * First version uploaded to the store.
39 | * Can configure which shortcut is run on click (All/CurrentDesktop/WindowClass).
40 | * Use same icon as Windows 10's Task View toggle.
41 |
--------------------------------------------------------------------------------
/package/contents/ui/lib/AppletIcon.qml:
--------------------------------------------------------------------------------
1 | // Version: 4
2 |
3 | import QtQuick 2.0
4 | import org.kde.plasma.core 2.0 as PlasmaCore
5 |
6 | Item {
7 | id: appletIcon
8 | property string source: ''
9 | property bool active: false
10 | readonly property bool usingPackageSvg: filename // plasmoid.file() returns "" if file doesn't exist.
11 | readonly property string filename: source ? plasmoid.file('', 'icons/' + source + '.svg') : ''
12 | readonly property int minSize: Math.min(width, height)
13 | property bool smooth: true
14 |
15 | PlasmaCore.IconItem {
16 | anchors.fill: parent
17 | visible: !appletIcon.usingPackageSvg
18 | source: appletIcon.usingPackageSvg ? '' : appletIcon.source
19 | active: appletIcon.active
20 | smooth: appletIcon.smooth
21 | }
22 |
23 | PlasmaCore.SvgItem {
24 | id: svgItem
25 | anchors.centerIn: parent
26 | readonly property real minSize: Math.min(naturalSize.width, naturalSize.height)
27 | readonly property real widthRatio: naturalSize.width / svgItem.minSize
28 | readonly property real heightRatio: naturalSize.height / svgItem.minSize
29 | width: appletIcon.minSize * widthRatio
30 | height: appletIcon.minSize * heightRatio
31 |
32 | smooth: appletIcon.smooth
33 |
34 | visible: appletIcon.usingPackageSvg
35 | svg: PlasmaCore.Svg {
36 | id: svg
37 | imagePath: appletIcon.filename
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/package/contents/ui/lib/KPackageModel.qml:
--------------------------------------------------------------------------------
1 | // Version 1
2 |
3 | import QtQuick 2.0
4 |
5 | ListModel {
6 | property string packageType
7 | property bool loaded: false
8 |
9 | readonly property var executable: ExecUtil {
10 | id: executable
11 | property string readStateCommand: '( kpackagetool5 --type="' + packageType + '" --list ; kpackagetool5 --g --type="' + packageType + '" --list ) | cat'
12 |
13 | function readState() {
14 | executable.exec(readStateCommand)
15 | }
16 | Component.onCompleted: {
17 | readState()
18 | }
19 |
20 | function parsePackageList(stdout) {
21 | clear()
22 | var lines = stdout.split('\n')
23 | for (var i = 0; i < lines.length; i++) {
24 | var line = lines[i]
25 | if (line.indexOf(packageType) >= 0) {
26 | // Treat line as:
27 | // Listing service types: KWin/Script in /usr/share/kwin/scripts/
28 | continue
29 | }
30 | var pluginId = line.trim()
31 | if (pluginId) {
32 | append({
33 | pluginId: pluginId,
34 | })
35 | }
36 | }
37 | }
38 |
39 | onExited: {
40 | if (command == readStateCommand) {
41 | parsePackageList(stdout)
42 | loaded = true
43 | }
44 | }
45 |
46 | function startsWith(a, b) {
47 | if (b.length <= a.length) {
48 | return a.substr(0, b.length) == b
49 | } else {
50 | return false
51 | }
52 | }
53 | }
54 |
55 | function contains(pluginId) {
56 | for (var i = 0; i < count; i++) {
57 | var item = get(i)
58 | if (item.pluginId == pluginId) {
59 | return true
60 | }
61 | }
62 | return false
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/package/contents/ui/libconfig/RadioButtonGroup.qml:
--------------------------------------------------------------------------------
1 | // Version 5
2 |
3 | import QtQuick 2.0
4 | import QtQuick.Controls 2.5 as QQC2
5 | import QtQuick.Layouts 1.0
6 | import org.kde.kirigami 2.5 as Kirigami
7 |
8 | /*
9 | ** Example:
10 | **
11 | import './libconfig' as LibConfig
12 | LibConfig.RadioButtonGroup {
13 | configKey: "priority"
14 | model: [
15 | { value: "a", text: i18n("A") },
16 | { value: "b", text: i18n("B") },
17 | { value: "c", text: i18n("C") },
18 | ]
19 | }
20 | */
21 | ColumnLayout {
22 | id: radioButtonGroup
23 |
24 | property string configKey: ''
25 | readonly property var configValue: configKey ? plasmoid.configuration[configKey] : ""
26 |
27 | property alias group: group
28 | QQC2.ButtonGroup {
29 | id: group
30 | }
31 |
32 | property alias model: buttonRepeater.model
33 |
34 | // The main reason we put all the RadioButtons in
35 | // a ColumnLayout is to shrink the spacing between the buttons.
36 | spacing: Kirigami.Units.smallSpacing
37 |
38 | // Assign buddyFor to the first RadioButton so that the Kirigami label aligns with it.
39 | // Repeater is also a visibleChild, so avoid it.
40 | Kirigami.FormData.buddyFor: {
41 | for (var i = 0; i < visibleChildren.length; i++) {
42 | if (!(visibleChildren[i] instanceof Repeater)) {
43 | return visibleChildren[i]
44 | }
45 | }
46 | return null
47 | }
48 |
49 | Repeater {
50 | id: buttonRepeater
51 | QQC2.RadioButton {
52 | visible: typeof modelData.visible !== "undefined" ? modelData.visible : true
53 | enabled: typeof modelData.enabled !== "undefined" ? modelData.enabled : true
54 | text: modelData.text
55 | checked: modelData.value === configValue
56 | QQC2.ButtonGroup.group: radioButtonGroup.group
57 | onClicked: {
58 | focus = true
59 | if (configKey) {
60 | plasmoid.configuration[configKey] = modelData.value
61 | }
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/package/translate/build:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Version: 6
3 |
4 | # This script will convert the *.po files to *.mo files, rebuilding the package/contents/locale folder.
5 | # Feature discussion: https://phabricator.kde.org/D5209
6 | # Eg: contents/locale/fr_CA/LC_MESSAGES/plasma_applet_org.kde.plasma.eventcalendar.mo
7 |
8 | DIR=`cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd`
9 | plasmoidName=`kreadconfig5 --file="$DIR/../metadata.desktop" --group="Desktop Entry" --key="X-KDE-PluginInfo-Name"`
10 | website=`kreadconfig5 --file="$DIR/../metadata.desktop" --group="Desktop Entry" --key="X-KDE-PluginInfo-Website"`
11 | bugAddress="$website"
12 | packageRoot=".." # Root of translatable sources
13 | projectName="plasma_applet_${plasmoidName}" # project name
14 |
15 | #---
16 | if [ -z "$plasmoidName" ]; then
17 | echo "[build] Error: Couldn't read plasmoidName."
18 | exit
19 | fi
20 |
21 | if [ -z "$(which msgfmt)" ]; then
22 | echo "[build] Error: msgfmt command not found. Need to install gettext"
23 | echo "[build] Running 'sudo apt install gettext'"
24 | sudo apt install gettext
25 | echo "[build] gettext installation should be finished. Going back to installing translations."
26 | fi
27 |
28 | #---
29 | echo "[build] Compiling messages"
30 |
31 | catalogs=`find . -name '*.po' | sort`
32 | for cat in $catalogs; do
33 | echo "$cat"
34 | catLocale=`basename ${cat%.*}`
35 | msgfmt -o "${catLocale}.mo" "$cat"
36 |
37 | installPath="$DIR/../contents/locale/${catLocale}/LC_MESSAGES/${projectName}.mo"
38 |
39 | echo "[build] Install to ${installPath}"
40 | mkdir -p "$(dirname "$installPath")"
41 | mv "${catLocale}.mo" "${installPath}"
42 | done
43 |
44 | echo "[build] Done building messages"
45 |
46 | if [ "$1" = "--restartplasma" ]; then
47 | echo "[build] Restarting plasmashell"
48 | killall plasmashell
49 | kstart5 plasmashell
50 | echo "[build] Done restarting plasmashell"
51 | else
52 | echo "[build] (re)install the plasmoid and restart plasmashell to test."
53 | fi
54 |
--------------------------------------------------------------------------------
/package/translate/ReadMe.md:
--------------------------------------------------------------------------------
1 | > Version 7 of Zren's i18n scripts.
2 |
3 | With KDE Frameworks v5.37 and above, translations are bundled with the `*.plasmoid` file downloaded from the store.
4 |
5 | ## Install Translations
6 |
7 | Go to `~/.local/share/plasma/plasmoids/com.github.zren.presentwindows/translate/` and run `sh ./build --restartplasma`.
8 |
9 | ## New Translations
10 |
11 | 1. Fill out [`template.pot`](template.pot) with your translations then open a [new issue](https://github.com/Zren/plasma-applet-presentwindows/issues/new), name the file `spanish.txt`, attach the txt file to the issue (drag and drop).
12 |
13 | Or if you know how to make a pull request
14 |
15 | 1. Copy the `template.pot` file and name it your locale's code (Eg: `en`/`de`/`fr`) with the extension `.po`. Then fill out all the `msgstr ""`.
16 |
17 | ## Scripts
18 |
19 | * `sh ./merge` will parse the `i18n()` calls in the `*.qml` files and write it to the `template.pot` file. Then it will merge any changes into the `*.po` language files.
20 | * `sh ./build` will convert the `*.po` files to it's binary `*.mo` version and move it to `contents/locale/...` which will bundle the translations in the `*.plasmoid` without needing the user to manually install them.
21 | * `sh ./plasmoidlocaletest` will run `./build` then `plasmoidviewer` (part of `plasma-sdk`).
22 |
23 | ## Links
24 |
25 | * https://zren.github.io/kde/docs/widget/#translations-i18n
26 | * https://techbase.kde.org/Development/Tutorials/Localization/i18n_Build_Systems
27 | * https://api.kde.org/frameworks/ki18n/html/prg_guide.html
28 |
29 | ## Examples
30 |
31 | * https://l10n.kde.org/stats/gui/trunk-kf5/team/fr/plasma-desktop/
32 | * https://github.com/psifidotos/nowdock-plasmoid/tree/master/po
33 | * https://github.com/kotelnik/plasma-applet-redshift-control/tree/master/translations
34 |
35 | ## Status
36 | | Locale | Lines | % Done|
37 | |----------|---------|-------|
38 | | Template | 20 | |
39 | | nl | 12/20 | 60% |
40 | | pl | 12/20 | 60% |
41 |
--------------------------------------------------------------------------------
/package/contents/ui/lib/DesktopEffectToggle.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 | import QtQuick.Controls 1.0
3 | import QtQuick.Layouts 1.0
4 |
5 | QtObject {
6 | id: desktopEffectToggle
7 | property string effectId
8 | property bool loaded: false
9 | property bool effectEnabled: false
10 |
11 |
12 | function toggle() {
13 | executable.toggleState()
14 | }
15 |
16 | property ExecUtil executable: ExecUtil {
17 | id: executable
18 | property string readStateCommand: 'qdbus org.kde.KWin /Effects isEffectLoaded ' + effectId
19 | property string toggleStateCommand: 'qdbus org.kde.KWin /Effects toggleEffect ' + effectId
20 |
21 | // For some reason, the toggleEffect qdbus function does not save to kwinrc.
22 | // So we need to manually write the new state to it, so that the next time
23 | // kwin is launched (next reboot), the desktop effect is still enabled/disabled.
24 | property string saveStateCommand: 'kwriteconfig5 --file ~/.config/kwinrc --group Plugins --key ' + effectId + 'Enabled' // saveStateCommand + ' ' + value
25 | property bool saveOnRead: false
26 |
27 | function readState() {
28 | executable.exec(readStateCommand)
29 | }
30 | function toggleState() {
31 | executable.exec(toggleStateCommand)
32 | }
33 | function saveState() {
34 | var isCurrentlyEnabled = effectEnabled
35 | executable.exec(saveStateCommand + ' ' + (isCurrentlyEnabled ? 'true' : 'false'))
36 | }
37 | Component.onCompleted: {
38 | readState()
39 | }
40 |
41 | onExited: {
42 | if (command == readStateCommand) {
43 | var value = executable.trimOutput(stdout)
44 | value = value === 'true' // cast to boolean
45 | effectEnabled = value
46 | loaded = true
47 | if (saveOnRead) {
48 | saveOnRead = false
49 | saveState()
50 | }
51 | } else if (command == toggleStateCommand) {
52 | saveOnRead = true
53 | readState()
54 | } else if (startsWith(command, saveStateCommand)) {
55 |
56 | }
57 | }
58 |
59 | function startsWith(a, b) {
60 | if (b.length <= a.length) {
61 | return a.substr(0, b.length) == b
62 | } else {
63 | return false
64 | }
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/package/contents/ui/libconfig/Heading.qml:
--------------------------------------------------------------------------------
1 | // Version 5
2 |
3 | import QtQuick 2.0
4 | import QtQuick.Controls 2.5 as QQC2
5 | import QtQuick.Layouts 1.0
6 | import org.kde.kirigami 2.5 as Kirigami
7 |
8 | /*
9 | ** Example:
10 | **
11 | import './libconfig' as LibConfig
12 | LibConfig.Heading {
13 | text: i18n("SpinBox (Double)")
14 | }
15 | */
16 |
17 | // While the following Kirigami is very simple:
18 | // Kirigami.Separator {
19 | // Kirigami.FormData.label: "Heading"
20 | // Kirigami.FormData.isSection: true
21 | // }
22 | //
23 | // I want to be able to adjust the label size and make it bold.
24 | // Kirigami's buddy Heading is level=3, which does not stand out
25 | // very well. I also want to center the heading.
26 | // Since we can't access the Heading in the buddy component, we
27 | // need to make sure the Heading has no text, and draw our own.
28 | ColumnLayout {
29 | id: heading
30 | spacing: 0
31 |
32 | property string text: ""
33 | property alias separator: separator
34 | property alias label: label
35 | property bool useThickTopMargin: true
36 |
37 | property Item __formLayout: {
38 | if (parent && typeof parent.wideMode === 'boolean') {
39 | return parent
40 | } else if (typeof formLayout !== 'undefined' && typeof formLayout.wideMode === 'boolean') {
41 | return formLayout
42 | } else if (typeof page !== 'undefined' && typeof page.wideMode === 'boolean') {
43 | return page
44 | } else {
45 | return null
46 | }
47 | }
48 |
49 | Layout.fillWidth: true
50 | // Kirigami.FormData.isSection: true
51 | Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.FormLabel
52 |
53 | Kirigami.Separator {
54 | id: separator
55 | visible: false
56 | Layout.fillWidth: true
57 | Layout.topMargin: Kirigami.Units.largeSpacing
58 | Layout.bottomMargin: Kirigami.Units.largeSpacing
59 | }
60 |
61 | Kirigami.Heading {
62 | id: label
63 | Layout.topMargin: useThickTopMargin ? Kirigami.Units.largeSpacing * 3 : Kirigami.Units.largeSpacing
64 | Layout.bottomMargin: Kirigami.Units.smallSpacing
65 | Layout.fillWidth: true
66 | text: heading.text
67 | level: 1
68 | font.weight: Font.Bold
69 | // horizontalAlignment: (!__formLayout || __formLayout.wideMode) ? Text.AlignHCenter : Text.AlignLeft
70 | verticalAlignment: (!__formLayout || __formLayout.wideMode) ? Text.AlignVCenter : Text.AlignBottom
71 | }
72 | }
73 |
74 | //--- Test Default Kirigami Heading
75 | // Kirigami.Separator {
76 | // property string text: ""
77 | // Kirigami.FormData.label: text
78 | // Kirigami.FormData.isSection: true
79 | // property alias separator: separator
80 | // Item {
81 | // id: separator
82 | // }
83 | // }
84 |
--------------------------------------------------------------------------------
/package/translate/template.pot:
--------------------------------------------------------------------------------
1 | # Translation of presentwindows in LANGUAGE
2 | # Copyright (C) 2022
3 | # This file is distributed under the same license as the presentwindows package.
4 | # FIRST AUTHOR , YEAR.
5 | #
6 | #, fuzzy
7 | msgid ""
8 | msgstr ""
9 | "Project-Id-Version: presentwindows\n"
10 | "Report-Msgid-Bugs-To: https://github.com/Zren/plasma-applet-presentwindows\n"
11 | "POT-Creation-Date: 2022-02-23 22:57-0500\n"
12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 | "Last-Translator: FULL NAME \n"
14 | "Language-Team: LANGUAGE \n"
15 | "Language: \n"
16 | "MIME-Version: 1.0\n"
17 | "Content-Type: text/plain; charset=UTF-8\n"
18 | "Content-Transfer-Encoding: 8bit\n"
19 |
20 | #: ../metadata.desktop
21 | msgid "Present Windows Button"
22 | msgstr ""
23 |
24 | #: ../metadata.desktop
25 | msgid "Trigger the Present Windows desktop effect's shortcut with a click."
26 | msgstr ""
27 |
28 | #: ../contents/config/config.qml
29 | msgid "General"
30 | msgstr ""
31 |
32 | #: ../contents/ui/config/ConfigGeneral.qml
33 | msgid "Behavior"
34 | msgstr ""
35 |
36 | #: ../contents/ui/config/ConfigGeneral.qml
37 | msgid "Click"
38 | msgstr ""
39 |
40 | #: ../contents/ui/config/ConfigGeneral.qml
41 | msgid "Enable Desktop Effect"
42 | msgstr ""
43 |
44 | #: ../contents/ui/config/ConfigGeneral.qml
45 | msgid "Appearance"
46 | msgstr ""
47 |
48 | #: ../contents/ui/config/ConfigGeneral.qml
49 | msgid "Icon"
50 | msgstr ""
51 |
52 | #: ../contents/ui/config/ConfigGeneral.qml
53 | msgid "Unity Pager Theme"
54 | msgstr ""
55 |
56 | #: ../contents/ui/config/ConfigGeneral.qml
57 | msgid "Use Unity 7 Theme"
58 | msgstr ""
59 |
60 | #: ../contents/ui/config/ConfigGeneral.qml
61 | msgid "Never"
62 | msgstr ""
63 |
64 | #: ../contents/ui/config/ConfigGeneral.qml
65 | msgid "When Plasma Style is Unity Ambiance"
66 | msgstr ""
67 |
68 | #: ../contents/ui/config/ConfigGeneral.qml
69 | msgid "Always"
70 | msgstr ""
71 |
72 | #: ../contents/ui/config/ConfigGeneral.qml
73 | msgid "Should we use a Virtual Desktop indicator similar to Unity 7? This feature is enabled for the Unity Ambiance Plasma Style by default."
74 | msgstr ""
75 |
76 | #: ../contents/ui/config/ConfigGeneral.qml
77 | msgid "Current Plasma Style: %1"
78 | msgstr ""
79 |
80 | #: ../contents/ui/Main.qml
81 | msgid "Show Overview"
82 | msgstr ""
83 |
84 | #: ../contents/ui/Main.qml
85 | msgid "Present Windows (All desktops)"
86 | msgstr ""
87 |
88 | #: ../contents/ui/Main.qml
89 | msgid "Present Windows (Current desktop)"
90 | msgstr ""
91 |
92 | #: ../contents/ui/Main.qml
93 | msgid "Present Windows (Window class)"
94 | msgstr ""
95 |
96 | #: ../contents/ui/Main.qml
97 | msgid "Show Desktop Grid"
98 | msgstr ""
99 |
--------------------------------------------------------------------------------
/package/translate/pl.po:
--------------------------------------------------------------------------------
1 | # Translation of presentwindows in pl
2 | # Copyright (C) 2020
3 | # This file is distributed under the same license as the presentwindows package.
4 | # FIRST AUTHOR , YEAR.
5 | #
6 | msgid ""
7 | msgstr ""
8 | "Project-Id-Version: presentwindows\n"
9 | "Report-Msgid-Bugs-To: https://github.com/Zren/plasma-applet-presentwindows\n"
10 | "POT-Creation-Date: 2022-02-23 22:57-0500\n"
11 | "PO-Revision-Date: 2020-05-31 08:11+0200\n"
12 | "Last-Translator: Piotr Komur \n"
13 | "Language-Team: Piotr Komur \n"
14 | "Language: pl\n"
15 | "MIME-Version: 1.0\n"
16 | "Content-Type: text/plain; charset=UTF-8\n"
17 | "Content-Transfer-Encoding: 8bit\n"
18 | "X-Generator: Poedit 2.3\n"
19 | "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 "
20 | "|| n%100>14) ? 1 : 2);\n"
21 |
22 | #: ../metadata.desktop
23 | msgid "Present Windows Button"
24 | msgstr ""
25 |
26 | #: ../metadata.desktop
27 | msgid "Trigger the Present Windows desktop effect's shortcut with a click."
28 | msgstr ""
29 |
30 | #: ../contents/config/config.qml
31 | msgid "General"
32 | msgstr "Ogólne"
33 |
34 | #: ../contents/ui/config/ConfigGeneral.qml
35 | msgid "Behavior"
36 | msgstr ""
37 |
38 | #: ../contents/ui/config/ConfigGeneral.qml
39 | msgid "Click"
40 | msgstr "Kliknięcie"
41 |
42 | #: ../contents/ui/config/ConfigGeneral.qml
43 | msgid "Enable Desktop Effect"
44 | msgstr ""
45 |
46 | #: ../contents/ui/config/ConfigGeneral.qml
47 | msgid "Appearance"
48 | msgstr "Wygląd"
49 |
50 | #: ../contents/ui/config/ConfigGeneral.qml
51 | msgid "Icon"
52 | msgstr "Ikona"
53 |
54 | #: ../contents/ui/config/ConfigGeneral.qml
55 | msgid "Unity Pager Theme"
56 | msgstr "Motyw Unity Pager"
57 |
58 | #: ../contents/ui/config/ConfigGeneral.qml
59 | msgid "Use Unity 7 Theme"
60 | msgstr "Motyw Unity 7"
61 |
62 | #: ../contents/ui/config/ConfigGeneral.qml
63 | msgid "Never"
64 | msgstr "Nigdy"
65 |
66 | #: ../contents/ui/config/ConfigGeneral.qml
67 | msgid "When Plasma Style is Unity Ambiance"
68 | msgstr ""
69 |
70 | #: ../contents/ui/config/ConfigGeneral.qml
71 | msgid "Always"
72 | msgstr "Zawsze"
73 |
74 | #: ../contents/ui/config/ConfigGeneral.qml
75 | msgid ""
76 | "Should we use a Virtual Desktop indicator similar to Unity 7? This feature "
77 | "is enabled for the Unity "
78 | "Ambiance Plasma Style by default."
79 | msgstr ""
80 |
81 | #: ../contents/ui/config/ConfigGeneral.qml
82 | msgid "Current Plasma Style: %1"
83 | msgstr ""
84 |
85 | #: ../contents/ui/Main.qml
86 | msgid "Show Overview"
87 | msgstr ""
88 |
89 | #: ../contents/ui/Main.qml
90 | msgid "Present Windows (All desktops)"
91 | msgstr "Prezentacja okien (Wszystkie pulpity)"
92 |
93 | #: ../contents/ui/Main.qml
94 | msgid "Present Windows (Current desktop)"
95 | msgstr "Prezentacja okien (Bieżący pulpit)"
96 |
97 | #: ../contents/ui/Main.qml
98 | msgid "Present Windows (Window class)"
99 | msgstr "Prezentacja okien (Klasa okna)"
100 |
101 | #: ../contents/ui/Main.qml
102 | msgid "Show Desktop Grid"
103 | msgstr "Siatka pulpitu"
104 |
105 | #~ msgid "Present Windows Effect"
106 | #~ msgstr "Efekt prezentacji okien"
107 |
108 | #~ msgid ""
109 | #~ "Button will not work when the Present Windows desktop effect is disabled."
110 | #~ msgstr "Przycisk nie działa, gdy efekt pulpitu jest nieaktywny."
111 |
112 | #~ msgid "Show Desktop Grid Effect"
113 | #~ msgstr "Efekt siatki pulpitu"
114 |
115 | #~ msgid ""
116 | #~ "Button will not work when the Desktop Grid desktop effect is disabled."
117 | #~ msgstr "Przycisk nie działa, gdy efekt pulpitu jest nieaktywny."
118 |
119 | #~ msgid "Current Desktop Theme: %1"
120 | #~ msgstr "Motyw bieżącego pulpitu: %1"
121 |
122 | #~ msgid "Version: %1"
123 | #~ msgstr "Wersja: %1"
124 |
125 | #~ msgid "Enabled"
126 | #~ msgstr "Włączone"
127 |
--------------------------------------------------------------------------------
/package/contents/ui/Unity7Workspaces.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 | import QtQuick.Layouts 1.1
3 | import org.kde.plasma.plasmoid 2.0
4 | import org.kde.plasma.core 2.0 as PlasmaCore
5 |
6 | import org.kde.plasma.private.pager 2.0
7 |
8 | import "lib"
9 |
10 | Item {
11 | id: panelItem
12 |
13 | // Heavy use of the default Pager's code.
14 | // See: /usr/share/plasma/plasmoid/org.kde.plasma.pager/contents/ui/main.qml
15 | PagerModel {
16 | id: pagerModel
17 |
18 | enabled: true
19 | showOnlyCurrentScreen: true //plasmoid.configuration.showOnlyCurrentScreen
20 | screenGeometry: plasmoid.screenGeometry
21 | pagerType: PagerModel.VirtualDesktops
22 | }
23 |
24 | PlasmaCore.FrameSvgItem {
25 | id: taskFrame
26 | anchors.fill: parent
27 | imagePath: "widgets/tasks"
28 | prefix: "normal"
29 | }
30 |
31 | Grid {
32 | id: pagerItemGrid
33 | anchors.fill: parent
34 |
35 | anchors.leftMargin: taskFrame.margins.left
36 | anchors.rightMargin: taskFrame.margins.right
37 | anchors.topMargin: taskFrame.margins.top
38 | anchors.bottomMargin: taskFrame.margins.bottom
39 |
40 | // spacing: PlasmaCore.Units.devicePixelRatio
41 | rows: effectiveRows
42 | columns: effectiveColumns
43 |
44 | readonly property int effectiveRows: {
45 | var rows = 1
46 | var columns = Math.floor(pagerModel.count / pagerModel.layoutRows)
47 |
48 | if (pagerModel.count % pagerModel.layoutRows > 0) {
49 | columns += 1
50 | }
51 |
52 | rows = Math.floor(pagerModel.count / columns)
53 |
54 | if (pagerModel.count % columns > 0) {
55 | rows += 1
56 | }
57 |
58 | return rows
59 | }
60 |
61 | readonly property int effectiveColumns: {
62 | if (!pagerModel.count) {
63 | return 1
64 | }
65 |
66 | return Math.ceil(pagerModel.count / effectiveRows)
67 | }
68 |
69 |
70 | readonly property real pagerItemSizeRatio: pagerModel.pagerItemSize.width / pagerModel.pagerItemSize.height
71 | // readonly property real widthScaleFactor: columnWidth / pagerModel.pagerItemSize.width
72 | // readonly property real heightScaleFactor: rowHeight / pagerModel.pagerItemSize.height
73 |
74 | property int rowHeight: Math.floor(height / effectiveRows)
75 | property int columnWidth: Math.floor(width / effectiveColumns)
76 |
77 | property color seperatorColor: "#44FFFFFF"
78 | property color activeDesktopFillColor: "#44442027"
79 |
80 | Repeater {
81 | id: repeater
82 | model: pagerModel
83 |
84 | Item {
85 | id: desktop
86 | property int desktopIndex: index
87 | property int desktopColumn: index % pagerItemGrid.columns
88 | property int desktopRow: Math.floor(index / pagerItemGrid.columns)
89 | property bool isActiveDesktop: (index == pagerModel.currentPage)
90 |
91 | width: pagerItemGrid.columnWidth
92 | height: pagerItemGrid.rowHeight
93 |
94 |
95 | Rectangle {
96 | anchors.fill: parent
97 | color: desktop.isActiveDesktop ? pagerItemGrid.activeDesktopFillColor : "transparent"
98 | }
99 |
100 | Rectangle {
101 | id: verticalSeperator
102 | visible: desktop.desktopColumn < pagerItemGrid.columns-1 // Don't show on last column
103 | anchors.top: parent.top
104 | anchors.right: parent.right
105 | anchors.bottom: parent.bottom
106 | width: Math.round(1 * PlasmaCore.Units.devicePixelRatio)
107 | color: pagerItemGrid.seperatorColor
108 | }
109 | Rectangle {
110 | id: horizontalSeperator
111 | visible: desktop.desktopRow < pagerItemGrid.rows-1 // Don't show on last row
112 | anchors.left: parent.left
113 | anchors.bottom: parent.bottom
114 | anchors.right: parent.right
115 | height: Math.round(1 * PlasmaCore.Units.devicePixelRatio)
116 | color: pagerItemGrid.seperatorColor
117 | }
118 |
119 | AppletIcon {
120 | anchors.fill: parent
121 | source: desktop.isActiveDesktop ? "unity7selectedworkspace" : ""
122 | }
123 | }
124 |
125 | }
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/package/contents/ui/Main.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 | import QtQuick.Layouts 1.1
3 | import org.kde.plasma.plasmoid 2.0
4 | import org.kde.plasma.core 2.0 as PlasmaCore
5 |
6 | import "lib" as Lib
7 |
8 | Item {
9 | id: widget
10 |
11 | UnityThemeDetector {
12 | id: unityThemeDetector
13 | }
14 |
15 | property bool disableLatteParabolicIcon: true // Don't hide the representation in Latte (https://github.com/psifidotos/Latte-Dock/issues/983)
16 |
17 | Plasmoid.onActivated: widget.activate()
18 |
19 | Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation
20 | Plasmoid.fullRepresentation: Item {
21 | id: panelItem
22 |
23 | readonly property bool inPanel: (plasmoid.location == PlasmaCore.Types.TopEdge
24 | || plasmoid.location == PlasmaCore.Types.RightEdge
25 | || plasmoid.location == PlasmaCore.Types.BottomEdge
26 | || plasmoid.location == PlasmaCore.Types.LeftEdge)
27 |
28 | Layout.minimumWidth: {
29 | switch (plasmoid.formFactor) {
30 | case PlasmaCore.Types.Vertical:
31 | return 0;
32 | case PlasmaCore.Types.Horizontal:
33 | return height;
34 | default:
35 | return PlasmaCore.Units.gridUnit * 3;
36 | }
37 | }
38 |
39 | Layout.minimumHeight: {
40 | switch (plasmoid.formFactor) {
41 | case PlasmaCore.Types.Vertical:
42 | return width;
43 | case PlasmaCore.Types.Horizontal:
44 | return 0;
45 | default:
46 | return PlasmaCore.Units.gridUnit * 3;
47 | }
48 | }
49 |
50 | Layout.maximumWidth: inPanel ? PlasmaCore.Units.iconSizeHints.panel : -1
51 | Layout.maximumHeight: inPanel ? PlasmaCore.Units.iconSizeHints.panel : -1
52 |
53 | Lib.AppletIcon {
54 | id: icon
55 | anchors.fill: parent
56 | visible: !unityThemeDetector.useUnityTheme
57 |
58 | source: plasmoid.configuration.icon
59 | active: mouseArea.containsMouse
60 | }
61 | Loader {
62 | anchors.fill: parent
63 | active: unityThemeDetector.useUnityTheme
64 | visible: active
65 | source: "Unity7Workspaces.qml"
66 | }
67 |
68 | MouseArea {
69 | id: mouseArea
70 | anchors.fill: parent
71 | hoverEnabled: true
72 | onClicked: widget.activate()
73 | }
74 | }
75 |
76 | PlasmaCore.DataSource {
77 | id: executable
78 | engine: "executable"
79 | connectedSources: []
80 | onNewData: disconnectSource(sourceName)
81 |
82 | function exec(cmd) {
83 | executable.connectSource(cmd)
84 | }
85 | }
86 |
87 | function action_showOverview() {
88 | executable.exec('qdbus org.kde.kglobalaccel /component/kwin invokeShortcut "Overview"')
89 | }
90 |
91 | function action_exposeAll() {
92 | executable.exec('qdbus org.kde.kglobalaccel /component/kwin invokeShortcut "ExposeAll"')
93 | }
94 |
95 | function action_exposeDesktop() {
96 | executable.exec('qdbus org.kde.kglobalaccel /component/kwin invokeShortcut "Expose"')
97 | }
98 |
99 | function action_exposeWindowClass() {
100 | executable.exec('qdbus org.kde.kglobalaccel /component/kwin invokeShortcut "ExposeClass"')
101 | }
102 |
103 | function action_showDesktopGrid() {
104 | executable.exec('qdbus org.kde.kglobalaccel /component/kwin invokeShortcut "ShowDesktopGrid"')
105 | }
106 |
107 | function action_toggleParachute() {
108 | executable.exec('qdbus org.kde.kglobalaccel /component/kwin invokeShortcut "Parachute"')
109 | }
110 |
111 | function activate() {
112 | if (plasmoid.configuration.clickCommand == 'Overview') {
113 | action_showOverview()
114 | } else if (plasmoid.configuration.clickCommand == 'ExposeAll') {
115 | action_exposeAll()
116 | } else if (plasmoid.configuration.clickCommand == 'Expose') {
117 | action_exposeDesktop()
118 | } else if (plasmoid.configuration.clickCommand == 'ExposeClass') {
119 | action_exposeWindowClass()
120 | } else if (plasmoid.configuration.clickCommand == 'ShowDesktopGrid') {
121 | action_showDesktopGrid()
122 | } else if (plasmoid.configuration.clickCommand == 'Parachute') {
123 | action_toggleParachute()
124 | }
125 | }
126 |
127 | Component.onCompleted: {
128 | plasmoid.setAction("showOverview", i18n("Show Overview"), "view-grid");
129 | plasmoid.setAction("exposeAll", i18n("Present Windows (All desktops)"), "window");
130 | plasmoid.setAction("exposeDesktop", i18n("Present Windows (Current desktop)"), "window");
131 | plasmoid.setAction("exposeWindowClass", i18n("Present Windows (Window class)"), "window");
132 | plasmoid.setAction("showDesktopGrid", i18n("Show Desktop Grid"), "view-grid");
133 |
134 | // plasmoid.action('configure').trigger() // Uncomment to open the config window on load.
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/package/contents/ui/libconfig/IconField.qml:
--------------------------------------------------------------------------------
1 | // Version 9
2 |
3 | import QtQuick 2.0
4 | import QtQuick.Controls 2.0 as QQC2
5 | import QtQuick.Layouts 1.0
6 |
7 | import org.kde.kirigami 2.0 as Kirigami
8 | import org.kde.plasma.core 2.0 as PlasmaCore
9 | import org.kde.kquickcontrolsaddons 2.0 as KQuickAddons
10 |
11 | RowLayout {
12 | id: iconField
13 |
14 | default property alias _contentChildren: content.data
15 |
16 | property string configKey: ''
17 | property alias value: textField.text
18 | readonly property string configValue: configKey ? plasmoid.configuration[configKey] : ""
19 | onConfigValueChanged: {
20 | if (!textField.focus && value != configValue) {
21 | value = configValue
22 | }
23 | }
24 | property int previewIconSize: Kirigami.Units.iconSizes.medium
25 | property string defaultValue: ""
26 | property alias placeholderValue: textField.placeholderText
27 | property var presetValues: []
28 |
29 | // Based on org.kde.plasma.kickoff
30 | QQC2.Button {
31 | id: iconButton
32 | padding: Kirigami.Units.smallSpacing
33 | Layout.alignment: Qt.AlignTop
34 |
35 | // KDE QQC2 sets implicitSize to background.implicitSize ignoring padding/inset properties.
36 | implicitWidth: leftPadding + contentItem.implicitWidth + rightPadding
37 | implicitHeight: topPadding + contentItem.implicitHeight + bottomPadding
38 |
39 | onPressed: iconMenu.opened ? iconMenu.close() : iconMenu.open()
40 |
41 | contentItem: PlasmaCore.FrameSvgItem {
42 | id: previewFrame
43 | imagePath: plasmoid.location === PlasmaCore.Types.Vertical || plasmoid.location === PlasmaCore.Types.Horizontal
44 | ? "widgets/panel-background" : "widgets/background"
45 | implicitWidth: fixedMargins.left + previewIconSize + fixedMargins.right
46 | implicitHeight: fixedMargins.top + previewIconSize + fixedMargins.bottom
47 |
48 | PlasmaCore.IconItem {
49 | anchors.fill: parent
50 | anchors.leftMargin: previewFrame.fixedMargins.left
51 | anchors.topMargin: previewFrame.fixedMargins.top
52 | anchors.rightMargin: previewFrame.fixedMargins.right
53 | anchors.bottomMargin: previewFrame.fixedMargins.bottom
54 | source: iconField.value || iconField.placeholderValue
55 | active: iconButton.hovered
56 | }
57 | }
58 |
59 | QQC2.Menu {
60 | id: iconMenu
61 |
62 | // Appear below the button
63 | y: +parent.height
64 |
65 | QQC2.MenuItem {
66 | text: i18ndc("plasma_applet_org.kde.plasma.kickoff", "@item:inmenu Open icon chooser dialog", "Choose...")
67 | icon.name: "document-open"
68 | onClicked: dialogLoader.active = true
69 | }
70 | QQC2.MenuItem {
71 | text: i18ndc("plasma_applet_org.kde.plasma.kickoff", "@item:inmenu Reset icon to default", "Clear Icon")
72 | icon.name: "edit-clear"
73 | onClicked: iconField.value = iconField.defaultValue
74 | }
75 | }
76 | }
77 |
78 | ColumnLayout {
79 | id: content
80 | Layout.fillWidth: true
81 |
82 | RowLayout {
83 | QQC2.TextField {
84 | id: textField
85 | Layout.fillWidth: true
86 |
87 | text: iconField.configValue
88 | onTextChanged: serializeTimer.restart()
89 |
90 | rightPadding: clearButton.width + Kirigami.Units.smallSpacing
91 |
92 | QQC2.ToolButton {
93 | id: clearButton
94 | visible: iconField.configValue != iconField.defaultValue
95 | icon.name: iconField.defaultValue === "" ? "edit-clear" : "edit-undo"
96 | onClicked: iconField.value = iconField.defaultValue
97 |
98 | anchors.top: parent.top
99 | anchors.right: parent.right
100 | anchors.bottom: parent.bottom
101 |
102 | width: height
103 | }
104 | }
105 |
106 | QQC2.Button {
107 | id: browseButton
108 | icon.name: "document-open"
109 | onClicked: dialogLoader.active = true
110 | }
111 | }
112 |
113 | Flow {
114 | Layout.fillWidth: true
115 | Layout.maximumWidth: Kirigami.Units.gridUnit * 30
116 | Repeater {
117 | model: presetValues
118 | QQC2.Button {
119 | icon.name: modelData
120 | text: modelData
121 | onClicked: iconField.value = modelData
122 | }
123 | }
124 | }
125 | }
126 |
127 | Loader {
128 | id: dialogLoader
129 | active: false
130 | sourceComponent: KQuickAddons.IconDialog {
131 | id: dialog
132 | visible: true
133 | modality: Qt.WindowModal
134 | onIconNameChanged: {
135 | iconField.value = iconName
136 | }
137 | onVisibleChanged: {
138 | if (!visible) {
139 | dialogLoader.active = false
140 | }
141 | }
142 | }
143 | }
144 |
145 | Timer { // throttle
146 | id: serializeTimer
147 | interval: 300
148 | onTriggered: {
149 | if (configKey) {
150 | plasmoid.configuration[configKey] = iconField.value
151 | }
152 | }
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/package/contents/ui/libconfig/AppletIconField.qml:
--------------------------------------------------------------------------------
1 | // Version 9
2 | // Forked LibConfig.IconField to use Lib.AppletIcon
3 |
4 | import QtQuick 2.0
5 | import QtQuick.Controls 2.0 as QQC2
6 | import QtQuick.Layouts 1.0
7 |
8 | import org.kde.kirigami 2.0 as Kirigami
9 | import org.kde.plasma.core 2.0 as PlasmaCore
10 | import org.kde.kquickcontrolsaddons 2.0 as KQuickAddons
11 |
12 | import "../lib" as Lib
13 |
14 | RowLayout {
15 | id: iconField
16 |
17 | default property alias _contentChildren: content.data
18 |
19 | property string configKey: ''
20 | property alias value: textField.text
21 | readonly property string configValue: configKey ? plasmoid.configuration[configKey] : ""
22 | onConfigValueChanged: {
23 | if (!textField.focus && value != configValue) {
24 | value = configValue
25 | }
26 | }
27 | property int previewIconSize: Kirigami.Units.iconSizes.medium
28 | property string defaultValue: ""
29 | property alias placeholderValue: textField.placeholderText
30 | property var presetValues: []
31 |
32 | // Based on org.kde.plasma.kickoff
33 | QQC2.Button {
34 | id: iconButton
35 | padding: Kirigami.Units.smallSpacing
36 | Layout.alignment: Qt.AlignTop
37 |
38 | // KDE QQC2 sets implicitSize to background.implicitSize ignoring padding/inset properties.
39 | implicitWidth: leftPadding + contentItem.implicitWidth + rightPadding
40 | implicitHeight: topPadding + contentItem.implicitHeight + bottomPadding
41 |
42 | onPressed: iconMenu.opened ? iconMenu.close() : iconMenu.open()
43 |
44 | contentItem: PlasmaCore.FrameSvgItem {
45 | id: previewFrame
46 | imagePath: plasmoid.location === PlasmaCore.Types.Vertical || plasmoid.location === PlasmaCore.Types.Horizontal
47 | ? "widgets/panel-background" : "widgets/background"
48 | implicitWidth: fixedMargins.left + previewIconSize + fixedMargins.right
49 | implicitHeight: fixedMargins.top + previewIconSize + fixedMargins.bottom
50 |
51 | Lib.AppletIcon {
52 | anchors.fill: parent
53 | anchors.leftMargin: previewFrame.fixedMargins.left
54 | anchors.topMargin: previewFrame.fixedMargins.top
55 | anchors.rightMargin: previewFrame.fixedMargins.right
56 | anchors.bottomMargin: previewFrame.fixedMargins.bottom
57 | source: iconField.value || iconField.placeholderValue
58 | active: iconButton.hovered
59 | }
60 | }
61 |
62 | QQC2.Menu {
63 | id: iconMenu
64 |
65 | // Appear below the button
66 | y: +parent.height
67 |
68 | QQC2.MenuItem {
69 | text: i18ndc("plasma_applet_org.kde.plasma.kickoff", "@item:inmenu Open icon chooser dialog", "Choose...")
70 | icon.name: "document-open"
71 | onClicked: dialogLoader.active = true
72 | }
73 | QQC2.MenuItem {
74 | text: i18ndc("plasma_applet_org.kde.plasma.kickoff", "@item:inmenu Reset icon to default", "Clear Icon")
75 | icon.name: "edit-clear"
76 | onClicked: iconField.value = iconField.defaultValue
77 | }
78 | }
79 | }
80 |
81 | ColumnLayout {
82 | id: content
83 | Layout.fillWidth: true
84 |
85 | RowLayout {
86 | QQC2.TextField {
87 | id: textField
88 | Layout.fillWidth: true
89 |
90 | text: iconField.configValue
91 | onTextChanged: serializeTimer.restart()
92 |
93 | rightPadding: clearButton.width + Kirigami.Units.smallSpacing
94 |
95 | QQC2.ToolButton {
96 | id: clearButton
97 | visible: iconField.configValue != iconField.defaultValue
98 | icon.name: iconField.defaultValue === "" ? "edit-clear" : "edit-undo"
99 | onClicked: iconField.value = iconField.defaultValue
100 |
101 | anchors.top: parent.top
102 | anchors.right: parent.right
103 | anchors.bottom: parent.bottom
104 |
105 | width: height
106 | }
107 | }
108 |
109 | QQC2.Button {
110 | id: browseButton
111 | icon.name: "document-open"
112 | onClicked: dialogLoader.active = true
113 | }
114 | }
115 |
116 | Flow {
117 | Layout.fillWidth: true
118 | Layout.maximumWidth: Kirigami.Units.gridUnit * 30
119 | Repeater {
120 | model: presetValues
121 | QQC2.Button {
122 | icon.name: modelData
123 | text: modelData
124 | onClicked: iconField.value = modelData
125 | }
126 | }
127 | }
128 | }
129 |
130 | Loader {
131 | id: dialogLoader
132 | active: false
133 | sourceComponent: KQuickAddons.IconDialog {
134 | id: dialog
135 | visible: true
136 | modality: Qt.WindowModal
137 | onIconNameChanged: {
138 | iconField.value = iconName
139 | }
140 | onVisibleChanged: {
141 | if (!visible) {
142 | dialogLoader.active = false
143 | }
144 | }
145 | }
146 | }
147 |
148 | Timer { // throttle
149 | id: serializeTimer
150 | interval: 300
151 | onTriggered: {
152 | if (configKey) {
153 | plasmoid.configuration[configKey] = iconField.value
154 | }
155 | }
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/package/translate/nl.po:
--------------------------------------------------------------------------------
1 | # Translation of presentwindows in nl_NL
2 | # Copyright (C) 2018
3 | # This file is distributed under the same license as the presentwindows package.
4 | # FIRST AUTHOR , YEAR.
5 | #
6 | msgid ""
7 | msgstr ""
8 | "Project-Id-Version: presentwindows\n"
9 | "Report-Msgid-Bugs-To: https://github.com/Zren/plasma-applet-presentwindows\n"
10 | "POT-Creation-Date: 2022-02-23 22:57-0500\n"
11 | "PO-Revision-Date: 2022-02-25 12:30+0100\n"
12 | "Last-Translator: Heimen Stoffels \n"
13 | "Language-Team: Dutch \n"
14 | "Language: nl_NL\n"
15 | "MIME-Version: 1.0\n"
16 | "Content-Type: text/plain; charset=UTF-8\n"
17 | "Content-Transfer-Encoding: 8bit\n"
18 | "Plural-Forms: nplurals=2; plural=(n != 1);\n"
19 | "X-Generator: Poedit 3.0.1\n"
20 |
21 | #: ../metadata.desktop
22 | msgid "Present Windows Button"
23 | msgstr "Vensters presenteren-knop"
24 |
25 | #: ../metadata.desktop
26 | msgid "Trigger the Present Windows desktop effect's shortcut with a click."
27 | msgstr "Toon het vensteroverzicht met één muisklik."
28 |
29 | #: ../contents/config/config.qml
30 | msgid "General"
31 | msgstr "Algemeen"
32 |
33 | #: ../contents/ui/config/ConfigGeneral.qml
34 | msgid "Behavior"
35 | msgstr "Gedrag"
36 |
37 | #: ../contents/ui/config/ConfigGeneral.qml
38 | msgid "Click"
39 | msgstr "Klik"
40 |
41 | #: ../contents/ui/config/ConfigGeneral.qml
42 | msgid "Enable Desktop Effect"
43 | msgstr "Effect inschakelen"
44 |
45 | #: ../contents/ui/config/ConfigGeneral.qml
46 | msgid "Appearance"
47 | msgstr "Vormgeving"
48 |
49 | #: ../contents/ui/config/ConfigGeneral.qml
50 | msgid "Icon"
51 | msgstr "Pictogram"
52 |
53 | #: ../contents/ui/config/ConfigGeneral.qml
54 | msgid "Unity Pager Theme"
55 | msgstr "Unity-thema"
56 |
57 | #: ../contents/ui/config/ConfigGeneral.qml
58 | msgid "Use Unity 7 Theme"
59 | msgstr "Unity 7-thema gebruiken"
60 |
61 | #: ../contents/ui/config/ConfigGeneral.qml
62 | msgid "Never"
63 | msgstr "Nooit"
64 |
65 | #: ../contents/ui/config/ConfigGeneral.qml
66 | msgid "When Plasma Style is Unity Ambiance"
67 | msgstr "Als Plasmastijl is ingesteld op Unity Ambience"
68 |
69 | #: ../contents/ui/config/ConfigGeneral.qml
70 | msgid "Always"
71 | msgstr "Altijd"
72 |
73 | #: ../contents/ui/config/ConfigGeneral.qml
74 | msgid ""
75 | "Should we use a Virtual Desktop indicator similar to Unity 7? This feature "
76 | "is enabled for the Unity "
77 | "Ambiance Plasma Style by default."
78 | msgstr ""
79 | "Moet er een virtuelebureaublad-indicator worden getoond, net zoals in Unity "
80 | "7? Deze functie is standaard ingeschakeld als je gebruikmaakt van de Unity Ambiance-plasmastijl."
82 |
83 | #: ../contents/ui/config/ConfigGeneral.qml
84 | msgid "Current Plasma Style: %1"
85 | msgstr "Huidige Plasma-stijl: %1"
86 |
87 | #: ../contents/ui/Main.qml
88 | msgid "Show Overview"
89 | msgstr "Overzicht tonen"
90 |
91 | #: ../contents/ui/Main.qml
92 | msgid "Present Windows (All desktops)"
93 | msgstr "Vensters presenteren (alle bureaubladen)"
94 |
95 | #: ../contents/ui/Main.qml
96 | msgid "Present Windows (Current desktop)"
97 | msgstr "Vensters presenteren (huidig bureaublad)"
98 |
99 | #: ../contents/ui/Main.qml
100 | msgid "Present Windows (Window class)"
101 | msgstr "Vensters presenteren (vensterklasse)"
102 |
103 | #: ../contents/ui/Main.qml
104 | msgid "Show Desktop Grid"
105 | msgstr "Bureaubladrooster tonen"
106 |
107 | #~ msgid "Present Windows Effect"
108 | #~ msgstr "Effect voor Vensters presenteren"
109 |
110 | #~ msgid ""
111 | #~ "Button will not work when the Present Windows desktop effect is disabled."
112 | #~ msgstr ""
113 | #~ "De knop werkt niet als het bureaubladeffect Vensters presenteren is "
114 | #~ "uitgeschakeld."
115 |
116 | #~ msgid "Show Desktop Grid Effect"
117 | #~ msgstr "Bureaubladraster-effect tonen"
118 |
119 | #~ msgid ""
120 | #~ "Button will not work when the Desktop Grid desktop effect is disabled."
121 | #~ msgstr ""
122 | #~ "De knop werkt niet als het bureaubladeffect Bureaubladraster is "
123 | #~ "uitgeschakeld."
124 |
125 | #~ msgid ""
126 | #~ "Should we use a Virtual Desktop indicator similar to Unity 7? This "
127 | #~ "feature is enabled for the Unity Ambiance desktop theme by default."
129 | #~ msgstr ""
130 | #~ "Moet er een virtuele bureaubladindicator in de stijl van Unity 7 worden "
131 | #~ "gebruikt? Deze functie is standaard ingeschakeld voor het bureaubladthema "
132 | #~ "Unity Ambiance."
133 |
134 | #~ msgid "Current Desktop Theme: %1"
135 | #~ msgstr "Huidig bureaubladthema: %1"
136 |
137 | #~ msgid "Version: %1"
138 | #~ msgstr "Versie: %1"
139 |
140 | #~ msgid "Enabled"
141 | #~ msgstr "Ingeschakeld"
142 |
--------------------------------------------------------------------------------
/package/contents/ui/config/ConfigGeneral.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 | import QtQuick.Controls 1.0
3 | import QtQuick.Controls 2.5 as QQC2
4 | import QtQuick.Layouts 1.0
5 |
6 | import org.kde.plasma.core 2.0 as PlasmaCore
7 | import org.kde.kirigami 2.5 as Kirigami
8 |
9 | import "../lib" as Lib
10 | import "../libconfig" as LibConfig
11 |
12 |
13 | Kirigami.FormLayout {
14 |
15 |
16 | //-------------------------------------------------------
17 | LibConfig.Heading {
18 | text: i18n("Behavior")
19 | useThickTopMargin: false
20 | }
21 | Lib.DesktopEffectToggle {
22 | id: overviewToggle
23 | effectId: 'overview'
24 | }
25 | Lib.DesktopEffectToggle {
26 | id: presentWindowsToggle
27 | effectId: 'presentwindows'
28 | }
29 | Lib.DesktopEffectToggle {
30 | id: showDesktopGridToggle
31 | effectId: 'desktopgrid'
32 | }
33 | LibConfig.RadioButtonGroup {
34 | id: clickCommandGroup
35 | configKey: 'clickCommand'
36 | Kirigami.FormData.label: i18n("Click")
37 | Kirigami.FormData.buddyFor: null // Note: it attaches to the first CheckBox in the Repeater since it loads first.
38 | model: []
39 |
40 | //---
41 | Repeater {
42 | model: [
43 | { value: 'Overview', text: i18nd("kwin_effects", "Toggle Overview"), effectToggle: overviewToggle },
44 | { value: 'ExposeAll', text: i18nd("kwin_effects", "Toggle Present Windows (All desktops)"), effectToggle: presentWindowsToggle },
45 | { value: 'Expose', text: i18nd("kwin_effects", "Toggle Present Windows (Current desktop)"), effectToggle: presentWindowsToggle },
46 | { value: 'ExposeClass', text: i18nd("kwin_effects", "Toggle Present Windows (Window class)"), effectToggle: presentWindowsToggle },
47 | { value: 'ShowDesktopGrid', text: i18nd("kwin_effects", "Toggle Desktop Grid"), effectToggle: showDesktopGridToggle },
48 | ]
49 | RowLayout {
50 | QQC2.RadioButton {
51 | text: modelData.text
52 | enabled: modelData.effectToggle.loaded && modelData.effectToggle.effectEnabled
53 | QQC2.ButtonGroup.group: clickCommandGroup.group
54 | checked: modelData.value === plasmoid.configuration[clickCommandGroup.configKey]
55 | onClicked: {
56 | focus = true
57 | if (clickCommandGroup.configKey) {
58 | plasmoid.configuration[clickCommandGroup.configKey] = modelData.value
59 | }
60 | }
61 | }
62 | QQC2.Button {
63 | visible: modelData.effectToggle.loaded && !modelData.effectToggle.effectEnabled
64 | text: i18n("Enable Desktop Effect")
65 | onClicked: modelData.effectToggle.toggle()
66 | }
67 | }
68 | }
69 |
70 | //---
71 | Lib.KPackageModel {
72 | id: kwinScriptModel
73 | packageType: 'KWin/Script'
74 | }
75 | Repeater {
76 | visible: kwinScriptModel.loaded
77 | model: [
78 | {
79 | pluginId: 'Parachute',
80 | url: 'https://store.kde.org/p/1370195/',
81 | },
82 | ]
83 | RowLayout {
84 | QQC2.RadioButton {
85 | text: modelData.pluginId
86 | enabled: kwinScriptModel.contains(modelData.pluginId)
87 | QQC2.ButtonGroup.group: clickCommandGroup.group
88 | checked: modelData.value === plasmoid.configuration[clickCommandGroup.configKey]
89 | onClicked: {
90 | focus = true
91 | if (clickCommandGroup.configKey) {
92 | plasmoid.configuration[clickCommandGroup.configKey] = modelData.value
93 | }
94 | }
95 | }
96 | LibConfig.Label {
97 | text: '' + modelData.url + ''
98 | }
99 | }
100 | }
101 | }
102 |
103 | //-------------------------------------------------------
104 | LibConfig.Heading {
105 | text: i18n("Appearance")
106 | }
107 |
108 | LibConfig.AppletIconField {
109 | id: iconField
110 | configKey: 'icon'
111 | Kirigami.FormData.label: i18n("Icon")
112 | defaultValue: 'presentwindows-24px'
113 | presetValues: [
114 | 'presentwindows-24px',
115 | 'presentwindows-22px',
116 | 'presentwindows-16px',
117 | 'edit-group',
118 | 'window',
119 | 'view-app-grid-symbolic',
120 | 'homerun',
121 | ]
122 | }
123 |
124 |
125 |
126 | //-------------------------------------------------------
127 | LibConfig.Heading {
128 | text: i18n("Unity Pager Theme")
129 | }
130 |
131 | LibConfig.RadioButtonGroup {
132 | configKey: 'useUnityTheme'
133 | Kirigami.FormData.label: i18n("Use Unity 7 Theme")
134 | model: [
135 | { value: 0, text: i18n("Never") },
136 | { value: 1, text: i18n("When Plasma Style is Unity Ambiance") },
137 | { value: 2, text: i18n("Always") },
138 | ]
139 | }
140 |
141 | LibConfig.Label {
142 | text: i18n("Should we use a Virtual Desktop indicator similar to Unity 7? This feature is enabled for the Unity Ambiance Plasma Style by default.")
143 | }
144 |
145 | Label {
146 | text: i18n("Current Plasma Style: %1", PlasmaCore.Theme.themeName)
147 | }
148 |
149 | }
150 |
--------------------------------------------------------------------------------
/package/contents/icons/unity7selectedworkspace.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
148 |
--------------------------------------------------------------------------------
/package/translate/plasmoidlocaletest:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Version 9
3 | # Requires plasmoidviewer v5.13.0
4 |
5 | function checkIfLangInstalled {
6 | if [ -x "$(command -v dpkg)" ]; then
7 | dpkg -l ${1} >/dev/null 2>&1 || ( \
8 | echo -e "${1} not installed.\nInstalling now before continuing.\n" \
9 | ; sudo apt install ${1} \
10 | ) || ( \
11 | echo -e "\nError trying to install ${1}\nPlease run 'sudo apt install ${1}'\n" \
12 | ; exit 1 \
13 | )
14 | elif [ -x "$(command -v pacman)" ]; then
15 | # TODO: run `locale -a` and check if the locale is enabled.
16 | if false; then
17 | # https://wiki.archlinux.org/index.php/Locale
18 | # Uncomment the locale in /etc/locale.gen
19 | # Then run `locale-gen`
20 | echo -e "\nPlease install this locale in System Settings first.\n"
21 | exit 1
22 | else
23 | echo ""
24 | fi
25 | else
26 | echo -e "\nPackage manager not recognized. If the widget is not translated, please install the package '${1}'\n"
27 | fi
28 | }
29 |
30 | langInput="${1}"
31 | lang=""
32 | languagePack=""
33 |
34 | if [[ "$langInput" =~ ":" ]]; then # String contains a colon so assume it's a locale code.
35 | lang="${langInput}"
36 | IFS=: read -r l1 l2 <<< "${lang}"
37 | languagePack="language-pack-${l2}"
38 | fi
39 |
40 | # https://stackoverflow.com/questions/3191664/list-of-all-locales-and-their-short-codes/28357857#28357857
41 | declare -a langArr=(
42 | "af_ZA:af:Afrikaans (South Africa)"
43 | "ak_GH:ak:Akan (Ghana)"
44 | "am_ET:am:Amharic (Ethiopia)"
45 | "ar_EG:ar:Arabic (Egypt)"
46 | "as_IN:as:Assamese (India)"
47 | "az_AZ:az:Azerbaijani (Azerbaijan)"
48 | "be_BY:be:Belarusian (Belarus)"
49 | "bem_ZM:bem:Bemba (Zambia)"
50 | "bg_BG:bg:Bulgarian (Bulgaria)"
51 | "bo_IN:bo:Tibetan (India)"
52 | "bs_BA:bs:Bosnian (Bosnia and Herzegovina)"
53 | "ca_ES:ca:Catalan (Spain)"
54 | "chr_US:ch:Cherokee (United States)"
55 | "cs_CZ:cs:Czech (Czech Republic)"
56 | "cy_GB:cy:Welsh (United Kingdom)"
57 | "da_DK:da:Danish (Denmark)"
58 | "de_DE:de:German (Germany)"
59 | "el_GR:el:Greek (Greece)"
60 | "es_MX:es:Spanish (Mexico)"
61 | "et_EE:et:Estonian (Estonia)"
62 | "eu_ES:eu:Basque (Spain)"
63 | "fa_IR:fa:Persian (Iran)"
64 | "ff_SN:ff:Fulah (Senegal)"
65 | "fi_FI:fi:Finnish (Finland)"
66 | "fo_FO:fo:Faroese (Faroe Islands)"
67 | "fr_CA:fr:French (Canada)"
68 | "ga_IE:ga:Irish (Ireland)"
69 | "gl_ES:gl:Galician (Spain)"
70 | "gu_IN:gu:Gujarati (India)"
71 | "gv_GB:gv:Manx (United Kingdom)"
72 | "ha_NG:ha:Hausa (Nigeria)"
73 | "he_IL:he:Hebrew (Israel)"
74 | "hi_IN:hi:Hindi (India)"
75 | "hr_HR:hr:Croatian (Croatia)"
76 | "hu_HU:hu:Hungarian (Hungary)"
77 | "hy_AM:hy:Armenian (Armenia)"
78 | "id_ID:id:Indonesian (Indonesia)"
79 | "ig_NG:ig:Igbo (Nigeria)"
80 | "is_IS:is:Icelandic (Iceland)"
81 | "it_IT:it:Italian (Italy)"
82 | "ja_JP:ja:Japanese (Japan)"
83 | "ka_GE:ka:Georgian (Georgia)"
84 | "kk_KZ:kk:Kazakh (Kazakhstan)"
85 | "kl_GL:kl:Kalaallisut (Greenland)"
86 | "km_KH:km:Khmer (Cambodia)"
87 | "kn_IN:kn:Kannada (India)"
88 | "ko_KR:ko:Korean (South Korea)"
89 | "ko_KR:ko:Korean (South Korea)"
90 | "lg_UG:lg:Ganda (Uganda)"
91 | "lt_LT:lt:Lithuanian (Lithuania)"
92 | "lv_LV:lv:Latvian (Latvia)"
93 | "mg_MG:mg:Malagasy (Madagascar)"
94 | "mk_MK:mk:Macedonian (Macedonia)"
95 | "ml_IN:ml:Malayalam (India)"
96 | "mr_IN:mr:Marathi (India)"
97 | "ms_MY:ms:Malay (Malaysia)"
98 | "mt_MT:mt:Maltese (Malta)"
99 | "my_MM:my:Burmese (Myanmar [Burma])"
100 | "nb_NO:nb:Norwegian Bokmål (Norway)"
101 | "ne_NP:ne:Nepali (Nepal)"
102 | "nl_NL:nl:Dutch (Netherlands)"
103 | "nn_NO:nn:Norwegian Nynorsk (Norway)"
104 | "om_ET:om:Oromo (Ethiopia)"
105 | "or_IN:or:Oriya (India)"
106 | "pa_PK:pa:Punjabi (Pakistan)"
107 | "pl_PL:pl:Polish (Poland)"
108 | "ps_AF:ps:Pashto (Afghanistan)"
109 | "pt_BR:pt:Portuguese (Brazil)"
110 | "ro_RO:ro:Romanian (Romania)"
111 | "ru_RU:ru:Russian (Russia)"
112 | "rw_RW:rw:Kinyarwanda (Rwanda)"
113 | "si_LK:si:Sinhala (Sri Lanka)"
114 | "sk_SK:sk:Slovak (Slovakia)"
115 | "sl_SI:sl:Slovenian (Slovenia)"
116 | "so_SO:so:Somali (Somalia)"
117 | "sq_AL:sq:Albanian (Albania)"
118 | "sr_RS:sr:Serbian (Serbia)"
119 | "sv_SE:sv:Swedish (Sweden)"
120 | "sw_KE:sw:Swahili (Kenya)"
121 | "ta_IN:ta:Tamil (India)"
122 | "te_IN:te:Telugu (India)"
123 | "th_TH:th:Thai (Thailand)"
124 | "ti_ER:ti:Tigrinya (Eritrea)"
125 | "to_TO:to:Tonga (Tonga)"
126 | "tr_TR:tr:Turkish (Turkey)"
127 | "uk_UA:uk:Ukrainian (Ukraine)"
128 | "ur_IN:ur:Urdu (India)"
129 | "uz_UZ:uz:Uzbek (Uzbekistan)"
130 | "vi_VN:vi:Vietnamese (Vietnam)"
131 | "yo_NG:yo:Yoruba (Nigeria)"
132 | "yo_NG:yo:Yoruba (Nigeria)"
133 | "yue_HK:yu:Cantonese (Hong Kong)"
134 | "zh_CN:zh:Chinese (China)"
135 | "zu_ZA:zu:Zulu (South Africa)"
136 | )
137 |
138 | for i in "${langArr[@]}"; do
139 | IFS=: read -r l1 l2 l3 <<< "$i"
140 | if [ "$langInput" == "$l2" ]; then
141 | lang="${l1}:${l2}"
142 | languagePack="language-pack-${l2}"
143 | fi
144 | done
145 |
146 | if [ -z "$lang" ]; then
147 | echo "plasmoidlocaletest doesn't recognize the language '$lang'"
148 | echo "Eg:"
149 | scriptcmd='sh ./plasmoidlocaletest'
150 | for i in "${langArr[@]}"; do
151 | IFS=: read -r l1 l2 l3 <<< "$i"
152 | echo " ${scriptcmd} ${l2} | ${l3}"
153 | done
154 | echo ""
155 | echo "Or use a the full locale code:"
156 | echo " ${scriptcmd} ar_EG:ar"
157 | exit 1
158 | fi
159 |
160 | IFS=: read -r l1 l2 <<< "${lang}"
161 | l1="${l1}.UTF-8"
162 |
163 | # Check if language is installed
164 | if [ ! -z "$languagePack" ]; then
165 | if [ "$lang" == "zh_CN:zh" ]; then languagePack="language-pack-zh-hans"
166 | fi
167 |
168 | checkIfLangInstalled "$languagePack" || exit 1
169 | fi
170 |
171 |
172 | echo "LANGUAGE=\"${lang}\""
173 | echo "LANG=\"${l1}\""
174 |
175 | scriptDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
176 | packageDir="${scriptDir}/.."
177 |
178 | # Build local translations for plasmoidviewer
179 | sh "${scriptDir}/build"
180 |
181 | LANGUAGE="${lang}" LANG="${l1}" LC_TIME="${l1}" QML_DISABLE_DISK_CACHE=true plasmoidviewer -a "$packageDir" -l topedge -f horizontal -x 0 -y 0
182 |
--------------------------------------------------------------------------------
/package/translate/merge:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Version: 22
3 |
4 | # https://techbase.kde.org/Development/Tutorials/Localization/i18n_Build_Systems
5 | # https://techbase.kde.org/Development/Tutorials/Localization/i18n_Build_Systems/Outside_KDE_repositories
6 | # https://invent.kde.org/sysadmin/l10n-scripty/-/blob/master/extract-messages.sh
7 |
8 | DIR=`cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd`
9 | plasmoidName=`kreadconfig5 --file="$DIR/../metadata.desktop" --group="Desktop Entry" --key="X-KDE-PluginInfo-Name"`
10 | widgetName="${plasmoidName##*.}" # Strip namespace
11 | website=`kreadconfig5 --file="$DIR/../metadata.desktop" --group="Desktop Entry" --key="X-KDE-PluginInfo-Website"`
12 | bugAddress="$website"
13 | packageRoot=".." # Root of translatable sources
14 | projectName="plasma_applet_${plasmoidName}" # project name
15 |
16 | #---
17 | if [ -z "$plasmoidName" ]; then
18 | echo "[merge] Error: Couldn't read plasmoidName."
19 | exit
20 | fi
21 |
22 | if [ -z "$(which xgettext)" ]; then
23 | echo "[merge] Error: xgettext command not found. Need to install gettext"
24 | echo "[merge] Running 'sudo apt install gettext'"
25 | sudo apt install gettext
26 | echo "[merge] gettext installation should be finished. Going back to merging translations."
27 | fi
28 |
29 | #---
30 | echo "[merge] Extracting messages"
31 | potArgs="--from-code=UTF-8 --width=200 --add-location=file"
32 |
33 | # Note: xgettext v0.20.1 (Kubuntu 20.04) and below will attempt to translate Icon,
34 | # so we need to specify Name, GenericName, Comment, and Keywords.
35 | # https://github.com/Zren/plasma-applet-lib/issues/1
36 | # https://savannah.gnu.org/support/?108887
37 | find "${packageRoot}" -name '*.desktop' | sort > "${DIR}/infiles.list"
38 | xgettext \
39 | ${potArgs} \
40 | --files-from="${DIR}/infiles.list" \
41 | --language=Desktop \
42 | -k -kName -kGenericName -kComment -kKeywords \
43 | -D "${packageRoot}" \
44 | -D "${DIR}" \
45 | -o "template.pot.new" \
46 | || \
47 | { echo "[merge] error while calling xgettext. aborting."; exit 1; }
48 |
49 | sed -i 's/"Content-Type: text\/plain; charset=CHARSET\\n"/"Content-Type: text\/plain; charset=UTF-8\\n"/' "template.pot.new"
50 |
51 | # See Ki18n's extract-messages.sh for a full example:
52 | # https://invent.kde.org/sysadmin/l10n-scripty/-/blob/master/extract-messages.sh#L25
53 | # The -kN_ and -kaliasLocale keywords are mentioned in the Outside_KDE_repositories wiki.
54 | # We don't need -kN_ since we don't use intltool-extract but might as well keep it.
55 | # I have no idea what -kaliasLocale is used for. Googling aliasLocale found only listed kde1 code.
56 | # We don't need to parse -ki18nd since that'll extract messages from other domains.
57 | find "${packageRoot}" -name '*.cpp' -o -name '*.h' -o -name '*.c' -o -name '*.qml' -o -name '*.js' | sort > "${DIR}/infiles.list"
58 | xgettext \
59 | ${potArgs} \
60 | --files-from="${DIR}/infiles.list" \
61 | -C -kde \
62 | -ci18n \
63 | -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 \
64 | -kki18n:1 -kki18nc:1c,2 -kki18np:1,2 -kki18ncp:1c,2,3 \
65 | -kxi18n:1 -kxi18nc:1c,2 -kxi18np:1,2 -kxi18ncp:1c,2,3 \
66 | -kkxi18n:1 -kkxi18nc:1c,2 -kkxi18np:1,2 -kkxi18ncp:1c,2,3 \
67 | -kI18N_NOOP:1 -kI18NC_NOOP:1c,2 \
68 | -kI18N_NOOP2:1c,2 -kI18N_NOOP2_NOSTRIP:1c,2 \
69 | -ktr2i18n:1 -ktr2xi18n:1 \
70 | -kN_:1 \
71 | -kaliasLocale \
72 | --package-name="${widgetName}" \
73 | --msgid-bugs-address="${bugAddress}" \
74 | -D "${packageRoot}" \
75 | -D "${DIR}" \
76 | --join-existing \
77 | -o "template.pot.new" \
78 | || \
79 | { echo "[merge] error while calling xgettext. aborting."; exit 1; }
80 |
81 | sed -i 's/# SOME DESCRIPTIVE TITLE./'"# Translation of ${widgetName} in LANGUAGE"'/' "template.pot.new"
82 | sed -i 's/# Copyright (C) YEAR THE PACKAGE'"'"'S COPYRIGHT HOLDER/'"# Copyright (C) $(date +%Y)"'/' "template.pot.new"
83 |
84 | if [ -f "template.pot" ]; then
85 | newPotDate=`grep "POT-Creation-Date:" template.pot.new | sed 's/.\{3\}$//'`
86 | oldPotDate=`grep "POT-Creation-Date:" template.pot | sed 's/.\{3\}$//'`
87 | sed -i 's/'"${newPotDate}"'/'"${oldPotDate}"'/' "template.pot.new"
88 | changes=`diff "template.pot" "template.pot.new"`
89 | if [ ! -z "$changes" ]; then
90 | # There's been changes
91 | sed -i 's/'"${oldPotDate}"'/'"${newPotDate}"'/' "template.pot.new"
92 | mv "template.pot.new" "template.pot"
93 |
94 | addedKeys=`echo "$changes" | grep "> msgid" | cut -c 9- | sort`
95 | removedKeys=`echo "$changes" | grep "< msgid" | cut -c 9- | sort`
96 | echo ""
97 | echo "Added Keys:"
98 | echo "$addedKeys"
99 | echo ""
100 | echo "Removed Keys:"
101 | echo "$removedKeys"
102 | echo ""
103 |
104 | else
105 | # No changes
106 | rm "template.pot.new"
107 | fi
108 | else
109 | # template.pot didn't already exist
110 | mv "template.pot.new" "template.pot"
111 | fi
112 |
113 | potMessageCount=`expr $(grep -Pzo 'msgstr ""\n(\n|$)' "template.pot" | grep -c 'msgstr ""')`
114 | echo "| Locale | Lines | % Done|" > "./Status.md"
115 | echo "|----------|---------|-------|" >> "./Status.md"
116 | entryFormat="| %-8s | %7s | %5s |"
117 | templateLine=`perl -e "printf(\"$entryFormat\", \"Template\", \"${potMessageCount}\", \"\")"`
118 | echo "$templateLine" >> "./Status.md"
119 |
120 | rm "${DIR}/infiles.list"
121 | echo "[merge] Done extracting messages"
122 |
123 | #---
124 | echo "[merge] Merging messages"
125 | catalogs=`find . -name '*.po' | sort`
126 | for cat in $catalogs; do
127 | echo "[merge] $cat"
128 | catLocale=`basename ${cat%.*}`
129 |
130 | widthArg=""
131 | catUsesGenerator=`grep "X-Generator:" "$cat"`
132 | if [ -z "$catUsesGenerator" ]; then
133 | widthArg="--width=400"
134 | fi
135 |
136 | compendiumArg=""
137 | if [ ! -z "$COMPENDIUM_DIR" ]; then
138 | langCode=`basename "${cat%.*}"`
139 | compendiumPath=`realpath "$COMPENDIUM_DIR/compendium-${langCode}.po"`
140 | if [ -f "$compendiumPath" ]; then
141 | echo "compendiumPath=$compendiumPath"
142 | compendiumArg="--compendium=$compendiumPath"
143 | fi
144 | fi
145 |
146 | cp "$cat" "$cat.new"
147 | sed -i 's/"Content-Type: text\/plain; charset=CHARSET\\n"/"Content-Type: text\/plain; charset=UTF-8\\n"/' "$cat.new"
148 |
149 | msgmerge \
150 | ${widthArg} \
151 | --add-location=file \
152 | --no-fuzzy-matching \
153 | ${compendiumArg} \
154 | -o "$cat.new" \
155 | "$cat.new" "${DIR}/template.pot"
156 |
157 | sed -i 's/# SOME DESCRIPTIVE TITLE./'"# Translation of ${widgetName} in ${catLocale}"'/' "$cat.new"
158 | sed -i 's/# Translation of '"${widgetName}"' in LANGUAGE/'"# Translation of ${widgetName} in ${catLocale}"'/' "$cat.new"
159 | sed -i 's/# Copyright (C) YEAR THE PACKAGE'"'"'S COPYRIGHT HOLDER/'"# Copyright (C) $(date +%Y)"'/' "$cat.new"
160 |
161 | poEmptyMessageCount=`expr $(grep -Pzo 'msgstr ""\n(\n|$)' "$cat.new" | grep -c 'msgstr ""')`
162 | poMessagesDoneCount=`expr $potMessageCount - $poEmptyMessageCount`
163 | poCompletion=`perl -e "printf(\"%d\", $poMessagesDoneCount * 100 / $potMessageCount)"`
164 | poLine=`perl -e "printf(\"$entryFormat\", \"$catLocale\", \"${poMessagesDoneCount}/${potMessageCount}\", \"${poCompletion}%\")"`
165 | echo "$poLine" >> "./Status.md"
166 |
167 | # mv "$cat" "$cat.old"
168 | mv "$cat.new" "$cat"
169 | done
170 | echo "[merge] Done merging messages"
171 |
172 | #---
173 | echo "[merge] Updating .desktop file"
174 |
175 | # Generate LINGUAS for msgfmt
176 | if [ -f "$DIR/LINGUAS" ]; then
177 | rm "$DIR/LINGUAS"
178 | fi
179 | touch "$DIR/LINGUAS"
180 | for cat in $catalogs; do
181 | catLocale=`basename ${cat%.*}`
182 | echo "${catLocale}" >> "$DIR/LINGUAS"
183 | done
184 |
185 | cp -f "$DIR/../metadata.desktop" "$DIR/template.desktop"
186 | sed -i '/^Name\[/ d; /^GenericName\[/ d; /^Comment\[/ d; /^Keywords\[/ d' "$DIR/template.desktop"
187 |
188 | msgfmt \
189 | --desktop \
190 | --template="$DIR/template.desktop" \
191 | -d "$DIR/" \
192 | -o "$DIR/new.desktop"
193 |
194 | # Delete empty msgid messages that used the po header
195 | if [ ! -z "$(grep '^Name=$' "$DIR/new.desktop")" ]; then
196 | echo "[merge] Name in metadata.desktop is empty!"
197 | sed -i '/^Name\[/ d' "$DIR/new.desktop"
198 | fi
199 | if [ ! -z "$(grep '^GenericName=$' "$DIR/new.desktop")" ]; then
200 | echo "[merge] GenericName in metadata.desktop is empty!"
201 | sed -i '/^GenericName\[/ d' "$DIR/new.desktop"
202 | fi
203 | if [ ! -z "$(grep '^Comment=$' "$DIR/new.desktop")" ]; then
204 | echo "[merge] Comment in metadata.desktop is empty!"
205 | sed -i '/^Comment\[/ d' "$DIR/new.desktop"
206 | fi
207 | if [ ! -z "$(grep '^Keywords=$' "$DIR/new.desktop")" ]; then
208 | echo "[merge] Keywords in metadata.desktop is empty!"
209 | sed -i '/^Keywords\[/ d' "$DIR/new.desktop"
210 | fi
211 |
212 | # Place translations at the bottom of the desktop file.
213 | translatedLines=`cat "$DIR/new.desktop" | grep "]="`
214 | if [ ! -z "${translatedLines}" ]; then
215 | sed -i '/^Name\[/ d; /^GenericName\[/ d; /^Comment\[/ d; /^Keywords\[/ d' "$DIR/new.desktop"
216 | if [ "$(tail -c 2 "$DIR/new.desktop" | wc -l)" != "2" ]; then
217 | # Does not end with 2 empty lines, so add an empty line.
218 | echo "" >> "$DIR/new.desktop"
219 | fi
220 | echo "${translatedLines}" >> "$DIR/new.desktop"
221 | fi
222 |
223 | # Cleanup
224 | mv "$DIR/new.desktop" "$DIR/../metadata.desktop"
225 | rm "$DIR/template.desktop"
226 | rm "$DIR/LINGUAS"
227 |
228 | #---
229 | # Populate ReadMe.md
230 | echo "[merge] Updating translate/ReadMe.md"
231 | sed -i -E 's`share\/plasma\/plasmoids\/(.+)\/translate`share/plasma/plasmoids/'"${plasmoidName}"'/translate`' ./ReadMe.md
232 | if [[ "$website" == *"github.com"* ]]; then
233 | sed -i -E 's`\[new issue\]\(https:\/\/github\.com\/(.+)\/(.+)\/issues\/new\)`[new issue]('"${website}"'/issues/new)`' ./ReadMe.md
234 | fi
235 | sed -i '/^|/ d' ./ReadMe.md # Remove status table from ReadMe
236 | cat ./Status.md >> ./ReadMe.md
237 | rm ./Status.md
238 |
239 | echo "[merge] Done"
240 |
--------------------------------------------------------------------------------