From bb9b2534b7d5706b471ae8cd63d0ac1218db68e4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aur=C3=A9lien=20COUDERC?= Date: Tue, 3 Dec 2024 16:36:30 +0100 Subject: [PATCH 1/1] Import libplasma_6.2.4.orig.tar.xz [dgit import orig libplasma_6.2.4.orig.tar.xz] --- .git-blame-ignore-revs | 7 + .gitattributes | 1 + .gitignore | 28 + .gitlab-ci.yml | 8 + .kde-ci.yml | 29 + CMakeLists.txt | 215 + ExtraDesktop.sh | 4 + LICENSES/BSD-3-Clause.txt | 26 + LICENSES/CC0-1.0.txt | 121 + LICENSES/GPL-2.0-only.txt | 319 ++ LICENSES/GPL-2.0-or-later.txt | 319 ++ LICENSES/GPL-3.0-only.txt | 625 +++ LICENSES/LGPL-2.0-or-later.txt | 446 ++ LICENSES/LGPL-2.1-only.txt | 467 ++ LICENSES/LGPL-2.1-or-later.txt | 468 ++ LICENSES/LGPL-3.0-only.txt | 163 + LICENSES/LicenseRef-KDE-Accepted-GPL.txt | 12 + LICENSES/LicenseRef-KDE-Accepted-LGPL.txt | 12 + LICENSES/LicenseRef-Qt-Commercial.txt | 7 + LICENSES/Qt-LGPL-exception-1.1.txt | 21 + PlasmaConfig.cmake.in | 23 + PlasmaMacros.cmake | 30 + README.md | 36 + autotests/CMakeLists.txt | 67 + autotests/TODO | 30 + autotests/coronatest.cpp | 206 + autotests/coronatest.h | 78 + autotests/coronatestresources.qrc | 5 + autotests/data/background.svgz | Bin 0 -> 2879 bytes .../hicolor/22x22/apps/bug359388.svg | 72 + .../22/tst-plasma-framework-test-icon.svg | 72 + .../data/icons/test-theme-two/index.theme | 28 + .../22/tst-plasma-framework-test-icon.svg | 72 + .../32/tst-plasma-framework-test-icon.svg | 763 +++ .../icons/test-theme/apps/48/konversation.svg | 317 ++ autotests/data/icons/test-theme/index.theme | 37 + .../metadata.desktop | 19 + .../data/plasma/desktoptheme/testtheme/colors | 119 + .../plasma/desktoptheme/testtheme/element.svg | 1 + .../desktoptheme/testtheme/metadata.json | 18 + .../desktoptheme/testtheme/opaque/element.svg | 1 + .../plasma/desktoptheme/testtheme/plasmarc | 5 + .../simplecontainment/contents/main.qml | 0 .../simplecontainment/contents/ui/main.qml | 0 .../plasmoids/simplecontainment/metadata.json | 9 + autotests/data/signedPackage/contents.hash | 1 + .../data/signedPackage/contents.hash.sig | Bin 0 -> 72 bytes .../data/signedPackage/contents/code/main.js | 45 + .../data/signedPackage/contents/images/dummy | 0 autotests/data/signedPackage/metadata.json | 96 + autotests/data/test_image.png | Bin 0 -> 1672 bytes autotests/data/test_nonsquare.png | Bin 0 -> 2827 bytes .../contents/config/config.qml | 14 + .../contents/config/main.xml | 17 + .../contents/ui/ConfigGeneral.qml | 11 + .../testconfigpackage/contents/ui/main.qml | 11 + .../data/testconfigpackage/metadata.json | 16 + .../testfallbackpackage/contents/ui/main.qml | 12 + .../data/testfallbackpackage/metadata.json | 50 + autotests/data/testpackage/contents.hash | 1 + .../testpackage/contents/images/empty.png | 0 .../data/testpackage/contents/ui/main.qml | 12 + .../testpackage/contents/ui/otherfile.qml | 12 + autotests/data/testpackage/metadata.json | 54 + autotests/data/view.qml | 10 + autotests/declarativetests/CMakeLists.txt | 10 + autotests/declarativetests/bug485688.qml | 31 + autotests/declarativetests/qmltest.cpp | 35 + autotests/dialognativetest.cpp | 129 + autotests/dialognativetest.h | 37 + autotests/dialogqmltest.cpp | 73 + autotests/dialogqmltest.h | 24 + autotests/dialogstatetest.cpp | 97 + autotests/dialogstatetest.h | 30 + autotests/dummycontainmentaction.cpp | 17 + autotests/dummycontainmentaction.json | 6 + autotests/dynamictreemodel.cpp | 292 ++ autotests/dynamictreemodel.h | 182 + autotests/i18ndcheck.sh | 9 + autotests/input/resizemodeitem.qml | 5 + autotests/plasma-test-appletsrc | 38 + autotests/plasmoidpackagerc | 38 + autotests/plasmoidpackagetest.cpp | 287 ++ autotests/plasmoidpackagetest.h | 42 + autotests/pluginloadertest.cpp | 43 + autotests/pluginloadertest.h | 23 + autotests/quickviewsharedenginetest.cpp | 257 + autotests/sharedqmlenginetest.cpp | 59 + autotests/signed.plasmoid | Bin 0 -> 1540 bytes autotests/signed.plasmoid.invalid.sig | Bin 0 -> 74 bytes autotests/signed.plasmoid.sig | Bin 0 -> 72 bytes autotests/themetest.cpp | 161 + autotests/themetest.h | 30 + autotests/utils.h | 60 + docs/Doxyfile.local | 9 + examples/CMakeLists.txt | 12 + examples/applets/CMakeLists.txt | 9 + .../applets/bugreport/contents/ui/main.qml | 86 + examples/applets/bugreport/metadata.json | 184 + .../contents/ui/main.qml | 65 + .../compactrepresentation/metadata.json | 132 + .../applets/config/contents/config/config.qml | 22 + .../applets/config/contents/config/main.xml | 42 + .../config/contents/ui/configGeneral.qml | 39 + .../config/contents/ui/configOther.qml | 12 + examples/applets/config/contents/ui/main.qml | 100 + examples/applets/config/metadata.json | 129 + .../applets/helloworld/contents/ui/main.qml | 25 + examples/applets/helloworld/metadata.json | 132 + .../applets/notes/contents/config/main.xml | 15 + examples/applets/notes/contents/ui/main.qml | 60 + examples/applets/notes/metadata.json | 140 + .../testcomponents/contents/images/bridge.jpg | Bin 0 -> 17134 bytes .../contents/images/surfboard.jpg | Bin 0 -> 25713 bytes .../contents/ui/ButtonsPage.qml | 64 + .../contents/ui/DialogContent.qml | 51 + .../contents/ui/DialogsPage.qml | 235 + .../testcomponents/contents/ui/DragItem.qml | 46 + .../testcomponents/contents/ui/DragPage.qml | 244 + .../testcomponents/contents/ui/IconsPage.qml | 146 + .../testcomponents/contents/ui/MousePage.qml | 106 + .../contents/ui/PlasmoidPage.qml | 78 + .../testcomponents/contents/ui/TestMenu.qml | 39 + .../testcomponents/contents/ui/ThemePage.qml | 89 + .../testcomponents/contents/ui/main.qml | 121 + examples/applets/testcomponents/metadata.json | 129 + .../testshaders/contents/config/main.xml | 17 + .../contents/images/elarun-small.png | Bin 0 -> 87370 bytes .../testshaders/contents/ui/ColorExample.qml | 30 + .../testshaders/contents/ui/ColorShower.qml | 89 + .../testshaders/contents/ui/EditorPage.qml | 144 + .../testshaders/contents/ui/ShaderExample.qml | 45 + .../testshaders/contents/ui/Shadows.qml | 208 + .../testshaders/contents/ui/SimpleExample.qml | 27 + .../testshaders/contents/ui/WaterEffect.qml | 95 + .../testshaders/contents/ui/WobbleExample.qml | 120 + .../testshaders/contents/ui/config.qml | 17 + .../applets/testshaders/contents/ui/main.qml | 78 + examples/applets/testshaders/metadata.json | 135 + .../widgetgallery/contents/ui/Busy.qml | 124 + .../widgetgallery/contents/ui/Buttons.qml | 171 + .../contents/ui/CheckableButtons.qml | 152 + .../widgetgallery/contents/ui/Menu.qml | 73 + .../widgetgallery/contents/ui/Misc.qml | 643 +++ .../widgetgallery/contents/ui/Scrollers.qml | 150 + .../widgetgallery/contents/ui/Sliders.qml | 168 + .../widgetgallery/contents/ui/Texts.qml | 151 + .../widgetgallery/contents/ui/Typography.qml | 167 + .../widgetgallery/contents/ui/main.qml | 43 + .../contents/ui/standalonemain.qml | 43 + examples/applets/widgetgallery/metadata.json | 138 + .../application/tablet/ui/main.qml | 111 + .../widgetgallery/widgetgallery-tablet | 5 + examples/containments/CMakeLists.txt | 2 + .../contents/ui/PlasmoidContainer.qml | 14 + .../testcontainment/contents/ui/main.qml | 40 + .../testcontainment/metadata.json | 130 + examples/developerguide/CMakeLists.txt | 2 + .../developerguide/basic/contents/ui/main.qml | 82 + examples/developerguide/basic/metadata.json | 140 + examples/shell/CMakeLists.txt | 19 + examples/shell/customcorona.cpp | 76 + examples/shell/customcorona.h | 28 + examples/shell/main.cpp | 37 + .../CMakeLists.txt | 23 + .../testcontainmentactionsplugin/config.ui | 27 + .../plasma-containmentactions-test.json | 109 + .../testcontainmentactionsplugin/test.cpp | 66 + examples/testcontainmentactionsplugin/test.h | 38 + examples/wallpapers/CMakeLists.txt | 2 + .../autumn/contents/config/main.xml | 17 + .../contents/images/backgroundLeaves.jpg | Bin 0 -> 78665 bytes .../autumn/contents/images/realLeaf1.png | Bin 0 -> 15625 bytes .../autumn/contents/images/realLeaf2.png | Bin 0 -> 13660 bytes .../autumn/contents/images/realLeaf3.png | Bin 0 -> 23809 bytes .../autumn/contents/images/realLeaf4.png | Bin 0 -> 23655 bytes .../wallpapers/autumn/contents/ui/config.qml | 29 + .../wallpapers/autumn/contents/ui/main.qml | 135 + examples/wallpapers/autumn/metadata.json | 130 + metainfo.yaml | 16 + po/ar/libplasma6.po | 922 ++++ po/ast/libplasma6.po | 322 ++ po/az/libplasma6.po | 683 +++ po/be/libplasma6.po | 524 ++ po/bg/libplasma6.po | 317 ++ po/bs/libplasma6.po | 1005 ++++ po/ca/libplasma6.po | 325 ++ po/ca@valencia/libplasma6.po | 327 ++ po/cs/libplasma6.po | 314 ++ po/da/libplasma6.po | 971 ++++ po/de/libplasma6.po | 1254 +++++ po/el/libplasma6.po | 950 ++++ po/en_GB/libplasma6.po | 1069 ++++ po/eo/libplasma6.po | 345 ++ po/es/libplasma6.po | 1103 +++++ po/et/libplasma6.po | 959 ++++ po/eu/libplasma6.po | 732 +++ po/fi/libplasma6.po | 1247 +++++ po/fr/libplasma6.po | 1271 +++++ po/gd/libplasma6.po | 959 ++++ po/gl/libplasma6.po | 1072 ++++ po/he/libplasma6.po | 496 ++ po/hu/libplasma6.po | 1082 +++++ po/ia/libplasma6.po | 1072 ++++ po/id/libplasma6.po | 702 +++ po/is/libplasma6.po | 344 ++ po/it/libplasma6.po | 1430 ++++++ po/ja/libplasma6.po | 324 ++ po/ka/libplasma6.po | 572 +++ po/ko/libplasma6.po | 963 ++++ po/lt/libplasma6.po | 967 ++++ po/lv/libplasma6.po | 685 +++ po/ml/libplasma6.po | 678 +++ po/mr/libplasma6.po | 669 +++ po/nb/libplasma6.po | 316 ++ po/nds/libplasma6.po | 1020 ++++ po/nl/libplasma6.po | 1084 +++++ po/nn/libplasma6.po | 338 ++ po/pa/libplasma6.po | 868 ++++ po/pl/libplasma6.po | 1083 +++++ po/pt/libplasma6.po | 577 +++ po/pt_BR/libplasma6.po | 711 +++ po/ro/libplasma6.po | 784 +++ po/ru/libplasma6.po | 1386 ++++++ po/sa/libplasma6.po | 344 ++ po/sk/libplasma6.po | 1072 ++++ po/sl/libplasma6.po | 590 +++ po/sr/libplasma6.po | 762 +++ po/sr@ijekavian/libplasma6.po | 762 +++ po/sr@ijekavianlatin/libplasma6.po | 762 +++ po/sr@latin/libplasma6.po | 762 +++ po/sv/libplasma6.po | 1083 +++++ po/ta/libplasma6.po | 575 +++ po/tg/libplasma6.po | 688 +++ po/tr/libplasma6.po | 350 ++ po/ug/libplasma6.po | 783 +++ po/uk/libplasma6.po | 1085 +++++ po/vi/libplasma6.po | 684 +++ po/zh_CN/libplasma6.po | 318 ++ po/zh_TW/libplasma6.po | 696 +++ src/CMakeLists.txt | 10 + src/Messages.sh | 11 + src/declarativeimports/CMakeLists.txt | 30 + src/declarativeimports/core/CMakeLists.txt | 58 + src/declarativeimports/core/Mainpage.dox | 33 + src/declarativeimports/core/action.cpp | 131 + src/declarativeimports/core/action.h | 101 + .../core/config-x11.h.cmake | 2 + .../core/corebindingsplugin.cpp | 44 + .../core/corebindingsplugin.h | 69 + .../core/private/DefaultToolTip.qml | 75 + .../core/private/DialogBackground.qml | 17 + src/declarativeimports/core/quicktheme.cpp | 232 + src/declarativeimports/core/quicktheme.h | 350 ++ src/declarativeimports/core/tooltiparea.cpp | 402 ++ src/declarativeimports/core/tooltiparea.h | 240 + src/declarativeimports/core/tooltipdialog.cpp | 163 + src/declarativeimports/core/tooltipdialog.h | 70 + .../core/windowthumbnail.cpp | 1014 ++++ src/declarativeimports/core/windowthumbnail.h | 171 + .../AbstractApplicationHeader.qml | 33 + .../kirigamiplasmastyle/CMakeLists.txt | 27 + .../kirigamiplasmastyle/plasmatheme.cpp | 151 + .../kirigamiplasmastyle/plasmatheme.h | 40 + .../kirigamiplasmastyle/plugin.cpp | 33 + .../kirigamiplasmastyle/plugin.h | 30 + .../kirigamiplasmastyle/plugin.json | 1 + .../kirigamiplasmastyle/units.cpp | 53 + .../kirigamiplasmastyle/units.h | 29 + .../plasmacomponents3/AbstractButton.qml | 14 + .../plasmacomponents3/BusyIndicator.qml | 109 + .../plasmacomponents3/Button.qml | 54 + .../plasmacomponents3/CheckBox.qml | 68 + .../plasmacomponents3/CheckDelegate.qml | 65 + .../plasmacomponents3/CheckIndicator.qml | 72 + .../plasmacomponents3/ComboBox.qml | 214 + .../plasmacomponents3/Container.qml | 17 + .../plasmacomponents3/Control.qml | 17 + .../plasmacomponents3/Dial.qml | 94 + .../plasmacomponents3/Dialog.qml | 60 + .../plasmacomponents3/DialogButtonBox.qml | 42 + .../plasmacomponents3/Drawer.qml | 65 + .../plasmacomponents3/Frame.qml | 30 + .../plasmacomponents3/GroupBox.qml | 43 + .../plasmacomponents3/ItemDelegate.qml | 52 + .../plasmacomponents3/Label.qml | 29 + .../plasmacomponents3/Menu.qml | 97 + .../plasmacomponents3/MenuItem.qml | 126 + .../plasmacomponents3/MenuSeparator.qml | 30 + .../plasmacomponents3/Page.qml | 19 + .../plasmacomponents3/PageIndicator.qml | 46 + .../plasmacomponents3/Pane.qml | 17 + .../plasmacomponents3/Popup.qml | 56 + .../plasmacomponents3/ProgressBar.qml | 88 + .../plasmacomponents3/README.md | 7 + .../plasmacomponents3/RadioButton.qml | 68 + .../plasmacomponents3/RadioDelegate.qml | 65 + .../plasmacomponents3/RadioIndicator.qml | 183 + .../plasmacomponents3/RangeSlider.qml | 100 + .../plasmacomponents3/RoundButton.qml | 152 + .../plasmacomponents3/ScrollBar.qml | 113 + .../plasmacomponents3/ScrollView.qml | 60 + .../plasmacomponents3/Slider.qml | 190 + .../plasmacomponents3/SpinBox.qml | 229 + .../plasmacomponents3/SwipeView.qml | 33 + .../plasmacomponents3/Switch.qml | 57 + .../plasmacomponents3/SwitchDelegate.qml | 65 + .../plasmacomponents3/SwitchIndicator.qml | 108 + .../plasmacomponents3/TabBar.qml | 47 + .../plasmacomponents3/TabButton.qml | 99 + .../plasmacomponents3/TextArea.qml | 104 + .../plasmacomponents3/TextField.qml | 230 + .../plasmacomponents3/ToolBar.qml | 43 + .../plasmacomponents3/ToolButton.qml | 59 + .../plasmacomponents3/ToolTip.qml | 120 + .../mobiletextselection/MobileCursor.qml | 63 + .../MobileTextActionsToolBar.qml | 18 + .../MobileTextActionsToolBarImpl.qml | 64 + .../mobiletextselection/qmldir | 2 + .../private/ButtonBackground.qml | 56 + .../private/ButtonContent.qml | 82 + .../plasmacomponents3/private/ButtonFocus.qml | 30 + .../plasmacomponents3/private/ButtonHover.qml | 23 + .../private/ButtonShadow.qml | 33 + .../private/DefaultListItemBackground.qml | 30 + .../private/FlatButtonBackground.qml | 61 + .../plasmacomponents3/private/IconLabel.qml | 100 + .../private/RaisedButtonBackground.qml | 75 + .../plasmacomponents3/private/RoundShadow.qml | 122 + .../private/TextFieldFocus.qml | 97 + .../plasmacomponents3/qmldir | 42 + .../plasmaextracomponents/CMakeLists.txt | 45 + .../plasmaextracomponents/Mainpage.dox | 34 + .../plasmaextracomponents/qmenu.cpp | 571 +++ .../plasmaextracomponents/qmenu.h | 251 + .../plasmaextracomponents/qmenuitem.cpp | 159 + .../plasmaextracomponents/qmenuitem.h | 88 + .../qml/ActionTextField.qml | 175 + .../qml/BasicPlasmoidHeading.qml | 135 + .../qml/DescriptiveLabel.qml | 42 + .../qml/ExpandableListItem.qml | 647 +++ .../plasmaextracomponents/qml/Heading.qml | 97 + .../plasmaextracomponents/qml/Highlight.qml | 98 + .../plasmaextracomponents/qml/ListItem.qml | 82 + .../qml/ListSectionHeader.qml | 94 + .../qml/ModelContextMenu.qml | 71 + .../qml/PasswordField.qml | 66 + .../qml/PlaceholderMessage.qml | 265 + .../qml/PlasmoidHeading.qml | 120 + .../qml/Representation.qml | 60 + .../plasmaextracomponents/qml/SearchField.qml | 80 + .../qml/ShadowedLabel.qml | 74 + .../qml/animations/ActivateAnimation.qml | 24 + .../qml/animations/AppearAnimation.qml | 41 + .../qml/animations/DisappearAnimation.qml | 39 + .../qml/animations/PressedAnimation.qml | 37 + .../qml/animations/ReleasedAnimation.qml | 38 + .../qml/private/BackgroundMetrics.qml | 25 + src/desktoptheme/CMakeLists.txt | 104 + src/desktoptheme/breeze-dark/CMakeLists.txt | 12 + src/desktoptheme/breeze-dark/colors | 123 + .../breeze-dark/metadata.json.cmake | 154 + src/desktoptheme/breeze-dark/plasmarc | 14 + src/desktoptheme/breeze-light/CMakeLists.txt | 11 + src/desktoptheme/breeze-light/colors | 122 + .../breeze-light/metadata.json.cmake | 154 + src/desktoptheme/breeze-light/plasmarc | 14 + src/desktoptheme/breeze/.gitignore | 5 + src/desktoptheme/breeze/CMakeLists.txt | 40 + .../breeze/dialogs/background.svg | 665 +++ src/desktoptheme/breeze/icons/akonadi.svg | 81 + src/desktoptheme/breeze/icons/akregator.svg | 57 + src/desktoptheme/breeze/icons/amarok.svg | 81 + .../breeze/icons/applications.svg | 95 + src/desktoptheme/breeze/icons/apport.svg | 81 + src/desktoptheme/breeze/icons/audio.svg | 140 + src/desktoptheme/breeze/icons/battery.svg | 956 ++++ src/desktoptheme/breeze/icons/bookmarks.svg | 95 + src/desktoptheme/breeze/icons/cantata.svg | 92 + src/desktoptheme/breeze/icons/computer.svg | 161 + src/desktoptheme/breeze/icons/configure.svg | 21 + src/desktoptheme/breeze/icons/device.svg | 83 + src/desktoptheme/breeze/icons/disk.svg | 32 + src/desktoptheme/breeze/icons/distribute.svg | 17 + src/desktoptheme/breeze/icons/document.svg | 168 + src/desktoptheme/breeze/icons/drive.svg | 21 + src/desktoptheme/breeze/icons/edit.svg | 21 + src/desktoptheme/breeze/icons/fcitx.svg | 766 +++ src/desktoptheme/breeze/icons/go.svg | 29 + src/desktoptheme/breeze/icons/ime.svg | 697 +++ src/desktoptheme/breeze/icons/input.svg | 117 + src/desktoptheme/breeze/icons/kalarm.svg | 126 + src/desktoptheme/breeze/icons/kdeconnect.svg | 79 + src/desktoptheme/breeze/icons/keyboard.svg | 99 + src/desktoptheme/breeze/icons/kget.svg | 67 + src/desktoptheme/breeze/icons/kgpg.svg | 14 + src/desktoptheme/breeze/icons/kleopatra.svg | 93 + src/desktoptheme/breeze/icons/klipper.svg | 70 + src/desktoptheme/breeze/icons/kmail.svg | 66 + .../breeze/icons/konv_message.svg | 152 + .../breeze/icons/konversation.svg | 67 + src/desktoptheme/breeze/icons/kopete.svg | 66 + src/desktoptheme/breeze/icons/korgac.svg | 66 + src/desktoptheme/breeze/icons/kpackagekit.svg | 88 + src/desktoptheme/breeze/icons/kruler.svg | 74 + src/desktoptheme/breeze/icons/kteatime.svg | 66 + src/desktoptheme/breeze/icons/ktorrent.svg | 80 + src/desktoptheme/breeze/icons/kup.svg | 13 + src/desktoptheme/breeze/icons/list.svg | 25 + src/desktoptheme/breeze/icons/mail.svg | 95 + src/desktoptheme/breeze/icons/media.svg | 143 + src/desktoptheme/breeze/icons/mobile.svg | 13 + src/desktoptheme/breeze/icons/network.svg | 4327 +++++++++++++++++ .../breeze/icons/notification.svg | 43 + src/desktoptheme/breeze/icons/osd.svg | 1048 ++++ src/desktoptheme/breeze/icons/phone.svg | 258 + src/desktoptheme/breeze/icons/plasmavault.svg | 17 + .../breeze/icons/plasmavault_error.svg | 17 + src/desktoptheme/breeze/icons/preferences.svg | 70 + src/desktoptheme/breeze/icons/printer.svg | 103 + src/desktoptheme/breeze/icons/quassel.svg | 175 + src/desktoptheme/breeze/icons/search.svg | 111 + src/desktoptheme/breeze/icons/slc.svg | 174 + src/desktoptheme/breeze/icons/software.svg | 94 + src/desktoptheme/breeze/icons/start.svg | 89 + src/desktoptheme/breeze/icons/system.svg | 125 + src/desktoptheme/breeze/icons/touchpad.svg | 153 + src/desktoptheme/breeze/icons/user.svg | 78 + src/desktoptheme/breeze/icons/video-card.svg | 50 + src/desktoptheme/breeze/icons/video.svg | 263 + src/desktoptheme/breeze/icons/view.svg | 25 + src/desktoptheme/breeze/icons/vlc.svg | 82 + src/desktoptheme/breeze/icons/wallet.svg | 103 + src/desktoptheme/breeze/icons/window.svg | 35 + src/desktoptheme/breeze/icons/yakuake.svg | 61 + src/desktoptheme/breeze/icons/zoom.svg | 105 + src/desktoptheme/breeze/metadata.json.cmake | 154 + .../breeze/opaque/dialogs/background.svg | 136 + .../opaque/widgets/panel-background.svg | 139 + .../breeze/opaque/widgets/tooltip.svg | 136 + src/desktoptheme/breeze/plasmarc | 13 + .../breeze/solid/dialogs/background.svg | 635 +++ .../breeze/solid/widgets/background.svg | 669 +++ .../breeze/solid/widgets/panel-background.svg | 676 +++ .../breeze/solid/widgets/tooltip.svg | 638 +++ .../breeze/translucent/dialogs/background.svg | 662 +++ .../breeze/translucent/widgets/background.svg | 1422 ++++++ .../translucent/widgets/panel-background.svg | 700 +++ .../breeze/translucent/widgets/tooltip.svg | 662 +++ src/desktoptheme/breeze/widgets/.png | Bin 0 -> 283 bytes .../breeze/widgets/action-overlays.svg | 420 ++ .../breeze/widgets/actionbutton.svg | 491 ++ .../breeze/widgets/analog_meter.svg | 697 +++ src/desktoptheme/breeze/widgets/arrows.svg | 189 + .../breeze/widgets/background.svg | 922 ++++ .../breeze/widgets/bar_meter_horizontal.svg | 457 ++ .../breeze/widgets/bar_meter_vertical.svg | 457 ++ src/desktoptheme/breeze/widgets/branding.svg | 69 + .../breeze/widgets/busywidget.svg | 268 + src/desktoptheme/breeze/widgets/button.svg | 1819 +++++++ src/desktoptheme/breeze/widgets/calendar.svg | 128 + .../breeze/widgets/checkmarks.svg | 23 + src/desktoptheme/breeze/widgets/clock.svg | 856 ++++ .../breeze/widgets/configuration-icons.svg | 715 +++ .../breeze/widgets/containment-controls.svg | 672 +++ src/desktoptheme/breeze/widgets/dragger.svg | 301 ++ src/desktoptheme/breeze/widgets/frame.svg | 879 ++++ src/desktoptheme/breeze/widgets/glowbar.svg | 48 + src/desktoptheme/breeze/widgets/line.svg | 43 + src/desktoptheme/breeze/widgets/lineedit.svg | 835 ++++ src/desktoptheme/breeze/widgets/listitem.svg | 870 ++++ .../breeze/widgets/margins-highlight.svg | 315 ++ .../breeze/widgets/media-delegate.svg | 531 ++ .../breeze/widgets/menubaritem.svg | 114 + src/desktoptheme/breeze/widgets/monitor.svg | 2910 +++++++++++ src/desktoptheme/breeze/widgets/notes.svg | 3095 ++++++++++++ src/desktoptheme/breeze/widgets/pager.svg | 727 +++ .../breeze/widgets/panel-background.svg | 700 +++ src/desktoptheme/breeze/widgets/picker.svg | 548 +++ .../breeze/widgets/plasmoidheading.svg | 273 ++ .../breeze/widgets/plot-background.svg | 99 + .../breeze/widgets/radiobutton.svg | 190 + src/desktoptheme/breeze/widgets/scrollbar.svg | 996 ++++ .../breeze/widgets/scrollwidget.svg | 226 + src/desktoptheme/breeze/widgets/slider.svg | 662 +++ src/desktoptheme/breeze/widgets/switch.svg | 487 ++ src/desktoptheme/breeze/widgets/tabbar.svg | 139 + src/desktoptheme/breeze/widgets/tasks.svg | 981 ++++ src/desktoptheme/breeze/widgets/toolbar.svg | 29 + src/desktoptheme/breeze/widgets/tooltip.svg | 662 +++ .../breeze/widgets/translucentbackground.svg | 215 + src/desktoptheme/breeze/widgets/viewitem.svg | 706 +++ src/desktoptheme/oxygen/metadata.json.cmake | 152 + src/plasma/.krazy | 2 + src/plasma/CMakeLists.txt | 161 + src/plasma/Mainpage.dox | 81 + src/plasma/README | 29 + src/plasma/applet.cpp | 890 ++++ src/plasma/applet.h | 925 ++++ src/plasma/config-plasma.h.cmake | 5 + src/plasma/containment.cpp | 685 +++ src/plasma/containment.h | 496 ++ src/plasma/containmentactions.cpp | 147 + src/plasma/containmentactions.h | 140 + src/plasma/corona.cpp | 716 +++ src/plasma/corona.h | 394 ++ .../kconfigxt/libplasma-theme-global.kcfg | 19 + .../kconfigxt/libplasma-theme-global.kcfgc | 4 + src/plasma/packagestructure/CMakeLists.txt | 21 + src/plasma/packagestructure/packages.cpp | 59 + src/plasma/packagestructure/packages_p.h | 25 + .../plasma_applet_packagestructure.cpp | 50 + .../plasma_applet_packagestructure.json | 4 + ...ma_containmentactions_packagestructure.cpp | 27 + ...a_containmentactions_packagestructure.json | 4 + .../plasma_generic_packagestructure.cpp | 11 + .../plasma_generic_packagestructure.json | 4 + .../plasma_theme_packagestructure.cpp | 75 + .../plasma_theme_packagestructure.json | 4 + .../plasma-packagestructure-wallpaper.json | 4 + .../qmlWallpaper/wallpaper.cpp | 58 + .../plasma-packagestructure-plasma-shell.json | 4 + .../packagestructure/shell/shellpackage.cpp | 89 + src/plasma/plasma.cpp | 28 + src/plasma/plasma.h | 148 + src/plasma/pluginloader.cpp | 249 + src/plasma/pluginloader.h | 146 + src/plasma/private/applet_p.cpp | 544 +++ src/plasma/private/applet_p.h | 125 + src/plasma/private/containment_p.cpp | 257 + src/plasma/private/containment_p.h | 95 + src/plasma/private/containmentactions_p.h | 28 + src/plasma/private/corona_p.h | 51 + src/plasma/private/effectwatcher.cpp | 93 + src/plasma/private/effectwatcher_p.h | 42 + src/plasma/private/theme_p.cpp | 704 +++ src/plasma/private/theme_p.h | 150 + src/plasma/theme.cpp | 349 ++ src/plasma/theme.h | 320 ++ src/plasmaquick/CMakeLists.txt | 179 + src/plasmaquick/Mainpage.dox | 26 + src/plasmaquick/PlasmaQuickConfig.cmake.in | 16 + src/plasmaquick/appletcontext.cpp | 53 + src/plasmaquick/appletcontext_p.h | 37 + src/plasmaquick/appletpopup.cpp | 348 ++ src/plasmaquick/appletpopup.h | 74 + src/plasmaquick/appletquickitem.cpp | 961 ++++ src/plasmaquick/appletquickitem.h | 176 + src/plasmaquick/appletquickitem_p.h | 125 + src/plasmaquick/configcategory_p.cpp | 117 + src/plasmaquick/configcategory_p.h | 79 + src/plasmaquick/configmodel.cpp | 349 ++ src/plasmaquick/configmodel.h | 125 + src/plasmaquick/configview.cpp | 407 ++ src/plasmaquick/configview.h | 88 + src/plasmaquick/containmentview.cpp | 295 ++ src/plasmaquick/containmentview.h | 127 + src/plasmaquick/dialog.cpp | 1651 +++++++ src/plasmaquick/dialog.h | 281 ++ src/plasmaquick/dialogbackground_p.cpp | 99 + src/plasmaquick/dialogbackground_p.h | 67 + src/plasmaquick/dialogshadows.cpp | 271 ++ src/plasmaquick/dialogshadows_p.h | 40 + src/plasmaquick/edgeeventforwarder.cpp | 183 + src/plasmaquick/edgeeventforwarder.h | 57 + .../plasmashellwaylandintegration.cpp | 212 + .../plasmashellwaylandintegration.h | 60 + src/plasmaquick/plasmawindow.cpp | 246 + src/plasmaquick/plasmawindow.h | 104 + src/plasmaquick/plasmoid/containmentitem.cpp | 1110 +++++ src/plasmaquick/plasmoid/containmentitem.h | 154 + src/plasmaquick/plasmoid/dropmenu.cpp | 106 + src/plasmaquick/plasmoid/dropmenu.h | 52 + src/plasmaquick/plasmoid/plasmoiditem.cpp | 453 ++ src/plasmaquick/plasmoid/plasmoiditem.h | 199 + src/plasmaquick/plasmoid/wallpaperitem.cpp | 274 ++ src/plasmaquick/plasmoid/wallpaperitem.h | 127 + src/plasmaquick/plasmoidattached_p.cpp | 68 + src/plasmaquick/plasmoidattached_p.h | 73 + src/plasmaquick/popupplasmawindow.cpp | 388 ++ src/plasmaquick/popupplasmawindow.h | 114 + src/plasmaquick/quickviewsharedengine.cpp | 244 + src/plasmaquick/quickviewsharedengine.h | 101 + src/plasmaquick/sharedqmlengine.cpp | 312 ++ src/plasmaquick/sharedqmlengine.h | 201 + src/plasmaquick/transientplacementhint.cpp | 285 ++ src/plasmaquick/transientplacementhint_p.h | 49 + src/plasmaquick/utils.cpp | 21 + src/plasmaquick/utils.h | 13 + src/plasmaquick/windowresizehandler.cpp | 189 + src/plasmaquick/windowresizehandler.h | 46 + src/tools/apply-stylesheet.sh | 287 ++ src/tools/currentColorFillFix.sh | 23 + .../inkscape extensions/plasmarename.inx | 16 + src/tools/inkscape extensions/plasmarename.py | 85 + templates/.clang-format | 2 + templates/CMakeLists.txt | 9 + templates/cpp-plasmoid6/CMakeLists.txt | 28 + .../LICENSES/LGPL-2.1-or-later.txt | 468 ++ templates/cpp-plasmoid6/Messages.sh | 2 + templates/cpp-plasmoid6/README | 46 + .../cpp-plasmoid6/cpp-plasmoid6.kdevtemplate | 90 + templates/cpp-plasmoid6/cpp-plasmoid6.png | Bin 0 -> 35613 bytes templates/cpp-plasmoid6/src/%{APPNAMELC}.cpp | 28 + templates/cpp-plasmoid6/src/%{APPNAMELC}.h | 26 + templates/cpp-plasmoid6/src/CMakeLists.txt | 14 + .../src/package/contents/images/pairs.svg | 1911 ++++++++ .../src/package/contents/ui/main.qml | 25 + .../cpp-plasmoid6/src/package/metadata.json | 152 + .../CMakeLists.txt | 31 + .../LICENSES/LGPL-2.1-or-later.txt | 468 ++ .../Messages.sh | 2 + .../README | 41 + .../package/contents/config/main.xml | 15 + .../package/contents/ui/config.qml | 39 + .../package/contents/ui/main.qml | 36 + .../package/metadata.json | 109 + ...-wallpaper-with-qml-extension.kdevtemplate | 86 + .../plugin/%{APPNAMELC}plugin.cpp | 32 + .../plugin/%{APPNAMELC}plugin.h | 20 + .../plugin/CMakeLists.txt | 11 + .../plugin/qmldir | 2 + templates/plasma6-wallpaper/CMakeLists.txt | 11 + .../LICENSES/LGPL-2.1-or-later.txt | 468 ++ templates/plasma6-wallpaper/Messages.sh | 2 + templates/plasma6-wallpaper/README | 41 + .../package/contents/config/main.xml | 15 + .../package/contents/ui/config.qml | 39 + .../package/contents/ui/main.qml | 24 + .../plasma6-wallpaper/package/metadata.json | 109 + .../plasma6-wallpaper.kdevtemplate | 93 + .../CMakeLists.txt | 31 + .../LICENSES/LGPL-2.1-or-later.txt | 468 ++ .../Messages.sh | 2 + .../qml-plasmoid6-with-qml-extension/README | 46 + .../package/contents/ui/main.qml | 21 + .../package/metadata.json | 153 + .../plugin/%{APPNAMELC}plugin.cpp | 32 + .../plugin/%{APPNAMELC}plugin.h | 20 + .../plugin/CMakeLists.txt | 11 + .../plugin/qmldir | 2 + ...-plasmoid6-with-qml-extension.kdevtemplate | 89 + .../qml-plasmoid6-with-qml-extension.png | Bin 0 -> 35613 bytes templates/qml-plasmoid6/CMakeLists.txt | 11 + .../LICENSES/LGPL-2.1-or-later.txt | 468 ++ templates/qml-plasmoid6/Messages.sh | 2 + templates/qml-plasmoid6/README | 46 + .../package/contents/images/pairs.svgz | Bin 0 -> 103064 bytes .../package/contents/ui/main.qml | 25 + templates/qml-plasmoid6/package/metadata.json | 153 + .../qml-plasmoid6/qml-plasmoid6.kdevtemplate | 91 + templates/qml-plasmoid6/qml-plasmoid6.png | Bin 0 -> 35613 bytes tests/CMakeLists.txt | 1 + tests/buttons_pc3.0.qml | 32 + tests/components/ComponentBase.qml | 38 + tests/components/busyindicator3.qml | 56 + tests/components/button3.qml | 245 + tests/components/checkbox3.qml | 84 + tests/components/combobox3.qml | 33 + tests/components/menu-placement.qml | 93 + tests/components/menu.qml | 122 + tests/components/progressbar3.qml | 199 + tests/components/radiobutton3.qml | 61 + tests/components/roundbutton3.qml | 267 + tests/components/slider3.qml | 73 + tests/components/tabbar3.qml | 38 + tests/components/textarea3.qml | 42 + tests/components/textfield3.qml | 37 + tests/components/toolbutton3.qml | 127 + tests/dialog.qml | 25 + tests/dialog_fullscreen.qml | 46 + tests/dialog_minWidthHeightRepositioning.qml | 62 + tests/dialog_positioning.qml | 104 + tests/dialog_positioning2.qml | 76 + tests/dialog_positioning_parentrotated.qml | 80 + tests/dialog_resizeWithParent.qml | 63 + tests/dialog_sizeMoreThanMin.qml | 58 + tests/dialog_tooltip.qml | 67 + tests/dialog_visualParentChange.qml | 107 + tests/dpi/CMakeLists.txt | 7 + tests/dpi/dpitest.cpp | 50 + tests/dpi/dpitest.h | 36 + tests/dpi/main.cpp | 34 + tests/extras/expandablelistitem.qml | 66 + tests/frames.qml | 40 + tests/selected_svg.qml | 42 + tests/shadows.qml | 44 + tests/testborders.qml | 93 + tests/tooltip-icons.qml | 33 + tests/tooltip.qml | 154 + tests/window.qml | 110 + 691 files changed, 148691 insertions(+) create mode 100644 .git-blame-ignore-revs create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 .kde-ci.yml create mode 100644 CMakeLists.txt create mode 100644 ExtraDesktop.sh create mode 100644 LICENSES/BSD-3-Clause.txt create mode 100644 LICENSES/CC0-1.0.txt create mode 100644 LICENSES/GPL-2.0-only.txt create mode 100644 LICENSES/GPL-2.0-or-later.txt create mode 100644 LICENSES/GPL-3.0-only.txt create mode 100644 LICENSES/LGPL-2.0-or-later.txt create mode 100644 LICENSES/LGPL-2.1-only.txt create mode 100644 LICENSES/LGPL-2.1-or-later.txt create mode 100644 LICENSES/LGPL-3.0-only.txt create mode 100644 LICENSES/LicenseRef-KDE-Accepted-GPL.txt create mode 100644 LICENSES/LicenseRef-KDE-Accepted-LGPL.txt create mode 100644 LICENSES/LicenseRef-Qt-Commercial.txt create mode 100644 LICENSES/Qt-LGPL-exception-1.1.txt create mode 100644 PlasmaConfig.cmake.in create mode 100644 PlasmaMacros.cmake create mode 100644 README.md create mode 100644 autotests/CMakeLists.txt create mode 100644 autotests/TODO create mode 100644 autotests/coronatest.cpp create mode 100644 autotests/coronatest.h create mode 100644 autotests/coronatestresources.qrc create mode 100644 autotests/data/background.svgz create mode 100644 autotests/data/bug359388/hicolor/22x22/apps/bug359388.svg create mode 100644 autotests/data/icons/test-theme-two/apps/22/tst-plasma-framework-test-icon.svg create mode 100644 autotests/data/icons/test-theme-two/index.theme create mode 100644 autotests/data/icons/test-theme/apps/22/tst-plasma-framework-test-icon.svg create mode 100644 autotests/data/icons/test-theme/apps/32/tst-plasma-framework-test-icon.svg create mode 100644 autotests/data/icons/test-theme/apps/48/konversation.svg create mode 100644 autotests/data/icons/test-theme/index.theme create mode 100644 autotests/data/plasma/desktoptheme/test_old_metadata_format_theme/metadata.desktop create mode 100644 autotests/data/plasma/desktoptheme/testtheme/colors create mode 100644 autotests/data/plasma/desktoptheme/testtheme/element.svg create mode 100644 autotests/data/plasma/desktoptheme/testtheme/metadata.json create mode 100644 autotests/data/plasma/desktoptheme/testtheme/opaque/element.svg create mode 100644 autotests/data/plasma/desktoptheme/testtheme/plasmarc create mode 100644 autotests/data/plasma/plasmoids/simplecontainment/contents/main.qml create mode 100644 autotests/data/plasma/plasmoids/simplecontainment/contents/ui/main.qml create mode 100644 autotests/data/plasma/plasmoids/simplecontainment/metadata.json create mode 100644 autotests/data/signedPackage/contents.hash create mode 100644 autotests/data/signedPackage/contents.hash.sig create mode 100644 autotests/data/signedPackage/contents/code/main.js create mode 100644 autotests/data/signedPackage/contents/images/dummy create mode 100644 autotests/data/signedPackage/metadata.json create mode 100644 autotests/data/test_image.png create mode 100644 autotests/data/test_nonsquare.png create mode 100644 autotests/data/testconfigpackage/contents/config/config.qml create mode 100644 autotests/data/testconfigpackage/contents/config/main.xml create mode 100644 autotests/data/testconfigpackage/contents/ui/ConfigGeneral.qml create mode 100644 autotests/data/testconfigpackage/contents/ui/main.qml create mode 100644 autotests/data/testconfigpackage/metadata.json create mode 100644 autotests/data/testfallbackpackage/contents/ui/main.qml create mode 100644 autotests/data/testfallbackpackage/metadata.json create mode 100644 autotests/data/testpackage/contents.hash create mode 100644 autotests/data/testpackage/contents/images/empty.png create mode 100644 autotests/data/testpackage/contents/ui/main.qml create mode 100644 autotests/data/testpackage/contents/ui/otherfile.qml create mode 100644 autotests/data/testpackage/metadata.json create mode 100644 autotests/data/view.qml create mode 100644 autotests/declarativetests/CMakeLists.txt create mode 100644 autotests/declarativetests/bug485688.qml create mode 100644 autotests/declarativetests/qmltest.cpp create mode 100644 autotests/dialognativetest.cpp create mode 100644 autotests/dialognativetest.h create mode 100644 autotests/dialogqmltest.cpp create mode 100644 autotests/dialogqmltest.h create mode 100644 autotests/dialogstatetest.cpp create mode 100644 autotests/dialogstatetest.h create mode 100644 autotests/dummycontainmentaction.cpp create mode 100644 autotests/dummycontainmentaction.json create mode 100644 autotests/dynamictreemodel.cpp create mode 100644 autotests/dynamictreemodel.h create mode 100644 autotests/i18ndcheck.sh create mode 100644 autotests/input/resizemodeitem.qml create mode 100644 autotests/plasma-test-appletsrc create mode 100644 autotests/plasmoidpackagerc create mode 100644 autotests/plasmoidpackagetest.cpp create mode 100644 autotests/plasmoidpackagetest.h create mode 100644 autotests/pluginloadertest.cpp create mode 100644 autotests/pluginloadertest.h create mode 100644 autotests/quickviewsharedenginetest.cpp create mode 100644 autotests/sharedqmlenginetest.cpp create mode 100644 autotests/signed.plasmoid create mode 100644 autotests/signed.plasmoid.invalid.sig create mode 100644 autotests/signed.plasmoid.sig create mode 100644 autotests/themetest.cpp create mode 100644 autotests/themetest.h create mode 100644 autotests/utils.h create mode 100644 docs/Doxyfile.local create mode 100644 examples/CMakeLists.txt create mode 100644 examples/applets/CMakeLists.txt create mode 100644 examples/applets/bugreport/contents/ui/main.qml create mode 100644 examples/applets/bugreport/metadata.json create mode 100644 examples/applets/compactrepresentation/contents/ui/main.qml create mode 100644 examples/applets/compactrepresentation/metadata.json create mode 100644 examples/applets/config/contents/config/config.qml create mode 100644 examples/applets/config/contents/config/main.xml create mode 100644 examples/applets/config/contents/ui/configGeneral.qml create mode 100644 examples/applets/config/contents/ui/configOther.qml create mode 100644 examples/applets/config/contents/ui/main.qml create mode 100644 examples/applets/config/metadata.json create mode 100644 examples/applets/helloworld/contents/ui/main.qml create mode 100644 examples/applets/helloworld/metadata.json create mode 100644 examples/applets/notes/contents/config/main.xml create mode 100644 examples/applets/notes/contents/ui/main.qml create mode 100644 examples/applets/notes/metadata.json create mode 100644 examples/applets/testcomponents/contents/images/bridge.jpg create mode 100644 examples/applets/testcomponents/contents/images/surfboard.jpg create mode 100644 examples/applets/testcomponents/contents/ui/ButtonsPage.qml create mode 100644 examples/applets/testcomponents/contents/ui/DialogContent.qml create mode 100644 examples/applets/testcomponents/contents/ui/DialogsPage.qml create mode 100644 examples/applets/testcomponents/contents/ui/DragItem.qml create mode 100644 examples/applets/testcomponents/contents/ui/DragPage.qml create mode 100644 examples/applets/testcomponents/contents/ui/IconsPage.qml create mode 100644 examples/applets/testcomponents/contents/ui/MousePage.qml create mode 100644 examples/applets/testcomponents/contents/ui/PlasmoidPage.qml create mode 100644 examples/applets/testcomponents/contents/ui/TestMenu.qml create mode 100644 examples/applets/testcomponents/contents/ui/ThemePage.qml create mode 100644 examples/applets/testcomponents/contents/ui/main.qml create mode 100644 examples/applets/testcomponents/metadata.json create mode 100644 examples/applets/testshaders/contents/config/main.xml create mode 100644 examples/applets/testshaders/contents/images/elarun-small.png create mode 100644 examples/applets/testshaders/contents/ui/ColorExample.qml create mode 100644 examples/applets/testshaders/contents/ui/ColorShower.qml create mode 100644 examples/applets/testshaders/contents/ui/EditorPage.qml create mode 100644 examples/applets/testshaders/contents/ui/ShaderExample.qml create mode 100644 examples/applets/testshaders/contents/ui/Shadows.qml create mode 100644 examples/applets/testshaders/contents/ui/SimpleExample.qml create mode 100644 examples/applets/testshaders/contents/ui/WaterEffect.qml create mode 100644 examples/applets/testshaders/contents/ui/WobbleExample.qml create mode 100644 examples/applets/testshaders/contents/ui/config.qml create mode 100644 examples/applets/testshaders/contents/ui/main.qml create mode 100644 examples/applets/testshaders/metadata.json create mode 100644 examples/applets/widgetgallery/contents/ui/Busy.qml create mode 100644 examples/applets/widgetgallery/contents/ui/Buttons.qml create mode 100644 examples/applets/widgetgallery/contents/ui/CheckableButtons.qml create mode 100644 examples/applets/widgetgallery/contents/ui/Menu.qml create mode 100644 examples/applets/widgetgallery/contents/ui/Misc.qml create mode 100644 examples/applets/widgetgallery/contents/ui/Scrollers.qml create mode 100644 examples/applets/widgetgallery/contents/ui/Sliders.qml create mode 100644 examples/applets/widgetgallery/contents/ui/Texts.qml create mode 100644 examples/applets/widgetgallery/contents/ui/Typography.qml create mode 100644 examples/applets/widgetgallery/contents/ui/main.qml create mode 100644 examples/applets/widgetgallery/contents/ui/standalonemain.qml create mode 100644 examples/applets/widgetgallery/metadata.json create mode 100644 examples/applets/widgetgallery/platformcontents/application/tablet/ui/main.qml create mode 100755 examples/applets/widgetgallery/widgetgallery-tablet create mode 100644 examples/containments/CMakeLists.txt create mode 100644 examples/containments/testcontainment/contents/ui/PlasmoidContainer.qml create mode 100644 examples/containments/testcontainment/contents/ui/main.qml create mode 100644 examples/containments/testcontainment/metadata.json create mode 100644 examples/developerguide/CMakeLists.txt create mode 100644 examples/developerguide/basic/contents/ui/main.qml create mode 100644 examples/developerguide/basic/metadata.json create mode 100644 examples/shell/CMakeLists.txt create mode 100644 examples/shell/customcorona.cpp create mode 100644 examples/shell/customcorona.h create mode 100644 examples/shell/main.cpp create mode 100644 examples/testcontainmentactionsplugin/CMakeLists.txt create mode 100644 examples/testcontainmentactionsplugin/config.ui create mode 100644 examples/testcontainmentactionsplugin/plasma-containmentactions-test.json create mode 100644 examples/testcontainmentactionsplugin/test.cpp create mode 100644 examples/testcontainmentactionsplugin/test.h create mode 100644 examples/wallpapers/CMakeLists.txt create mode 100644 examples/wallpapers/autumn/contents/config/main.xml create mode 100644 examples/wallpapers/autumn/contents/images/backgroundLeaves.jpg create mode 100644 examples/wallpapers/autumn/contents/images/realLeaf1.png create mode 100644 examples/wallpapers/autumn/contents/images/realLeaf2.png create mode 100644 examples/wallpapers/autumn/contents/images/realLeaf3.png create mode 100644 examples/wallpapers/autumn/contents/images/realLeaf4.png create mode 100644 examples/wallpapers/autumn/contents/ui/config.qml create mode 100644 examples/wallpapers/autumn/contents/ui/main.qml create mode 100644 examples/wallpapers/autumn/metadata.json create mode 100644 metainfo.yaml create mode 100644 po/ar/libplasma6.po create mode 100644 po/ast/libplasma6.po create mode 100644 po/az/libplasma6.po create mode 100644 po/be/libplasma6.po create mode 100644 po/bg/libplasma6.po create mode 100644 po/bs/libplasma6.po create mode 100644 po/ca/libplasma6.po create mode 100644 po/ca@valencia/libplasma6.po create mode 100644 po/cs/libplasma6.po create mode 100644 po/da/libplasma6.po create mode 100644 po/de/libplasma6.po create mode 100644 po/el/libplasma6.po create mode 100644 po/en_GB/libplasma6.po create mode 100644 po/eo/libplasma6.po create mode 100644 po/es/libplasma6.po create mode 100644 po/et/libplasma6.po create mode 100644 po/eu/libplasma6.po create mode 100644 po/fi/libplasma6.po create mode 100644 po/fr/libplasma6.po create mode 100644 po/gd/libplasma6.po create mode 100644 po/gl/libplasma6.po create mode 100644 po/he/libplasma6.po create mode 100644 po/hu/libplasma6.po create mode 100644 po/ia/libplasma6.po create mode 100644 po/id/libplasma6.po create mode 100644 po/is/libplasma6.po create mode 100644 po/it/libplasma6.po create mode 100644 po/ja/libplasma6.po create mode 100644 po/ka/libplasma6.po create mode 100644 po/ko/libplasma6.po create mode 100644 po/lt/libplasma6.po create mode 100644 po/lv/libplasma6.po create mode 100644 po/ml/libplasma6.po create mode 100644 po/mr/libplasma6.po create mode 100644 po/nb/libplasma6.po create mode 100644 po/nds/libplasma6.po create mode 100644 po/nl/libplasma6.po create mode 100644 po/nn/libplasma6.po create mode 100644 po/pa/libplasma6.po create mode 100644 po/pl/libplasma6.po create mode 100644 po/pt/libplasma6.po create mode 100644 po/pt_BR/libplasma6.po create mode 100644 po/ro/libplasma6.po create mode 100644 po/ru/libplasma6.po create mode 100644 po/sa/libplasma6.po create mode 100644 po/sk/libplasma6.po create mode 100644 po/sl/libplasma6.po create mode 100644 po/sr/libplasma6.po create mode 100644 po/sr@ijekavian/libplasma6.po create mode 100644 po/sr@ijekavianlatin/libplasma6.po create mode 100644 po/sr@latin/libplasma6.po create mode 100644 po/sv/libplasma6.po create mode 100644 po/ta/libplasma6.po create mode 100644 po/tg/libplasma6.po create mode 100644 po/tr/libplasma6.po create mode 100644 po/ug/libplasma6.po create mode 100644 po/uk/libplasma6.po create mode 100644 po/vi/libplasma6.po create mode 100644 po/zh_CN/libplasma6.po create mode 100644 po/zh_TW/libplasma6.po create mode 100644 src/CMakeLists.txt create mode 100644 src/Messages.sh create mode 100644 src/declarativeimports/CMakeLists.txt create mode 100644 src/declarativeimports/core/CMakeLists.txt create mode 100644 src/declarativeimports/core/Mainpage.dox create mode 100644 src/declarativeimports/core/action.cpp create mode 100644 src/declarativeimports/core/action.h create mode 100644 src/declarativeimports/core/config-x11.h.cmake create mode 100644 src/declarativeimports/core/corebindingsplugin.cpp create mode 100644 src/declarativeimports/core/corebindingsplugin.h create mode 100644 src/declarativeimports/core/private/DefaultToolTip.qml create mode 100644 src/declarativeimports/core/private/DialogBackground.qml create mode 100644 src/declarativeimports/core/quicktheme.cpp create mode 100644 src/declarativeimports/core/quicktheme.h create mode 100644 src/declarativeimports/core/tooltiparea.cpp create mode 100644 src/declarativeimports/core/tooltiparea.h create mode 100644 src/declarativeimports/core/tooltipdialog.cpp create mode 100644 src/declarativeimports/core/tooltipdialog.h create mode 100644 src/declarativeimports/core/windowthumbnail.cpp create mode 100644 src/declarativeimports/core/windowthumbnail.h create mode 100644 src/declarativeimports/kirigamiplasmastyle/AbstractApplicationHeader.qml create mode 100644 src/declarativeimports/kirigamiplasmastyle/CMakeLists.txt create mode 100644 src/declarativeimports/kirigamiplasmastyle/plasmatheme.cpp create mode 100644 src/declarativeimports/kirigamiplasmastyle/plasmatheme.h create mode 100644 src/declarativeimports/kirigamiplasmastyle/plugin.cpp create mode 100644 src/declarativeimports/kirigamiplasmastyle/plugin.h create mode 100644 src/declarativeimports/kirigamiplasmastyle/plugin.json create mode 100644 src/declarativeimports/kirigamiplasmastyle/units.cpp create mode 100644 src/declarativeimports/kirigamiplasmastyle/units.h create mode 100644 src/declarativeimports/plasmacomponents3/AbstractButton.qml create mode 100644 src/declarativeimports/plasmacomponents3/BusyIndicator.qml create mode 100644 src/declarativeimports/plasmacomponents3/Button.qml create mode 100644 src/declarativeimports/plasmacomponents3/CheckBox.qml create mode 100644 src/declarativeimports/plasmacomponents3/CheckDelegate.qml create mode 100644 src/declarativeimports/plasmacomponents3/CheckIndicator.qml create mode 100644 src/declarativeimports/plasmacomponents3/ComboBox.qml create mode 100644 src/declarativeimports/plasmacomponents3/Container.qml create mode 100644 src/declarativeimports/plasmacomponents3/Control.qml create mode 100644 src/declarativeimports/plasmacomponents3/Dial.qml create mode 100644 src/declarativeimports/plasmacomponents3/Dialog.qml create mode 100644 src/declarativeimports/plasmacomponents3/DialogButtonBox.qml create mode 100644 src/declarativeimports/plasmacomponents3/Drawer.qml create mode 100644 src/declarativeimports/plasmacomponents3/Frame.qml create mode 100644 src/declarativeimports/plasmacomponents3/GroupBox.qml create mode 100644 src/declarativeimports/plasmacomponents3/ItemDelegate.qml create mode 100644 src/declarativeimports/plasmacomponents3/Label.qml create mode 100644 src/declarativeimports/plasmacomponents3/Menu.qml create mode 100644 src/declarativeimports/plasmacomponents3/MenuItem.qml create mode 100644 src/declarativeimports/plasmacomponents3/MenuSeparator.qml create mode 100644 src/declarativeimports/plasmacomponents3/Page.qml create mode 100644 src/declarativeimports/plasmacomponents3/PageIndicator.qml create mode 100644 src/declarativeimports/plasmacomponents3/Pane.qml create mode 100644 src/declarativeimports/plasmacomponents3/Popup.qml create mode 100644 src/declarativeimports/plasmacomponents3/ProgressBar.qml create mode 100644 src/declarativeimports/plasmacomponents3/README.md create mode 100644 src/declarativeimports/plasmacomponents3/RadioButton.qml create mode 100644 src/declarativeimports/plasmacomponents3/RadioDelegate.qml create mode 100644 src/declarativeimports/plasmacomponents3/RadioIndicator.qml create mode 100644 src/declarativeimports/plasmacomponents3/RangeSlider.qml create mode 100644 src/declarativeimports/plasmacomponents3/RoundButton.qml create mode 100644 src/declarativeimports/plasmacomponents3/ScrollBar.qml create mode 100644 src/declarativeimports/plasmacomponents3/ScrollView.qml create mode 100644 src/declarativeimports/plasmacomponents3/Slider.qml create mode 100644 src/declarativeimports/plasmacomponents3/SpinBox.qml create mode 100644 src/declarativeimports/plasmacomponents3/SwipeView.qml create mode 100644 src/declarativeimports/plasmacomponents3/Switch.qml create mode 100644 src/declarativeimports/plasmacomponents3/SwitchDelegate.qml create mode 100644 src/declarativeimports/plasmacomponents3/SwitchIndicator.qml create mode 100644 src/declarativeimports/plasmacomponents3/TabBar.qml create mode 100644 src/declarativeimports/plasmacomponents3/TabButton.qml create mode 100644 src/declarativeimports/plasmacomponents3/TextArea.qml create mode 100644 src/declarativeimports/plasmacomponents3/TextField.qml create mode 100644 src/declarativeimports/plasmacomponents3/ToolBar.qml create mode 100644 src/declarativeimports/plasmacomponents3/ToolButton.qml create mode 100644 src/declarativeimports/plasmacomponents3/ToolTip.qml create mode 100644 src/declarativeimports/plasmacomponents3/mobiletextselection/MobileCursor.qml create mode 100644 src/declarativeimports/plasmacomponents3/mobiletextselection/MobileTextActionsToolBar.qml create mode 100644 src/declarativeimports/plasmacomponents3/mobiletextselection/MobileTextActionsToolBarImpl.qml create mode 100644 src/declarativeimports/plasmacomponents3/mobiletextselection/qmldir create mode 100644 src/declarativeimports/plasmacomponents3/private/ButtonBackground.qml create mode 100644 src/declarativeimports/plasmacomponents3/private/ButtonContent.qml create mode 100644 src/declarativeimports/plasmacomponents3/private/ButtonFocus.qml create mode 100644 src/declarativeimports/plasmacomponents3/private/ButtonHover.qml create mode 100644 src/declarativeimports/plasmacomponents3/private/ButtonShadow.qml create mode 100644 src/declarativeimports/plasmacomponents3/private/DefaultListItemBackground.qml create mode 100644 src/declarativeimports/plasmacomponents3/private/FlatButtonBackground.qml create mode 100644 src/declarativeimports/plasmacomponents3/private/IconLabel.qml create mode 100644 src/declarativeimports/plasmacomponents3/private/RaisedButtonBackground.qml create mode 100644 src/declarativeimports/plasmacomponents3/private/RoundShadow.qml create mode 100644 src/declarativeimports/plasmacomponents3/private/TextFieldFocus.qml create mode 100644 src/declarativeimports/plasmacomponents3/qmldir create mode 100644 src/declarativeimports/plasmaextracomponents/CMakeLists.txt create mode 100644 src/declarativeimports/plasmaextracomponents/Mainpage.dox create mode 100644 src/declarativeimports/plasmaextracomponents/qmenu.cpp create mode 100644 src/declarativeimports/plasmaextracomponents/qmenu.h create mode 100644 src/declarativeimports/plasmaextracomponents/qmenuitem.cpp create mode 100644 src/declarativeimports/plasmaextracomponents/qmenuitem.h create mode 100644 src/declarativeimports/plasmaextracomponents/qml/ActionTextField.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/DescriptiveLabel.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/Heading.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/Highlight.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/ListItem.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/ListSectionHeader.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/ModelContextMenu.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/PasswordField.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/PlaceholderMessage.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/PlasmoidHeading.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/Representation.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/SearchField.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/ShadowedLabel.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/animations/ActivateAnimation.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/animations/AppearAnimation.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/animations/DisappearAnimation.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/animations/PressedAnimation.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/animations/ReleasedAnimation.qml create mode 100644 src/declarativeimports/plasmaextracomponents/qml/private/BackgroundMetrics.qml create mode 100644 src/desktoptheme/CMakeLists.txt create mode 100644 src/desktoptheme/breeze-dark/CMakeLists.txt create mode 100644 src/desktoptheme/breeze-dark/colors create mode 100644 src/desktoptheme/breeze-dark/metadata.json.cmake create mode 100644 src/desktoptheme/breeze-dark/plasmarc create mode 100644 src/desktoptheme/breeze-light/CMakeLists.txt create mode 100644 src/desktoptheme/breeze-light/colors create mode 100644 src/desktoptheme/breeze-light/metadata.json.cmake create mode 100644 src/desktoptheme/breeze-light/plasmarc create mode 100644 src/desktoptheme/breeze/.gitignore create mode 100644 src/desktoptheme/breeze/CMakeLists.txt create mode 100644 src/desktoptheme/breeze/dialogs/background.svg create mode 100644 src/desktoptheme/breeze/icons/akonadi.svg create mode 100644 src/desktoptheme/breeze/icons/akregator.svg create mode 100644 src/desktoptheme/breeze/icons/amarok.svg create mode 100644 src/desktoptheme/breeze/icons/applications.svg create mode 100644 src/desktoptheme/breeze/icons/apport.svg create mode 100644 src/desktoptheme/breeze/icons/audio.svg create mode 100644 src/desktoptheme/breeze/icons/battery.svg create mode 100644 src/desktoptheme/breeze/icons/bookmarks.svg create mode 100644 src/desktoptheme/breeze/icons/cantata.svg create mode 100644 src/desktoptheme/breeze/icons/computer.svg create mode 100644 src/desktoptheme/breeze/icons/configure.svg create mode 100644 src/desktoptheme/breeze/icons/device.svg create mode 100644 src/desktoptheme/breeze/icons/disk.svg create mode 100644 src/desktoptheme/breeze/icons/distribute.svg create mode 100644 src/desktoptheme/breeze/icons/document.svg create mode 100644 src/desktoptheme/breeze/icons/drive.svg create mode 100644 src/desktoptheme/breeze/icons/edit.svg create mode 100644 src/desktoptheme/breeze/icons/fcitx.svg create mode 100644 src/desktoptheme/breeze/icons/go.svg create mode 100644 src/desktoptheme/breeze/icons/ime.svg create mode 100644 src/desktoptheme/breeze/icons/input.svg create mode 100644 src/desktoptheme/breeze/icons/kalarm.svg create mode 100644 src/desktoptheme/breeze/icons/kdeconnect.svg create mode 100644 src/desktoptheme/breeze/icons/keyboard.svg create mode 100644 src/desktoptheme/breeze/icons/kget.svg create mode 100644 src/desktoptheme/breeze/icons/kgpg.svg create mode 100644 src/desktoptheme/breeze/icons/kleopatra.svg create mode 100644 src/desktoptheme/breeze/icons/klipper.svg create mode 100644 src/desktoptheme/breeze/icons/kmail.svg create mode 100644 src/desktoptheme/breeze/icons/konv_message.svg create mode 100644 src/desktoptheme/breeze/icons/konversation.svg create mode 100644 src/desktoptheme/breeze/icons/kopete.svg create mode 100644 src/desktoptheme/breeze/icons/korgac.svg create mode 100644 src/desktoptheme/breeze/icons/kpackagekit.svg create mode 100644 src/desktoptheme/breeze/icons/kruler.svg create mode 100644 src/desktoptheme/breeze/icons/kteatime.svg create mode 100644 src/desktoptheme/breeze/icons/ktorrent.svg create mode 100644 src/desktoptheme/breeze/icons/kup.svg create mode 100644 src/desktoptheme/breeze/icons/list.svg create mode 100644 src/desktoptheme/breeze/icons/mail.svg create mode 100644 src/desktoptheme/breeze/icons/media.svg create mode 100644 src/desktoptheme/breeze/icons/mobile.svg create mode 100644 src/desktoptheme/breeze/icons/network.svg create mode 100644 src/desktoptheme/breeze/icons/notification.svg create mode 100644 src/desktoptheme/breeze/icons/osd.svg create mode 100644 src/desktoptheme/breeze/icons/phone.svg create mode 100644 src/desktoptheme/breeze/icons/plasmavault.svg create mode 100644 src/desktoptheme/breeze/icons/plasmavault_error.svg create mode 100644 src/desktoptheme/breeze/icons/preferences.svg create mode 100644 src/desktoptheme/breeze/icons/printer.svg create mode 100644 src/desktoptheme/breeze/icons/quassel.svg create mode 100644 src/desktoptheme/breeze/icons/search.svg create mode 100644 src/desktoptheme/breeze/icons/slc.svg create mode 100644 src/desktoptheme/breeze/icons/software.svg create mode 100644 src/desktoptheme/breeze/icons/start.svg create mode 100644 src/desktoptheme/breeze/icons/system.svg create mode 100644 src/desktoptheme/breeze/icons/touchpad.svg create mode 100644 src/desktoptheme/breeze/icons/user.svg create mode 100644 src/desktoptheme/breeze/icons/video-card.svg create mode 100644 src/desktoptheme/breeze/icons/video.svg create mode 100644 src/desktoptheme/breeze/icons/view.svg create mode 100644 src/desktoptheme/breeze/icons/vlc.svg create mode 100644 src/desktoptheme/breeze/icons/wallet.svg create mode 100644 src/desktoptheme/breeze/icons/window.svg create mode 100644 src/desktoptheme/breeze/icons/yakuake.svg create mode 100644 src/desktoptheme/breeze/icons/zoom.svg create mode 100644 src/desktoptheme/breeze/metadata.json.cmake create mode 100644 src/desktoptheme/breeze/opaque/dialogs/background.svg create mode 100644 src/desktoptheme/breeze/opaque/widgets/panel-background.svg create mode 100644 src/desktoptheme/breeze/opaque/widgets/tooltip.svg create mode 100644 src/desktoptheme/breeze/plasmarc create mode 100644 src/desktoptheme/breeze/solid/dialogs/background.svg create mode 100644 src/desktoptheme/breeze/solid/widgets/background.svg create mode 100644 src/desktoptheme/breeze/solid/widgets/panel-background.svg create mode 100644 src/desktoptheme/breeze/solid/widgets/tooltip.svg create mode 100644 src/desktoptheme/breeze/translucent/dialogs/background.svg create mode 100644 src/desktoptheme/breeze/translucent/widgets/background.svg create mode 100644 src/desktoptheme/breeze/translucent/widgets/panel-background.svg create mode 100644 src/desktoptheme/breeze/translucent/widgets/tooltip.svg create mode 100644 src/desktoptheme/breeze/widgets/.png create mode 100644 src/desktoptheme/breeze/widgets/action-overlays.svg create mode 100644 src/desktoptheme/breeze/widgets/actionbutton.svg create mode 100644 src/desktoptheme/breeze/widgets/analog_meter.svg create mode 100644 src/desktoptheme/breeze/widgets/arrows.svg create mode 100644 src/desktoptheme/breeze/widgets/background.svg create mode 100644 src/desktoptheme/breeze/widgets/bar_meter_horizontal.svg create mode 100644 src/desktoptheme/breeze/widgets/bar_meter_vertical.svg create mode 100644 src/desktoptheme/breeze/widgets/branding.svg create mode 100644 src/desktoptheme/breeze/widgets/busywidget.svg create mode 100644 src/desktoptheme/breeze/widgets/button.svg create mode 100644 src/desktoptheme/breeze/widgets/calendar.svg create mode 100644 src/desktoptheme/breeze/widgets/checkmarks.svg create mode 100644 src/desktoptheme/breeze/widgets/clock.svg create mode 100644 src/desktoptheme/breeze/widgets/configuration-icons.svg create mode 100644 src/desktoptheme/breeze/widgets/containment-controls.svg create mode 100644 src/desktoptheme/breeze/widgets/dragger.svg create mode 100644 src/desktoptheme/breeze/widgets/frame.svg create mode 100644 src/desktoptheme/breeze/widgets/glowbar.svg create mode 100644 src/desktoptheme/breeze/widgets/line.svg create mode 100644 src/desktoptheme/breeze/widgets/lineedit.svg create mode 100644 src/desktoptheme/breeze/widgets/listitem.svg create mode 100644 src/desktoptheme/breeze/widgets/margins-highlight.svg create mode 100644 src/desktoptheme/breeze/widgets/media-delegate.svg create mode 100644 src/desktoptheme/breeze/widgets/menubaritem.svg create mode 100644 src/desktoptheme/breeze/widgets/monitor.svg create mode 100644 src/desktoptheme/breeze/widgets/notes.svg create mode 100644 src/desktoptheme/breeze/widgets/pager.svg create mode 100644 src/desktoptheme/breeze/widgets/panel-background.svg create mode 100644 src/desktoptheme/breeze/widgets/picker.svg create mode 100644 src/desktoptheme/breeze/widgets/plasmoidheading.svg create mode 100644 src/desktoptheme/breeze/widgets/plot-background.svg create mode 100644 src/desktoptheme/breeze/widgets/radiobutton.svg create mode 100644 src/desktoptheme/breeze/widgets/scrollbar.svg create mode 100644 src/desktoptheme/breeze/widgets/scrollwidget.svg create mode 100644 src/desktoptheme/breeze/widgets/slider.svg create mode 100644 src/desktoptheme/breeze/widgets/switch.svg create mode 100644 src/desktoptheme/breeze/widgets/tabbar.svg create mode 100644 src/desktoptheme/breeze/widgets/tasks.svg create mode 100644 src/desktoptheme/breeze/widgets/toolbar.svg create mode 100644 src/desktoptheme/breeze/widgets/tooltip.svg create mode 100644 src/desktoptheme/breeze/widgets/translucentbackground.svg create mode 100644 src/desktoptheme/breeze/widgets/viewitem.svg create mode 100644 src/desktoptheme/oxygen/metadata.json.cmake create mode 100644 src/plasma/.krazy create mode 100644 src/plasma/CMakeLists.txt create mode 100644 src/plasma/Mainpage.dox create mode 100644 src/plasma/README create mode 100644 src/plasma/applet.cpp create mode 100644 src/plasma/applet.h create mode 100644 src/plasma/config-plasma.h.cmake create mode 100644 src/plasma/containment.cpp create mode 100644 src/plasma/containment.h create mode 100644 src/plasma/containmentactions.cpp create mode 100644 src/plasma/containmentactions.h create mode 100644 src/plasma/corona.cpp create mode 100644 src/plasma/corona.h create mode 100644 src/plasma/data/kconfigxt/libplasma-theme-global.kcfg create mode 100644 src/plasma/data/kconfigxt/libplasma-theme-global.kcfgc create mode 100644 src/plasma/packagestructure/CMakeLists.txt create mode 100644 src/plasma/packagestructure/packages.cpp create mode 100644 src/plasma/packagestructure/packages_p.h create mode 100644 src/plasma/packagestructure/plasma_applet_packagestructure.cpp create mode 100644 src/plasma/packagestructure/plasma_applet_packagestructure.json create mode 100644 src/plasma/packagestructure/plasma_containmentactions_packagestructure.cpp create mode 100644 src/plasma/packagestructure/plasma_containmentactions_packagestructure.json create mode 100644 src/plasma/packagestructure/plasma_generic_packagestructure.cpp create mode 100644 src/plasma/packagestructure/plasma_generic_packagestructure.json create mode 100644 src/plasma/packagestructure/plasma_theme_packagestructure.cpp create mode 100644 src/plasma/packagestructure/plasma_theme_packagestructure.json create mode 100644 src/plasma/packagestructure/qmlWallpaper/plasma-packagestructure-wallpaper.json create mode 100644 src/plasma/packagestructure/qmlWallpaper/wallpaper.cpp create mode 100644 src/plasma/packagestructure/shell/plasma-packagestructure-plasma-shell.json create mode 100644 src/plasma/packagestructure/shell/shellpackage.cpp create mode 100644 src/plasma/plasma.cpp create mode 100644 src/plasma/plasma.h create mode 100644 src/plasma/pluginloader.cpp create mode 100644 src/plasma/pluginloader.h create mode 100644 src/plasma/private/applet_p.cpp create mode 100644 src/plasma/private/applet_p.h create mode 100644 src/plasma/private/containment_p.cpp create mode 100644 src/plasma/private/containment_p.h create mode 100644 src/plasma/private/containmentactions_p.h create mode 100644 src/plasma/private/corona_p.h create mode 100644 src/plasma/private/effectwatcher.cpp create mode 100644 src/plasma/private/effectwatcher_p.h create mode 100644 src/plasma/private/theme_p.cpp create mode 100644 src/plasma/private/theme_p.h create mode 100644 src/plasma/theme.cpp create mode 100644 src/plasma/theme.h create mode 100644 src/plasmaquick/CMakeLists.txt create mode 100644 src/plasmaquick/Mainpage.dox create mode 100644 src/plasmaquick/PlasmaQuickConfig.cmake.in create mode 100644 src/plasmaquick/appletcontext.cpp create mode 100644 src/plasmaquick/appletcontext_p.h create mode 100644 src/plasmaquick/appletpopup.cpp create mode 100644 src/plasmaquick/appletpopup.h create mode 100644 src/plasmaquick/appletquickitem.cpp create mode 100644 src/plasmaquick/appletquickitem.h create mode 100644 src/plasmaquick/appletquickitem_p.h create mode 100644 src/plasmaquick/configcategory_p.cpp create mode 100644 src/plasmaquick/configcategory_p.h create mode 100644 src/plasmaquick/configmodel.cpp create mode 100644 src/plasmaquick/configmodel.h create mode 100644 src/plasmaquick/configview.cpp create mode 100644 src/plasmaquick/configview.h create mode 100644 src/plasmaquick/containmentview.cpp create mode 100644 src/plasmaquick/containmentview.h create mode 100644 src/plasmaquick/dialog.cpp create mode 100644 src/plasmaquick/dialog.h create mode 100644 src/plasmaquick/dialogbackground_p.cpp create mode 100644 src/plasmaquick/dialogbackground_p.h create mode 100644 src/plasmaquick/dialogshadows.cpp create mode 100644 src/plasmaquick/dialogshadows_p.h create mode 100644 src/plasmaquick/edgeeventforwarder.cpp create mode 100644 src/plasmaquick/edgeeventforwarder.h create mode 100644 src/plasmaquick/plasmashellwaylandintegration.cpp create mode 100644 src/plasmaquick/plasmashellwaylandintegration.h create mode 100644 src/plasmaquick/plasmawindow.cpp create mode 100644 src/plasmaquick/plasmawindow.h create mode 100644 src/plasmaquick/plasmoid/containmentitem.cpp create mode 100644 src/plasmaquick/plasmoid/containmentitem.h create mode 100644 src/plasmaquick/plasmoid/dropmenu.cpp create mode 100644 src/plasmaquick/plasmoid/dropmenu.h create mode 100644 src/plasmaquick/plasmoid/plasmoiditem.cpp create mode 100644 src/plasmaquick/plasmoid/plasmoiditem.h create mode 100644 src/plasmaquick/plasmoid/wallpaperitem.cpp create mode 100644 src/plasmaquick/plasmoid/wallpaperitem.h create mode 100644 src/plasmaquick/plasmoidattached_p.cpp create mode 100644 src/plasmaquick/plasmoidattached_p.h create mode 100644 src/plasmaquick/popupplasmawindow.cpp create mode 100644 src/plasmaquick/popupplasmawindow.h create mode 100644 src/plasmaquick/quickviewsharedengine.cpp create mode 100644 src/plasmaquick/quickviewsharedengine.h create mode 100644 src/plasmaquick/sharedqmlengine.cpp create mode 100644 src/plasmaquick/sharedqmlengine.h create mode 100644 src/plasmaquick/transientplacementhint.cpp create mode 100644 src/plasmaquick/transientplacementhint_p.h create mode 100644 src/plasmaquick/utils.cpp create mode 100644 src/plasmaquick/utils.h create mode 100644 src/plasmaquick/windowresizehandler.cpp create mode 100644 src/plasmaquick/windowresizehandler.h create mode 100755 src/tools/apply-stylesheet.sh create mode 100755 src/tools/currentColorFillFix.sh create mode 100644 src/tools/inkscape extensions/plasmarename.inx create mode 100644 src/tools/inkscape extensions/plasmarename.py create mode 100644 templates/.clang-format create mode 100644 templates/CMakeLists.txt create mode 100644 templates/cpp-plasmoid6/CMakeLists.txt create mode 100644 templates/cpp-plasmoid6/LICENSES/LGPL-2.1-or-later.txt create mode 100644 templates/cpp-plasmoid6/Messages.sh create mode 100644 templates/cpp-plasmoid6/README create mode 100644 templates/cpp-plasmoid6/cpp-plasmoid6.kdevtemplate create mode 100644 templates/cpp-plasmoid6/cpp-plasmoid6.png create mode 100644 templates/cpp-plasmoid6/src/%{APPNAMELC}.cpp create mode 100644 templates/cpp-plasmoid6/src/%{APPNAMELC}.h create mode 100644 templates/cpp-plasmoid6/src/CMakeLists.txt create mode 100644 templates/cpp-plasmoid6/src/package/contents/images/pairs.svg create mode 100644 templates/cpp-plasmoid6/src/package/contents/ui/main.qml create mode 100644 templates/cpp-plasmoid6/src/package/metadata.json create mode 100644 templates/plasma6-wallpaper-with-qml-extension/CMakeLists.txt create mode 100644 templates/plasma6-wallpaper-with-qml-extension/LICENSES/LGPL-2.1-or-later.txt create mode 100644 templates/plasma6-wallpaper-with-qml-extension/Messages.sh create mode 100644 templates/plasma6-wallpaper-with-qml-extension/README create mode 100644 templates/plasma6-wallpaper-with-qml-extension/package/contents/config/main.xml create mode 100644 templates/plasma6-wallpaper-with-qml-extension/package/contents/ui/config.qml create mode 100644 templates/plasma6-wallpaper-with-qml-extension/package/contents/ui/main.qml create mode 100644 templates/plasma6-wallpaper-with-qml-extension/package/metadata.json create mode 100644 templates/plasma6-wallpaper-with-qml-extension/plasma6-wallpaper-with-qml-extension.kdevtemplate create mode 100644 templates/plasma6-wallpaper-with-qml-extension/plugin/%{APPNAMELC}plugin.cpp create mode 100644 templates/plasma6-wallpaper-with-qml-extension/plugin/%{APPNAMELC}plugin.h create mode 100644 templates/plasma6-wallpaper-with-qml-extension/plugin/CMakeLists.txt create mode 100644 templates/plasma6-wallpaper-with-qml-extension/plugin/qmldir create mode 100644 templates/plasma6-wallpaper/CMakeLists.txt create mode 100644 templates/plasma6-wallpaper/LICENSES/LGPL-2.1-or-later.txt create mode 100644 templates/plasma6-wallpaper/Messages.sh create mode 100644 templates/plasma6-wallpaper/README create mode 100644 templates/plasma6-wallpaper/package/contents/config/main.xml create mode 100644 templates/plasma6-wallpaper/package/contents/ui/config.qml create mode 100644 templates/plasma6-wallpaper/package/contents/ui/main.qml create mode 100644 templates/plasma6-wallpaper/package/metadata.json create mode 100644 templates/plasma6-wallpaper/plasma6-wallpaper.kdevtemplate create mode 100644 templates/qml-plasmoid6-with-qml-extension/CMakeLists.txt create mode 100644 templates/qml-plasmoid6-with-qml-extension/LICENSES/LGPL-2.1-or-later.txt create mode 100644 templates/qml-plasmoid6-with-qml-extension/Messages.sh create mode 100644 templates/qml-plasmoid6-with-qml-extension/README create mode 100644 templates/qml-plasmoid6-with-qml-extension/package/contents/ui/main.qml create mode 100644 templates/qml-plasmoid6-with-qml-extension/package/metadata.json create mode 100644 templates/qml-plasmoid6-with-qml-extension/plugin/%{APPNAMELC}plugin.cpp create mode 100644 templates/qml-plasmoid6-with-qml-extension/plugin/%{APPNAMELC}plugin.h create mode 100644 templates/qml-plasmoid6-with-qml-extension/plugin/CMakeLists.txt create mode 100644 templates/qml-plasmoid6-with-qml-extension/plugin/qmldir create mode 100644 templates/qml-plasmoid6-with-qml-extension/qml-plasmoid6-with-qml-extension.kdevtemplate create mode 100644 templates/qml-plasmoid6-with-qml-extension/qml-plasmoid6-with-qml-extension.png create mode 100644 templates/qml-plasmoid6/CMakeLists.txt create mode 100644 templates/qml-plasmoid6/LICENSES/LGPL-2.1-or-later.txt create mode 100644 templates/qml-plasmoid6/Messages.sh create mode 100644 templates/qml-plasmoid6/README create mode 100644 templates/qml-plasmoid6/package/contents/images/pairs.svgz create mode 100644 templates/qml-plasmoid6/package/contents/ui/main.qml create mode 100644 templates/qml-plasmoid6/package/metadata.json create mode 100644 templates/qml-plasmoid6/qml-plasmoid6.kdevtemplate create mode 100644 templates/qml-plasmoid6/qml-plasmoid6.png create mode 100644 tests/CMakeLists.txt create mode 100644 tests/buttons_pc3.0.qml create mode 100644 tests/components/ComponentBase.qml create mode 100644 tests/components/busyindicator3.qml create mode 100644 tests/components/button3.qml create mode 100644 tests/components/checkbox3.qml create mode 100644 tests/components/combobox3.qml create mode 100644 tests/components/menu-placement.qml create mode 100644 tests/components/menu.qml create mode 100644 tests/components/progressbar3.qml create mode 100644 tests/components/radiobutton3.qml create mode 100644 tests/components/roundbutton3.qml create mode 100644 tests/components/slider3.qml create mode 100644 tests/components/tabbar3.qml create mode 100644 tests/components/textarea3.qml create mode 100644 tests/components/textfield3.qml create mode 100644 tests/components/toolbutton3.qml create mode 100644 tests/dialog.qml create mode 100644 tests/dialog_fullscreen.qml create mode 100644 tests/dialog_minWidthHeightRepositioning.qml create mode 100644 tests/dialog_positioning.qml create mode 100644 tests/dialog_positioning2.qml create mode 100644 tests/dialog_positioning_parentrotated.qml create mode 100644 tests/dialog_resizeWithParent.qml create mode 100644 tests/dialog_sizeMoreThanMin.qml create mode 100644 tests/dialog_tooltip.qml create mode 100644 tests/dialog_visualParentChange.qml create mode 100644 tests/dpi/CMakeLists.txt create mode 100644 tests/dpi/dpitest.cpp create mode 100644 tests/dpi/dpitest.h create mode 100644 tests/dpi/main.cpp create mode 100644 tests/extras/expandablelistitem.qml create mode 100644 tests/frames.qml create mode 100644 tests/selected_svg.qml create mode 100644 tests/shadows.qml create mode 100644 tests/testborders.qml create mode 100644 tests/tooltip-icons.qml create mode 100644 tests/tooltip.qml create mode 100644 tests/window.qml diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..3ea49ca --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,7 @@ +#clang-format +08d4f6335bcd60306b243f4fd53d1ea60a995a06 +adaffcfc08d7dec7a5ae4b2a34d38494d5fe94c2 +#clang-tidy +3120de70f25378cad1faf0ee4e96ac506006b953 +# re-run of clang-format +30f46ade664d7a9492817befa838297aecc44506 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..58da693 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.svg binary diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..31ded7d --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +# Ignore the following files +*~ +*.[oa] +*.diff +*.kate-swp +*.kdev4 +.kdev_include_paths +*.kdevelop.pcs +*.moc +*.moc.cpp +*.orig +*.user +.*.swp +.swp.* +Doxyfile +Makefile +avail +random_seed +/build*/ +CMakeLists.txt.user* +*.unc-backup* +.cmake/ +cmake-build-debug* +.idea +/.clang-format +/compile_commands.json +.clangd +.cache diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..202fd25 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: 2020 Volker Krause +# SPDX-License-Identifier: CC0-1.0 + +include: + - project: sysadmin/ci-utilities + file: + - /gitlab-templates/linux-qt6.yml + - /gitlab-templates/freebsd-qt6.yml diff --git a/.kde-ci.yml b/.kde-ci.yml new file mode 100644 index 0000000..71dbb49 --- /dev/null +++ b/.kde-ci.yml @@ -0,0 +1,29 @@ +Dependencies: +- 'on': ['Linux', 'FreeBSD', 'Windows', 'macOS'] + 'require': + 'frameworks/extra-cmake-modules': '@latest-kf6' + 'frameworks/karchive' : '@latest-kf6' + 'frameworks/kconfig' : '@latest-kf6' + 'frameworks/kconfigwidgets' : '@latest-kf6' + 'frameworks/kcoreaddons' : '@latest-kf6' + 'frameworks/kdbusaddons' : '@latest-kf6' + 'frameworks/kglobalaccel' : '@latest-kf6' + 'frameworks/kguiaddons' : '@latest-kf6' + 'frameworks/ki18n' : '@latest-kf6' + 'frameworks/kiconthemes' : '@latest-kf6' + 'frameworks/kio' : '@latest-kf6' + 'frameworks/knotifications' : '@latest-kf6' + 'frameworks/kpackage' : '@latest-kf6' + # kparts for examples + 'frameworks/kparts' : '@latest-kf6' + 'frameworks/kwidgetsaddons' : '@latest-kf6' + 'frameworks/kwindowsystem' : '@latest-kf6' + 'frameworks/kirigami' : '@latest-kf6' + 'frameworks/kcmutils' : '@latest-kf6' + 'frameworks/ksvg' : '@latest-kf6' + 'plasma/plasma-activities' : '@same' + +Options: + cppcheck-ignore-files: ['templates/'] + require-passing-tests-on: [ '@all' ] + cmake-options: -DBUILD_EXAMPLES=ON diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..4b67fc2 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,215 @@ +cmake_minimum_required(VERSION 3.16) + +set(PROJECT_VERSION "6.2.4") +project(plasma-framework VERSION ${PROJECT_VERSION}) + +set(QT_MIN_VERSION "6.7.0") +set(PROJECT_DEP_VERSION "6.2.4") +set(KF6_MIN_VERSION "6.5.0") + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(ECM ${KF6_MIN_VERSION} REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ) + +include(FeatureSummary) +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDEGitCommitHooks) +include(KDECompilerSettings NO_POLICY_SCOPE) +include(KDEClangFormat) + +include(ECMGenerateExportHeader) +include(ECMGenerateHeaders) +include(CMakePackageConfigHelpers) +include(ECMSetupVersion) +include(ECMQtDeclareLoggingCategory) +include(ECMAddQch) +include(KDEPackageAppTemplates) +include(ECMGenerateQmlTypes) +include(ECMMarkNonGuiExecutable) +include(ECMDeprecationSettings) +include(ECMQmlModule) + +option(BUILD_QCH "Build API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)" OFF) +add_feature_info(QCH ${BUILD_QCH} "API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)") + +ecm_setup_version(PROJECT + VARIABLE_PREFIX PLASMA + VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/plasma_version.h" + PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/PlasmaConfigVersion.cmake" + SOVERSION 6) + +################# now find all used packages ################# + +find_package(Qt6 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Quick Gui Qml Svg QuickControls2 DBus) + +find_package(KF6 ${KF6_MIN_VERSION} REQUIRED + COMPONENTS + Archive + Config + ConfigWidgets + CoreAddons + GlobalAccel + GuiAddons + I18n + IconThemes + KIO + WindowSystem + Notifications + Package + KirigamiPlatform + KCMUtils + Svg +) +find_package(PlasmaActivities REQUIRED ${PROJECT_DEP_VERSION}) + +# Wayland features +find_package(PlasmaWaylandProtocols 1.10.0 REQUIRED) +find_package(Qt6WaylandClient ${QT_MIN_VERSION} REQUIRED CONFIG) +find_package(Wayland 1.9 REQUIRED Client) + +option(WITHOUT_X11 "Build without X11 support (skips finding X11)." OFF) +if(NOT WITHOUT_X11) + #optional features + find_package(X11 MODULE) + set_package_properties(X11 PROPERTIES DESCRIPTION "X11 libraries" + URL "https://www.x.org/" + TYPE OPTIONAL + ) + find_package(XCB MODULE COMPONENTS XCB COMPOSITE DAMAGE XFIXES RENDER) + set_package_properties(XCB PROPERTIES DESCRIPTION "X protocol C-language Binding" + URL "https://xcb.freedesktop.org/" + TYPE OPTIONAL + ) + if(X11_FOUND AND XCB_XCB_FOUND) + set(HAVE_X11 1) + #X11_Xrender discovery is done by FindX11 + #add_feature_info("X Rendering Extension (libXrender)" X11_Xrender_FOUND "Support for compositing, rendering operations, and alpha-blending. STRONGLY RECOMMENDED") + else() + set(HAVE_X11 0) + endif() +endif() + +find_package(OpenGL) +set_package_properties(OpenGL PROPERTIES DESCRIPTION "The OpenGL libraries" + URL "https://www.opengl.org/" + TYPE OPTIONAL + ) + +find_package(EGL) +set_package_properties(EGL PROPERTIES + PURPOSE "Fallback when OpenGL not available because of missing GLVND" + TYPE OPTIONAL + ) + +get_target_property(QtGui_Enabled_Features Qt6::Gui QT_ENABLED_PUBLIC_FEATURES) +if(OpenGL_GLX_FOUND AND HAVE_X11 AND (QtGui_Enabled_Features MATCHES "opengl")) + add_feature_info(GLX OpenGL_GLX_FOUND "OpenGL GLX libraries.") + set(HAVE_GLX 1) +else() + set(HAVE_GLX 0) +endif() + +# OpenGL_EGL_FOUND is defined by FindOpenGL +if(TARGET OpenGL::EGL) + add_feature_info(EGL OpenGL_EGL_FOUND + "A platform-agnostic mechanism for creating rendering surfaces for use with other graphics libraries, such as OpenGL|ES and OpenVG.") + set(HAVE_EGL 1) +else() + set(HAVE_EGL 0) + message(STATUS "OpenGL::EGL is not available") +endif() + +######################################################################### + +ecm_set_disabled_deprecation_versions( + QT 6.7 + KF 6.5 +) + +#add_definitions(-Wno-deprecated) + +include(PlasmaMacros.cmake) + +######################################################################### + + +option(BUILD_EXAMPLES "Build and install Plasma examples." OFF) +option(BUILD_COVERAGE "Build Plasma Frameworks with gcov support" OFF) + +if (BUILD_EXAMPLES) + find_package(KF6DBusAddons ${KF6_MIN_VERSION}) +endif() + +if(BUILD_COVERAGE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov") +endif() + +# make plasma_version.h available +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +################# list the subdirectories ################# +add_definitions(-DTRANSLATION_DOMAIN=\"libplasma6\") +ki18n_install(po) +add_subdirectory(src) + +if (BUILD_EXAMPLES) + add_subdirectory(examples) +endif() + +if (BUILD_TESTING) + add_subdirectory(autotests) + add_subdirectory(tests) +endif() +add_subdirectory(templates) + +################ create PlasmaConfig.cmake and install it ########################### + +# create a Config.cmake and a ConfigVersion.cmake file and install them + +set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/Plasma") + +if (BUILD_QCH) + ecm_install_qch_export( + TARGETS Plasma_QCH + FILE PlasmaQchTargets.cmake + DESTINATION "${CMAKECONFIG_INSTALL_DIR}" + COMPONENT Devel + ) + set(PACKAGE_INCLUDE_QCHTARGETS "include(\"\${CMAKE_CURRENT_LIST_DIR}/PlasmaQchTargets.cmake\")") +endif() + +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/PlasmaConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/PlasmaConfig.cmake" + INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} + PATH_VARS CMAKE_INSTALL_PREFIX +) + +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/PlasmaConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/PlasmaConfigVersion.cmake" + "${CMAKE_CURRENT_SOURCE_DIR}/PlasmaMacros.cmake" + DESTINATION "${CMAKECONFIG_INSTALL_DIR}" + COMPONENT Devel +) + +install(EXPORT PlasmaTargets + DESTINATION "${CMAKECONFIG_INSTALL_DIR}" + FILE PlasmaTargets.cmake + NAMESPACE Plasma:: + COMPONENT Devel) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasma_version.h + DESTINATION ${KDE_INSTALL_INCLUDEDIR}/Plasma COMPONENT Devel ) + +include(ECMFeatureSummary) +ecm_feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) + +# add clang-format target for all our source files +file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h) +kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES}) +kde_configure_git_pre_commit_hook(CHECKS CLANG_FORMAT) diff --git a/ExtraDesktop.sh b/ExtraDesktop.sh new file mode 100644 index 0000000..0c46ec1 --- /dev/null +++ b/ExtraDesktop.sh @@ -0,0 +1,4 @@ +#! /bin/sh +#This file outputs in a separate line each file with a .desktop syntax +#that needs to be translated but has a non .desktop extension +find -name \*.kdevtemplate -print diff --git a/LICENSES/BSD-3-Clause.txt b/LICENSES/BSD-3-Clause.txt new file mode 100644 index 0000000..0741db7 --- /dev/null +++ b/LICENSES/BSD-3-Clause.txt @@ -0,0 +1,26 @@ +Copyright (c) . All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/LICENSES/CC0-1.0.txt b/LICENSES/CC0-1.0.txt new file mode 100644 index 0000000..0e259d4 --- /dev/null +++ b/LICENSES/CC0-1.0.txt @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/LICENSES/GPL-2.0-only.txt b/LICENSES/GPL-2.0-only.txt new file mode 100644 index 0000000..0f3d641 --- /dev/null +++ b/LICENSES/GPL-2.0-only.txt @@ -0,0 +1,319 @@ +GNU GENERAL PUBLIC LICENSE + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. + +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to +most of the Free Software Foundation's software and to any other program whose +authors commit to using it. (Some other Free Software Foundation software +is covered by the GNU Lesser General Public License instead.) You can apply +it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you +wish), that you receive source code or can get it if you want it, that you +can change the software or use pieces of it in new free programs; and that +you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or +for a fee, you must give the recipients all the rights that you have. You +must make sure that they, too, receive or can get the source code. And you +must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If +the software is modified by someone else and passed on, we want its recipients +to know that what they have is not the original, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will individually +obtain patent licenses, in effect making the program proprietary. To prevent +this, we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms +of this General Public License. The "Program", below, refers to any such program +or work, and a "work based on the Program" means either the Program or any +derivative work under copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with modifications and/or translated +into another language. (Hereinafter, translation is included without limitation +in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running the Program +is not restricted, and the output from the Program is covered only if its +contents constitute a work based on the Program (independent of having been +made by running the Program). Whether that is true depends on what the Program +does. + +1. You may copy and distribute verbatim copies of the Program's source code +as you receive it, in any medium, provided that you conspicuously and appropriately +publish on each copy an appropriate copyright notice and disclaimer of warranty; +keep intact all the notices that refer to this License and to the absence +of any warranty; and give any other recipients of the Program a copy of this +License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, +thus forming a work based on the Program, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + +a) You must cause the modified files to carry prominent notices stating that +you changed the files and the date of any change. + +b) You must cause any work that you distribute or publish, that in whole or +in part contains or is derived from the Program or any part thereof, to be +licensed as a whole at no charge to all third parties under the terms of this +License. + +c) If the modified program normally reads commands interactively when run, +you must cause it, when started running for such interactive use in the most +ordinary way, to print or display an announcement including an appropriate +copyright notice and a notice that there is no warranty (or else, saying that +you provide a warranty) and that users may redistribute the program under +these conditions, and telling the user how to view a copy of this License. +(Exception: if the Program itself is interactive but does not normally print +such an announcement, your work based on the Program is not required to print +an announcement.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Program, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Program. + +In addition, mere aggregation of another work not based on the Program with +the Program (or with a work based on the Program) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may copy and distribute the Program (or a work based on it, under Section +2) in object code or executable form under the terms of Sections 1 and 2 above +provided that you also do one of the following: + +a) Accompany it with the complete corresponding machine-readable source code, +which must be distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, + +b) Accompany it with a written offer, valid for at least three years, to give +any third party, for a charge no more than your cost of physically performing +source distribution, a complete machine-readable copy of the corresponding +source code, to be distributed under the terms of Sections 1 and 2 above on +a medium customarily used for software interchange; or, + +c) Accompany it with the information you received as to the offer to distribute +corresponding source code. (This alternative is allowed only for noncommercial +distribution and only if you received the program in object code or executable +form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all +the source code for all modules it contains, plus any associated interface +definition files, plus the scripts used to control compilation and installation +of the executable. However, as a special exception, the source code distributed +need not include anything that is normally distributed (in either source or +binary form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component itself +accompanies the executable. + +If distribution of executable or object code is made by offering access to +copy from a designated place, then offering equivalent access to copy the +source code from the same place counts as distribution of the source code, +even though third parties are not compelled to copy the source along with +the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except +as expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate +your rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses terminated +so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Program or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Program +(or any work based on the Program), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), +the recipient automatically receives a license from the original licensor +to copy, distribute or modify the Program subject to these terms and conditions. +You may not impose any further restrictions on the recipients' exercise of +the rights granted herein. You are not responsible for enforcing compliance +by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of +this License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Program at all. For example, if a +patent license would not permit royalty-free redistribution of the Program +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and +the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system, which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Program under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of +the General Public License from time to time. Such new versions will be similar +in spirit to the present version, but may differ in detail to address new +problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Program does not specify a version number of this License, you may choose +any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software Foundation, +write to the Free Software Foundation; we sometimes make exceptions for this. +Our decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing and reuse +of software generally. + + NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA +OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible +use to the public, the best way to achieve this is to make it free software +which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach +them to the start of each source file to most effectively convey the exclusion +of warranty; and each file should have at least the "copyright" line and a +pointer to where the full notice is found. + + + +Copyright (C)< yyyy> + +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. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when +it starts in an interactive mode: + +Gnomovision version 69, Copyright (C) year name of author Gnomovision comes +with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, +and you are welcome to redistribute it under certain conditions; type `show +c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may be +called something other than `show w' and `show c'; they could even be mouse-clicks +or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the program, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' +(which makes passes at compilers) written by James Hacker. + +, 1 April 1989 Ty Coon, President of Vice This General +Public License does not permit incorporating your program into proprietary +programs. If your program is a subroutine library, you may consider it more +useful to permit linking proprietary applications with the library. If this +is what you want to do, use the GNU Lesser General Public License instead +of this License. diff --git a/LICENSES/GPL-2.0-or-later.txt b/LICENSES/GPL-2.0-or-later.txt new file mode 100644 index 0000000..1d80ac3 --- /dev/null +++ b/LICENSES/GPL-2.0-or-later.txt @@ -0,0 +1,319 @@ +GNU GENERAL PUBLIC LICENSE + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. + +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to +most of the Free Software Foundation's software and to any other program whose +authors commit to using it. (Some other Free Software Foundation software +is covered by the GNU Lesser General Public License instead.) You can apply +it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you +wish), that you receive source code or can get it if you want it, that you +can change the software or use pieces of it in new free programs; and that +you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or +for a fee, you must give the recipients all the rights that you have. You +must make sure that they, too, receive or can get the source code. And you +must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If +the software is modified by someone else and passed on, we want its recipients +to know that what they have is not the original, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will individually +obtain patent licenses, in effect making the program proprietary. To prevent +this, we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms +of this General Public License. The "Program", below, refers to any such program +or work, and a "work based on the Program" means either the Program or any +derivative work under copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with modifications and/or translated +into another language. (Hereinafter, translation is included without limitation +in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running the Program +is not restricted, and the output from the Program is covered only if its +contents constitute a work based on the Program (independent of having been +made by running the Program). Whether that is true depends on what the Program +does. + +1. You may copy and distribute verbatim copies of the Program's source code +as you receive it, in any medium, provided that you conspicuously and appropriately +publish on each copy an appropriate copyright notice and disclaimer of warranty; +keep intact all the notices that refer to this License and to the absence +of any warranty; and give any other recipients of the Program a copy of this +License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, +thus forming a work based on the Program, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + +a) You must cause the modified files to carry prominent notices stating that +you changed the files and the date of any change. + +b) You must cause any work that you distribute or publish, that in whole or +in part contains or is derived from the Program or any part thereof, to be +licensed as a whole at no charge to all third parties under the terms of this +License. + +c) If the modified program normally reads commands interactively when run, +you must cause it, when started running for such interactive use in the most +ordinary way, to print or display an announcement including an appropriate +copyright notice and a notice that there is no warranty (or else, saying that +you provide a warranty) and that users may redistribute the program under +these conditions, and telling the user how to view a copy of this License. +(Exception: if the Program itself is interactive but does not normally print +such an announcement, your work based on the Program is not required to print +an announcement.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Program, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Program. + +In addition, mere aggregation of another work not based on the Program with +the Program (or with a work based on the Program) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may copy and distribute the Program (or a work based on it, under Section +2) in object code or executable form under the terms of Sections 1 and 2 above +provided that you also do one of the following: + +a) Accompany it with the complete corresponding machine-readable source code, +which must be distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, + +b) Accompany it with a written offer, valid for at least three years, to give +any third party, for a charge no more than your cost of physically performing +source distribution, a complete machine-readable copy of the corresponding +source code, to be distributed under the terms of Sections 1 and 2 above on +a medium customarily used for software interchange; or, + +c) Accompany it with the information you received as to the offer to distribute +corresponding source code. (This alternative is allowed only for noncommercial +distribution and only if you received the program in object code or executable +form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all +the source code for all modules it contains, plus any associated interface +definition files, plus the scripts used to control compilation and installation +of the executable. However, as a special exception, the source code distributed +need not include anything that is normally distributed (in either source or +binary form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component itself +accompanies the executable. + +If distribution of executable or object code is made by offering access to +copy from a designated place, then offering equivalent access to copy the +source code from the same place counts as distribution of the source code, +even though third parties are not compelled to copy the source along with +the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except +as expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate +your rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses terminated +so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Program or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Program +(or any work based on the Program), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), +the recipient automatically receives a license from the original licensor +to copy, distribute or modify the Program subject to these terms and conditions. +You may not impose any further restrictions on the recipients' exercise of +the rights granted herein. You are not responsible for enforcing compliance +by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of +this License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Program at all. For example, if a +patent license would not permit royalty-free redistribution of the Program +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and +the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system, which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Program under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of +the General Public License from time to time. Such new versions will be similar +in spirit to the present version, but may differ in detail to address new +problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Program does not specify a version number of this License, you may choose +any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software Foundation, +write to the Free Software Foundation; we sometimes make exceptions for this. +Our decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing and reuse +of software generally. + + NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA +OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible +use to the public, the best way to achieve this is to make it free software +which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach +them to the start of each source file to most effectively convey the exclusion +of warranty; and each file should have at least the "copyright" line and a +pointer to where the full notice is found. + + + +Copyright (C) + +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. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when +it starts in an interactive mode: + +Gnomovision version 69, Copyright (C) year name of author Gnomovision comes +with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, +and you are welcome to redistribute it under certain conditions; type `show +c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may be +called something other than `show w' and `show c'; they could even be mouse-clicks +or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the program, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' +(which makes passes at compilers) written by James Hacker. + +, 1 April 1989 Ty Coon, President of Vice This General +Public License does not permit incorporating your program into proprietary +programs. If your program is a subroutine library, you may consider it more +useful to permit linking proprietary applications with the library. If this +is what you want to do, use the GNU Lesser General Public License instead +of this License. diff --git a/LICENSES/GPL-3.0-only.txt b/LICENSES/GPL-3.0-only.txt new file mode 100644 index 0000000..e142a52 --- /dev/null +++ b/LICENSES/GPL-3.0-only.txt @@ -0,0 +1,625 @@ +GNU GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and +other kinds of works. + +The licenses for most software and other practical works are designed to take +away your freedom to share and change the works. By contrast, the GNU General +Public License is intended to guarantee your freedom to share and change all +versions of a program--to make sure it remains free software for all its users. +We, the Free Software Foundation, use the GNU General Public License for most +of our software; it applies also to any other work released this way by its +authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for them if you wish), that +you receive source code or can get it if you want it, that you can change +the software or use pieces of it in new free programs, and that you know you +can do these things. + +To protect your rights, we need to prevent others from denying you these rights +or asking you to surrender the rights. Therefore, you have certain responsibilities +if you distribute copies of the software, or if you modify it: responsibilities +to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or +for a fee, you must pass on to the recipients the same freedoms that you received. +You must make sure that they, too, receive or can get the source code. And +you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert +copyright on the software, and (2) offer you this License giving you legal +permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that +there is no warranty for this free software. For both users' and authors' +sake, the GPL requires that modified versions be marked as changed, so that +their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified +versions of the software inside them, although the manufacturer can do so. +This is fundamentally incompatible with the aim of protecting users' freedom +to change the software. The systematic pattern of such abuse occurs in the +area of products for individuals to use, which is precisely where it is most +unacceptable. Therefore, we have designed this version of the GPL to prohibit +the practice for those products. If such problems arise substantially in other +domains, we stand ready to extend this provision to those domains in future +versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States +should not allow patents to restrict development and use of software on general-purpose +computers, but in those that do, we wish to avoid the special danger that +patents applied to a free program could make it effectively proprietary. To +prevent this, the GPL assures that patents cannot be used to render the program +non-free. + +The precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + +"Copyright" also means copyright-like laws that apply to other kinds of works, +such as semiconductor masks. + +"The Program" refers to any copyrightable work licensed under this License. +Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals +or organizations. + +To "modify" a work means to copy from or adapt all or part of the work in +a fashion requiring copyright permission, other than the making of an exact +copy. The resulting work is called a "modified version" of the earlier work +or a work "based on" the earlier work. + +A "covered work" means either the unmodified Program or a work based on the +Program. + +To "propagate" a work means to do anything with it that, without permission, +would make you directly or secondarily liable for infringement under applicable +copyright law, except executing it on a computer or modifying a private copy. +Propagation includes copying, distribution (with or without modification), +making available to the public, and in some countries other activities as +well. + +To "convey" a work means any kind of propagation that enables other parties +to make or receive copies. Mere interaction with a user through a computer +network, with no transfer of a copy, is not conveying. + +An interactive user interface displays "Appropriate Legal Notices" to the +extent that it includes a convenient and prominently visible feature that +(1) displays an appropriate copyright notice, and (2) tells the user that +there is no warranty for the work (except to the extent that warranties are +provided), that licensees may convey the work under this License, and how +to view a copy of this License. If the interface presents a list of user commands +or options, such as a menu, a prominent item in the list meets this criterion. + + 1. Source Code. + +The "source code" for a work means the preferred form of the work for making +modifications to it. "Object code" means any non-source form of a work. + +A "Standard Interface" means an interface that either is an official standard +defined by a recognized standards body, or, in the case of interfaces specified +for a particular programming language, one that is widely used among developers +working in that language. + +The "System Libraries" of an executable work include anything, other than +the work as a whole, that (a) is included in the normal form of packaging +a Major Component, but which is not part of that Major Component, and (b) +serves only to enable use of the work with that Major Component, or to implement +a Standard Interface for which an implementation is available to the public +in source code form. A "Major Component", in this context, means a major essential +component (kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to produce +the work, or an object code interpreter used to run it. + +The "Corresponding Source" for a work in object code form means all the source +code needed to generate, install, and (for an executable work) run the object +code and to modify the work, including scripts to control those activities. +However, it does not include the work's System Libraries, or general-purpose +tools or generally available free programs which are used unmodified in performing +those activities but which are not part of the work. For example, Corresponding +Source includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically linked +subprograms that the work is specifically designed to require, such as by +intimate data communication or control flow between those subprograms and +other parts of the work. + +The Corresponding Source need not include anything that users can regenerate +automatically from other parts of the Corresponding Source. + + The Corresponding Source for a work in source code form is that same work. + + 2. Basic Permissions. + +All rights granted under this License are granted for the term of copyright +on the Program, and are irrevocable provided the stated conditions are met. +This License explicitly affirms your unlimited permission to run the unmodified +Program. The output from running a covered work is covered by this License +only if the output, given its content, constitutes a covered work. This License +acknowledges your rights of fair use or other equivalent, as provided by copyright +law. + +You may make, run and propagate covered works that you do not convey, without +conditions so long as your license otherwise remains in force. You may convey +covered works to others for the sole purpose of having them make modifications +exclusively for you, or provide you with facilities for running those works, +provided that you comply with the terms of this License in conveying all material +for which you do not control copyright. Those thus making or running the covered +works for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of your copyrighted +material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions +stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + +No covered work shall be deemed part of an effective technological measure +under any applicable law fulfilling obligations under article 11 of the WIPO +copyright treaty adopted on 20 December 1996, or similar laws prohibiting +or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention +of technological measures to the extent such circumvention is effected by +exercising rights under this License with respect to the covered work, and +you disclaim any intention to limit operation or modification of the work +as a means of enforcing, against the work's users, your or third parties' +legal rights to forbid circumvention of technological measures. + + 4. Conveying Verbatim Copies. + +You may convey verbatim copies of the Program's source code as you receive +it, in any medium, provided that you conspicuously and appropriately publish +on each copy an appropriate copyright notice; keep intact all notices stating +that this License and any non-permissive terms added in accord with section +7 apply to the code; keep intact all notices of the absence of any warranty; +and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you +may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + +You may convey a work based on the Program, or the modifications to produce +it from the Program, in the form of source code under the terms of section +4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified it, and +giving a relevant date. + +b) The work must carry prominent notices stating that it is released under +this License and any conditions added under section 7. This requirement modifies +the requirement in section 4 to "keep intact all notices". + +c) You must license the entire work, as a whole, under this License to anyone +who comes into possession of a copy. This License will therefore apply, along +with any applicable section 7 additional terms, to the whole of the work, +and all its parts, regardless of how they are packaged. This License gives +no permission to license the work in any other way, but it does not invalidate +such permission if you have separately received it. + +d) If the work has interactive user interfaces, each must display Appropriate +Legal Notices; however, if the Program has interactive interfaces that do +not display Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, +which are not by their nature extensions of the covered work, and which are +not combined with it such as to form a larger program, in or on a volume of +a storage or distribution medium, is called an "aggregate" if the compilation +and its resulting copyright are not used to limit the access or legal rights +of the compilation's users beyond what the individual works permit. Inclusion +of a covered work in an aggregate does not cause this License to apply to +the other parts of the aggregate. + + 6. Conveying Non-Source Forms. + +You may convey a covered work in object code form under the terms of sections +4 and 5, provided that you also convey the machine-readable Corresponding +Source under the terms of this License, in one of these ways: + +a) Convey the object code in, or embodied in, a physical product (including +a physical distribution medium), accompanied by the Corresponding Source fixed +on a durable physical medium customarily used for software interchange. + +b) Convey the object code in, or embodied in, a physical product (including +a physical distribution medium), accompanied by a written offer, valid for +at least three years and valid for as long as you offer spare parts or customer +support for that product model, to give anyone who possesses the object code +either (1) a copy of the Corresponding Source for all the software in the +product that is covered by this License, on a durable physical medium customarily +used for software interchange, for a price no more than your reasonable cost +of physically performing this conveying of source, or (2) access to copy the +Corresponding Source from a network server at no charge. + +c) Convey individual copies of the object code with a copy of the written +offer to provide the Corresponding Source. This alternative is allowed only +occasionally and noncommercially, and only if you received the object code +with such an offer, in accord with subsection 6b. + +d) Convey the object code by offering access from a designated place (gratis +or for a charge), and offer equivalent access to the Corresponding Source +in the same way through the same place at no further charge. You need not +require recipients to copy the Corresponding Source along with the object +code. If the place to copy the object code is a network server, the Corresponding +Source may be on a different server (operated by you or a third party) that +supports equivalent copying facilities, provided you maintain clear directions +next to the object code saying where to find the Corresponding Source. Regardless +of what server hosts the Corresponding Source, you remain obligated to ensure +that it is available for as long as needed to satisfy these requirements. + +e) Convey the object code using peer-to-peer transmission, provided you inform +other peers where the object code and Corresponding Source of the work are +being offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from +the Corresponding Source as a System Library, need not be included in conveying +the object code work. + +A "User Product" is either (1) a "consumer product", which means any tangible +personal property which is normally used for personal, family, or household +purposes, or (2) anything designed or sold for incorporation into a dwelling. +In determining whether a product is a consumer product, doubtful cases shall +be resolved in favor of coverage. For a particular product received by a particular +user, "normally used" refers to a typical or common use of that class of product, +regardless of the status of the particular user or of the way in which the +particular user actually uses, or expects or is expected to use, the product. +A product is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent the +only significant mode of use of the product. + +"Installation Information" for a User Product means any methods, procedures, +authorization keys, or other information required to install and execute modified +versions of a covered work in that User Product from a modified version of +its Corresponding Source. The information must suffice to ensure that the +continued functioning of the modified object code is in no case prevented +or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically +for use in, a User Product, and the conveying occurs as part of a transaction +in which the right of possession and use of the User Product is transferred +to the recipient in perpetuity or for a fixed term (regardless of how the +transaction is characterized), the Corresponding Source conveyed under this +section must be accompanied by the Installation Information. But this requirement +does not apply if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has been installed +in ROM). + +The requirement to provide Installation Information does not include a requirement +to continue to provide support service, warranty, or updates for a work that +has been modified or installed by the recipient, or for the User Product in +which it has been modified or installed. Access to a network may be denied +when the modification itself materially and adversely affects the operation +of the network or violates the rules and protocols for communication across +the network. + +Corresponding Source conveyed, and Installation Information provided, in accord +with this section must be in a format that is publicly documented (and with +an implementation available to the public in source code form), and must require +no special password or key for unpacking, reading or copying. + + 7. Additional Terms. + +"Additional permissions" are terms that supplement the terms of this License +by making exceptions from one or more of its conditions. Additional permissions +that are applicable to the entire Program shall be treated as though they +were included in this License, to the extent that they are valid under applicable +law. If additional permissions apply only to part of the Program, that part +may be used separately under those permissions, but the entire Program remains +governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any +additional permissions from that copy, or from any part of it. (Additional +permissions may be written to require their own removal in certain cases when +you modify the work.) You may place additional permissions on material, added +by you to a covered work, for which you have or can give appropriate copyright +permission. + +Notwithstanding any other provision of this License, for material you add +to a covered work, you may (if authorized by the copyright holders of that +material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the terms of +sections 15 and 16 of this License; or + +b) Requiring preservation of specified reasonable legal notices or author +attributions in that material or in the Appropriate Legal Notices displayed +by works containing it; or + +c) Prohibiting misrepresentation of the origin of that material, or requiring +that modified versions of such material be marked in reasonable ways as different +from the original version; or + +d) Limiting the use for publicity purposes of names of licensors or authors +of the material; or + +e) Declining to grant rights under trademark law for use of some trade names, +trademarks, or service marks; or + +f) Requiring indemnification of licensors and authors of that material by +anyone who conveys the material (or modified versions of it) with contractual +assumptions of liability to the recipient, for any liability that these contractual +assumptions directly impose on those licensors and authors. + +All other non-permissive additional terms are considered "further restrictions" +within the meaning of section 10. If the Program as you received it, or any +part of it, contains a notice stating that it is governed by this License +along with a term that is a further restriction, you may remove that term. +If a license document contains a further restriction but permits relicensing +or conveying under this License, you may add to a covered work material governed +by the terms of that license document, provided that the further restriction +does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, +in the relevant source files, a statement of the additional terms that apply +to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form +of a separately written license, or stated as exceptions; the above requirements +apply either way. + + 8. Termination. + +You may not propagate or modify a covered work except as expressly provided +under this License. Any attempt otherwise to propagate or modify it is void, +and will automatically terminate your rights under this License (including +any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from +a particular copyright holder is reinstated (a) provisionally, unless and +until the copyright holder explicitly and finally terminates your license, +and (b) permanently, if the copyright holder fails to notify you of the violation +by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently +if the copyright holder notifies you of the violation by some reasonable means, +this is the first time you have received notice of violation of this License +(for any work) from that copyright holder, and you cure the violation prior +to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses +of parties who have received copies or rights from you under this License. +If your rights have been terminated and not permanently reinstated, you do +not qualify to receive new licenses for the same material under section 10. + + 9. Acceptance Not Required for Having Copies. + +You are not required to accept this License in order to receive or run a copy +of the Program. Ancillary propagation of a covered work occurring solely as +a consequence of using peer-to-peer transmission to receive a copy likewise +does not require acceptance. However, nothing other than this License grants +you permission to propagate or modify any covered work. These actions infringe +copyright if you do not accept this License. Therefore, by modifying or propagating +a covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + +Each time you convey a covered work, the recipient automatically receives +a license from the original licensors, to run, modify and propagate that work, +subject to this License. You are not responsible for enforcing compliance +by third parties with this License. + +An "entity transaction" is a transaction transferring control of an organization, +or substantially all assets of one, or subdividing an organization, or merging +organizations. If propagation of a covered work results from an entity transaction, +each party to that transaction who receives a copy of the work also receives +whatever licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the Corresponding +Source of the work from the predecessor in interest, if the predecessor has +it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights +granted or affirmed under this License. For example, you may not impose a +license fee, royalty, or other charge for exercise of rights granted under +this License, and you may not initiate litigation (including a cross-claim +or counterclaim in a lawsuit) alleging that any patent claim is infringed +by making, using, selling, offering for sale, or importing the Program or +any portion of it. + + 11. Patents. + +A "contributor" is a copyright holder who authorizes use under this License +of the Program or a work on which the Program is based. The work thus licensed +is called the contributor's "contributor version". + +A contributor's "essential patent claims" are all patent claims owned or controlled +by the contributor, whether already acquired or hereafter acquired, that would +be infringed by some manner, permitted by this License, of making, using, +or selling its contributor version, but do not include claims that would be +infringed only as a consequence of further modification of the contributor +version. For purposes of this definition, "control" includes the right to +grant patent sublicenses in a manner consistent with the requirements of this +License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent +license under the contributor's essential patent claims, to make, use, sell, +offer for sale, import and otherwise run, modify and propagate the contents +of its contributor version. + +In the following three paragraphs, a "patent license" is any express agreement +or commitment, however denominated, not to enforce a patent (such as an express +permission to practice a patent or covenant not to sue for patent infringement). +To "grant" such a patent license to a party means to make such an agreement +or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the +Corresponding Source of the work is not available for anyone to copy, free +of charge and under the terms of this License, through a publicly available +network server or other readily accessible means, then you must either (1) +cause the Corresponding Source to be so available, or (2) arrange to deprive +yourself of the benefit of the patent license for this particular work, or +(3) arrange, in a manner consistent with the requirements of this License, +to extend the patent license to downstream recipients. "Knowingly relying" +means you have actual knowledge that, but for the patent license, your conveying +the covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that country +that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, +you convey, or propagate by procuring conveyance of, a covered work, and grant +a patent license to some of the parties receiving the covered work authorizing +them to use, propagate, modify or convey a specific copy of the covered work, +then the patent license you grant is automatically extended to all recipients +of the covered work and works based on it. + +A patent license is "discriminatory" if it does not include within the scope +of its coverage, prohibits the exercise of, or is conditioned on the non-exercise +of one or more of the rights that are specifically granted under this License. +You may not convey a covered work if you are a party to an arrangement with +a third party that is in the business of distributing software, under which +you make payment to the third party based on the extent of your activity of +conveying the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory patent +license (a) in connection with copies of the covered work conveyed by you +(or copies made from those copies), or (b) primarily for and in connection +with specific products or compilations that contain the covered work, unless +you entered into that arrangement, or that patent license was granted, prior +to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied +license or other defenses to infringement that may otherwise be available +to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + +If conditions are imposed on you (whether by court order, agreement or otherwise) +that contradict the conditions of this License, they do not excuse you from +the conditions of this License. If you cannot convey a covered work so as +to satisfy simultaneously your obligations under this License and any other +pertinent obligations, then as a consequence you may not convey it at all. +For example, if you agree to terms that obligate you to collect a royalty +for further conveying from those to whom you convey the Program, the only +way you could satisfy both those terms and this License would be to refrain +entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + +Notwithstanding any other provision of this License, you have permission to +link or combine any covered work with a work licensed under version 3 of the +GNU Affero General Public License into a single combined work, and to convey +the resulting work. The terms of this License will continue to apply to the +part which is the covered work, but the special requirements of the GNU Affero +General Public License, section 13, concerning interaction through a network +will apply to the combination as such. + + 14. Revised Versions of this License. + +The Free Software Foundation may publish revised and/or new versions of the +GNU General Public License from time to time. Such new versions will be similar +in spirit to the present version, but may differ in detail to address new +problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies +that a certain numbered version of the GNU General Public License "or any +later version" applies to it, you have the option of following the terms and +conditions either of that numbered version or of any later version published +by the Free Software Foundation. If the Program does not specify a version +number of the GNU General Public License, you may choose any version ever +published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of +the GNU General Public License can be used, that proxy's public statement +of acceptance of a version permanently authorizes you to choose that version +for the Program. + +Later license versions may give you additional or different permissions. However, +no additional obligations are imposed on any author or copyright holder as +a result of your choosing to follow a later version. + + 15. Disclaimer of Warranty. + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE +LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM +PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR +CORRECTION. + + 16. Limitation of Liability. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL +ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM +AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, +INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO +USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED +INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE +PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER +PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + +If the disclaimer of warranty and limitation of liability provided above cannot +be given local legal effect according to their terms, reviewing courts shall +apply local law that most closely approximates an absolute waiver of all civil +liability in connection with the Program, unless a warranty or assumption +of liability accompanies a copy of the Program in return for a fee. END OF +TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible +use to the public, the best way to achieve this is to make it free software +which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach +them to the start of each source file to most effectively state the exclusion +of warranty; and each file should have at least the "copyright" line and a +pointer to where the full notice is found. + + + +Copyright (C) + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + +If the program does terminal interaction, make it output a short notice like +this when it starts in an interactive mode: + + Copyright (C) + +This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + +This is free software, and you are welcome to redistribute it under certain +conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands might +be different; for a GUI interface, you would use an "about box". + +You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. For +more information on this, and how to apply and follow the GNU GPL, see . + +The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General Public +License instead of this License. But first, please read . diff --git a/LICENSES/LGPL-2.0-or-later.txt b/LICENSES/LGPL-2.0-or-later.txt new file mode 100644 index 0000000..5c96471 --- /dev/null +++ b/LICENSES/LGPL-2.0-or-later.txt @@ -0,0 +1,446 @@ +GNU LIBRARY GENERAL PUBLIC LICENSE + +Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. + +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is numbered 2 because +it goes with version 2 of the ordinary GPL.] + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public Licenses are intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. + +This license, the Library General Public License, applies to some specially +designated Free Software Foundation software, and to any other libraries whose +authors decide to use it. You can use it for your libraries, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you +wish), that you receive source code or can get it if you want it, that you +can change the software or use pieces of it in new free programs; and that +you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the library, or if you modify it. + +For example, if you distribute copies of the library, whether gratis or for +a fee, you must give the recipients all the rights that we gave you. You must +make sure that they, too, receive or can get the source code. If you link +a program with the library, you must provide complete object files to the +recipients so that they can relink them with the library, after making changes +to the library and recompiling it. And you must show them these terms so they +know their rights. + +Our method of protecting your rights has two steps: (1) copyright the library, +and (2) offer you this license which gives you legal permission to copy, distribute +and/or modify the library. + +Also, for each distributor's protection, we want to make certain that everyone +understands that there is no warranty for this free library. If the library +is modified by someone else and passed on, we want its recipients to know +that what they have is not the original version, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that companies distributing free software will individually +obtain patent licenses, thus in effect transforming the program into proprietary +software. To prevent this, we have made it clear that any patent must be licensed +for everyone's free use or not licensed at all. + +Most GNU software, including some libraries, is covered by the ordinary GNU +General Public License, which was designed for utility programs. This license, +the GNU Library General Public License, applies to certain designated libraries. +This license is quite different from the ordinary one; be sure to read it +in full, and don't assume that anything in it is the same as in the ordinary +license. + +The reason we have a separate public license for some libraries is that they +blur the distinction we usually make between modifying or adding to a program +and simply using it. Linking a program with a library, without changing the +library, is in some sense simply using the library, and is analogous to running +a utility program or application program. However, in a textual and legal +sense, the linked executable is a combined work, a derivative of the original +library, and the ordinary General Public License treats it as such. + +Because of this blurred distinction, using the ordinary General Public License +for libraries did not effectively promote software sharing, because most developers +did not use the libraries. We concluded that weaker conditions might promote +sharing better. + +However, unrestricted linking of non-free programs would deprive the users +of those programs of all benefit from the free status of the libraries themselves. +This Library General Public License is intended to permit developers of non-free +programs to use free libraries, while preserving your freedom as a user of +such programs to change the free libraries that are incorporated in them. +(We have not seen how to achieve this as regards changes in header files, +but we have achieved it as regards changes in the actual functions of the +Library.) The hope is that this will lead to faster development of free libraries. + +The precise terms and conditions for copying, distribution and modification +follow. Pay close attention to the difference between a "work based on the +library" and a "work that uses the library". The former contains code derived +from the library, while the latter only works together with the library. + +Note that it is possible for a library to be covered by the ordinary General +Public License rather than by this special one. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library which contains a +notice placed by the copyright holder or other authorized party saying it +may be distributed under the terms of this Library General Public License +(also called "this License"). Each licensee is addressed as "you". + +A "library" means a collection of software functions and/or data prepared +so as to be conveniently linked with application programs (which use some +of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work which has +been distributed under these terms. A "work based on the Library" means either +the Library or any derivative work under copyright law: that is to say, a +work containing the Library or a portion of it, either verbatim or with modifications +and/or translated straightforwardly into another language. (Hereinafter, translation +is included without limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for making modifications +to it. For a library, complete source code means all the source code for all +modules it contains, plus any associated interface definition files, plus +the scripts used to control compilation and installation of the library. + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running a program +using the Library is not restricted, and output from such a program is covered +only if its contents constitute a work based on the Library (independent of +the use of the Library in a tool for writing it). Whether that is true depends +on what the Library does and what the program that uses the Library does. + +1. You may copy and distribute verbatim copies of the Library's complete source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and disclaimer +of warranty; keep intact all the notices that refer to this License and to +the absence of any warranty; and distribute a copy of this License along with +the Library. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Library or any portion of it, +thus forming a work based on the Library, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + + a) The modified work must itself be a software library. + +b) You must cause the files modified to carry prominent notices stating that +you changed the files and the date of any change. + +c) You must cause the whole of the work to be licensed at no charge to all +third parties under the terms of this License. + +d) If a facility in the modified Library refers to a function or a table of +data to be supplied by an application program that uses the facility, other +than as an argument passed when the facility is invoked, then you must make +a good faith effort to ensure that, in the event an application does not supply +such function or table, the facility still operates, and performs whatever +part of its purpose remains meaningful. + +(For example, a function in a library to compute square roots has a purpose +that is entirely well-defined independent of the application. Therefore, Subsection +2d requires that any application-supplied function or table used by this function +must be optional: if the application does not supply it, the square root function +must still compute square roots.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Library, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Library. + +In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may opt to apply the terms of the ordinary GNU General Public License +instead of this License to a given copy of the Library. To do this, you must +alter all the notices that refer to this License, so that they refer to the +ordinary GNU General Public License, version 2, instead of to this License. +(If a newer version than version 2 of the ordinary GNU General Public License +has appeared, then you can specify that version instead if you wish.) Do not +make any other change in these notices. + +Once this change is made in a given copy, it is irreversible for that copy, +so the ordinary GNU General Public License applies to all subsequent copies +and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of the Library +into a program that is not a library. + +4. You may copy and distribute the Library (or a portion or derivative of +it, under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you accompany it with the complete corresponding +machine-readable source code, which must be distributed under the terms of +Sections 1 and 2 above on a medium customarily used for software interchange. + +If distribution of object code is made by offering access to copy from a designated +place, then offering equivalent access to copy the source code from the same +place satisfies the requirement to distribute the source code, even though +third parties are not compelled to copy the source along with the object code. + +5. A program that contains no derivative of any portion of the Library, but +is designed to work with the Library by being compiled or linked with it, +is called a "work that uses the Library". Such a work, in isolation, is not +a derivative work of the Library, and therefore falls outside the scope of +this License. + +However, linking a "work that uses the Library" with the Library creates an +executable that is a derivative of the Library (because it contains portions +of the Library), rather than a "work that uses the library". The executable +is therefore covered by this License. Section 6 states terms for distribution +of such executables. + +When a "work that uses the Library" uses material from a header file that +is part of the Library, the object code for the work may be a derivative work +of the Library even though the source code is not. Whether this is true is +especially significant if the work can be linked without the Library, or if +the work is itself a library. The threshold for this to be true is not precisely +defined by law. + +If such an object file uses only numerical parameters, data structure layouts +and accessors, and small macros and small inline functions (ten lines or less +in length), then the use of the object file is unrestricted, regardless of +whether it is legally a derivative work. (Executables containing this object +code plus portions of the Library will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may distribute +the object code for the work under the terms of Section 6. Any executables +containing that work also fall under Section 6, whether or not they are linked +directly with the Library itself. + +6. As an exception to the Sections above, you may also compile or link a "work +that uses the Library" with the Library to produce a work containing portions +of the Library, and distribute that work under terms of your choice, provided +that the terms permit modification of the work for the customer's own use +and reverse engineering for debugging such modifications. + +You must give prominent notice with each copy of the work that the Library +is used in it and that the Library and its use are covered by this License. +You must supply a copy of this License. If the work during execution displays +copyright notices, you must include the copyright notice for the Library among +them, as well as a reference directing the user to the copy of this License. +Also, you must do one of these things: + +a) Accompany the work with the complete corresponding machine-readable source +code for the Library including whatever changes were used in the work (which +must be distributed under Sections 1 and 2 above); and, if the work is an +executable linked with the Library, with the complete machine-readable "work +that uses the Library", as object code and/or source code, so that the user +can modify the Library and then relink to produce a modified executable containing +the modified Library. (It is understood that the user who changes the contents +of definitions files in the Library will not necessarily be able to recompile +the application to use the modified definitions.) + +b) Accompany the work with a written offer, valid for at least three years, +to give the same user the materials specified in Subsection 6a, above, for +a charge no more than the cost of performing this distribution. + +c) If distribution of the work is made by offering access to copy from a designated +place, offer equivalent access to copy the above specified materials from +the same place. + +d) Verify that the user has already received a copy of these materials or +that you have already sent this user a copy. + +For an executable, the required form of the "work that uses the Library" must +include any data and utility programs needed for reproducing the executable +from it. However, as a special exception, the source code distributed need +not include anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the operating +system on which the executable runs, unless that component itself accompanies +the executable. + +It may happen that this requirement contradicts the license restrictions of +other proprietary libraries that do not normally accompany the operating system. +Such a contradiction means you cannot use both them and the Library together +in an executable that you distribute. + +7. You may place library facilities that are a work based on the Library side-by-side +in a single library together with other library facilities not covered by +this License, and distribute such a combined library, provided that the separate +distribution of the work based on the Library and of the other library facilities +is otherwise permitted, and provided that you do these two things: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities. This must be distributed +under the terms of the Sections above. + +b) Give prominent notice with the combined library of the fact that part of +it is a work based on the Library, and explaining where to find the accompanying +uncombined form of the same work. + +8. You may not copy, modify, sublicense, link with, or distribute the Library +except as expressly provided under this License. Any attempt otherwise to +copy, modify, sublicense, link with, or distribute the Library is void, and +will automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +9. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Library or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Library +(or any work based on the Library), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +10. Each time you redistribute the Library (or any work based on the Library), +the recipient automatically receives a license from the original licensor +to copy, distribute, link with or modify the Library subject to these terms +and conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties to this License. + +11. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of +this License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Library at all. For example, if a +patent license would not permit royalty-free redistribution of the Library +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +12. If the distribution and/or use of the Library is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Library under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +13. The Free Software Foundation may publish revised and/or new versions of +the Library General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Library specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Library does not specify a license version number, you may choose any version +ever published by the Free Software Foundation. + +14. If you wish to incorporate parts of the Library into other free programs +whose distribution conditions are incompatible with these, write to the author +to ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make exceptions +for this. Our decision will be guided by the two goals of preserving the free +status of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA +OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest possible +use to the public, we recommend making it free software that everyone can +redistribute and change. You can do so by permitting redistribution under +these terms (or, alternatively, under the terms of the ordinary General Public +License). + +To apply these terms, attach the following notices to the library. It is safest +to attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the "copyright" +line and a pointer to where the full notice is found. + +one line to give the library's name and an idea of what it does. + +Copyright (C) year name of author + +This library is free software; you can redistribute it and/or modify it under +the terms of the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. + +This library 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 Library General Public License for more +details. + +You should have received a copy of the GNU Library General Public License +along with this library; if not, write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the library, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in + +the library `Frob' (a library for tweaking knobs) written + +by James Random Hacker. + +signature of Ty Coon, 1 April 1990 + +Ty Coon, President of Vice + +That's all there is to it! diff --git a/LICENSES/LGPL-2.1-only.txt b/LICENSES/LGPL-2.1-only.txt new file mode 100644 index 0000000..130dffb --- /dev/null +++ b/LICENSES/LGPL-2.1-only.txt @@ -0,0 +1,467 @@ +GNU LESSER GENERAL PUBLIC LICENSE + +Version 2.1, February 1999 + +Copyright (C) 1991, 1999 Free Software Foundation, Inc. + +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts as the +successor of the GNU Library Public License, version 2, hence the version +number 2.1.] + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public Licenses are intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. + +This license, the Lesser General Public License, applies to some specially +designated software packages--typically libraries--of the Free Software Foundation +and other authors who decide to use it. You can use it too, but we suggest +you first think carefully about whether this license or the ordinary General +Public License is the better strategy to use in any particular case, based +on the explanations below. + +When we speak of free software, we are referring to freedom of use, not price. +Our General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you +wish); that you receive source code or can get it if you want it; that you +can change the software and use pieces of it in new free programs; and that +you are informed that you can do these things. + +To protect your rights, we need to make restrictions that forbid distributors +to deny you these rights or to ask you to surrender these rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the library or if you modify it. + +For example, if you distribute copies of the library, whether gratis or for +a fee, you must give the recipients all the rights that we gave you. You must +make sure that they, too, receive or can get the source code. If you link +other code with the library, you must provide complete object files to the +recipients, so that they can relink them with the library after making changes +to the library and recompiling it. And you must show them these terms so they +know their rights. + +We protect your rights with a two-step method: (1) we copyright the library, +and (2) we offer you this license, which gives you legal permission to copy, +distribute and/or modify the library. + +To protect each distributor, we want to make it very clear that there is no +warranty for the free library. Also, if the library is modified by someone +else and passed on, the recipients should know that what they have is not +the original version, so that the original author's reputation will not be +affected by problems that might be introduced by others. + +Finally, software patents pose a constant threat to the existence of any free +program. We wish to make sure that a company cannot effectively restrict the +users of a free program by obtaining a restrictive license from a patent holder. +Therefore, we insist that any patent license obtained for a version of the +library must be consistent with the full freedom of use specified in this +license. + +Most GNU software, including some libraries, is covered by the ordinary GNU +General Public License. This license, the GNU Lesser General Public License, +applies to certain designated libraries, and is quite different from the ordinary +General Public License. We use this license for certain libraries in order +to permit linking those libraries into non-free programs. + +When a program is linked with a library, whether statically or using a shared +library, the combination of the two is legally speaking a combined work, a +derivative of the original library. The ordinary General Public License therefore +permits such linking only if the entire combination fits its criteria of freedom. +The Lesser General Public License permits more lax criteria for linking other +code with the library. + +We call this license the "Lesser" General Public License because it does Less +to protect the user's freedom than the ordinary General Public License. It +also provides other free software developers Less of an advantage over competing +non-free programs. These disadvantages are the reason we use the ordinary +General Public License for many libraries. However, the Lesser license provides +advantages in certain special circumstances. + +For example, on rare occasions, there may be a special need to encourage the +widest possible use of a certain library, so that it becomes a de-facto standard. +To achieve this, non-free programs must be allowed to use the library. A more +frequent case is that a free library does the same job as widely used non-free +libraries. In this case, there is little to gain by limiting the free library +to free software only, so we use the Lesser General Public License. + +In other cases, permission to use a particular library in non-free programs +enables a greater number of people to use a large body of free software. For +example, permission to use the GNU C Library in non-free programs enables +many more people to use the whole GNU operating system, as well as its variant, +the GNU/Linux operating system. + +Although the Lesser General Public License is Less protective of the users' +freedom, it does ensure that the user of a program that is linked with the +Library has the freedom and the wherewithal to run that program using a modified +version of the Library. + +The precise terms and conditions for copying, distribution and modification +follow. Pay close attention to the difference between a "work based on the +library" and a "work that uses the library". The former contains code derived +from the library, whereas the latter must be combined with the library in +order to run. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library or other program +which contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Lesser General +Public License (also called "this License"). Each licensee is addressed as +"you". + +A "library" means a collection of software functions and/or data prepared +so as to be conveniently linked with application programs (which use some +of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work which has +been distributed under these terms. A "work based on the Library" means either +the Library or any derivative work under copyright law: that is to say, a +work containing the Library or a portion of it, either verbatim or with modifications +and/or translated straightforwardly into another language. (Hereinafter, translation +is included without limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for making modifications +to it. For a library, complete source code means all the source code for all +modules it contains, plus any associated interface definition files, plus +the scripts used to control compilation and installation of the library. + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running a program +using the Library is not restricted, and output from such a program is covered +only if its contents constitute a work based on the Library (independent of +the use of the Library in a tool for writing it). Whether that is true depends +on what the Library does and what the program that uses the Library does. + +1. You may copy and distribute verbatim copies of the Library's complete source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and disclaimer +of warranty; keep intact all the notices that refer to this License and to +the absence of any warranty; and distribute a copy of this License along with +the Library. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Library or any portion of it, +thus forming a work based on the Library, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + + a) The modified work must itself be a software library. + +b) You must cause the files modified to carry prominent notices stating that +you changed the files and the date of any change. + +c) You must cause the whole of the work to be licensed at no charge to all +third parties under the terms of this License. + +d) If a facility in the modified Library refers to a function or a table of +data to be supplied by an application program that uses the facility, other +than as an argument passed when the facility is invoked, then you must make +a good faith effort to ensure that, in the event an application does not supply +such function or table, the facility still operates, and performs whatever +part of its purpose remains meaningful. + +(For example, a function in a library to compute square roots has a purpose +that is entirely well-defined independent of the application. Therefore, Subsection +2d requires that any application-supplied function or table used by this function +must be optional: if the application does not supply it, the square root function +must still compute square roots.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Library, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Library. + +In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may opt to apply the terms of the ordinary GNU General Public License +instead of this License to a given copy of the Library. To do this, you must +alter all the notices that refer to this License, so that they refer to the +ordinary GNU General Public License, version 2, instead of to this License. +(If a newer version than version 2 of the ordinary GNU General Public License +has appeared, then you can specify that version instead if you wish.) Do not +make any other change in these notices. + +Once this change is made in a given copy, it is irreversible for that copy, +so the ordinary GNU General Public License applies to all subsequent copies +and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of the Library +into a program that is not a library. + +4. You may copy and distribute the Library (or a portion or derivative of +it, under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you accompany it with the complete corresponding +machine-readable source code, which must be distributed under the terms of +Sections 1 and 2 above on a medium customarily used for software interchange. + +If distribution of object code is made by offering access to copy from a designated +place, then offering equivalent access to copy the source code from the same +place satisfies the requirement to distribute the source code, even though +third parties are not compelled to copy the source along with the object code. + +5. A program that contains no derivative of any portion of the Library, but +is designed to work with the Library by being compiled or linked with it, +is called a "work that uses the Library". Such a work, in isolation, is not +a derivative work of the Library, and therefore falls outside the scope of +this License. + +However, linking a "work that uses the Library" with the Library creates an +executable that is a derivative of the Library (because it contains portions +of the Library), rather than a "work that uses the library". The executable +is therefore covered by this License. Section 6 states terms for distribution +of such executables. + +When a "work that uses the Library" uses material from a header file that +is part of the Library, the object code for the work may be a derivative work +of the Library even though the source code is not. Whether this is true is +especially significant if the work can be linked without the Library, or if +the work is itself a library. The threshold for this to be true is not precisely +defined by law. + +If such an object file uses only numerical parameters, data structure layouts +and accessors, and small macros and small inline functions (ten lines or less +in length), then the use of the object file is unrestricted, regardless of +whether it is legally a derivative work. (Executables containing this object +code plus portions of the Library will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may distribute +the object code for the work under the terms of Section 6. Any executables +containing that work also fall under Section 6, whether or not they are linked +directly with the Library itself. + +6. As an exception to the Sections above, you may also combine or link a "work +that uses the Library" with the Library to produce a work containing portions +of the Library, and distribute that work under terms of your choice, provided +that the terms permit modification of the work for the customer's own use +and reverse engineering for debugging such modifications. + +You must give prominent notice with each copy of the work that the Library +is used in it and that the Library and its use are covered by this License. +You must supply a copy of this License. If the work during execution displays +copyright notices, you must include the copyright notice for the Library among +them, as well as a reference directing the user to the copy of this License. +Also, you must do one of these things: + +a) Accompany the work with the complete corresponding machine-readable source +code for the Library including whatever changes were used in the work (which +must be distributed under Sections 1 and 2 above); and, if the work is an +executable linked with the Library, with the complete machine-readable "work +that uses the Library", as object code and/or source code, so that the user +can modify the Library and then relink to produce a modified executable containing +the modified Library. (It is understood that the user who changes the contents +of definitions files in the Library will not necessarily be able to recompile +the application to use the modified definitions.) + +b) Use a suitable shared library mechanism for linking with the Library. A +suitable mechanism is one that (1) uses at run time a copy of the library +already present on the user's computer system, rather than copying library +functions into the executable, and (2) will operate properly with a modified +version of the library, if the user installs one, as long as the modified +version is interface-compatible with the version that the work was made with. + +c) Accompany the work with a written offer, valid for at least three years, +to give the same user the materials specified in Subsection 6a, above, for +a charge no more than the cost of performing this distribution. + +d) If distribution of the work is made by offering access to copy from a designated +place, offer equivalent access to copy the above specified materials from +the same place. + +e) Verify that the user has already received a copy of these materials or +that you have already sent this user a copy. + +For an executable, the required form of the "work that uses the Library" must +include any data and utility programs needed for reproducing the executable +from it. However, as a special exception, the materials to be distributed +need not include anything that is normally distributed (in either source or +binary form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component itself +accompanies the executable. + +It may happen that this requirement contradicts the license restrictions of +other proprietary libraries that do not normally accompany the operating system. +Such a contradiction means you cannot use both them and the Library together +in an executable that you distribute. + +7. You may place library facilities that are a work based on the Library side-by-side +in a single library together with other library facilities not covered by +this License, and distribute such a combined library, provided that the separate +distribution of the work based on the Library and of the other library facilities +is otherwise permitted, and provided that you do these two things: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities. This must be distributed +under the terms of the Sections above. + +b) Give prominent notice with the combined library of the fact that part of +it is a work based on the Library, and explaining where to find the accompanying +uncombined form of the same work. + +8. You may not copy, modify, sublicense, link with, or distribute the Library +except as expressly provided under this License. Any attempt otherwise to +copy, modify, sublicense, link with, or distribute the Library is void, and +will automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +9. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Library or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Library +(or any work based on the Library), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +10. Each time you redistribute the Library (or any work based on the Library), +the recipient automatically receives a license from the original licensor +to copy, distribute, link with or modify the Library subject to these terms +and conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties with this License. + +11. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of +this License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Library at all. For example, if a +patent license would not permit royalty-free redistribution of the Library +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +12. If the distribution and/or use of the Library is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Library under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +13. The Free Software Foundation may publish revised and/or new versions of +the Lesser General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Library specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Library does not specify a license version number, you may choose any version +ever published by the Free Software Foundation. + +14. If you wish to incorporate parts of the Library into other free programs +whose distribution conditions are incompatible with these, write to the author +to ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make exceptions +for this. Our decision will be guided by the two goals of preserving the free +status of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA +OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest possible +use to the public, we recommend making it free software that everyone can +redistribute and change. You can do so by permitting redistribution under +these terms (or, alternatively, under the terms of the ordinary General Public +License). + +To apply these terms, attach the following notices to the library. It is safest +to attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the "copyright" +line and a pointer to where the full notice is found. + +< one line to give the library's name and an idea of what it does. > + +Copyright (C) < year > < name of author > + +This library is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free +Software Foundation; either version 2.1 of the License, or (at your option) +any later version. + +This library 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 Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with this library; if not, write to the Free Software Foundation, Inc., 51 +Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information +on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the library, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in + +the library `Frob' (a library for tweaking knobs) written + +by James Random Hacker. + +< signature of Ty Coon > , 1 April 1990 + +Ty Coon, President of Vice + +That's all there is to it! diff --git a/LICENSES/LGPL-2.1-or-later.txt b/LICENSES/LGPL-2.1-or-later.txt new file mode 100644 index 0000000..04bb156 --- /dev/null +++ b/LICENSES/LGPL-2.1-or-later.txt @@ -0,0 +1,468 @@ +GNU LESSER GENERAL PUBLIC LICENSE + +Version 2.1, February 1999 + +Copyright (C) 1991, 1999 Free Software Foundation, Inc. + +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts as the +successor of the GNU Library Public License, version 2, hence the version +number 2.1.] + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public Licenses are intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. + +This license, the Lesser General Public License, applies to some specially +designated software packages--typically libraries--of the Free Software Foundation +and other authors who decide to use it. You can use it too, but we suggest +you first think carefully about whether this license or the ordinary General +Public License is the better strategy to use in any particular case, based +on the explanations below. + +When we speak of free software, we are referring to freedom of use, not price. +Our General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you +wish); that you receive source code or can get it if you want it; that you +can change the software and use pieces of it in new free programs; and that +you are informed that you can do these things. + +To protect your rights, we need to make restrictions that forbid distributors +to deny you these rights or to ask you to surrender these rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the library or if you modify it. + +For example, if you distribute copies of the library, whether gratis or for +a fee, you must give the recipients all the rights that we gave you. You must +make sure that they, too, receive or can get the source code. If you link +other code with the library, you must provide complete object files to the +recipients, so that they can relink them with the library after making changes +to the library and recompiling it. And you must show them these terms so they +know their rights. + +We protect your rights with a two-step method: (1) we copyright the library, +and (2) we offer you this license, which gives you legal permission to copy, +distribute and/or modify the library. + +To protect each distributor, we want to make it very clear that there is no +warranty for the free library. Also, if the library is modified by someone +else and passed on, the recipients should know that what they have is not +the original version, so that the original author's reputation will not be +affected by problems that might be introduced by others. + +Finally, software patents pose a constant threat to the existence of any free +program. We wish to make sure that a company cannot effectively restrict the +users of a free program by obtaining a restrictive license from a patent holder. +Therefore, we insist that any patent license obtained for a version of the +library must be consistent with the full freedom of use specified in this +license. + +Most GNU software, including some libraries, is covered by the ordinary GNU +General Public License. This license, the GNU Lesser General Public License, +applies to certain designated libraries, and is quite different from the ordinary +General Public License. We use this license for certain libraries in order +to permit linking those libraries into non-free programs. + +When a program is linked with a library, whether statically or using a shared +library, the combination of the two is legally speaking a combined work, a +derivative of the original library. The ordinary General Public License therefore +permits such linking only if the entire combination fits its criteria of freedom. +The Lesser General Public License permits more lax criteria for linking other +code with the library. + +We call this license the "Lesser" General Public License because it does Less +to protect the user's freedom than the ordinary General Public License. It +also provides other free software developers Less of an advantage over competing +non-free programs. These disadvantages are the reason we use the ordinary +General Public License for many libraries. However, the Lesser license provides +advantages in certain special circumstances. + +For example, on rare occasions, there may be a special need to encourage the +widest possible use of a certain library, so that it becomes a de-facto standard. +To achieve this, non-free programs must be allowed to use the library. A more +frequent case is that a free library does the same job as widely used non-free +libraries. In this case, there is little to gain by limiting the free library +to free software only, so we use the Lesser General Public License. + +In other cases, permission to use a particular library in non-free programs +enables a greater number of people to use a large body of free software. For +example, permission to use the GNU C Library in non-free programs enables +many more people to use the whole GNU operating system, as well as its variant, +the GNU/Linux operating system. + +Although the Lesser General Public License is Less protective of the users' +freedom, it does ensure that the user of a program that is linked with the +Library has the freedom and the wherewithal to run that program using a modified +version of the Library. + +The precise terms and conditions for copying, distribution and modification +follow. Pay close attention to the difference between a "work based on the +library" and a "work that uses the library". The former contains code derived +from the library, whereas the latter must be combined with the library in +order to run. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library or other program +which contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Lesser General +Public License (also called "this License"). Each licensee is addressed as +"you". + +A "library" means a collection of software functions and/or data prepared +so as to be conveniently linked with application programs (which use some +of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work which has +been distributed under these terms. A "work based on the Library" means either +the Library or any derivative work under copyright law: that is to say, a +work containing the Library or a portion of it, either verbatim or with modifications +and/or translated straightforwardly into another language. (Hereinafter, translation +is included without limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for making modifications +to it. For a library, complete source code means all the source code for all +modules it contains, plus any associated interface definition files, plus +the scripts used to control compilation and installation of the library. + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running a program +using the Library is not restricted, and output from such a program is covered +only if its contents constitute a work based on the Library (independent of +the use of the Library in a tool for writing it). Whether that is true depends +on what the Library does and what the program that uses the Library does. + +1. You may copy and distribute verbatim copies of the Library's complete source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and disclaimer +of warranty; keep intact all the notices that refer to this License and to +the absence of any warranty; and distribute a copy of this License along with +the Library. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Library or any portion of it, +thus forming a work based on the Library, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + + a) The modified work must itself be a software library. + +b) You must cause the files modified to carry prominent notices stating that +you changed the files and the date of any change. + +c) You must cause the whole of the work to be licensed at no charge to all +third parties under the terms of this License. + +d) If a facility in the modified Library refers to a function or a table of +data to be supplied by an application program that uses the facility, other +than as an argument passed when the facility is invoked, then you must make +a good faith effort to ensure that, in the event an application does not supply +such function or table, the facility still operates, and performs whatever +part of its purpose remains meaningful. + +(For example, a function in a library to compute square roots has a purpose +that is entirely well-defined independent of the application. Therefore, Subsection +2d requires that any application-supplied function or table used by this function +must be optional: if the application does not supply it, the square root function +must still compute square roots.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Library, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Library. + +In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may opt to apply the terms of the ordinary GNU General Public License +instead of this License to a given copy of the Library. To do this, you must +alter all the notices that refer to this License, so that they refer to the +ordinary GNU General Public License, version 2, instead of to this License. +(If a newer version than version 2 of the ordinary GNU General Public License +has appeared, then you can specify that version instead if you wish.) Do not +make any other change in these notices. + +Once this change is made in a given copy, it is irreversible for that copy, +so the ordinary GNU General Public License applies to all subsequent copies +and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of the Library +into a program that is not a library. + +4. You may copy and distribute the Library (or a portion or derivative of +it, under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you accompany it with the complete corresponding +machine-readable source code, which must be distributed under the terms of +Sections 1 and 2 above on a medium customarily used for software interchange. + +If distribution of object code is made by offering access to copy from a designated +place, then offering equivalent access to copy the source code from the same +place satisfies the requirement to distribute the source code, even though +third parties are not compelled to copy the source along with the object code. + +5. A program that contains no derivative of any portion of the Library, but +is designed to work with the Library by being compiled or linked with it, +is called a "work that uses the Library". Such a work, in isolation, is not +a derivative work of the Library, and therefore falls outside the scope of +this License. + +However, linking a "work that uses the Library" with the Library creates an +executable that is a derivative of the Library (because it contains portions +of the Library), rather than a "work that uses the library". The executable +is therefore covered by this License. Section 6 states terms for distribution +of such executables. + +When a "work that uses the Library" uses material from a header file that +is part of the Library, the object code for the work may be a derivative work +of the Library even though the source code is not. Whether this is true is +especially significant if the work can be linked without the Library, or if +the work is itself a library. The threshold for this to be true is not precisely +defined by law. + +If such an object file uses only numerical parameters, data structure layouts +and accessors, and small macros and small inline functions (ten lines or less +in length), then the use of the object file is unrestricted, regardless of +whether it is legally a derivative work. (Executables containing this object +code plus portions of the Library will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may distribute +the object code for the work under the terms of Section 6. Any executables +containing that work also fall under Section 6, whether or not they are linked +directly with the Library itself. + +6. As an exception to the Sections above, you may also combine or link a "work +that uses the Library" with the Library to produce a work containing portions +of the Library, and distribute that work under terms of your choice, provided +that the terms permit modification of the work for the customer's own use +and reverse engineering for debugging such modifications. + +You must give prominent notice with each copy of the work that the Library +is used in it and that the Library and its use are covered by this License. +You must supply a copy of this License. If the work during execution displays +copyright notices, you must include the copyright notice for the Library among +them, as well as a reference directing the user to the copy of this License. +Also, you must do one of these things: + +a) Accompany the work with the complete corresponding machine-readable source +code for the Library including whatever changes were used in the work (which +must be distributed under Sections 1 and 2 above); and, if the work is an +executable linked with the Library, with the complete machine-readable "work +that uses the Library", as object code and/or source code, so that the user +can modify the Library and then relink to produce a modified executable containing +the modified Library. (It is understood that the user who changes the contents +of definitions files in the Library will not necessarily be able to recompile +the application to use the modified definitions.) + +b) Use a suitable shared library mechanism for linking with the Library. A +suitable mechanism is one that (1) uses at run time a copy of the library +already present on the user's computer system, rather than copying library +functions into the executable, and (2) will operate properly with a modified +version of the library, if the user installs one, as long as the modified +version is interface-compatible with the version that the work was made with. + +c) Accompany the work with a written offer, valid for at least three years, +to give the same user the materials specified in Subsection 6a, above, for +a charge no more than the cost of performing this distribution. + +d) If distribution of the work is made by offering access to copy from a designated +place, offer equivalent access to copy the above specified materials from +the same place. + +e) Verify that the user has already received a copy of these materials or +that you have already sent this user a copy. + +For an executable, the required form of the "work that uses the Library" must +include any data and utility programs needed for reproducing the executable +from it. However, as a special exception, the materials to be distributed +need not include anything that is normally distributed (in either source or +binary form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component itself +accompanies the executable. + +It may happen that this requirement contradicts the license restrictions of +other proprietary libraries that do not normally accompany the operating system. +Such a contradiction means you cannot use both them and the Library together +in an executable that you distribute. + +7. You may place library facilities that are a work based on the Library side-by-side +in a single library together with other library facilities not covered by +this License, and distribute such a combined library, provided that the separate +distribution of the work based on the Library and of the other library facilities +is otherwise permitted, and provided that you do these two things: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities. This must be distributed +under the terms of the Sections above. + +b) Give prominent notice with the combined library of the fact that part of +it is a work based on the Library, and explaining where to find the accompanying +uncombined form of the same work. + +8. You may not copy, modify, sublicense, link with, or distribute the Library +except as expressly provided under this License. Any attempt otherwise to +copy, modify, sublicense, link with, or distribute the Library is void, and +will automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +9. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Library or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Library +(or any work based on the Library), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +10. Each time you redistribute the Library (or any work based on the Library), +the recipient automatically receives a license from the original licensor +to copy, distribute, link with or modify the Library subject to these terms +and conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties with this License. + +11. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of +this License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Library at all. For example, if a +patent license would not permit royalty-free redistribution of the Library +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +12. If the distribution and/or use of the Library is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Library under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +13. The Free Software Foundation may publish revised and/or new versions of +the Lesser General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Library specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Library does not specify a license version number, you may choose any version +ever published by the Free Software Foundation. + +14. If you wish to incorporate parts of the Library into other free programs +whose distribution conditions are incompatible with these, write to the author +to ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make exceptions +for this. Our decision will be guided by the two goals of preserving the free +status of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA +OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest possible +use to the public, we recommend making it free software that everyone can +redistribute and change. You can do so by permitting redistribution under +these terms (or, alternatively, under the terms of the ordinary General Public +License). + +To apply these terms, attach the following notices to the library. It is safest +to attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the "copyright" +line and a pointer to where the full notice is found. + + + +Copyright (C) + +This library is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free +Software Foundation; either version 2.1 of the License, or (at your option) +any later version. + +This library 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 Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with this library; if not, write to the Free Software Foundation, Inc., 51 +Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the library, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in + +the library `Frob' (a library for tweaking knobs) written + +by James Random Hacker. + +< signature of Ty Coon > , 1 April 1990 + +Ty Coon, President of Vice + +That's all there is to it! diff --git a/LICENSES/LGPL-3.0-only.txt b/LICENSES/LGPL-3.0-only.txt new file mode 100644 index 0000000..bd405af --- /dev/null +++ b/LICENSES/LGPL-3.0-only.txt @@ -0,0 +1,163 @@ +GNU LESSER GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright (C) 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +This version of the GNU Lesser General Public License incorporates the terms +and conditions of version 3 of the GNU General Public License, supplemented +by the additional permissions listed below. + + 0. Additional Definitions. + + + +As used herein, "this License" refers to version 3 of the GNU Lesser General +Public License, and the "GNU GPL" refers to version 3 of the GNU General Public +License. + + + +"The Library" refers to a covered work governed by this License, other than +an Application or a Combined Work as defined below. + + + +An "Application" is any work that makes use of an interface provided by the +Library, but which is not otherwise based on the Library. Defining a subclass +of a class defined by the Library is deemed a mode of using an interface provided +by the Library. + + + +A "Combined Work" is a work produced by combining or linking an Application +with the Library. The particular version of the Library with which the Combined +Work was made is also called the "Linked Version". + + + +The "Minimal Corresponding Source" for a Combined Work means the Corresponding +Source for the Combined Work, excluding any source code for portions of the +Combined Work that, considered in isolation, are based on the Application, +and not on the Linked Version. + + + +The "Corresponding Application Code" for a Combined Work means the object +code and/or source code for the Application, including any data and utility +programs needed for reproducing the Combined Work from the Application, but +excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + +You may convey a covered work under sections 3 and 4 of this License without +being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + +If you modify a copy of the Library, and, in your modifications, a facility +refers to a function or data to be supplied by an Application that uses the +facility (other than as an argument passed when the facility is invoked), +then you may convey a copy of the modified version: + +a) under this License, provided that you make a good faith effort to ensure +that, in the event an Application does not supply the function or data, the +facility still operates, and performs whatever part of its purpose remains +meaningful, or + +b) under the GNU GPL, with none of the additional permissions of this License +applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + +The object code form of an Application may incorporate material from a header +file that is part of the Library. You may convey such object code under terms +of your choice, provided that, if the incorporated material is not limited +to numerical parameters, data structure layouts and accessors, or small macros, +inline functions and templates (ten or fewer lines in length), you do both +of the following: + +a) Give prominent notice with each copy of the object code that the Library +is used in it and that the Library and its use are covered by this License. + +b) Accompany the object code with a copy of the GNU GPL and this license document. + + 4. Combined Works. + +You may convey a Combined Work under terms of your choice that, taken together, +effectively do not restrict modification of the portions of the Library contained +in the Combined Work and reverse engineering for debugging such modifications, +if you also do each of the following: + +a) Give prominent notice with each copy of the Combined Work that the Library +is used in it and that the Library and its use are covered by this License. + +b) Accompany the Combined Work with a copy of the GNU GPL and this license +document. + +c) For a Combined Work that displays copyright notices during execution, include +the copyright notice for the Library among these notices, as well as a reference +directing the user to the copies of the GNU GPL and this license document. + + d) Do one of the following: + +0) Convey the Minimal Corresponding Source under the terms of this License, +and the Corresponding Application Code in a form suitable for, and under terms +that permit, the user to recombine or relink the Application with a modified +version of the Linked Version to produce a modified Combined Work, in the +manner specified by section 6 of the GNU GPL for conveying Corresponding Source. + +1) Use a suitable shared library mechanism for linking with the Library. A +suitable mechanism is one that (a) uses at run time a copy of the Library +already present on the user's computer system, and (b) will operate properly +with a modified version of the Library that is interface-compatible with the +Linked Version. + +e) Provide Installation Information, but only if you would otherwise be required +to provide such information under section 6 of the GNU GPL, and only to the +extent that such information is necessary to install and execute a modified +version of the Combined Work produced by recombining or relinking the Application +with a modified version of the Linked Version. (If you use option 4d0, the +Installation Information must accompany the Minimal Corresponding Source and +Corresponding Application Code. If you use option 4d1, you must provide the +Installation Information in the manner specified by section 6 of the GNU GPL +for conveying Corresponding Source.) + + 5. Combined Libraries. + +You may place library facilities that are a work based on the Library side +by side in a single library together with other library facilities that are +not Applications and are not covered by this License, and convey such a combined +library under terms of your choice, if you do both of the following: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities, conveyed under the +terms of this License. + +b) Give prominent notice with the combined library that part of it is a work +based on the Library, and explaining where to find the accompanying uncombined +form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + +The Free Software Foundation may publish revised and/or new versions of the +GNU Lesser General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Library as you +received it specifies that a certain numbered version of the GNU Lesser General +Public License "or any later version" applies to it, you have the option of +following the terms and conditions either of that published version or of +any later version published by the Free Software Foundation. If the Library +as you received it does not specify a version number of the GNU Lesser General +Public License, you may choose any version of the GNU Lesser General Public +License ever published by the Free Software Foundation. + +If the Library as you received it specifies that a proxy can decide whether +future versions of the GNU Lesser General Public License shall apply, that +proxy's public statement of acceptance of any version is permanent authorization +for you to choose that version for the Library. diff --git a/LICENSES/LicenseRef-KDE-Accepted-GPL.txt b/LICENSES/LicenseRef-KDE-Accepted-GPL.txt new file mode 100644 index 0000000..60a2dff --- /dev/null +++ b/LICENSES/LicenseRef-KDE-Accepted-GPL.txt @@ -0,0 +1,12 @@ +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of +the license or (at your option) at any later version that is +accepted by the membership of KDE e.V. (or its successor +approved by the membership of KDE e.V.), which shall act as a +proxy as defined in Section 14 of version 3 of the license. + +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. diff --git a/LICENSES/LicenseRef-KDE-Accepted-LGPL.txt b/LICENSES/LicenseRef-KDE-Accepted-LGPL.txt new file mode 100644 index 0000000..232b3c5 --- /dev/null +++ b/LICENSES/LicenseRef-KDE-Accepted-LGPL.txt @@ -0,0 +1,12 @@ +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the license or (at your option) any later version +that is accepted by the membership of KDE e.V. (or its successor +approved by the membership of KDE e.V.), which shall act as a +proxy as defined in Section 6 of version 3 of the license. + +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. diff --git a/LICENSES/LicenseRef-Qt-Commercial.txt b/LICENSES/LicenseRef-Qt-Commercial.txt new file mode 100644 index 0000000..11e00c7 --- /dev/null +++ b/LICENSES/LicenseRef-Qt-Commercial.txt @@ -0,0 +1,7 @@ +Commercial License Usage +Licensees holding valid commercial Qt licenses may use this file in +accordance with the commercial license agreement provided with the +Software or, alternatively, in accordance with the terms contained in +a written agreement between you and The Qt Company. For licensing terms +and conditions see https://www.qt.io/terms-conditions. For further +information use the contact form at https://www.qt.io/contact-us. diff --git a/LICENSES/Qt-LGPL-exception-1.1.txt b/LICENSES/Qt-LGPL-exception-1.1.txt new file mode 100644 index 0000000..d0f532e --- /dev/null +++ b/LICENSES/Qt-LGPL-exception-1.1.txt @@ -0,0 +1,21 @@ +The Qt Company Qt LGPL Exception version 1.1 + +As an additional permission to the GNU Lesser General Public License version 2.1, the object code form of a "work that uses the Library" may incorporate material from a header file that is part of the Library. You may distribute such object code under terms of your choice, provided that: + + (i) the header files of the Library have not been modified; and + + (ii) the incorporated material is limited to numerical parameters, data structure layouts, accessors, macros, inline functions and templates; and + + (iii) you comply with the terms of Section 6 of the GNU Lesser General Public License version 2.1. + +Moreover, you may apply this exception to a modified version of the Library, provided that such modification does not involve copying material from the Library into the modified Library's header files unless such material is limited to + + (i) numerical parameters; + + (ii) data structure layouts; + + (iii) accessors; and + + (iv) small macros, templates and inline functions of five lines or less in length. + +Furthermore, you are not required to apply this additional permission to a modified version of the Library. diff --git a/PlasmaConfig.cmake.in b/PlasmaConfig.cmake.in new file mode 100644 index 0000000..9e974f3 --- /dev/null +++ b/PlasmaConfig.cmake.in @@ -0,0 +1,23 @@ +@PACKAGE_INIT@ + +# Any changes in this ".cmake" file will be overwritten by CMake, the source is the ".cmake.in" file. + +include("${CMAKE_CURRENT_LIST_DIR}/PlasmaTargets.cmake") +@PACKAGE_INCLUDE_QCHTARGETS@ + +set(Plasma_INSTALL_PREFIX "@PACKAGE_CMAKE_INSTALL_PREFIX@") + +set(Plasma_LIBRARIES Plasma::Plasma) + +set(PLASMA_PLASMOIDS_PLUGINDIR ${KDE_INSTALL_PLUGINDIR}/plasma/applets) +set(PLASMA_CONTAINMENTACTIONS_PLUGINDIR ${KDE_INSTALL_PLUGINDIR}/plasma/containmentactions) + +include(CMakeFindDependencyMacro) +find_dependency(Qt6Qml "@REQUIRED_QT_VERSION@") +find_dependency(Qt6Gui "@REQUIRED_QT_VERSION@") +find_dependency(KF6Package "@KF_DEP_VERSION@") +find_dependency(KF6WindowSystem "@KF_DEP_VERSION@") + +@PACKAGE_SETUP_AUTOMOC_VARIABLES@ + +include("${CMAKE_CURRENT_LIST_DIR}/PlasmaMacros.cmake") diff --git a/PlasmaMacros.cmake b/PlasmaMacros.cmake new file mode 100644 index 0000000..a2e19eb --- /dev/null +++ b/PlasmaMacros.cmake @@ -0,0 +1,30 @@ +set(PLASMA_RELATIVE_DATA_INSTALL_DIR "plasma") +set(PLASMA_DATA_INSTALL_DIR "${KDE_INSTALL_DATADIR}/${PLASMA_RELATIVE_DATA_INSTALL_DIR}") + +# plasma_install_package(path componentname [root] [type]) +# +# Installs a Plasma package to the system path +# @arg path The source path to install from, location of metadata.desktop +# @arg componentname The plugin name of the component, corresponding to the +# X-KDE-PluginInfo-Name key in metadata.desktop +# @arg root The subdirectory to install to, default: plasmoids +# @arg type The type, default to applet, or applet, package, containment, +# wallpaper, shell, lookandfeel, etc. +# @see Types column in kpackagetool6 --list-types +# +# Examples: +# plasma_install_package(mywidget org.kde.plasma.mywidget) # installs an applet +# plasma_install_package(declarativetoolbox org.kde.toolbox packages package) # installs a generic package +# +macro(plasma_install_package dir component) + set(root ${ARGV2}) + set(type ${ARGV3}) + if(NOT root) + set(root plasmoids) + endif() + if(NOT type) + set(type applet) + endif() + + kpackage_install_package(${dir} ${component} ${root} ${PLASMA_RELATIVE_DATA_INSTALL_DIR} NO_DEPRECATED_WARNING) +endmacro() diff --git a/README.md b/README.md new file mode 100644 index 0000000..ccce3f5 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +# libplasma + +Foundational libraries, components, and tools of the Plasma workspaces + +## Introduction +libplasma provides the following: +- QML components that can be used by any Plasma shell +- A C++ library: `libplasma` itself +- Script engines + +## QML components +### org.kde.plasma.core + +Bindings for libplasma functionality, such FrameSvg, see @ref core. + +### org.kde.plasma.components +Graphical components for common items such as buttons, lineedits, tabbars and so on. Compatible subset of the MeeGo components used on the N9, see @ref plasmacomponents. + +### org.kde.plasma.extras +Extra graphical components that extend org.kde.plasma.components but are not in the standard api, see @ref plasmaextracomponents. + +### org.kde.plasma.plasmoid +Attached properties for manipulating the current applet or containment, see @ref libplasmaquick + +## libplasma +This C++ library provides: +- rendering of SVG themes +- loading of files from a certain filesystem structure: packages +- data access through data engines +- loading of the plugin structure of the workspace: containments and applets + +See @ref libplasma. + +## Script engines +Provides support to create applets or containments in various scripting languages. + diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt new file mode 100644 index 0000000..8196321 --- /dev/null +++ b/autotests/CMakeLists.txt @@ -0,0 +1,67 @@ +find_package(Qt6Test ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE) +set_package_properties(Qt6Test PROPERTIES PURPOSE "Required for tests") + +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) +remove_definitions(-DQT_NO_CAST_FROM_ASCII -DQT_STRICT_ITERATORS -DQT_NO_CAST_FROM_BYTEARRAY -DQT_NO_KEYWORDS) + +include(ECMMarkAsTest) +include(ECMAddTests) + +find_package(KF6CoreAddons REQUIRED) +find_package(Qt6 COMPONENTS QuickTest Widgets REQUIRED) + +MACRO(PLASMA_UNIT_TESTS) + FOREACH(_testname ${ARGN}) + set(libs Qt6::Qml Qt6::Test Plasma::Plasma Plasma::PlasmaQuick + KF6::Archive KF6::CoreAddons KF6::ConfigGui KF6::I18n KF6::IconThemes) + if(QT_QTOPENGL_FOUND) + list(APPEND libs Qt6::OpenGL) + endif() + ecm_add_test(${_testname}.cpp + LINK_LIBRARIES ${libs} + NAME_PREFIX "plasma-") + target_include_directories(${_testname} PRIVATE "$>;") + ENDFOREACH(_testname) +ENDMACRO(PLASMA_UNIT_TESTS) + +PLASMA_UNIT_TESTS( + dialogqmltest + dialogstatetest + pluginloadertest + themetest + sharedqmlenginetest +) + +kcoreaddons_add_plugin(dummycontainmentaction SOURCES dummycontainmentaction.cpp INSTALL_NAMESPACE "plasma/containmentactions" STATIC) +target_link_libraries(dummycontainmentaction Plasma::Plasma) +kcoreaddons_target_static_plugins(pluginloadertest NAMESPACE "plasma/containmentactions") + +if(HAVE_X11) + ecm_add_test( + dialognativetest.cpp + TEST_NAME dialognativetest + LINK_LIBRARIES Qt6::Gui Qt6::Test Qt6::Qml Qt6::Quick KF6::WindowSystem Plasma::Plasma Plasma::PlasmaQuick + ) +endif() + +ecm_add_test( + coronatest.cpp + coronatestresources.qrc + TEST_NAME coronatest + LINK_LIBRARIES Qt6::Gui Qt6::Qml Qt6::Widgets Qt6::Test Plasma::Plasma KF6::CoreAddons +) + +ecm_add_test( + quickviewsharedenginetest.cpp + LINK_LIBRARIES Qt6::Test Plasma::PlasmaQuick +) + + +#Add a test that i18n is not used directly in any import. +# It should /always/ be i18nd +find_program(SH bash) +if(SH) + add_test(i18ndcheck ${SH} ${CMAKE_CURRENT_SOURCE_DIR}/i18ndcheck.sh ${CMAKE_SOURCE_DIR}/src/declarativeimports) +endif() + +add_subdirectory(declarativetests) diff --git a/autotests/TODO b/autotests/TODO new file mode 100644 index 0000000..1c9ac76 --- /dev/null +++ b/autotests/TODO @@ -0,0 +1,30 @@ +This file enumerates which classes and methods needs test. Please feel free to +add a specific test you'd like to see for a class/method. + +// Finished (as in has test for each method) +package +packagemetadata +packagestructure + +// No tests written atm. +abstractrunner +animator +appletbrowser +applet +configxml +containment +corona +datacontainer +datacontainer_p +glapplet +packages_p +phase +plasma_export +plasma +scriptengine +searchaction +searchcontext +shadowitem_p +svg +theme +uiloader diff --git a/autotests/coronatest.cpp b/autotests/coronatest.cpp new file mode 100644 index 0000000..611fdbd --- /dev/null +++ b/autotests/coronatest.cpp @@ -0,0 +1,206 @@ +/* + SPDX-FileCopyrightText: 2014 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "coronatest.h" + +#include +#include +#include +#include +#include +#include + +SimpleCorona::SimpleCorona(QObject *parent) + : Plasma::Corona(parent) +{ +} + +SimpleCorona::~SimpleCorona() +{ +} + +QRect SimpleCorona::screenGeometry(int screen) const +{ + // completely arbitrary, still not tested + return QRect(100 * screen, 100, 100, 100); +} + +int SimpleCorona::screenForContainment(const Plasma::Containment *c) const +{ + if (qobject_cast(c)) { + return -1; + } + return 0; +} + +SimpleApplet::SimpleApplet(QObject *parentObject, const KPluginMetaData &data, const QVariantList &args) + : Plasma::Applet(parentObject, data, args) +{ + // updateConstraints(Plasma::Types::UiReadyConstraint); + m_timer.setSingleShot(true); + m_timer.setInterval(QRandomGenerator::global()->bounded((500 + 1) - 100) + 100); + m_timer.start(); + connect(&m_timer, &QTimer::timeout, [this]() { + updateConstraints(Plasma::Applet::UiReadyConstraint); + }); +} + +SimpleContainment::SimpleContainment(QObject *parentObject, const KPluginMetaData &data, const QVariantList &args) + : Plasma::Containment(parentObject, data, args) +{ + // updateConstraints(Plasma::Types::UiReadyConstraint); + m_timer.setSingleShot(true); + m_timer.setInterval(QRandomGenerator::global()->bounded((500 + 1) - 100) + 100); + m_timer.start(); + connect(&m_timer, &QTimer::timeout, [this]() { + updateConstraints(Plasma::Applet::UiReadyConstraint); + }); +} + +SimpleNoScreenContainment::SimpleNoScreenContainment(QObject *parentObject, const KPluginMetaData &data, const QVariantList &args) + : Plasma::Containment(parentObject, data, args) +{ + // This containment will *never* be isUiReady() +} + +void CoronaTest::initTestCase() +{ + QStandardPaths::setTestModeEnabled(true); + m_corona = new SimpleCorona; + + m_configDir = QDir(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); + m_configDir.removeRecursively(); + + QVERIFY(m_configDir.mkpath(QStringLiteral("."))); + + QVERIFY(QFile::copy(QStringLiteral(":/plasma-test-appletsrc"), m_configDir.filePath(QStringLiteral("plasma-test-appletsrc")))); +} + +void CoronaTest::cleanupTestCase() +{ + m_configDir.removeRecursively(); + delete m_corona; +} + +void CoronaTest::restore() +{ + m_corona->loadLayout(QStringLiteral("plasma-test-appletsrc")); + QCOMPARE(m_corona->containments().count(), 3); + + const auto containments = m_corona->containments(); + for (auto cont : containments) { + switch (cont->id()) { + case 1: + QCOMPARE(cont->applets().count(), 2); + break; + default: + QCOMPARE(cont->applets().count(), 0); + break; + } + } +} + +void CoronaTest::checkOrder() +{ + QCOMPARE(m_corona->containments().count(), 3); + + // check containments order + QCOMPARE(m_corona->containments().at(0)->id(), (uint)1); + QCOMPARE(m_corona->containments().at(1)->id(), (uint)4); + QCOMPARE(m_corona->containments().at(2)->id(), (uint)5); + + // check applets order + QCOMPARE(m_corona->containments().at(0)->applets().count(), 2); + QCOMPARE(m_corona->containments().at(0)->applets().at(0)->id(), (uint)2); + QCOMPARE(m_corona->containments().at(0)->applets().at(1)->id(), (uint)3); +} + +void CoronaTest::startupCompletion() +{ + QVERIFY(!m_corona->isStartupCompleted()); + QVERIFY(!m_corona->containments().at(0)->isUiReady()); + + QSignalSpy spy(m_corona, SIGNAL(startupCompleted())); + QVERIFY(spy.wait(1000)); + + QVERIFY(m_corona->isStartupCompleted()); + QVERIFY(m_corona->containments().at(0)->isUiReady()); +} + +void CoronaTest::addRemoveApplets() +{ + m_corona->containments().at(0)->createApplet(QStringLiteral("invalid")); + QCOMPARE(m_corona->containments().at(0)->applets().count(), 3); + + // remove action present + QVERIFY(m_corona->containments().at(0)->applets().at(0)->internalAction(QStringLiteral("remove"))); + // kill an applet + m_corona->containments().at(0)->applets().at(0)->destroy(); + + QSignalSpy spy(m_corona->containments().at(0)->applets().at(0), SIGNAL(destroyed())); + QVERIFY(spy.wait(1000)); + QCOMPARE(m_corona->containments().at(0)->applets().count(), 2); +} + +// this test has to be the last, since systemimmutability +// can't be programmatically unlocked +void CoronaTest::immutability() +{ + // immutability + QCOMPARE(m_corona->immutability(), Plasma::Types::Mutable); + m_corona->setImmutability(Plasma::Types::UserImmutable); + QCOMPARE(m_corona->immutability(), Plasma::Types::UserImmutable); + + auto containments = m_corona->containments(); + for (Plasma::Containment *cont : std::as_const(containments)) { + QCOMPARE(cont->immutability(), Plasma::Types::UserImmutable); + const auto lstApplets = cont->applets(); + for (Plasma::Applet *app : lstApplets) { + QCOMPARE(app->immutability(), Plasma::Types::UserImmutable); + } + } + + m_corona->setImmutability(Plasma::Types::Mutable); + QCOMPARE(m_corona->immutability(), Plasma::Types::Mutable); + + containments = m_corona->containments(); + for (Plasma::Containment *cont : std::as_const(containments)) { + QCOMPARE(cont->immutability(), Plasma::Types::Mutable); + const auto lstApplets = cont->applets(); + for (Plasma::Applet *app : lstApplets) { + QCOMPARE(app->immutability(), Plasma::Types::Mutable); + } + } + + m_corona->setImmutability(Plasma::Types::SystemImmutable); + QCOMPARE(m_corona->immutability(), Plasma::Types::SystemImmutable); + + containments = m_corona->containments(); + for (Plasma::Containment *cont : std::as_const(containments)) { + QCOMPARE(cont->immutability(), Plasma::Types::SystemImmutable); + const auto lstApplets = cont->applets(); + for (Plasma::Applet *app : lstApplets) { + QCOMPARE(app->immutability(), Plasma::Types::SystemImmutable); + } + } + + // can't unlock systemimmutable + m_corona->setImmutability(Plasma::Types::Mutable); + QCOMPARE(m_corona->immutability(), Plasma::Types::SystemImmutable); + + containments = m_corona->containments(); + for (Plasma::Containment *cont : std::as_const(containments)) { + QCOMPARE(cont->immutability(), Plasma::Types::SystemImmutable); + const auto lstApplets = cont->applets(); + for (Plasma::Applet *app : lstApplets) { + QCOMPARE(app->immutability(), Plasma::Types::SystemImmutable); + } + } +} + +QTEST_MAIN(CoronaTest) + +#include "moc_coronatest.cpp" diff --git a/autotests/coronatest.h b/autotests/coronatest.h new file mode 100644 index 0000000..0ce2300 --- /dev/null +++ b/autotests/coronatest.h @@ -0,0 +1,78 @@ +/* + SPDX-FileCopyrightText: 2014 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ +#ifndef CORONATEST_H +#define CORONATEST_H + +#include + +#include + +#include "plasma/corona.h" +#include "plasma/pluginloader.h" + +class SimpleCorona : public Plasma::Corona +{ + Q_OBJECT + +public: + explicit SimpleCorona(QObject *parent = nullptr); + ~SimpleCorona() override; + + QRect screenGeometry(int) const override; + int screenForContainment(const Plasma::Containment *) const override; +}; + +class SimpleApplet : public Plasma::Applet +{ + Q_OBJECT + +public: + explicit SimpleApplet(QObject *parentObject, const KPluginMetaData &data, const QVariantList &args); + +private: + QTimer m_timer; +}; + +class SimpleContainment : public Plasma::Containment +{ + Q_OBJECT + +public: + explicit SimpleContainment(QObject *parentObject, const KPluginMetaData &data, const QVariantList &args); + +private: + QTimer m_timer; +}; + +class SimpleNoScreenContainment : public Plasma::Containment +{ + Q_OBJECT + +public: + explicit SimpleNoScreenContainment(QObject *parentObject, const KPluginMetaData &data, const QVariantList &args); +}; + +class CoronaTest : public QObject +{ + Q_OBJECT + +public Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); + +private Q_SLOTS: + void restore(); + void checkOrder(); + void startupCompletion(); + void addRemoveApplets(); + void immutability(); + +private: + SimpleCorona *m_corona; + QDir m_configDir; +}; + +#endif diff --git a/autotests/coronatestresources.qrc b/autotests/coronatestresources.qrc new file mode 100644 index 0000000..6a7b2b9 --- /dev/null +++ b/autotests/coronatestresources.qrc @@ -0,0 +1,5 @@ + + + plasma-test-appletsrc + + diff --git a/autotests/data/background.svgz b/autotests/data/background.svgz new file mode 100644 index 0000000000000000000000000000000000000000..70a668aa314b238a2997704e02c3e175f998c657 GIT binary patch literal 2879 zcmV-F3&8XriwFP!000000PR~@SK`VRe(ztA%XvAyBtxY#(&$~tpkSk-pu)>tAt@n1 z5=_GQ>u*)a$l%b&?qi>0TnbgYb`5*@YFA}j{O{75P;=yZreh!H0K?@dWb2M$+Joa< zr(L6!9Oe0%ZDjc zR6w}^%Dk9mHXNPI=Q!8b^zp!TX12lLQP$ahoS8qJ`Ts*pAK9A@@j_Co3djK;lUY*6 z#7}TdF&>zVYRpZvAni7*>ucVIjiRR70NdEaagTFSm0;yA}|6W5Mo;c7Wvq_nGT<7#hNcVkbf?Unkv2pS+ zq>weI>OnNlNQmA6Arjg%QVbViX-m^G*T^92JPFzqGm6--;qh#3IyXJD zKS87#V+`^fd$P*(PEp935(o(JUQB9j4f7dWZNu)iYKc{l5g?4!Mp6EX0MBwo2sw%k zJdWLUxuD)ak6z+?q=cbGh`21|Ylh})NsFikw~`|fU??x#RB9*T_(feW+&k_#nhr&g z23jBE!*MQm5?2=uy@27=()<(C!d^#k`v}8lkxdAh#$;Vdr<-nFw87=QTbZF-CShW4 zeRDFYlR?6jr8+hJ2}&x9Y&iShZ8iUti5Jc~P2Q zKbFMWx-ORt(kE4_PHOG(?W|>$%T#Jj5xi#v5^e*$l&bUm6~VZ0doFNzw@jPLRP%?= zHvaaAEv)dzWAFq8IwFHj(Vb0D!FKF54idh3zUz#GB1%nyz#Jur3`ZW27iIhnD3U~R zdB8KOssJcZyp-oCVhwSPPT??+<5W2xd;1wn8?z{|#w zBwn=?OCc(!WB?f+(Zb6z5D&^A)kDa(K5Q!BT~z;C2^QJGHh844BKSJN2edzFz#$q7 z1ANVF*}gM9h#ULdVz2-F6M-T)-UQJ%O=NT!J-5;IO~CPzmUkV4m!y{*<6|Mj`(ooe zNb;w+>xTxY$aX|tfqQ_%#o~$@6KfV?R&48H;{B2DrvM>@2qA+hLld9!u+!jEiaRjv zn6_gHN^A-or(k()3xA*D_rhEh5-}1dNFo4Og!qRiz912GD2&W=Duj6`FsclAPROF5 zj?bkyXp2p2kjQS|C{PfB0q_a{P()75Lq=4DJS{7bQ52}~U$><1JIkMD0t>>I0rJrwy z@GiEpL*~ZI3@`Aam^M0~Fe1;33fQqdfq}BPZGPge`QfP{Umwz&OBnB6Y%u)3xu7U; zQ4t?0kUPQ0alar$b%uub4%gLI8OFHR#G2E>_)Gq=BLQ-J*!IBP9X*z7TKtItk;@Xe z$M?d}AvmJE5I$r!$M+5&%FR^xP(pnFvUf0i=z>l7a9@9@0q*Q-vBKfQU8SvGtKZj8 z-=Avt{Yt;wz3H+NoO9N=)oCnS%S%+LpYfyixhEM7OaFq>YF4Ovtz5fD&iG;}pLQAG4S zOoyIlU3AVbZMOY5t2mdXp;+%-o-HqWR=r=+g__z7Av#s-hAvlJi1__AN7>h^r(S5m^ay3v)PyK8ltcsEW6NX$d@(os7I;G z(dd>t)5YFBcO!X=g|`MBp*FV87X9v(|NU}(*&g!UnS2J!@dElQ%k27d$&$^b#P!6r zNsTjyRJR!bK{(0rJ8^hHzgt}A-w`svc_Y3|S}w^8F9KJ`3} zD-G@}byRH*ue&8py6!AkyDs!hD2deUS|OHFy6xOu-CT&}ZoPhdI4H~<(6=0CdnbMC zfik`$a|}doEIhnP19qoSK|&h=shE+-i4i4UqyP>b@cxD4 zH42hH6G{!`__Gd_&m0p&40j14KYPyv$W0SR?wInt^!zoGaM&M`TPB#1@hAF!qW|xK z{?FYV{`eKZPrW;QPjHW~<{(slXcu~BQ+us+-tn;h>tQ_+pzuR`)Q{f?25+++eEhUt zc&Pw_b1i}U&0P+UkBZ8BK)%F%LjEV@e?tDD#vdK>CH@og{}SX&!mow=122rDNItx( z58fN^?h>0b!RN)!C(i#%a6TQWD2D@@k9em8q0IfvJz&oox$N_MUGZRf@qhou@awL4 z-f+JI^W;rq@VrYl5s=?!Gx)Gc0>3Pq=>0ry%kn>T>OhhV6elsi1{+?HT*QMH1o2_s z-GAWZq7Xpn_|gCXDGwxdUqtztWOOLWD8x$sIZXY3~ zj+AWrK@y+srYG#;MV#>vL^?kw>FDRBX>8!}K%$1QBZ$yXPgt59wBt59(Hg89ulR7O&H7 zI;;0nwJ)nS%vXG)T2t!T_~k*DmET9LVYvA*#Q1w?b|(qswYpV*431NLZ_{mdmY=G9 dEgrvvc4I&eVz?st*SwQ2{|9JMI+!>>0059Jq1*rf literal 0 HcmV?d00001 diff --git a/autotests/data/bug359388/hicolor/22x22/apps/bug359388.svg b/autotests/data/bug359388/hicolor/22x22/apps/bug359388.svg new file mode 100644 index 0000000..8739af5 --- /dev/null +++ b/autotests/data/bug359388/hicolor/22x22/apps/bug359388.svg @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/autotests/data/icons/test-theme-two/apps/22/tst-plasma-framework-test-icon.svg b/autotests/data/icons/test-theme-two/apps/22/tst-plasma-framework-test-icon.svg new file mode 100644 index 0000000..8739af5 --- /dev/null +++ b/autotests/data/icons/test-theme-two/apps/22/tst-plasma-framework-test-icon.svg @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/autotests/data/icons/test-theme-two/index.theme b/autotests/data/icons/test-theme-two/index.theme new file mode 100644 index 0000000..65f3190 --- /dev/null +++ b/autotests/data/icons/test-theme-two/index.theme @@ -0,0 +1,28 @@ +[Icon Theme] +Name=Unittest Theme two + +DisplayDepth=32 + +DesktopDefault=48 +DesktopSizes=16,22,32,48,64,128,256 +ToolbarDefault=22 +ToolbarSizes=16,22,32,48 +MainToolbarDefault=22 +MainToolbarSizes=16,22,32,48 +SmallDefault=16 +SmallSizes=16,22,32,48 +PanelDefault=32 +PanelSizes=16,22,32,48,64,128,256 +DialogDefault=32 +DialogSizes=16,22,32,48,64,128,256 + +########## Directories +########## ordered by category and alphabetically + +Directories=apps/22 + +[apps/22] +Size=22 +Context=Applications +Type=Fixed + diff --git a/autotests/data/icons/test-theme/apps/22/tst-plasma-framework-test-icon.svg b/autotests/data/icons/test-theme/apps/22/tst-plasma-framework-test-icon.svg new file mode 100644 index 0000000..8739af5 --- /dev/null +++ b/autotests/data/icons/test-theme/apps/22/tst-plasma-framework-test-icon.svg @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/autotests/data/icons/test-theme/apps/32/tst-plasma-framework-test-icon.svg b/autotests/data/icons/test-theme/apps/32/tst-plasma-framework-test-icon.svg new file mode 100644 index 0000000..940d46d --- /dev/null +++ b/autotests/data/icons/test-theme/apps/32/tst-plasma-framework-test-icon.svg @@ -0,0 +1,763 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Plasm + + + + + + + + + + diff --git a/autotests/data/icons/test-theme/apps/48/konversation.svg b/autotests/data/icons/test-theme/apps/48/konversation.svg new file mode 100644 index 0000000..68027b8 --- /dev/null +++ b/autotests/data/icons/test-theme/apps/48/konversation.svg @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/autotests/data/icons/test-theme/index.theme b/autotests/data/icons/test-theme/index.theme new file mode 100644 index 0000000..5eaeff3 --- /dev/null +++ b/autotests/data/icons/test-theme/index.theme @@ -0,0 +1,37 @@ +[Icon Theme] +Name=Unittest Theme + +DisplayDepth=32 + +DesktopDefault=48 +DesktopSizes=16,22,32,48,64,128,256 +ToolbarDefault=22 +ToolbarSizes=16,22,32,48 +MainToolbarDefault=22 +MainToolbarSizes=16,22,32,48 +SmallDefault=16 +SmallSizes=16,22,32,48 +PanelDefault=32 +PanelSizes=16,22,32,48,64,128,256 +DialogDefault=32 +DialogSizes=16,22,32,48,64,128,256 + +########## Directories +########## ordered by category and alphabetically + +Directories=apps/22,apps/32,apps/48 + +[apps/22] +Size=22 +Context=Applications +Type=Fixed + +[apps/32] +Size=32 +Context=Applications +Type=Fixed + +[apps/48] +Size=48 +Context=Applications +Type=Fixed diff --git a/autotests/data/plasma/desktoptheme/test_old_metadata_format_theme/metadata.desktop b/autotests/data/plasma/desktoptheme/test_old_metadata_format_theme/metadata.desktop new file mode 100644 index 0000000..68686d6 --- /dev/null +++ b/autotests/data/plasma/desktoptheme/test_old_metadata_format_theme/metadata.desktop @@ -0,0 +1,19 @@ +[Desktop Entry] +Name=Plasma test theme + + +X-KDE-PluginInfo-Author=KDE Visual Design Group +X-KDE-PluginInfo-Email=kde-artists@kde.org +X-KDE-PluginInfo-Name=default +X-KDE-PluginInfo-Version=5.20 +X-KDE-PluginInfo-Website=https://plasma.kde.org +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-API=5.0 + +[ContrastEffect] +enabled=true +contrast=0.23 +intensity=2.0 +saturation=1.7 diff --git a/autotests/data/plasma/desktoptheme/testtheme/colors b/autotests/data/plasma/desktoptheme/testtheme/colors new file mode 100644 index 0000000..16ad35c --- /dev/null +++ b/autotests/data/plasma/desktoptheme/testtheme/colors @@ -0,0 +1,119 @@ +[ColorEffects:Disabled] +Color=56,56,56 +ColorAmount=0 +ColorEffect=0 +ContrastAmount=0.65 +ContrastEffect=1 +IntensityAmount=0.1 +IntensityEffect=2 + +[ColorEffects:Inactive] +ChangeSelectionColor=true +Color=112,111,110 +ColorAmount=0.025 +ColorEffect=2 +ContrastAmount=0.1 +ContrastEffect=2 +Enable=false +IntensityAmount=0 +IntensityEffect=0 + +[Colors:Button] +BackgroundAlternate=224,223,222 +BackgroundNormal=239,240,241 +DecorationFocus=30,146,255 +DecorationHover=61,174,230 +ForegroundActive=246,116,0 +ForegroundInactive=175,176,179 +ForegroundLink=61,174,230 +ForegroundNegative=237,21,22 +ForegroundNeutral=201,206,60 +ForegroundNormal=49,54,59 +ForegroundPositive=17,209,23 +ForegroundVisited=61,174,230 + +[Colors:Selection] +BackgroundAlternate=48,138,183 +BackgroundNormal=61,174,230 +DecorationFocus=30,146,255 +DecorationHover=61,174,230 +ForegroundActive=246,116,0 +ForegroundInactive=146,204,230 +ForegroundLink=252,252,252 +ForegroundNegative=237,21,21 +ForegroundNeutral=201,206,59 +ForegroundNormal=252,252,252 +ForegroundPositive=17,209,22 +ForegroundVisited=252,252,252 + +[Colors:Tooltip] +BackgroundAlternate=196,224,255 +BackgroundNormal=239,240,241 +DecorationFocus=30,146,255 +DecorationHover=61,174,230 +ForegroundActive=246,116,0 +ForegroundInactive=175,176,179 +ForegroundLink=61,174,230 +ForegroundNegative=237,21,21 +ForegroundNeutral=201,206,59 +ForegroundNormal=49,54,59 +ForegroundPositive=17,209,22 +ForegroundVisited=61,174,230 + +[Colors:View] +BackgroundAlternate=248,247,246 +BackgroundNormal=252,252,252 +DecorationFocus=30,146,255 +DecorationHover=61,174,230 +ForegroundActive=246,116,0 +ForegroundInactive=175,176,179 +ForegroundLink=61,174,230 +ForegroundNegative=237,21,23 +ForegroundNeutral=201,206,61 +ForegroundNormal=49,54,59 +ForegroundPositive=17,209,24 +ForegroundVisited=61,174,230 + +[Colors:Window] +BackgroundAlternate=218,217,216 +BackgroundNormal=239,240,241 +DecorationFocus=30,146,255 +DecorationHover=61,174,230 +ForegroundActive=246,116,0 +ForegroundInactive=175,176,179 +ForegroundLink=61,174,230 +ForegroundNegative=237,21,21 +ForegroundNeutral=201,206,59 +ForegroundNormal=49,54,59 +ForegroundPositive=17,209,22 +ForegroundVisited=61,174,230 + +[Colors:Complementary] +BackgroundAlternate=59,64,69 +BackgroundNormal=49,54,59 +DecorationFocus=40,146,255 +DecorationHover=71,174,230 +ForegroundActive=246,116,20 +ForegroundInactive=185,176,179 +ForegroundLink=71,174,230 +ForegroundNegative=237,21,24 +ForegroundNeutral=201,206,62 +ForegroundNormal=239,240,241 +ForegroundPositive=17,209,25 +ForegroundVisited=71,174,230 + +[General] +ColorScheme=Breeze +Name=Breeze +shadeSortColumn=true + +[KDE] +contrast=7 + +[WM] +activeBackground=61,174,230 +activeBlend=252,252,252 +activeForeground=252,252,252 +inactiveBackground=123,124,126 +inactiveBlend=123,124,126 +inactiveForeground=252,252,252 diff --git a/autotests/data/plasma/desktoptheme/testtheme/element.svg b/autotests/data/plasma/desktoptheme/testtheme/element.svg new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/autotests/data/plasma/desktoptheme/testtheme/element.svg @@ -0,0 +1 @@ + diff --git a/autotests/data/plasma/desktoptheme/testtheme/metadata.json b/autotests/data/plasma/desktoptheme/testtheme/metadata.json new file mode 100644 index 0000000..bd0ff12 --- /dev/null +++ b/autotests/data/plasma/desktoptheme/testtheme/metadata.json @@ -0,0 +1,18 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "kde-artists@kde.org", + "Name": "KDE Visual Design Group" + } + ], + "Category": "", + "EnabledByDefault": true, + "Id": "default", + "License": "LGPL", + "Name": "Plasma test theme", + "Version": "5.20", + "Website": "https://www.kde.org/" + }, + "X-Plasma-API": "5.0" +} diff --git a/autotests/data/plasma/desktoptheme/testtheme/opaque/element.svg b/autotests/data/plasma/desktoptheme/testtheme/opaque/element.svg new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/autotests/data/plasma/desktoptheme/testtheme/opaque/element.svg @@ -0,0 +1 @@ + diff --git a/autotests/data/plasma/desktoptheme/testtheme/plasmarc b/autotests/data/plasma/desktoptheme/testtheme/plasmarc new file mode 100644 index 0000000..a31148a --- /dev/null +++ b/autotests/data/plasma/desktoptheme/testtheme/plasmarc @@ -0,0 +1,5 @@ +[ContrastEffect] +enabled=true +contrast=0.23 +intensity=2.0 +saturation=1.7 diff --git a/autotests/data/plasma/plasmoids/simplecontainment/contents/main.qml b/autotests/data/plasma/plasmoids/simplecontainment/contents/main.qml new file mode 100644 index 0000000..e69de29 diff --git a/autotests/data/plasma/plasmoids/simplecontainment/contents/ui/main.qml b/autotests/data/plasma/plasmoids/simplecontainment/contents/ui/main.qml new file mode 100644 index 0000000..e69de29 diff --git a/autotests/data/plasma/plasmoids/simplecontainment/metadata.json b/autotests/data/plasma/plasmoids/simplecontainment/metadata.json new file mode 100644 index 0000000..4d3ba20 --- /dev/null +++ b/autotests/data/plasma/plasmoids/simplecontainment/metadata.json @@ -0,0 +1,9 @@ +{ + "KPlugin": { + "Id": "simplecontainment", + "Name": "Testcontainment", + "Category": "System Information" + }, + "KPackageStructure": "Plasma/Applet", + "X-Plasma-ContainmentType": "Desktop" +} diff --git a/autotests/data/signedPackage/contents.hash b/autotests/data/signedPackage/contents.hash new file mode 100644 index 0000000..7daabbb --- /dev/null +++ b/autotests/data/signedPackage/contents.hash @@ -0,0 +1 @@ +5fd34038c612b9ee59ba9b8199594a370009f7ff \ No newline at end of file diff --git a/autotests/data/signedPackage/contents.hash.sig b/autotests/data/signedPackage/contents.hash.sig new file mode 100644 index 0000000000000000000000000000000000000000..4c74f37f8bf2b8c668aa0592d1697e71e46bfeed GIT binary patch literal 72 zcmV-O0Jr~$Mg#y60ssaD0!`jw;{XZ?5Z1RYv8VCdLw1$`poHmne1dg8#mX8`d5x41 e!2HyYG60`_==8_4uZC>}4@+Bi<~ZXC9Fa!@@gE)l literal 0 HcmV?d00001 diff --git a/autotests/data/signedPackage/contents/code/main.js b/autotests/data/signedPackage/contents/code/main.js new file mode 100644 index 0000000..554d5de --- /dev/null +++ b/autotests/data/signedPackage/contents/code/main.js @@ -0,0 +1,45 @@ +// because we put the following line in the metadata.desktop file, we have access +// to the HTTP extension in this Plasmoid. +// +// X-Plasma-RequiredExtensions=http +// +// More documentation can be found here: +// +// https://techbase.kde.org/Development/Tutorials/Plasma/JavaScript/API#Extensions + +output = new TextEdit +output.readOnly = true + +layout = new LinearLayout +layout.orientation = QtVertical +layout.addItem(output) + +// in case our request for HTTP urls in the metadata.desktop was rejected (e.g. due +// to security restrictions) we won't have a plasmoid.get, so let's check for it +// before using it! +if (plasmoid.getUrl) { + var getJob = plasmoid.getUrl("https://dot.kde.org/rss.xml"); + function recv(job, data) + { + if (job == getJob) { + print("we have our job") + if (data.length) { + output.append(data.toUtf8()) + } + } + } + + function fini(job) + { + if (job == getJob) { + print("our job is finished") + } else { + print("some other job is finished?") + } + } + + getJob.data.connect(recv) + getJob.finished.connect(fini) +} else { + output.text = i18n("HTTP access denied!") +} diff --git a/autotests/data/signedPackage/contents/images/dummy b/autotests/data/signedPackage/contents/images/dummy new file mode 100644 index 0000000..e69de29 diff --git a/autotests/data/signedPackage/metadata.json b/autotests/data/signedPackage/metadata.json new file mode 100644 index 0000000..5a86317 --- /dev/null +++ b/autotests/data/signedPackage/metadata.json @@ -0,0 +1,96 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "aseigo@kde.org", + "Name": "Aaron Seigo" + } + ], + "Category": "Examples", + "Description": "Demonstrates accessing data via HTTP in JavaScript", + "Description[bs]": "Demonstrira pristupanje padacima preko HTTP u JavaScript", + "Description[ca@valencia]": "Demostra l'accés a dades via HTTP en JavaScript", + "Description[ca]": "Demostra l'accés a dades via HTTP en JavaScript", + "Description[cs]": "Ukazuje jak v JavaScriptu přistupovat k datům přes HTTP", + "Description[da]": "Demonstrerer tilgang til data via HTTP i JavaScript", + "Description[de]": "Demonstriert den Zugriff auf Daten über HTTP in JavaScript", + "Description[en_GB]": "Demonstrates accessing data via HTTP in JavaScript", + "Description[es]": "Demuestra el acceso a datos usando HTTP en JavaScript", + "Description[fi]": "Demonstroi datan hakemista HTTP:n välityksellä käyttäen JavaScriptiä", + "Description[fr]": "Illustre l'accès aux données via HTTP en JavaScript", + "Description[gd]": "Seallaidh seo mar a nì thu inntrigeadh air dàta le HTTP ann an JavaScript", + "Description[gl]": "Demostra o acceso a datos mediante HTTP en JavaScript", + "Description[hu]": "Demonstrálja adatok elérését HTTP-n keresztül JavaScriptben", + "Description[ia]": "Il demonstra como acceder datos via HTTP inJavaScript", + "Description[it]": "Dimostra l'accesso ai dati tramite HTTP in JavaScript", + "Description[ko]": "JavaScript 내에서 데이터를 HTTP로 접근하는 과정 시연", + "Description[lt]": "Demonstruoja duomenų pasiekimą per HTTP su JavaScript", + "Description[mr]": "जावास्क्रिप्ट मध्ये डेटा HTTP ने बघण्याचे प्रदर्शन", + "Description[nb]": "Demonstrerer tilgang til data via HTTP i JavaScript", + "Description[nds]": "Wiest, wodennig een op Daten över HTTP in JavaScript togriepen kann", + "Description[nl]": "Demonstreert toegang tot gegevens via HTTP in JavaScript", + "Description[nn]": "Demonstrerer JavaScript-tilgang til data via HTTP", + "Description[pl]": "Przedstawia uzyskiwanie dostępu do danych przez HTTP w JavaScript", + "Description[pt]": "Demonstra o acesso a dados por HTTP em JavaScript", + "Description[pt_BR]": "Demonstra o acesso a dados por HTTP em JavaScript", + "Description[ru]": "Демонстрация доступа к данным по HTTP в JavaScript", + "Description[sk]": "Demonštruje prístup k údajom cez HTTP v JavaScripte", + "Description[sl]": "Predstavi dostopanje do podatkov preko HTTP v JavaScript", + "Description[sr@ijekavian]": "Демонстрира приступање подацима преко ХТТП‑а у јаваскрипту", + "Description[sr@ijekavianlatin]": "Demonstrira pristupanje podacima preko HTTP‑a u JavaScriptu", + "Description[sr@latin]": "Demonstrira pristupanje podacima preko HTTP‑a u JavaScriptu", + "Description[sr]": "Демонстрира приступање подацима преко ХТТП‑а у јаваскрипту", + "Description[sv]": "Förevisar åtkomst av data via HTTP i Javascript", + "Description[tr]": "JavaScript HTTP üzerinden veri erişimini gösterir", + "Description[uk]": "Демонстрації доступу до даних за допомогою HTTP мовою JavaScript", + "Description[x-test]": "xxDemonstrates accessing data via HTTP in JavaScriptxx", + "Description[zh_CN]": "展示在 JavaScript 中通过 HTTP 访问数据", + "Description[zh_TW]": "展示如何在 JavaScript 中透過 HTTP 存取資料", + "Icon": "text-x-generic", + "Id": "org.kde.plasma.simpified-javascript-http-example", + "License": "GPL", + "Name": "JavaScript File Operations", + "Name[bs]": "JavaScript operacije s datotekama", + "Name[ca@valencia]": "Operacions amb fitxers en JavaScript", + "Name[ca]": "Operacions amb fitxers en JavaScript", + "Name[cs]": "Operace souboru JavaScript", + "Name[da]": "JavaScript filoperationer", + "Name[de]": "JavaScript-Datei-Aktionen", + "Name[en_GB]": "JavaScript File Operations", + "Name[es]": "Operaciones de archivo JavaScript", + "Name[fi]": "JavaScript-tiedostotoiminnot", + "Name[fr]": "Opérations sur les fichiers en JavaScript", + "Name[gd]": "Obrachaidhean faidhle JavaScript", + "Name[gl]": "Operacións de ficheiro JavaScript", + "Name[hu]": "JavaScript fájlműveletek", + "Name[ia]": "Operationes de file de JavaScript", + "Name[it]": "Operazioni su file JavaScript", + "Name[ko]": "JavaScript 파일 작업", + "Name[lt]": "JavaScript failo operacijos", + "Name[mr]": "जावास्क्रिप्ट फाईलच्या क्रिया", + "Name[nb]": "JavaScript filhandlinger", + "Name[nds]": "JavaScript-Dateiakschonen", + "Name[nl]": "Bestandsbewerkingen in JavaScript", + "Name[nn]": "JavaScript-filoperasjonar", + "Name[pl]": "Operacje plikowe JavaScript", + "Name[pt]": "Operações com Ficheiros em JavaScript", + "Name[pt_BR]": "Operações com arquivos JavaScript", + "Name[ru]": "Операции с файлами в JavaScript", + "Name[sk]": "JavaScriptové súborové operácie", + "Name[sl]": "Datotečna opravila v JavaScript", + "Name[sr@ijekavian]": "Јаваскриптне операције над фајловима", + "Name[sr@ijekavianlatin]": "JavaScript operacije nad fajlovima", + "Name[sr@latin]": "JavaScript operacije nad fajlovima", + "Name[sr]": "Јаваскриптне операције над фајловима", + "Name[sv]": "Filåtgärder för Javascript", + "Name[tr]": "JavaScript Dosya Operatörleri", + "Name[uk]": "Дії з файлами за допомогою JavaScript", + "Name[x-test]": "xxJavaScript File Operationsxx", + "Name[zh_CN]": "JavaScript 文件操作", + "Name[zh_TW]": "JavaScript 檔案操作", + "Version": "0.1", + "Website": "https://www.kde.org/" + }, + "X-Plasma-OptionalExtensions": "http", + "KPackageStructure": "Plasma/Applet" +} diff --git a/autotests/data/test_image.png b/autotests/data/test_image.png new file mode 100644 index 0000000000000000000000000000000000000000..ceb8e03b669bb00e05cf21b12f6e17f06c3a5485 GIT binary patch literal 1672 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 literal 0 HcmV?d00001 diff --git a/autotests/data/testconfigpackage/contents/config/config.qml b/autotests/data/testconfigpackage/contents/config/config.qml new file mode 100644 index 0000000..f5d362a --- /dev/null +++ b/autotests/data/testconfigpackage/contents/config/config.qml @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2016 David Rosca + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +import org.kde.plasma.configuration + +ConfigModel { + ConfigCategory { + name: "General" + icon: "plasma" + source: "ConfigGeneral.qml" + } +} diff --git a/autotests/data/testconfigpackage/contents/config/main.xml b/autotests/data/testconfigpackage/contents/config/main.xml new file mode 100644 index 0000000..7b4cb2f --- /dev/null +++ b/autotests/data/testconfigpackage/contents/config/main.xml @@ -0,0 +1,17 @@ + + + + + + + 23 + + + string-value + + + + diff --git a/autotests/data/testconfigpackage/contents/ui/ConfigGeneral.qml b/autotests/data/testconfigpackage/contents/ui/ConfigGeneral.qml new file mode 100644 index 0000000..3b0851f --- /dev/null +++ b/autotests/data/testconfigpackage/contents/ui/ConfigGeneral.qml @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2016 David Rosca + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick 2.0 + +Rectangle { + id: root + color: "darkblue" +} + diff --git a/autotests/data/testconfigpackage/contents/ui/main.qml b/autotests/data/testconfigpackage/contents/ui/main.qml new file mode 100644 index 0000000..3b0851f --- /dev/null +++ b/autotests/data/testconfigpackage/contents/ui/main.qml @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2016 David Rosca + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick 2.0 + +Rectangle { + id: root + color: "darkblue" +} + diff --git a/autotests/data/testconfigpackage/metadata.json b/autotests/data/testconfigpackage/metadata.json new file mode 100644 index 0000000..4d08c91 --- /dev/null +++ b/autotests/data/testconfigpackage/metadata.json @@ -0,0 +1,16 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "jblow@kde.org", + "Name": "Joe Blow" + } + ], + "Category": "", + "Id": "org.kde.configtestpackage", + "License": "GPLv2+", + "Name": "Config Test Package", + "Version": "", + "Website": "https://www.kde.org/" + } +} diff --git a/autotests/data/testfallbackpackage/contents/ui/main.qml b/autotests/data/testfallbackpackage/contents/ui/main.qml new file mode 100644 index 0000000..c23e170 --- /dev/null +++ b/autotests/data/testfallbackpackage/contents/ui/main.qml @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2014 Marco Martin + * SPDX-FileCopyrightText: 2014 Vishesh Handa + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick 2.0 + +Rectangle { + id: root + color: "darkblue" +} + diff --git a/autotests/data/testfallbackpackage/metadata.json b/autotests/data/testfallbackpackage/metadata.json new file mode 100644 index 0000000..a062fce --- /dev/null +++ b/autotests/data/testfallbackpackage/metadata.json @@ -0,0 +1,50 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "mart@kde.org", + "Name": "Marco Martin" + } + ], + "Category": "", + "Id": "org.kde.testfallbackpackage", + "License": "GPLv2+", + "Name": "Test Fallback Package", + "Name[ca@valencia]": "Paquet de proves alternatiu", + "Name[ca]": "Paquet de proves alternatiu", + "Name[da]": "Test af fallback-pakke", + "Name[de]": "Test-Ausweichpaket", + "Name[en_GB]": "Test Fallback Package", + "Name[es]": "Probar el paquete al que recurrir", + "Name[fi]": "Testivarapaketti", + "Name[fr]": "Tester le paquet de repli", + "Name[gd]": "Pacaid dheuchainneach èiginneach", + "Name[gl]": "Paquete de probas por omisión", + "Name[hu]": "Tartalék tesztcsomag", + "Name[it]": "Pacchetto di ripiego di test", + "Name[ko]": "테스트 폴백 패키지", + "Name[lt]": "Bandomasis surogatinis paketas", + "Name[nb]": "Test reservepakke", + "Name[nds]": "Test-Torüchfallpaket", + "Name[nl]": "Testterugvalpakket", + "Name[nn]": "Test-reservepakke", + "Name[pl]": "Zapasowy pakiet próbny", + "Name[pt]": "Pacote de Salvaguarda de Testes", + "Name[pt_BR]": "Pacote de teste secundário", + "Name[ru]": "Тестовый резервный пакет", + "Name[sk]": "Testovací záchranný balík", + "Name[sl]": "Preizkusni zasilni paket", + "Name[sr@ijekavian]": "Пробни одступни пакет", + "Name[sr@ijekavianlatin]": "Probni odstupni paket", + "Name[sr@latin]": "Probni odstupni paket", + "Name[sr]": "Пробни одступни пакет", + "Name[sv]": "Reservtestpaket", + "Name[tr]": "Yedek Paketi Denetle", + "Name[uk]": "Тестовий резервний пакунок", + "Name[x-test]": "xxTest Fallback Packagexx", + "Name[zh_CN]": "测试回退包", + "Name[zh_TW]": "測試預設套件", + "Version": "", + "Website": "https://www.kde.org/" + } +} diff --git a/autotests/data/testpackage/contents.hash b/autotests/data/testpackage/contents.hash new file mode 100644 index 0000000..fceeab3 --- /dev/null +++ b/autotests/data/testpackage/contents.hash @@ -0,0 +1 @@ +88a45736f27b7b477a470feaacd9e725232c47cc diff --git a/autotests/data/testpackage/contents/images/empty.png b/autotests/data/testpackage/contents/images/empty.png new file mode 100644 index 0000000..e69de29 diff --git a/autotests/data/testpackage/contents/ui/main.qml b/autotests/data/testpackage/contents/ui/main.qml new file mode 100644 index 0000000..7a8ff9b --- /dev/null +++ b/autotests/data/testpackage/contents/ui/main.qml @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2014 Marco Martin + * SPDX-FileCopyrightText: 2014 Sebastian Kügler + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick 2.0 + +Rectangle { + id: root + color: "darkblue" +} + diff --git a/autotests/data/testpackage/contents/ui/otherfile.qml b/autotests/data/testpackage/contents/ui/otherfile.qml new file mode 100644 index 0000000..c23e170 --- /dev/null +++ b/autotests/data/testpackage/contents/ui/otherfile.qml @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2014 Marco Martin + * SPDX-FileCopyrightText: 2014 Vishesh Handa + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick 2.0 + +Rectangle { + id: root + color: "darkblue" +} + diff --git a/autotests/data/testpackage/metadata.json b/autotests/data/testpackage/metadata.json new file mode 100644 index 0000000..c12d3f8 --- /dev/null +++ b/autotests/data/testpackage/metadata.json @@ -0,0 +1,54 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "jblow@kde.org", + "Name": "Joe Blow" + } + ], + "Category": "", + "Id": "org.kde.testpackage", + "License": "GPLv2+", + "Name": "Test Package", + "Name[ar]": "حزمة اختبارية", + "Name[bs]": "Testni paket", + "Name[ca@valencia]": "Paquet de proves", + "Name[ca]": "Paquet de proves", + "Name[cs]": "Testovací balíček", + "Name[da]": "Testpakke", + "Name[de]": "Test-Paket", + "Name[en_GB]": "Test Package", + "Name[es]": "Probar el paquete", + "Name[fi]": "Testipaketti", + "Name[fr]": "Paquet de test", + "Name[gd]": "Pacaid dheuchainneach", + "Name[gl]": "Paquete de probas", + "Name[hu]": "Tesztcsomag", + "Name[ia]": "Pacchetto de prova", + "Name[it]": "Pacchetto di prova", + "Name[ko]": "테스트 패키지", + "Name[lt]": "Bandomasis paketas", + "Name[mr]": "चाचणी पॅकेज", + "Name[nb]": "Test pakke", + "Name[nds]": "Testpaket", + "Name[nl]": "Testpakket", + "Name[nn]": "Testpakke", + "Name[pa]": "ਟੈਸਟ ਪੈਕੇਜ", + "Name[pl]": "Pakiet próbny", + "Name[pt]": "Pacote de Teste", + "Name[pt_BR]": "Pacote de teste", + "Name[ru]": "Тестовый пакет", + "Name[sk]": "Testovací balík", + "Name[sl]": "Preizkusni paket", + "Name[sr@ijekavian]": "Пробни пакет", + "Name[sr@ijekavianlatin]": "Probni paket", + "Name[sr@latin]": "Probni paket", + "Name[sr]": "Пробни пакет", + "Name[sv]": "Testpaket", + "Name[tr]": "Paketi Denetle", + "Name[uk]": "Тестовий пакунок", + "Name[x-test]": "xxTest Packagexx", + "Name[zh_CN]": "测试包", + "Name[zh_TW]": "測試套件" + } +} diff --git a/autotests/data/view.qml b/autotests/data/view.qml new file mode 100644 index 0000000..86b2695 --- /dev/null +++ b/autotests/data/view.qml @@ -0,0 +1,10 @@ +/* + * SPDX-FileCopyrightText: 2016 David Rosca + * SPDX-FileCopyrightText: 2016 Marco Martin + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +Item { + width: 100 + height: 100 +} diff --git a/autotests/declarativetests/CMakeLists.txt b/autotests/declarativetests/CMakeLists.txt new file mode 100644 index 0000000..ca1e3df --- /dev/null +++ b/autotests/declarativetests/CMakeLists.txt @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2024 Fushan Wen +# SPDX-License-Identifier: BSD-3-Clause + +add_executable(qmltest qmltest.cpp) +target_link_libraries(qmltest Qt::QuickTest Qt::Qml) + +add_test( + NAME bug485688test + COMMAND qmltest -import ${CMAKE_BINARY_DIR}/bin -input "${CMAKE_CURRENT_SOURCE_DIR}/bug485688.qml" +) diff --git a/autotests/declarativetests/bug485688.qml b/autotests/declarativetests/bug485688.qml new file mode 100644 index 0000000..7c5a066 --- /dev/null +++ b/autotests/declarativetests/bug485688.qml @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2024 Fushan Wen +// SPDX-License-Identifier: LGPL-2.1-or-later + +import QtQuick +import QtTest + +import org.kde.plasma.components as PC3 +import org.kde.plasma.extras as PlasmaExtras + +// Make sure the text field and the button have (almost) the same height +TestCase { + id: root + width: 640 + height: 480 + when: windowShown + + PlasmaExtras.SearchField { + id: searchField + } + PC3.ToolButton { + id: pinButton + icon.name: "window-pin" + text: "Keep Open" + display: PC3.ToolButton.IconOnly + } + + function test_compareHeight() { + verify(searchField.implicitBackgroundHeight > 0); + compare(searchField.implicitBackgroundHeight, pinButton.implicitBackgroundHeight + 4); + } +} diff --git a/autotests/declarativetests/qmltest.cpp b/autotests/declarativetests/qmltest.cpp new file mode 100644 index 0000000..b61cb79 --- /dev/null +++ b/autotests/declarativetests/qmltest.cpp @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: 2024 Fushan Wen +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include +#include + +class Setup : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY_MOVE(Setup) + +public: + explicit Setup() + { + } + +public Q_SLOTS: + void applicationAvailable() + { + } + + void qmlEngineAvailable(QQmlEngine *engine) + { + // Initialization requiring the QQmlEngine to be constructed + engine->setProperty("_kirigamiTheme", QStringLiteral("KirigamiPlasmaStyle")); + } + + void cleanupTestCase() + { + } +}; + +QUICK_TEST_MAIN_WITH_SETUP(QuickTest, Setup) + +#include "qmltest.moc" diff --git a/autotests/dialognativetest.cpp b/autotests/dialognativetest.cpp new file mode 100644 index 0000000..a335c2f --- /dev/null +++ b/autotests/dialognativetest.cpp @@ -0,0 +1,129 @@ +/* + SPDX-FileCopyrightText: 2014 Marco Martin + SPDX-FileCopyrightText: 2023 Harald Sitter + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "dialognativetest.h" + +#include "utils.h" + +#include +#include + +namespace +{ +constexpr auto panelHeight = 50; +constexpr auto panelWidth = panelHeight; +constexpr qreal content1Width = 100; +constexpr qreal content1Height = content1Width; +constexpr qreal content2Width = 50; +constexpr qreal content2Height = 25; +} // namespace + +void DialogNativeTest::initTestCase() +{ + QStandardPaths::setTestModeEnabled(true); + Plasma::TestUtils::installPlasmaTheme(); + + m_cacheDir = QDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); + m_cacheDir.removeRecursively(); + + m_dialog = new PlasmaQuick::Dialog; + m_dialog->setLocation(Plasma::Types::TopEdge); + + m_panel = new QQuickView; + m_panel->setColor(Qt::red); + m_panel->setGeometry(0, 0, panelHeight, panelWidth); + m_panel->setFlags(Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus); + + m_panel2 = new QQuickView; + m_panel2->setColor(Qt::green); + m_panel2->setGeometry(panelWidth * 2, 0, panelHeight, panelWidth); + m_panel2->setFlags(Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus); + + m_panel3 = new QQuickView; + m_panel3->setColor(Qt::blue); + m_panel3->setGeometry(panelWidth * 4, 0, panelHeight, panelWidth); + m_panel3->setFlags(Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus); + + m_content = new QQuickItem; + m_content->setWidth(content1Width); + m_content->setHeight(content1Height); + m_dialog->setMainItem(m_content); + + m_content2 = new QQuickItem(m_panel3->contentItem()); + m_content2->setWidth(content2Width); + m_content2->setHeight(content2Height); + + m_panel->show(); + m_panel2->show(); + m_panel3->show(); + KX11Extras::setType(m_panel->winId(), NET::Dock); + KX11Extras::setType(m_panel3->winId(), NET::Dock); + m_dialog->setVisualParent(m_panel->contentItem()); + m_dialog->show(); +} + +void DialogNativeTest::cleanupTestCase() +{ + delete m_dialog; + delete m_panel; + delete m_panel2; + delete m_panel3; + delete m_content; + + m_cacheDir.removeRecursively(); +} + +void DialogNativeTest::size() +{ + QVERIFY(QTest::qWaitForWindowExposed(m_dialog)); + + QCOMPARE(m_content->width(), content1Width); + QCOMPARE(m_content->height(), content1Height); + + constexpr qreal themeFixedMargin = 4.0; + QCOMPARE(m_dialog->margins()->property("left").value(), themeFixedMargin); + QCOMPARE(m_dialog->margins()->property("top").value(), themeFixedMargin); + QCOMPARE(m_dialog->margins()->property("right").value(), themeFixedMargin); + QCOMPARE(m_dialog->margins()->property("bottom").value(), themeFixedMargin); + + QCOMPARE(m_dialog->width(), content1Width + themeFixedMargin * 2); + QCOMPARE(m_dialog->height(), content1Height + themeFixedMargin * 2); + + QCOMPARE(m_content2->width(), content2Width); + QCOMPARE(m_content2->height(), content2Height); +} + +void DialogNativeTest::position() +{ + QVERIFY(QTest::qWaitForWindowExposed(m_dialog)); + + // Find where the outermost test-panel lives. Normally that would be + // at x,y = (0,0) but if the test is run on a desktop with a + // left-hand-edge panel, then the test-panel is placed next to it. + const auto upper_left_x = m_panel->x(); + const auto upper_left_y = m_panel->y(); + + constexpr auto offset = 1; + constexpr auto anchorY = panelHeight - offset; + + QCOMPARE(m_dialog->x(), upper_left_x + 0); + QCOMPARE(m_dialog->y(), upper_left_y + anchorY); + + m_dialog->setVisualParent(m_panel2->contentItem()); + // this derives from the center point of the current panel, I am too lazy to calculate this - sitter, 2023 + QCOMPARE(m_dialog->x(), 71); + QCOMPARE(m_dialog->y(), anchorY); + + m_panel3->setMask(QRect(0, 0, panelWidth, panelHeight / 2)); + m_dialog->setVisualParent(m_content2); + QCOMPARE(m_dialog->x(), 171); + QCOMPARE(m_dialog->y(), panelHeight / 2 - offset); +} + +QTEST_MAIN(DialogNativeTest) + +#include "moc_dialognativetest.cpp" diff --git a/autotests/dialognativetest.h b/autotests/dialognativetest.h new file mode 100644 index 0000000..3847800 --- /dev/null +++ b/autotests/dialognativetest.h @@ -0,0 +1,37 @@ +/* + SPDX-FileCopyrightText: 2014 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ +#ifndef DIALOGNATIVETEST_H +#define DIALOGNATIVETEST_H + +#include +#include +#include + +#include "plasmaquick/dialog.h" + +class DialogNativeTest : public QObject +{ + Q_OBJECT + +public Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); + +private Q_SLOTS: + void size(); + void position(); + +private: + QQuickView *m_panel; + QQuickView *m_panel2; + QQuickView *m_panel3; + QQuickItem *m_content; + QQuickItem *m_content2; + PlasmaQuick::Dialog *m_dialog; + QDir m_cacheDir; +}; + +#endif diff --git a/autotests/dialogqmltest.cpp b/autotests/dialogqmltest.cpp new file mode 100644 index 0000000..41f7971 --- /dev/null +++ b/autotests/dialogqmltest.cpp @@ -0,0 +1,73 @@ +/* + SPDX-FileCopyrightText: 2014 David Edmundson + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "dialogqmltest.h" + +#include + +#include +#include + +#include + +// this test checks that we don't set visible to true until after we set the window flags +void DialogQmlTest::loadAndShow() +{ + QQmlEngine engine; + + QByteArray dialogQml = + "import QtQuick 2.0\n" + "import org.kde.plasma.core as PlasmaCore\n" + "\n" + "PlasmaCore.Dialog {\n" + " id: root\n" + "\n" + " location: true && PlasmaCore.Types.TopEdge\n" + " visible: true && true\n" + " type: true && PlasmaCore.Dialog.Notification\n" + "\n" + " mainItem: Rectangle {\n" + " width: 200\n" + " height: 200\n" + " }\n" + "}\n"; + + // we use true && Value to force it to be a complex binding, which won't be evaluated in + // component.beginCreate + // the bug still appears without this, but we need to delay it in this test + // so we can connect to the visibleChanged signal + + QQmlComponent component(&engine); + + QSignalSpy spy(&component, SIGNAL(statusChanged(QQmlComponent::Status))); + component.setData(dialogQml, QUrl(QStringLiteral("test://dialogTest"))); + spy.wait(); + + PlasmaQuick::Dialog *dialog = qobject_cast(component.beginCreate(engine.rootContext())); + qDebug() << component.errorString(); + Q_ASSERT(dialog); + + m_dialogShown = false; + + // this will be called during component.completeCreate + auto c = connect(dialog, &QWindow::visibleChanged, [=, this]() { + m_dialogShown = true; + QCOMPARE(dialog->type(), PlasmaQuick::Dialog::Notification); + QCOMPARE(dialog->location(), Plasma::Types::TopEdge); + }); + + component.completeCreate(); + QCOMPARE(m_dialogShown, true); + + // disconnect on visible changed before we delete the dialog + disconnect(c); + + delete dialog; +} + +QTEST_MAIN(DialogQmlTest) + +#include "moc_dialogqmltest.cpp" diff --git a/autotests/dialogqmltest.h b/autotests/dialogqmltest.h new file mode 100644 index 0000000..31bbb8c --- /dev/null +++ b/autotests/dialogqmltest.h @@ -0,0 +1,24 @@ +/* + SPDX-FileCopyrightText: 2014 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ +#ifndef DIALOGQMLTEST_H +#define DIALOGQMLTEST_H + +#include + +#include "plasmaquick/dialog.h" + +class DialogQmlTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void loadAndShow(); + +private: + bool m_dialogShown; +}; + +#endif diff --git a/autotests/dialogstatetest.cpp b/autotests/dialogstatetest.cpp new file mode 100644 index 0000000..3eb7300 --- /dev/null +++ b/autotests/dialogstatetest.cpp @@ -0,0 +1,97 @@ +/* + SPDX-FileCopyrightText: 2016 Eike Hein + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "dialogstatetest.h" +#include +#include + +#include + +void DialogStateTest::initTestCase() +{ + m_dialog = new PlasmaQuick::Dialog; + m_dialog->setLocation(Plasma::Types::TopEdge); + m_dialog->setGeometry(0, 0, 50, 50); + + qRegisterMetaType("WId"); +} + +void DialogStateTest::cleanupTestCase() +{ + delete m_dialog; +} + +void DialogStateTest::windowState() +{ + if (QGuiApplication::platformName() == "wayland") { + QEXPECT_FAIL("windowState", "KX11Extras::windowAdded doesn't work on wayland", Continue); + return; + } + + for (int i = 0; i <= 100; ++i) { + m_dialog->show(); + + QSignalSpy windowAddedSpy(KX11Extras::self(), &KX11Extras::windowAdded); + QVERIFY(windowAddedSpy.isValid()); + QVERIFY(windowAddedSpy.wait()); + + bool windowAdded = false; + + while (windowAddedSpy.count()) { + const QVariantList &arguments = windowAddedSpy.takeFirst(); + + if (arguments.at(0).value() == m_dialog->winId()) { + windowAdded = true; + break; + } + if (windowAddedSpy.isEmpty()) { + QVERIFY(windowAddedSpy.wait()); + } + } + + QVERIFY(windowAdded); + + QVERIFY(verifyState(m_dialog)); + + m_dialog->hide(); + + QSignalSpy windowRemovedSpy(KX11Extras::self(), &KX11Extras::windowRemoved); + QVERIFY(windowRemovedSpy.isValid()); + QVERIFY(windowRemovedSpy.wait()); + + bool windowRemoved = false; + + while (windowRemovedSpy.count()) { + const QVariantList &arguments = windowRemovedSpy.takeFirst(); + + if (arguments.at(0).value() == m_dialog->winId()) { + windowRemoved = true; + break; + } + } + + QVERIFY(windowRemoved); + } +} + +bool DialogStateTest::verifyState(PlasmaQuick::Dialog *dialog) const +{ + KWindowInfo info(dialog->winId(), NET::WMState); + + if (!(info.state() & NET::SkipTaskbar)) { + return false; + } + + if (!info.hasState(NET::SkipPager)) { + return false; + } + + return true; +} + +QTEST_MAIN(DialogStateTest) + +#include "moc_dialogstatetest.cpp" diff --git a/autotests/dialogstatetest.h b/autotests/dialogstatetest.h new file mode 100644 index 0000000..08e2fe3 --- /dev/null +++ b/autotests/dialogstatetest.h @@ -0,0 +1,30 @@ +/* + SPDX-FileCopyrightText: 2016 Eike Hein + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ +#ifndef DIALOGSTATETEST_H +#define DIALOGSTATETEST_H + +#include + +#include "plasmaquick/dialog.h" + +class DialogStateTest : public QObject +{ + Q_OBJECT + +public Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); + +private Q_SLOTS: + void windowState(); + +private: + bool verifyState(PlasmaQuick::Dialog *dialog) const; + + PlasmaQuick::Dialog *m_dialog; +}; + +#endif diff --git a/autotests/dummycontainmentaction.cpp b/autotests/dummycontainmentaction.cpp new file mode 100644 index 0000000..a047bb2 --- /dev/null +++ b/autotests/dummycontainmentaction.cpp @@ -0,0 +1,17 @@ +#include "containmentactions.h" +#include + +class DummyContainmentAction : public Plasma::ContainmentActions +{ + Q_OBJECT + +public: + explicit DummyContainmentAction(QObject *parent) + : Plasma::ContainmentActions(parent) + { + } +}; + +K_PLUGIN_CLASS_WITH_JSON(DummyContainmentAction, "dummycontainmentaction.json") + +#include "dummycontainmentaction.moc" diff --git a/autotests/dummycontainmentaction.json b/autotests/dummycontainmentaction.json new file mode 100644 index 0000000..505404f --- /dev/null +++ b/autotests/dummycontainmentaction.json @@ -0,0 +1,6 @@ +{ + "KPlugin": { + "Name": "DummyContainmentActions" + }, + "X-KDE-ParentApp": "plasma-shell" +} diff --git a/autotests/dynamictreemodel.cpp b/autotests/dynamictreemodel.cpp new file mode 100644 index 0000000..c78bea4 --- /dev/null +++ b/autotests/dynamictreemodel.cpp @@ -0,0 +1,292 @@ +/* + SPDX-FileCopyrightText: 2009 Stephen Kelly + SPDX-FileCopyrightText: 2009 Nokia Corporation and /or its subsidiary(-ies) + + This file is part of the test suite of the Qt Toolkit. + + SPDX-License-Identifier: LGPL-2.1-only WITH Qt-LGPL-exception-1.1 +*/ + +#include "dynamictreemodel.h" + +#include + +DynamicTreeModel::DynamicTreeModel(QObject *parent) + : QAbstractItemModel(parent) + , nextId(1) +{ +} + +QModelIndex DynamicTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + // if (column != 0) + // return QModelIndex(); + + if (column < 0 || row < 0) { + return QModelIndex(); + } + + QList> childIdColumns = m_childItems.value(parent.internalId()); + + const qint64 grandParent = findParentId(parent.internalId()); + if (grandParent >= 0) { + QList> parentTable = m_childItems.value(grandParent); + Q_ASSERT(parent.column() < parentTable.size()); + QList parentSiblings = parentTable.at(parent.column()); + Q_ASSERT(parent.row() < parentSiblings.size()); + } + + if (childIdColumns.size() == 0) { + return QModelIndex(); + } + + if (column >= childIdColumns.size()) { + return QModelIndex(); + } + + QList rowIds = childIdColumns.at(column); + + if (row >= rowIds.size()) { + return QModelIndex(); + } + + qint64 id = rowIds.at(row); + + return createIndex(row, column, reinterpret_cast(id)); +} + +qint64 DynamicTreeModel::findParentId(qint64 searchId) const +{ + if (searchId <= 0) { + return -1; + } + + QHashIterator>> i(m_childItems); + while (i.hasNext()) { + i.next(); + QListIterator> j(i.value()); + while (j.hasNext()) { + QList l = j.next(); + if (l.contains(searchId)) { + return i.key(); + } + } + } + return -1; +} + +QModelIndex DynamicTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) { + return QModelIndex(); + } + + qint64 searchId = index.internalId(); + qint64 parentId = findParentId(searchId); + // Will never happen for valid index, but what the hey... + if (parentId <= 0) { + return QModelIndex(); + } + + qint64 grandParentId = findParentId(parentId); + if (grandParentId < 0) { + grandParentId = 0; + } + + int column = 0; + QList childList = m_childItems.value(grandParentId).at(column); + + int row = childList.indexOf(parentId); + + return createIndex(row, column, reinterpret_cast(parentId)); +} + +int DynamicTreeModel::rowCount(const QModelIndex &index) const +{ + QList> cols = m_childItems.value(index.internalId()); + + if (cols.size() == 0) { + return 0; + } + + if (index.column() > 0) { + return 0; + } + + return cols.at(0).size(); +} + +int DynamicTreeModel::columnCount(const QModelIndex &index) const +{ + // Q_UNUSED(index); + return m_childItems.value(index.internalId()).size(); +} + +QVariant DynamicTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return QVariant(); + } + + if (Qt::DisplayRole == role) { + return m_items.value(index.internalId()); + } + return QVariant(); +} + +void DynamicTreeModel::clear() +{ + beginResetModel(); + m_items.clear(); + m_childItems.clear(); + nextId = 1; + endResetModel(); +} + +ModelChangeCommand::ModelChangeCommand(DynamicTreeModel *model, QObject *parent) + : QObject(parent) + , m_model(model) + , m_numCols(1) + , m_startRow(-1) + , m_endRow(-1) +{ +} + +QModelIndex ModelChangeCommand::findIndex(QList rows) +{ + const int col = 0; + QModelIndex parent = QModelIndex(); + QListIterator i(rows); + while (i.hasNext()) { + parent = m_model->index(i.next(), col, parent); + Q_ASSERT(parent.isValid()); + } + return parent; +} + +ModelInsertCommand::ModelInsertCommand(DynamicTreeModel *model, QObject *parent) + : ModelChangeCommand(model, parent) +{ +} + +void ModelInsertCommand::doCommand() +{ + QModelIndex parent = findIndex(m_rowNumbers); + m_model->beginInsertRows(parent, m_startRow, m_endRow); + qint64 parentId = parent.internalId(); + for (int row = m_startRow; row <= m_endRow; row++) { + for (int col = 0; col < m_numCols; col++) { + if (m_model->m_childItems[parentId].size() <= col) { + m_model->m_childItems[parentId].append(QList()); + } + // QString name = QUuid::createUuid().toString(); + qint64 id = m_model->newId(); + QString name = QString::number(id); + + m_model->m_items.insert(id, name); + m_model->m_childItems[parentId][col].insert(row, id); + } + } + m_model->endInsertRows(); +} + +ModelMoveCommand::ModelMoveCommand(DynamicTreeModel *model, QObject *parent) + : ModelChangeCommand(model, parent) +{ +} +bool ModelMoveCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) +{ + return m_model->beginMoveRows(srcParent, srcStart, srcEnd, destParent, destRow); +} + +void ModelMoveCommand::doCommand() +{ + QModelIndex srcParent = findIndex(m_rowNumbers); + QModelIndex destParent = findIndex(m_destRowNumbers); + + if (!emitPreSignal(srcParent, m_startRow, m_endRow, destParent, m_destRow)) { + return; + } + + for (int column = 0; column < m_numCols; ++column) { + const QList lst = m_model->m_childItems.value(srcParent.internalId())[column].mid(m_startRow, m_endRow - m_startRow + 1); + + for (int i = m_startRow; i <= m_endRow; i++) { + m_model->m_childItems[srcParent.internalId()][column].removeAt(m_startRow); + } + int d; + if (m_destRow < m_startRow) { + d = m_destRow; + } else { + if (srcParent == destParent) { + d = m_destRow - (m_endRow - m_startRow + 1); + } else { + d = m_destRow - (m_endRow - m_startRow) + 1; + } + } + + for (const qint64 id : lst) { + m_model->m_childItems[destParent.internalId()][column].insert(d++, id); + } + } + + emitPostSignal(); +} + +void ModelMoveCommand::emitPostSignal() +{ + m_model->endMoveRows(); +} + +ModelResetCommand::ModelResetCommand(DynamicTreeModel *model, QObject *parent) + : ModelMoveCommand(model, parent) +{ +} + +ModelResetCommand::~ModelResetCommand() +{ +} + +bool ModelResetCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) +{ + Q_UNUSED(srcParent); + Q_UNUSED(srcStart); + Q_UNUSED(srcEnd); + Q_UNUSED(destParent); + Q_UNUSED(destRow); + + return true; +} + +void ModelResetCommand::emitPostSignal() +{ + m_model->reset(); +} + +ModelResetCommandFixed::ModelResetCommandFixed(DynamicTreeModel *model, QObject *parent) + : ModelMoveCommand(model, parent) +{ +} + +ModelResetCommandFixed::~ModelResetCommandFixed() +{ +} + +bool ModelResetCommandFixed::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) +{ + Q_UNUSED(srcParent); + Q_UNUSED(srcStart); + Q_UNUSED(srcEnd); + Q_UNUSED(destParent); + Q_UNUSED(destRow); + + m_model->beginResetModel(); + return true; +} + +void ModelResetCommandFixed::emitPostSignal() +{ + m_model->endResetModel(); +} + +#include "moc_dynamictreemodel.cpp" diff --git a/autotests/dynamictreemodel.h b/autotests/dynamictreemodel.h new file mode 100644 index 0000000..9b17b3c --- /dev/null +++ b/autotests/dynamictreemodel.h @@ -0,0 +1,182 @@ +/* + SPDX-FileCopyrightText: 2009 Stephen Kelly + SPDX-FileCopyrightText: 2009 Nokia Corporation and /or its subsidiary(-ies) + + This file is part of the test suite of the Qt Toolkit. + + SPDX-License-Identifier: LGPL-2.1-only WITH Qt-LGPL-exception-1.1 +*/ + +#ifndef DYNAMICTREEMODEL_H +#define DYNAMICTREEMODEL_H + +#include + +#include +#include + +class DynamicTreeModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + DynamicTreeModel(QObject *parent = nullptr); + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index) const; + int rowCount(const QModelIndex &index = QModelIndex()) const; + int columnCount(const QModelIndex &index = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + + void clear(); + +protected Q_SLOTS: + + /** + Finds the parent id of the string with id @p searchId. + + Returns -1 if not found. + */ + qint64 findParentId(qint64 searchId) const; + +private: + QHash m_items; + QHash>> m_childItems; + qint64 nextId; + qint64 newId() + { + return nextId++; + }; + + QModelIndex m_nextParentIndex; + int m_nextRow; + + int m_depth; + int maxDepth; + + friend class ModelInsertCommand; + friend class ModelMoveCommand; + friend class ModelResetCommand; + friend class ModelResetCommandFixed; +}; + +class ModelChangeCommand : public QObject +{ + Q_OBJECT +public: + explicit ModelChangeCommand(DynamicTreeModel *model, QObject *parent = nullptr); + + virtual ~ModelChangeCommand() + { + } + + void setAncestorRowNumbers(QList rowNumbers) + { + m_rowNumbers = rowNumbers; + } + + QModelIndex findIndex(QList rows); + + void setStartRow(int row) + { + m_startRow = row; + } + + void setEndRow(int row) + { + m_endRow = row; + } + + void setNumCols(int cols) + { + m_numCols = cols; + } + + virtual void doCommand() = 0; + +protected: + DynamicTreeModel *m_model; + QList m_rowNumbers; + int m_numCols; + int m_startRow; + int m_endRow; +}; + +typedef QList ModelChangeCommandList; + +class ModelInsertCommand : public ModelChangeCommand +{ + Q_OBJECT + +public: + explicit ModelInsertCommand(DynamicTreeModel *model, QObject *parent = nullptr); + virtual ~ModelInsertCommand() + { + } + + void doCommand() override; +}; + +class ModelMoveCommand : public ModelChangeCommand +{ + Q_OBJECT +public: + ModelMoveCommand(DynamicTreeModel *model, QObject *parent); + + virtual ~ModelMoveCommand() + { + } + + virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); + + void doCommand() override; + + virtual void emitPostSignal(); + + void setDestAncestors(QList rows) + { + m_destRowNumbers = rows; + } + + void setDestRow(int row) + { + m_destRow = row; + } + +protected: + QList m_destRowNumbers; + int m_destRow; +}; + +/** + A command which does a move and emits a reset signal. +*/ +class ModelResetCommand : public ModelMoveCommand +{ + Q_OBJECT +public: + explicit ModelResetCommand(DynamicTreeModel *model, QObject *parent = nullptr); + + virtual ~ModelResetCommand(); + + bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) override; + void emitPostSignal() override; +}; + +/** + A command which does a move and emits a beginResetModel and endResetModel signals. +*/ +class ModelResetCommandFixed : public ModelMoveCommand +{ + Q_OBJECT +public: + explicit ModelResetCommandFixed(DynamicTreeModel *model, QObject *parent = nullptr); + + virtual ~ModelResetCommandFixed(); + + bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) override; + void emitPostSignal() override; +}; + +#endif diff --git a/autotests/i18ndcheck.sh b/autotests/i18ndcheck.sh new file mode 100644 index 0000000..668f90e --- /dev/null +++ b/autotests/i18ndcheck.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +#If this test fails it means you are probably using i18n() in your QML code +#This should be replaced by i18nd in order to for i18n to load the correct catalog + +#First arg should be the directory to check + +! find "$1" -name '*.qml' -print0 | xargs -0 grep 'i18n[^d]*(' + diff --git a/autotests/input/resizemodeitem.qml b/autotests/input/resizemodeitem.qml new file mode 100644 index 0000000..c1cdb80 --- /dev/null +++ b/autotests/input/resizemodeitem.qml @@ -0,0 +1,5 @@ +import QtQuick +Item { + width: 200 + height: 200 +} diff --git a/autotests/plasma-test-appletsrc b/autotests/plasma-test-appletsrc new file mode 100644 index 0000000..ef84978 --- /dev/null +++ b/autotests/plasma-test-appletsrc @@ -0,0 +1,38 @@ + +[Containments][1] +formfactor=0 +immutability=1 +lastScreen=0 +location=0 +plugin=simplecontainment + +#those two applets are not ordered by id +#but applets() should be ordered anyways +[Containments][1][Applets][3] +immutability=1 +plugin=simpleapplet + +[Containments][1][Applets][2] +immutability=1 +plugin=invalid + +#empty panel: should emit complete even if empty +[Containments][4] +formfactor=2 +immutability=1 +lastScreen=0 +location=4 +plugin=simplecontainment + +#this is a desktop containment that even if has lastScreen=0 +#its screen will be -1: this is the case of a containment of +#another activity, not the current one +[Containments][5] +formfactor=0 +immutability=1 +lastScreen=0 +location=0 +plugin=simplenoscreencontainment + +[General] +immutability=1 diff --git a/autotests/plasmoidpackagerc b/autotests/plasmoidpackagerc new file mode 100644 index 0000000..3feaaa4 --- /dev/null +++ b/autotests/plasmoidpackagerc @@ -0,0 +1,38 @@ +Type=Plasmoid + +[images] +Path=images +Name=Images +Mimetypes=image/svg+xml,image/png,image/jpeg +Directory=true + +[config] +Path=config/xml +Name=Configuration Definitions +Mimetypes=text/xml +Directory=true + +[configui] +Path=config/ui +Name=Configuration UI +Mimetypes=text/xml +Directory=true + +[scripts] +Path=code +Name=Executable Scripts +Mimetypes=text/* +Directory=true + +[mainconfiggui] +Path=config/ui/main.ui +Name=Main Config UI File + +[mainconfigxml] +Path=config/ui/main.xml +Name=Configuration XML File + +[mainscript] +Path=code/main +Name=Main Script File +Required=true diff --git a/autotests/plasmoidpackagetest.cpp b/autotests/plasmoidpackagetest.cpp new file mode 100644 index 0000000..0f08924 --- /dev/null +++ b/autotests/plasmoidpackagetest.cpp @@ -0,0 +1,287 @@ +/* + SPDX-FileCopyrightText: 2007 Bertjan Broeksema + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "plasmoidpackagetest.h" +#include "../config-plasma.h" + +#include +#include +#include +#include +#include + +#include + +#include "applet.h" +#include "pluginloader.h" + +void PlasmoidPackageTest::initTestCase() +{ + QStandardPaths::setTestModeEnabled(true); +} + +void PlasmoidPackageTest::init() +{ + qDebug() << "PlasmoidPackage::init()"; + m_package = QString("Package"); + m_packageRoot = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/packageRoot"; + m_defaultPackage = Plasma::PluginLoader::self()->loadPackage("Plasma/Applet"); + cleanup(); // to prevent previous runs from interfering with this one +} + +void PlasmoidPackageTest::cleanup() +{ + qDebug() << "cleaning up"; + // Clean things up. + QDir(m_packageRoot).removeRecursively(); +} + +void PlasmoidPackageTest::createTestPackage(const QString &packageName) +{ + qDebug() << "Create test package" << m_packageRoot; + QDir pRoot(m_packageRoot); + // Create the root and package dir. + if (!pRoot.exists()) { + QVERIFY(QDir().mkpath(m_packageRoot)); + } + + // Create the package dir + QVERIFY(QDir().mkpath(m_packageRoot + "/" + packageName)); + qDebug() << "Created" << (m_packageRoot + "/" + packageName); + + // Create the metadata.desktop file + QFile file(m_packageRoot + "/" + packageName + "/metadata.desktop"); + + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text)); + + QTextStream out(&file); + out << "[Desktop Entry]\n"; + out << "Name=" << packageName << "\n"; + out << "X-KDE-PluginInfo-Name=" << packageName << "\n"; + file.flush(); + file.close(); + + qDebug() << "OUT: " << packageName; + + // Create the ui dir. + QVERIFY(QDir().mkpath(m_packageRoot + "/" + packageName + "/contents/ui")); + + // Create the main file. + file.setFileName(m_packageRoot + "/" + packageName + "/contents/ui/main.qml"); + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text)); + + out << "THIS IS A PLASMOID SCRIPT....."; + file.flush(); + file.close(); + + qDebug() << "THIS IS A PLASMOID SCRIPT THING"; + // Now we have a minimal plasmoid package which is valid. Let's add some + // files to it for test purposes. + + // Create the images dir. + QVERIFY(QDir().mkpath(m_packageRoot + "/" + packageName + "/contents/images")); + file.setFileName(m_packageRoot + "/" + packageName + "/contents/images/image-1.svg"); + + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text)); + + out << "This is a test image"; + file.flush(); + file.close(); + + file.setFileName(m_packageRoot + "/" + packageName + "/contents/images/image-2.svg"); + + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text)); + + out.setDevice(&file); + out << "This is another test image"; + file.flush(); + file.close(); +} + +void PlasmoidPackageTest::isValid() +{ + Plasma::Package *p = new Plasma::Package(m_defaultPackage); + p->setPath(m_packageRoot + '/' + m_package); + + // A PlasmoidPackage is valid when: + // - The package root exists. + // - The package root consists an file named "ui/main.qml" + QVERIFY(!p->isValid()); + + // Create the root and package dir. + QVERIFY(QDir().mkpath(m_packageRoot)); + QVERIFY(QDir().mkpath(m_packageRoot + "/" + m_package)); + + // Should still be invalid. + delete p; + p = new Plasma::Package(m_defaultPackage); + p->setPath(m_packageRoot + '/' + m_package); + QVERIFY(!p->isValid()); + + // Create the metadata.desktop file. + QFile file(m_packageRoot + "/" + m_package + "/metadata.desktop"); + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text)); + + QTextStream out(&file); + out << "[Desktop Entry]\n"; + out << "Name=test\n"; + out << "Description=Just a test desktop file"; + file.flush(); + file.close(); + + // Create the ui dir. + QVERIFY(QDir().mkpath(m_packageRoot + "/" + m_package + "/contents/ui")); + + // No main file yet so should still be invalid. + delete p; + p = new Plasma::Package(m_defaultPackage); + p->setPath(m_packageRoot + '/' + m_package); + QVERIFY(!p->isValid()); + + // Create the main file. + file.setFileName(m_packageRoot + "/" + m_package + "/contents/ui/main.qml"); + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text)); + + out.setDevice(&file); + out << "THIS IS A PLASMOID SCRIPT.....\n"; + file.flush(); + file.close(); + + file.setPermissions(QFile::ReadUser | QFile::WriteUser); + // Main file exists so should be valid now. + delete p; + p = new Plasma::Package(m_defaultPackage); + p->setPath(m_packageRoot + '/' + m_package); + QVERIFY(p->isValid()); + QCOMPARE(p->contentsHash(), QString("db0b38c2b4fe21a9f37923cc25152340de055f6d")); + delete p; +} + +void PlasmoidPackageTest::filePath() +{ + return; + // Package::filePath() returns + // - {package_root}/{package_name}/path/to/file if the file exists + // - QString() otherwise. + Plasma::Package *p = new Plasma::Package(m_defaultPackage); + p->setPath(m_packageRoot + '/' + m_package); + + QCOMPARE(p->filePath("scripts", "main"), QString()); + + QVERIFY(QDir().mkpath(m_packageRoot + "/" + m_package + "/contents/ui/main.qml")); + QFile file(m_packageRoot + "/" + m_package + "/contents/ui/main.qml"); + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text)); + + QTextStream out(&file); + out << "THIS IS A PLASMOID SCRIPT....."; + file.flush(); + file.close(); + + // The package is valid by now so a path for code/main should get returned. + delete p; + p = new Plasma::Package(m_defaultPackage); + p->setPath(m_packageRoot + '/' + m_package); + + const QString path = QFileInfo(m_packageRoot + "/" + m_package + "/contents/ui/main.qml").canonicalFilePath(); + + // Two ways to get the same info. + // 1. Give the file type which refers to a class of files (a directory) in + // the package structure and the file name. + // 2. Give the file type which refers to a file in the package structure. + // + // NOTE: scripts, main and mainscript are defined in packages.cpp and are + // specific for a PlasmoidPackage. + QCOMPARE(p->filePath("scripts", "main"), path); + QCOMPARE(p->filePath("mainscript"), path); + delete p; +} + +void PlasmoidPackageTest::entryList() +{ + // Create a package named @p packageName which is valid and has some images. + createTestPackage(m_package); + + // Create a package object and verify that it is valid. + Plasma::Package *p = new Plasma::Package(m_defaultPackage); + p->setPath(m_packageRoot + '/' + m_package); + QVERIFY(p->isValid()); + + // Now we have a valid package that should contain the following files in + // given filetypes: + // fileTye - Files + // scripts - {"main"} + // images - {"image-1.svg", "image-2.svg"} + QStringList files = p->entryList("scripts"); + QCOMPARE(files.size(), 1); + QVERIFY(files.contains("main")); + + files = p->entryList("images"); + QCOMPARE(files.size(), 2); + QVERIFY(files.contains("image-1.svg")); + QVERIFY(files.contains("image-2.svg")); + delete p; +} + +void PlasmoidPackageTest::createAndInstallPackage() +{ + qDebug() << " "; + qDebug() << " CreateAndInstall "; + createTestPackage("plasmoid_to_package"); + const QString packagePath = m_packageRoot + '/' + "testpackage.plasmoid"; + + KZip creator(packagePath); + QVERIFY(creator.open(QIODevice::WriteOnly)); + creator.addLocalDirectory(m_packageRoot + '/' + "plasmoid_to_package", "."); + creator.close(); + KIO::NetAccess::del(QUrl::fromLocalFile(m_packageRoot + "/plasmoid_to_package"), 0); + + QVERIFY(QFile::exists(packagePath)); + + KZip package(packagePath); + QVERIFY(package.open(QIODevice::ReadOnly)); + const KArchiveDirectory *dir = package.directory(); + QVERIFY(dir); // + QVERIFY(dir->entry("metadata.desktop")); + const KArchiveEntry *contentsEntry = dir->entry("contents"); + QVERIFY(contentsEntry); + QVERIFY(contentsEntry->isDirectory()); + const KArchiveDirectory *contents = static_cast(contentsEntry); + QVERIFY(contents->entry("ui")); + QVERIFY(contents->entry("images")); + + m_defaultPackageStructure = new Plasma::PackageStructure(this); + Plasma::Package *p = new Plasma::Package(m_defaultPackageStructure); + qDebug() << "Installing " << archivePath; + // const QString packageRoot = "plasma/plasmoids/"; + // const QString servicePrefix = "plasma-applet-"; + KJob *job = p->install(archivePath, m_packageRoot); + connect(job, SIGNAL(finished(KJob *)), SLOT(packageInstalled(KJob *))); + + // QVERIFY(p->isValid()); + delete p; +} + +void PlasmoidPackageTest::packageInstalled(KJob *j) +{ + qDebug() << "!!!!!!!!!!!!!!!!!!!! package installed" << (j->error() == KJob::NoError); + QVERIFY(j->error() == KJob::NoError); + // QVERIFY(p->path()); + + Plasma::Package *p = new Plasma::Package(m_defaultPackageStructure); + KJob *jj = p->uninstall("org.kde.microblog-qml", m_packageRoot); + // QObject::disconnect(j, SIGNAL(finished(KJob*)), this, SLOT(packageInstalled(KJob*))); + connect(jj, SIGNAL(finished(KJob *)), SLOT(packageInstalled(KJob *))); +} + +void PlasmoidPackageTest::packageUninstalled(KJob *j) +{ + qDebug() << "!!!!!!!!!!!!!!!!!!!!! package uninstalled"; + QVERIFY(j->error() == KJob::NoError); +} + +QTEST_MAIN(PlasmoidPackageTest) + +#include "moc_plasmoidpackagetest.cpp" diff --git a/autotests/plasmoidpackagetest.h b/autotests/plasmoidpackagetest.h new file mode 100644 index 0000000..4e0c797 --- /dev/null +++ b/autotests/plasmoidpackagetest.h @@ -0,0 +1,42 @@ +/* + SPDX-FileCopyrightText: 2007 Bertjan Broeksema + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PACKAGETEST_H + +#include + +#include "plasma/package.h" +#include "plasma/packagestructure.h" + +class PlasmoidPackageTest : public QObject +{ + Q_OBJECT + +public Q_SLOTS: + void initTestCase(); + void init(); + void cleanup(); + +private Q_SLOTS: + void createAndInstallPackage(); + void isValid(); + void filePath(); + void entryList(); + + void packageInstalled(KJob *j); + void packageUninstalled(KJob *j); + +private: + void createTestPackage(const QString &packageName); + + QString m_packageRoot; + QString m_package; + KJob *m_packageJob; + Plasma::Package m_defaultPackage; + Plasma::PackageStructure *m_defaultPackageStructure; +}; + +#endif diff --git a/autotests/pluginloadertest.cpp b/autotests/pluginloadertest.cpp new file mode 100644 index 0000000..610a112 --- /dev/null +++ b/autotests/pluginloadertest.cpp @@ -0,0 +1,43 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "pluginloadertest.h" + +#include +#include +#include + +#include + +#include + +QTEST_MAIN(PluginTest) + +PluginTest::PluginTest() +{ + // To pick up the simpelcontianment dummy package + qputenv("XDG_DATA_DIRS", QFINDTESTDATA("data/").toLocal8Bit().constData()); +} + +void PluginTest::listContainmentActions() +{ + const QList plugins = Plasma::PluginLoader::self()->listContainmentActionsMetaData(QStringLiteral("plasma-shell")); + const bool pluginFound = std::any_of(plugins.begin(), plugins.end(), [](const KPluginMetaData &data) { + return data.pluginId() == QLatin1String("dummycontainmentaction"); + }); + QVERIFY(pluginFound); +} + +void PluginTest::listContainmentsOfType() +{ + const QList plugins = Plasma::PluginLoader::listContainmentsMetaDataOfType(QStringLiteral("Desktop")); + const bool pluginFound = std::any_of(plugins.begin(), plugins.end(), [](const KPluginMetaData &data) { + return data.pluginId() == QLatin1String("simplecontainment"); + }); + QVERIFY(pluginFound); +} + +#include "moc_pluginloadertest.cpp" diff --git a/autotests/pluginloadertest.h b/autotests/pluginloadertest.h new file mode 100644 index 0000000..5dc5213 --- /dev/null +++ b/autotests/pluginloadertest.h @@ -0,0 +1,23 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLUGINLOADERTEST_H +#define PLUGINLOADERTEST_H + +#include + +class PluginTest : public QObject +{ + Q_OBJECT +public: + PluginTest(); + +private Q_SLOTS: + void listContainmentActions(); + void listContainmentsOfType(); +}; + +#endif diff --git a/autotests/quickviewsharedenginetest.cpp b/autotests/quickviewsharedenginetest.cpp new file mode 100644 index 0000000..6612123 --- /dev/null +++ b/autotests/quickviewsharedenginetest.cpp @@ -0,0 +1,257 @@ +/* + This file is part of the test suite of the Qt Toolkit. + SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) + + SPDX-License-Identifier: LGPL-2.1-only WITH Qt-LGPL-exception-1.1 OR LGPL-3.0-only WITH Qt-LGPL-exception-1.1 OR LicenseRef-Qt-Commercial +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QQmlDataTest : public QObject +{ + Q_OBJECT +public: + QQmlDataTest() + { + } + + QString testFile(const QString &fileName) const + { + if (m_directory.isEmpty()) { + qFatal("QQmlDataTest::initTestCase() not called."); + } + QString result = m_dataDirectory; + result += QLatin1Char('/'); + result += fileName; + return result; + } + inline QString testFile(const char *fileName) const + { + return testFile(QLatin1String(fileName)); + } + inline QUrl testFileUrl(const QString &fileName) const + { + return QUrl::fromLocalFile(testFile(fileName)); + } + inline QUrl testFileUrl(const char *fileName) const + { + return testFileUrl(QLatin1String(fileName)); + } + + inline QString dataDirectory() const + { + return m_dataDirectory; + } + inline QUrl dataDirectoryUrl() const + { + return m_dataDirectoryUrl; + } + inline QString directory() const + { + return m_directory; + } + + static QByteArray msgComponentError(const QQmlComponent &, const QQmlEngine *engine = nullptr); + +public Q_SLOTS: + virtual void initTestCase() + { + QVERIFY2(!m_dataDirectory.isEmpty(), "'input' directory not found"); + m_directory = QFileInfo(m_dataDirectory).absolutePath(); + QVERIFY2(QDir::setCurrent(m_directory), qPrintable(QLatin1String("Could not chdir to ") + m_directory)); + } + +private: + static QQmlDataTest *m_instance; + + const QString m_dataDirectory = QFINDTESTDATA("input"); + const QUrl m_dataDirectoryUrl = QUrl::fromLocalFile(m_dataDirectory + QLatin1Char('/')); + + QString m_directory; +}; + +class QuickViewSharedEngineTest : public QQmlDataTest +{ + Q_OBJECT +public: + QuickViewSharedEngineTest(); + +private Q_SLOTS: + void resizemodeitem(); + void errors(); + void engine(); +}; + +QuickViewSharedEngineTest::QuickViewSharedEngineTest() +{ +} + +void QuickViewSharedEngineTest::resizemodeitem() +{ + QWindow window; + window.setGeometry(0, 0, 400, 400); + + auto view = new PlasmaQuick::QuickViewSharedEngine(&window); + QVERIFY(view); + view->setResizeMode(PlasmaQuick::QuickViewSharedEngine::SizeRootObjectToView); + QCOMPARE(QSize(0, 0), view->initialSize()); + view->setSource(testFileUrl("resizemodeitem.qml")); + QQuickItem *item = qobject_cast(view->rootObject()); + QVERIFY(item); + window.show(); + + view->showNormal(); + + // initial size from root object + QCOMPARE(item->width(), 200.0); + QCOMPARE(item->height(), 200.0); + QCOMPARE(view->size(), QSize(200, 200)); + QCOMPARE(view->size(), view->sizeHint()); + QCOMPARE(view->size(), view->initialSize()); + + // size update from view + view->resize(QSize(80, 100)); + + QTRY_COMPARE(item->width(), 80.0); + QCOMPARE(item->height(), 100.0); + QCOMPARE(view->size(), QSize(80, 100)); + QCOMPARE(view->size(), view->sizeHint()); + + view->setResizeMode(PlasmaQuick::QuickViewSharedEngine::SizeViewToRootObject); + + // size update from view disabled + view->resize(QSize(60, 80)); + QCOMPARE(item->width(), 80.0); + QCOMPARE(item->height(), 100.0); + QTest::qWait(50); + QCOMPARE(view->size(), QSize(60, 80)); + + // size update from root object + item->setWidth(250); + item->setHeight(350); + QCOMPARE(item->width(), 250.0); + QCOMPARE(item->height(), 350.0); + QTRY_COMPARE(view->size(), QSize(250, 350)); + QCOMPARE(view->size(), QSize(250, 350)); + QCOMPARE(view->size(), view->sizeHint()); + + // reset window + window.hide(); + delete view; + view = new PlasmaQuick::QuickViewSharedEngine(&window); + QVERIFY(view); + view->setResizeMode(PlasmaQuick::QuickViewSharedEngine::SizeViewToRootObject); + view->setSource(testFileUrl("resizemodeitem.qml")); + item = qobject_cast(view->rootObject()); + QVERIFY(item); + window.show(); + + view->showNormal(); + + // initial size for root object + QCOMPARE(item->width(), 200.0); + QCOMPARE(item->height(), 200.0); + QCOMPARE(view->size(), view->sizeHint()); + QCOMPARE(view->size(), view->initialSize()); + + // size update from root object + item->setWidth(80); + item->setHeight(100); + QCOMPARE(item->width(), 80.0); + QCOMPARE(item->height(), 100.0); + QTRY_COMPARE(view->size(), QSize(80, 100)); + QCOMPARE(view->size(), QSize(80, 100)); + QCOMPARE(view->size(), view->sizeHint()); + + // size update from root object disabled + view->setResizeMode(PlasmaQuick::QuickViewSharedEngine::SizeRootObjectToView); + item->setWidth(60); + item->setHeight(80); + QCOMPARE(view->width(), 80); + QCOMPARE(view->height(), 100); + QCOMPARE(QSize(item->width(), item->height()), view->sizeHint()); + + // size update from view + view->resize(QSize(200, 300)); + QTRY_COMPARE(item->width(), 200.0); + QCOMPARE(item->height(), 300.0); + QCOMPARE(view->size(), QSize(200, 300)); + QCOMPARE(view->size(), view->sizeHint()); + + delete view; + + // if we set a specific size for the view then it should keep that size + // for SizeRootObjectToView mode. + view = new PlasmaQuick::QuickViewSharedEngine(&window); + view->resize(300, 300); + view->setResizeMode(PlasmaQuick::QuickViewSharedEngine::SizeRootObjectToView); + QCOMPARE(QSize(0, 0), view->initialSize()); + view->setSource(testFileUrl("resizemodeitem.qml")); + qWarning() << "bbb" << view->size(); + view->resize(300, 300); + qWarning() << "ccc" << view->size(); + item = qobject_cast(view->rootObject()); + QVERIFY(item); + + view->showNormal(); + QTest::qWait(50); + + // initial size from root object + QCOMPARE(item->width(), 300.0); + QCOMPARE(item->height(), 300.0); + QCOMPARE(view->size(), QSize(300, 300)); + QCOMPARE(view->size(), view->sizeHint()); + QCOMPARE(view->initialSize(), QSize(200, 200)); // initial object size + + delete view; +} + +QStringList messages; +void messageHandler(QtMsgType, const QMessageLogContext &, const QString &message) +{ + messages.append(message); +}; +void QuickViewSharedEngineTest::errors() +{ + qInstallMessageHandler(messageHandler); + + auto view = new PlasmaQuick::QuickViewSharedEngine; + QVERIFY(view); + view->setSource(testFileUrl("error1.qml")); + QCOMPARE(view->status(), QQmlComponent::Error); + QVERIFY(messages.count() >= 1); + delete view; +} + +void QuickViewSharedEngineTest::engine() +{ + // test if engines are actually shared + // test if the engine gets deleted when the last view dies + auto view = new PlasmaQuick::QuickViewSharedEngine(); + QQmlEngine *engine = view->engine().get(); + + auto view2 = new PlasmaQuick::QuickViewSharedEngine(); + QQmlEngine *engine2 = view2->engine().get(); + + QCOMPARE(engine, engine2); + QSignalSpy engineDestroyedSpy(engine, &QObject::destroyed); + + delete view; + delete view2; + + QCOMPARE(engineDestroyedSpy.count(), 1); +} + +QTEST_MAIN(QuickViewSharedEngineTest) + +#include "quickviewsharedenginetest.moc" diff --git a/autotests/sharedqmlenginetest.cpp b/autotests/sharedqmlenginetest.cpp new file mode 100644 index 0000000..4da7e59 --- /dev/null +++ b/autotests/sharedqmlenginetest.cpp @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: 2023 Alexander Lohnau +// SPDX-License-Identifier: LGPL-2.0-or-later + +#include +#include + +using namespace PlasmaQuick; + +class SharedQmlEngineTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void testSettingTranslationDomain() + { + std::unique_ptr obj(new SharedQmlEngine()); + + const QString testDomain = QStringLiteral("testme"); + QVERIFY(obj->translationDomain().isEmpty()); + obj->setTranslationDomain(testDomain); + QCOMPARE(obj->translationDomain(), testDomain); + obj.reset(new SharedQmlEngine()); + QVERIFY(obj->translationDomain().isEmpty()); + } + + void testUsingSameEngine() + { + std::unique_ptr obj1(new SharedQmlEngine()); + std::unique_ptr obj2(new SharedQmlEngine()); + + QVERIFY(obj1->engine() == obj2->engine()); + QVERIFY(obj1->rootContext() != obj2->rootContext()); + } + + void testDeletingEngine() + { + std::unique_ptr obj1(new SharedQmlEngine()); + std::weak_ptr weakPtr(obj1->engine()); + QVERIFY(weakPtr.lock()); + + // The one in obj1 + QCOMPARE(weakPtr.use_count(), 1); + + { + std::unique_ptr obj2(new SharedQmlEngine()); + // The one in obj1 and in obj2 + QCOMPARE(weakPtr.use_count(), 2); + } + + obj1.reset(nullptr); + // Our object is deleted and as the last strong ref it should ensure everything is deleted. + QVERIFY(!weakPtr.lock()); + QCOMPARE(weakPtr.use_count(), 0); + } +}; + +QTEST_MAIN(SharedQmlEngineTest) + +#include "sharedqmlenginetest.moc" diff --git a/autotests/signed.plasmoid b/autotests/signed.plasmoid new file mode 100644 index 0000000000000000000000000000000000000000..68ca4b70accd1e8d70bbaca2f8253674d3d8b54b GIT binary patch literal 1540 zcmWIWW@h1H0D;oTN;@zEN^mmBFeK;am89mC6zhkEa56B*X7%_!u)pV9TEWf0$nt`j zfq^9js5k&_L|SPliV=LsMkME_q(aPz4_ScA91);-9AKyLt44;qF)=V~Wno|t#V{u~ zF*8pus~GMqH3tl5%?&x2ciVtx?{DoJZvvz}a^HlNaI`UMZxEB6miuzUYNd-CgLtj0NN!;-%N2zy=OngYFJpC!X35?CLd;Xc zaZ!kb*^{UhTMuTg%09y9=+UW|63Y6->QDR8B)%Um8O>$e(l0VTb8A_9c~we=Q~mx| zN{?P~|LeH5c$e+8mPqF-d>i`DDQl=d7SrYQ>IsSnJD;^U^umJUvl(Zf%3IYHVCF5j z;f{vR-1yMMy&NzPkJ8-PL^2$Y)ARFP=H@NKP#0 zWmu-vqNVN&?IJ&)$^0a^`AkQ8xs&||hSvHQPR?yhUrcV7tXY=-!qYpkuX5oP*@tHD zr9~n)Etwp9Z&J6M4L=w2#=`sjmQ}+4b}rq^5wp?FbA`h3qR^(KnSbXooqAzvYpgWk zx=|*V>#djfZhA|Zalb80*IuH@!p`>6s39jH&q~s!Pit<_+-)MxR*clm@I@z_oI z6XSw5_}Qj8Z%>-yv;OO?AUn&r!dd!{)sISQY%Fm$%?Q7;=ZQ!D4z`QiGD7*)zI%Kv zjhj;}yXkX$`dOlsWf*Yf0@W`3ajtNFp(8HsCl zg$I?DE!{kAy^cS(=CPZ~r#UAwxt6J=O2~gae)Ri-`1sp3m+qGR-_FFf)~)oQ72i#L zP~t`;%Fw!;8UscK23=sn6aXg5+|-i9l*E!my_D4A?2`NfeCaVaFxv01fxw^dnl+5e z3mCjZd>fn=PK;s{dX((BZRPDBito31<@a9>5z(x9cjirn&F`7YZ*Q_kTJ$Z~|Hviw zRaho5)Kxg*-fXd_MhPrt_a@G$%)Yqs+{I-Rg?m&Mu9|RShugIS3jJ(P9#_SBJ$`c4 z>x}k$ljP&8f_bfamI)=*a;*rL=wIgaapAnrPO;18DaLMd5L3G>5S21fgn7ZTr!ns* zne*P;|ASk?e9v<2_{T?B$wqhk8og@$?W%;J3c_k0cXSFBPG&ycdeCX%`Ls)KFy z_VtFJH%hKPH&<2dwdlh+%F4;jHzn3wHC=kkh`m+z#+R8J&q}*_$-bWbrp#yGV{=J2 z+qAToEWQ2eu{_62rah6kaP`aiPfDV1IlemY{1N=l=*#i8Z7(b~{=Hi&ANvPbtS~ak zG2<$mB%q~~0K;2H5EH4SVuh4c7^M`#ILvYi**Irp literal 0 HcmV?d00001 diff --git a/autotests/signed.plasmoid.sig b/autotests/signed.plasmoid.sig new file mode 100644 index 0000000000000000000000000000000000000000..cbaacf7949b14aadeb8d4d69105651a9a0b2a0e7 GIT binary patch literal 72 zcmV-O0Jr~$Mg#y60ssaD0!`jf!~hBj5Z1RYv8VCdLocELo+2&sw%v?~v&Tv1!-fs_ eS!*bY=K!Bu-)m5&3a)btmFv=k?tH^|D(GqaP9TQ> literal 0 HcmV?d00001 diff --git a/autotests/themetest.cpp b/autotests/themetest.cpp new file mode 100644 index 0000000..b03e8aa --- /dev/null +++ b/autotests/themetest.cpp @@ -0,0 +1,161 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "themetest.h" +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#if HAVE_X11 +#include +#endif +#include + +void ThemeTest::initTestCase() +{ + // make our theme in search path + qputenv("XDG_DATA_DIRS", QByteArray(qgetenv("XDG_DATA_DIRS") + ":" + QFINDTESTDATA("data").toLocal8Bit())); + + // set default icon theme to test-theme + QStandardPaths::setTestModeEnabled(true); + + m_theme = new Plasma::Theme("testtheme", this); + QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation); + + if (!QDir(configPath).mkpath(QStringLiteral("."))) { + qFatal("Failed to create test configuration directory."); + } + + QFile::remove(configPath); + + QIcon::setThemeSearchPaths(QStringList() << QFINDTESTDATA("data/icons")); + + KConfigGroup plasmaConfig(KSharedConfig::openConfig("plasmarc"), "Theme"); + plasmaConfig.writeEntry("name", "default"); + + KIconTheme::forceThemeForTests("test-theme"); + KSharedConfig::openConfig()->reparseConfiguration(); + KIconTheme::reconfigure(); + KIconLoader::global()->reconfigure(QString()); +} + +void ThemeTest::testThemeConfig_data() +{ + QTest::addColumn("themeName"); + + QTest::addRow("new metadata style theme") << QStringLiteral("testtheme"); +} + +void ThemeTest::testThemeConfig() +{ + QFETCH(QString, themeName); + auto theme = std::make_unique(themeName, this); + QCOMPARE(theme->backgroundContrastEnabled(), true); + QCOMPARE(theme->backgroundContrast(), 0.23); +} + +void ThemeTest::testColors() +{ + QCOMPARE(m_theme->color(Plasma::Theme::TextColor, Plasma::Theme::NormalColorGroup), QColor(49, 54, 59)); + QCOMPARE(m_theme->color(Plasma::Theme::BackgroundColor, Plasma::Theme::NormalColorGroup), QColor(239, 240, 241)); + QCOMPARE(m_theme->color(Plasma::Theme::HighlightColor, Plasma::Theme::NormalColorGroup), QColor(61, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::HoverColor, Plasma::Theme::NormalColorGroup), QColor(61, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::FocusColor, Plasma::Theme::NormalColorGroup), QColor(30, 146, 255)); + QCOMPARE(m_theme->color(Plasma::Theme::LinkColor, Plasma::Theme::NormalColorGroup), QColor(61, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::VisitedLinkColor, Plasma::Theme::NormalColorGroup), QColor(61, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::NormalColorGroup), QColor(252, 252, 252)); + QCOMPARE(m_theme->color(Plasma::Theme::PositiveTextColor, Plasma::Theme::NormalColorGroup), QColor(17, 209, 22)); + QCOMPARE(m_theme->color(Plasma::Theme::NeutralTextColor, Plasma::Theme::NormalColorGroup), QColor(201, 206, 59)); + QCOMPARE(m_theme->color(Plasma::Theme::NegativeTextColor, Plasma::Theme::NormalColorGroup), QColor(237, 21, 21)); + + QCOMPARE(m_theme->color(Plasma::Theme::TextColor, Plasma::Theme::ButtonColorGroup), QColor(49, 54, 59)); + QCOMPARE(m_theme->color(Plasma::Theme::BackgroundColor, Plasma::Theme::ButtonColorGroup), QColor(239, 240, 241)); + QCOMPARE(m_theme->color(Plasma::Theme::HighlightColor, Plasma::Theme::ButtonColorGroup), QColor(61, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::HoverColor, Plasma::Theme::ButtonColorGroup), QColor(61, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::FocusColor, Plasma::Theme::ButtonColorGroup), QColor(30, 146, 255)); + QCOMPARE(m_theme->color(Plasma::Theme::LinkColor, Plasma::Theme::ButtonColorGroup), QColor(61, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::VisitedLinkColor, Plasma::Theme::ButtonColorGroup), QColor(61, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::ButtonColorGroup), QColor(252, 252, 252)); + QCOMPARE(m_theme->color(Plasma::Theme::PositiveTextColor, Plasma::Theme::ButtonColorGroup), QColor(17, 209, 23)); + QCOMPARE(m_theme->color(Plasma::Theme::NeutralTextColor, Plasma::Theme::ButtonColorGroup), QColor(201, 206, 60)); + QCOMPARE(m_theme->color(Plasma::Theme::NegativeTextColor, Plasma::Theme::ButtonColorGroup), QColor(237, 21, 22)); + + QCOMPARE(m_theme->color(Plasma::Theme::TextColor, Plasma::Theme::ViewColorGroup), QColor(49, 54, 59)); + QCOMPARE(m_theme->color(Plasma::Theme::BackgroundColor, Plasma::Theme::ViewColorGroup), QColor(252, 252, 252)); + QCOMPARE(m_theme->color(Plasma::Theme::HighlightColor, Plasma::Theme::ViewColorGroup), QColor(61, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::HoverColor, Plasma::Theme::ViewColorGroup), QColor(61, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::FocusColor, Plasma::Theme::ViewColorGroup), QColor(30, 146, 255)); + QCOMPARE(m_theme->color(Plasma::Theme::LinkColor, Plasma::Theme::ViewColorGroup), QColor(61, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::VisitedLinkColor, Plasma::Theme::ViewColorGroup), QColor(61, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::ViewColorGroup), QColor(252, 252, 252)); + QCOMPARE(m_theme->color(Plasma::Theme::PositiveTextColor, Plasma::Theme::ViewColorGroup), QColor(17, 209, 24)); + QCOMPARE(m_theme->color(Plasma::Theme::NeutralTextColor, Plasma::Theme::ViewColorGroup), QColor(201, 206, 61)); + QCOMPARE(m_theme->color(Plasma::Theme::NegativeTextColor, Plasma::Theme::ViewColorGroup), QColor(237, 21, 23)); + + QCOMPARE(m_theme->color(Plasma::Theme::TextColor, Plasma::Theme::ComplementaryColorGroup), QColor(239, 240, 241)); + QCOMPARE(m_theme->color(Plasma::Theme::BackgroundColor, Plasma::Theme::ComplementaryColorGroup), QColor(49, 54, 59)); + QCOMPARE(m_theme->color(Plasma::Theme::HighlightColor, Plasma::Theme::ComplementaryColorGroup), QColor(61, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::HoverColor, Plasma::Theme::ComplementaryColorGroup), QColor(71, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::FocusColor, Plasma::Theme::ComplementaryColorGroup), QColor(40, 146, 255)); + QCOMPARE(m_theme->color(Plasma::Theme::LinkColor, Plasma::Theme::ComplementaryColorGroup), QColor(71, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::VisitedLinkColor, Plasma::Theme::ComplementaryColorGroup), QColor(71, 174, 230)); + QCOMPARE(m_theme->color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::ComplementaryColorGroup), QColor(252, 252, 252)); + QCOMPARE(m_theme->color(Plasma::Theme::PositiveTextColor, Plasma::Theme::ComplementaryColorGroup), QColor(17, 209, 25)); + QCOMPARE(m_theme->color(Plasma::Theme::NeutralTextColor, Plasma::Theme::ComplementaryColorGroup), QColor(201, 206, 62)); + QCOMPARE(m_theme->color(Plasma::Theme::NegativeTextColor, Plasma::Theme::ComplementaryColorGroup), QColor(237, 21, 24)); +} + +void ThemeTest::testCompositingChange() +{ + // this test simulates the compositing change on X11 +#if HAVE_X11 + if (!KWindowSystem::isPlatformX11()) { + QSKIP("Test is only for X11"); + } + QVERIFY(!KX11Extras::compositingActive()); + + // image path should give us an opaque variant + QVERIFY(m_theme->imagePath(QStringLiteral("element")).endsWith(QLatin1String("/desktoptheme/testtheme/opaque/element.svg"))); + + QSignalSpy themeChangedSpy(m_theme, &Plasma::Theme::themeChanged); + QVERIFY(themeChangedSpy.isValid()); + + // fake the compositor + QSignalSpy compositingChangedSpy(KX11Extras::self(), &KX11Extras::compositingChanged); + QVERIFY(compositingChangedSpy.isValid()); + std::unique_ptr compositorSelection(new KSelectionOwner("_NET_WM_CM_S0")); + QSignalSpy claimedSpy(compositorSelection.get(), &KSelectionOwner::claimedOwnership); + QVERIFY(claimedSpy.isValid()); + compositorSelection->claim(true); + QVERIFY(claimedSpy.wait()); + + QCOMPARE(compositingChangedSpy.count(), 1); + QVERIFY(KX11Extras::compositingActive()); + QVERIFY(themeChangedSpy.wait()); + QCOMPARE(themeChangedSpy.count(), 1); + QVERIFY(m_theme->imagePath(QStringLiteral("element")).endsWith(QLatin1String("/desktoptheme/testtheme/element.svg"))); + + // remove compositor again + compositorSelection.reset(); + QVERIFY(compositingChangedSpy.wait()); + QCOMPARE(compositingChangedSpy.count(), 2); + QVERIFY(!KX11Extras::compositingActive()); + QVERIFY(themeChangedSpy.wait()); + QCOMPARE(themeChangedSpy.count(), 2); + QVERIFY(m_theme->imagePath(QStringLiteral("element")).endsWith(QLatin1String("/desktoptheme/testtheme/opaque/element.svg"))); +#endif +} + +QTEST_MAIN(ThemeTest) + +#include "moc_themetest.cpp" diff --git a/autotests/themetest.h b/autotests/themetest.h new file mode 100644 index 0000000..8e14fc7 --- /dev/null +++ b/autotests/themetest.h @@ -0,0 +1,30 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ +#ifndef THEMETEST_H +#define THEMETEST_H + +#include + +#include "plasma/theme.h" + +class ThemeTest : public QObject +{ + Q_OBJECT + +public Q_SLOTS: + void initTestCase(); + +private Q_SLOTS: + void testThemeConfig_data(); + void testThemeConfig(); + void testColors(); + void testCompositingChange(); + +private: + Plasma::Theme *m_theme; +}; + +#endif diff --git a/autotests/utils.h b/autotests/utils.h new file mode 100644 index 0000000..69da03e --- /dev/null +++ b/autotests/utils.h @@ -0,0 +1,60 @@ +/* + SPDX-FileCopyrightText: 2019 Aleix Pol + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ +#ifndef UTILS_H +#define UTILS_H + +#include +#include +#include +#include + +namespace Plasma +{ +namespace TestUtils +{ +static void copyPath(const QString &src, const QString &dst) +{ + QDir dir(src); + + const auto dirList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + for (const auto &d : dirList) { + QString dst_path = dst + QLatin1Char('/') + d; + dir.mkpath(dst_path); + copyPath(src + QLatin1Char('/') + d, dst_path); + } + + const auto entryList = dir.entryList(QDir::Files); + for (const auto &f : entryList) { + QFile::copy(src + QLatin1Char('/') + f, dst + QLatin1Char('/') + f); + } +} + +static void installPlasmaTheme(const QString &theme = QStringLiteral("breeze")) +{ + QString destinationTheme = (theme == QLatin1String("breeze") ? QStringLiteral("default") : theme); + + QStandardPaths::setTestModeEnabled(true); + const auto qttestPath = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation).constFirst(); + Q_ASSERT(!qttestPath.isEmpty()); + QDir themePath(qttestPath + QLatin1String("/plasma/desktoptheme/") + destinationTheme); + + auto data = QFINDTESTDATA("../src/desktoptheme/" + theme + "/metadata.json"); + QFileInfo f(data); + QVERIFY(f.dir().mkpath(themePath.path())); + + copyPath(f.dir().filePath("default.gzipped"), themePath.path()); + QFile::copy(f.dir().filePath("metadata.json"), themePath.filePath("metadata.json")); + + const QString colorsFile = QFINDTESTDATA("../src/desktoptheme/" + theme + "/colors"); + if (!colorsFile.isEmpty()) { + QFile::copy(colorsFile, themePath.filePath("colors")); + } +} + +} // TestUtils +} // Plasma + +#endif diff --git a/docs/Doxyfile.local b/docs/Doxyfile.local new file mode 100644 index 0000000..f218edc --- /dev/null +++ b/docs/Doxyfile.local @@ -0,0 +1,9 @@ +### KApiDox Project-specific Overrides File + +# define so that deprecated API is not skipped +PREDEFINED += \ + "PLASMA_ENABLE_DEPRECATED_SINCE(x, y)=1" \ + "PLASMA_BUILD_DEPRECATED_SINCE(x, y)=1" \ + "PLASMA_DEPRECATED_VERSION(x, y, t)=" + +EXCLUDE_SYMBOLS = ToolTipDialog diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..6f6b1f8 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,12 @@ +find_package(KF6Parts ${KF_DEP_VERSION} REQUIRED) +set_package_properties(KF6Parts PROPERTIES PURPOSE "Required for examples") + +find_package(KF6WidgetsAddons ${KF_DEP_VERSION} REQUIRED) +set_package_properties(KF6WidgetsAddons PROPERTIES PURPOSE "Required for examples") + +add_subdirectory(applets) +add_subdirectory(containments) +add_subdirectory(wallpapers) +add_subdirectory(testcontainmentactionsplugin) +add_subdirectory(developerguide) +add_subdirectory(shell) diff --git a/examples/applets/CMakeLists.txt b/examples/applets/CMakeLists.txt new file mode 100644 index 0000000..6536e22 --- /dev/null +++ b/examples/applets/CMakeLists.txt @@ -0,0 +1,9 @@ + +plasma_install_package(bugreport org.kde.example.bugreport) +plasma_install_package(compactrepresentation org.kde.example.compactrepresentation) +plasma_install_package(config org.kde.example.configuration) +plasma_install_package(helloworld org.kde.example.helloworld) +plasma_install_package(notes org.kde.example.notes) +plasma_install_package(testcomponents org.kde.example.testcomponents) +plasma_install_package(testshaders org.kde.example.testshaders) +plasma_install_package(widgetgallery org.kde.example.widgetgallery) diff --git a/examples/applets/bugreport/contents/ui/main.qml b/examples/applets/bugreport/contents/ui/main.qml new file mode 100644 index 0000000..4ab0bda --- /dev/null +++ b/examples/applets/bugreport/contents/ui/main.qml @@ -0,0 +1,86 @@ +/* + SPDX-FileCopyrightText: 2014 Sebastian Kügler + SPDX-FileCopyrightText: 2023 ivan tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts + +import org.kde.plasma.plasmoid +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +PlasmoidItem { + id: root + + switchWidth: Kirigami.Units.gridUnit * 10 + switchHeight: Kirigami.Units.gridUnit * 5 + + Plasmoid.icon: "tools-report-bug" + + fullRepresentation: PlasmaComponents.ScrollView { + Layout.minimumWidth: Kirigami.Units.gridUnit * 10 + Layout.preferredWidth: Kirigami.Units.gridUnit * 20 + + PlasmaComponents.ScrollBar.horizontal.policy: PlasmaComponents.ScrollBar.AlwaysOff + + contentWidth: availableWidth + contentHeight: Math.ceil(col.implicitHeight + col.anchors.margins * 2) + + Item { + width: parent.width + + Kirigami.Icon { + id: icon + + anchors { + top: col.top + right: col.right + } + width: Kirigami.Units.iconSizes.large + height: Kirigami.Units.iconSizes.large + source: root.Plasmoid.icon + } + + ColumnLayout { + id: col + + anchors { + fill: parent + margins: Kirigami.Units.gridUnit + } + spacing: Kirigami.Units.largeSpacing + + Kirigami.Heading { + level: 1 + text: i18n("Reporting Bugs") + wrapMode: Text.Wrap + Layout.fillWidth: true + Layout.rightMargin: icon.width + } + Kirigami.Heading { + level: 3 + text: i18n("So you found something wrong in Plasma…") + wrapMode: Text.Wrap + Layout.fillWidth: true + Layout.rightMargin: icon.width + } + PlasmaComponents.Label { + Layout.fillWidth: true + wrapMode: Text.Wrap + textFormat: Text.StyledText + text: i18n("You are running a development version of Plasma. This software is not fit for production use. We do, however encourage testing and reporting the results. A few easy steps to report a bug:
\ + \ +
If you would like to participate in development, or have a question, you can ask them on the plasma-devel@kde.org mailing list.\ + ") + } + } + } + } +} diff --git a/examples/applets/bugreport/metadata.json b/examples/applets/bugreport/metadata.json new file mode 100644 index 0000000..cd2c70f --- /dev/null +++ b/examples/applets/bugreport/metadata.json @@ -0,0 +1,184 @@ +{ + "KPackageStructure": "Plasma/Applet", + "KPlugin": { + "Authors": [ + { + "Email": "sebas@kde.org", + "Name": "Sebastian Kügler", + "Name[ar]": "Sebastian Kügler", + "Name[az]": "Sebastian Kügler", + "Name[be]": "Sebastian Kügler", + "Name[bg]": "Sebastian Kügler", + "Name[ca@valencia]": "Sebastian Kügler", + "Name[ca]": "Sebastian Kügler", + "Name[cs]": "Sebastian Kügler", + "Name[de]": "Sebastian Kügler", + "Name[en_GB]": "Sebastian Kügler", + "Name[eo]": "Sebastian Kügler", + "Name[es]": "Sebastian Kügler", + "Name[eu]": "Sebastian Kügler", + "Name[fi]": "Sebastian Kügler", + "Name[fr]": "Sebastian Kügler", + "Name[gl]": "Sebastian Kügler", + "Name[he]": "סבסטיאן קיגלר", + "Name[hu]": "Sebastian Kügler", + "Name[ia]": "Sebastian Kügler", + "Name[id]": "Sebastian Kügler", + "Name[it]": "Sebastian Kügler", + "Name[ka]": "Sebastian Kügler", + "Name[ko]": "Sebastian Kügler", + "Name[lv]": "Sebastian Kügler", + "Name[nl]": "Sebastian Kügler", + "Name[nn]": "Sebastian Kügler", + "Name[pl]": "Sebastian Kügler", + "Name[pt]": "Sebastian Kügler", + "Name[pt_BR]": "Sebastian Kügler", + "Name[ro]": "Sebastian Kügler", + "Name[ru]": "Sebastian Kügler", + "Name[sa]": "सेबास्टियन कुग्लर", + "Name[sk]": "Sebastian Kügler", + "Name[sl]": "Sebastian Kügler", + "Name[sv]": "Sebastian Kügler", + "Name[ta]": "ஸெபாஸ்டியன் கூக்லர்", + "Name[tr]": "Sebastian Kügler", + "Name[uk]": "Sebastian Kügler", + "Name[vi]": "Sebastian Kügler", + "Name[x-test]": "xxSebastian Küglerxx", + "Name[zh_CN]": "Sebastian Kügler", + "Name[zh_TW]": "Sebastian Kügler" + } + ], + "Category": "Development", + "Description": "Report a bug in Plasma", + "Description[az]": "Plasmadakı xəta hesabatı", + "Description[be]": "Адправіць справаздачу пра хібу ў Plasma", + "Description[bg]": "Подаване на сигнал за грешка в Plasma", + "Description[ca@valencia]": "Informeu d'un error en Plasma", + "Description[ca]": "Informa d'un error en el Plasma", + "Description[cs]": "Nahlásit chybu v Plasma", + "Description[de]": "Einen Fehler in Plasma berichten", + "Description[en_GB]": "Report a bug in Plasma", + "Description[eo]": "Raporti cimon en Plasma", + "Description[es]": "Informar de un fallo en Plasma", + "Description[eu]": "Bidali Plasmako akats baten berri", + "Description[fi]": "Ilmoita ohjelmavirheestä Plasmassa", + "Description[fr]": "Signaler un bogue de Plasma", + "Description[gl]": "Informar dun fallo en Plasma.", + "Description[he]": "דיוח על תקלה בפלזמה", + "Description[hu]": "Plasma hiba bejelentése", + "Description[ia]": "Reporta un bug in Plasma", + "Description[id]": "Laporkan sebuah bug di Plasma", + "Description[it]": "Segnala un bug in Plasma", + "Description[ka]": "Plasma-ის შეცდომის ანგარიში", + "Description[ko]": "Plasma 버그 보고", + "Description[lv]": "Ziņot par „Plasma“ kļūdu", + "Description[nl]": "Een bug in Plasma rapporteren", + "Description[nn]": "Meld frå om feil i Plasma", + "Description[pl]": "Zgłoś błąd w Plazmie", + "Description[pt]": "Comunicar um erro no Plasma", + "Description[pt_BR]": "Relate um erro no Plasma", + "Description[ro]": "Raportează o problemă în Plasma", + "Description[ru]": "Отчёт об ошибке в Plasma", + "Description[sa]": "प्लाज्मायां दोषस्य सूचनां ददातु", + "Description[sk]": "Nahlásiť chybu v Plasma", + "Description[sl]": "Poročaj o hrošču v Plasmi", + "Description[sv]": "Rapportera ett fel i Plasma", + "Description[ta]": "பிளாஸ்மாவில் ஓர் பிழையை தெரிவி", + "Description[tr]": "Plasma'daki bir hatayı bildirin", + "Description[uk]": "Повідомити про ваду у Плазмі", + "Description[vi]": "Báo một lỗi trong Plasma", + "Description[x-test]": "xxReport a bug in Plasmaxx", + "Description[zh_CN]": "报告 Plasma 程序缺陷", + "Description[zh_TW]": "回報 Plasma 的問題", + "Icon": "kbugbuster", + "Id": "org.kde.example.bugreport", + "License": "GPL", + "Name": "Bug", + "Name[ar]": "علّة", + "Name[az]": "Xəta", + "Name[be]": "Хіба", + "Name[bg]": "Бъг", + "Name[ca@valencia]": "S'ha produït un error", + "Name[ca]": "Error", + "Name[cs]": "Chyba", + "Name[de]": "Fehler", + "Name[en_GB]": "Bug", + "Name[eo]": "Cimo", + "Name[es]": "Fallo", + "Name[eu]": "Akatsa", + "Name[fi]": "Ohjelmavirhe", + "Name[fr]": "Bogue", + "Name[gl]": "Fallo", + "Name[he]": "תקלה", + "Name[hu]": "Hiba", + "Name[ia]": "Bug", + "Name[id]": "Bug", + "Name[it]": "Bug", + "Name[ka]": "შეცდომა", + "Name[ko]": "버그", + "Name[lv]": "Kļūda", + "Name[nl]": "Bug", + "Name[nn]": "Feil", + "Name[pl]": "Błąd", + "Name[pt]": "Insecto", + "Name[pt_BR]": "Erro", + "Name[ro]": "Defect", + "Name[ru]": "Ошибка", + "Name[sa]": "दोष", + "Name[sk]": "Chyba", + "Name[sl]": "Hrošč", + "Name[sv]": "Fel", + "Name[ta]": "பிழை", + "Name[tr]": "Hata", + "Name[uk]": "Вада", + "Name[vi]": "Lỗi", + "Name[x-test]": "xxBugxx", + "Name[zh_CN]": "程序缺陷", + "Name[zh_TW]": "錯誤", + "Version": "", + "Website": "https://bugs.kde.org" + }, + "Keywords": "plasma;bugzilla;bug;development;support;", + "Keywords[az]": "plasma;bugzilla;bug;development;support;səhv;xəta;dəstək;tərtibat;", + "Keywords[ca@valencia]": "plasma;bugzilla;error;desenvolupament;suport;", + "Keywords[ca]": "plasma;bugzilla;error;desenvolupament;suport;", + "Keywords[da]": "plasma;bugzilla;bug;udvikling;støtte;", + "Keywords[de]": "plasma;bugzilla;Fehler;Entwicklung;Unterstützung;", + "Keywords[en_GB]": "plasma;bugzilla;bug;development;support;", + "Keywords[es]": "plasma;bugzilla;fallo;desarrollo;soporte;", + "Keywords[et]": "plasma;bugzilla;viga;arendus;toetus;veateade;vearaport;", + "Keywords[eu]": "plasma;bugzilla;akatsa;bug;garapena;euskarria;", + "Keywords[fi]": "plasma;bugzilla;bug;bugi;vika;virhe;development;kehitys;kehittäminen;support;tuki;", + "Keywords[fr]": "plasma;bugzilla;bug;développement;gestion;", + "Keywords[gd]": "plasma;bugzilla;bug;development;support;buga;leasachadh;taic;cobhair;", + "Keywords[gl]": "plasma;bugzilla;bug;erro;fallo;desenvolvemento;support;soporte;asistencia;asistencia técnica;axuda;", + "Keywords[hu]": "plasma;bugzilla;hiba;fejlesztés;támogatás;", + "Keywords[ia]": "plasma;bugzilla;bug;development;support;", + "Keywords[id]": "plasma;bugzilla;bug;development;support;", + "Keywords[it]": "plasma;bugzilla;bug;sviluppo;supporto;", + "Keywords[ko]": "plasma;bugzilla;bug;development;support;버그;개발;지원;", + "Keywords[lt]": "plasma;bugzilla;klaida;kūrimas;palaikymas;programavimas;strigtis;", + "Keywords[nb]": "plasma;bugzilla;feil;utvikling;støtte;", + "Keywords[nl]": "plasma;bugzilla;bug;ontwikkeling;ondersteuning;", + "Keywords[nn]": "plasma;bugzilla;feil;utvikling;støtte;", + "Keywords[pl]": "plazma;bugzilla;błąd;rozwój;programowanie;wsparcie;obsługa;", + "Keywords[pt]": "plasma;bugzilla;erro;desenvolvimento;suporte;", + "Keywords[pt_BR]": "plasma;bugzilla;erro;bug;desenvolvimento;suporte;", + "Keywords[ro]": "plasma;bugzilla;bug;development;suport;problemă;", + "Keywords[ru]": "plasma;bugzilla;bug;development;support;ошибка;сбой;поддержка;разработка;", + "Keywords[sk]": "plasma;bugzilla;chyba;vývoj;podpora;", + "Keywords[sl]": "plasma;bugzilla;hrošč;napaka;razvoj;podpora;", + "Keywords[sr@ijekavian]": "plasma;bugzilla;bug;development;support;Плазма;Бубаждаја;грешка;развој;подршка;", + "Keywords[sr@ijekavianlatin]": "plasma;bugzilla;bug;development;support;Plasma;Bubaždaja;greška;razvoj;podrška;", + "Keywords[sr@latin]": "plasma;bugzilla;bug;development;support;Plasma;Bubaždaja;greška;razvoj;podrška;", + "Keywords[sr]": "plasma;bugzilla;bug;development;support;Плазма;Бубаждаја;грешка;развој;подршка;", + "Keywords[sv]": "plasma;bugzilla;fel;utveckling;support;", + "Keywords[ta]": "plasma;bugzilla;bug;development;support;பிளாஸ்மா;பிழை;தவறு;சிக்கல்;ஆதரவு;பிழையறிக்கை;", + "Keywords[tg]": "plasma;bugzilla;хато;барномарезӣ;дастгирӣ;", + "Keywords[tr]": "plazma;bugzilla;hata;geliştirme;destek;plasma;", + "Keywords[uk]": "plasma;bugzilla;bug;development;support;плазма;багзілла;вада;баг;розробка;підтримка;супровід;помилка;", + "Keywords[vi]": "plasma;bugzilla;bug;development;support;lỗi;phát triển;hỗ trợ;", + "Keywords[x-test]": "xxplasmaxx;xxbugzillaxx;xxbugxx;xxdevelopmentxx;xxsupportxx;", + "Keywords[zh_CN]": "plasma;bugzilla;bug;development;support;错误;;程序缺陷;开发;支持;", + "Keywords[zh_TW]": "plasma;bugzilla;bug;development;support;" +} diff --git a/examples/applets/compactrepresentation/contents/ui/main.qml b/examples/applets/compactrepresentation/contents/ui/main.qml new file mode 100644 index 0000000..6812c9c --- /dev/null +++ b/examples/applets/compactrepresentation/contents/ui/main.qml @@ -0,0 +1,65 @@ +/* + SPDX-FileCopyrightText: 2012 Marco Martin + SPDX-FileCopyrightText: 2023 ivan tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import org.kde.kirigami as Kirigami +import org.kde.plasma.components as PlasmaComponents +import org.kde.plasma.extras as PlasmaExtras +import org.kde.plasma.plasmoid + +PlasmoidItem { + id: root + + Plasmoid.title: "Representations Example" + + switchWidth: Kirigami.Units.gridUnit * 10 + switchHeight: Kirigami.Units.gridUnit * 10 + + compactRepresentation: MouseArea { + property bool wasExpanded + + Accessible.name: Plasmoid.title + Accessible.role: Accessible.Button + + Layout.minimumWidth: Kirigami.Units.gridUnit * 3 + Layout.minimumHeight: Kirigami.Units.gridUnit * 3 + + onPressed: wasExpanded = root.expanded + onClicked: root.expanded = !wasExpanded + + PlasmaComponents.Label { + anchors.fill: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Text.Wrap + text: i18n("Click me") + } + } + + fullRepresentation: PlasmaExtras.Representation { + Layout.preferredWidth: Kirigami.Units.gridUnit * 20 + Layout.preferredHeight: Kirigami.Units.gridUnit * 20 + + Layout.minimumWidth: root.switchWidth + Layout.minimumHeight: root.switchHeight + + header: PlasmaExtras.BasicPlasmoidHeading {} + contentItem: PlasmaComponents.ScrollView { + contentWidth: availableWidth + PlasmaExtras.Heading { + anchors.fill: parent + topPadding: Kirigami.Units.gridUnit * 2 + bottomPadding: Kirigami.Units.gridUnit * 2 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Text.Wrap + text: i18n("Hello world") + } + } + } +} diff --git a/examples/applets/compactrepresentation/metadata.json b/examples/applets/compactrepresentation/metadata.json new file mode 100644 index 0000000..af44066 --- /dev/null +++ b/examples/applets/compactrepresentation/metadata.json @@ -0,0 +1,132 @@ +{ + "KPackageStructure": "Plasma/Applet", + "KPlugin": { + "Authors": [ + { + "Email": "mart@kde.org", + "Name": "Marco Martin", + "Name[ar]": "ماركو مارتن", + "Name[ast]": "Marco Martin", + "Name[az]": "Marco Martin", + "Name[be]": "Marco Martin", + "Name[bg]": "Marco Martin", + "Name[ca@valencia]": "Marco Martin", + "Name[ca]": "Marco Martin", + "Name[cs]": "Marco Martin", + "Name[de]": "Marco Martin", + "Name[en_GB]": "Marco Martin", + "Name[eo]": "Marco Martin", + "Name[es]": "Marco Martin", + "Name[eu]": "Marco Martin", + "Name[fi]": "Marco Martin", + "Name[fr]": "Marco Martin", + "Name[gl]": "Marco Martin", + "Name[he]": "מרקו מרטין", + "Name[hu]": "Marco Martin", + "Name[ia]": "Marco Martin", + "Name[id]": "Marco Martin", + "Name[it]": "Marco Martin", + "Name[ka]": "Marco Martin", + "Name[ko]": "Marco Martin", + "Name[lv]": "Marco Martin", + "Name[nl]": "Marco Martin", + "Name[nn]": "Marco Martin", + "Name[pl]": "Marco Martin", + "Name[pt]": "Marco Martin", + "Name[pt_BR]": "Marco Martin", + "Name[ro]": "Marco Martin", + "Name[ru]": "Marco Martin", + "Name[sa]": "मार्को मार्टिन्", + "Name[sk]": "Marco Martin", + "Name[sl]": "Marco Martin", + "Name[sv]": "Marco Martin", + "Name[ta]": "மார்க்கோ மார்ட்டின்", + "Name[tr]": "Marco Martin", + "Name[uk]": "Marco Martin", + "Name[vi]": "Marco Martin", + "Name[x-test]": "xxMarco Martinxx", + "Name[zh_CN]": "Marco Martin", + "Name[zh_TW]": "Marco Martin" + } + ], + "Category": "Miscellaneous", + "Description": "Example applet with compact and full representations", + "Description[bg]": "Примерна приставка с компактно и пълно представяне", + "Description[ca@valencia]": "Miniaplicació d'exemple amb representació compacta i completa", + "Description[ca]": "Miniaplicació d'exemple amb representació compacta i completa", + "Description[eo]": "Ekzempla apleto kun kompakta kaj plena reprezentoj", + "Description[es]": "Miniaplicación de ejemplo con representaciones compacta y completa", + "Description[eu]": "Irudikapen trinko eta osoak dituen aplikaziotxo baten adibidea", + "Description[fi]": "Esimerkkisovelma tiiviillä ja täydellä esitystavalla", + "Description[fr]": "Un exemple d'applet avec des représentations synthétique et complète", + "Description[gl]": "Trebello de exemplo con representacións compacta e completa.", + "Description[he]": "יישומון לדוגמה עם ייצוג מצומצם ומלא", + "Description[hu]": "Példa kisalkalmazás kompakt és teljes ábrázolással", + "Description[ia]": "Applet de exemplo con representationes compacte e plene", + "Description[it]": "Applet di esempio con rappresentazioni compatta e completa", + "Description[ka]": "სამაგალითო აპლეტი კომპაქტური და სრული რეპრეზენტაციით", + "Description[ko]": "소형과 대형 표시가 있는 예제 애플릿", + "Description[lv]": "Parauga programma ar kompaktām un pilnām reprezentācijām", + "Description[nl]": "Voorbeeld applet met compacte en volledige representaties", + "Description[pl]": "Przykładowy aplet w zwartej i pełnej odmianie", + "Description[pt_BR]": "Exemplo de applet com representações compactas e completas", + "Description[ru]": "Пример виджета с компактным и полным представлениями", + "Description[sa]": "संकुचितं पूर्णं च प्रतिनिधित्वं कृत्वा उदाहरणं एप्लेट् (applet)", + "Description[sl]": "Primer apleta s kompaktno in polno predstavitvijo", + "Description[tr]": "Kompakt ve tam temsilli örnek uygulamacık", + "Description[uk]": "Приклад аплету із щільним та повним представленням", + "Description[vi]": "Tiểu ứng dụng ví dụ với dạng hiển thị gọn và đầy đủ", + "Description[x-test]": "xxExample applet with compact and full representationsxx", + "Description[zh_CN]": "简洁但功能完整的示例小程序", + "Description[zh_TW]": "有簡潔和完整模式的範例小程式", + "Icon": "package_toys", + "Id": "org.kde.example.compactrepresentation", + "License": "GPL", + "Name": "hello world", + "Name[ar]": "مرحبا أيها العالم", + "Name[az]": "salam dünya", + "Name[be]": "вітаю, свет", + "Name[bg]": "hello world", + "Name[ca@valencia]": "hola món", + "Name[ca]": "hola món", + "Name[cs]": "Hello World", + "Name[de]": "Hallo Welt", + "Name[en_GB]": "hello world", + "Name[eo]": "Saluton mondo", + "Name[es]": "hola mundo", + "Name[eu]": "kaixo mundua", + "Name[fi]": "hei maailma", + "Name[fr]": "Bonjour à tout le monde", + "Name[gl]": "Ola mundo", + "Name[he]": "שלום עולם", + "Name[hu]": "helló világ", + "Name[ia]": "Salute mundo", + "Name[id]": "hello world", + "Name[it]": "ciao mondo", + "Name[ka]": "გამარჯობა კინო", + "Name[ko]": "hello world", + "Name[lv]": "sveika, pasaule", + "Name[nl]": "hallo wereld", + "Name[nn]": "hei, verda", + "Name[pl]": "witaj świecie", + "Name[pt]": "olá mundo", + "Name[pt_BR]": "olá mundo", + "Name[ro]": "salut lume", + "Name[ru]": "привет мир", + "Name[sa]": "नमस्कार विश्व", + "Name[sk]": "ahoj svet", + "Name[sl]": "pozdravljen svet", + "Name[sv]": "hello world", + "Name[ta]": "வணக்கம், உலகமே", + "Name[tr]": "merhaba dünya", + "Name[uk]": "Привіт, світе", + "Name[vi]": "chào thế giới", + "Name[x-test]": "xxhello worldxx", + "Name[zh_CN]": "hello world", + "Name[zh_TW]": "hello world", + "Version": "", + "Website": "https://www.kde.org/" + }, + "Keywords": "", + "X-KDE-ParentApp": "" +} diff --git a/examples/applets/config/contents/config/config.qml b/examples/applets/config/contents/config/config.qml new file mode 100644 index 0000000..792cf19 --- /dev/null +++ b/examples/applets/config/contents/config/config.qml @@ -0,0 +1,22 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + SPDX-FileCopyrightText: 2023 ivan tkachenko + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.configuration + +ConfigModel { + ConfigCategory { + name: "General" + icon: "plasma" + source: "configGeneral.qml" + } + ConfigCategory { + name: "Other page" + icon: "konqueror" + source: "configOther.qml" + } +} diff --git a/examples/applets/config/contents/config/main.xml b/examples/applets/config/contents/config/main.xml new file mode 100644 index 0000000..628cadb --- /dev/null +++ b/examples/applets/config/contents/config/main.xml @@ -0,0 +1,42 @@ + + + + + + + true + + + + test + + + 1 + -1 + 100 + + + + + + + test2 + + + Value2 + + + + + + + + + + + + + diff --git a/examples/applets/config/contents/ui/configGeneral.qml b/examples/applets/config/contents/ui/configGeneral.qml new file mode 100644 index 0000000..c9f9541 --- /dev/null +++ b/examples/applets/config/contents/ui/configGeneral.qml @@ -0,0 +1,39 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + SPDX-FileCopyrightText: 2023 ivan tkachenko + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Controls as QQC2 +import org.kde.kirigami as Kirigami + +QQC2.Pane { + id: root + + property alias cfg_BoolTest: testBoolConfigField.checked + property alias cfg_Test: testConfigField.text + property alias cfg_IntTest: intTestConfigField.value + + Kirigami.FormLayout { + anchors.fill: parent + + QQC2.CheckBox { + id: testBoolConfigField + text: i18nc("@label example config", "Bool from config") + Kirigami.FormData.label: i18nc("@label example config", "Bool Config value:") + } + QQC2.TextField { + id: testConfigField + placeholderText: i18nc("@label example config", "String test") + Kirigami.FormData.label: i18nc("@label example config", "Text Config value:") + } + QQC2.SpinBox { + id: intTestConfigField + Kirigami.FormData.label: i18nc("@label example config", "Integer:") + from: -1 + to: 100 + } + } +} diff --git a/examples/applets/config/contents/ui/configOther.qml b/examples/applets/config/contents/ui/configOther.qml new file mode 100644 index 0000000..c469fba --- /dev/null +++ b/examples/applets/config/contents/ui/configOther.qml @@ -0,0 +1,12 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Controls as QQC2 + +Item { + // TODO: How to fetch properties from another config group? +} diff --git a/examples/applets/config/contents/ui/main.qml b/examples/applets/config/contents/ui/main.qml new file mode 100644 index 0000000..0014724 --- /dev/null +++ b/examples/applets/config/contents/ui/main.qml @@ -0,0 +1,100 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + SPDX-FileCopyrightText: 2023 ivan tkachenko + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts + +import org.kde.plasma.plasmoid +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +PlasmoidItem { + id: root + + fullRepresentation: ColumnLayout { + id: column + spacing: Kirigami.Units.smallSpacing + + Layout.minimumWidth: Kirigami.Units.gridUnit * 10 + Layout.minimumHeight: implicitHeight + + Item { + Layout.fillHeight: true + } + PlasmaComponents.CheckBox { + Layout.fillWidth: true + Layout.bottomMargin: Kirigami.Units.largeSpacing + enabled: true + checked: Plasmoid.configuration.BoolTest + text: i18n("Bool from config") + onToggled: { + Plasmoid.configuration.BoolTest = checked; + } + } + PlasmaComponents.Label { + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.Wrap + text: i18n("String test") + } + PlasmaComponents.TextField { + Layout.fillWidth: true + Layout.bottomMargin: Kirigami.Units.largeSpacing + text: Plasmoid.configuration.Test + onTextEdited: { + Plasmoid.configuration.Test = text; + } + } + PlasmaComponents.Label { + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.Wrap + text: i18n("String from another group") + } + PlasmaComponents.TextField { + Layout.fillWidth: true + Layout.bottomMargin: Kirigami.Units.largeSpacing + text: Plasmoid.configuration.OtherTest + onTextEdited: { + Plasmoid.configuration.OtherTest = text; + } + } + PlasmaComponents.Label { + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.Wrap + text: i18n("Enum\ndisplayed as int,\nwritten as string") + } + PlasmaComponents.TextField { + Layout.fillWidth: true + Layout.bottomMargin: Kirigami.Units.largeSpacing + text: Plasmoid.configuration.EnumTest + onTextEdited: { + Plasmoid.configuration.EnumTest = text; + } + } + PlasmaComponents.Label { + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.Wrap + text: i18n("Integer\nminimum: -1\nmaximum: 100") + } + PlasmaComponents.SpinBox { + Layout.fillWidth: true + Layout.bottomMargin: Kirigami.Units.largeSpacing + from: -1 + to: 100 + value: Plasmoid.configuration.IntTest + onValueModified: { + Plasmoid.configuration.IntTest = value; + } + } + Item { + Layout.fillHeight: true + } + } +} diff --git a/examples/applets/config/metadata.json b/examples/applets/config/metadata.json new file mode 100644 index 0000000..a3997e8 --- /dev/null +++ b/examples/applets/config/metadata.json @@ -0,0 +1,129 @@ +{ + "KPackageStructure": "Plasma/Applet", + "KPlugin": { + "Authors": [ + { + "Email": "mart@kde.org", + "Name": "Marco Martin", + "Name[ar]": "ماركو مارتن", + "Name[ast]": "Marco Martin", + "Name[az]": "Marco Martin", + "Name[be]": "Marco Martin", + "Name[bg]": "Marco Martin", + "Name[ca@valencia]": "Marco Martin", + "Name[ca]": "Marco Martin", + "Name[cs]": "Marco Martin", + "Name[de]": "Marco Martin", + "Name[en_GB]": "Marco Martin", + "Name[eo]": "Marco Martin", + "Name[es]": "Marco Martin", + "Name[eu]": "Marco Martin", + "Name[fi]": "Marco Martin", + "Name[fr]": "Marco Martin", + "Name[gl]": "Marco Martin", + "Name[he]": "מרקו מרטין", + "Name[hu]": "Marco Martin", + "Name[ia]": "Marco Martin", + "Name[id]": "Marco Martin", + "Name[it]": "Marco Martin", + "Name[ka]": "Marco Martin", + "Name[ko]": "Marco Martin", + "Name[lv]": "Marco Martin", + "Name[nl]": "Marco Martin", + "Name[nn]": "Marco Martin", + "Name[pl]": "Marco Martin", + "Name[pt]": "Marco Martin", + "Name[pt_BR]": "Marco Martin", + "Name[ro]": "Marco Martin", + "Name[ru]": "Marco Martin", + "Name[sa]": "मार्को मार्टिन्", + "Name[sk]": "Marco Martin", + "Name[sl]": "Marco Martin", + "Name[sv]": "Marco Martin", + "Name[ta]": "மார்க்கோ மார்ட்டின்", + "Name[tr]": "Marco Martin", + "Name[uk]": "Marco Martin", + "Name[vi]": "Marco Martin", + "Name[x-test]": "xxMarco Martinxx", + "Name[zh_CN]": "Marco Martin", + "Name[zh_TW]": "Marco Martin" + } + ], + "Category": "", + "Description": "Example applet with config", + "Description[bg]": "Примерна приставка с конфигурация", + "Description[ca@valencia]": "Miniaplicació d'exemple amb configuració", + "Description[ca]": "Miniaplicació d'exemple amb configuració", + "Description[eo]": "Ekzempla apleto kun agordo", + "Description[es]": "Miniaplicación de ejemplo con configuración", + "Description[eu]": "Aplikaziotxo baten adibidea konfigurazioarekin", + "Description[fi]": "Esimerkkisovelma asetuksin", + "Description[fr]": "Un exemple d'applet avec une configuration", + "Description[gl]": "Trebello de exemplo con configuración.", + "Description[he]": "יישומון לדוגמה עם הגדרות", + "Description[hu]": "Példa kisalkalmazás beállítással", + "Description[ia]": "Applet de exemplo con configuration", + "Description[it]": "Applet di esempio con configurazione", + "Description[ka]": "სამაგალითო აპლეტი კონფიგურაციით", + "Description[ko]": "설정 가능한 예제 애플릿", + "Description[lv]": "Parauga programma ar konfigurāciju", + "Description[nl]": "Voorbeeld applet met configuratie", + "Description[pl]": "Przykładowy aplet z ustawieniami", + "Description[pt_BR]": "Exemplo de applet com configuração", + "Description[ru]": "Пример виджета с настройкой", + "Description[sa]": "विन्याससहितं उदाहरणम् एप्लेट् (applet)", + "Description[sl]": "Primer apleta", + "Description[tr]": "Yapılandırmalı örnek uygulamacık", + "Description[uk]": "Приклад аплету із налаштуваннями", + "Description[vi]": "Tiểu ứng dụng ví dụ với cấu hình", + "Description[x-test]": "xxExample applet with configxx", + "Description[zh_CN]": "带有配置的示例小程序", + "Description[zh_TW]": "有設定的範例小程式", + "Id": "org.kde.example.configuration", + "License": "GPLv2+", + "Name": "Configuration test", + "Name[az]": "Tənzimləmə testi", + "Name[be]": "Тэставанне канфігурацыі", + "Name[bg]": "Тест на настройките", + "Name[ca@valencia]": "Prova de configuració", + "Name[ca]": "Prova de configuració", + "Name[cs]": "Test nastavení", + "Name[en_GB]": "Configuration test", + "Name[eo]": "Testo de agordo", + "Name[es]": "Prueba de configuración", + "Name[eu]": "Konfigurazio-proba", + "Name[fi]": "Asetustesti", + "Name[fr]": "Test de configuration", + "Name[gl]": "Proba de configuración", + "Name[he]": "בדיקת הגדרות", + "Name[hu]": "Konfigurációteszt", + "Name[ia]": "Prova de configuration", + "Name[id]": "Pengujian konfigurasi", + "Name[it]": "Prova di configurazione", + "Name[ka]": "კონფიგურაციის ტესტი", + "Name[ko]": "설정 테스트", + "Name[lv]": "Konfigurācijas tests", + "Name[nl]": "Test van instellingen", + "Name[nn]": "Oppsett-test", + "Name[pl]": "Próba ustawień", + "Name[pt]": "Teste de configuração", + "Name[pt_BR]": "Teste de configuração", + "Name[ro]": "Test configurări", + "Name[ru]": "Тест конфигурации", + "Name[sa]": "विन्यास परीक्षणम्", + "Name[sk]": "Test nastavenia", + "Name[sl]": "Preizkus konfiguracije", + "Name[sv]": "Inställningstest", + "Name[ta]": "அமைப்புகள் சோதனை", + "Name[tr]": "Yapılandırma Sınaması", + "Name[uk]": "Перевірка налаштувань", + "Name[vi]": "Kiểm thử cấu hình", + "Name[x-test]": "xxConfiguration testxx", + "Name[zh_CN]": "配置测试", + "Name[zh_TW]": "設定測試", + "Version": "", + "Website": "https://www.kde.org/" + }, + "Keywords": "", + "X-KDE-ParentApp": "" +} diff --git a/examples/applets/helloworld/contents/ui/main.qml b/examples/applets/helloworld/contents/ui/main.qml new file mode 100644 index 0000000..1a1dd45 --- /dev/null +++ b/examples/applets/helloworld/contents/ui/main.qml @@ -0,0 +1,25 @@ +/* + SPDX-FileCopyrightText: 2012 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import org.kde.kirigami as Kirigami +import org.kde.plasma.plasmoid +import org.kde.plasma.components as PlasmaComponents + +PlasmoidItem { + Layout.minimumWidth: Kirigami.Units.gridUnit * 5 + Layout.minimumHeight: Kirigami.Units.gridUnit * 5 + + implicitHeight: Kirigami.Units.gridUnit * 10 + implicitWidth: Kirigami.Units.gridUnit * 10 + + PlasmaComponents.Label { + anchors.fill: parent + wrapMode: Text.Wrap + text: i18n("Hello world") + } +} diff --git a/examples/applets/helloworld/metadata.json b/examples/applets/helloworld/metadata.json new file mode 100644 index 0000000..661fd73 --- /dev/null +++ b/examples/applets/helloworld/metadata.json @@ -0,0 +1,132 @@ +{ + "KPackageStructure": "Plasma/Applet", + "KPlugin": { + "Authors": [ + { + "Email": "mart@kde.org", + "Name": "Marco Martin", + "Name[ar]": "ماركو مارتن", + "Name[ast]": "Marco Martin", + "Name[az]": "Marco Martin", + "Name[be]": "Marco Martin", + "Name[bg]": "Marco Martin", + "Name[ca@valencia]": "Marco Martin", + "Name[ca]": "Marco Martin", + "Name[cs]": "Marco Martin", + "Name[de]": "Marco Martin", + "Name[en_GB]": "Marco Martin", + "Name[eo]": "Marco Martin", + "Name[es]": "Marco Martin", + "Name[eu]": "Marco Martin", + "Name[fi]": "Marco Martin", + "Name[fr]": "Marco Martin", + "Name[gl]": "Marco Martin", + "Name[he]": "מרקו מרטין", + "Name[hu]": "Marco Martin", + "Name[ia]": "Marco Martin", + "Name[id]": "Marco Martin", + "Name[it]": "Marco Martin", + "Name[ka]": "Marco Martin", + "Name[ko]": "Marco Martin", + "Name[lv]": "Marco Martin", + "Name[nl]": "Marco Martin", + "Name[nn]": "Marco Martin", + "Name[pl]": "Marco Martin", + "Name[pt]": "Marco Martin", + "Name[pt_BR]": "Marco Martin", + "Name[ro]": "Marco Martin", + "Name[ru]": "Marco Martin", + "Name[sa]": "मार्को मार्टिन्", + "Name[sk]": "Marco Martin", + "Name[sl]": "Marco Martin", + "Name[sv]": "Marco Martin", + "Name[ta]": "மார்க்கோ மார்ட்டின்", + "Name[tr]": "Marco Martin", + "Name[uk]": "Marco Martin", + "Name[vi]": "Marco Martin", + "Name[x-test]": "xxMarco Martinxx", + "Name[zh_CN]": "Marco Martin", + "Name[zh_TW]": "Marco Martin" + } + ], + "Category": "Miscellaneous", + "Description": "Hello World", + "Description[bg]": "Hello World", + "Description[ca@valencia]": "Hola món", + "Description[ca]": "Hola món", + "Description[cs]": "Hello World", + "Description[de]": "Hallo Welt", + "Description[eo]": "Saluton Mondo", + "Description[es]": "Hola, mundo", + "Description[eu]": "kaixo mundua", + "Description[fi]": "Hei maailma", + "Description[fr]": "Bonjour à tout le monde", + "Description[gl]": "Ola, mundo!", + "Description[he]": "שלום עולם", + "Description[hu]": "Helló világ", + "Description[ia]": "Salute mundo", + "Description[it]": "Ciao mondo", + "Description[ka]": "გამარჯობა კინო", + "Description[ko]": "Hello World", + "Description[lv]": "Sveika, pasaule", + "Description[nl]": "Hallo wereld", + "Description[pl]": "Witaj świecie", + "Description[pt_BR]": "Olá mundo", + "Description[ru]": "привет мир", + "Description[sa]": "नमस्कार विश्व", + "Description[sl]": "Pozdravljen svet", + "Description[tr]": "Merhaba Dünya", + "Description[uk]": "Привіт, світе", + "Description[vi]": "Chào Thế giới", + "Description[x-test]": "xxHello Worldxx", + "Description[zh_CN]": "Hello World", + "Description[zh_TW]": "Hello World", + "Icon": "package_toys", + "Id": "org.kde.example.helloworld", + "License": "GPL", + "Name": "hello world", + "Name[ar]": "مرحبا أيها العالم", + "Name[az]": "salam dünya", + "Name[be]": "вітаю, свет", + "Name[bg]": "hello world", + "Name[ca@valencia]": "hola món", + "Name[ca]": "hola món", + "Name[cs]": "Hello World", + "Name[de]": "Hallo Welt", + "Name[en_GB]": "hello world", + "Name[eo]": "Saluton mondo", + "Name[es]": "hola mundo", + "Name[eu]": "kaixo mundua", + "Name[fi]": "hei maailma", + "Name[fr]": "Bonjour à tout le monde", + "Name[gl]": "Ola mundo", + "Name[he]": "שלום עולם", + "Name[hu]": "helló világ", + "Name[ia]": "Salute mundo", + "Name[id]": "hello world", + "Name[it]": "ciao mondo", + "Name[ka]": "გამარჯობა კინო", + "Name[ko]": "hello world", + "Name[lv]": "sveika, pasaule", + "Name[nl]": "hallo wereld", + "Name[nn]": "hei, verda", + "Name[pl]": "witaj świecie", + "Name[pt]": "olá mundo", + "Name[pt_BR]": "olá mundo", + "Name[ro]": "salut lume", + "Name[ru]": "привет мир", + "Name[sa]": "नमस्कार विश्व", + "Name[sk]": "ahoj svet", + "Name[sl]": "pozdravljen svet", + "Name[sv]": "hello world", + "Name[ta]": "வணக்கம், உலகமே", + "Name[tr]": "merhaba dünya", + "Name[uk]": "Привіт, світе", + "Name[vi]": "chào thế giới", + "Name[x-test]": "xxhello worldxx", + "Name[zh_CN]": "hello world", + "Name[zh_TW]": "hello world", + "Version": "", + "Website": "https://www.kde.org/" + } +} diff --git a/examples/applets/notes/contents/config/main.xml b/examples/applets/notes/contents/config/main.xml new file mode 100644 index 0000000..dc3720a --- /dev/null +++ b/examples/applets/notes/contents/config/main.xml @@ -0,0 +1,15 @@ + + + + + + + + Hello! + + + + diff --git a/examples/applets/notes/contents/ui/main.qml b/examples/applets/notes/contents/ui/main.qml new file mode 100644 index 0000000..8740ecc --- /dev/null +++ b/examples/applets/notes/contents/ui/main.qml @@ -0,0 +1,60 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + SPDX-FileCopyrightText: 2023 ivan tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import org.kde.kirigami as Kirigami +import org.kde.ksvg as KSvg +import org.kde.plasma.core as PlasmaCore +import org.kde.plasma.plasmoid +import org.kde.plasma.components as PlasmaComponents + +PlasmoidItem { + // this isn't a frameSVG, the default SVG margins take up around 7% of the frame size, so we use that + readonly property real horizontalMargins: width * 0.07 + readonly property real verticalMargins: height * 0.07 + + Layout.minimumWidth: Kirigami.Units.gridUnit * 8 + Layout.minimumHeight: Kirigami.Units.gridUnit * 8 + + Plasmoid.backgroundHints: PlasmaCore.Types.NoBackground + + onExternalData: (mimetype, data) => { + if (mimetype === "text/plain") { + noteText.text = data; + } + } + + KSvg.SvgItem { + anchors.fill: parent + + imagePath: "widgets/notes" + elementId: "yellow-notes" + + PlasmaComponents.TextArea { + id: noteText + + anchors { + fill: parent + leftMargin: horizontalMargins + rightMargin: horizontalMargins + topMargin: verticalMargins + bottomMargin: verticalMargins + } + + background: null + color: Qt.alpha("black", 0.8) + font.pointSize: Math.round(Kirigami.Theme.defaultFont.pointSize * 1.3) + wrapMode: TextEdit.Wrap + + text: Plasmoid.configuration.Text + onEditingFinished: { + Plasmoid.configuration.Text = text; + } + } + } +} diff --git a/examples/applets/notes/metadata.json b/examples/applets/notes/metadata.json new file mode 100644 index 0000000..8c5165a --- /dev/null +++ b/examples/applets/notes/metadata.json @@ -0,0 +1,140 @@ +{ + "KPackageStructure": "Plasma/Applet", + "KPlugin": { + "Authors": [ + { + "Email": "mart@kde.org", + "Name": "Marco Martin", + "Name[ar]": "ماركو مارتن", + "Name[ast]": "Marco Martin", + "Name[az]": "Marco Martin", + "Name[be]": "Marco Martin", + "Name[bg]": "Marco Martin", + "Name[ca@valencia]": "Marco Martin", + "Name[ca]": "Marco Martin", + "Name[cs]": "Marco Martin", + "Name[de]": "Marco Martin", + "Name[en_GB]": "Marco Martin", + "Name[eo]": "Marco Martin", + "Name[es]": "Marco Martin", + "Name[eu]": "Marco Martin", + "Name[fi]": "Marco Martin", + "Name[fr]": "Marco Martin", + "Name[gl]": "Marco Martin", + "Name[he]": "מרקו מרטין", + "Name[hu]": "Marco Martin", + "Name[ia]": "Marco Martin", + "Name[id]": "Marco Martin", + "Name[it]": "Marco Martin", + "Name[ka]": "Marco Martin", + "Name[ko]": "Marco Martin", + "Name[lv]": "Marco Martin", + "Name[nl]": "Marco Martin", + "Name[nn]": "Marco Martin", + "Name[pl]": "Marco Martin", + "Name[pt]": "Marco Martin", + "Name[pt_BR]": "Marco Martin", + "Name[ro]": "Marco Martin", + "Name[ru]": "Marco Martin", + "Name[sa]": "मार्को मार्टिन्", + "Name[sk]": "Marco Martin", + "Name[sl]": "Marco Martin", + "Name[sv]": "Marco Martin", + "Name[ta]": "மார்க்கோ மார்ட்டின்", + "Name[tr]": "Marco Martin", + "Name[uk]": "Marco Martin", + "Name[vi]": "Marco Martin", + "Name[x-test]": "xxMarco Martinxx", + "Name[zh_CN]": "Marco Martin", + "Name[zh_TW]": "Marco Martin" + } + ], + "Category": "Miscellaneous", + "Description": "Example on how to manage Drop data", + "Description[az]": "Daşınan elementlərlə işləmə nümunəsi", + "Description[be]": "Прыклад таго, як кіраваць перацягваннем даных", + "Description[bg]": "Пример за управление на пуснати данни", + "Description[ca@valencia]": "Exemple de com gestionar dades «Drop»", + "Description[ca]": "Exemple de com gestionar dades «Drop»", + "Description[en_GB]": "Example on how to manage Drop data", + "Description[eo]": "Ekzemplo pri kiel administri Drop-datumojn", + "Description[es]": "Ejemplo sobre cómo manejar datos soltados", + "Description[eu]": "Adibidea jaregindako datuak kudeatzeko moduari buruz", + "Description[fi]": "Esimerkki pudotetun tiedon käsittelystä", + "Description[fr]": "Exemple sur comment gérer les données fournies", + "Description[gl]": "Exemplo de como xestionar os datos soltados.", + "Description[he]": "דוגמה לאיך לנהל נתונים שנגררו", + "Description[hu]": "Példa ejtett adatok kezelésére", + "Description[ia]": "Exemplo de como gerer Drop data (deponer datos)", + "Description[id]": "Example on how to manage Drop data", + "Description[it]": "Esempio su come gestire i dati Drop", + "Description[ka]": "მაგალითი, როგორ მართოთ შემოთრეული მონაცემები", + "Description[ko]": "드롭 데이터를 관리하는 방법 시연", + "Description[lv]": "Piemērs datu nomešanas pārvaldīšanai", + "Description[nl]": "Voorbeeld van hoe gegevens van Drop te beheren", + "Description[nn]": "Eksempel på korleis handtera «Drop»-data", + "Description[pl]": "Przykład postępowania z upuszczanymi danymi", + "Description[pt]": "Exemplo de gestão dos dados do Drop", + "Description[pt_BR]": "Exemplo de como gerenciar os dados do Drop", + "Description[ru]": "Пример обработки перетаскиваемых объектов", + "Description[sa]": "ह्रास दत्तांश कथं प्रबन्धयितव्यम् इति उदाहरणम्", + "Description[sk]": "Príklad, ako spravovať vypustenie dát", + "Description[sl]": "Primer kako obravnavati opustitev podatkov", + "Description[sv]": "Exempel på hur Släpp data hanteras", + "Description[tr]": "Bırakma verisinin nice yönetileceği üzerine örnek", + "Description[uk]": "Приклад керування скинутими даними", + "Description[vi]": "Ví dụ về cách quản lí dữ liệu thả", + "Description[x-test]": "xxExample on how to manage Drop dataxx", + "Description[zh_CN]": "展示如何管理拖放数据的示例程序", + "Description[zh_TW]": "管理拖放資料的範例", + "Icon": "org.kde.plasma.notes", + "Id": "org.kde.example.notes", + "License": "GPL", + "Name": "Example notes", + "Name[az]": "Nümunə qeydlər", + "Name[be]": "Прыклады нататак", + "Name[bg]": "Примерни бележки", + "Name[ca@valencia]": "Notes d'exemple", + "Name[ca]": "Notes d'exemple", + "Name[en_GB]": "Example notes", + "Name[eo]": "Ekzemplaj notoj", + "Name[es]": "Notas de ejemplo", + "Name[eu]": "Adibide-oharrak", + "Name[fi]": "Esimerkkimuistiinpanot", + "Name[fr]": "Exemple de notes", + "Name[gl]": "Notas de exemplo", + "Name[he]": "הערות לדוגמה", + "Name[hu]": "Példa jegyzetek", + "Name[ia]": "Notas de exemplo", + "Name[id]": "Contoh catatan", + "Name[it]": "Note di esempio", + "Name[ka]": "შენიშვნის მაგალითები", + "Name[ko]": "예제 노트", + "Name[lv]": "Piezīmes piemēram", + "Name[nl]": "Voorbeeldnotities", + "Name[nn]": "Eksempelnotat", + "Name[pl]": "Uwagi do przykładu", + "Name[pt]": "Notas de exemplo", + "Name[pt_BR]": "Notas de exemplo", + "Name[ro]": "Notițe ca exemplu", + "Name[ru]": "Пример заметок", + "Name[sa]": "उदाहरणानि टिप्पण्यानि", + "Name[sk]": "Ukážkové poznámky", + "Name[sl]": "Zabeležke primera", + "Name[sv]": "Exempelanteckningar", + "Name[ta]": "எடுத்துக்காட்டு குறிப்புகள்", + "Name[tr]": "Örnek notlar", + "Name[uk]": "Нотатки щодо прикладу", + "Name[vi]": "Ghi chú ví dụ", + "Name[x-test]": "xxExample notesxx", + "Name[zh_CN]": "示例便笺", + "Name[zh_TW]": "範例備註", + "Version": "", + "Website": "https://www.kde.org/" + }, + "Keywords": "", + "X-KDE-ParentApp": "", + "X-Plasma-DropMimeTypes": [ + "text/plain" + ] +} diff --git a/examples/applets/testcomponents/contents/images/bridge.jpg b/examples/applets/testcomponents/contents/images/bridge.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dd4bbcc8152623ca1a6a69be9e70f0b307845f57 GIT binary patch literal 17134 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 literal 0 HcmV?d00001 diff --git a/examples/applets/testcomponents/contents/images/surfboard.jpg b/examples/applets/testcomponents/contents/images/surfboard.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7a571aac1ebb44de3498f71ad756bb68ab78570f GIT binary patch literal 25713 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 + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import org.kde.plasma.components as PlasmaComponents +import org.kde.kquickcontrolsaddons as KQuickControlsAddons +import org.kde.kirigami as Kirigami + +// ButtonsPage + +PlasmaComponents.Page { + id: plasmoidPage + anchors { + fill: parent + margins: _s + } + Column { + spacing: _s/2 + anchors.fill: parent + Kirigami.Heading { + level: 1 + width: parent.width + text: "Buttons" + } + Row { + height: _h + spacing: _s + PlasmaComponents.Button { + text: "Button" + iconSource: "call-start" + } + PlasmaComponents.ToolButton { + text: "ToolButton" + iconSource: "call-stop" + } + } + Row { + height: _h + spacing: _s + PlasmaComponents.RadioButton { + id: radio + text: "RadioButton" + //iconSource: "call-stop" + onCheckedChanged: if (checked) tfield.forceActiveFocus() + } + PlasmaComponents.TextField { + id: tfield + enabled: radio.checked + text: "input here" + clearButtonShown: true + } + } +// PlasmaComponents.TextArea { +// width: parent.width +// height: _h*2 +// wrapMode: TextEdit.Wrap +// } + } +} + diff --git a/examples/applets/testcomponents/contents/ui/DialogContent.qml b/examples/applets/testcomponents/contents/ui/DialogContent.qml new file mode 100644 index 0000000..d5d8f8b --- /dev/null +++ b/examples/applets/testcomponents/contents/ui/DialogContent.qml @@ -0,0 +1,51 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Window + +import org.kde.plasma.components as PlasmaComponents +import org.kde.kquickcontrolsaddons as KQuickControlsAddons +import org.kde.kirigami as Kirigami + +// DialogContent + +Item { + id: dialogsPage + width: 300 + height: 200 + signal closeMe() + Rectangle { + color: "green" + //anchors.margins: 24 + opacity: 0 + anchors.fill: parent + } + Column { + anchors.fill: parent + spacing: 12 + Kirigami.Heading { + id: tx + level: 1 + text: "Test Dialog" + } + PlasmaComponents.TextArea { + anchors { left: parent.left; right: parent.right; top: localeItem.bottom; } + width: parent.width + height: 80 + wrapMode: TextEdit.Wrap + } + PlasmaComponents.Button { + id: thanks + anchors { horizontalCenter: parent.horizontalCenter; bottom: parent.bottom; bottomMargin: 24; } + iconSource: "dialog-ok" + text: "Thanks." + //onClicked: dialogsPage.parent.visible = false; + onClicked: closeMe() + } + } +} + diff --git a/examples/applets/testcomponents/contents/ui/DialogsPage.qml b/examples/applets/testcomponents/contents/ui/DialogsPage.qml new file mode 100644 index 0000000..5d13d93 --- /dev/null +++ b/examples/applets/testcomponents/contents/ui/DialogsPage.qml @@ -0,0 +1,235 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Window + +import org.kde.plasma.core as PlasmaCore +import org.kde.plasma.components as PlasmaComponents +import org.kde.kquickcontrolsaddons as KQuickControlsAddons +import org.kde.kirigami as Kirigami + +// DialogsPage + +PlasmaComponents.Page { + id: dialogsPage + anchors { + fill: parent + margins: _s + } + Column { + spacing: _s/2 + anchors.fill: parent + Kirigami.Heading { + width: parent.width + level: 1 + text: "Dialogs" + } + Row { + height: _h + spacing: _s + PlasmaComponents.Button { + id: radio + checkable: true + iconSource: "dialog-ok" + text: "Window" + } + Window { + title: radio.text + id: qWindow + visible: radio.checked + width: childrenRect.width + height: childrenRect.height + color: Qt.rgba(0,0,0,0) + DialogContent { + id: dContent + onCloseMe: { + qWindow.visible = false + } + } + } + + PlasmaComponents.Label { + text: qWindow.visible ? "shown" : "hidden" + } + } + Row { + height: _h + spacing: _s + PlasmaComponents.Button { + text: "Core.Dialog" + iconSource: "dialog-ok-apply" + checkable: true + //onCheckedChanged: pcDialog.visible = checked + onCheckedChanged: pcDialog.visible = checked + } + PlasmaComponents.Label { + text: pcDialog.visible ? "shown" : "hidden" + } + + PlasmaCore.Dialog { + id: pcDialog + //windowFlags: Qt.Popup + visualParent: dialogsPage + //mainItem: dContent2 + color: Qt.rgba(0,0,0,0) + + mainItem: DialogContent { + id: dContent2 + onCloseMe: pcDialog.visible = false + } + } + } + Row { + height: _h + spacing: _s + PlasmaComponents.Button { + text: "Dialog" + iconSource: "dialog-ok-apply" + checkable: true + onCheckedChanged: { + if (checked) { + pcompDialog.open(); + } else { + pcompDialog.close(); + } + } + } + PlasmaComponents.Label { + text: pcompDialog.visible ? "shown" : "hidden" + } + + PlasmaComponents.Dialog { + id: pcompDialog + //windowFlags: Qt.Popup + visualParent: root + content: DialogContent { + id: dContent3 + onCloseMe: pcompDialog.close() + } + buttons: PlasmaComponents.ButtonRow { + PlasmaComponents.Button { + text: "Close"; + onClicked: { + print("Closing..."); + pcompDialog.close() + } + } + PlasmaComponents.Button { + text: "Accept"; + onClicked: { + print("Accepting..."); + pcompDialog.accept(); + pcompDialog.close(); + } + } + } + } + } + Row { + height: _h + spacing: _s + PlasmaComponents.Button { + text: "QueryDialog" + iconSource: "dialog-ok-apply" + checkable: true + onCheckedChanged: { + if (checked) { + queryDialog.open(); + } else { + queryDialog.close(); + } + } + } + PlasmaComponents.Label { + text: queryDialog.visible ? "shown" : "hidden" + } + + PlasmaComponents.QueryDialog { + id: queryDialog + //windowFlags: Qt.Popup + visualParent: root + titleText: "Fruit Inquiry" + message: "Would you rather have apples or oranges?" + acceptButtonText: "Apples" + rejectButtonText: "Oranges" + onButtonClicked: { + print("hey"); + queryDialog.close(); + } + } + } + PlasmaComponents.ButtonRow { + id: buttonRow + spacing: _s/2 + PlasmaComponents.Button { + width: _h + text: "Top" + onClicked: { + locationDialog.location = PlasmaCore.Types.TopEdge; + locationDialog.visible = !locationDialog.visible + } + } + PlasmaComponents.Button { + text: "Bottom" + width: _h + onClicked: { + locationDialog.location = PlasmaCore.Types.BottomEdge; + locationDialog.visible = !locationDialog.visible + } + } + PlasmaComponents.Button { + text: "Left" + width: _h + onClicked: { + locationDialog.location = PlasmaCore.Types.LeftEdge; + locationDialog.visible = !locationDialog.visible + } + } + PlasmaComponents.Button { + text: "Right" + width: _h + onClicked: { + locationDialog.location = PlasmaCore.Types.RightEdge; + locationDialog.visible = !locationDialog.visible + } + } + PlasmaComponents.Button { + text: "Desktop" + width: _h + onClicked: { + locationDialog.location = PlasmaCore.Types.Desktop; + locationDialog.visible = !locationDialog.visible + } + } + PlasmaComponents.Button { + text: "Floating" + width: _h + onClicked: { + locationDialog.location = PlasmaCore.Types.Floating; + locationDialog.visible = !locationDialog.visible + } + } + PlasmaComponents.Button { + text: "FullScreen" + width: _h + onClicked: { + locationDialog.location = PlasmaCore.Types.FullScreen; + locationDialog.visible = !locationDialog.visible + } + } + } + PlasmaCore.Dialog { + id: locationDialog + visualParent: buttonRow + mainItem: DialogContent { + id: dContent4 + onCloseMe: locationDialog.visible = false + } + } + } +} + diff --git a/examples/applets/testcomponents/contents/ui/DragItem.qml b/examples/applets/testcomponents/contents/ui/DragItem.qml new file mode 100644 index 0000000..343d2eb --- /dev/null +++ b/examples/applets/testcomponents/contents/ui/DragItem.qml @@ -0,0 +1,46 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + SPDX-FileCopyrightText: 2023 ivan tkachenko + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import org.kde.kirigami as Kirigami +import org.kde.plasma.components as PlasmaComponents + +import org.kde.draganddrop as DragAndDrop + +PlasmaComponents.ItemDelegate { + id: control + + width: parent?.width ?? 0 + //height: _h * 1.5 + + Kirigami.Icon { + id: itemIcon + + width: _h + height: width + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: _h/2 + + source: control.icon.name + } + + PlasmaComponents.Label { + id: label + + anchors { + verticalCenter: parent.verticalCenter + left: itemIcon.right + leftMargin: _h/2 + right: parent.right + rightMargin: _h/2 + } + + text: control.text + } +} diff --git a/examples/applets/testcomponents/contents/ui/DragPage.qml b/examples/applets/testcomponents/contents/ui/DragPage.qml new file mode 100644 index 0000000..d327fcf --- /dev/null +++ b/examples/applets/testcomponents/contents/ui/DragPage.qml @@ -0,0 +1,244 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + SPDX-FileCopyrightText: 2023 ivan tkachenko + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami +import org.kde.draganddrop as DragAndDrop +import org.kde.plasma.components as PlasmaComponents +import org.kde.plasma.extras as PlasmaExtras +import org.kde.plasma.plasmoid + +PlasmaComponents.Page { + id: root + + property int _h: 48 + property bool isDragging: false + + padding: Kirigami.Units.largeSpacing + + contentItem: ColumnLayout { + + spacing: 0 + + Kirigami.Heading { + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideMiddle + + level: 1 + text: "Drag & Drop" + } + + RowLayout { + spacing: 0 + + Layout.fillWidth: true + Layout.fillHeight: true + + ColumnLayout { + id: dragCol + + property int itemHeight: _h*1.5 + + spacing: _h/4 + + Layout.fillWidth: true + Layout.fillHeight: true + Layout.preferredWidth: 1 + + DragItem { + text: "Image and URL" + icon.name: "image-png" + Layout.preferredHeight: parent.itemHeight + DragAndDrop.DragArea { + objectName: "imageandurl" + anchors { fill: parent; } + //delegateImage: "akonadi" + mimeData.url: "https://plasma.kde.org/" + onDragStarted: { + isDragging = true; + print(" drag started for " + objectName); + ooo.text = objectName + } + onDrop: { + isDragging = false; + print(" item dropped " + objectName); + ooo.text = objectName + } + //Rectangle { anchors.fill: parent; color: "blue"; opacity: 0.4; } + } + } + DragItem { + text: "Delegate Image" + icon.name: "image-png" + Layout.preferredHeight: parent.itemHeight + DragAndDrop.DragArea { + objectName: "image" + anchors { fill: parent; } + //delegateImage: "akonadi" + //mimeData.url: "https://www.kde.org/" + onDragStarted: { + isDragging = true; + print(" drag started for " + objectName); + ooo.text = objectName + } + onDrop: { + isDragging = false; + print(" item dropped " + objectName); + ooo.text = objectName + } + //Rectangle { anchors.fill: parent; color: "green"; opacity: 0.4; } + } + } + DragItem { + text: "HTML" + icon.name: "text-html" + Layout.preferredHeight: parent.itemHeight + DragAndDrop.DragArea { + objectName: "html" + anchors { fill: parent; } + mimeData.html: "One Two Three Four Five " + onDragStarted: { + isDragging = true; + print(" drag started for " + objectName); + ooo.text = objectName + } + onDrop: { + isDragging = false; + print(" item dropped " + objectName); + ooo.text = objectName + } + } + } + DragItem { + text: "Color" + icon.name: "preferences-color" + Layout.preferredHeight: parent.itemHeight + DragAndDrop.DragArea { + objectName: "color" + anchors { fill: parent; } + mimeData.color: "orange" + onDragStarted: { + isDragging = true; + print(" drag started for " + objectName); + ooo.text = objectName + } + onDrop: { + isDragging = false; + print(" item dropped " + objectName); + ooo.text = objectName + //mimeData. + } + } + } + DragItem { + text: "Lots of Stuff" + icon.name: "ksplash" + Layout.preferredHeight: parent.itemHeight + + DragAndDrop.DragArea { + id: dragArea2 + objectName: "stuff" + anchors.fill: parent + + mimeData.text: "Clownfish" + mimeData.html: "

Swimming in a Sea of Cheese

Primus->perform();

" + mimeData.color: "darkred" + mimeData.url: "https://www.kde.org/" + mimeData.urls: ["https://planet.kde.org", "https://fsfe.org", "https://techbase.kde.org", "https://qt.io"] + + //Rectangle { anchors.fill: parent; color: "yellow"; opacity: 0.6; } + + onDragStarted: { + isDragging = true; + print(" drag started for " + objectName); + ooo.text = objectName + } + onDrop: { + isDragging = false; + print(" item dropped " + objectName); + ooo.text = objectName + } + } + } + PlasmaComponents.Label { + id: ooo + } + } + + DragAndDrop.DropArea { + Layout.fillWidth: true + Layout.fillHeight: true + Layout.preferredWidth: 1 + + PlasmaExtras.Highlight { + id: dropHightlight + anchors.fill: parent + opacity: 0 + + PropertyAnimation { properties: "opacity"; easing.type: Easing.Linear; duration: 2000; } + } + + Rectangle { id: clr; anchors.fill: parent; color: "transparent"; opacity: color != "transparent" ? 1 : 0; } + + PlasmaComponents.Label { + id: ilabel + font.pointSize: _h / 2 + text: "Drop here." + opacity: isDragging ? 0.7 : 0 + anchors.centerIn: parent + horizontalAlignment: Text.AlignCenter + PropertyAnimation { properties: "opacity"; easing.type: Easing.Linear; duration: 2000; } + } + + PlasmaComponents.Label { + id: slabel + font.pointSize: _h / 4 + //text: "Drop here." + //opacity: isDragging ? 1 : 0 + //onTextChanged: print("droparea changed to " + text) + anchors.top: parent.top + anchors.right: parent.right + anchors.left: parent.left + //horizontalAlignment: Text.AlignCenter + } + + onDragEnter: { + // slabel.text = "drop item here"; + dropHightlight.opacity = 1; + } + onDragLeave: { + // slabel.text = "drop left"; + dropHightlight.opacity = 0; + } + onDrop: { + var txt = event.mimeData.html; + txt += event.mimeData.text; + if (event.mimeData.url != "") { + txt += "
Url: " + event.mimeData.url; + } + var i = 0; + var u; + for (u in event.mimeData.urls) { + txt += "
Url " + i + " : " + event.mimeData.urls[i]; + i++; + } + // print("COLOR: " + event.mimeData.color); + if (event.mimeData.hasColor()) { + clr.color = event.mimeData.color; + } else { + clr.color = "transparent"; + } + slabel.text = txt + dropHightlight.opacity = 0.5; + } + } + } + } +} diff --git a/examples/applets/testcomponents/contents/ui/IconsPage.qml b/examples/applets/testcomponents/contents/ui/IconsPage.qml new file mode 100644 index 0000000..b092259 --- /dev/null +++ b/examples/applets/testcomponents/contents/ui/IconsPage.qml @@ -0,0 +1,146 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import org.kde.plasma.core as PlasmaCore +import org.kde.plasma.components as PlasmaComponents +import org.kde.kquickcontrolsaddons as KQuickControlsAddons +import org.kde.kirigami as Kirigami + +// IconTab + +PlasmaComponents.Page { + id: iconsPage + anchors { + fill: parent + margins: _s + } + Column { + anchors.fill: parent + spacing: _s + + Kirigami.Heading { + width: parent.width + elide: Text.ElideRight + level: 1 + text: "Icons" + } + PlasmaComponents.Label { + text: "iconSizes.small : " + Kirigami.Units.iconSizes.small + + ", iconSizes.desktop: " + Kirigami.Units.iconSizes.desktop + + ",
iconSizes.toolbar: " + Kirigami.Units.iconSizes.toolbar + + ", iconSizes.dialog : " + Kirigami.Units.iconSizes.dialog + + } + Flow { + //height: _h + width: parent.width + spacing: _s + + Kirigami.Icon { + source: "configure" + width: _h + height: width + } + Kirigami.Icon { + source: "dialog-ok" + width: _h + height: width + } + Kirigami.Icon { + source: "folder-green" + width: _h + height: width + } + Kirigami.Icon { + source: "akonadi" + width: _h + height: width + } + Kirigami.Icon { + source: "clock" + width: _h + height: width + } + KQuickControlsAddons.QIconItem { + icon: "preferences-desktop-icons" + width: _h + height: width + } + + } + Kirigami.Heading { + level: 2 + text: "ToolTip" + } + + Row { + spacing: _s + PlasmaCore.ToolTipArea { + width: childrenRect.width + height: childrenRect.height + icon: "klipper" + mainText: "Fish sighted in the wild, in the wild, a fish was seen." + subText: "A mean-looking grouper swam by." + Kirigami.Icon { + id: akonadiIcon + objectName: "akonadiIcon" + source: "akonadi" + width: height + height: _h + //anchors.horizontalCenter: parent.horizontalCenter + Rectangle { color: "orange"; opacity: 0.3; anchors.fill: parent; } + } + } + PlasmaCore.ToolTipArea { + height: _h + width: height + image: bridgeimage.source + mainText: "Bridge" + subText: "Waalbrug." + Image { + id: bridgeimage + objectName: "bridgeimage" + height: _h + width: height + fillMode: Image.PreserveAspectFit + source: "../images/bridge.jpg" + } + } + PlasmaCore.ToolTipArea { + width: childrenRect.width + height: childrenRect.height + mainItem: PlasmaComponents.Label { + text: "Nijmegen North Beach" + anchors.centerIn: parent + } + Image { + objectName: "surfboardimage" + height: _h + width: height + fillMode: Image.PreserveAspectFit + source: "../images/surfboard.jpg" + + //subText: "A surfboard on the beach.
The photo shows the Waal river's north beach, \ + //across the water from Nijmegen, Netherlands. It was taken during the summer festivals a few years back." + } + } + PlasmaCore.ToolTipArea { + width: childrenRect.width + height: childrenRect.height + mainText: "Tooltip on button" + PlasmaComponents.Button { + id: button + text: "Button" + iconSource: "call-start" + } + } + + + } + } +} diff --git a/examples/applets/testcomponents/contents/ui/MousePage.qml b/examples/applets/testcomponents/contents/ui/MousePage.qml new file mode 100644 index 0000000..3ce5bbe --- /dev/null +++ b/examples/applets/testcomponents/contents/ui/MousePage.qml @@ -0,0 +1,106 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import org.kde.plasma.components as PlasmaComponents +import org.kde.plasma.extras as PlasmaExtras +import org.kde.kquickcontrolsaddons as KQuickControlsAddons +import org.kde.kirigami as Kirigami + +// MousePage + +PlasmaComponents.Page { + id: mousePage + anchors { + fill: parent + margins: _s + } + Kirigami.Heading { + id: mellabel + level: 1 + text: "MouseEventListener" + anchors { left: parent.left; right: parent.right; top: parent.top } + } + KQuickControlsAddons.MouseEventListener { + id: mel + hoverEnabled: true + anchors { left: parent.left; right: parent.right; top: mellabel.bottom; bottom: parent.bottom; } + /* + void pressed(KDeclarativeMouseEvent *mouse); + void positionChanged(KDeclarativeMouseEvent *mouse); + void released(KDeclarativeMouseEvent *mouse); + void clicked(KDeclarativeMouseEvent *mouse); + void pressAndHold(KDeclarativeMouseEvent *mouse); + void wheelMoved(KDeclarativeWheelEvent *wheel); + void containsMouseChanged(bool containsMouseChanged); + void hoverEnabledChanged(bool hoverEnabled); + */ + onPressed: { + print("Pressed"); + melstatus.text = "pressed"; + } + onPositionChanged: { + print("positionChanged: " + mouse.x + "," + mouse.y); + } + onReleased: { + print("Released"); + melstatus.text = "Released"; + } + onPressAndHold: { + print("pressAndHold"); + melstatus.text = "pressAndHold"; + } + onClicked: { + print("Clicked"); + melstatus.text = "clicked"; + } + onWheelMoved: { + print("Wheel: " + wheel.delta); + } + onContainsMouseChanged: { + print("Contains mouse: " + containsMouse); + } + + MouseArea { + //target: mel + anchors.fill: parent + onPressed: PlasmaExtras.DisappearAnimation { targetItem: bgImage } + onReleased: PlasmaExtras.AppearAnimation { targetItem: bgImage } + } + Image { + id: bgImage + source: "image://appbackgrounds/standard" + fillMode: Image.Tile + anchors.fill: parent + asynchronous: true +// opacity: mel.containsMouse ? 1 : 0.2 +// Behavior on opacity { PropertyAnimation {} } + } + Column { + //width: parent.width + spacing: _s + anchors.fill: parent + PlasmaComponents.Button { + text: "Button" + iconSource: "call-start" + } + PlasmaComponents.ToolButton { + text: "ToolButton" + iconSource: "call-stop" + } + PlasmaComponents.RadioButton { + text: "RadioButton" + //iconSource: "call-stop" + } + PlasmaComponents.Label { + id: melstatus + } + } + + } +} + diff --git a/examples/applets/testcomponents/contents/ui/PlasmoidPage.qml b/examples/applets/testcomponents/contents/ui/PlasmoidPage.qml new file mode 100644 index 0000000..81c3def --- /dev/null +++ b/examples/applets/testcomponents/contents/ui/PlasmoidPage.qml @@ -0,0 +1,78 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.plasmoid +import org.kde.plasma.components as PlasmaComponents +import org.kde.kquickcontrolsaddons as KQuickControlsAddons +import org.kde.kirigami as Kirigami + +// PlasmoidPage + +PlasmaComponents.Page { + id: plasmoidPage + anchors { + fill: parent + margins: _s + } + Column { + anchors.centerIn: parent + spacing: _s + Kirigami.Heading { + level: 2 + text: "I'm an applet" + } + + PlasmaComponents.ButtonColumn { + PlasmaComponents.RadioButton { + text: "No background" + onClicked: { + if (checked) Plasmoid.backgroundHints = 0; + } + } + PlasmaComponents.RadioButton { + text: "Default background" + checked: true + onClicked: { + if (checked) Plasmoid.backgroundHints = 1; + } + } + PlasmaComponents.RadioButton { + text: "Translucent background" + onClicked: { + if (checked) Plasmoid.backgroundHints = 2; + } + } + } + + PlasmaComponents.Button { + height: Kirigami.Units.iconSizes.desktop + text: "Busy" + checked: Plasmoid.busy + onClicked: { + Plasmoid.busy = !Plasmoid.busy + } + } + + PlasmaComponents.Button { + id: ctxButton + height: Kirigami.Units.iconSizes.desktop + text: "Context Menu" + Loader { + id: menuLoader + } + onClicked: { + if (menuLoader.source == "") { + menuLoader.source = "TestMenu.qml" + } else { + //menuLoader.source = "" + } + menuLoader.item.open(0, height); + } + } + } +} + diff --git a/examples/applets/testcomponents/contents/ui/TestMenu.qml b/examples/applets/testcomponents/contents/ui/TestMenu.qml new file mode 100644 index 0000000..6352835 --- /dev/null +++ b/examples/applets/testcomponents/contents/ui/TestMenu.qml @@ -0,0 +1,39 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.components as PlasmaComponents +import org.kde.kquickcontrolsaddons as KQuickControlsAddons + +// PlasmoidPage + +PlasmaComponents.Menu { + id: testMenu + + PlasmaComponents.MenuItem { + text: "Red Snapper" + icon: "dragonplayer" + onClicked: print(" Clicked on : " + text) + } + + PlasmaComponents.MenuItem { + text: "Eel" + icon: "kthesaurus" + onClicked: print(" Clicked on : " + text) + } + + PlasmaComponents.MenuItem { + text: "White Tip Reef Shark" + icon: "kmag" + onClicked: print(" Clicked on : " + text) + } + + Component.onCompleted:{ + print("TestMenu.qml served .. opening"); + + } +} + diff --git a/examples/applets/testcomponents/contents/ui/ThemePage.qml b/examples/applets/testcomponents/contents/ui/ThemePage.qml new file mode 100644 index 0000000..4d6048d --- /dev/null +++ b/examples/applets/testcomponents/contents/ui/ThemePage.qml @@ -0,0 +1,89 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + SPDX-FileCopyrightText: 2023 ivan tkachenko + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +PlasmaComponents.Page { + id: root + + padding: Kirigami.Units.largeSpacing + + component GridLabel : PlasmaComponents.Label { + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + + component ColorItem : Rectangle { + implicitWidth: Kirigami.Units.gridUnit * 2 + implicitHeight: Math.round(Kirigami.Units.gridUnit * 1.5) + radius: 5 + border { + color: root.Kirigami.Theme.textColor + width: 1 + } + } + + contentItem: GridLayout { + columns: 2 + columnSpacing: Kirigami.Units.largeSpacing + rowSpacing: Kirigami.Units.largeSpacing + + Kirigami.Heading { + Layout.columnSpan: 2 + Layout.fillWidth: true + elide: Text.ElideRight + level: 1 + text: "Theme" + } + + PlasmaComponents.Label { + Layout.columnSpan: 2 + text: "This is the smallest readable Font." + font: Kirigami.Theme.smallFont + } + + GridLabel { + text: "textColor:" + } + ColorItem { + color: Kirigami.Theme.textColor + } + + GridLabel { + text: "Button textColor:" + } + ColorItem { + Kirigami.Theme.inherit: false + Kirigami.Theme.colorSet: Kirigami.Theme.Button + color: Kirigami.Theme.textColor + } + + GridLabel { + text: "highlightColor:" + } + ColorItem { + color: Kirigami.Theme.highlightColor + } + + GridLabel { + text: "View backgroundColor:" + } + ColorItem { + Kirigami.Theme.inherit: false + Kirigami.Theme.colorSet: Kirigami.Theme.View + color: Kirigami.Theme.backgroundColor + } + + Item { + Layout.fillWidth: true + Layout.fillHeight: true + } + } +} diff --git a/examples/applets/testcomponents/contents/ui/main.qml b/examples/applets/testcomponents/contents/ui/main.qml new file mode 100644 index 0000000..d5fe677 --- /dev/null +++ b/examples/applets/testcomponents/contents/ui/main.qml @@ -0,0 +1,121 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + SPDX-FileCopyrightText: 2023 ivan tkachenko + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami +import org.kde.plasma.components as PlasmaComponents +import org.kde.plasma.plasmoid + +PlasmoidItem { + id: root + + property int currentIndex: 0 + onCurrentIndexChanged: print("AAA", currentIndex) + + fullRepresentation: ColumnLayout { + spacing: 0 + + Layout.minimumWidth: Kirigami.Units.gridUnit * 15 + Layout.minimumHeight: Kirigami.Units.gridUnit * 15 + + Layout.maximumWidth: Kirigami.Units.gridUnit * 60 + Layout.maximumHeight: Kirigami.Units.gridUnit * 60 + + PlasmaComponents.TabBar { + id: tabBar + + currentIndex: root.currentIndex + + onCurrentIndexChanged: { + root.currentIndex = currentIndex; + } + + Layout.fillWidth: true + // Layout.preferredHeight: + // anchors { + // left: parent.left + // right: parent.right + // top: parent.top + // } + + // height: Kirigami.Units.iconSizes.desktop + + PlasmaComponents.TabButton { + display: T.AbstractButton.IconOnly + text: "Theme Page" + icon.name: "preferences-desktop-appearance" + } + PlasmaComponents.TabButton { + display: T.AbstractButton.IconOnly + text: "Drag Page" + icon.name: "preferences-desktop-mouse" + } + PlasmaComponents.TabButton { + display: T.AbstractButton.IconOnly + text: "Icons Page" + icon.name: "preferences-desktop-icons" + } + PlasmaComponents.TabButton { + display: T.AbstractButton.IconOnly + text: "Dialogs Page" + icon.name: "preferences-system-windows" + } + PlasmaComponents.TabButton { + display: T.AbstractButton.IconOnly + text: "Buttons Page" + icon.name: "preferences-desktop-theme" + } + PlasmaComponents.TabButton { + display: T.AbstractButton.IconOnly + text: "Plasmoid Page" + icon.name: "plasma" + } + PlasmaComponents.TabButton { + display: T.AbstractButton.IconOnly + text: "Mouse Page" + icon.name: "preferences-desktop-mouse" + } + } + + PlasmaComponents.SwipeView { + id: contentViewContainer + + Layout.fillWidth: true + Layout.fillHeight: true + + clip: true + + currentIndex: root.currentIndex + + onCurrentIndexChanged: { + root.currentIndex = currentIndex; + } + + ThemePage {} + DragPage {} + // IconsPage { + // id: iconsPage + // } + // DialogsPage { + // id: dialogsPage + // } + // ButtonsPage { + // id: buttonsPage + // } + // PlasmoidPage { + // id: plasmoidPage + // } + + // MousePage { + // id: mousePage + // } + + } + } +} diff --git a/examples/applets/testcomponents/metadata.json b/examples/applets/testcomponents/metadata.json new file mode 100644 index 0000000..c1c6a81 --- /dev/null +++ b/examples/applets/testcomponents/metadata.json @@ -0,0 +1,129 @@ +{ + "KPackageStructure": "Plasma/Applet", + "KPlugin": { + "Authors": [ + { + "Email": "sebas@kde.org", + "Name": "Sebastian Kügler", + "Name[ar]": "Sebastian Kügler", + "Name[az]": "Sebastian Kügler", + "Name[be]": "Sebastian Kügler", + "Name[bg]": "Sebastian Kügler", + "Name[ca@valencia]": "Sebastian Kügler", + "Name[ca]": "Sebastian Kügler", + "Name[cs]": "Sebastian Kügler", + "Name[de]": "Sebastian Kügler", + "Name[en_GB]": "Sebastian Kügler", + "Name[eo]": "Sebastian Kügler", + "Name[es]": "Sebastian Kügler", + "Name[eu]": "Sebastian Kügler", + "Name[fi]": "Sebastian Kügler", + "Name[fr]": "Sebastian Kügler", + "Name[gl]": "Sebastian Kügler", + "Name[he]": "סבסטיאן קיגלר", + "Name[hu]": "Sebastian Kügler", + "Name[ia]": "Sebastian Kügler", + "Name[id]": "Sebastian Kügler", + "Name[it]": "Sebastian Kügler", + "Name[ka]": "Sebastian Kügler", + "Name[ko]": "Sebastian Kügler", + "Name[lv]": "Sebastian Kügler", + "Name[nl]": "Sebastian Kügler", + "Name[nn]": "Sebastian Kügler", + "Name[pl]": "Sebastian Kügler", + "Name[pt]": "Sebastian Kügler", + "Name[pt_BR]": "Sebastian Kügler", + "Name[ro]": "Sebastian Kügler", + "Name[ru]": "Sebastian Kügler", + "Name[sa]": "सेबास्टियन कुग्लर", + "Name[sk]": "Sebastian Kügler", + "Name[sl]": "Sebastian Kügler", + "Name[sv]": "Sebastian Kügler", + "Name[ta]": "ஸெபாஸ்டியன் கூக்லர்", + "Name[tr]": "Sebastian Kügler", + "Name[uk]": "Sebastian Kügler", + "Name[vi]": "Sebastian Kügler", + "Name[x-test]": "xxSebastian Küglerxx", + "Name[zh_CN]": "Sebastian Kügler", + "Name[zh_TW]": "Sebastian Kügler" + } + ], + "Category": "Development Tools", + "Description": "Test Components", + "Description[bg]": "Тест на компоненти", + "Description[ca@valencia]": "Components de prova", + "Description[ca]": "Components de prova", + "Description[de]": "Komponenten testen", + "Description[eo]": "Testi Komponantojn", + "Description[es]": "Prueba de componentes", + "Description[eu]": "Proba osagaiak", + "Description[fi]": "Testin osat", + "Description[fr]": "Test de composants", + "Description[gl]": "Compoñentes de proba.", + "Description[he]": "בדיקת רכיבים", + "Description[hu]": "Komponensek tesztelése", + "Description[ia]": "Essayo de componentes( Components)", + "Description[it]": "Prova dei componenti", + "Description[ka]": "კომპონენტების ტესტი", + "Description[ko]": "구성 요소 테스트", + "Description[lv]": "KomponenÅ¡u tests", + "Description[nl]": "Componenten testen", + "Description[pl]": "Próba składników", + "Description[pt_BR]": "Teste de componentes", + "Description[ru]": "Тест компонентов", + "Description[sa]": "परीक्षण घटक", + "Description[sl]": "Preizkus komponent", + "Description[tr]": "Sınama Bileşenleri", + "Description[uk]": "Тест компонентів", + "Description[vi]": "Các thành phần kiểm thá»­", + "Description[x-test]": "xxTest Componentsxx", + "Description[zh_CN]": "测试组件", + "Description[zh_TW]": "測試元件", + "Icon": "plasma", + "Id": "org.kde.example.testcomponents", + "License": "GPLv2+", + "Name": "Components Test", + "Name[az]": "Komponentlərin testləri", + "Name[be]": "Тэставанне кампанентаў", + "Name[bg]": "Тест на компоненти", + "Name[ca@valencia]": "Prova de components", + "Name[ca]": "Prova de components", + "Name[en_GB]": "Components Test", + "Name[eo]": "Testo de Komponentoj", + "Name[es]": "Prueba de componentes", + "Name[eu]": "Osagaien proba", + "Name[fi]": "Osatesti", + "Name[fr]": "Test de composants", + "Name[gl]": "Proba dos compoñentes", + "Name[he]": "בדיקת רכיבים", + "Name[hu]": "Komponensteszt", + "Name[ia]": "Essayo de componentes(Components)", + "Name[id]": "Uji Komponent", + "Name[it]": "Prova dei componenti", + "Name[ka]": "კომპონენტების ტესტი", + "Name[ko]": "구성 요소 테스트", + "Name[lv]": "KomponenÅ¡u tests", + "Name[nl]": "Test van componenten", + "Name[nn]": "Komponenttest", + "Name[pl]": "Próba składników", + "Name[pt]": "Teste de Componentes", + "Name[pt_BR]": "Teste de componentes", + "Name[ro]": "Test componente", + "Name[ru]": "Тест компонентов", + "Name[sa]": "घटक परीक्षण", + "Name[sk]": "Test komponentov", + "Name[sl]": "Preizkus komponent", + "Name[sv]": "Komponenttest", + "Name[ta]": "கூறு சோதனை", + "Name[tr]": "Bileşenler Sınaması", + "Name[uk]": "Тестування компонентів", + "Name[vi]": "Kiểm thá»­ các thành phần", + "Name[x-test]": "xxComponents Testxx", + "Name[zh_CN]": "组件测试", + "Name[zh_TW]": "元件測試", + "Version": "", + "Website": "https://www.kde.org/" + }, + "Keywords": "", + "X-KDE-ParentApp": "" +} diff --git a/examples/applets/testshaders/contents/config/main.xml b/examples/applets/testshaders/contents/config/main.xml new file mode 100644 index 0000000..bac72e5 --- /dev/null +++ b/examples/applets/testshaders/contents/config/main.xml @@ -0,0 +1,17 @@ + + + + + + + + 60 + 20 + 150 + + + + diff --git a/examples/applets/testshaders/contents/images/elarun-small.png b/examples/applets/testshaders/contents/images/elarun-small.png new file mode 100644 index 0000000000000000000000000000000000000000..59a208db8ee7628ead1712c34114403de2505661 GIT binary patch literal 87370 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 literal 0 HcmV?d00001 diff --git a/examples/applets/testshaders/contents/ui/ColorExample.qml b/examples/applets/testshaders/contents/ui/ColorExample.qml new file mode 100644 index 0000000..93b3a07 --- /dev/null +++ b/examples/applets/testshaders/contents/ui/ColorExample.qml @@ -0,0 +1,30 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +ShaderExample { + + pageName: "Colors" + pageDescription: "" + + ShaderEffect { + anchors.fill: parent + anchors.topMargin: 48 + opacity: 0.2 + + fragmentShader: { + "uniform mat4 gl_ModelViewMatrix;" + + "uniform mat4 gl_ProjectionMatrix;" + + //"attribute vec4 gl_Vertex;" + + "void main(void) {" + + " gl_FragColor = vec4(1.0, 0.0, 0.0, 0.3); " + + " gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex; " + + "}" + } + } +} + diff --git a/examples/applets/testshaders/contents/ui/ColorShower.qml b/examples/applets/testshaders/contents/ui/ColorShower.qml new file mode 100644 index 0000000..6a9e251 --- /dev/null +++ b/examples/applets/testshaders/contents/ui/ColorShower.qml @@ -0,0 +1,89 @@ +/* + SPDX-FileCopyrightText: 2013 Digia Plc and /or its subsidiary(-ies) + + This file is part of the examples of the Qt Toolkit. + + SPDX-License-Identifier: BSD-3-Clause +*/ + +import QtQuick +import QtQuick.Particles + +ShaderExample { + + pageName: "Particles" + pageDescription: "Fun rainbow colors using a fragment shader" + + Item { + anchors.fill: parent + clip: true + anchors.margins: -_s + ParticleSystem { + id: psItem + //anchors.fill: parent + x: parent.width / 2 + y: parent.height / 2 + width: parent.width + height: parent.height +// clip: true + anchors.topMargin: 48 + //anchors.leftMargin: 42 + + Emitter { + emitRate: 400 + lifeSpan: 8000 + size: 24 + sizeVariation: 16 + velocity: PointDirection {x: psItem.width/20; y: psItem.height/20;} + acceleration: PointDirection {x: -psItem.width/40; y: -psItem.height/40; xVariation: -psItem.width/20; yVariation: -psItem.width/20} + } + + CustomParticle { + vertexShader:" + uniform lowp float qt_Opacity; + varying lowp float fFade; + varying highp vec2 fPos; + + void main() { + qt_TexCoord0 = qt_ParticleTex; + highp float size = qt_ParticleData.z; + highp float endSize = qt_ParticleData.w; + + highp float t = (qt_Timestamp - qt_ParticleData.x) / qt_ParticleData.y; + + highp float currentSize = mix(size, endSize, t * t); + + if (t < 0. || t > 1.) + currentSize = 0.; + + highp vec2 pos = qt_ParticlePos + - currentSize / 2. + currentSize * qt_ParticleTex // adjust size + + qt_ParticleVec.xy * t * qt_ParticleData.y // apply velocity vector.. + + 0.5 * qt_ParticleVec.zw * pow(t * qt_ParticleData.y, 2.); + + gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1); + + highp float fadeIn = min(t * 20., 1.); + highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.)); + + fFade = fadeIn * fadeOut * qt_Opacity; + fPos = vec2(pos.x/320., pos.y/480.); + } + " + //! [0] + fragmentShader: " + varying highp vec2 fPos; + varying lowp float fFade; + varying highp vec2 qt_TexCoord0; + void main() {//*2 because this generates dark colors mostly + highp vec2 circlePos = qt_TexCoord0*2.0 - vec2(1.0,1.0); + highp float dist = length(circlePos); + highp float circleFactor = max(min(1.0 - dist, 1.0), 0.0); + gl_FragColor = vec4(fPos.x*2.0 - fPos.y, fPos.y*2.0 - fPos.x, fPos.x*fPos.y*2.0, 0.0) * circleFactor * fFade; + }" + //! [0] + + } + } + } +} diff --git a/examples/applets/testshaders/contents/ui/EditorPage.qml b/examples/applets/testshaders/contents/ui/EditorPage.qml new file mode 100644 index 0000000..32ac3fb --- /dev/null +++ b/examples/applets/testshaders/contents/ui/EditorPage.qml @@ -0,0 +1,144 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +// ButtonsPage + +PlasmaComponents.Page { + id: editorPage + + property string shader + property alias shaderText: editor.text + property string pageName: "Editor" + property string icon: "accessories-text-editor" + + anchors { + fill: parent + margins: _s + } + + Image { + id: imageItem + anchors.fill: parent + //source: "../images/elarun-small.png" + } + + ShaderEffectSource { + id: effectSource + sourceItem: imageItem + //hideSource: hideSourceCheckbox.checked + hideSource: true + } + + ShaderEffect { + id: mainShader + anchors.fill: editorPage + property ShaderEffectSource source: effectSource + property real f: 0 + property real f2: 0 + property int intensity: 1 + smooth: true + } + PlasmaComponents.ToolButton { + iconSource: "dialog-close" + width: _h + height: width + visible: !(mainShader.fragmentShader == "" && mainShader.vertexShader == "") + anchors { top: parent.top; right: parent.right; } + onClicked: { + mainShader.fragmentShader = ""; + mainShader.vertexShader = ""; + editorPage.shader = "" + vertexPage.shader = "" + } + } + + + Kirigami.Heading { + id: heading + level: 1 + anchors { + top: parent.top; + left: parent.left + right: parent.right + } + text: pageName + } + PlasmaComponents.ButtonColumn { + anchors { + right: parent.right + top: heading.top + } + PlasmaComponents.RadioButton { + id: fragmentRadio + text: "Fragment / Pixel Shader" + } + PlasmaComponents.RadioButton { + text: "Vertex Shader" + } + } + +// PlasmaComponents.TextArea { +// id: editor +// anchors { +// top: heading.bottom; +// topMargin: _s +// left: parent.left +// right: parent.right +// bottom: applyButton.top +// wrapMode: TextEdit.Wrap +// bottomMargin: _s +// +// } +// // text: { "void main(void) {\ +// // gl_FragColor = vec4(1.0, 0.0, 0.0, 0.3);\ +// // }" +// // } +// text:" +// void main(void) { +// gl_FragColor = vec4(0.2, 0.8, 0.6, 0.3); +// } +// " +// +// // width: parent.width +// // parent.height-height: _h*2 +// } + + PlasmaComponents.Button { + id: applyButton + text: "Upload Shader" + onClicked: { + shader = editor.text + if (fragmentRadio.checked) { + print("Uploading new fragment shader: \n" + shader); + mainShader.fragmentShader = shader + } else { + print("Uploading new vertex shader: \n" + shader); + mainShader.vertexShader = shader; + } + } + + anchors { + right: parent.right + bottom: parent.bottom + + } + + + + } +// PlasmaComponents.CheckBox { +// id: hideSourceCheckbox +// text: "Hide Source Item" +// anchors { bottom: parent.bottom; left: parent.left; margins: _s; } +// onCheckedChanged: effectSource.hideSource = checked +// } + +} diff --git a/examples/applets/testshaders/contents/ui/ShaderExample.qml b/examples/applets/testshaders/contents/ui/ShaderExample.qml new file mode 100644 index 0000000..4a79a06 --- /dev/null +++ b/examples/applets/testshaders/contents/ui/ShaderExample.qml @@ -0,0 +1,45 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +// VertexPage + +PlasmaComponents.Page { + id: examplesPage + + //property string shader + property string pageName: "Shader Examples" + property string pageDescription: "Shader Examples" + property string icon: "weather-clear" + + anchors { + fill: parent + margins: _s + } + + Kirigami.Heading { + id: heading + level: 1 + anchors { + top: parent.top; + left: parent.left + right: parent.right + } + text: pageName + } + PlasmaComponents.Label { + anchors { + top: heading.bottom; + left: parent.left; + right: parent.right; + } + text: pageDescription + } +} diff --git a/examples/applets/testshaders/contents/ui/Shadows.qml b/examples/applets/testshaders/contents/ui/Shadows.qml new file mode 100644 index 0000000..66bf571 --- /dev/null +++ b/examples/applets/testshaders/contents/ui/Shadows.qml @@ -0,0 +1,208 @@ +/* + SPDX-FileCopyrightText: 2013 Digia Plc and /or its subsidiary(-ies) + + This file is part of the examples of the Qt Toolkit. + + SPDX-License-Identifier: BSD-3-Clause +*/ + +import QtQuick +//import QtQuick.Particles + +import org.kde.plasma.components as PlasmaComponents +import org.kde.ksvg as KSvg +import org.kde.kirigami as Kirigami + +ShaderExample { + + pageName: "Shadows" + pageDescription: "" + Grid { + id: cfgrid + columns: 2 + + anchors.top: parent.top + anchors.right: parent.right + width: parent.width * 0.6 + height: 96 + spacing: 6 + columnSpacing: 12 + PlasmaComponents.Label { + text: "Distance:"; + width: parent.width * 0.5; + horizontalAlignment: Text.AlignRight + elide: Text.ElideRight + } + PlasmaComponents.Slider { + width: parent.width * 0.4 + id: distanceSlider + stepSize: 1 + minimumValue: 0 + maximumValue: 25 + value: 8 + } + + PlasmaComponents.Label { + text: "Opacity:"; + horizontalAlignment: Text.AlignRight + elide: Text.ElideRight + width: parent.width * 0.5; + } + PlasmaComponents.Slider { + width: parent.width * 0.4 + id: opacitySlider +// stepSize: 250 + minimumValue: 0 + maximumValue: 1.0 + stepSize: 0.05 + value: 0.4 + } + } + + Item { + anchors.fill: parent + clip: true + anchors.margins: -_s + + Item { + id: theItem + anchors.fill: parent + anchors.topMargin: _s * 2 + + Column { + anchors.fill: parent + anchors.margins: _s + anchors.topMargin: _s * 2 + spacing: _s + + Kirigami.Heading { + text: "Effects on Components" + + } + PlasmaComponents.Label { + text:"In Plasma 2, the user interface is based on an OpenGL scenegraph, composition of the UI happens on the graphics card. In the past weeks, we've been working on getting a Plasma 2 shell up and running, and on porting the QML imports of the Plasma Components." + } + + Kirigami.Heading { + font.pointSize: 48 + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: _s * 3 + text: "This is shadowy text." + } + Row { + height: 48 + width: parent.width + spacing: _s + + Kirigami.Icon { + source: "configure" + width: parent.height + height: width + } + Kirigami.Icon { + source: "dialog-ok" + width: parent.height + height: width + } + + KSvg.SvgItem { + id: buttonItem + svg: KSvg.Svg { + id: configIconsSvg + imagePath: "widgets/configuration-icons" + } + elementId: "maximize" + width: parent.height + height: width + } + + Kirigami.Icon { + source: "akonadi" + width: parent.height + height: width + } + Kirigami.Icon { + source: "clock" + width: parent.height + height: width + } + } + } + } + ShaderEffectSource { + id: theSource + sourceItem: theItem + hideSource: true + } + + ShaderEffect { + anchors.fill: theItem + property ShaderEffectSource source: theSource + property ShaderEffectSource shadow: ShaderEffectSource { + sourceItem: ShaderEffect { + width: theItem.width + height: theItem.height + property size delta: Qt.size(0.0, 1.0 / height) + property ShaderEffectSource source: ShaderEffectSource { + sourceItem: ShaderEffect { + width: theItem.width + height: theItem.height + property size delta: Qt.size(1.0 / width, 0.0) + property ShaderEffectSource source: theSource + fragmentShader: " + uniform lowp float qt_Opacity; + uniform sampler2D source; + uniform highp vec2 delta; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor =(0.0538 * texture2D(source, qt_TexCoord0 - 3.182 * delta) + + 0.3229 * texture2D(source, qt_TexCoord0 - 1.364 * delta) + + 0.2466 * texture2D(source, qt_TexCoord0) + + 0.3229 * texture2D(source, qt_TexCoord0 + 1.364 * delta) + + 0.0538 * texture2D(source, qt_TexCoord0 + 3.182 * delta)) * qt_Opacity; + }" + } + } + fragmentShader: " + uniform lowp float qt_Opacity; + uniform sampler2D source; + uniform highp vec2 delta; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor =(0.0538 * texture2D(source, qt_TexCoord0 - 3.182 * delta) + + 0.3229 * texture2D(source, qt_TexCoord0 - 1.364 * delta) + + 0.2466 * texture2D(source, qt_TexCoord0) + + 0.3229 * texture2D(source, qt_TexCoord0 + 1.364 * delta) + + 0.0538 * texture2D(source, qt_TexCoord0 + 3.182 * delta)) * qt_Opacity; + }" + } + } + property real angle: 0 + property point offset: Qt.point(distanceSlider.value * Math.cos(angle), distanceSlider.value * Math.sin(angle)) + NumberAnimation on angle { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 6000 } + property size delta: Qt.size(offset.x / width, offset.y / height) + property real darkness: opacitySlider.value // Changeme + fragmentShader: " + uniform lowp float qt_Opacity; + uniform highp vec2 offset; + uniform sampler2D source; + uniform sampler2D shadow; + uniform highp float darkness; + uniform highp vec2 delta; + varying highp vec2 qt_TexCoord0; + void main() { + lowp vec4 fg = texture2D(source, qt_TexCoord0); + lowp vec4 bg = texture2D(shadow, qt_TexCoord0 + delta); + gl_FragColor = (fg + vec4(0., 0., 0., darkness * bg.a) * (1. - fg.a)) * qt_Opacity; + }" +// Slider { +// id: shadowSlider +// anchors.left: parent.left +// anchors.right: parent.right +// anchors.bottom: parent.bottom +// height: 40 +// } + } + + } +} diff --git a/examples/applets/testshaders/contents/ui/SimpleExample.qml b/examples/applets/testshaders/contents/ui/SimpleExample.qml new file mode 100644 index 0000000..017f790 --- /dev/null +++ b/examples/applets/testshaders/contents/ui/SimpleExample.qml @@ -0,0 +1,27 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +ShaderExample { + + pageName: "Simple" + pageDescription: "Paints a red, translucent rectangle" + + ShaderEffect { + anchors.fill: parent + anchors.topMargin: 48 + opacity: 0.2 + + fragmentShader: { " \ + void main(void) { \ + gl_FragColor = vec4(1.0, 0.0, 0.0, 0.3); \ + } \ + " + } + } +} + diff --git a/examples/applets/testshaders/contents/ui/WaterEffect.qml b/examples/applets/testshaders/contents/ui/WaterEffect.qml new file mode 100644 index 0000000..8de16f9 --- /dev/null +++ b/examples/applets/testshaders/contents/ui/WaterEffect.qml @@ -0,0 +1,95 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import org.kde.plasma.components as PlasmaComponents + +// VertexPage + +Item { + id: waterRoot + property alias sourceItem: effectsource.sourceItem + property bool waving: true + //anchors.top: parent.bottom + anchors.top: iconCol.bottom + width: sourceItem.width + height: sourceItem.height + + ShaderEffect { + anchors.fill: parent + property ShaderEffectSource source: effectsource + property real f: 0 + property real f2: 0 + property real intensity: 1 + smooth: true + + ShaderEffectSource { + id: effectsource + //hideSource: false + //smooth: true + sourceItem: mainItem + } + + fragmentShader: + " + varying highp vec2 qt_TexCoord0; + uniform sampler2D source; + uniform lowp float qt_Opacity; + uniform highp float f; + uniform highp float f2; + uniform highp float intensity; + + void main() { + const highp float twopi = 3.141592653589 * 2.0; + + highp float distanceFactorToPhase = pow(qt_TexCoord0.y + 0.5, 8.0) * 5.0; + highp float ofx = sin(f * twopi + distanceFactorToPhase) / 100.0; + highp float ofy = sin(f2 * twopi + distanceFactorToPhase * qt_TexCoord0.x) / 60.0; + + highp float intensityDampingFactor = (qt_TexCoord0.x + 2.0) * (qt_TexCoord0.y + 0.2); + highp float distanceFactor = (1.0 - qt_TexCoord0.y) * 4.0 * intensity * intensityDampingFactor; + + ofx *= distanceFactor; + ofy *= distanceFactor; + + highp float x = qt_TexCoord0.x + ofx; + highp float y = 1.0 - qt_TexCoord0.y + ofy; + + highp float fake = (sin((ofy + ofx) * twopi) + 0.5) * 0.05 * (1.2 - qt_TexCoord0.y) * intensity * intensityDampingFactor; + + highp vec4 pix = + texture2D(source, vec2(x, y)) * 0.6 + + texture2D(source, vec2(x-fake, y)) * 2.05 + + texture2D(source, vec2(x, y-fake)) * 2.05 + + texture2D(source, vec2(x+fake, y)) * 2.05 + + texture2D(source, vec2(x, y+fake)) * 2.05; + + highp float darken = 0.6 - (ofx - ofy) / 2.0; + pix.b *= 1.2 * darken; + pix.r *= 0.9 * darken; + pix.g *= darken; + + gl_FragColor = qt_Opacity * vec4(pix.r, pix.g, pix.b, 1.0); + } + " + + NumberAnimation on f { + running: waterRoot.waving + loops: Animation.Infinite + from: 0 + to: 1 + duration: 2410 + } + NumberAnimation on f2 { + running: waterRoot.waving + loops: Animation.Infinite + from: 0 + to: 1 + duration: 1754 + } + } +} diff --git a/examples/applets/testshaders/contents/ui/WobbleExample.qml b/examples/applets/testshaders/contents/ui/WobbleExample.qml new file mode 100644 index 0000000..e6a87be --- /dev/null +++ b/examples/applets/testshaders/contents/ui/WobbleExample.qml @@ -0,0 +1,120 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.plasmoid +import org.kde.plasma.components as PlasmaComponents + +ShaderExample { + + pageName: "Wobble" + pageDescription: "Makes an image wobble" + + Grid { + id: cfgrid + columns: 2 + + anchors.top: parent.top + anchors.right: parent.right + width: parent.width * 0.6 + height: 96 + spacing: 6 + columnSpacing: _m + PlasmaComponents.Label { + text: "Amplitude:"; + width: parent.width * 0.5; + horizontalAlignment: Text.AlignRight + elide: Text.ElideRight + } + PlasmaComponents.Slider { + width: parent.width * 0.4 + id: amplitudeSlider + stepSize: 0.05 + minimumValue: 0 + maximumValue: 1.0 + value: 0.4 + } + + PlasmaComponents.Label { + text: "Speed:"; + horizontalAlignment: Text.AlignRight + width: parent.width * 0.5; + elide: Text.ElideRight + } + PlasmaComponents.Slider { + width: parent.width * 0.4 + id: speedSlider + stepSize: 250 + minimumValue: 0 + maximumValue: 6000 + value: 3000 + onValueChanged: { + if (timeAnimation != null) { + timeAnimation.duration = maximumValue - value +1; + timeAnimation.restart(); + } + } + } + } + PlasmaComponents.Button { + anchors { right: parent.right; bottom: parent.bottom; } + text: "Busy" + checked: Plasmoid.busy + onClicked: { + Plasmoid.busy = !Plasmoid.busy + } + } + + + Item { + id: imageItem + opacity: 0.8 + anchors.fill: parent + anchors.topMargin: 48 + Image { + source: "../images/elarun-small.png" + anchors.fill: parent + anchors.margins: parent.height / 10 + } + } + + ShaderEffect { + id: wobbleShader + + anchors.fill: imageItem + //property real time + property var mouse + property var resolution + + property int fadeDuration: 250 + property real amplitude: 0.04 * amplitudeSlider.value + property real frequency: 20 + property real time: 10 + property int speed: (speedSlider.maximumValue - speedSlider.value + 1) + + property ShaderEffectSource source: ShaderEffectSource { + sourceItem: imageItem + hideSource: true + } + + NumberAnimation on time { id: timeAnimation; loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 3000 } + Behavior on amplitude { NumberAnimation { duration: wobbleShader.fadeDuration } } + + fragmentShader: { //mainItem.opacity = 0; + "uniform lowp float qt_Opacity;" + + "uniform highp float amplitude;" + + "uniform highp float frequency;" + + "uniform highp float time;" + + "uniform sampler2D source;" + + "varying highp vec2 qt_TexCoord0;" + + "void main() {" + + " highp vec2 p = sin(time + frequency * qt_TexCoord0);" + + " gl_FragColor = texture2D(source, qt_TexCoord0 + amplitude * vec2(p.y, -p.x)) * qt_Opacity;" + + "}" + } + } + +} diff --git a/examples/applets/testshaders/contents/ui/config.qml b/examples/applets/testshaders/contents/ui/config.qml new file mode 100644 index 0000000..1de84ae --- /dev/null +++ b/examples/applets/testshaders/contents/ui/config.qml @@ -0,0 +1,17 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +// import org.kde.kirigami as Kirigami + +Column { + id: root + //property alias cfg_Speed + Rectangle { color: "green"; width: 200; height: 300; } +// Kirigami.Heading { +// text: "Applet Config:" +// } +} diff --git a/examples/applets/testshaders/contents/ui/main.qml b/examples/applets/testshaders/contents/ui/main.qml new file mode 100644 index 0000000..152a9d5 --- /dev/null +++ b/examples/applets/testshaders/contents/ui/main.qml @@ -0,0 +1,78 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts + +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +Item { + id: root + width: 400 + height: 400 + + Layout.minimumWidth: Kirigami.Units.gridUnit * 20 + Layout.minimumHeight: Kirigami.Units.gridUnit * 30 + property int _s: Kirigami.Units.iconSizes.small + property int _h: Kirigami.Units.iconSizes.desktop + property int _m: 12 + + Item { + id: mainItem + anchors.fill: parent + + PlasmaComponents.TabBar { + id: tabBar + + anchors { + left: parent.left + right: parent.right + top: parent.top + } + height: Kirigami.Units.iconSizes.toolbar * 1.5 + + PlasmaComponents.TabButton { tab: colorShower; text: tab.pageName; } + PlasmaComponents.TabButton { tab: wobbleExample; text: tab.pageName; } + PlasmaComponents.TabButton { tab: shadowExample; text: tab.pageName; } + PlasmaComponents.TabButton { tab: simpleExample; text: tab.pageName; } + //PlasmaComponents.TabButton { tab: vertexPage; iconSource: vertexPage.icon; } + } + + PlasmaComponents.TabGroup { + id: tabGroup + anchors { + left: parent.left + right: parent.right + top: tabBar.bottom + bottom: parent.bottom + } + + ColorShower { + id: colorShower + } + WobbleExample { + id: wobbleExample + } +// ColorExample { +// id: colorExample +// } + Shadows { + id: shadowExample + } + SimpleExample { + id: simpleExample + } +// EditorPage { +// id: vertexPage +// } + } + } + + Component.onCompleted: { + print("Shader Test Applet loaded"); + } +} diff --git a/examples/applets/testshaders/metadata.json b/examples/applets/testshaders/metadata.json new file mode 100644 index 0000000..ed63d6e --- /dev/null +++ b/examples/applets/testshaders/metadata.json @@ -0,0 +1,135 @@ +{ + "KPackageStructure": "Plasma/Applet", + "KPlugin": { + "Authors": [ + { + "Email": "sebas@kde.org", + "Name": "Sebastian Kügler", + "Name[ar]": "Sebastian Kügler", + "Name[az]": "Sebastian Kügler", + "Name[be]": "Sebastian Kügler", + "Name[bg]": "Sebastian Kügler", + "Name[ca@valencia]": "Sebastian Kügler", + "Name[ca]": "Sebastian Kügler", + "Name[cs]": "Sebastian Kügler", + "Name[de]": "Sebastian Kügler", + "Name[en_GB]": "Sebastian Kügler", + "Name[eo]": "Sebastian Kügler", + "Name[es]": "Sebastian Kügler", + "Name[eu]": "Sebastian Kügler", + "Name[fi]": "Sebastian Kügler", + "Name[fr]": "Sebastian Kügler", + "Name[gl]": "Sebastian Kügler", + "Name[he]": "סבסטיאן קיגלר", + "Name[hu]": "Sebastian Kügler", + "Name[ia]": "Sebastian Kügler", + "Name[id]": "Sebastian Kügler", + "Name[it]": "Sebastian Kügler", + "Name[ka]": "Sebastian Kügler", + "Name[ko]": "Sebastian Kügler", + "Name[lv]": "Sebastian Kügler", + "Name[nl]": "Sebastian Kügler", + "Name[nn]": "Sebastian Kügler", + "Name[pl]": "Sebastian Kügler", + "Name[pt]": "Sebastian Kügler", + "Name[pt_BR]": "Sebastian Kügler", + "Name[ro]": "Sebastian Kügler", + "Name[ru]": "Sebastian Kügler", + "Name[sa]": "सेबास्टियन कुग्लर", + "Name[sk]": "Sebastian Kügler", + "Name[sl]": "Sebastian Kügler", + "Name[sv]": "Sebastian Kügler", + "Name[ta]": "ஸெபாஸ்டியன் கூக்லர்", + "Name[tr]": "Sebastian Kügler", + "Name[uk]": "Sebastian Kügler", + "Name[vi]": "Sebastian Kügler", + "Name[x-test]": "xxSebastian Küglerxx", + "Name[zh_CN]": "Sebastian Kügler", + "Name[zh_TW]": "Sebastian Kügler" + } + ], + "Category": "Graphics", + "Description": "Futzing with Visual Effects", + "Description[az]": "Vizual Effektlər nümunəsi", + "Description[be]": "Дэманстрацыя візуальных эфектаў", + "Description[bg]": "Заиграване с визуалните ефекти", + "Description[ca@valencia]": "Jugant amb els efectes visuals", + "Description[ca]": "Jugant amb els efectes visuals", + "Description[en_GB]": "Futzing with Visual Effects", + "Description[eo]": "Futzing kun Vidaj Efektoj", + "Description[es]": "Jugando con efectos visuales", + "Description[eu]": "Denbora xahutu ikus-efektuekin", + "Description[fi]": "Leiki visuaalisilla tehosteilla", + "Description[fr]": "Les effets visuels à la louche", + "Description[gl]": "Perdas de tempo con efectos visuais.", + "Description[he]": "לשחק עם אפקטים חזותיים", + "Description[hu]": "Játék vizuális hatásokkal", + "Description[ia]": "Jocante (Futzing) con effectos visual", + "Description[id]": "Futzing dengan Efek Visual", + "Description[it]": "Divertirsi con gli effetti visuali", + "Description[ka]": "ვიზუალური ეფექტის მაგალითები", + "Description[ko]": "시각 효과 가지고 놀기", + "Description[lv]": "Spēlēšanās ar vizuāliem efektiem", + "Description[nl]": "Tijd verspillen met visuele effecten", + "Description[nn]": "Fomling med visuelle effektar", + "Description[pl]": "Grzebanie przy efektach wizualnych", + "Description[pt]": "Brincar com Efeitos Visuais", + "Description[pt_BR]": "Brincando com efeitos visuais", + "Description[ru]": "Примеры визуальных эффектов", + "Description[sa]": "दृश्यप्रभावैः सह Futzing", + "Description[sk]": "Hranie sa s vizuálnymi efektmi", + "Description[sl]": "Preigravanje z vizualnimi učinki", + "Description[sv]": "Greja med visuella effekter", + "Description[tr]": "Görsel Efektlerle Oynaşma", + "Description[uk]": "Маніпулювання візуальними ефектами", + "Description[vi]": "Thá»­ các hiệu ứng trá»±c quan", + "Description[x-test]": "xxFutzing with Visual Effectsxx", + "Description[zh_CN]": "测试各种视觉效果", + "Description[zh_TW]": "玩玩視覺效果", + "Icon": "plasma", + "Id": "org.kde.example.testshaders", + "License": "GPLv2+", + "Name": "Shader Test", + "Name[az]": "Şeyderin testi", + "Name[be]": "Тэставанне шэйдараў", + "Name[bg]": "Тест на шейдър", + "Name[ca@valencia]": "Prova de «shader»", + "Name[ca]": "Prova de «shader»", + "Name[de]": "Shadertest", + "Name[en_GB]": "Shader Test", + "Name[eo]": "Shader Testo", + "Name[es]": "Prueba de sombreado", + "Name[eu]": "Itzaldura-proba", + "Name[fi]": "Varjostustesti", + "Name[fr]": "Test de shader", + "Name[gl]": "Proba de sombreador", + "Name[he]": "בדיקת הצללה (Shader)", + "Name[hu]": "Árnyékolóteszt", + "Name[ia]": "Essayo de umbrator (Shader)", + "Name[id]": "Uji Shader", + "Name[it]": "Prova shader", + "Name[ka]": "შეიდეერის ტესტი", + "Name[ko]": "셰이더 테스트", + "Name[lv]": "Ēnotāja tests", + "Name[nl]": "Test van schaduw", + "Name[nn]": "Skuggar-test", + "Name[pl]": "Próba cieniowania", + "Name[pt]": "Teste de Sombreado", + "Name[pt_BR]": "Teste do sombreador", + "Name[ru]": "Проверка шейдера", + "Name[sa]": "शेडर परीक्षण", + "Name[sk]": "Test tieňovačov", + "Name[sl]": "Preizkus osenčevalnika", + "Name[sv]": "Skuggningstest", + "Name[tr]": "Gölgelendirici Sınaması", + "Name[uk]": "Тестування підпрограм побудови тіней", + "Name[vi]": "Kiểm thá»­ trình đánh bóng", + "Name[x-test]": "xxShader Testxx", + "Name[zh_CN]": "着色器测试", + "Name[zh_TW]": "著色器測試", + "Version": "", + "Website": "https://www.kde.org/" + }, + "Keywords": "", + "X-KDE-ParentApp": "" +} diff --git a/examples/applets/widgetgallery/contents/ui/Busy.qml b/examples/applets/widgetgallery/contents/ui/Busy.qml new file mode 100644 index 0000000..840ccda --- /dev/null +++ b/examples/applets/widgetgallery/contents/ui/Busy.qml @@ -0,0 +1,124 @@ +/* + SPDX-FileCopyrightText: 2011 Daker Fernandes Pinheiro + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.components as PlasmaComponents + +PlasmaComponents.Page { + height: childrenRect.height + property int implicitHeight: childrenRect.height + + tools: PlasmaComponents.ToolBarLayout { + spacing: 5 + PlasmaComponents.ToolButton { + visible: pageStack.depth > 1 + iconSource: "go-previous" + onClicked: pageStack.pop() + } + PlasmaComponents.ProgressBar { + value: 0.3 + } + PlasmaComponents.TextField { + clearButtonShown: true + text: "Busy widgets" + } + } + + Flickable { + id: flickable + contentWidth: column.width + contentHeight: column.height + clip: true + anchors.fill: parent + + Item { + width: Math.max(flickable.width, column.width) + height: column.height + Column { + id: column + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + PlasmaComponents.Label { + font.pixelSize: 20 + text: "Busy Indicator" + } + + PlasmaComponents.BusyIndicator { } + + PlasmaComponents.BusyIndicator { running: true } + + PlasmaComponents.Label { + font.pixelSize: 20 + text: "Progress Bar" + } + + PlasmaComponents.Label { text: "Horizontal" } + + PlasmaComponents.ProgressBar { + value: 0.3 + } + + PlasmaComponents.ProgressBar { + indeterminate: true + } + + PlasmaComponents.ProgressBar { + minimumValue: 0 + maximumValue: 100 + value: 30 + } + + PlasmaComponents.Label { text: "Vertical" } + Row { + spacing: 20 + PlasmaComponents.ProgressBar { + value: 0.3 + orientation: Qt.Vertical + width: 20 + height: 100 + } + PlasmaComponents.ProgressBar { + value: 0.4 + orientation: Qt.Vertical + width: 20 + height: 120 + } + PlasmaComponents.ProgressBar { + orientation: Qt.Vertical + width: 20 + height: 100 + indeterminate: true + } + } + } + } + } + + PlasmaComponents.ScrollBar { + id: horizontalScrollBar + + flickableItem: flickable + orientation: Qt.Horizontal + anchors { + left: parent.left + right: verticalScrollBar.left + bottom: parent.bottom + } + } + + PlasmaComponents.ScrollBar { + id: verticalScrollBar + + orientation: Qt.Vertical + flickableItem: flickable + anchors { + top: parent.top + right: parent.right + bottom: horizontalScrollBar.top + } + } +} diff --git a/examples/applets/widgetgallery/contents/ui/Buttons.qml b/examples/applets/widgetgallery/contents/ui/Buttons.qml new file mode 100644 index 0000000..bdb522b --- /dev/null +++ b/examples/applets/widgetgallery/contents/ui/Buttons.qml @@ -0,0 +1,171 @@ +/* + SPDX-FileCopyrightText: 2011 Daker Fernandes Pinheiro + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Controls as QQC2 +import org.kde.plasma.components as PlasmaComponents + +PlasmaComponents.Page { + height: childrenRect.height + tools: PlasmaComponents.ToolBarLayout { + spacing: 5 + PlasmaComponents.ToolButton { + visible: pageStack.depth > 1 + icon.name: "go-previous" + onClicked: pageStack.pop() + } + PlasmaComponents.Button { + text: "Button" + } + PlasmaComponents.TextField { + clearButtonShown: true + } + } + + Flickable { + id: flickable + contentWidth: column.width + contentHeight: column.height + clip: true + anchors.fill: parent + + Item { + width: Math.max(flickable.width, column.width) + height: column.height + Column { + id: column + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + PlasmaComponents.Label { + font.pixelSize: 20 + text: "Buttons" + } + + PlasmaComponents.Button { + id: bt1 + + text: "Button" + + onClicked: { + console.log("Clicked"); + pageStack.push(Qt.createComponent("Scrollers.qml")) + } + + Keys.onTabPressed: bt2.forceActiveFocus(); + } + + PlasmaComponents.Button { + id: bt2 + + text: "Checkable Button" + checkable: true + + onCheckedChanged: { + if (checked) + console.log("Button Checked"); + else + console.log("Button Unchecked"); + } + + Keys.onTabPressed: bt3.forceActiveFocus(); + } + + PlasmaComponents.Button { + id: bt3 + + text: "Different Font" + font { + pointSize: 20 + family: "Helvetica" + } + + Keys.onTabPressed: bt4.forceActiveFocus(); + } + + PlasmaComponents.Button { + id: bt4 + + text: "Icon Button" + icon.name: "konqueror" + + Keys.onTabPressed: bt5.forceActiveFocus(); + menu: QQC2.Menu { + QQC2.MenuItem { text: "This Button" } + QQC2.MenuItem { text: "Happens To Have" } + QQC2.MenuItem { text: "A Menu Assigned" } + } + } + + PlasmaComponents.Button { + id: bt5 + + icon.name: "plasma" + + Keys.onTabPressed: bt1.forceActiveFocus(); + } + + PlasmaComponents.Button { + + text: "Disabled Button" + enabled: false + } + + PlasmaComponents.ToolButton { + text: "ToolButton" + } + + PlasmaComponents.ToolButton { + text: "ToolButton not flat" + flat: false + } + + PlasmaComponents.ToolButton { + + text: "Icon ToolButton" + icon.name: "konqueror" + } + + PlasmaComponents.ToolButton { + icon.name: "plasma" + } + PlasmaComponents.ToolButton { + icon.name: "plasma" + flat: false + } + + PlasmaComponents.ToolButton { + text: "Disabled ToolButton" + enabled: false + } + } + } + } + + PlasmaComponents.ScrollBar { + id: horizontalScrollBar + + flickableItem: flickable + orientation: Qt.Horizontal + anchors { + left: parent.left + right: verticalScrollBar.left + bottom: parent.bottom + } + } + + PlasmaComponents.ScrollBar { + id: verticalScrollBar + + orientation: Qt.Vertical + flickableItem: flickable + anchors { + top: parent.top + right: parent.right + bottom: horizontalScrollBar.top + } + } +} diff --git a/examples/applets/widgetgallery/contents/ui/CheckableButtons.qml b/examples/applets/widgetgallery/contents/ui/CheckableButtons.qml new file mode 100644 index 0000000..6e331b4 --- /dev/null +++ b/examples/applets/widgetgallery/contents/ui/CheckableButtons.qml @@ -0,0 +1,152 @@ +/* + SPDX-FileCopyrightText: 2011 Daker Fernandes Pinheiro + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.components as PlasmaComponents + + +PlasmaComponents.Page { + + tools: PlasmaComponents.ToolBarLayout { + spacing: 5 + PlasmaComponents.ToolButton { + visible: pageStack.depth > 1 + iconSource: "go-previous" + onClicked: pageStack.pop() + } + PlasmaComponents.CheckBox { + text: "Checkbox in the toolbar" + } + PlasmaComponents.TextField { + clearButtonShown: true + text: "hello" + } + } + + Flickable { + id: flickable + contentWidth: column.width + contentHeight: column.height + clip: true + anchors.fill: parent + + Item { + width: Math.max(flickable.width, column.width) + height: column.height + Column { + id: column + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + PlasmaComponents.Label { + font.pixelSize: 20 + text: "Check Box" + } + + PlasmaComponents.CheckBox { + width: 140 + height: 30 + text: "Check Box 1" + + onCheckedChanged: { + if (checked) + console.log("CheckBox checked"); + else + console.log("CheckBox unchecked"); + } + onClicked: { + console.log("CheckBox clicked"); + } + } + + PlasmaComponents.CheckBox { + height: 30 + text: "Disabled" + enabled: false + } + + PlasmaComponents.CheckBox { + height: 30 + text: "" + } + + PlasmaComponents.CheckBox { + height: 30 + text: "A loooooooooooooong text" + } + + PlasmaComponents.Label { + font.pixelSize: 20 + text: "Radio Button" + } + + PlasmaComponents.RadioButton { + width: 140 + height: 30 + text: "RadioButton" + + onCheckedChanged: { + if (checked) + console.log("RadioButton Checked"); + else + console.log("RadioButton Unchecked"); + } + } + + PlasmaComponents.Switch { } + + PlasmaComponents.Label { + font.pixelSize: 20 + text: "Button Row" + } + + PlasmaComponents.ButtonRow { + spacing: 20 + PlasmaComponents.RadioButton { text: "A" } + PlasmaComponents.RadioButton { text: "B" } + PlasmaComponents.RadioButton { text: "C" } + } + + PlasmaComponents.Label { + font.pixelSize: 20 + text: "Button Column" + } + + PlasmaComponents.ButtonColumn { + spacing: 20 + PlasmaComponents.RadioButton { text: "Alice" } + PlasmaComponents.RadioButton { text: "Bob" } + PlasmaComponents.RadioButton { text: "Charles" } + } + + } + } + } + + PlasmaComponents.ScrollBar { + id: horizontalScrollBar + + flickableItem: flickable + orientation: Qt.Horizontal + anchors { + left: parent.left + right: verticalScrollBar.left + bottom: parent.bottom + } + } + + PlasmaComponents.ScrollBar { + id: verticalScrollBar + + orientation: Qt.Vertical + flickableItem: flickable + anchors { + top: parent.top + right: parent.right + bottom: horizontalScrollBar.top + } + } +} diff --git a/examples/applets/widgetgallery/contents/ui/Menu.qml b/examples/applets/widgetgallery/contents/ui/Menu.qml new file mode 100644 index 0000000..500c8f3 --- /dev/null +++ b/examples/applets/widgetgallery/contents/ui/Menu.qml @@ -0,0 +1,73 @@ +/* + SPDX-FileCopyrightText: 2011 Daker Fernandes Pinheiro + SPDX-FileCopyrightText: 2011 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.components + +Page { + ListView { + id: pageSelector + clip: true + anchors.fill: parent + + model: ListModel { + id: pagesModel + ListElement { + page: "Buttons.qml" + title: "Buttons" + } + ListElement { + page: "CheckableButtons.qml" + title: "Checkable buttons" + } + ListElement { + page: "Busy.qml" + title: "Busy indicators" + } + ListElement { + page: "Sliders.qml" + title: "Sliders" + } + ListElement { + page: "Scrollers.qml" + title: "Scrollers" + } + ListElement { + page: "Texts.qml" + title: "Text elements" + } + ListElement { + page: "Typography.qml" + title: "Typography" + } + ListElement { + page: "Misc.qml" + title: "Misc stuff" + } + } + delegate: ListItem { + enabled: true + Column { + Label { + text: title + } + } + onClicked: pageStack.push(Qt.createComponent(page)) + } + } + ScrollBar { + id: verticalScrollBar + + orientation: Qt.Vertical + flickableItem: pageSelector + anchors { + top: parent.top + right: parent.right + bottom: parent.bottom + } + } +} diff --git a/examples/applets/widgetgallery/contents/ui/Misc.qml b/examples/applets/widgetgallery/contents/ui/Misc.qml new file mode 100644 index 0000000..caf8a23 --- /dev/null +++ b/examples/applets/widgetgallery/contents/ui/Misc.qml @@ -0,0 +1,643 @@ +/* + SPDX-FileCopyrightText: 2011 Nokia Corporation and /or its subsidiary(-ies) + + This file is part of the Qt Components project. + + SPDX-License-Identifier: BSD-3-Clause +*/ + +import QtQuick +import org.kde.plasma.components +import org.kde.plasma.extras as PlasmaExtras + + +Page { + implicitWidth: childrenRect.width + implicitHeight: childrenRect.height + tools: Row { + spacing: 5 + ToolButton { + visible: pageStack.depth > 1 + iconSource: "go-previous" + onClicked: pageStack.pop() + } + Button { + text: "Button" + } + } + + PlasmaExtras.ScrollArea { + anchors.fill: parent + Flickable { + id: flickable + contentWidth: column.width + contentHeight: column.height + clip: true + anchors.fill: parent + + Item { + width: Math.max(flickable.width, column.width) + height: column.height + Column { + id: column + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + // for demonstration and testing purposes each component needs to + // set its inverted state explicitly + property bool childrenInverted: false + property bool windowInverted: false + + Label { + anchors.horizontalCenter: parent.horizontalCenter + text: "Qt Components " + (enabled ? "(enabled)" : "(disabled)") + } + + Button { + anchors.horizontalCenter: parent.horizontalCenter + text: "Push me" + width: parent.width - parent.spacing + } + + TextField { + anchors.horizontalCenter: parent.horizontalCenter + placeholderText: "TextField" + width: parent.width - parent.spacing + } + + TextField { + id: clearable + clearButtonShown: true + anchors.horizontalCenter: parent.horizontalCenter + placeholderText: "Clearable TextField" + text: "Clearable TextField" + width: parent.width - parent.spacing + } + + TextField { + id: customOperation + anchors.horizontalCenter: parent.horizontalCenter + placeholderText: "Custom operation" + width: parent.width - parent.spacing + + Image { + id: addText + anchors { top: parent.top; right: parent.right } + smooth: true + fillMode: Image.PreserveAspectFit + source: "qrc:ok.svg" + height: parent.height; width: parent.height + scale: LayoutMirroring.enabled ? -1 : 1 + + MouseArea { + id: add + anchors.fill: parent + onClicked: textSelection.open() + } + + SelectionDialog { + id: textSelection + titleText: "Preset Texts" + selectedIndex: -1 + model: ListModel { + ListElement { name: "Lorem ipsum." } + ListElement { name: "Lorem ipsum dolor sit amet." } + ListElement { name: "Lorem ipsum dolor sit amet ipsum." } + } + + onAccepted: { + customOperation.text = textSelection.model.get(textSelection.selectedIndex).name + customOperation.forceActiveFocus() + } + + onRejected: selectedIndex = -1 + } + } + } + + TextArea { + anchors.horizontalCenter: parent.horizontalCenter + placeholderText: "This is a\n multiline control." + width: parent.width - parent.spacing; height: 280 + wrapMode: TextEdit.Wrap + } + + Slider { + anchors.horizontalCenter: parent.horizontalCenter + value: 50 + } + + ButtonRow { + anchors.horizontalCenter: parent.horizontalCenter + spacing: parent.spacing + + exclusive: true + + RadioButton { + } + + RadioButton { + } + } + + Row { + anchors.horizontalCenter: parent.horizontalCenter + spacing: parent.spacing + + CheckBox { + } + + CheckBox { + checked: true + } + } + + Switch { + anchors.horizontalCenter: parent.horizontalCenter + } + + ProgressBar { + anchors.horizontalCenter: parent.horizontalCenter + + Timer { + running: true + repeat: true + interval: 25 + onTriggered: parent.value = (parent.value + 1) % 1.1 + } + } + + ProgressBar { + anchors.horizontalCenter: parent.horizontalCenter + indeterminate: true + } + + Component { + id: dialogComponent + CommonDialog { + id: dialog + titleText: "CommonDialog" + buttonTexts: ["Ok", "Cancel"] + + content: Label { + text: "This is the content" + font { bold: true; pixelSize: 16 } + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + } + + Button { + property CommonDialog dialog + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width - parent.spacing + text: "CommonDialog" + onClicked: { + if (!dialog) + dialog = dialogComponent.createObject(column) + dialog.open() + } + } + + Component { + id: singleSelectionDialogComponent + SelectionDialog { + titleText: "Select background color" + selectedIndex: 1 + + model: ListModel { + id: colorModel + + ListElement { name: "Red" } + ListElement { name: "Blue" } + ListElement { name: "Green" } + ListElement { name: "Yellow" } + ListElement { name: "Black" } + ListElement { name: "White" } + ListElement { name: "Grey" } + ListElement { name: "Orange" } + ListElement { name: "Pink" } + } + + onAccepted: { selectionDialogButton.parent.color = colorModel.get(selectedIndex).name } + } + } + + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + height: selectionDialogButton.height + width: parent.width - parent.spacing + radius: 10 + + Button { + id: selectionDialogButton + property SelectionDialog singleSelectionDialog + anchors.centerIn: parent + text: "Selection Dialog" + onClicked: { + if (!singleSelectionDialog) + singleSelectionDialog = singleSelectionDialogComponent.createObject(column) + singleSelectionDialog.open() + } + } + } + + Button { + property QueryDialog queryDialog + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width - parent.spacing + text: "QueryDialog" + onClicked: { + if (!queryDialog) + queryDialog = queryDialogComponent.createObject(column) + queryDialog.open() + } + } + + Component { + id: queryDialogComponent + QueryDialog { + titleText: "Query Dialog" + // Arabic character in the beginning to test right-to-left UI alignment + message: (LayoutMirroring.enabled ? "\u062a" : "") + "Lorem ipsum dolor sit amet, consectetur adipisici elit," + + "sed eiusmod tempor incidunt ut labore et dolore magna aliqua." + + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris" + + "nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit" + + "in voluptate velit esse cillum dolore eu fugiat nulla pariatur." + + "Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui" + + "officia deserunt mollit anim id est laborum." + + acceptButtonText: "Ok" + rejectButtonText: "Cancel" + + titleIcon: "kmail" + } + } + + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + height: contentMenuButton.height + width: parent.width - parent.spacing + radius: 10 + + Button { + id: contentMenuButton + property ContextMenu contextMenu + anchors.horizontalCenter: parent.horizontalCenter + text: "ContextMenu" + onClicked: { + if (!contextMenu) + contextMenu = contextMenuComponent.createObject(contentMenuButton) + contextMenu.open() + } + } + } + + Component { + id: contextMenuComponent + ContextMenu { + visualParent: contentMenuButton + MenuItem { + text: "White" + onClicked: contentMenuButton.parent.color = "White" + } + MenuItem { + text: "Red" + onClicked: contentMenuButton.parent.color = "Red" + } + MenuItem { + text: "LightBlue" + onClicked: contentMenuButton.parent.color = "LightBlue" + } + MenuItem { + text: "LightGreen" + onClicked: contentMenuButton.parent.color = "LightGreen" + } + } + } + + ListView { + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width - parent.spacing; height: 120 + clip: true + delegate: listDelegate + model: listModel + header: listHeading + } + + ListModel { + id: listModel + + ListElement { + titleText: "Title" + subTitleText: "SubTitle" + } + ListElement { + titleText: "Title2" + subTitleText: "SubTitle" + } + ListElement { + titleText: "Title3" + subTitleText: "SubTitle" + } + } + + Component { + id: listHeading + Label { + text: "Heading" + } + } + + Component { + id: listDelegate + ListItem { + id: listItem + Column { + + Label { + text: titleText + } + Label { + text: subTitleText + } + } + } + } + + Label { + property SelectionDialog selectionDialog + text: { + if (selectionDialog) { + if (selectionDialog.selectedIndex >= 0) + return selectionDialog.model.get(selectionDialog.selectedIndex).name + } + return "Three" + } + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width - parent.spacing + + MouseArea { + anchors.fill: parent + onClicked: { + if (!selectionDialog) + selectionDialog = selectionDialogComponent.createObject(column) + selectionDialog.open() + } + } + + Component { + id: selectionDialogComponent + SelectionDialog { + titleText: "Select" + selectedIndex: 2 + model: ListModel { + ListElement { name: "One" } + ListElement { name: "Two" } + ListElement { name: "Three" } + ListElement { name: "Four" } + ListElement { name: "Five" } + ListElement { name: "Six" } + ListElement { name: "Seven" } + ListElement { name: "Eight" } + ListElement { name: "Nine" } + } + } + } + } + + + TabBar { + //width: parent.width - parent.spacing + //height: 50 + anchors.horizontalCenter: parent.horizontalCenter + TabButton { tab: tab1content; text: "1"; iconSource: "qrc:close_stop.svg"} + TabButton { tab: tab2content; text: "2"; iconSource: "konqueror"} + TabButton { tab: tab3content; text: "3"} + } + + TabGroup { + height: 100 + width: parent.width - parent.spacing + Button { id: tab1content; text: "tab1" } + Label { + id: tab2content + text: "tab2" + horizontalAlignment: "AlignHCenter" + verticalAlignment: "AlignVCenter" + } + Page { + id: tab3content + width: 50 + height: 32 + CheckBox { anchors.fill: parent; text: "tab3"} + } + } + + ToolButton { + id: toolButton + text: "ToolButton" + iconSource: "konqueror" + } + + ToolButton { + id: toolButton2 + flat: true + iconSource: "qrc:ok.svg" + } + + ToolButton { + id: toolButton3 + text: "ToolButton" + iconSource: "qrc:close_stop.svg" + } + + Row { + spacing: 5 + + BusyIndicator { + id: busyInd1 + width: 20 + height: 20 + running: true + } + + BusyIndicator { + // default width/height is 40 + id: busyInd2 + running: true + } + + BusyIndicator { + id: busyInd3 + width: 60 + height: 60 + running: true + } + + Button { + text: "Toggle" + onClicked: { + busyInd1.running = !busyInd1.running + busyInd2.running = !busyInd2.running + busyInd3.running = !busyInd3.running + } + } + } + + Button { + property CommonDialog sectionScroll + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width - parent.spacing + text: "SectionScroller" + iconSource: "konqueror" + onClicked: { + if (!sectionScroll) + sectionScroll = sectionScrollComponent.createObject(column) + sectionScroll.open() + } + } + + Component { + id: sectionScrollComponent + CommonDialog { + id: sectionScroll + titleText: "Section Scroller" + buttonTexts: ["Close"] + onButtonClicked: close() + + content: Rectangle { + color: Qr.rgba(1,1,1,0.8) + width: parent.width + implicitHeight: 300 + + ListModel { + id: testModel + ListElement { name: "A Cat 1"; alphabet: "A" } + ListElement { name: "A Cat 2"; alphabet: "A" } + ListElement { name: "Boo 1"; alphabet: "B" } + ListElement { name: "Boo 2"; alphabet: "B" } + ListElement { name: "Cat 1"; alphabet: "C" } + ListElement { name: "Cat 2"; alphabet: "C" } + ListElement { name: "Dog 1"; alphabet: "D" } + ListElement { name: "Dog 2"; alphabet: "D" } + ListElement { name: "Dog 3"; alphabet: "D" } + ListElement { name: "Dog 4"; alphabet: "D" } + ListElement { name: "Dog 5"; alphabet: "D" } + ListElement { name: "Dog 6"; alphabet: "D" } + ListElement { name: "Dog 7"; alphabet: "D" } + ListElement { name: "Dog 8"; alphabet: "D" } + ListElement { name: "Dog 9"; alphabet: "D" } + ListElement { name: "Dog 10"; alphabet: "D" } + ListElement { name: "Dog 11"; alphabet: "D" } + ListElement { name: "Dog 12"; alphabet: "D" } + ListElement { name: "Elephant 1"; alphabet: "E" } + ListElement { name: "Elephant 2"; alphabet: "E" } + ListElement { name: "FElephant 1"; alphabet: "F" } + ListElement { name: "FElephant 2"; alphabet: "F" } + ListElement { name: "Guinea pig"; alphabet: "G" } + ListElement { name: "Goose"; alphabet: "G" } + ListElement { name: "Horse"; alphabet: "H" } + ListElement { name: "Horse"; alphabet: "H" } + ListElement { name: "Parrot"; alphabet: "P" } + ListElement { name: "Parrot"; alphabet: "P" } + } + + PlasmaExtras.ScrollArea { + anchors.fill: parent + ListView { + id: list + anchors.fill: parent + clip: true + cacheBuffer: contentHeight + delegate: ListItem { + Label { + anchors { + top: parent.top; topMargin: 4 + left: parent.left; leftMargin: 4 + } + color: Qt.rgba(0,0,0,0.8) + text: name + " (index " + index + ")" + horizontalAlignment: Text.AlignLeft + } + } + + model: testModel + section.property: "alphabet" + section.criteria: ViewSection.FullString + section.delegate: ListItem { + sectionDelegate: true + Label { + anchors { + top: parent.top; topMargin: 4 + left: parent.left; leftMargin: 4 + } + color: Qt.rgba(0,0,0,0.8) + text: section + horizontalAlignment: Text.AlignLeft + font { bold: true; } + } + } + } + } + } + } + } + + ButtonRow { + id: buttonRow1 + width: parent.width - parent.spacing + exclusive: true + checkedButton: b2 + + Button { text: "b1" } + Button { text: "b2" } + Button { text: "b3" } + } + + ButtonRow { + id: buttonRow2 + width: parent.width - parent.spacing + exclusive: true + + ToolButton { text: "tb1" } + ToolButton { text: "tb2" } + } + ButtonRow { + id: buttonRow3 + exclusive: true + spacing: 0 + + ToolButton { flat:false; iconSource: "go-previous" } + ToolButton { flat:false; text: "tb2" } + ToolButton { flat:false; text: "tb3" } + ToolButton { flat:false; iconSource: "go-next" } + } + ButtonColumn { + id: buttonRow4 + exclusive: true + spacing: 0 + + ToolButton { flat:false; text: "tb1" } + ToolButton { flat:false; text: "tb2" } + ToolButton { flat:false; text: "tb3" } + ToolButton { flat:false; text: "tb4" } + } + + ButtonColumn { + id: buttonColumn + width: parent.width - parent.spacing + exclusive: true + + Button { text: "b4" } + Button { text: "b5" } + Button { text: "b6" } + Button { text: "b7" } + } + } + } + } + } + +} diff --git a/examples/applets/widgetgallery/contents/ui/Scrollers.qml b/examples/applets/widgetgallery/contents/ui/Scrollers.qml new file mode 100644 index 0000000..f5ca81d --- /dev/null +++ b/examples/applets/widgetgallery/contents/ui/Scrollers.qml @@ -0,0 +1,150 @@ +/* + SPDX-FileCopyrightText: 2011 Daker Fernandes Pinheiro + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.components as PlasmaComponents +import org.kde.plasma.extras as PlasmaExtras + +PlasmaComponents.Page { + height: childrenRect.height + property int implicitHeight: childrenRect.height + + tools: PlasmaComponents.ToolBarLayout { + spacing: 5 + PlasmaComponents.ToolButton { + visible: pageStack.depth > 1 + iconSource: "go-previous" + onClicked: pageStack.pop() + } + PlasmaComponents.ScrollBar { + orientation: Qt.Horizontal + interactive: true + flickableItem: scrollArea + width: 200 + } + PlasmaComponents.TextField { + clearButtonShown: true + text: "hello" + } + } + + PlasmaExtras.ScrollArea { + anchors.fill: parent + Flickable { + id: flickable + contentWidth: column.width + contentHeight: column.height + clip: true + anchors.fill: parent + + Item { + width: Math.max(flickable.width, column.width) + height: column.height + Column { + id: column + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + PlasmaComponents.Label { + font.pixelSize: 20 + text: "Scroll Bar" + } + + PlasmaExtras.ScrollArea { + width: 200 + height: 200 + ListView { + id: scrollList + + width: 200 + height: 200 + clip: true + model: 20 + delegate: PlasmaComponents.Label { + width: 200 + height: 30 + text: index + font.pixelSize: 18 + } + + Rectangle { + anchors.fill: parent + color: "grey" + opacity: 0.3 + } + } + } + + PlasmaComponents.Label { + font.pixelSize: 20 + text: "Scroll Decorator" + } + + Item { + width: 200 + height: 200 + PlasmaExtras.Highlight { anchors.fill: parent } + Flickable { + id: scrollArea + anchors.fill: parent + clip: true + contentWidth: 400 + contentHeight: 400 + + // Flickable Contents + Rectangle { + color: "green" + width: 100 + height: 100 + } + Rectangle { + x: 80 + y: 80 + color: "blue" + width: 200 + height: 200 + } + Rectangle { + x: 200 + y: 200 + color: "red" + width: 150 + height: 150 + } + } + + // Scroll Decorators + PlasmaComponents.ScrollBar { + orientation: Qt.Vertical + flickableItem: scrollArea + inverted: true + anchors { + top: scrollArea.top + right: scrollArea.right + bottom: scrollArea.bottom + } + PlasmaComponents.Label { + y: parent.height / 2 + x: 13 + rotation: -90 + text: "inverted" + } + } + PlasmaComponents.ScrollBar { + orientation: Qt.Horizontal + flickableItem: scrollArea + anchors { + left: scrollArea.left + right: scrollArea.right + bottom: scrollArea.bottom + } + } + } + } + } + } + } +} diff --git a/examples/applets/widgetgallery/contents/ui/Sliders.qml b/examples/applets/widgetgallery/contents/ui/Sliders.qml new file mode 100644 index 0000000..2b104d1 --- /dev/null +++ b/examples/applets/widgetgallery/contents/ui/Sliders.qml @@ -0,0 +1,168 @@ +/* + SPDX-FileCopyrightText: 2011 Daker Fernandes Pinheiro + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.components as PlasmaComponents + +PlasmaComponents.Page { + height: childrenRect.height + property int implicitHeight: childrenRect.height + + tools: PlasmaComponents.ToolBarLayout { + spacing: 5 + PlasmaComponents.ToolButton { + visible: pageStack.depth > 1 + iconSource: "go-previous" + onClicked: pageStack.pop() + } + PlasmaComponents.Slider { + width: 140 + enabled: true + } + PlasmaComponents.TextField { + clearButtonShown: true + text: "hello" + } + } + + Flickable { + id: flickable + contentWidth: column.width + contentHeight: column.height + clip: true + anchors.fill: parent + + Item { + width: Math.max(flickable.width, column.width) + height: column.height + Column { + id: column + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + PlasmaComponents.Label { + font.pixelSize: 20 + text: "Slider" + } + + + Column { + spacing: 10 + + PlasmaComponents.Label { text: "Color Selector"; font.pixelSize: 20 } + + PlasmaComponents.Label { text: "Red" } + + PlasmaComponents.Slider { + id: redSlider + height: 20 + width: 255 + orientation: Qt.Horizontal + minimumValue: 0 + maximumValue: 255 + stepSize: 10 + Keys.onTabPressed: greenSlider.forceActiveFocus() + } + + PlasmaComponents.Label { text: "Green" } + + PlasmaComponents.Slider { + id: greenSlider + height: 20 + width: 255 + orientation: Qt.Horizontal + minimumValue: 0 + maximumValue: 255 + tickmarksEnabled: true + stepSize: 10 + Keys.onTabPressed: blueSlider.forceActiveFocus() + } + + PlasmaComponents.Label { text: "Blue" } + + PlasmaComponents.Slider { + id: blueSlider + height: 20 + width: 255 + orientation: Qt.Horizontal + minimumValue: 0 + maximumValue: 255 + stepSize: 10 + Keys.onTabPressed: redSlider.forceActiveFocus() + } + + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width / 2 + height: width + color: Qt.rgba(redSlider.value / 255, greenSlider.value / 255, blueSlider.value / 255, 1) + } + } + + PlasmaComponents.Label { text: "Disabled Horizontal Slider" } + + PlasmaComponents.Slider { + id: horizontalSlider + width: 140 + height: 20 + enabled: false + } + + PlasmaComponents.Label { text: "Inverted Horizontal Slider" } + + PlasmaComponents.Slider { + id: invHorizontalSlider + width: 140 + height: 20 + inverted: true + enabled: true + } + + PlasmaComponents.Label { text: "Vertical Slider" } + + Row { + spacing: 30 + PlasmaComponents.Slider { + id: verticalSlider + width: 20 + height: 140 + orientation: Qt.Vertical + minimumValue: 10 + maximumValue: 1000 + stepSize: 50 + inverted: true + } + PlasmaComponents.Label { text: verticalSlider.value } + } + + } + } + } + + PlasmaComponents.ScrollBar { + id: horizontalScrollBar + + flickableItem: flickable + orientation: Qt.Horizontal + anchors { + left: parent.left + right: verticalScrollBar.left + bottom: parent.bottom + } + } + + PlasmaComponents.ScrollBar { + id: verticalScrollBar + + orientation: Qt.Vertical + flickableItem: flickable + anchors { + top: parent.top + right: parent.right + bottom: horizontalScrollBar.top + } + } +} diff --git a/examples/applets/widgetgallery/contents/ui/Texts.qml b/examples/applets/widgetgallery/contents/ui/Texts.qml new file mode 100644 index 0000000..fa0d11d --- /dev/null +++ b/examples/applets/widgetgallery/contents/ui/Texts.qml @@ -0,0 +1,151 @@ +/* + SPDX-FileCopyrightText: 2011 Daker Fernandes Pinheiro + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.components as PlasmaComponents +import org.kde.plasma.extras as PlasmaExtras + +PlasmaComponents.Page { + height: childrenRect.height + property int implicitHeight: childrenRect.height + + tools: PlasmaComponents.ToolBarLayout { + spacing: 5 + PlasmaComponents.ToolButton { + visible: pageStack.depth > 1 + iconSource: "go-previous" + onClicked: pageStack.pop() + } + PlasmaComponents.Label { + text: "Text label:" + } + PlasmaComponents.TextField { + placeholderText: "Place holder text" + } + PlasmaComponents.TextField { + clearButtonShown: true + text: "Text fields page" + } + } + + Flickable { + id: flickable + contentWidth: column.width + contentHeight: column.height + clip: true + anchors.fill: parent + + Item { + width: Math.max(flickable.width, column.width) + height: column.height + Column { + id: column + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + PlasmaComponents.Label { + text: "Text Fields" + font.pixelSize: 20 + } + + PlasmaExtras.Highlight { + width: 200 + height: 100 + Column { + spacing: 10 + Row { + PlasmaComponents.Label { + text: "Username: " + anchors.verticalCenter: tf1.verticalCenter + } + PlasmaComponents.TextField { + id: tf1 + placeholderText: "login" + Keys.onTabPressed: tf2.forceActiveFocus(); + } + } + + Row { + PlasmaComponents.Label { + text: "Password: " + anchors.verticalCenter: tf2.verticalCenter + } + PlasmaComponents.TextField { + id: tf2 + width: 120 + echoMode: TextInput.Password + Keys.onTabPressed: loginButton.forceActiveFocus(); + } + } + + PlasmaComponents.Button { + id: loginButton + text: "Login" + anchors { + right: parent.right + rightMargin: 0 + } + width: 100 + } + } + } + + PlasmaComponents.TextField { + width: 120 + placeholderText: "Disabled Text Field" + Keys.onTabPressed: loginButton.forceActiveFocus(); + enabled: false + } + + PlasmaComponents.Label { + text: "Text Area" + font.pixelSize: 20 + } + + PlasmaComponents.TextArea { + width: 200 + height: 200 + placeholderText: "Lorem ipsum et dolor" + wrapMode: TextEdit.WordWrap + contentMaxWidth: 400 + contentMaxHeight: 400 + } + + PlasmaComponents.TextArea { + width: 200 + height: 100 + enabled: false + wrapMode: TextEdit.WordWrap + text: "Disabled Text Area" + } + } + } + } + + PlasmaComponents.ScrollBar { + id: horizontalScrollBar + + flickableItem: flickable + orientation: Qt.Horizontal + anchors { + left: parent.left + right: verticalScrollBar.left + bottom: parent.bottom + } + } + + PlasmaComponents.ScrollBar { + id: verticalScrollBar + + orientation: Qt.Vertical + flickableItem: flickable + anchors { + top: parent.top + right: parent.right + bottom: horizontalScrollBar.top + } + } +} diff --git a/examples/applets/widgetgallery/contents/ui/Typography.qml b/examples/applets/widgetgallery/contents/ui/Typography.qml new file mode 100644 index 0000000..6f4bca5 --- /dev/null +++ b/examples/applets/widgetgallery/contents/ui/Typography.qml @@ -0,0 +1,167 @@ +/* + SPDX-FileCopyrightText: 2012 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.components as PlasmaComponents +import org.kde.plasma.extras as PlasmaExtras +import org.kde.kirigami as Kirigami + + +PlasmaComponents.Page { + implicitWidth: childrenRect.width + implicitHeight: childrenRect.height + tools: Row { + spacing: 5 + PlasmaComponents.ToolButton { + visible: pageStack.depth > 1 + iconSource: "go-previous" + onClicked: pageStack.pop() + } + Kirigami.Heading { + level: 1 + text: "Typography" + } + } + + PlasmaExtras.ScrollArea { + anchors.fill: parent + Flickable { + id: flickable + //contentWidth: column.width + contentHeight: column.height + clip: true + anchors.fill: parent + + Column { + id: column + width: parent.width + anchors { + //fill: parent + margins: 12 + } + spacing: 12 + + Kirigami.Heading { + level: 1 + text: "A Title" + } + + Repeater { + model: 5 + Kirigami.Heading { + level: index + 1 + text: "Header level " + (index + 1) + } + } + + Kirigami.Heading { + level: 1 + text: "Paragraphs" + } + + PlasmaComponents.Label { + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sit amet turpis eros, in luctus lectus. Curabitur pulvinar ligula at leo pellentesque non faucibus mauris elementum. Pellentesque convallis porttitor sodales. Maecenas risus erat, viverra blandit vestibulum eu, suscipit in est. Praesent quis mattis eros. Sed ante ante, adipiscing non gravida sed, ultrices ultrices urna. Etiam congue mattis convallis. Maecenas sollicitudin mauris at lorem aliquam in venenatis erat convallis. Fusce eleifend scelerisque porttitor. Praesent metus sapien, hendrerit ac congue eget, feugiat id enim. Morbi venenatis gravida felis, vitae varius nunc dictum a. Etiam accumsan, velit ac tempor convallis, leo nibh consequat purus, sit amet fringilla nisi mi et libero." + } + + PlasmaComponents.Label { + text: "Donec tincidunt justo eget nulla eleifend hendrerit. Ut eleifend erat nibh. Nunc sagittis tincidunt quam quis lobortis. Nam suscipit ultrices nulla. Suspendisse ullamcorper eleifend massa eu pharetra. Donec tempor iaculis elit, in suscipit velit tristique eu. Curabitur suscipit, lacus id pharetra dapibus, velit ante consectetur erat, ac dignissim quam arcu vitae diam. Suspendisse laoreet tortor nec dolor venenatis ultricies. Sed nunc erat, placerat non gravida sit amet, ullamcorper eu turpis. Nullam vestibulum lacus sed tellus fermentum mollis id at urna. Sed eleifend lobortis mollis. Donec lacus dolor, varius commodo gravida et, fringilla in justo. Nam gravida lorem in odio viverra elementum. Suspendisse non tellus at justo convallis placerat vel ac tellus. Nulla tristique tristique dui ut vestibulum." + } + + + Kirigami.Heading { + level: 1 + text: "TBD Components" + } + + PlasmaComponents.Label { + id: menuEntry + text: "Menu entry" + } + + PlasmaComponents.Label { + id: notificationHeader + text: "Notification header" + } + + PlasmaComponents.Label { + id: notificationContent + text: "Menu entry" + } + + PlasmaComponents.Label { + id: activeTab + text: "Active tab" + } + + PlasmaComponents.Label { + id: inactiveTab + text: "Intactive tab" + } + + PlasmaComponents.Label { + id: activeSelection + text: "Active selection" + } + + PlasmaComponents.Label { + id: inactiveSelection + text: "Inactive selection" + } + + PlasmaComponents.Label { + id: listItemPrimary + text: "List item: primary text" + } + + PlasmaComponents.Label { + id: listItemSub + text: "List item: secondary text" + } + + PlasmaComponents.Label { + id: listItemPrimarySelected + text: "List item: selected, primary text" + } + + PlasmaComponents.Label { + id: listItemPrimarySub + text: "List item: selected, secondary text" + } + + PlasmaComponents.Label { + id: widgetHeader + text: "Widget headers" + } + + PlasmaComponents.Label { + id: widgetContent + text: "Widget Content" + } + + PlasmaComponents.Label { + id: iconTextSelected + text: "Icon text, selected" + } + + PlasmaComponents.Label { + id: iconTextUnselected + text: "Icon text, unselected" + } + + PlasmaComponents.Label { + id: groupHeader + text: "Group Header" + } + + PlasmaComponents.Label { + id: groupContent + text: "Group Content" + } + } + } + } +} + diff --git a/examples/applets/widgetgallery/contents/ui/main.qml b/examples/applets/widgetgallery/contents/ui/main.qml new file mode 100644 index 0000000..229aaa9 --- /dev/null +++ b/examples/applets/widgetgallery/contents/ui/main.qml @@ -0,0 +1,43 @@ +/* + SPDX-FileCopyrightText: 2011 Daker Fernandes Pinheiro + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.plasmoid +import QtQuick.Layouts +import org.kde.plasma.components + +Item { + Plasmoid.switchWidth: 300 + Plasmoid.switchHeight: 400 + + Plasmoid.fullRepresentation: Item { + Layout.minimumWidth: 300 + Layout.minimumHeight: 400 + + ToolBar { + id: toolBar + z: 10 + anchors { + top: parent.top + left: parent.left + right: parent.right + } + } + + PageStack { + id: pageStack + toolBar: toolBar + clip: true + anchors { + top: toolBar.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + } + initialPage: Qt.createComponent("Menu.qml") + } + } +} diff --git a/examples/applets/widgetgallery/contents/ui/standalonemain.qml b/examples/applets/widgetgallery/contents/ui/standalonemain.qml new file mode 100644 index 0000000..e13d52b --- /dev/null +++ b/examples/applets/widgetgallery/contents/ui/standalonemain.qml @@ -0,0 +1,43 @@ +/* + SPDX-FileCopyrightText: 2011 Daker Fernandes Pinheiro + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.core +import org.kde.plasma.components + +FrameSvgItem { + width: 300 + height: 400 + imagePath: "widgets/background" + + + ToolBar { + id: toolBar + z: 10 + + anchors { + top: parent.top + left: parent.left + right: parent.right + margins: 10 + } + } + + PageStack { + id: pageStack + toolBar: toolBar + clip: true + anchors { + top: toolBar.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + margins: 10 + } + initialPage: Qt.createComponent("Menu.qml") + } +} diff --git a/examples/applets/widgetgallery/metadata.json b/examples/applets/widgetgallery/metadata.json new file mode 100644 index 0000000..16abed2 --- /dev/null +++ b/examples/applets/widgetgallery/metadata.json @@ -0,0 +1,138 @@ +{ + "KPackageStructure": "Plasma/Applet", + "KPlugin": { + "Authors": [ + { + "Email": "notmart@gmail.com", + "Name": "Marco Martin", + "Name[ar]": "ماركو مارتن", + "Name[ast]": "Marco Martin", + "Name[az]": "Marco Martin", + "Name[be]": "Marco Martin", + "Name[bg]": "Marco Martin", + "Name[ca@valencia]": "Marco Martin", + "Name[ca]": "Marco Martin", + "Name[cs]": "Marco Martin", + "Name[de]": "Marco Martin", + "Name[en_GB]": "Marco Martin", + "Name[eo]": "Marco Martin", + "Name[es]": "Marco Martin", + "Name[eu]": "Marco Martin", + "Name[fi]": "Marco Martin", + "Name[fr]": "Marco Martin", + "Name[gl]": "Marco Martin", + "Name[he]": "מרקו מרטין", + "Name[hu]": "Marco Martin", + "Name[ia]": "Marco Martin", + "Name[id]": "Marco Martin", + "Name[it]": "Marco Martin", + "Name[ka]": "Marco Martin", + "Name[ko]": "Marco Martin", + "Name[lv]": "Marco Martin", + "Name[nl]": "Marco Martin", + "Name[nn]": "Marco Martin", + "Name[pl]": "Marco Martin", + "Name[pt]": "Marco Martin", + "Name[pt_BR]": "Marco Martin", + "Name[ro]": "Marco Martin", + "Name[ru]": "Marco Martin", + "Name[sa]": "मार्को मार्टिन्", + "Name[sk]": "Marco Martin", + "Name[sl]": "Marco Martin", + "Name[sv]": "Marco Martin", + "Name[ta]": "மார்க்கோ மார்ட்டின்", + "Name[tr]": "Marco Martin", + "Name[uk]": "Marco Martin", + "Name[vi]": "Marco Martin", + "Name[x-test]": "xxMarco Martinxx", + "Name[zh_CN]": "Marco Martin", + "Name[zh_TW]": "Marco Martin" + } + ], + "Category": "Examples", + "Description": "Gallery of widgets done with Plasma QtComponents", + "Description[az]": "Plasmada QtComponents köməyi ilə reallaşan vidjetlər qalareyası", + "Description[be]": "галерэя віджэтаў, зробленых з дапамогай Plasma QtComponents", + "Description[bg]": "галерия от уиджети с QtComponents на Plasma", + "Description[ca@valencia]": "Galeria de ginys fets amb «QtComponents» de Plasma", + "Description[ca]": "Galeria de ginys fets amb el «QtComponents» del Plasma", + "Description[en_GB]": "gallery of widgets done with Plasma QtComponents", + "Description[eo]": "galerio de fenestraĵoj faritaj per Plasma QtComponents", + "Description[es]": "Galería de widgets realizada con QtComponents de Plasma", + "Description[eu]": "Plasmaren «QtComponents» erabiliz egindako trepeten galeria", + "Description[fi]": "Plasma QtComponentsilla tehty sovelmagalleria", + "Description[fr]": "galerie de composants graphiques, réalisées avec les composants Qt de Plasma", + "Description[gl]": "galería de trebellos feita con QtComponents de Plasma.", + "Description[he]": "גלריה של יישומונים עם QtComponents של פלזמה", + "Description[hu]": "A Plasma QtComponentscel készült elemek galériája", + "Description[ia]": "galleria de widget facite con Plasma QtComponents", + "Description[id]": "galeri widget yang dibuat dengan Plasma QtComponents", + "Description[it]": "galleria di widget realizzata con Plasma QtComponents", + "Description[ka]": "plasma QtComponents-ით დაწერილი ვიჯეტების გალერეა", + "Description[ko]": "Plasma QtComponents로 작성한 위젯 갤러리", + "Description[lv]": "galerija ar logdaļām veidota ar „Plasma“ „QtComponents“", + "Description[nl]": "galerij van widgets gemaakt met Plasma QtComponents", + "Description[nn]": "Galleri med element laga med Plasma QtComponents", + "Description[pl]": "galeria elementów interfejsu wykonana w QtComponents Plazmy", + "Description[pt]": "galeria de elementos criados com os QtComponents do Plasma", + "Description[pt_BR]": "Galeria de widgets feitos com Plasma QtComponents", + "Description[ro]": "galerie de controale făcute cu Plasma QtComponents", + "Description[ru]": "Галерея виджетов, реализованная при помощи QtComponents в Plasma", + "Description[sa]": "पलाज्मा QtComponents इत्यनेन कृतानां विजेट्-समूहानां मञ्चक", + "Description[sk]": "galéria miniaplikácií vytvorených pomocou Plasma QtComponents", + "Description[sl]": "galerija gradnikov izdelanih s Plasma QtComponents", + "Description[sv]": "galleri av grafiska komponenter skapade med Plasma Qt-komponenter", + "Description[tr]": "Plasma QtComponents ile yapılmış araç takımları galerisi", + "Description[uk]": "Галерея віджетів, створених за допомогою QtComponent-ів Плазми", + "Description[vi]": "nÆ¡i trưng bày các phụ kiện làm bằng QtComponents cá»§a Plasma", + "Description[x-test]": "xxgallery of widgets done with Plasma QtComponentsxx", + "Description[zh_CN]": "通过 Plasma Qt 组件实现的挂件展厅", + "Description[zh_TW]": "用 Plasma QtComponents 做的元件範例庫", + "EnabledByDefault": true, + "Icon": "preferences-desktop-theme", + "Id": "org.kde.example.widgetgallery", + "License": "GPL", + "Name": "Widgets gallery", + "Name[az]": "Vidjetlər qalareyası", + "Name[be]": "Галерэя віджэтаў", + "Name[bg]": "Галерия с уиджети", + "Name[ca@valencia]": "Galeria de ginys", + "Name[ca]": "Galeria de ginys", + "Name[cs]": "Galerie widgetů", + "Name[en_GB]": "Widgets gallery", + "Name[eo]": "Widgets galerio", + "Name[es]": "Galería de widgets", + "Name[eu]": "Trepeten galeria", + "Name[fi]": "Sovelmagalleria", + "Name[fr]": "Galerie de composants graphiques", + "Name[gl]": "Galería de trebellos", + "Name[he]": "גלריית יישומונים", + "Name[hu]": "Elemgaléria", + "Name[ia]": "Galeria de widget", + "Name[id]": "Galeri widget", + "Name[it]": "Galleria dei widget", + "Name[ka]": "ვიჯეტების გალერეა", + "Name[ko]": "위젯 갤러리", + "Name[lv]": "Logdaļu galerija", + "Name[nl]": "Galerij van widgets", + "Name[nn]": "Elementgalleri", + "Name[pl]": "Galeria elementów interfejsu", + "Name[pt]": "Galeria de elementos", + "Name[pt_BR]": "Galeria de widgets", + "Name[ro]": "Galerie de controale", + "Name[ru]": "Галерея виджетов", + "Name[sa]": "विजेटस् मञ्चक", + "Name[sk]": "Galéria miniaplikácií", + "Name[sl]": "Galerija gradnikov", + "Name[sv]": "Grafiskt komponentgalleri", + "Name[ta]": "பிளாஸ்மாய்டு காட்சியகம்", + "Name[tr]": "Araç takımları galerisi", + "Name[uk]": "Галерея віджетів", + "Name[vi]": "Bộ sưu tập phụ kiện", + "Name[x-test]": "xxWidgets galleryxx", + "Name[zh_CN]": "挂件展厅", + "Name[zh_TW]": "元件範例庫", + "Version": "1.0", + "Website": "https://www.kde.org/" + } +} diff --git a/examples/applets/widgetgallery/platformcontents/application/tablet/ui/main.qml b/examples/applets/widgetgallery/platformcontents/application/tablet/ui/main.qml new file mode 100644 index 0000000..576f2a6 --- /dev/null +++ b/examples/applets/widgetgallery/platformcontents/application/tablet/ui/main.qml @@ -0,0 +1,111 @@ +/* + SPDX-FileCopyrightText: 2011 Daker Fernandes Pinheiro + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.plasmoid +import org.kde.plasma.components + +Image { + Layout.minimumWidth: 300 + Layout.minimumHeight: 400 + source: "image://appbackgrounds/standard" + fillMode: Image.Tile + asynchronous: true + + ToolBar { + id: toolBar + anchors { + top: parent.top + left: parent.left + right: parent.right + } + } + + + Image { + id: sidebar + source: "image://appbackgrounds/contextarea" + fillMode: Image.Tile + asynchronous: true + width: 200 + z: 10 + anchors { + top: toolBar.bottom + bottom: parent.bottom + } + Image { + source: "image://appbackgrounds/shadow-right" + fillMode: Image.Tile + anchors { + left: parent.right + top: parent.top + bottom: parent.bottom + leftMargin: -1 + } + } + + ListView { + id: pageSelector + clip: true + anchors.fill: parent + + model: ListModel { + id: pagesModel + ListElement { + page: "Buttons.qml" + title: "Buttons" + } + ListElement { + page: "CheckableButtons.qml" + title: "Checkable buttons" + } + ListElement { + page: "Busy.qml" + title: "Busy indicators" + } + ListElement { + page: "Sliders.qml" + title: "Sliders" + } + ListElement { + page: "Scrollers.qml" + title: "Scrollers" + } + ListElement { + page: "Texts.qml" + title: "Text elements" + } + ListElement { + page: "Misc.qml" + title: "Misc stuff" + } + } + delegate: ListItem { + enabled: true + Column { + Label { + text: title + } + } + onClicked: pageStack.replace(Qt.createComponent(Plasmoid.file("ui", page))) + } + } + } + + + PageStack { + id: pageStack + toolBar: toolBar + anchors { + top: toolBar.bottom + left: sidebar.right + right: parent.right + bottom: parent.bottom + } + initialPage: Qt.createComponent("Buttons.qml") + } + +} diff --git a/examples/applets/widgetgallery/widgetgallery-tablet b/examples/applets/widgetgallery/widgetgallery-tablet new file mode 100755 index 0000000..a16aab8 --- /dev/null +++ b/examples/applets/widgetgallery/widgetgallery-tablet @@ -0,0 +1,5 @@ +#!/bin/sh + +export PLASMA_CUSTOM_PREFIX_PATHS=platformcontents/application/generic/:platformcontents/application/tablet/:contents/ + +plasmoidviewer -graphicssystem raster org.kde.example.widgetgallery diff --git a/examples/containments/CMakeLists.txt b/examples/containments/CMakeLists.txt new file mode 100644 index 0000000..aa52568 --- /dev/null +++ b/examples/containments/CMakeLists.txt @@ -0,0 +1,2 @@ + +plasma_install_package(testcontainment org.kde.example.testcontainment plasmoids containment) diff --git a/examples/containments/testcontainment/contents/ui/PlasmoidContainer.qml b/examples/containments/testcontainment/contents/ui/PlasmoidContainer.qml new file mode 100644 index 0000000..2ee4a06 --- /dev/null +++ b/examples/containments/testcontainment/contents/ui/PlasmoidContainer.qml @@ -0,0 +1,14 @@ +/* + SPDX-FileCopyrightText: 2015 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick + +Item { + id: plasmoidContainer + width: 300 + height: 300 + property Item applet +} diff --git a/examples/containments/testcontainment/contents/ui/main.qml b/examples/containments/testcontainment/contents/ui/main.qml new file mode 100644 index 0000000..7b8030c --- /dev/null +++ b/examples/containments/testcontainment/contents/ui/main.qml @@ -0,0 +1,40 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import org.kde.plasma.components as PlasmaComponents +import org.kde.plasma.plasmoid + +Item { + id: root + width: 640 + height: 480 + + property Item toolBox + + function addApplet(applet, x, y) { + var component = Qt.createComponent("PlasmoidContainer.qml") + var plasmoidContainer = component.createObject(root, {"x": x, "y": y}); + + plasmoidContainer.parent = root; + plasmoidContainer.applet = applet + applet.parent = plasmoidContainer + applet.anchors.fill = plasmoidContainer + applet.visible = true + plasmoidContainer.visible = true + + } + + Containment.onAppletAdded: { + addApplet(applet, x, y); + } + + Component.onCompleted: { + print("Test Containment loaded") + print(plasmoid) + } +} diff --git a/examples/containments/testcontainment/metadata.json b/examples/containments/testcontainment/metadata.json new file mode 100644 index 0000000..b692fc4 --- /dev/null +++ b/examples/containments/testcontainment/metadata.json @@ -0,0 +1,130 @@ +{ + "KPackageStructure": "Plasma/Applet", + "KPlugin": { + "Authors": [ + { + "Email": "mart@kde.org", + "Name": "Marco Martin", + "Name[ar]": "ماركو مارتن", + "Name[ast]": "Marco Martin", + "Name[az]": "Marco Martin", + "Name[be]": "Marco Martin", + "Name[bg]": "Marco Martin", + "Name[ca@valencia]": "Marco Martin", + "Name[ca]": "Marco Martin", + "Name[cs]": "Marco Martin", + "Name[de]": "Marco Martin", + "Name[en_GB]": "Marco Martin", + "Name[eo]": "Marco Martin", + "Name[es]": "Marco Martin", + "Name[eu]": "Marco Martin", + "Name[fi]": "Marco Martin", + "Name[fr]": "Marco Martin", + "Name[gl]": "Marco Martin", + "Name[he]": "מרקו מרטין", + "Name[hu]": "Marco Martin", + "Name[ia]": "Marco Martin", + "Name[id]": "Marco Martin", + "Name[it]": "Marco Martin", + "Name[ka]": "Marco Martin", + "Name[ko]": "Marco Martin", + "Name[lv]": "Marco Martin", + "Name[nl]": "Marco Martin", + "Name[nn]": "Marco Martin", + "Name[pl]": "Marco Martin", + "Name[pt]": "Marco Martin", + "Name[pt_BR]": "Marco Martin", + "Name[ro]": "Marco Martin", + "Name[ru]": "Marco Martin", + "Name[sa]": "मार्को मार्टिन्", + "Name[sk]": "Marco Martin", + "Name[sl]": "Marco Martin", + "Name[sv]": "Marco Martin", + "Name[ta]": "மார்க்கோ மார்ட்டின்", + "Name[tr]": "Marco Martin", + "Name[uk]": "Marco Martin", + "Name[vi]": "Marco Martin", + "Name[x-test]": "xxMarco Martinxx", + "Name[zh_CN]": "Marco Martin", + "Name[zh_TW]": "Marco Martin" + } + ], + "Category": "", + "Description": "Test Containment", + "Description[bg]": "Тест на съдържание", + "Description[ca@valencia]": "Contenidor de prova", + "Description[ca]": "Contenidor de prova", + "Description[de]": "Containment testen", + "Description[eo]": "Testi Retenon", + "Description[es]": "Prueba de contenedor", + "Description[eu]": "Proba konfinamendu", + "Description[fi]": "Testisäilö", + "Description[fr]": "Tester un confinement", + "Description[gl]": "Contedor de proba.", + "Description[he]": "בדיקת בלימה", + "Description[hu]": "Tároló tesztelése", + "Description[ia]": "Essayo de Containment", + "Description[it]": "Prova del contenitore", + "Description[ka]": "შეკავების ტესტი", + "Description[ko]": "테스트 컨테이너", + "Description[lv]": "Ietvēruma tests", + "Description[nl]": "Container testen", + "Description[pl]": "Próba pojemnika", + "Description[pt_BR]": "Teste de contêiner", + "Description[ru]": "Тест контейнеров", + "Description[sa]": "परीक्षण निरोधः", + "Description[sl]": "Preizkus vsebnika", + "Description[tr]": "Sınama Kapsayıcısı", + "Description[uk]": "Тест контейнера", + "Description[vi]": "Phần bao chứa kiểm thá»­", + "Description[x-test]": "xxTest Containmentxx", + "Description[zh_CN]": "测试容器", + "Description[zh_TW]": "測試容器", + "Id": "org.kde.example.testcontainment", + "License": "GPLv2+", + "Name": "Containment Test", + "Name[az]": "Konteyner testi", + "Name[be]": "Тэставанне кантэйнера", + "Name[bg]": "Тест на съдържание", + "Name[ca@valencia]": "Prova de contenidor", + "Name[ca]": "Prova de contenidor", + "Name[de]": "Containment-Test", + "Name[en_GB]": "Containment Test", + "Name[eo]": "Tena Testo", + "Name[es]": "Prueba de contenedor", + "Name[eu]": "Konfinamendu-proba", + "Name[fi]": "Säilötesti", + "Name[fr]": "Test de confinement", + "Name[gl]": "Proba de contedor", + "Name[he]": "בדיקת בלימה", + "Name[hu]": "Tárolóteszt", + "Name[ia]": "Essayo de Containment", + "Name[id]": "Uji Containment", + "Name[it]": "Prova del contenitore", + "Name[ka]": "შეკავების ტესტი", + "Name[ko]": "컨테이너 테스트", + "Name[lv]": "Ietvēruma tests", + "Name[nl]": "Test van container", + "Name[nn]": "Behaldartest", + "Name[pl]": "Próba pojemnika", + "Name[pt]": "Teste do Contentor", + "Name[pt_BR]": "Teste de contêiner", + "Name[ro]": "Test container", + "Name[ru]": "Тест контейнеров", + "Name[sa]": "निरोध परीक्षण", + "Name[sk]": "Test obmedzenia", + "Name[sl]": "Preizkus vsebnikov", + "Name[sv]": "Omgivningstest", + "Name[ta]": "கொள்ளிட சோதனை", + "Name[tr]": "Kapsama Sınaması", + "Name[uk]": "Перевірка контейнера", + "Name[vi]": "Kiểm thá»­ việc bao chứa", + "Name[x-test]": "xxContainment Testxx", + "Name[zh_CN]": "容器测试", + "Name[zh_TW]": "容器測試", + "Version": "", + "Website": "https://www.kde.org/" + }, + "Keywords": "", + "X-KDE-ParentApp": "" +} diff --git a/examples/developerguide/CMakeLists.txt b/examples/developerguide/CMakeLists.txt new file mode 100644 index 0000000..bf5315a --- /dev/null +++ b/examples/developerguide/CMakeLists.txt @@ -0,0 +1,2 @@ +#plasma_install_package(basic org.kde.example.developerguide.basic) + diff --git a/examples/developerguide/basic/contents/ui/main.qml b/examples/developerguide/basic/contents/ui/main.qml new file mode 100644 index 0000000..39e108b --- /dev/null +++ b/examples/developerguide/basic/contents/ui/main.qml @@ -0,0 +1,82 @@ +/* + SPDX-FileCopyrightText: 2015 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls as QQC2 +import org.kde.kirigami as Kirigami + +Item { + + // Initial size of the window in gridUnits + width: Kirigami.Units.gridUnit * 28 + height: Kirigami.Units.gridUnit * 20 + + // We use a ColumnLayout to position and size the individual items + ColumnLayout { + + // Our ColumnLayout is fills the parent item with a bit of margin + anchors { + fill: parent + margins: Kirigami.Units.gridUnit + } + + spacing: Kirigami.Units.gridUnit + + // A title on top + Kirigami.Heading { + level: 1 // from 1 to 5; level 1 is the size used for titles + text: i18n("Hello Plasma World!") + } + + // The central area is a rectangle + Rectangle { + // The id is used to reference this item from the + // button's onClicked function + id: colorRect + + // It's supposed to grow in both direction + Layout.fillWidth: true + Layout.fillHeight: true + } + + // A button to change the color to blue or green + QQC2.Button { + + // The button is aligned to the right + Layout.alignment: Qt.AlignRight + + // The button's label, ready for translations + text: i18n("Change Color") + + onClicked: { + // Simply switch colors of the rectangle around + if (colorRect.color != "#b0c4de") { + colorRect.color = "#b0c4de"; // lightsteelblue + } else { + colorRect.color = "lightgreen"; + } + // This message will end up being printed to the terminal + print("Color is now " + colorRect.color); + } + } + } + + // Overlay everything with a decorative, large, translucent icon + Kirigami.Icon { + + // We use an anchor layout and dpi-corrected sizing + width: Kirigami.Units.iconSizes.large * 4 + height: width + anchors { + left: parent.left + bottom: parent.bottom + } + + source: "akregator" + opacity: 0.1 + } +} diff --git a/examples/developerguide/basic/metadata.json b/examples/developerguide/basic/metadata.json new file mode 100644 index 0000000..eadcd31 --- /dev/null +++ b/examples/developerguide/basic/metadata.json @@ -0,0 +1,140 @@ +{ + "KPackageStructure": "KPackage/GenericQML", + "KPlugin": { + "Authors": [ + { + "Email": "sebas@kde.org", + "Name": "Sebastian Kügler", + "Name[ar]": "Sebastian Kügler", + "Name[az]": "Sebastian Kügler", + "Name[be]": "Sebastian Kügler", + "Name[bg]": "Sebastian Kügler", + "Name[ca@valencia]": "Sebastian Kügler", + "Name[ca]": "Sebastian Kügler", + "Name[cs]": "Sebastian Kügler", + "Name[de]": "Sebastian Kügler", + "Name[en_GB]": "Sebastian Kügler", + "Name[eo]": "Sebastian Kügler", + "Name[es]": "Sebastian Kügler", + "Name[eu]": "Sebastian Kügler", + "Name[fi]": "Sebastian Kügler", + "Name[fr]": "Sebastian Kügler", + "Name[gl]": "Sebastian Kügler", + "Name[he]": "סבסטיאן קיגלר", + "Name[hu]": "Sebastian Kügler", + "Name[ia]": "Sebastian Kügler", + "Name[id]": "Sebastian Kügler", + "Name[it]": "Sebastian Kügler", + "Name[ka]": "Sebastian Kügler", + "Name[ko]": "Sebastian Kügler", + "Name[lv]": "Sebastian Kügler", + "Name[nl]": "Sebastian Kügler", + "Name[nn]": "Sebastian Kügler", + "Name[pl]": "Sebastian Kügler", + "Name[pt]": "Sebastian Kügler", + "Name[pt_BR]": "Sebastian Kügler", + "Name[ro]": "Sebastian Kügler", + "Name[ru]": "Sebastian Kügler", + "Name[sa]": "सेबास्टियन कुग्लर", + "Name[sk]": "Sebastian Kügler", + "Name[sl]": "Sebastian Kügler", + "Name[sv]": "Sebastian Kügler", + "Name[ta]": "ஸெபாஸ்டியன் கூக்லர்", + "Name[tr]": "Sebastian Kügler", + "Name[uk]": "Sebastian Kügler", + "Name[vi]": "Sebastian Kügler", + "Name[x-test]": "xxSebastian Küglerxx", + "Name[zh_CN]": "Sebastian Kügler", + "Name[zh_TW]": "Sebastian Kügler" + } + ], + "Category": "Development", + "Description": "Basic App", + "Description[az]": "Əsas tətbiq", + "Description[be]": "Базавая праграма", + "Description[bg]": "Основни приложения", + "Description[ca@valencia]": "Aplicació bàsica", + "Description[ca]": "Aplicació bàsica", + "Description[cs]": "Základní aplikace", + "Description[de]": "Einfache Anwendung", + "Description[en_GB]": "Basic App", + "Description[eo]": "Baza Apo", + "Description[es]": "Aplicación básica", + "Description[eu]": "Oinarrizko aplikazioa", + "Description[fi]": "Perussovelma", + "Description[fr]": "Application de base", + "Description[gl]": "Aplicación básica.", + "Description[he]": "יישום בסיסי", + "Description[hu]": "Egyszerű alkalmazás", + "Description[ia]": "App Basic", + "Description[id]": "Aplikasi Dasar", + "Description[it]": "Applicazione di base", + "Description[ka]": "ჩვეულებრივი აპი", + "Description[ko]": "기본 앱", + "Description[lv]": "VienkārÅ¡a programma", + "Description[nl]": "Basis app", + "Description[nn]": "Grunnleggjande program", + "Description[pl]": "Podstawowa aplikacja", + "Description[pt]": "Aplicação Básica", + "Description[pt_BR]": "Aplicativo básico", + "Description[ro]": "Aplicație simplă", + "Description[ru]": "Простейшее приложение", + "Description[sa]": "मूलभूत अनुप्रयोग", + "Description[sk]": "Základná aplikácia", + "Description[sl]": "Osnovna aplikacija", + "Description[sv]": "Enkel applikation", + "Description[tr]": "Yalın Uygulama", + "Description[uk]": "Базова програма", + "Description[vi]": "Ứng dụng cÆ¡ bản", + "Description[x-test]": "xxBasic Appxx", + "Description[zh_CN]": "基本应用程序", + "Description[zh_TW]": "基礎的應用程式", + "Icon": "kbugbuster", + "Id": "org.kde.example.developerguide.basic", + "License": "LGPLv2+", + "Name": "Bug", + "Name[ar]": "علّة", + "Name[az]": "Xəta", + "Name[be]": "Хіба", + "Name[bg]": "Бъг", + "Name[ca@valencia]": "S'ha produït un error", + "Name[ca]": "Error", + "Name[cs]": "Chyba", + "Name[de]": "Fehler", + "Name[en_GB]": "Bug", + "Name[eo]": "Cimo", + "Name[es]": "Fallo", + "Name[eu]": "Akatsa", + "Name[fi]": "Ohjelmavirhe", + "Name[fr]": "Bogue", + "Name[gl]": "Fallo", + "Name[he]": "תקלה", + "Name[hu]": "Hiba", + "Name[ia]": "Bug", + "Name[id]": "Bug", + "Name[it]": "Bug", + "Name[ka]": "შეცდომა", + "Name[ko]": "버그", + "Name[lv]": "Kļūda", + "Name[nl]": "Bug", + "Name[nn]": "Feil", + "Name[pl]": "Błąd", + "Name[pt]": "Insecto", + "Name[pt_BR]": "Erro", + "Name[ro]": "Defect", + "Name[ru]": "Ошибка", + "Name[sa]": "दोष", + "Name[sk]": "Chyba", + "Name[sl]": "Hrošč", + "Name[sv]": "Fel", + "Name[ta]": "பிழை", + "Name[tr]": "Hata", + "Name[uk]": "Вада", + "Name[vi]": "Lỗi", + "Name[x-test]": "xxBugxx", + "Name[zh_CN]": "程序缺陷", + "Name[zh_TW]": "錯誤", + "Version": "1.0", + "Website": "https://www.kde.org" + } +} diff --git a/examples/shell/CMakeLists.txt b/examples/shell/CMakeLists.txt new file mode 100644 index 0000000..96254b7 --- /dev/null +++ b/examples/shell/CMakeLists.txt @@ -0,0 +1,19 @@ +add_executable(exampleplasmashell) + +target_sources(exampleplasmashell PRIVATE + customcorona.cpp + main.cpp +) + +target_link_libraries(exampleplasmashell + Qt6::Widgets + Qt6::Quick + Qt6::Qml + KF6::I18n + Plasma::PlasmaQuick + Plasma::Plasma + KF6::DBusAddons + KF6::Notifications + KF6::Package +) + diff --git a/examples/shell/customcorona.cpp b/examples/shell/customcorona.cpp new file mode 100644 index 0000000..543e043 --- /dev/null +++ b/examples/shell/customcorona.cpp @@ -0,0 +1,76 @@ +/* + SPDX-FileCopyrightText: 2015 Marco Martin + + SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +*/ + +#include "customcorona.h" +#include +#include + +#include +#include +#include + +CustomCorona::CustomCorona(QObject *parent) + : Plasma::Corona(parent) +{ + KPackage::Package package = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Shell")); + // applications that want to load a plasma scene would have to load their own shell.. TODO: have a simple shell in plasma-framework for this purpose? + package.setPath(QStringLiteral("org.kde.plasma.desktop")); + setKPackage(package); + + qmlRegisterUncreatableType("org.kde.plasma.shell", + 2, + 0, + "Desktop", + QStringLiteral("It is not possible to create objects of type Desktop")); + + m_view = new PlasmaQuick::ContainmentView(this); + m_view->setSource(package.fileUrl("views", QStringLiteral("Desktop.qml"))); + m_view->show(); + + load(); +} + +QRect CustomCorona::screenGeometry(int id) const +{ + Q_UNUSED(id); + // TODO? + return QRect(); +} + +void CustomCorona::load() +{ + loadLayout(QStringLiteral("exampleplasmashell-appletsrc")); + + bool desktopFound = false; + for (auto c : containments()) { + if (c->containmentType() == Plasma::Containment::Type::Desktop) { + desktopFound = true; + break; + } + } + + if (!desktopFound) { + qDebug() << "Loading default layout"; + Plasma::Containment *c = createContainment(QStringLiteral("org.kde.desktopcontainment")); + c->createApplet(QStringLiteral("org.kde.plasma.analogclock")); + saveLayout(QStringLiteral("exampleplasmashell-appletsrc")); + } + + // don't let containments to be removed + for (auto c : containments()) { + if (c->containmentType() == Plasma::Containment::Type::Desktop) { + // example of a shell without a wallpaper + c->setWallpaperPlugin(QStringLiteral("null")); + m_view->setContainment(c); + if (QAction *removeAction = c->internalAction(QStringLiteral("remove"))) { + removeAction->deleteLater(); + } + break; + } + } +} + +#include "moc_customcorona.cpp" diff --git a/examples/shell/customcorona.h b/examples/shell/customcorona.h new file mode 100644 index 0000000..84fc9e3 --- /dev/null +++ b/examples/shell/customcorona.h @@ -0,0 +1,28 @@ +/* + SPDX-FileCopyrightText: 2015 Marco Martin + + SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +*/ + +#ifndef CUSTOMCORONA_H +#define CUSTOMCORONA_H + +#include +#include + +class CustomCorona : public Plasma::Corona +{ + Q_OBJECT + +public: + explicit CustomCorona(QObject *parent = nullptr); + QRect screenGeometry(int id) const override; + +public Q_SLOTS: + void load(); + +private: + PlasmaQuick::ContainmentView *m_view; +}; + +#endif diff --git a/examples/shell/main.cpp b/examples/shell/main.cpp new file mode 100644 index 0000000..44cf7f5 --- /dev/null +++ b/examples/shell/main.cpp @@ -0,0 +1,37 @@ +/* + SPDX-FileCopyrightText: 2015 Marco Martin + + SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +*/ + +#include +#include +#include + +#include +#include + +#include "customcorona.h" + +int main(int argc, char **argv) +{ + QQuickWindow::setDefaultAlphaBuffer(true); + + QApplication app(argc, argv); + app.setApplicationVersion(QStringLiteral("1.0")); + app.setOrganizationDomain(QStringLiteral("kde.org")); + + KDBusService service(KDBusService::Unique); + + QCommandLineParser parser; + parser.setApplicationDescription(i18n("Plasma Example shell")); + parser.addVersionOption(); + parser.addHelpOption(); + parser.process(app); + + CustomCorona *corona = new CustomCorona(); + + const int ret = app.exec(); + delete corona; + return ret; +} diff --git a/examples/testcontainmentactionsplugin/CMakeLists.txt b/examples/testcontainmentactionsplugin/CMakeLists.txt new file mode 100644 index 0000000..38798f6 --- /dev/null +++ b/examples/testcontainmentactionsplugin/CMakeLists.txt @@ -0,0 +1,23 @@ +remove_definitions(-DTRANSLATION_DOMAIN=\"libplasma6\") # Undo the global domain +add_definitions(-DTRANSLATION_DOMAIN=\"plasma_containmentactions_test\") + +set(plasma_containmentactions_test_SRCS + test.cpp + test.h +) +ki18n_wrap_ui(plasma_containmentactions_test_SRCS config.ui) + +kcoreaddons_add_plugin(plasma_containmentactions_test + SOURCES ${plasma_containmentactions_test_SRCS} + INSTALL_NAMESPACE "plasma/containmentactions" +) + +set_target_properties(plasma_containmentactions_test PROPERTIES + OUTPUT_NAME org.kde.test +) + +target_link_libraries(plasma_containmentactions_test + Qt::Widgets + Plasma::Plasma + KF6::I18n +) diff --git a/examples/testcontainmentactionsplugin/config.ui b/examples/testcontainmentactionsplugin/config.ui new file mode 100644 index 0000000..a58b904 --- /dev/null +++ b/examples/testcontainmentactionsplugin/config.ui @@ -0,0 +1,27 @@ + + Config + + + + 0 + 0 + 355 + 100 + + + + + + + Text: + + + + + + + + + + + diff --git a/examples/testcontainmentactionsplugin/plasma-containmentactions-test.json b/examples/testcontainmentactionsplugin/plasma-containmentactions-test.json new file mode 100644 index 0000000..98a6ad4 --- /dev/null +++ b/examples/testcontainmentactionsplugin/plasma-containmentactions-test.json @@ -0,0 +1,109 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "chani@kde.org", + "Name": "Chani", + "Name[bg]": "Chani", + "Name[ca@valencia]": "Chani", + "Name[ca]": "Chani", + "Name[cs]": "Chani", + "Name[de]": "Chani", + "Name[eo]": "Ĉani", + "Name[es]": "Chani", + "Name[eu]": "Chani", + "Name[fi]": "Chani", + "Name[fr]": "Chani", + "Name[gl]": "Chani", + "Name[he]": "צ׳אני", + "Name[hu]": "Chani", + "Name[ia]": "Chani", + "Name[it]": "Chani", + "Name[ka]": "Chani", + "Name[ko]": "Chani", + "Name[lv]": "Chani", + "Name[nl]": "Chani", + "Name[pl]": "Chani", + "Name[pt_BR]": "Chani", + "Name[ru]": "Chani", + "Name[sa]": "चनि", + "Name[sl]": "Chani", + "Name[ta]": "இச்சானி", + "Name[tr]": "Çani", + "Name[uk]": "Chani", + "Name[vi]": "Chani", + "Name[x-test]": "xxChanixx", + "Name[zh_CN]": "Chani", + "Name[zh_TW]": "Chani" + } + ], + "Description": "A dummy plugin for testing", + "Description[bg]": "Тестов плъгин", + "Description[ca@valencia]": "Un connector simulat per a proves", + "Description[ca]": "Un connector simulat per a proves", + "Description[cs]": "FaleÅ¡ný zásuvný modul pro testování", + "Description[eo]": "Lokokupa kromprogramo por testado", + "Description[es]": "Un complemento simulado para pruebas", + "Description[eu]": "Probatarako gezurrezko plugin bat", + "Description[fi]": "Tyhjä liitännäinen testaamiseen", + "Description[fr]": "Un module externe vide pour du test", + "Description[gl]": "Un complemento para probas.", + "Description[he]": "תוסף דמה לבדיקה", + "Description[hu]": "Üres bővítmény teszteléshez", + "Description[ia]": "Un plugin vacue pro essayar", + "Description[it]": "Un'estensione finta di prova", + "Description[ka]": "უაზრო დამატება, ტესტირებისთვის", + "Description[ko]": "테스트용 뼈대 플러그인", + "Description[lv]": "TukÅ¡s spraudnis testēšanai", + "Description[nl]": "Een dummy plugin voor testen", + "Description[pl]": "Pusta wtyczka do wypróbowywania", + "Description[pt_BR]": "Um plugin fictício para testes", + "Description[ru]": "Тестовый модуль", + "Description[sa]": "परीक्षणार्थं एकं नकली प्लगिन्", + "Description[sl]": "Slepi vtičnik za preizkus", + "Description[tr]": "Sınama için bir boş eklenti", + "Description[uk]": "Додаток для тестування", + "Description[vi]": "Một phần cài cắm nộm dùng cho kiểm thá»­", + "Description[x-test]": "xxA dummy plugin for testingxx", + "Description[zh_CN]": "测试用虚拟插件", + "Description[zh_TW]": "測試用的外掛程式", + "EnabledByDefault": true, + "Icon": "preferences-desktop-color", + "License": "GPL", + "Name": "Test", + "Name[bg]": "Изпробване", + "Name[ca@valencia]": "Prova", + "Name[ca]": "Prova", + "Name[cs]": "Test", + "Name[de]": "Test", + "Name[eo]": "Testo", + "Name[es]": "Prueba", + "Name[eu]": "Proba", + "Name[fi]": "Testi", + "Name[fr]": "Test", + "Name[gl]": "Proba", + "Name[he]": "בדיקה", + "Name[hu]": "Teszt", + "Name[ia]": "Essayo", + "Name[it]": "Prova", + "Name[ka]": "შემოწმება", + "Name[ko]": "테스트", + "Name[lv]": "Tests", + "Name[nl]": "Test", + "Name[pl]": "Próba", + "Name[pt_BR]": "Testar", + "Name[ru]": "Проверка", + "Name[sa]": "परीक्षणम्", + "Name[sl]": "Test", + "Name[ta]": "சோதனை", + "Name[tr]": "Sınama", + "Name[uk]": "Тест", + "Name[vi]": "Kiểm thá»­", + "Name[x-test]": "xxTestxx", + "Name[zh_CN]": "测试", + "Name[zh_TW]": "測試", + "Version": "pre0.1", + "Website": "https://plasma.kde.org/" + }, + "X-Plasma-HasConfigurationInterface": true +} diff --git a/examples/testcontainmentactionsplugin/test.cpp b/examples/testcontainmentactionsplugin/test.cpp new file mode 100644 index 0000000..ce82f17 --- /dev/null +++ b/examples/testcontainmentactionsplugin/test.cpp @@ -0,0 +1,66 @@ +/* + SPDX-FileCopyrightText: 2009 Chani Armitage + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "test.h" + +#include + +#include + +ContextTest::ContextTest(QObject *parent, const QVariantList &args) + : Plasma::ContainmentActions(parent, args) +{ +} + +QList ContextTest::contextualActions() +{ + return {}; +} + +void ContextTest::performNextAction() +{ + qWarning() << "Next action requested"; +} + +void ContextTest::performPreviousAction() +{ + qWarning() << "Previous action requested"; +} + +void ContextTest::init(const KConfigGroup &config) +{ + Q_UNUSED(config) +} + +QWidget *ContextTest::createConfigurationInterface(QWidget *parent) +{ + QWidget *widget = new QWidget(parent); + m_ui.setupUi(widget); + + m_ui.text->setText(m_text); + return widget; +} + +void ContextTest::configurationAccepted() +{ + m_text = m_ui.text->text(); +} + +void ContextTest::restore(const KConfigGroup &config) +{ + m_text = config.readEntry("test-text", QString()); +} + +void ContextTest::save(KConfigGroup &config) +{ + config.writeEntry("test-text", m_text); +} + +K_PLUGIN_CLASS_WITH_JSON(ContextTest, "plasma-containmentactions-test.json") + +#include "test.moc" + +#include "moc_test.cpp" diff --git a/examples/testcontainmentactionsplugin/test.h b/examples/testcontainmentactionsplugin/test.h new file mode 100644 index 0000000..63202bc --- /dev/null +++ b/examples/testcontainmentactionsplugin/test.h @@ -0,0 +1,38 @@ +/* + SPDX-FileCopyrightText: 2009 Chani Armitage + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef CONTEXTTEST_HEADER +#define CONTEXTTEST_HEADER + +#include "ui_config.h" +#include +#include + +class ContextTest : public Plasma::ContainmentActions +{ + Q_OBJECT +public: + ContextTest(QObject *parent, const QVariantList &args); + + void init(const KConfigGroup &config); + + QList contextualActions() override; + + void performNextAction() override; + void performPreviousAction() override; + + QWidget *createConfigurationInterface(QWidget *parent) override; + void configurationAccepted() override; + + void restore(const KConfigGroup &config) override; + void save(KConfigGroup &config) override; + +private: + Ui::Config m_ui; + QString m_text; +}; + +#endif diff --git a/examples/wallpapers/CMakeLists.txt b/examples/wallpapers/CMakeLists.txt new file mode 100644 index 0000000..1eb8318 --- /dev/null +++ b/examples/wallpapers/CMakeLists.txt @@ -0,0 +1,2 @@ + +plasma_install_package(autumn org.kde.autumn wallpapers wallpaper) diff --git a/examples/wallpapers/autumn/contents/config/main.xml b/examples/wallpapers/autumn/contents/config/main.xml new file mode 100644 index 0000000..bac72e5 --- /dev/null +++ b/examples/wallpapers/autumn/contents/config/main.xml @@ -0,0 +1,17 @@ + + + + + + + + 60 + 20 + 150 + + + + diff --git a/examples/wallpapers/autumn/contents/images/backgroundLeaves.jpg b/examples/wallpapers/autumn/contents/images/backgroundLeaves.jpg new file mode 100644 index 0000000000000000000000000000000000000000..08be16751df332a1ee862f9da4eb33679e0bad18 GIT binary patch literal 78665 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­<1OJqP2&5k^h|P#RQPx;qoSU%sa0t=uH;C7ycnw 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 literal 0 HcmV?d00001 diff --git a/examples/wallpapers/autumn/contents/images/realLeaf1.png b/examples/wallpapers/autumn/contents/images/realLeaf1.png new file mode 100644 index 0000000000000000000000000000000000000000..6cabf29efd22792f783b673c747ca4b4942ec8e0 GIT binary patch literal 15625 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∋EnQikYZR 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

*Z~mY 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 KMNUMnLSTY^-g|ri literal 0 HcmV?d00001 diff --git a/examples/wallpapers/autumn/contents/ui/config.qml b/examples/wallpapers/autumn/contents/ui/config.qml new file mode 100644 index 0000000..e1a885b --- /dev/null +++ b/examples/wallpapers/autumn/contents/ui/config.qml @@ -0,0 +1,29 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Controls as QtControls +import org.kde.kirigami as Kirigami + +Column { + id: root + property alias cfg_Speed: slider.value + + Row { + spacing: Kirigami.Units.largeSpacing + + QtControls.Label { + width: formAlignment - Kirigami.Units.largeSpacing * 2 + horizontalAlignment: Text.AlignRight + text: "Speed:" + } + QtControls.Slider { + id: slider + from: .2 + to: 1.5 + } + } +} diff --git a/examples/wallpapers/autumn/contents/ui/main.qml b/examples/wallpapers/autumn/contents/ui/main.qml new file mode 100644 index 0000000..d50d7eb --- /dev/null +++ b/examples/wallpapers/autumn/contents/ui/main.qml @@ -0,0 +1,135 @@ +/* + SPDX-FileCopyrightText: 2013 Digia Plc and /or its subsidiary(-ies) + + This file is part of the examples of the Qt Toolkit. + + SPDX-License-Identifier: BSD-3-Clause +*/ + +import QtQuick +import QtQuick.Particles + +Item { + width: 360 + height: 600 + + Image { + source: "../images/backgroundLeaves.jpg" + anchors.fill: parent + } + ParticleSystem { + anchors.fill: parent + Emitter { + width: parent.width + emitRate: 4 + lifeSpan: 14000 + size: 80 + velocity: PointDirection { y: wallpaper.configuration.Speed } + } + Wander { + anchors.fill: parent + anchors.bottomMargin: 100 + xVariance: 60 + pace: 60 + } + + //! [0] + Affector { + property real coefficient: 2.0 + property real velocity: 1.5 + width: parent.width + height: parent.height - 100 + onAffectParticles: { + /* //Linear movement + if (particle.r == 0) { + particle.r = Math.random() > 0.5 ? -1 : 1; + } else if (particle.r == 1) { + particle.rotation += velocity * dt; + if (particle.rotation >= maxAngle) + particle.r = -1; + } else if (particle.r == -1) { + particle.rotation -= velocity * dt; + if (particle.rotation <= -1 * maxAngle) + particle.r = 1; + } + */ + //Wobbly movement + for (var i=0; i, 2014, 2015, 2017, 2018. +# SPDX-FileCopyrightText: 2021, 2022, 2023, 2024 Zayed Al-Saidi +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-06-08 13:47+0400\n" +"Last-Translator: Zayed Al-Saidi \n" +"Language-Team: ar\n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: Lokalize 23.08.5\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "إجراءات أكثر" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "اطوِ" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "وسع" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "كلمة السّرّ" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "ابحث..." + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "ابحث" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "مسح سجل البحث" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "مجهول" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "فعّل الودجة %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "أزِل %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "ادخل نمط التحرير" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "اضبط %1…" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "اقفل الودجات" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "أزِل قفل الودجات" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "اخرج من نمط التحرير" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "فيما إذا كان يجب إنشاء خبيئة على القرص للسمة." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"الحد الأقصى لحجم ذاكرة التخزين المؤقت للسمة على القرص بالكيلو بايت. لاحظ أن " +"هذه الملفات هي ملفات متفرقة ، لذا قد لا يتم استخدام الحجم الأقصى. لذلك فإن " +"تحديد حجم أكبر غالبًا ما يكون آمنًا تمامًا." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "أظهر البدائل..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "أُزيلت ودجة" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "أُزيلت الودجة ”%1“." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "أُزيلت لوحة" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "أُزيلت إحدى اللوحات." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "أُزيل سطح مكتب" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "أُزيل أحد أسطح المكتب." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "تراجع" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "إعدادات الودجة" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "أزِل هذه الودجة" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "أزِل هذه اللوحة" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "أزِل هذا النشاط" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "إعدادات النشاط" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "تعذر العثور على المكون المطلوب: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "تطبيق مجهول" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"كُتبت هذه الأداة لإصدار أقدم غير معروف من بلازما وهي غير متوافقة مع بلازما " +"%1. يرجى الاتصال بمؤلف الودجة للحصول على نسخة محدثة." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"كُتبت هذه الأداة لإصدار بلازما %1 وهي غير متوافقة مع بلازما %2. . يرجى " +"الاتصال بمؤلف الودجة للحصول على نسخة محدثة." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"كُتبت هذه الأداة لإصدار بلازما %1 وهي غير متوافقة مع بلازما %2. يرجى تحديث " +"بلازما لتستخدم هذه الودجة." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "للأسف! حصل خطأ أثناء تحميل %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "خطأ في تحميل ملف QML:‏ %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "خطأ في تحميل البريمج: الحزمة %1غير موجودة." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "إعدادات %1 — %2" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "إعدادات %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "حزمة بلازما" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "ثبّت" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "فشل تثبيت الحزمة" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "الحزمة التي أسقطتها غير صالحة." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "الودجات" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "أضف %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "أضف أيقونة" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "الخلفية" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "عيّن %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "أسقط المحتوى" + +#~ msgid "Add Widgets..." +#~ msgstr "أضف ودجات…" + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "تعذر فتح الحزمة %1 المطلوبة للودجة %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "تتيح لك مشاركة إحدى الودجات على نفس الشبكة الوصولَ إليها من حاسوب آخر " +#~ "كتحكم بعيد." + +#~ msgid "Share this widget on the network" +#~ msgstr "شارك هذه الودجة عبر الشبكة" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "اسمح للكل بالوصول الحر إلى هذه الودجة" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "خدمة غير صالحة (صفريّة null)، لا إجراء عمل أي عملية." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "لا تُعرّف الودجة %1 أي «محرك سكرِبتات» ليُستخدم." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "متنوع" + +#~ msgid "Main Script File" +#~ msgstr "ملف السكرِبت الرئيسي" + +#~ msgid "Tests" +#~ msgstr "الاختبارات" + +#~ msgid "Images" +#~ msgstr "الصور" + +#~ msgid "Themed Images" +#~ msgstr "صور ذوات سمة" + +#~ msgid "Configuration Definitions" +#~ msgstr "تعاريف الضبط" + +#~ msgid "User Interface" +#~ msgstr "واجهة المستخدم" + +#~ msgid "Data Files" +#~ msgstr "ملفات البيانات" + +#~ msgid "Executable Scripts" +#~ msgstr "السكرِبتات التنفيذية" + +#~ msgid "Screenshot" +#~ msgstr "لقطة شاشة" + +#~ msgid "Translations" +#~ msgstr "الترجمات" + +#~ msgid "Configuration XML file" +#~ msgstr "ملف الضبط XML" + +#~ msgid "Images for dialogs" +#~ msgstr "صور الحواريّات" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "سمة حواريّ الخروج" + +#~ msgid "Wallpaper packages" +#~ msgstr "حزم الخلفية" + +#~ msgid "Images for widgets" +#~ msgstr "صور الودجات" + +#~ msgid "Background image for widgets" +#~ msgstr "صورة خلفية الودجات" + +#~ msgid "Analog clock face" +#~ msgstr "وجه الساعة التناظرية" + +#~ msgid "Background image for panels" +#~ msgstr "صورة خلفية اللوحات" + +#~ msgid "Background image for tooltips" +#~ msgstr "صورة خلفية التلميحات" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "ملف ضبط «مخطط ألوانك»" + +#~ msgid "Service Descriptions" +#~ msgstr "أوصاف الخدمة" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "تعذر إنشاء «محرّك سكرِبتات» %1 للودجة %2." + +#~ msgid "Script initialization failed" +#~ msgstr "فشل تمهيد السكرِبت" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "العُطل" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "الأحداث" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "المهام" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "أخرى" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "الشهر الماضي" + +#~ msgid "Previous Year" +#~ msgstr "السنة الماضية" + +#~ msgid "Previous Decade" +#~ msgstr "العقد الماضي" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "اليوم" + +#~ msgid "Reset calendar to today" +#~ msgstr "صفّر التقويم إلى اليوم" + +#~ msgid "Next Month" +#~ msgstr "الشهر القادم" + +#~ msgid "Next Year" +#~ msgstr "السنة القادمة" + +#~ msgid "Next Decade" +#~ msgstr "العقد القادم" + +#~ msgid "Days" +#~ msgstr "الأيام" + +#~ msgid "Months" +#~ msgstr "الأشهر" + +#~ msgid "Years" +#~ msgstr "السنوات" + +#~ msgid "OK" +#~ msgstr "حسنًا" + +#~ msgid "Cancel" +#~ msgstr "ألغِ" + +#~ msgid "Run the Associated Application" +#~ msgstr "افتح التطبيق المرتبط" + +#~ msgid "Open with %1" +#~ msgstr "افتح في %1" + +#~ msgid "Accessibility" +#~ msgstr "الإتاحة" + +#~ msgid "Application Launchers" +#~ msgstr "مُطلِقات التطبيقات" + +#~ msgid "Astronomy" +#~ msgstr "الفلك" + +#~ msgid "Date and Time" +#~ msgstr "التاريخ والوقت" + +#~ msgid "Development Tools" +#~ msgstr "أدوات التطوير" + +#~ msgid "Education" +#~ msgstr "التعليم" + +#~ msgid "Environment and Weather" +#~ msgstr "البيئة والطقس" + +#~ msgid "Examples" +#~ msgstr "أمثلة" + +#~ msgid "File System" +#~ msgstr "نظام الملفات" + +#~ msgid "Fun and Games" +#~ msgstr "الترفيه والألعاب" + +#~ msgid "Graphics" +#~ msgstr "الرسوميات" + +#~ msgid "Language" +#~ msgstr "اللغة" + +#~ msgid "Mapping" +#~ msgstr "الخرائط" + +#~ msgid "Miscellaneous" +#~ msgstr "متنوع" + +#~ msgid "Multimedia" +#~ msgstr "الوسائط المتعددة" + +#~ msgid "Online Services" +#~ msgstr "الخدمات على الشابكة" + +#~ msgid "Productivity" +#~ msgstr "الإنتاجية" + +#~ msgid "System Information" +#~ msgstr "معلومات النظام" + +#~ msgid "Utilities" +#~ msgstr "أدوات" + +#~ msgid "Windows and Tasks" +#~ msgstr "النوافذ والمهام" + +#~ msgid "Clipboard" +#~ msgstr "الحافظة" + +#~ msgid "Tasks" +#~ msgstr "المهام" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "حرّر %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "الإعدادات المبدئية للسمة، إلخ." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "مخطط الألوان لاستخدامه في التطبيقات." + +#~ msgid "Preview Images" +#~ msgstr "صور معاينة" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "معاينة لمدير الولوج" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "معاينة لشاشة القفل" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "معاينة لمُبدّل المستخدمين" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "معاينة لمُبدِّل سطح المكتب الوهمي" + +#, fuzzy +#~ msgid "Preview for KRunner" +#~ msgstr "معاينة لِ«مشغّلك»" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "معاينة لزخارف النوافذ" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "معاينة لمُبدّل النوافذ" + +#~ msgid "Login Manager" +#~ msgstr "مدير الولوج" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "السكرِبت الرئيسي لمدير الولوج" + +#~ msgid "Logout Dialog" +#~ msgstr "حواريّ الخروج" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "السكرِبت الرئيسي لحواريّ الخروج" + +#~ msgid "Screenlocker" +#~ msgstr "قافل الشاشة" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "السكرِبت الرئيسي لقافل الشاشة" + +#~ msgid "UI for fast user switching" +#~ msgstr "واجهة لتبديل سريع للمستخدم" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "السكربِت الرئيسي لمُبدّل المستخدمين" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "مُبدّل سطح المكتب الوهمي" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "السكرِبت الرئيسي لمُبدّل سطح المكتب الوهمي" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "إخطارات العرض على الشاشة" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "سكرِبت إخطارات العرض على الشاشة الرئيسي" + +#~ msgid "KRunner UI" +#~ msgstr "واجهة «مشغّلك»" + +#~ msgid "Main Script KRunner" +#~ msgstr "سكرِبت «مشغّلك» الرئيسي" + +#~ msgid "Window Decoration" +#~ msgstr "زخارف النوافذ" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "السكرِبت الرئيسي لزخارف النوافذ" + +#~ msgid "Window Switcher" +#~ msgstr "مُبدّل النوافذ" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "السكربِت الرئيسي لمُبدّل النوافذ" + +#~ msgid "Fetching file type..." +#~ msgstr "يجلب نوع الملف…" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "خيارات %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "أزل الودجة \"%1\" هذه" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "إعدادات %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "إعدادات %1..." + +#~ msgid "Plasma Package Manager" +#~ msgstr "مدير بلازما للحزم" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "ولّد تلبيدة SHA للحزمة في " + +#, fuzzy +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "(هناك مشكلة بالأسفل)" + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "ثبّت الحزمة في " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "أظهر معلومات الحزمة " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "رقِّ الحزمة في " + +#~ msgid "List installed packages" +#~ msgstr "اسرد الحزم المثبّتة" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "اسرد كلّ أنواع الحزم المعروفة الّتي يمكن تثبيتها" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "أزل الحزمة المسمّاة " + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "خلفيّة" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "بلازمويد" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "حزمة" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "سمة" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "محرّك-بيانات" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "مشغّل" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "ملحقة-خلفيّة" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "المظهر-والإحساس" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "صدفة" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "قالب-تصميم" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "تأثير-نوافذك" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "مبدّل-نوافذ" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "سكرِبت-نوافذك" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "تعذّر العثور على مثبِّت مناسب لنوع الحزم %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "يسرد أنواع الخدمات: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "خطأ: الملحقة %1 غير مثبّتة." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "خطأ: تعذّر العثور على بيانات الملحقة الوصفيّة: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "يظهر معلومات الحزمة: %1" + +#~ msgid " Name : %1" +#~ msgstr " الاسم: %1" + +#~ msgid " Comment : %1" +#~ msgstr " تعليق: %1" + +#~ msgid " Plugin : %1" +#~ msgstr " الملحقة: %1" + +#~ msgid " Author : %1" +#~ msgstr " المؤلّف: %1" + +#~ msgid " Path : %1" +#~ msgstr " المسار: %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "خياريّ packageroot و global يتضاربان، فضلًا اختر أحدهما فقط." + +#~ msgid "Addon Name" +#~ msgstr "اسم الإضافة" + +#~ msgid "Service Type" +#~ msgstr "نوع الخدمة" + +#~ msgid "Path" +#~ msgstr "المسار" + +#~ msgid "Type Argument" +#~ msgstr "نوع المعطى" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "الحزم القابلة للتّثبيت بهذه الأداة:" + +#~ msgid "Built in:" +#~ msgstr "مدمَجة:" + +#~ msgid "DataEngine" +#~ msgstr "محرّك بيانات" + +#~ msgid "Layout Template" +#~ msgstr "قالب تصميم" + +#~ msgid "Look and Feel" +#~ msgstr "المظهر والإحساس" + +#~ msgid "Package" +#~ msgstr "حزمة" + +#~ msgid "Plasmoid" +#~ msgstr "بلازمويد" + +#~ msgid "Runner" +#~ msgstr "مشغّل" + +#~ msgid "Shell" +#~ msgstr "صَدفة" + +#~ msgid "Theme" +#~ msgstr "سمة" + +#~ msgid "Wallpaper Images" +#~ msgstr "حزم الخلفيّة" + +#~ msgid "KWin Effect" +#~ msgstr "تأثير نوافذك" + +#~ msgid "KWin Window Switcher" +#~ msgstr "مبدّل نوافذك للنّوافذ" + +#~ msgid "KWin Script" +#~ msgstr "سكرِبت نوافذك" + +#~ msgid "Provided by plugins:" +#~ msgstr "توفّرها الملحقات:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "توفّرها ملفّات ‎.desktop:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "رُقِّيت %1 بنجاح" + +#~ msgid "Successfully installed %1" +#~ msgstr "ثُبِّتت %1 بنجاح" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "خطأ: فشل تثبيت %1: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "يرقّي الحزمة من الملفّ: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "أُزيلت %1 بنجاح" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "خطأ: فشلت إزالة %1: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "تعذّر تحميل المثبِّت المناسب لنوع الحزم %1. الخطأ المبلّغ عنه كان: %2" + +#~ msgid "No such file: %1" +#~ msgstr "لا ملف كهذا: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "تعذّر فتح الملف، هيئة الأرشيف غير مدعومة: %1 %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "تعذّر فتح ملف الحزمة: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "لا ملف بيانات وصفية في الحزمة: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "اسم ملحقة الحزمة غير محدَّد: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "اسم ملحقة الحزمة %1 يحوي محارف غير صالحة" + +#~ msgid "%1 already exists" +#~ msgstr "%1 موجود بالفعل" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "تعذّر نقل الحزمة إلى المقصد: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "تعذّر نسخ الحزمة إلى المقصد: %1" + +#, fuzzy +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "تعذّر تسجيل الحزمة كخدمة (هذا ليس فادحًا بالضرورة): %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 غير موجود" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "تعذّر حذف الحزمة من: %1" + +#, fuzzy +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "أتريد حقًّا إزالة %1 هذه؟" + +#~ msgid "Default layout file" +#~ msgstr "ملف التصميم الافتراضي" + +#~ msgid "Ok" +#~ msgstr "حسنًا" diff --git a/po/ast/libplasma6.po b/po/ast/libplasma6.po new file mode 100644 index 0000000..32d3899 --- /dev/null +++ b/po/ast/libplasma6.po @@ -0,0 +1,322 @@ +# Copyright (C) 2023 This file is copyright: +# This file is distributed under the same license as the plasma-framework package. +# +# SPDX-FileCopyrightText: 2023, 2024 Enol P. +msgid "" +msgstr "" +"Project-Id-Version: plasma-framework\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-03-14 23:24+0100\n" +"Last-Translator: Enol P. \n" +"Language-Team: Asturian \n" +"Language: ast\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 24.02.0\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Más aiciones" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Recoyer" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Espander" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Contraseña" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Buscar…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Quitar «%1»" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Entrar nel mou d'edición" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Configurar «%1»…" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Colar del mou d'edición" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Amosar les alternatives…" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Widget quitáu" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Quitóse'l widget «%1»." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Quitóse un panel." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Quitóse un escritoriu." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Desfacer" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Nun se pudo atopar el componente solicitáu: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Hebo un error al cargar el ficheru QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package does not exist. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Hebo un error al cargar l'applet: el paquete nun esiste. %1" + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Configuración de: %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Widgets" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Fondu de pantalla" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "" + +#~ msgid "Add Widgets..." +#~ msgstr "Amestar widgets…" + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Nun se pudo abrir el paquete «%1» riquíu pol widget «%2»." + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "El serviciu ye inválidu, nun se pue facer nenguna operación." diff --git a/po/az/libplasma6.po b/po/az/libplasma6.po new file mode 100644 index 0000000..2820e38 --- /dev/null +++ b/po/az/libplasma6.po @@ -0,0 +1,683 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the plasma-framework package. +# +# Xəyyam Qocayev , 2020, 2021, 2022, 2023. +msgid "" +msgstr "" +"Project-Id-Version: plasma-framework\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2023-02-19 15:12+0400\n" +"Last-Translator: Kheyyam \n" +"Language-Team: Azerbaijani \n" +"Language: az\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 22.12.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Daha çox fəaliyyətlər" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Yığmaq" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Genişləndirmək" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Şifrə" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Axtarış…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Axtarış" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Naməlum" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "%1 Vidjetin aktiv edilməsi" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "%1 silinməsi" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Düzəliş rejimi" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "%1 tənzimləmək..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Vidjetləri kilidləmək" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Vidjetlərin kilidini açmaq" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Düzəliş rejimindən çıxın" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Diskdə Mövzu üçün keş yaradılsın ya yox." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Diskdəki Mövzuların kilobytla maksimum ölçüsü. Qeyd edək ki, bu fayllar " +"seyrək fayllardır, bu halda maksimum ölçü istifadə olunmaya bilər. Buna görə " +"daha böyük bir ölçü qurmaq əslində daha etibarlıdır." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Alternativ Vidjetləri göstər..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Vidjet ləğv edildi" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "\"%1\" vidjeti ləğv edildi" + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panel ləğv edildi" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Panel ləğv edildi" + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Masaüstü ləğv edildi" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Masaüstü ləğv edildi" + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Geri qaytar" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Vidjet ayarları" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Bu vidjeti sil" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Bu paneli ləğv et" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Bu otağı ləğv et" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "İş otağı Ayarları" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Tapılmayan tələb olunan komponent: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Naməlum Qoşma" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "QML faylının yüklənməsi xətası: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package inexistent. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Vidjetin yüklənməsində xəta: paket mövcud olmayan paket: %1" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "%1 Ayarları" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 Ayarları" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma Paketi" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Quraşdırmaq" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Paketin quraşdırılması alınmadı" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Yararsız paket." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Vidjetlər" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "%1 əlavə et" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "İkon əlavə et" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Divar Kağızı" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "%1 istifadə et" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Elementin daşınması" + +#~ msgid "Add Widgets..." +#~ msgstr "Vidjet əlavə edin..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "%2 vidjetinin tələb etdiyi %1 paketi açıla bilmir." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Vidjetə uzaqdan idarəetməni açmaq, şəbəkə üzərindən digər komputer " +#~ "vasitəsi ilə onunla işləməyə imkan verir." + +#~ msgid "Share this widget on the network" +#~ msgstr "Bu vidjetə şəbəkə üzərindən uzaqdan girişə icazə verimək" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Bu vidjetə hamı üçün girişə icazə vermək" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Xidmətin istifadəsində xəta." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "" +#~ "%1 vidgetin hansı Script Yaradıcını istifadə edəcəyi müəyyənləşdirmədi." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Müxtəlif" + +#~ msgid "Main Script File" +#~ msgstr "Əsas skript faylı" + +#~ msgid "Tests" +#~ msgstr "Testlər" + +#~ msgid "Images" +#~ msgstr "Şəkillər" + +#~ msgid "Themed Images" +#~ msgstr "Mövzu şəkilləri" + +#~ msgid "Configuration Definitions" +#~ msgstr "Ayarların təyinatı" + +#~ msgid "User Interface" +#~ msgstr "İstifadəçi interfeysi" + +#~ msgid "Data Files" +#~ msgstr "Verilənlər faylı" + +#~ msgid "Executable Scripts" +#~ msgstr "İcra olunabilən skriptlər" + +#~ msgid "Screenshot" +#~ msgstr "Ekranın şəkli" + +#~ msgid "Translations" +#~ msgstr "Tərcümələr" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Ayarlar dialoqu səhifəsinin izahı" + +#~ msgid "Configuration XML file" +#~ msgstr "XML konfiqurasiya faylı" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Yığcam vidjetlər üçün açılan pəncərə" + +#~ msgid "Images for dialogs" +#~ msgstr "Dialoqlar üçün şəkillər" + +#~ msgid "Generic dialog background" +#~ msgstr "Əsas dialoq arxa fonları" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Sistemdən çıxış dialoqu Mövzusu" + +#~ msgid "Wallpaper packages" +#~ msgstr "Divar kağızlı paketlər" + +#~ msgid "Images for widgets" +#~ msgstr "Vidjetlər üçün şəkillər" + +#~ msgid "Background image for widgets" +#~ msgstr "Vidjetlər üçün arxa fon şəkilləri" + +#~ msgid "Analog clock face" +#~ msgstr "Əqrəbli saat üzlüyü" + +#~ msgid "Background image for panels" +#~ msgstr "pabellər üçün arxa fon şəkilləri" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Qrafik vidjetlər üçün arxa fon" + +#~ msgid "Background image for tooltips" +#~ msgstr "İpucları üçün arxa fon şəkli" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Dialoqlar üçün qeyri-şəffaf şəkillər" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Qeyri-şəffaf əsas dialoq arxa fonu" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Sistemdən çıxış dialoqu üçün qeyri-şəffaf Mövzu" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Vidjet üçün qeyri-şəffaf şəkillər" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Panellər üçün qeyri-şəffaf arxa fon" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Yardımçı mətnləri üçün qeyri-şəffaf arxa fon şəkili" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme rəng sxemi konfiqurasiya faylı" + +#~ msgid "Service Descriptions" +#~ msgstr "Xidmətin təsviri" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "%2 vidjeti üçün %1 Script Yaradıcısı yaradıla bilmədi." + +#~ msgid "Script initialization failed" +#~ msgstr "Skriptin açılmasında xəta" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Bayramlar" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Hadisələr" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Tapşırıq" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Digəri" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Keçən Ay" + +#~ msgid "Previous Year" +#~ msgstr "Keçən İl" + +#~ msgid "Previous Decade" +#~ msgstr "Keçən Onillik" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Bugün" + +#~ msgid "Reset calendar to today" +#~ msgstr "Bugünkü tarixə keç" + +#~ msgid "Next Month" +#~ msgstr "Növbəti Ay" + +#~ msgid "Next Year" +#~ msgstr "Gələn İl" + +#~ msgid "Next Decade" +#~ msgstr "Növbəti Onillik" + +#~ msgid "Days" +#~ msgstr "Günlər" + +#~ msgid "Months" +#~ msgstr "Aylar" + +#~ msgid "Years" +#~ msgstr "İllər" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "İmtina" + +#~ msgid "Run the Associated Application" +#~ msgstr "Uyğun tətbiqi başladın" + +#~ msgid "Open with %1" +#~ msgstr "%1 ilə aç" + +#~ msgid "Accessibility" +#~ msgstr "Xüsusi imkanlar" + +#~ msgid "Application Launchers" +#~ msgstr "Tətbiq Başladıcısı" + +#~ msgid "Astronomy" +#~ msgstr "Astronomiya" + +#~ msgid "Date and Time" +#~ msgstr "Tarix və Vaxt" + +#~ msgid "Development Tools" +#~ msgstr "Tərtibatçı Vasitələri" + +#~ msgid "Education" +#~ msgstr "Elm" + +#~ msgid "Environment and Weather" +#~ msgstr "Ətraf mühit və Hava" + +#~ msgid "Examples" +#~ msgstr "Nümunələr" + +#~ msgid "File System" +#~ msgstr "Fayl Sistemi" + +#~ msgid "Fun and Games" +#~ msgstr "Əyləncə və Oyunlar" + +#~ msgid "Graphics" +#~ msgstr "Təsvirlər" + +#~ msgid "Language" +#~ msgstr "Dil" + +#~ msgid "Mapping" +#~ msgstr "Xəritəçəkmə" + +#~ msgid "Miscellaneous" +#~ msgstr "Müxtəlif" + +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + +#~ msgid "Online Services" +#~ msgstr "Canlı Xidmətlər" + +#~ msgid "Productivity" +#~ msgstr "Faydalı" + +#~ msgid "System Information" +#~ msgstr "Sistem Məlumatları" + +#~ msgid "Utilities" +#~ msgstr "Yardımçı Vasitələr" + +#~ msgid "Windows and Tasks" +#~ msgstr "Pəncərə və Tapşırıqlar" + +#~ msgid "Clipboard" +#~ msgstr "Mübadilə Buferi" + +#~ msgid "Tasks" +#~ msgstr "Tapşırıqlar" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "%1 düzəliş etmək..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Mövzü üçün standart ayarlar və s." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Tətbiqlər üçün istifadə olunan rəng sxemi" + +#~ msgid "Preview Images" +#~ msgstr "Öncədən baxış üçün şəkillər" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Sistemə giriş ekranına öncədən baxış" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Kilidlənən ekrana öncədən baxış" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "İstifadəçi dəyişdiriciyə öncədən baxış" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Virtual Masaüstü Dəyişdirici üçün öncədən baxış" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Başlanğıc Ekranı üçün öncədən baxış" + +#~ msgid "Preview for KRunner" +#~ msgstr "Axtar və Başlat dialoqu görünüşü" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Pəncərə tərtibatı görünüşü" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Pəncərə dəyişdiricisi görünüşü" + +#~ msgid "Login Manager" +#~ msgstr "Sistemə Giriş Rəhbəri" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Sistemə Giriş Rəhbəri üçün əsas skript" + +#~ msgid "Logout Dialog" +#~ msgstr "Çıxış Dialoqu" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Çıxış Dialoqu üçün əsas skript" + +#~ msgid "Screenlocker" +#~ msgstr "Ekran Kilidləyici" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Ekran Kilidləyici üçün skript" + +#~ msgid "UI for fast user switching" +#~ msgstr "İstifadəçi Dəyişdirici" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "İstifadəçi Dəyişdirici üçün skript" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Virtual Masaüstü Dəyişdirici" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Virtual Masaüstü Dəyişdirici üçün əsas skript" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Ekran bildirişləri" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Ekran bildirişləri üçün əsas skript" + +#~ msgid "Splash Screen" +#~ msgstr "Başlanğıc Ekran" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Başlanğıc ekran üçün əsas skript" + +#~ msgid "KRunner UI" +#~ msgstr "Axtar və Başlat Dialoqu" + +#~ msgid "Main Script KRunner" +#~ msgstr "Axtar və Başlat Dialoqu üçün əsas skript" + +#~ msgid "Window Decoration" +#~ msgstr "Pəncərə Tərtibatı" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Pəncərə Tərtibatı üçün əsas skript" + +#~ msgid "Window Switcher" +#~ msgstr "Pəncərə Dəyişdirici" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Pəncərə Dəyişdirici üçün əsas skript" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Vidjetlərin yerləşdirilməsini sonlandırmaq" + +#~ msgid "Customize Layout..." +#~ msgstr "Vidjetləri yerləşdirmə ayarları..." diff --git a/po/be/libplasma6.po b/po/be/libplasma6.po new file mode 100644 index 0000000..7570da8 --- /dev/null +++ b/po/be/libplasma6.po @@ -0,0 +1,524 @@ +# Zmicier , 2023. +msgid "" +msgstr "" +"Project-Id-Version: fc57ad16a28d02dea100ceb1c60de14e\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-06-06 19:00\n" +"Last-Translator: Zmicier \n" +"Language-Team: Belarusian\n" +"Language: be\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || n%10>=5 && n%10<=9 || n" +"%100>=11 && n%100<=14 ? 2 : 3);\n" +"X-Generator: Lokalize 22.12.1\n" +"X-Crowdin-Project: fc57ad16a28d02dea100ceb1c60de14e\n" +"X-Crowdin-Project-ID: 136\n" +"X-Crowdin-Language: be\n" +"X-Crowdin-File: /[antikruk.KDE] main/KDE6/be/messages/libplasma/libplasma6." +"po\n" +"X-Crowdin-File-ID: 10486\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Яшчэ дзеянні" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Згарнуць" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Разгарнуць" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Пароль" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Пошук…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Пошук" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Ачысціць пошук" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Невядома" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Актываваць віджэт \"%1\"" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Выдаліць \"%1\"" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Увайсці ў рэжым рэдагавання" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Наладжванне \"%1\"..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Заблакаваць віджэты" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Разблакаваць віджэты" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Выйсці з рэжыму рэдагавання" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Ці ствараць кэш на дыску для тэмы." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Максімальны памер кэшу тэмы на дыску ў кілабайтах. Звярніце ўвагу на тое, " +"што гэтыя файлы разрэджаныя, таму максімальны памер можа не выкарыстоўвацца. " +"Таму вызначэнне большага памеру не стварае небяспекі." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Паказаць альтэрнатыўныя варыянты..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Віджэт выдалены" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Віджэт \"%1\" быў выдалены." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Панэль выдаленая" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Панэль была выдаленая." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Працоўны стол выдалены" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Працоўны стол быў выдалены." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Адрабіць" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Налады віджэтаў" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Выдаліць гэты віджэт" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Выдаліць гэтую панэль" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Выдаліць гэты пакой" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Налады пакояў" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Не ўдалося знайсці патрэбны кампанент: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Каранёвы элемент %1 мусіць мець тып \"containmentItem\"" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Каранёвы элемент %1 мусіць мець тып \"plasmoidItem\"" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Невядомы аплет" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Гэты віджэт быў створаны для невядомай старой версіі Plasma, ён " +"несумяшчальны з Plasma %1. Каб атрымаць абноўленую версію, звяжыцеся з " +"аўтарам віджэта." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 не сумяшчаецца з Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Гэты віджэт быў створаны для Plasma %1, ён несумяшчальны з Plasma %2. Каб " +"атрымаць абноўленую версію, звяжыцеся з аўтарам віджэта." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Гэты віджэт быў створаны для Plasma %1, ён несумяшчальны з Plasma %2. Каб " +"карыстацца віджэтам, абнавіце Plasma." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Выбачайце! Не ўдалося загрузіць %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Не ўдалося загрузіць файл QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Не ўдалося загрузіць аплет: пакет %1 не існуе." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 Налады" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 Налады" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Пакет Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Усталяваць" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Не ўдалося ўсталяваць пакет" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Пакет, які вы толькі што перацягнулі, хібны." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Віджэты" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Дадаць %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Дадаць значок" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Шпалеры" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Вызначыць %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Змесціва перацягнута" + +#~ msgid "Add Widgets..." +#~ msgstr "Дадаць віджэты..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Не ўдалося адкрыць пакунак %1, неабходны для віджэта %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Абагульванне віджэта ў сетцы дае магчымасць атрымаць доступ да гэтага " +#~ "віджэта з іншага камп'ютара, які можна выкарыстоўваць як пульт " +#~ "дыстанцыйнага кіравання." + +#~ msgid "Share this widget on the network" +#~ msgstr "Абагуліць гэты віджэт у сетцы" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Дазволіць усім свабодны доступ да гэтага віджэта" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Хібная (нулявая) служба, не можа выконваць ніякіх аперацый." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Віджэт %1 не вызначыў, які ScriptEngine выкарыстоўваць." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Рознае" + +#~ msgid "Main Script File" +#~ msgstr "Файл галоўнага скрыпта" + +#~ msgid "Tests" +#~ msgstr "Тэсты" + +#~ msgid "Images" +#~ msgstr "Выявы" + +#~ msgid "Themed Images" +#~ msgstr "Тэматычныя выявы" + +#~ msgid "Configuration Definitions" +#~ msgstr "Вызначэнні канфігурацыі" + +#~ msgid "User Interface" +#~ msgstr "Інтэрфейс карыстальніка" + +#~ msgid "Data Files" +#~ msgstr "Файлы даных" + +#~ msgid "Executable Scripts" +#~ msgstr "Выканальныя скрыпты" + +#~ msgid "Screenshot" +#~ msgstr "Здымак экрана" + +#~ msgid "Translations" +#~ msgstr "Пераклады" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Мадэль старонак карыстальніцкага інтэрфейсу канфігурацыі" + +#~ msgid "Configuration XML file" +#~ msgstr "XML-файл канфігурацыі" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Адвольны пашыральнік для кампактнага аплета" + +#~ msgid "Images for dialogs" +#~ msgstr "Выявы для дыялогавых акон" + +#~ msgid "Generic dialog background" +#~ msgstr "Фон агульных дыялогавых акон" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Тэма для дыялогавага акна выхаду з сістэмы" + +#~ msgid "Wallpaper packages" +#~ msgstr "Пакункі шпалераў" + +#~ msgid "Images for widgets" +#~ msgstr "Выявы для віджэтаў" + +#~ msgid "Background image for widgets" +#~ msgstr "Фонавая выява для віджэтаў" + +#~ msgid "Analog clock face" +#~ msgstr "Выгляд аналагавага гадзінніка" + +#~ msgid "Background image for panels" +#~ msgstr "Фонавая выява для панэляў" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Фон для графічных віджэтаў" + +#~ msgid "Background image for tooltips" +#~ msgstr "Фонавая выява для падказак" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Непразрыстасць выяў для дыялогавых акон" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Непразрыстасць фону агульных дыялогавых акон" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Непразрыстасць тэмы для дыялоговага акна выхаду з сістэмы" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Непразрыстасць выяў для віджэтаў" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Непразрыстасць фонавай выявы для панэляў" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Непразрыстасць фонавай выявы для падказак" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Файл канфігурацыі KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Апісанні службаў" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Не ўдалося стварыць ScriptEngine %1 для віджэта %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Не ўдалося ініцыялізаваць скрыпт" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Святы" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Падзеі" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Спіс задач" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Іншае" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1%2" + +#~ msgid "Previous Month" +#~ msgstr "Папярэдні месяц" + +#~ msgid "Previous Year" +#~ msgstr "Папярэдні год" + +#~ msgid "Previous Decade" +#~ msgstr "Папярэдняя дзесяцігоддзе" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Сёння" + +#~ msgid "Reset calendar to today" +#~ msgstr "Вярнуцца да сённяшняга дня" + +#~ msgid "Next Month" +#~ msgstr "Наступны месяц" + +#~ msgid "Next Year" +#~ msgstr "Наступны год" + +#~ msgid "Next Decade" +#~ msgstr "Наступнае дзесяцігоддзе" + +#~ msgid "Days" +#~ msgstr "Дні" + +#~ msgid "Months" +#~ msgstr "Месяцы" + +#~ msgid "Years" +#~ msgstr "Гады" + +#~ msgid "OK" +#~ msgstr "Добра" + +#~ msgid "Cancel" +#~ msgstr "Скасаваць" + +#~ msgid "Run the Associated Application" +#~ msgstr "Запусціць асацыяваную праграму" + +#~ msgid "Open with %1" +#~ msgstr "Адкрыць у %1" diff --git a/po/bg/libplasma6.po b/po/bg/libplasma6.po new file mode 100644 index 0000000..4d2b6d1 --- /dev/null +++ b/po/bg/libplasma6.po @@ -0,0 +1,317 @@ +# SPDX-FileCopyrightText: 2022, 2023, 2024 Mincho Kondarev +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-11-06 23:19+0100\n" +"Last-Translator: Mincho Kondarev \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 24.11.70\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Повече действия" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Свиване" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Разгъване" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Парола" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Търсене…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Търсене" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Изчистване на търсенето" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Неизвестно" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Активиране на %1 Widget" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Премахване на %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Влизане в режим на редактиране" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Конфигуриране на %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Заключване на уиджети" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Отключване на уиджети" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Излизане от режима за редактиране" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Създаване на кеш на диска за темата." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Максималният размер на кеша на темата на диска в килобайта. Имайте предвид, " +"че тези файлове са малки файлове, така че максималният размер може да не се " +"използва. Следователно задаване на по-голям размер често е безопасно." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Показване на алтернативи..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Уиджетът е премахнат" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Уиджетът „%1“ е премахнат." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Панелът е премахнат" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Панелът е премахнат." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Работният плот е премахнат" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Работният плот е премахнат." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Отмяна" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Настройки на уиджет" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Премахване на този уиджет" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Премахване на този панел" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Премахване на тази дейност" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Настройки на дейност" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Добавяне или управление на уиджети…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Не можа да се намери заявения компонент:%1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Основният елемент на %1 трябва да бъде от тип ContaimentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Основният елемент на %1 трябва да бъде от тип PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Неизвестна приставка" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Този уиджет е написан за неизвестна по-стара версия на Plasma и не е " +"съвместим с Plasma %1. Моля, свържете се с автора на уиджета за по-" +"актуализирана версия." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 не е съвместим с Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Този уиджет е написан за Plasma %1 и не е съвместим с Plasma %2. Моля, " +"свържете се с автора на уиджета за по-актуализирана версия." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Този уиджет е написан за Plasma %1 и не е съвместим с Plasma %2. Моля, " +"актуализирайте Plasma, за да можете да го използвате." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "За съжаление, възникна грешка при зареждане на %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Грешка при зареждането на QML файл: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Грешка при зареждането на аплета: пакетът не съществува. %1" + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 настройки" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 Настройки" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Пакет на Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Инсталиране" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Инсталацията на пакета е неуспешна" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Пакетът, който току-що пуснахте, е невалиден." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Уиджети" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Добавяне %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Добавяне на икона" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Тапет" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Задаване на %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Съдържанието е пуснато" diff --git a/po/bs/libplasma6.po b/po/bs/libplasma6.po new file mode 100644 index 0000000..39b8411 --- /dev/null +++ b/po/bs/libplasma6.po @@ -0,0 +1,1005 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: plasma\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2014-01-31 21:06+0100\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: bosanski \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-12-06 06:21+0000\n" +"X-Generator: Launchpad (build 16863)\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Nepoznato" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Aktiviraj grafičku kontrolu %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, fuzzy, kde-format +#| msgctxt "%1 is the name of the applet" +#| msgid "Remove this %1" +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Ukloni ovaj %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Zaključaj grafičku kontrolu" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Otključaj grafičku kontrolu" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "" + +#: plasma/private/applet_p.cpp:232 +#, fuzzy, kde-format +#| msgid "Widgets explorer UI" +msgid "Widget Removed" +msgstr "Istraživač dodataka UI" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "" + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "" + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "" + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Postavke grafičke kontrole" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Ukloni ovu grafičku kontrolu" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Ukloni ovaj panel" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Ukloni ovu aktivnost" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Postavke aktivnosti" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Ne mogu da nađem zahtijevanu komponentu: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, fuzzy, kde-format +#| msgid "Unknown" +msgid "Unknown Applet" +msgstr "Nepoznato" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, fuzzy, kde-format +#| msgid "Error loading QML file: %1" +msgid "Error loading QML file: %1 %2" +msgstr "Greška pri učitavanju QML datoteke: %1" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgctxt "%1 is the name of the applet" +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "%1 Postavke" + +#: plasmaquick/configview.cpp:232 +#, fuzzy, kde-format +#| msgctxt "%1 is the name of the applet" +#| msgid "%1 Settings" +msgid "%1 Settings" +msgstr "%1 Postavke" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, fuzzy, kde-format +#| msgid "Plasma Package Manager" +msgid "Plasma Package" +msgstr "Plasmin menadžer paketa" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, fuzzy, kde-format +#| msgid "Script initialization failed" +msgid "Package Installation Failed" +msgstr "Neuspjelo pripremanje skripte" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, fuzzy, kde-format +#| msgid "Lock Widgets" +msgid "Widgets" +msgstr "Zaključaj grafičku kontrolu" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, fuzzy, kde-format +#| msgid "Wallpaper packages" +msgid "Wallpaper" +msgstr "Paketi pozadinskih slika" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "" + +#~ msgid "Add Widgets..." +#~ msgstr "Dodaj grafičke kontrole..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Ne mogu da otvorim paket %1 neophodan za grafičku kontrolu %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Dijeljenje grafičke kontrole na mreži omogućava vam da pristupite toj " +#~ "grafičkoj kontroli sa drugog računara kao daljinskim upravljačem." + +#~ msgid "Share this widget on the network" +#~ msgstr "Podijeli ovu grafičku kontrolu na mreži" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Dozvoli svima slobodan pristup ovoj grafičkoj kontroli" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Neispravan (nulti) servis, ne može izvršiti nikakvu operaciju." + +#, fuzzy +#~| msgid "The %2 widget did not define which ScriptEngine to use." +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Dodatak %2 nije odredio koji ScriptEngine će koristiti" + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Ostalo" + +# >> @item file definition +#~ msgid "Main Script File" +#~ msgstr "glavnu datoteku skripte" + +#~ msgid "Images" +#~ msgstr "Slike" + +#~ msgid "Themed Images" +#~ msgstr "Tematske slike" + +# >> @item directory definition +#~ msgid "Configuration Definitions" +#~ msgstr "definicije postave" + +#~ msgid "User Interface" +#~ msgstr "Korisnički interfejs" + +# >> @item directory definition +#~ msgid "Data Files" +#~ msgstr "opšte datoteke" + +# >> @item directory definition +#~ msgid "Executable Scripts" +#~ msgstr "izvršne skripte" + +# >> @item directory definition +#~ msgid "Translations" +#~ msgstr "prevodi" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Konfiguracije UI stranica modela" + +# >> @item file definition +#~ msgid "Configuration XML file" +#~ msgstr "XML konfiguracijska datoteka" + +# >> @item directory definition +#~ msgid "Images for dialogs" +#~ msgstr "Slike za dijaloge" + +# >> @item file definition +#~ msgid "Generic dialog background" +#~ msgstr "Generička pozadina dijaloga" + +# >> @item file definition +#~ msgid "Theme for the logout dialog" +#~ msgstr "Tema za odjavni dijalog" + +#~ msgid "Wallpaper packages" +#~ msgstr "Paketi pozadinskih slika" + +# >> @item directory definition +#~ msgid "Images for widgets" +#~ msgstr "Slike za grafičku kontrolu" + +# >> @item file definition +#~ msgid "Background image for widgets" +#~ msgstr "Pozadinska slika za grafičku kontrolu" + +# >> @item file definition +#~ msgid "Analog clock face" +#~ msgstr "Lice analognog sata" + +# >> @item file definition +#~ msgid "Background image for panels" +#~ msgstr "Pozadinska slika za panele" + +# >> @item file definition +#~ msgid "Background for graphing widgets" +#~ msgstr "Pozadina za grafičke kontrole" + +# >> @item file definition +#~ msgid "Background image for tooltips" +#~ msgstr "Pozadinska slika za oblačiće" + +# >> @item directory definition +#~ msgid "Opaque images for dialogs" +#~ msgstr "Neprozirne slike za dijaloge" + +# >> @item file definition +#~ msgid "Opaque generic dialog background" +#~ msgstr "Neprozirna generička pozadina dijaloga" + +# >> @item file definition +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Neprozirna tema za odjavni dijalog" + +# >> @item directory definition +#~ msgid "Opaque images for widgets" +#~ msgstr "Neprozirne slike za grafičke kontrole" + +# >> @item file definition +#~ msgid "Opaque background image for panels" +#~ msgstr "Neprozirna pozadinska slika za panele" + +# >> @item file definition +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Neprozirna pozadinska slika za oblačiće" + +# >> @item file definition +#~ msgid "KColorScheme configuration file" +#~ msgstr "postavnu datoteku šeme boja" + +#~ msgid "Service Descriptions" +#~ msgstr "Opis usluga" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Ne mogu da stvorim skriptni motor %1 za grafičku kontrolu %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Neuspjelo pripremanje skripte" + +#~ msgid "Run the Associated Application" +#~ msgstr "Izvrši pridruženi program" + +#~ msgid "Accessibility" +#~ msgstr "Pristupačnost" + +# >> @item applet category +#~ msgid "Application Launchers" +#~ msgstr "pokretači programa" + +#~ msgid "Astronomy" +#~ msgstr "Astronomija" + +#~ msgid "Date and Time" +#~ msgstr "Datum i vrijeme" + +# >> @item applet category +#~ msgid "Development Tools" +#~ msgstr "razvojne alatke" + +#~ msgid "Education" +#~ msgstr "Obrazovanje" + +# >> @item applet category +#~ msgid "Environment and Weather" +#~ msgstr "priroda i vrijeme" + +#~ msgid "Examples" +#~ msgstr "Primjeri" + +#~ msgid "File System" +#~ msgstr "Datotečni sistem" + +# >> @item applet category +#~ msgid "Fun and Games" +#~ msgstr "zabava i igre" + +#~ msgid "Graphics" +#~ msgstr "Grafika" + +#~ msgid "Language" +#~ msgstr "Jezik" + +# >> @item applet category +#~ msgid "Mapping" +#~ msgstr "kartografija" + +#~ msgid "Miscellaneous" +#~ msgstr "Ostalo" + +#~ msgid "Multimedia" +#~ msgstr "Multimedija" + +# >> @item applet category +#~ msgid "Online Services" +#~ msgstr "servisi na vezi" + +#~ msgid "Productivity" +#~ msgstr "Produktivnost" + +# >> @item applet category +#~ msgid "System Information" +#~ msgstr "podaci o sistemu" + +#~ msgid "Utilities" +#~ msgstr "Alatke" + +# >> @item applet category +#~ msgid "Windows and Tasks" +#~ msgstr "prozori i zadaci" + +#, fuzzy +#~| msgid "Themed Images" +#~ msgid "Preview Images" +#~ msgstr "Tematske slike" + +# >> @item file definition +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script for Login Manager" +#~ msgstr "glavnu datoteku skripte" + +# >> @item file definition +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "glavnu datoteku skripte" + +# >> @item file definition +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script for Lock Screen" +#~ msgstr "glavnu datoteku skripte" + +# >> @item file definition +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script for User Switcher" +#~ msgstr "glavnu datoteku skripte" + +# >> @item file definition +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script for Splash Screen" +#~ msgstr "glavnu datoteku skripte" + +# >> @item file definition +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script KRunner" +#~ msgstr "glavnu datoteku skripte" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1 Opcije" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Ukloni ovaj %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "%1 Postavke" + +#, fuzzy +#~| msgctxt "%1 is the name of the applet" +#~| msgid "%1 Settings" +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "%1 Postavke" + +# >> @item directory definition +#~ msgid "Low color images for dialogs" +#~ msgstr "malobojne slike za dijaloge" + +# >> @item file definition +#~ msgid "Low color generic dialog background" +#~ msgstr "malobojna generička pozadina dijaloga" + +# >> @item file definition +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "malobojna tema za odjavni dijalog" + +# >> @item file definition +#~ msgid "Low color background image for widgets" +#~ msgstr "malobojna pozadinska slika za grafičke kontrole" + +# >> @item file definition +#~ msgid "Low color analog clock face" +#~ msgstr "malobojno lice analognog sata" + +# >> @item file definition +#~ msgid "Low color background image for panels" +#~ msgstr "malobojna pozadinska slika za panele" + +# >> @item file definition +#~ msgid "Low color background for graphing widgets" +#~ msgstr "malobojna pozadina za crtačke grafičke kontrole" + +# >> @item file definition +#~ msgid "Low color background image for tooltips" +#~ msgstr "malobojna pozadinska slika za oblačiće" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Plasmin menadžer paketa" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Generiši SHA1 hash za paket " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Pri instaliranju ili uklanjanju, radi nad paketima instaliranim za sve " +#~ "korisnike." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Tip paketa, jedno od: plasmoid theme wallpaper dataengine runner layout-" +#~ "template" + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Instaliraj paket s date putanje" + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Prikazi informacije o paketu " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Nadogradi paket s date putanje" + +#, fuzzy +#~| msgid "Wallpaper packages" +#~ msgid "List installed packages" +#~ msgstr "Paketi pozadinskih slika" + +#, fuzzy +#~| msgid "lists all known Package types that can be installed" +#~ msgid "List all known package types that can be installed" +#~ msgstr "prikazuje sve poznate tipove paketa koji se mogu instalisati" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Ukloni paket po imenu " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Apsolutna putanja do korijena paketa. Ako se ne zada, traži se po " +#~ "standardnim direktorijumima u ovoj sesiji KDE‑a." + +#, fuzzy +#~| msgid "Could not delete package from: %1" +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Ne mogu obrisati paket sa: %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "SHA1 hash za paket na %1: '%2'" + +# literal-segment: wallpaper +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "wallpaper" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "paket" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "theme" + +# literal-segment: dataengine +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "dataengine" + +# literal-segment: runner +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "runner" + +#, fuzzy +#~| msgid "Wallpaper packages" +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "Paketi pozadinskih slika" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "izgled" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "školjka" + +# literal-segment: layout-template +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "layout-template" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "kwineffect" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "windowswitcher" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "kwinscript" + +#, fuzzy +#~| msgid "Could not delete package from: %1" +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "Ne mogu obrisati paket sa: %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "Vrsta usluge:%1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Greska: %1 nije instaliran." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Mora se zadati install, remove, upgrade ili list." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Greška: Ne mogu pronaći metapodatke priključka: %1" + +#, fuzzy +#~| msgid "Could not open package file: %1" +#~ msgid "Showing info for package: %1" +#~ msgstr "Ne mogu otvoriti paket datoteku: %1" + +#~ msgid " Name : %1" +#~ msgstr " Ime : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Komentar : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Umetak : %1" + +#~ msgid " Author : %1" +#~ msgstr " Autor : %1" + +#~ msgid " Path : %1" +#~ msgstr " Staza: %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Opcije packageroot i global isključuju jedna drugu, zadajte samo jednu od " +#~ "njih." + +#~ msgid "Addon Name" +#~ msgstr "Ime dodatka" + +#~ msgid "Service Type" +#~ msgstr "Tip servisa" + +#~ msgid "Path" +#~ msgstr "Staza" + +#~ msgid "Type Argument" +#~ msgstr "Tip argumenta" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Tipovi paketa koji se mogu instalisati ovim alatom" + +#~ msgid "Built in:" +#~ msgstr "Ugrađeno:" + +# >> @item directory definition +#, fuzzy +#~| msgid "Data Files" +#~ msgid "DataEngine" +#~ msgstr "opšte datoteke" + +# literal-segment: layout-template +#~ msgid "Layout Template" +#~ msgstr "Predložak rasporeda" + +#~ msgid "Look and Feel" +#~ msgstr "Izgled i Osjećaj" + +#~ msgid "Package" +#~ msgstr "Paket" + +#~ msgid "Plasmoid" +#~ msgstr "Plazmoid" + +# literal-segment: runner +#~ msgid "Runner" +#~ msgstr "Trkač" + +#~ msgid "Shell" +#~ msgstr "Školjka" + +#~ msgid "Theme" +#~ msgstr "Tema" + +#, fuzzy +#~| msgid "Wallpaper packages" +#~ msgid "Wallpaper Images" +#~ msgstr "Paketi pozadinskih slika" + +#~ msgid "KWin Effect" +#~ msgstr "Efekti KWin-a" + +#~ msgid "KWin Window Switcher" +#~ msgstr "KWin prebacivač prozora" + +# >> @item file definition +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "KWin Script" +#~ msgstr "glavnu datoteku skripte" + +#~ msgid "Provided by plugins:" +#~ msgstr "Navedeni dodaci:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Dato preko .desktop datoteka:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "Uspiješno nadograđen%1" + +#~ msgid "Successfully installed %1" +#~ msgstr "Uspješno instalirano: %1" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Greska: Instalacija %1 neuspijela:%2" + +#, fuzzy +#~| msgid "Could not open package file: %1" +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Ne mogu otvoriti paket datoteku: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Uspijesno izbrisan %1" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Greska: Brisanje %1 neuspijelo:%2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Ne mogu da učitam instalator za paket tipa %1. Prijavljena greška: %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Nije moguće kreirati korijenski direktorijum paketa: %1" + +#~ msgid "No such file: %1" +#~ msgstr "Nema te datoteke: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "Ne mogu otvoriti paket datoteku, nije podržan arhiv format: %1 %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "Ne mogu otvoriti paket datoteku: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "Nema datoteke metapodataka u paketu: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "Paket plugin imena nije specificiran: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "Paket plugin imena %1 sadrži karktere koji nisu validni" + +#~ msgid "%1 already exists" +#~ msgstr "%1 već postoji" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Ne mogu premjestiti paket na destinaciju: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Ne mogu kopirati paket na destinaciju: %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Ne mogu kreirati lokalni servis direktorij: %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "Ne mogu registrovati paket kao servis (nije nužno fatalno): %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 ne postoji" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Ne mogu obrisati paket sa: %1" + +#~ msgid "Applets furniture" +#~ msgstr "Applets furniture" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "Istraživač UI za dodavanje dodataka" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "Korisnički interfejs za poglede koji će pokazati sadržaj" + +#~ msgid "Default layout file" +#~ msgstr "Zadani izgled datoteke" + +#, fuzzy +#~| msgid "Default plugins for containments, containmentActions etc" +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "Zadani plugini za sadržaje, akcije sadržaja itd" + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "Poruka za grešku kada se applet ne može učitati" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "QML komponenta koja pokazuje applet u iskočnom prozoru" + +#, fuzzy +#~| msgid "" +#~| "Compact representation of an applet when collapsed in a popup, for " +#~| "instance as an icon. applets can override this component." +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Kompaktna zastupljenost appleta kada se sažme u iskočnom prozoru, na " +#~ "primjer kao ikona. appleti mogu nadjačati ovu komponentu." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "QML komponenta za konfiguracijski dijalog za applet" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "QML komponenta za konfiguracijski dijalog za sadržaj" + +#~ msgid "Panel configuration UI" +#~ msgstr "Konfiguracija ploče UI" + +#, fuzzy +#~| msgid "QML component for the configuration dialog for applets" +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "QML komponenta za konfiguracijski dijalog za applet" + +#~ msgid "search term" +#~ msgstr "izraz za traženje" + +#~ msgctxt "o/o1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Ukloni programčić %1" + +#~ msgctxt "o/o1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "%1 Postavke" diff --git a/po/ca/libplasma6.po b/po/ca/libplasma6.po new file mode 100644 index 0000000..c8577cf --- /dev/null +++ b/po/ca/libplasma6.po @@ -0,0 +1,325 @@ +# Translation of libplasma6.po to Catalan +# Copyright (C) 2014-2024 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# SPDX-FileCopyrightText: 2014, 2015, 2016, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Josep M. Ferrer +# Antoni Bella Pérez , 2014, 2018, 2019, 2020, 2022. +# Empar Montoro Martín , 2019. +msgid "" +msgstr "" +"Project-Id-Version: libplasma\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-23 11:00+0200\n" +"Last-Translator: Josep M. Ferrer \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" +"X-Generator: Lokalize 24.05.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Més accions" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Redueix" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Expandeix" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Contrasenya" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Cerca…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Cerca" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Neteja la cerca" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Desconegut" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Activa el giny %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Elimina %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Entra en el mode d'edició" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Configura %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Bloqueja els ginys" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Desbloqueja els ginys" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Surt del mode d'edició" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Determina si s'ha de crear o no una memòria cau al disc per al tema." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"La mida màxima de la memòria cau al disc per al tema en kilobytes. Cal tenir " +"en compte que aquests fitxers són fitxers dispersos, per tant, gairebé no " +"s'usarà la mida màxima. Per consegüent, es força segur definir una mida gran." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Mostra les alternatives..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "S'ha eliminat el giny" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "S'ha eliminat el giny «%1»." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "S'ha eliminat el plafó" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "S'ha eliminat un plafó." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "S'ha eliminat l'escriptori" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "S'ha eliminat un escriptori." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Desfés" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Configuració del giny" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Suprimeix aquest giny" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Elimina aquest plafó" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Elimina aquesta activitat" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Configuració de l'activitat" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Afegeix o gestiona ginys…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "No s'ha pogut trobar el component sol·licitat: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "L'element arrel de %1 cal que sigui del tipus ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "L'element arrel de %1 cal que sigui del tipus PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Miniaplicació desconeguda" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Aquest giny s'ha escrit per a una versió antiga desconeguda del Plasma i no " +"és compatible amb el Plasma %1. Poseu-vos en contacte amb l'autor del giny " +"per a una versió actualitzada." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 no és compatible amb el Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Aquest giny s'ha escrit per al Plasma %1 i no és compatible amb el Plasma " +"%2. Poseu-vos en contacte amb l'autor del giny per a una versió actualitzada." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Aquest giny s'ha escrit per al Plasma %1 i no és compatible amb el Plasma " +"%2. Actualitzeu el Plasma per tal de fer servir el giny." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "S'ha produït un error en carregar %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Error en carregar el fitxer QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Error en carregar la miniaplicació: el paquet %1 no existeix." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — Configuració de %2" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Configuració de %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Paquet del Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Instal·la" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "La instal·lació del paquet ha fallat" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "El paquet que acabeu de deixar no és vàlid." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Ginys" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Afegeix el %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Afegeix una icona" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Fons de pantalla" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Estableix el %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Contingut descartat" diff --git a/po/ca@valencia/libplasma6.po b/po/ca@valencia/libplasma6.po new file mode 100644 index 0000000..a61354f --- /dev/null +++ b/po/ca@valencia/libplasma6.po @@ -0,0 +1,327 @@ +# Translation of libplasma6.po to Catalan (Valencian) +# Copyright (C) 2014-2024 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# SPDX-FileCopyrightText: 2014, 2015, 2016, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Josep M. Ferrer +# Antoni Bella Pérez , 2014, 2018, 2019, 2020, 2022. +# Empar Montoro Martín , 2019. +msgid "" +msgstr "" +"Project-Id-Version: libplasma\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-23 11:00+0200\n" +"Last-Translator: Josep M. Ferrer \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" +"X-Generator: Lokalize 24.05.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Més accions" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Reduïx" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Expandix" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Contrasenya" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Busca…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Busca" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Neteja la busca" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Desconegut" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Activa el giny %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Elimina %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Entra en el mode edició" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Configura %1…" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Bloqueja els ginys" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Desbloqueja els ginys" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Ix del mode edició" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "" +"Determina si s'ha de crear o no una memòria cau en el disc per al tema." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"La mida màxima de la memòria cau en el disc per al tema en kilobytes. Cal " +"tindre en compte que estos fitxers són fitxers dispersos, per tant, quasi no " +"s'utilitzarà la mida màxima. Per tant, es força segur definir una mida gran." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Mostra les alternatives…" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "S'ha eliminat el giny" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "S'ha eliminat el giny «%1»." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "S'ha eliminat el quadro" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "S'ha eliminat un quadro." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "S'ha eliminat l'escriptori" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "S'ha eliminat un escriptori." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Desfés" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Configureu el giny" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Suprimix este giny" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Elimina este quadro" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Elimina esta activitat" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Configureu l'activitat" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Afig o gestiona els ginys…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "No s'ha pogut trobar el component sol·licitat: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "L'element arrel de %1 cal que siga del tipus ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "L'element arrel de %1 cal que siga del tipus PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Miniaplicació desconeguda" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Este giny s'ha escrit per a una versió antiga desconeguda de Plasma i no és " +"compatible amb Plasma %1. Poseu-vos en contacte amb el seu autor per a una " +"versió actualitzada." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 no és compatible amb Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Este giny s'ha escrit per a Plasma %1 i no és compatible amb Plasma %2. " +"Poseu-vos en contacte amb el seu autor per a una versió actualitzada." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Este giny s'ha escrit per a Plasma %1 i no és compatible amb Plasma %2. " +"Actualitzeu Plasma per tal d'emprar-lo." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "S'ha produït un error en carregar %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "S'ha produït un error en carregar el fitxer en QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "" +"S'ha produït un error en carregar la miniaplicació: el paquet %1 no existix." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — Configuració de %2" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Configuració de %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Paquet de Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Instal·la" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "La instal·lació del paquet ha fallat" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "El paquet que acabeu de deixar no és vàlid." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Ginys" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Afig %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Afig una icona" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Fons de pantalla" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Establix %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Contingut descartat" diff --git a/po/cs/libplasma6.po b/po/cs/libplasma6.po new file mode 100644 index 0000000..8ac6216 --- /dev/null +++ b/po/cs/libplasma6.po @@ -0,0 +1,314 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# SPDX-FileCopyrightText: 2010, 2011, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2023, 2024 Vít Pelčák +# Lukáš Tinkl , 2010, 2012. +# SPDX-FileCopyrightText: 2021, 2023, 2024 Vit Pelcak +# +msgid "" +msgstr "" +"Project-Id-Version: plasmapkg\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-23 15:37+0200\n" +"Last-Translator: Vit Pelcak \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 24.05.2\n" +"X-Language: cs_CZ\n" +"X-Source-Language: en_US\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Další činnosti" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Svinout" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Rozvinout" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Heslo" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Hledat…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Hledat" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Vyprázdnit hledání" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Neznámý" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Aktivovat %1 widget" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Odstranit %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Spustit režim úprav" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Nastavit %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Uzamknout widgety" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Odemknout widgety" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Ukončit režim úprav" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Zda pro motiv vytvářet nebo nevytvářet mezipaměť na disku." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Zobrazit alternativy..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Widget byl odstraněn." + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Widget \"%1\" byl odstraněn." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panel byl odstraněn" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Panel byl odstraněn." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Pracovní plocha byla odstraněna" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Pracovní plocha byla odstraněna." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Zpět" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Nastavení widgetu" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Odstranit tento widget" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Odstranit tento panel" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Odstranit tuto činnost" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Nastavení aktivit" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Přidat nebo spravovat widgety…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Požadovanou komponentu se nepovedlo nalézt: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Neznámý applet" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 není kompatibilní s Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Při načítání došlo k chybě %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Chyba při načítání souboru QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Chyba při načítání appletu: balíček %1 neexistuje." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Nastavení %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Balíček Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Instalovat" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Instalace balíčku selhala" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Widgety" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Přidat %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Přidat ikonu" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Tapeta" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Nastavit %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Obsah byl zahozen" diff --git a/po/da/libplasma6.po b/po/da/libplasma6.po new file mode 100644 index 0000000..7f54c73 --- /dev/null +++ b/po/da/libplasma6.po @@ -0,0 +1,971 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Martin Schlander , 2014, 2015, 2016, 2018, 2019. +# SPDX-FileCopyrightText: 2024 rasmus rosendahl-kaa +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-07-30 12:27+0200\n" +"Last-Translator: rasmus rosendahl-kaa \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 24.05.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Flere handlinger" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Fold sammen" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Udfold" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Adgangskode" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Søg…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Søg" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Ryd søgning" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Ukendt" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Aktivér widgetten %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Fjern %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Skift til redigeringstilstand" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Indstil %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Lås widgets" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Lås widgets op" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Afslut redigeringstilstand" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Om der skal oprettes en cache på disken til temaet." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Den maksimale størrelse på tema-cachen på disken i kilobyte. Bemærk at disse " +"filer er små, så den maksimale størrelse bliver måske ikke brugt. Det er " +"altså normalt helt ufarligt at angive en stor størrelse." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Vis alternativer..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Widget fjernet" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Widgetten \"%1\" er blevet fjernet." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panel fjernet" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Et panel er blevet fjernet." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Skrivebord fjernet" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Et skrivebord er blevet fjernet." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Fortryd" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Indstilling af widget" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Fjern denne widget" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Fjern dette panel" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Fjern denne aktivitet" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Aktivitetsindstillinger" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Kunne ikke finde den anmodede komponent: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Rodelementet af %1 skal være af type ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Rodelementet af %1 skal være af type PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Ukendt applet" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Denne widget var skrevet til en ukendt ældre version af Plasma og er derfor " +"ikke kompatibel med Plasma %1. Venligst kontakt forfatteren af widgeten for " +"en opdateret version." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 er ikke kompatibel med Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Denne widget var skrevet til Plasma %1 og er ikke kompatibel med Plasma %2. " +"Kontakt venligst forfatteren af widgeten for en opdateret version." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Denne widget var skrevet til Plasma %1 og er ikke kompatibel med Plasma %2. " +"Opdatér venligst Plasma for at bruge widgeten." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Undskyld! Der var en fejl under indlæsning af %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Fejl ved indlæsning af QML-fil: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Fejl ved indlæsning af applet. Pakken %1 eksisterer ikke." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "Indstilling af %1 — %2" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Indstilling af %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma-pakke" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Installér" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Installation af pakken mislykkedes" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Pakken du netop slap er ugyldig." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Widgets" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Tilføj %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Tilføj ikon" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Baggrundsbillede" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Sæt %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Indhold droppet" + +#~ msgid "Add Widgets..." +#~ msgstr "Tilføj widgets..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Kunne ikke åbne pakken %1 som er påkrævet af widgetten %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Deling af en widget på netværket lader dig tilgå denne widget fra en " +#~ "anden computer som fjernbetjening." + +#~ msgid "Share this widget on the network" +#~ msgstr "Del denne widget på netværket" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Lad alle få fri adgang til denne widget" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Ugyldig (null) tjeneste, kan ikke udføre nogen handlinger." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Widgetten %1 definerede ikke hvilken scriptmotor der skal bruges." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Diverse" + +#~ msgid "Main Script File" +#~ msgstr "Hovedscriptfil" + +#~ msgid "Tests" +#~ msgstr "Tester" + +#~ msgid "Images" +#~ msgstr "Billeder" + +#~ msgid "Themed Images" +#~ msgstr "Tematiserede billeder" + +#~ msgid "Configuration Definitions" +#~ msgstr "Indstillingsdefinitioner" + +#~ msgid "User Interface" +#~ msgstr "Brugerflade" + +#~ msgid "Data Files" +#~ msgstr "Datafiler" + +#~ msgid "Executable Scripts" +#~ msgstr "Kørbare scripts" + +#~ msgid "Screenshot" +#~ msgstr "Skærmbillede" + +#~ msgid "Translations" +#~ msgstr "Oversættelser" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Sidemodel til konfigurationsbrugerflade" + +#~ msgid "Configuration XML file" +#~ msgstr "XML-konfigurationsfil" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Brugertilpasset udvider til kompakte applets" + +#~ msgid "Images for dialogs" +#~ msgstr "Billeder til dialoger" + +#~ msgid "Generic dialog background" +#~ msgstr "Generisk dialogbaggrund" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Tema til log ud-dialog" + +#~ msgid "Wallpaper packages" +#~ msgstr "Baggrundsbillede-pakker" + +#~ msgid "Images for widgets" +#~ msgstr "Billeder til widgets" + +#~ msgid "Background image for widgets" +#~ msgstr "Baggrundsbillede til widgets" + +#~ msgid "Analog clock face" +#~ msgstr "Analog urplade" + +#~ msgid "Background image for panels" +#~ msgstr "Baggrundsbillede til paneler" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Baggrund til graf-widgets" + +#~ msgid "Background image for tooltips" +#~ msgstr "Baggrundsbillede til værktøjstips" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Ugennemsigtige billeder til dialoger" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Ugennemsigtig generisk dialogbaggrund" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Ugennemsigtigt tema til log ud-dialogen" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Ugennemsigtige billeder til widgets" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Ugennemsigtigt baggrundsbillede til paneler" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Ugennemsigtigt baggrundsbillede til værktøjstips" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Konfigurationsfil til KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Tjenestebeskrivelser" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Kunne ikke oprette en %1-ScriptEngine til widgetten %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Initialisering af script mislykkedes" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Mærkedage" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Begivenheder" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Gøremål" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Andet" + +#~ msgid "Previous Month" +#~ msgstr "Forrige måned" + +#~ msgid "Previous Year" +#~ msgstr "Forrige år" + +#~ msgid "Previous Decade" +#~ msgstr "Forrige årti" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "I dag" + +#~ msgid "Reset calendar to today" +#~ msgstr "Nulstil kalender til i dag" + +#~ msgid "Next Month" +#~ msgstr "Næste måned" + +#~ msgid "Next Year" +#~ msgstr "Næste år" + +#~ msgid "Next Decade" +#~ msgstr "Næste årti" + +#, fuzzy +#~| msgid "Next Month" +#~ msgid "Months" +#~ msgstr "Næste måned" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "Annullér" + +#~ msgid "Run the Associated Application" +#~ msgstr "Kør det associerede program" + +#~ msgid "Open with %1" +#~ msgstr "Åbn med %1" + +#~ msgid "Accessibility" +#~ msgstr "Tilgængelighed" + +#~ msgid "Application Launchers" +#~ msgstr "Startmenuer" + +#~ msgid "Astronomy" +#~ msgstr "Astronomi" + +#~ msgid "Date and Time" +#~ msgstr "Dato og klokkeslæt" + +#~ msgid "Development Tools" +#~ msgstr "Udviklingsværktøjer" + +#~ msgid "Education" +#~ msgstr "Uddannelse" + +#~ msgid "Environment and Weather" +#~ msgstr "Miljø og vejr" + +#~ msgid "Examples" +#~ msgstr "Eksempler" + +#~ msgid "File System" +#~ msgstr "Filsystem" + +#~ msgid "Fun and Games" +#~ msgstr "Spil og spas" + +#~ msgid "Graphics" +#~ msgstr "Grafik" + +#~ msgid "Language" +#~ msgstr "Sprog" + +#~ msgid "Mapping" +#~ msgstr "Kort" + +#~ msgid "Miscellaneous" +#~ msgstr "Diverse" + +#~ msgid "Multimedia" +#~ msgstr "Multimedie" + +#~ msgid "Online Services" +#~ msgstr "Online tjenester" + +#~ msgid "Productivity" +#~ msgstr "Produktivitet" + +#~ msgid "System Information" +#~ msgstr "Systeminformation" + +#~ msgid "Utilities" +#~ msgstr "Værktøjer" + +#~ msgid "Windows and Tasks" +#~ msgstr "Vinduer og opgaver" + +#~ msgid "Clipboard" +#~ msgstr "Udklipsholder" + +#~ msgid "Tasks" +#~ msgstr "Opgaver" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Redigér %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Standardindstillinger for tema osv." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Farveskema som skal bruges til programmer." + +#~ msgid "Preview Images" +#~ msgstr "Forhåndsvis billeder" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Forhåndsvisning af login-håndteringen" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Forhåndsvisning af låseskærmen" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Forhåndsvisning af brugerskifter" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Forhåndsvisning af virtuel skrivebordsvælger" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Forhåndsvisning af opstartsskærm" + +#~ msgid "Preview for KRunner" +#~ msgstr "Forhåndsvisning af KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Forhåndsvisning af vinduesdekorationer" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Forhåndsvisning af vinduesskifter" + +#~ msgid "Login Manager" +#~ msgstr "Login-håndtering" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Hovedscript til login-håndtering" + +#~ msgid "Logout Dialog" +#~ msgstr "Log ud-dialog" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Hovedscript til log ud-dialog" + +#~ msgid "Screenlocker" +#~ msgstr "Skærmlås" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Hovedscript til låseskærm" + +#~ msgid "UI for fast user switching" +#~ msgstr "Brugerflade til hurtigt brugerskift" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Hovedscript til brugerskifter" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Skift mellem virtuelle skriveborde" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Hovedscript til virtuel skrivebordsvælger" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Bekendtgørelser med on-screen-display" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Hovedscript til bekendtgørelser med on-screen-display" + +#~ msgid "Splash Screen" +#~ msgstr "Opstartsskærm" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Hovedscript til opstartsskærm" + +#~ msgid "KRunner UI" +#~ msgstr "KRunner-brugerflade" + +#~ msgid "Main Script KRunner" +#~ msgstr "Hovedscript til KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Vinduesdekoration" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Hovedscript til vinduesdekoration" + +#~ msgid "Window Switcher" +#~ msgstr "Vinduesskifter" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Hovedscript til vinduesskifter" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Afslut tilpasning af layout" + +#~ msgid "Customize Layout..." +#~ msgstr "Tilpas layout..." + +#~ msgid "Fetching file type..." +#~ msgstr "Henter filtype..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Indstilling af %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Fjern denne %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Indstilling af %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Indstilling af %1..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Billeder med lav farve til dialoger" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Generisk dialogbaggrund med lav farve" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Tema til log ud-dialog med lav farve" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Baggrundsbillede til widgets med lav farve" + +#~ msgid "Low color analog clock face" +#~ msgstr "Front til analogt ur med lav farve" + +#~ msgid "Low color background image for panels" +#~ msgstr "Baggrundsbillede til paneler med lav farve" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Baggrund til graf-widgets med lav farve" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Baggrundsbillede til værktøjstips med lav farve" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Plasma pakkehåndtering" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Generér en SHA1-hash for pakken i " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Til at installere eller fjerne. Påvirker pakker installeret for alle " +#~ "brugere." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Typen af pakke, f.eks. tema, baggrundsbillede, plasmoid, datamotor, " +#~ "runner, layout-skabelon, osv." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Installér pakken i " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Vis information om pakken " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Opgradér pakken i " + +#~ msgid "List installed packages" +#~ msgstr "Liste over installerede pakker" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "Oplist alle kendte pakketyper som kan installeres" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Fjern pakken kaldet " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Absolut sti til pakkens rod. Hvis ikke angivet, vil standard datamapper " +#~ "for denne KDE-session blive gennemsøgt i stedet." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Kunne ikke generere pakke-hash for %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "SHA1-hash for pakken i %1: \"%2\"" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "baggrundsbillede" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "pakke" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "tema" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "datamotor" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "runner" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "baggrundsbillede-plugin" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "udseende og fremtoning" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "skal" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "layout-skabelon" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "kwin-effekt" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "vinduesskifter" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "kwin-script" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "" +#~ "Kunne ikke finde passende installationsprogram til pakke af typen %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "Oplister tjenestetyper: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Fejl: Plugin %1 er ikke installeret." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Enten installér, fjern, opgradér eller vis liste er påkrævet." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Fejl: Kan ikke finde plugin-metadata: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Viser info for pakken: %1" + +#~ msgid " Name : %1" +#~ msgstr " Navn : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Kommentar: %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Plugin : %1" + +#~ msgid " Author : %1" +#~ msgstr " Ophavsmand : %1" + +#~ msgid " Path : %1" +#~ msgstr " Sti: %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Pakkeroden og de globale indstillinger er i modstrid med hinanden, vælg " +#~ "en anden." + +#~ msgid "Addon Name" +#~ msgstr "Navn på tilføjelse" + +#~ msgid "Service Type" +#~ msgstr "Tjenestetype" + +#~ msgid "Path" +#~ msgstr "Sti" + +#~ msgid "Type Argument" +#~ msgstr "Typeargument" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Pakketyper der kan installeres med dette værktøj:" + +#~ msgid "Built in:" +#~ msgstr "Indbygget:" + +#~ msgid "DataEngine" +#~ msgstr "Datamotor" + +#~ msgid "Layout Template" +#~ msgstr "Layout-skabelon" + +#~ msgid "Look and Feel" +#~ msgstr "Udseende og fremtoning" + +#~ msgid "Package" +#~ msgstr "Pakke" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoid" + +#~ msgid "Runner" +#~ msgstr "Runner" + +#~ msgid "Shell" +#~ msgstr "Skal" + +#~ msgid "Theme" +#~ msgstr "Tema" + +#~ msgid "Wallpaper Images" +#~ msgstr "Baggrundsbilleder" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Animeret baggrundsbillede" + +#~ msgid "KWin Effect" +#~ msgstr "KWin-effekt" + +#~ msgid "KWin Window Switcher" +#~ msgstr "KWin vinduesskifter" + +#~ msgid "KWin Script" +#~ msgstr "KWin-script" + +#~ msgid "Provided by plugins:" +#~ msgstr "Leveret af plugins:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Leveret af .desktop-filer:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "Opgradering af %1 gennemført" + +#~ msgid "Successfully installed %1" +#~ msgstr "Installation af %1 gennemført" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Fejl: Installation af %1 mislykkedes: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Opgraderer pakke fra fil: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Afinstallation af %1 gennemført" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Fejl: Afinstallation af %1 mislykkedes: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Kunne ikke indlæse installationsprogram til pakketypen %1. Fejlbeskeden " +#~ "var: %2" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "Vil du fjerne %1?" diff --git a/po/de/libplasma6.po b/po/de/libplasma6.po new file mode 100644 index 0000000..6617914 --- /dev/null +++ b/po/de/libplasma6.po @@ -0,0 +1,1254 @@ +# SPDX-FileCopyrightText: 2023, 2024 Johannes Obermayr +# Burkhard Lück , 2013, 2014, 2015, 2018, 2019, 2020, 2021. +# Frederik Schwarzer , 2014, 2016, 2022, 2023. +# SPDX-FileCopyrightText: 2024 Frank Steinmetzger +msgid "" +msgstr "" +"Project-Id-Version: libplasma6\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-28 21:42+0200\n" +"Last-Translator: Johannes Obermayr \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 24.11.70\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Weitere Aktionen" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Einklappen" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Ausklappen" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Passwort" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Suchen ..." + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Suchen" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Suche leeren" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Unbekannt" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Miniprogramm %1 aktivieren" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "%1 entfernen" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Bearbeitungsmodus starten" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "%1 einrichten ..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Miniprogramme sperren" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Miniprogramme entsperren" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Bearbeitungsmodus beenden" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "" +"Ob ein Zwischenspeicher für Designs auf der Festplatte erstellt werden soll." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Die maximale Größe des Design-Zwischenspeichers auf dem Datenträger. " +"Beachten Sie, dass dies „Sparse-Dateien“ sind, sodass die maximale Größe " +"wahrscheinlich nicht erreicht wird. Ein höheres Limit zu setzen, ist hier " +"daher oft eine gute Wahl." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Alternativen anzeigen ..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Miniprogramm entfernt" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Das Miniprogramm „%1“ wurde entfernt." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Kontrollleiste entfernt" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Eine Kontrollleiste wurde entfernt." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Arbeitsfläche entfernt" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Eine Arbeitsfläche wurde entfernt." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Zurücknehmen" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Miniprogramm-Einstellungen" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Dieses Miniprogramm entfernen" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Diese Kontrollleiste entfernen" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Diese Aktivität entfernen" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Aktivitäten-Einstellungen" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Miniprogramme hinzufügen oder verwalten …" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Die angeforderte Komponente ist nicht auffindbar: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Das Wurzelelement von %1 muss vom Typ ContainmentItem sein" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Das Wurzelelement von %1 muss vom Typ PlasmoidItem sein" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Unbekanntes Miniprogramm" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Dieses Miniprogramm wurde für eine unbekannte ältere Version von Plasma " +"geschrieben und ist nicht mit Plasma %1 kompatibel. Bitte nehmen Sie mit dem " +"Autor des Miniprogramms Kontakt auf und bitten diesen um eine aktualisierte " +"Version." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 ist mit Plasma %2 nicht kompatibel" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Dieses Miniprogramm wurde für Plasma %1 geschrieben und ist nicht mit Plasma " +"%2 kompatibel. Bitte nehmen Sie mit dem Autor des Miniprogramms Kontakt auf " +"und bitten diesen um eine aktualisierte Version." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Dieses Miniprogramm wurde für Plasma %1 geschrieben und ist nicht mit Plasma " +"%2 kompatibel. Bitte aktualisieren Plasma, damit das Miniprogramm verwendet " +"werden kann." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Leider ist beim Laden von %1 ein Fehler aufgetreten." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Fehler beim Laden der QML-Datei: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Fehler beim Laden des Miniprogramms: Das Paket %1 existiert nicht." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — Einstellungen für %2" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Einstellungen für %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma-Paket" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Installieren" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Paketinstallation ist fehlgeschlagen" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Das gerade abhgelegte Paket ist ungültig." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Miniprogramme" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "%1 hinzufügen" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Symbol hinzufügen" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Hintergrundbild" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "%1 einstellen" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Inhalt abgelegt" + +#~ msgid "Add Widgets..." +#~ msgstr "Miniprogramme hinzufügen ..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Das Paket %1 (nötig für %2) kann nicht geöffnet werden." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Das Freigeben eines Miniprogramms im Netzwerk ermöglicht Ihnen den " +#~ "Zugriff darauf von einem anderen Rechner aus (wie mit einer " +#~ "Fernbedienung)." + +#~ msgid "Share this widget on the network" +#~ msgstr "Dieses Miniprogramm im Netzwerk freigeben" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Beliebigen Benutzern den Zugriff auf dieses Miniprogramm erlauben" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Ungültiger Dienst (null), es sind keine Operationen möglich." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "" +#~ "Das Bedienelement %1 definiert kein Skript-Modul, das benutzt werden soll." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Verschiedenes" + +#~ msgid "Main Script File" +#~ msgstr "Haupt-Skriptdatei" + +#~ msgid "Tests" +#~ msgstr "Tests" + +#~ msgid "Images" +#~ msgstr "Bilder" + +#~ msgid "Themed Images" +#~ msgstr "Design-Bilder" + +#~ msgid "Configuration Definitions" +#~ msgstr "Einrichtungs-Definitionen" + +#~ msgid "User Interface" +#~ msgstr "Benutzeroberfläche" + +#~ msgid "Data Files" +#~ msgstr "Datendateien" + +#~ msgid "Executable Scripts" +#~ msgstr "Ausführbare Skripte" + +#~ msgid "Screenshot" +#~ msgstr "Bildschirmfoto" + +#~ msgid "Translations" +#~ msgstr "Übersetzungen" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Einrichtungsmodell für Benutzeroberflächenseiten" + +#~ msgid "Configuration XML file" +#~ msgstr "XML-Einrichtungsdatei" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Eigener Expander für kompakte Miniprogramme" + +#~ msgid "Images for dialogs" +#~ msgstr "Bilder für Dialoge" + +#~ msgid "Generic dialog background" +#~ msgstr "Allgemeiner Dialoghintergrund" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Design für den Abmeldedialog" + +#~ msgid "Wallpaper packages" +#~ msgstr "Hintergrundbild-Pakete" + +#~ msgid "Images for widgets" +#~ msgstr "Bilder für Miniprogramme" + +#~ msgid "Background image for widgets" +#~ msgstr "Hintergrundbild für Miniprogramme" + +#~ msgid "Analog clock face" +#~ msgstr "Aussehen der analogen Uhr" + +#~ msgid "Background image for panels" +#~ msgstr "Hintergrundbild für Kontrollleisten" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Hintergrund für Grafik-Bedienelemente" + +#~ msgid "Background image for tooltips" +#~ msgstr "Hintergrundbild für Kurzinfos" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Bilder (undurchsichtig) für Dialoge" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Allgemeiner Dialoghintergrund (undurchsichtig)" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Design für den Abmeldedialog (undurchsichtig)" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Bilder (undurchsichtig) für Miniprogramme" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Hintergrundbild (undurchsichtig) für Kontrollleisten" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Hintergrundbild (undurchsichtig) für Kurzinfos" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Farben-Einrichtungsdatei" + +#~ msgid "Service Descriptions" +#~ msgstr "Dienstbeschreibungen" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Der %1-Skript-Treiber für %2 kann nicht initialisiert werden." + +#~ msgid "Script initialization failed" +#~ msgstr "Skript-Initialisierung fehlgeschlagen" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Feiertage" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Termine" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Aufgabe" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Weitere" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Vorheriger Monat" + +#~ msgid "Previous Year" +#~ msgstr "Vorheriges Jahr" + +#~ msgid "Previous Decade" +#~ msgstr "Vorheriges Jahrzehnt" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Heute" + +#~ msgid "Reset calendar to today" +#~ msgstr "Kalender auf den heutigen Tag zurücksetzen" + +#~ msgid "Next Month" +#~ msgstr "Nächster Monat" + +#~ msgid "Next Year" +#~ msgstr "Nächstes Jahr" + +#~ msgid "Next Decade" +#~ msgstr "Nächstes Jahrzehnt" + +#~ msgid "Days" +#~ msgstr "Tage" + +#~ msgid "Months" +#~ msgstr "Monate" + +#~ msgid "Years" +#~ msgstr "Jahre" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "Abbrechen" + +#~ msgid "Run the Associated Application" +#~ msgstr "Die zugewiesene Anwendung starten" + +#~ msgid "Open with %1" +#~ msgstr "Öffnen mit %1" + +#~ msgid "Accessibility" +#~ msgstr "Zugangshilfen" + +#~ msgid "Application Launchers" +#~ msgstr "Programmstarter" + +#~ msgid "Astronomy" +#~ msgstr "Astronomie" + +#~ msgid "Date and Time" +#~ msgstr "Datum und Zeit" + +#~ msgid "Development Tools" +#~ msgstr "Entwicklungswerkzeuge" + +#~ msgid "Education" +#~ msgstr "Lernprogramme" + +#~ msgid "Environment and Weather" +#~ msgstr "Wetter und Umwelt" + +#~ msgid "Examples" +#~ msgstr "Beispiele" + +#~ msgid "File System" +#~ msgstr "Dateisystem" + +#~ msgid "Fun and Games" +#~ msgstr "Spiele und Spaß" + +#~ msgid "Graphics" +#~ msgstr "Grafik" + +#~ msgid "Language" +#~ msgstr "Sprache" + +#~ msgid "Mapping" +#~ msgstr "Zuordnung" + +#~ msgid "Miscellaneous" +#~ msgstr "Verschiedenes" + +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + +#~ msgid "Online Services" +#~ msgstr "Online-Dienste" + +#~ msgid "Productivity" +#~ msgstr "Produktivität" + +#~ msgid "System Information" +#~ msgstr "Systeminformationen" + +#~ msgid "Utilities" +#~ msgstr "Dienstprogramme" + +#~ msgid "Windows and Tasks" +#~ msgstr "Fenster und Prozesse" + +#~ msgid "Clipboard" +#~ msgstr "Zwischenablage" + +#~ msgid "Tasks" +#~ msgstr "Aufgaben" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "%1 bearbeiten ..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Standardeinstellungen für Designs etc." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Farbschema für Anwendungen." + +#~ msgid "Preview Images" +#~ msgstr "Vorschaubilder" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Vorschau für die Anmeldungsverwaltung" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Vorschau für die Bildschirmsperre" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Vorschau für den Benutzerwechsel" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Vorschau für den Umschalter virtueller Arbeitsflächen" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Vorschau für den Startbildschirm" + +#~ msgid "Preview for KRunner" +#~ msgstr "Vorschau für KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Vorschau für Fensterdekorationen" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Vorschau für Fensterwechsler" + +#~ msgid "Login Manager" +#~ msgstr "Anmeldungsverwaltung" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Haupt-Skript für den Anmeldungsverwaltung" + +#~ msgid "Logout Dialog" +#~ msgstr "Abmeldungsdialog" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Haupt-Skript für den Abmeldungsdialog" + +#~ msgid "Screenlocker" +#~ msgstr "Bildschirmsperre" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Haupt-Skript für die Bildschirmsperre" + +#~ msgid "UI for fast user switching" +#~ msgstr "Oberfläche für schnellen Benutzerwechsel" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Haupt-Skript für den Benutzerwechsel" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Umschalten virtueller Arbeitsflächen" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Haupt-Skript für den Umschalter virtueller Arbeitsflächen" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Benachrichtigungen über On-Screen-Anzeige" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Haupt-Skript für Benachrichtigungen über On-Screen-Anzeige" + +#~ msgid "Splash Screen" +#~ msgstr "Startbildschirm" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Haupt-Skript für den Startbildschirm" + +#~ msgid "KRunner UI" +#~ msgstr "KRunner-Oberfläche" + +#~ msgid "Main Script KRunner" +#~ msgstr "Haupt-Skript für KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Fensterdekoration" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Haupt-Skript für Fensterdekoration" + +#~ msgid "Window Switcher" +#~ msgstr "Fensterwechsler" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Haupt-Skript für den Fensterwechsler" + +#~ msgid "Fetching file type..." +#~ msgstr "Dateityp wird bezogen ..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1-Optionen" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "„%1“ entfernen" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Einstellungen für %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Einstellungen für %1 ..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Bilder für Dialoge (wenig Farben)" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Allgemeiner Dialoghintergrund (wenig Farben)" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Design für den Abmeldedialog (wenig Farben)" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Hintergrundbild für Miniprogramme (wenig Farben)" + +#~ msgid "Low color analog clock face" +#~ msgstr "Aussehen der analogen Uhr (wenig Farben)" + +#~ msgid "Low color background image for panels" +#~ msgstr "Hintergrundbild für Kontrollleisten (wenig Farben)" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Hintergrund für Grafik-Bedienelemente (wenig Farben)" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Hintergrundbild für Kurzinfos (wenig Farben)" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Plasma-Paketverwaltung" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "SHA1-Hash für das Paket in generieren" + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Zum Installieren oder Entfernen, beeinflusst Plasma-Pakete für alle " +#~ "Benutzer." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Der Pakettyp, z. B. Design, Hintergrundbild, Plasmoid, Datenquelle, " +#~ "Starter, Layout-Vorlage usw." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Paket von installieren" + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Informationen für Paket anzeigen" + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Paket von aktualisieren" + +#~ msgid "List installed packages" +#~ msgstr "Installierte Pakete anzeigen" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "Alle Arten von Paketen anzeigen, die installiert werden können" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Paket namens entfernen" + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Absoluter Pfad zum Paket. Falls nicht angegeben, werden die Standard-" +#~ "Datenpfade dieser KDE-Sitzung durchsucht." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "" +#~ "Das Generieren des Hash-Wertes für das Paket „%1“ ist fehlgeschlagen" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "SHA1-Hash für das Paket in %1: „%2“" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "Hintergrundbild" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "Plasmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "Paket" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "Design" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "Datenquelle" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "Starter" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "Hintergrundbild-Modul" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "Aussehen und Handhabung" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "Shell" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "Layout-Vorlage" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "KWin-Effekt" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "Fensterwechsler" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "KWin-Skript" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "" +#~ "Es wurde keine passende Installationsroutine für Pakete des Typs %1 " +#~ "gefunden" + +#~ msgid "Listing service types: %1" +#~ msgstr "Diensttypen werden aufgelistet: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Fehler: Das Modul %1 ist nicht installiert." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "" +#~ "Entweder „install“, „remove“, „upgrade“ oder „list“ muss angegeben werden." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Fehler: Metadaten des Moduls wurden nicht gefunden: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Anzeige der Informationen für Paket: %1" + +#~ msgid " Name : %1" +#~ msgstr " Name : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Kommentar : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Modul : %1" + +#~ msgid " Author : %1" +#~ msgstr " Autor : %1" + +#~ msgid " Path : %1" +#~ msgstr " Pfad : %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Die packageroot- und die globalen Optionen stehen in Konflikt zueinander. " +#~ "Bitte benutzen Sie nur eine von beiden." + +#~ msgid "Addon Name" +#~ msgstr "Name der Erweiterung" + +#~ msgid "Service Type" +#~ msgstr "Diensttyp" + +#~ msgid "Path" +#~ msgstr "Pfad" + +#~ msgid "Type Argument" +#~ msgstr "Typ-Argument" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "" +#~ "Arten von Paketen, die mit diesem Werkzeug installiert werden können:" + +#~ msgid "Built in:" +#~ msgstr "Eingebaut:" + +#~ msgid "DataEngine" +#~ msgstr "Datenquelle" + +#~ msgid "Layout Template" +#~ msgstr "Layout-Vorlage" + +#~ msgid "Look and Feel" +#~ msgstr "Erscheinungsbild" + +#~ msgid "Package" +#~ msgstr "Paket" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoid" + +#~ msgid "Runner" +#~ msgstr "Starter" + +#~ msgid "Shell" +#~ msgstr "Shell" + +#~ msgid "Theme" +#~ msgstr "Design" + +#~ msgid "Wallpaper Images" +#~ msgstr "Hintergrundbilder" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Animiertes Hintergrundbild" + +#~ msgid "KWin Effect" +#~ msgstr "KWin-Effekt" + +#~ msgid "KWin Window Switcher" +#~ msgstr "KWin-Fensterwechsler" + +#~ msgid "KWin Script" +#~ msgstr "KWin-Skript" + +#~ msgid "Provided by plugins:" +#~ msgstr "Bereitgestellt über Module:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Bereitgestellt über .desktop-Dateien:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "Erfolgreich aktualisiert: %1" + +#~ msgid "Successfully installed %1" +#~ msgstr "Erfolgreich installiert: %1" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Fehler: Installation von %1 fehlgeschlagen: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Paket wird aktualisiert von Datei: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Erfolgreich deinstalliert: %1" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Fehler: Deinstallation von %1 fehlgeschlagen: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Die Installationsroutine für Pakete des Typs %1 kann nicht geladen " +#~ "werden. Die Fehlermeldung lautet: %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Der Basisordner des Pakts kann nicht erstellt werden: %1" + +#~ msgid "No such file: %1" +#~ msgstr "Datei nicht gefunden: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "" +#~ "Das Paket lässt sich nicht öffnen. Nicht unterstütztes Archivformat: %1 %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "Die Paketdatei lässt sich nicht öffnen: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "Keine Metadatendatei im Paket: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "Der Modulname des Pakets wurde nicht angegeben: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "Der Modulname %1 des Pakets enthält ungültige Zeichen" + +#~ msgid "%1 already exists" +#~ msgstr "%1 existiert bereits." + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Das Paket kann nicht zum Ziel verschoben werden: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Das Paket kann nicht zum Ziel kopiert werden: %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Der lokale Dienstordner des Pakts kann nicht erstellt werden: %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "Das Paket kann nicht als Dienst registriert werden. das ist nicht " +#~ "zwangsläufig ein schwerwiegender Fehler: %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 existiert nicht" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Das Paket kann nicht gelöscht werden von: %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "Möchten Sie „%1“ wirklich entfernen?" + +#~ msgid "Applets furniture" +#~ msgstr "Einrichtung von Miniprogrammen" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "Benutzeroberfläche für das Hinzufügen von Miniprogrammen" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "Benutzeroberfläche für die Ansichten, die Container anzeigen" + +#~ msgid "Default layout file" +#~ msgstr "Standard-Layoutdatei" + +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "Standardmodule für Container, Container-Aktionen usw." + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "Fehlermeldung, wenn ein Miniprogramm nicht geladen werden kann" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "" +#~ "QML-Komponente, die ein Miniprogramm in einem Nachrichtenfenster anzeigt" + +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Kompakte Darstellung eines Miniprogramms, wenn es in einem " +#~ "Nachrichtenfenster zusammengeklappt ist - zum Beispiel als Symbol. " +#~ "Miniprogramme können diese Komponente überschreiben." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "QML-Komponente für den Einrichtungsdialog von Miniprogrammen" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "QML-Komponente für den Einrichtungsdialog von Containern" + +#~ msgid "Panel configuration UI" +#~ msgstr "Benutzeroberfläche zur Einrichtung der Kontrollleiste" + +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "QML-Komponente für die Auswahl eines alternativen Miniprogramms" + +#~ msgid "Theme preview thumbnail" +#~ msgstr "Design-Vorschaubild" + +#~ msgid "Ok" +#~ msgstr "OK" + +#~ msgid "search term" +#~ msgstr "Suchbegriff" + +#~ msgid "Unnamed" +#~ msgstr "Unbenannt" + +#~ msgid "Panel" +#~ msgstr "Kontrollleiste" + +#~ msgid "Shortcut Settings" +#~ msgstr "Tastenkürzel einrichten" + +#~ msgid "Settings" +#~ msgstr "Einstellungen" + +#~ msgctxt "@title:window" +#~ msgid "%1 Settings" +#~ msgstr "%1-Einstellungen" + +#~ msgid "Keyboard Shortcut" +#~ msgstr "Tastenkürzel" + +#~ msgid "Main Config UI File" +#~ msgstr "Haupt-UI-Einrichtungsdatei" + +#~ msgid "Unknown ContainmentActions" +#~ msgstr "Unbekannte Container-Aktionen" + +#~ msgid "This plugin needs to be configured" +#~ msgstr "Dieses Modul muss eingerichtet werden" + +#~ msgid "Animation scripts" +#~ msgstr "Animationsskripte" + +#~ msgid "This object could not be created." +#~ msgstr "Dieses Objekt kann nicht erzeugt werden." + +#~ msgid "" +#~ "This object could not be created for the following reason:

%1

" +#~ msgstr "" +#~ "Dieses Objekt kann aus folgendem Grund nicht erzeugt werden:

%1" + +#~ msgid "" +#~ "There was an error attempting to exec the associated application with " +#~ "this widget." +#~ msgstr "" +#~ "Beim Ausführen der zugehörigen Anwendung zu diesem Miniprogramme ist ein " +#~ "Fehler aufgetreten." + +#~ msgctxt "Error message, access to a remote service failed." +#~ msgid "Invalid token." +#~ msgstr "Ungültiges Zeichen." + +#~ msgctxt "Error message, access to a remote service failed." +#~ msgid "Matching password required." +#~ msgstr "Passendes Passwort erforderlich." + +#~ msgctxt "Error message, access to a remote service failed." +#~ msgid "Access denied." +#~ msgstr "Zugriff verweigert." + +#~ msgid "Unknown error." +#~ msgstr "Unbekannter Fehler." + +#~ msgctxt "" +#~ "%1 is the name of a plasmoid, %2 the name of the machine that plasmoid is " +#~ "published on" +#~ msgid "%1 on %2" +#~ msgstr "%1 auf %2" + +#~ msgid "Share" +#~ msgstr "Freigeben" + +#~ msgid "Job no longer valid, operation is not enabled." +#~ msgstr "Job nicht länger gültig, die Operation ist nicht aktiviert." + +#~ msgid "Job no longer valid, invalid parameters." +#~ msgstr "Job nicht länger gültig, ungültige Parameter." + +#~ msgid "Timeout." +#~ msgstr "Zeitüberschreitung." + +#~ msgid "Server sent an invalid plasmoid package." +#~ msgstr "Der Server hat ein ungültiges Plasmoid-Paket übermittelt." + +#~ msgid "You are about to open a remote widget on your system.
" +#~ msgstr "" +#~ "Sie sind gerade dabei, ein entferntes Miniprogramm auf Ihrem Rechner zu " +#~ "öffnen.
" + +#~ msgid "" +#~ msgstr "
" + +#~ msgid "" +#~ msgstr "" + +#~ msgid "" +#~ "" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ "" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ msgstr "" + +#~ msgid "
Name:  %1
Name:  %1
Description:  %1
Beschreibung:  %1
Author:  %1 <%2>
Autor:  %1 <%2>
Server:  %1
Server:  %1
" +#~ msgstr "" + +#~ msgid "

Are you sure you want to open this widget on your system?" +#~ msgstr "" +#~ "

Sind Sie sicher, dass Sie dieses Miniprogramm auf Ihrem Rechner " +#~ "öffnen möchten?" + +#~ msgid "Remote Widget" +#~ msgstr "Entferntes Miniprogramm" + +#~ msgid "Open Widget" +#~ msgstr "Miniprogramm öffnen" + +#~ msgid "Reject Widget" +#~ msgstr "Miniprogramm ablehnen" + +#~ msgctxt "A remote widget was rejected by the user." +#~ msgid "User rejected" +#~ msgstr "Benutzer hat abgelehnt" + +#~ msgid "Timeout" +#~ msgstr "Zeitüberschreitung" + +#~ msgid "" +#~ "Your system does not provide support for the 'remote widgets' feature. " +#~ "Access Failed." +#~ msgstr "" +#~ "Ihr System unterstützt das Freigeben von Miniprogrammen nicht. Zugriff " +#~ "fehlgeschlagen." + +#~ msgid "Allow everybody access to %1." +#~ msgstr "Jedem den Zugriff auf %1 erlauben." + +#~ msgid "Deny everybody access to %1" +#~ msgstr "Niemanden den Zugriff auf %1 erlauben." + +#~ msgid "Allow %1 access to all services." +#~ msgstr "%1 den Zugriff auf alle Dienste erlauben." + +#~ msgid "Deny %1 access to all services." +#~ msgstr "%1 den Zugriff auf alle Dienste verbieten." + +#~ msgid "Allow access to %1, by %2." +#~ msgstr "Den Zugriff auf %1 durch %2 erlauben." + +#~ msgid "Deny access to %1, by %2." +#~ msgstr "Den Zugriff auf %1 durch %2 verbieten." + +#~ msgid "Allow access to %1, by %2?" +#~ msgstr "Den Zugriff auf %1 durch %2 erlauben?" + +#~ msgid "You have requested access to the %1 hosted at %2." +#~ msgstr "Sie haben den Zugriff auf %1 (freigebeben auf %2) angefordert." + +#~ msgid "Incoming connection request" +#~ msgstr "Eingehende Verbindungsanfrage" + +#~ msgid "Connect with remote widget" +#~ msgstr "Mit freigegebenem Miniprogramm verbinden" + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not locate the %1 package required for the %2 widget." +#~ msgstr "Das Paket %1 (nötig für %2) kann nicht gefunden werden." diff --git a/po/el/libplasma6.po b/po/el/libplasma6.po new file mode 100644 index 0000000..94e0736 --- /dev/null +++ b/po/el/libplasma6.po @@ -0,0 +1,950 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Dimitris Kardarakos , 2015, 2016. +# Dimitrys Meliates , 2024. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-31 12:02+0300\n" +"Last-Translator: Αντώνης Γέραλης \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 24.08.0\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Περισσότερες ενέργειες" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Σύμπτυξη" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Επέκταση" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Κωδικός πρόσβασης" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Αναζήτηση…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Αναζήτηση" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Καθαρισμός αναζήτησης" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Άγνωστο" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Ενεργοποίηση συστατικού %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Αφαίρεση %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Έναρξη επεξεργασίας" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Διαμόρφωση %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Κλείδωμα συστατικών" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Ξεκλείδωμα συστατικών" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Έξοδος επεξεργασίας" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Δημιουργία ή όχι λανθάνουσας μνήμης δίσκου για το θέμα." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Το μέγιστο μέγεθος της λανθάνουσας μνήμης του Θέματος στον δίσκο, σε " +"kilobytes. Σημειώστε πως αυτά τα αρχεία έχουν μεγάλο βαθμό διασποράς, " +"επομένως ενδέχεται να μη χρησιμοποιηθεί το μέγιστο μέγεθος. Συνεπώς, ο " +"ορισμός ενός μεγάλου μεγέθους είναι συχνά μια αρκετά ασφαλής επιλογή." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Εναλλακτικά..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Το συστατικό αφαιρέθηκε" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Το συστατικό «%1» αφαιρέθηκε." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Ο πίνακας αφαιρέθηκε" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Ένας πίνακας αφαιρέθηκε." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Η επιφάνεια εργασίας αφαιρέθηκε" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Μια επιφάνεια εργασίας αφαιρέθηκε." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Αναίρεση" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Ρυθμίσεις συστατικού" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Αφαίρεση του συστατικού" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Αφαίρεση του πίνακα" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Αφαίρεση της δραστηριότητας" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Ρυθμίσεις δραστηριότητας" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Προσθήκη συστατικών…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Αδυναμία εύρεσης του απαιτούμενου συστατικού: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Το ριζικό στοιχείο του %1 πρέπει να είναι τύπου ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Το ριζικό στοιχείο του %1 πρέπει να είναι τύπου PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Άγνωστη μικροεφαρμογή" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Αυτό το συστατικό γράφτηκε για μια άγνωστη παλαιότερη έκδοση του Plasma και " +"δεν είναι συμβατό με το Plasma %1. Παρακαλούμε επικοινωνήστε με τον " +"συγγραφέα του συστατικού για μια ενημερωμένη έκδοση." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "Το %1 δεν είναι συμβατό με το Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Αυτό το συστατικό γράφτηκε για το Plasma %1 και δεν είναι συμβατό με το " +"Plasma %2. Παρακαλούμε επικοινωνήστε με τον δημιουργό του συστατικού για μια " +"ενημερωμένη έκδοση." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Αυτό το συστατικό γράφτηκε για το Plasma %1 και δεν είναι συμβατό με το " +"Plasma %2. Παρακαλούμε ενημερώστε το Plasma για να χρησιμοποιήσετε το " +"συστατικό." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Συγγνώμη! Υπήρξε σφάλμα κατά τη φόρτωση του %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Σφάλμα φόρτωσης αρχείου QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Σφάλμα φόρτωσης μικροεφαρμογής: το πακέτο %1 δεν υπάρχει." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 Ρυθμίσεις" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Ρυθμίσεις %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Πακέτο Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Εγκατάσταση" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Αποτυχία εγκατάστασης πακέτου" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Το πακέτο που μόλις ρίξατε είναι άκυρο." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Γραφικά συστατικά" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Προσθήκη %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Προσθήκη εικονιδίου" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Ταπετσαρία" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Ορισμός %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Περιεχόμενο αφέθηκε" + +#~ msgid "Add Widgets..." +#~ msgstr "Προσθήκη γραφικών συστατικών..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "" +#~ "Αδυναμία ανοίγματος του πακέτου %1 που απαιτείται για το γραφικό " +#~ "συστατικό %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Η κοινή χρήση ενός γραφικού συστατικού στο δίκτυο σας επιτρέπει την " +#~ "πρόσβαση σε αυτό από έναν άλλο υπολογιστή σαν απομακρυσμένο χειριστήριο." + +#~ msgid "Share this widget on the network" +#~ msgstr "Διαμοιρασμός αυτού του γραφικού συστατικού στο δίκτυο" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Να επιτρέπεται ελεύθερα σε όλους η πρόσβαση σε αυτό το συστατικό" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Άκυρη (null) υπηρεσία, αδυναμία εκτέλεσης οποιασδήποτε ενέργειας." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "" +#~ "Το γραφικό συστατικό %1 δεν καθορίζει ποιο ScriptEngine θα χρησιμοποιηθεί." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Διάφορα" + +#~ msgid "Main Script File" +#~ msgstr "Κύριο αρχείο σεναρίου" + +#~ msgid "Tests" +#~ msgstr "Έλεγχοι" + +#~ msgid "Images" +#~ msgstr "Εικόνες" + +#~ msgid "Themed Images" +#~ msgstr "Εικόνες με θέμα" + +#~ msgid "Configuration Definitions" +#~ msgstr "Ορισμοί διαμόρφωσης" + +#~ msgid "User Interface" +#~ msgstr "Περιβάλλον χρήστη" + +#~ msgid "Data Files" +#~ msgstr "Αρχεία δεδομένων" + +#~ msgid "Executable Scripts" +#~ msgstr "Εκτελέσιμα σενάρια" + +#~ msgid "Screenshot" +#~ msgstr "Στιγμιότυπο οθόνης" + +#~ msgid "Translations" +#~ msgstr "Μεταφράσεις" + +#~ msgid "Configuration XML file" +#~ msgstr "Αρχείο διαμόρφωσης XML" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Προσαρμοσμένη επέκταση για συμπαγείς μικροεφαρμογές" + +#~ msgid "Images for dialogs" +#~ msgstr "Εικόνες για διαλόγους" + +#~ msgid "Generic dialog background" +#~ msgstr "Φόντο γενικού διαλόγου" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Θέμα για τον διάλογο αποσύνδεσης" + +#~ msgid "Wallpaper packages" +#~ msgstr "Πακέτα ταπετσαριών" + +#~ msgid "Images for widgets" +#~ msgstr "Εικόνες για γραφικά συστατικά" + +#~ msgid "Background image for widgets" +#~ msgstr "Εικόνα φόντου για γραφικά συστατικά" + +#~ msgid "Analog clock face" +#~ msgstr "Πρόσοψη αναλογικού ρολογιού" + +#~ msgid "Background image for panels" +#~ msgstr "Εικόνα φόντου για πίνακες" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Φόντο για γραφικά συστατικά σχεδίασης" + +#~ msgid "Background image for tooltips" +#~ msgstr "Εικόνα φόντου για υποδείξεις" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Αδιαφανείς εικόνες για διαλόγους" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Αδιαφανές φόντο γενικού διαλόγου" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Αδιαφανές θέμα για τον διάλογο αποσύνδεσης" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Αδιαφανείς εικόνες για γραφικά συστατικά" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Αδιαφανής εικόνα φόντου για πίνακες" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Αδιαφανής εικόνα φόντου για υποδείξεις" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Αρχείο διαμόρφωσης KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Περιγραφές υπηρεσιών" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "" +#~ "Αδυναμία δημιουργίας ενός ScriptEngine %1 για το γραφικό συστατικό %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Αποτυχία αρχικοποίησης σεναρίου" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Αργίες" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Γεγονότα" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Προς υλοποίηση" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Άλλα" + +#~ msgid "Previous Month" +#~ msgstr "Προηγούμενος μήνας" + +#~ msgid "Previous Year" +#~ msgstr "Προηγούμενο έτος" + +#~ msgid "Previous Decade" +#~ msgstr "Προηγούμενη δεκαετία" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Σήμερα" + +#~ msgid "Reset calendar to today" +#~ msgstr "Επαναφορά ημερολογίου στη σημερινή μέρα" + +#~ msgid "Next Month" +#~ msgstr "Επόμενος μήνας" + +#~ msgid "Next Year" +#~ msgstr "Επόμενο έτος" + +#~ msgid "Next Decade" +#~ msgstr "Επόμενη δεκαετία" + +#, fuzzy +#~| msgid "Next Month" +#~ msgid "Months" +#~ msgstr "Επόμενος μήνας" + +#~ msgid "OK" +#~ msgstr "Εντάξει" + +#~ msgid "Cancel" +#~ msgstr "Ακύρωση" + +#~ msgid "Run the Associated Application" +#~ msgstr "Εκτέλεση της συσχετισμένης εφαρμογής" + +#~ msgid "Open with %1" +#~ msgstr "Άνοιγμα με %1" + +#~ msgid "Accessibility" +#~ msgstr "Προσβασιμότητα" + +#~ msgid "Application Launchers" +#~ msgstr "Εκτελεστές εφαρμογών" + +#~ msgid "Astronomy" +#~ msgstr "Αστρονομία" + +#~ msgid "Date and Time" +#~ msgstr "Ημερομηνία και ώρα" + +#~ msgid "Development Tools" +#~ msgstr "Εργαλεία ανάπτυξης" + +#~ msgid "Education" +#~ msgstr "Εκπαίδευση" + +#~ msgid "Environment and Weather" +#~ msgstr "Περιβάλλον και καιρός" + +#~ msgid "Examples" +#~ msgstr "Παραδείγματα" + +#~ msgid "File System" +#~ msgstr "Σύστημα αρχείων" + +#~ msgid "Fun and Games" +#~ msgstr "Διασκέδαση και παιχνίδια" + +#~ msgid "Graphics" +#~ msgstr "Γραφικά" + +#~ msgid "Language" +#~ msgstr "Γλώσσα" + +#~ msgid "Miscellaneous" +#~ msgstr "Διάφορα" + +#~ msgid "Multimedia" +#~ msgstr "Πολυμέσα" + +#~ msgid "Online Services" +#~ msgstr "Διαδικτυακές υπηρεσίες" + +#~ msgid "Productivity" +#~ msgstr "Παραγωγικότητα" + +#~ msgid "System Information" +#~ msgstr "Πληροφορίες συστήματος" + +#~ msgid "Utilities" +#~ msgstr "Εργαλεία" + +#~ msgid "Windows and Tasks" +#~ msgstr "Παράθυρα και εργασίες" + +#~ msgid "Clipboard" +#~ msgstr "Πρόχειρο" + +#~ msgid "Tasks" +#~ msgstr "Εργασίες" + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Προκαθορισμένες ρυθμίσεις για θέμα, κλπ." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Θέμα χρωμάτων που θα χρησιμοποιηθεί στις εφαρμογές." + +#~ msgid "Preview Images" +#~ msgstr "Προεπισκόπηση εικόνων" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Προεπισκόπηση για τον διαχειριστή εισόδου" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Προεπισκόπηση για το κλείδωμα οθόνης" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Προεπισκόπηση για την εναλλαγή χρήστη" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Προεπισκόπηση για την εναλλαγή εικονικής επιφάνειας εργασίας" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Προεπισκόπηση για την οθόνη εκκίνησης" + +#~ msgid "Preview for KRunner" +#~ msgstr "Προεπισκόπηση για τον KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Προεπισκόπηση για τις διακοσμήσεις παραθύρου" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Προεπισκόπηση για την εναλλαγή παραθύρων" + +#~ msgid "Login Manager" +#~ msgstr "Διαχειριστής εισόδου" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Κύριο σενάριο για τον διαχειριστή εισόδου" + +#~ msgid "Logout Dialog" +#~ msgstr "Διάλογος αποσύνδεσης" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Κύριο σενάριο για τον διάλογο αποσύνδεσης" + +#~ msgid "Screenlocker" +#~ msgstr "Κλείδωμα οθόνης" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Κύριο σενάριο για το κλείδωμα οθόνης" + +#~ msgid "UI for fast user switching" +#~ msgstr "Γραφικό περιβάλλον για γρήγορη εναλλαγή χρήστη" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Κύριο σενάριο για την εναλλαγή χρήστη" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Εναλλαγή εικονικής επιφάνειας εργασίας" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Κύριο σενάριο για την εναλλαγή εικονικής επιφάνειας εργασίας" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Εμφάνιση ειδοποιήσεων στην οθόνη" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Κύριο σενάριο για την εμφάνιση ειδοποιήσεων στην οθόνη" + +#~ msgid "Splash Screen" +#~ msgstr "Οθόνη εκκίνησης" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Κύριο σενάριο για την οθόνη εκκίνησης" + +#~ msgid "KRunner UI" +#~ msgstr "KRunner UI" + +#~ msgid "Main Script KRunner" +#~ msgstr "Κύριο σενάριο KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Διακοσμήσεις παραθύρων" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Κύριο σενάριο για τις διακοσμήσεις παραθύρων" + +#~ msgid "Window Switcher" +#~ msgstr "Πρόγραμμα εναλλαγής παραθύρων" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Κύριο σενάριο για την εναλλαγή παραθύρων" + +#~ msgid "Fetching file type..." +#~ msgstr "Ανάκτηση τύπου αρχείου..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Επιλογές του %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Ρυθμίσεις του %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Ρυθμίσεις του %1 ..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Εικόνες χαμηλού χρωματισμού για διαλόγους" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Φόντο γενικού διαλόγου με χαμηλό χρωματισμό" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Θέμα χαμηλού χρωματισμού για τον διάλογο αποσύνδεσης" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Εικόνα φόντου χαμηλού χρωματισμού για γραφικά συστατικά" + +#~ msgid "Low color analog clock face" +#~ msgstr "Πρόσοψη αναλογικού ρολογιού με χαμηλό χρωματισμό" + +#~ msgid "Low color background image for panels" +#~ msgstr "Εικόνα φόντου χαμηλού χρωματισμού για πίνακες" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Φόντο χαμηλού χρωματισμού για γραφικά συστατικά σχεδίασης" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Εικόνα φόντου χαμηλού χρωματισμού για υποδείξεις" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Διαχειριστής πακέτων Plasma" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Δημιουργία μιας τιμής κατακερματισμού SHA1 για το πακέτο στο " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Για εγκατάσταση ή αφαίρεση, λειτουργεί για τα πακέτα που έχουν " +#~ "εγκατασταθεί για όλους τους χρήστες." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Ο τύπος του πακέτου, π.χ. θέμα, ταπετσαρία, πλασμοειδές, μηχανή " +#~ "δεδομένων, εκτελεστής, διάταξη προτύπου κτλ." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Εγκατάσταση του πακέτου στο " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Εμφάνιση πληροφοριών του πακέτου στο " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Ενημέρωση του πακέτου στο " + +#~ msgid "List installed packages" +#~ msgstr "Εμφάνιση εγκατεστημένων πακέτων" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "" +#~ "Εμφανίζει όλους τους γνωστούς τύπους πακέτων που μπορούν να εγκατασταθούν" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Αφαίρεση του πακέτου με όνομα " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Απόλυτη διαδρομή του βασικού καταλόγου του πακέτου. Αν δε δοθεί, θα γίνει " +#~ "αναζήτηση στους τυπικούς καταλόγους δεδομένων της συνεδρίας του KDE." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Αποτυχία δημιουργίας τιμής κατακερματισμού πακέτου για το %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "Τιμή κατακερματισμού SHA1 για το πακέτο στο %1: '%2'" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "ταπετσαρία" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "πλασμοειδές" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "πακέτο" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "θέμα" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "μηχανή δεδομένων" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "εκτελεστής" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "πρόσθετο ταπετσαρίας" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "εμφάνιση και αίσθηση" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "κέλυφος" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "πρότυπο-διάταξης" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "εφέ kwin" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "εναλλαγή παραθύρων" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "σενάριο kwin" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "" +#~ "Αδυναμία εύρεσης κατάλληλου προγράμματος εγκατάστασης για πακέτο τύπου %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "Λίστα τύπων υπηρεσιών: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Σφάλμα: το πρόσθετο %1 δεν είναι εγκατεστημένο." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Απαιτείται ένα από τα εξής: install, remove, upgrade, list." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Σφάλμα: αδυναμία εύρεσης των μεταδεδομένων του προσθέτου : %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Εμφάνιση πληροφοριών για το πακέτο: %1" + +#~ msgid " Name : %1" +#~ msgstr " Όνομα : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Σχόλιο : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Πρόσθετο: %1" + +#~ msgid " Author : %1" +#~ msgstr " Συγγραφέας : %1" + +#~ msgid " Path : %1" +#~ msgstr " Διαδρομή: %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Το packageroot και οι καθολικές επιλογές συγκρούονται μεταξύ τους, " +#~ "παρακαλώ επιλέξτε μόνο ένα." + +#~ msgid "Addon Name" +#~ msgstr "Όνομα πρόσθετου" + +#~ msgid "Service Type" +#~ msgstr "Τύπος υπηρεσίας" + +#~ msgid "Path" +#~ msgstr "Διαδρομή" + +#~ msgid "Type Argument" +#~ msgstr "Τύπος ορίσματος" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "" +#~ "Τύποι πακέτων που μπορούν να εγκατασταθούν μέσω αυτού του εργαλείου:" + +#~ msgid "Built in:" +#~ msgstr "Ενσωματωμένο:" + +#~ msgid "DataEngine" +#~ msgstr "Μηχανή δεδομένων" + +#~ msgid "Layout Template" +#~ msgstr "Πρότυπο διάταξης" + +#~ msgid "Look and Feel" +#~ msgstr "Εμφάνιση και αίσθηση" + +#~ msgid "Package" +#~ msgstr "Πακέτο" + +#~ msgid "Plasmoid" +#~ msgstr "Πλασμοειδές" + +#~ msgid "Runner" +#~ msgstr "Εκτελεστής" + +#~ msgid "Shell" +#~ msgstr "Κέλυφος" + +#~ msgid "Theme" +#~ msgstr "Θέμα" + +#~ msgid "Wallpaper Images" +#~ msgstr "Εικόνες ταπετσαρίας" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Ταπετσαρία με κίνηση" + +#~ msgid "KWin Effect" +#~ msgstr "Εφέ KWin" + +#~ msgid "KWin Window Switcher" +#~ msgstr "Πρόγραμμα εναλλαγής παραθύρων KWin" + +#~ msgid "KWin Script" +#~ msgstr "Σενάριο KWin" + +#~ msgid "Provided by plugins:" +#~ msgstr "Παρέχεται από τα πρόσθετα:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Παρέχεται από τα αρχεία .desktop:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "Το %1 αναβαθμίστηκε επιτυχώς" + +#~ msgid "Successfully installed %1" +#~ msgstr "Το %1 εγκαταστάθηκε επιτυχώς" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Σφάλμα: η εγκατάσταση του %1 απέτυχε: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Αναβάθμιση πακέτου από αρχείο: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Το %1 απεγκαταστάθηκε επιτυχώς" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Σφάλμα: η απεγκατάσταση του %1 απέτυχε: %2" diff --git a/po/en_GB/libplasma6.po b/po/en_GB/libplasma6.po new file mode 100644 index 0000000..ada706f --- /dev/null +++ b/po/en_GB/libplasma6.po @@ -0,0 +1,1069 @@ +# translation of plasmapkg.po to British English +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Malcolm Hunter , 2008. +# Andrew Coles , 2009, 2010. +# SPDX-FileCopyrightText: 2014, 2015, 2016, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Steve Allewell +msgid "" +msgstr "" +"Project-Id-Version: plasmapkg\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-24 12:05+0100\n" +"Last-Translator: Steve Allewell \n" +"Language-Team: British English\n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 24.05.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "More actions" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Collapse" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Expand" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Password" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Search…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Search" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Clear search" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Unknown" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Activate %1 Widget" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Remove %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Enter Edit Mode" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Configure %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Lock Widgets" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Unlock Widgets" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Exit Edit Mode" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Whether or not to create an on-disk cache for the theme." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Show Alternatives..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Widget Removed" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "The widget \"%1\" has been removed." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panel Removed" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "A panel has been removed." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Desktop Removed" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "A desktop has been removed." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Undo" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Widget Settings" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Remove this Widget" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Remove this Panel" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Remove this Activity" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Activity Settings" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Add or Manage Widgets…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Could not find requested component: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "The root item of %1 must be of type ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "The root item of %1 must be of type PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Unknown Applet" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 is not compatible with Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Sorry! There was an error loading %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Error loading QML file: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Error loading Applet: package %1 does not exist." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 Settings" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 Settings" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma Package" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Install" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Package Installation Failed" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "The package you just dropped is invalid." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Widgets" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Add %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Add Icon" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Wallpaper" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Set %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Content dropped" + +#~ msgid "Add Widgets..." +#~ msgstr "Add Widgets..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Could not open the %1 package required for the %2 widget." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." + +#~ msgid "Share this widget on the network" +#~ msgstr "Share this widget on the network" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Allow everybody to freely access this widget" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Invalid (null) service, can not perform any operations." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "The %1 widget did not define which ScriptEngine to use." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Miscellaneous" + +#~ msgid "Main Script File" +#~ msgstr "Main Script File" + +#~ msgid "Tests" +#~ msgstr "Tests" + +#~ msgid "Images" +#~ msgstr "Images" + +#~ msgid "Themed Images" +#~ msgstr "Themed Images" + +#~ msgid "Configuration Definitions" +#~ msgstr "Configuration Definitions" + +#~ msgid "User Interface" +#~ msgstr "User Interface" + +#~ msgid "Data Files" +#~ msgstr "Data Files" + +#~ msgid "Executable Scripts" +#~ msgstr "Executable Scripts" + +#~ msgid "Screenshot" +#~ msgstr "Screenshot" + +#~ msgid "Translations" +#~ msgstr "Translations" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Configuration UI pages model" + +#~ msgid "Configuration XML file" +#~ msgstr "Configuration XML file" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Custom expander for compact applets" + +#~ msgid "Images for dialogs" +#~ msgstr "Images for dialogues" + +#~ msgid "Generic dialog background" +#~ msgstr "Generic dialogue background" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Theme for the logout dialogue" + +#~ msgid "Wallpaper packages" +#~ msgstr "Wallpaper packages" + +#~ msgid "Images for widgets" +#~ msgstr "Images for widgets" + +#~ msgid "Background image for widgets" +#~ msgstr "Background image for widgets" + +#~ msgid "Analog clock face" +#~ msgstr "Analog clock face" + +#~ msgid "Background image for panels" +#~ msgstr "Background image for panels" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Background for graphing widgets" + +#~ msgid "Background image for tooltips" +#~ msgstr "Background image for tooltips" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Opaque images for dialogues" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Opaque generic dialogue background" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Opaque theme for the logout dialogue" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Opaque images for widgets" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Opaque background image for panels" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Opaque background image for tooltips" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme configuration file" + +#~ msgid "Service Descriptions" +#~ msgstr "Service Descriptions" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Could not create a %1 ScriptEngine for the %2 widget." + +#~ msgid "Script initialization failed" +#~ msgstr "Script initialisation failed" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Holidays" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Events" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Todo" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Other" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Previous Month" + +#~ msgid "Previous Year" +#~ msgstr "Previous Year" + +#~ msgid "Previous Decade" +#~ msgstr "Previous Decade" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Today" + +#~ msgid "Reset calendar to today" +#~ msgstr "Reset calendar to today" + +#~ msgid "Next Month" +#~ msgstr "Next Month" + +#~ msgid "Next Year" +#~ msgstr "Next Year" + +#~ msgid "Next Decade" +#~ msgstr "Next Decade" + +#~ msgid "Days" +#~ msgstr "Days" + +#~ msgid "Months" +#~ msgstr "Months" + +#~ msgid "Years" +#~ msgstr "Years" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "Cancel" + +#~ msgid "Run the Associated Application" +#~ msgstr "Run the Associated Application" + +#~ msgid "Open with %1" +#~ msgstr "Open with %1" + +#~ msgid "Accessibility" +#~ msgstr "Accessibility" + +#~ msgid "Application Launchers" +#~ msgstr "Application Launchers" + +#~ msgid "Astronomy" +#~ msgstr "Astronomy" + +#~ msgid "Date and Time" +#~ msgstr "Date and Time" + +#~ msgid "Development Tools" +#~ msgstr "Development Tools" + +#~ msgid "Education" +#~ msgstr "Education" + +#~ msgid "Environment and Weather" +#~ msgstr "Environment and Weather" + +#~ msgid "Examples" +#~ msgstr "Examples" + +#~ msgid "File System" +#~ msgstr "File System" + +#~ msgid "Fun and Games" +#~ msgstr "Fun and Games" + +#~ msgid "Graphics" +#~ msgstr "Graphics" + +#~ msgid "Language" +#~ msgstr "Language" + +#~ msgid "Mapping" +#~ msgstr "Mapping" + +#~ msgid "Miscellaneous" +#~ msgstr "Miscellaneous" + +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + +#~ msgid "Online Services" +#~ msgstr "Online Services" + +#~ msgid "Productivity" +#~ msgstr "Productivity" + +#~ msgid "System Information" +#~ msgstr "System Information" + +#~ msgid "Utilities" +#~ msgstr "Utilities" + +#~ msgid "Windows and Tasks" +#~ msgstr "Windows and Tasks" + +#~ msgid "Clipboard" +#~ msgstr "Clipboard" + +#~ msgid "Tasks" +#~ msgstr "Tasks" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Edit %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Default settings for theme, etc." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Colour scheme to use for applications." + +#~ msgid "Preview Images" +#~ msgstr "Preview Images" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Preview for the Login Manager" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Preview for the Lock Screen" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Preview for the Userswitcher" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Preview for the Virtual Desktop Switcher" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Preview for Splash Screen" + +#~ msgid "Preview for KRunner" +#~ msgstr "Preview for KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Preview for the Window Decorations" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Preview for Window Switcher" + +#~ msgid "Login Manager" +#~ msgstr "Login Manager" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Main Script for Login Manager" + +#~ msgid "Logout Dialog" +#~ msgstr "Logout Dialogue" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Main Script for Logout Dialogue" + +#~ msgid "Screenlocker" +#~ msgstr "Screenlocker" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Main Script for Lock Screen" + +#~ msgid "UI for fast user switching" +#~ msgstr "UI for fast user switching" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Main Script for User Switcher" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Virtual Desktop Switcher" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Main Script for Virtual Desktop Switcher" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "On-Screen Display Notifications" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Main Script for On-Screen Display Notifications" + +#~ msgid "Splash Screen" +#~ msgstr "Splash Screen" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Main Script for Splash Screen" + +#~ msgid "KRunner UI" +#~ msgstr "KRunner UI" + +#~ msgid "Main Script KRunner" +#~ msgstr "Main Script KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Window Decoration" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Main Script for Window Decoration" + +#~ msgid "Window Switcher" +#~ msgstr "Window Switcher" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Main Script for Window Switcher" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Finish Customising Layout" + +#~ msgid "Customize Layout..." +#~ msgstr "Customise Layout..." + +#~ msgid "Fetching file type..." +#~ msgstr "Fetching file type..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1 Options" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Remove this %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "%1 Settings" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "%1 Settings..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Low colour images for dialogues" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Low colour generic dialogue background" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Low colour theme for the logout dialogue" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Low colour background image for widgets" + +#~ msgid "Low color analog clock face" +#~ msgstr "Low colour analog clock face" + +#~ msgid "Low color background image for panels" +#~ msgstr "Low colour background image for panels" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Low colour background for graphing widgets" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Low colour background image for tooltips" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Plasma Package Manager" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Generate a SHA1 hash for the package at " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "For install or remove, operates on packages installed for all users." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Install the package at " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Show information of package " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Upgrade the package at " + +#~ msgid "List installed packages" +#~ msgstr "List installed packages" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "List all known package types that can be installed" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Remove the package named " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Failed to generate a Package hash for %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "SHA1 hash for Package at %1: '%2'" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "wallpaper" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "package" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "theme" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "dataengine" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "runner" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "wallpaperplugin" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "lookandfeel" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "shell" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "layout-template" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "kwineffect" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "windowswitcher" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "kwinscript" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "Could not find a suitable installer for package of type %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "Listing service types: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Error: Plugin %1 is not installed." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "One of install, remove, upgrade or list is required." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Error: Cannot find plugin metadata: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Showing info for package: %1" + +#~ msgid " Name : %1" +#~ msgstr " Name : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Comment : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Plugin : %1" + +#~ msgid " Author : %1" +#~ msgstr " Author : %1" + +#~ msgid " Path : %1" +#~ msgstr " Path : %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." + +#~ msgid "Addon Name" +#~ msgstr "Addon Name" + +#~ msgid "Service Type" +#~ msgstr "Service Type" + +#~ msgid "Path" +#~ msgstr "Path" + +#~ msgid "Type Argument" +#~ msgstr "Type Argument" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Package types that are installable with this tool:" + +#~ msgid "Built in:" +#~ msgstr "Built in:" + +#~ msgid "DataEngine" +#~ msgstr "DataEngine" + +#~ msgid "Layout Template" +#~ msgstr "Layout Template" + +#~ msgid "Look and Feel" +#~ msgstr "Look and Feel" + +#~ msgid "Package" +#~ msgstr "Package" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoid" + +#~ msgid "Runner" +#~ msgstr "Runner" + +#~ msgid "Shell" +#~ msgstr "Shell" + +#~ msgid "Theme" +#~ msgstr "Theme" + +#~ msgid "Wallpaper Images" +#~ msgstr "Wallpaper Images" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Animated Wallpaper" + +#~ msgid "KWin Effect" +#~ msgstr "KWin Effect" + +#~ msgid "KWin Window Switcher" +#~ msgstr "KWin Window Switcher" + +#~ msgid "KWin Script" +#~ msgstr "KWin Script" + +#~ msgid "Provided by plugins:" +#~ msgstr "Provided by plugins:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Provided by .desktop files:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "Successfully upgraded %1" + +#~ msgid "Successfully installed %1" +#~ msgstr "Successfully installed %1" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Error: Installation of %1 failed: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Upgrading package from file: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Successfully uninstalled %1" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Error: Uninstallation of %1 failed: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Could not load installer for package of type %1. Error reported was: %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Could not create package root directory: %1" + +#~ msgid "No such file: %1" +#~ msgstr "No such file: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "Could not open package file, unsupported archive format: %1 %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "Could not open package file: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "No metadata file in package: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "Package plugin name not specified: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "Package plugin name %1 contains invalid characters" + +#~ msgid "%1 already exists" +#~ msgstr "%1 already exists" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Could not move package to destination: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Could not copy package to destination: %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Could not create local service directory: %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "Could not register package as service (this is not necessarily fatal): %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 does not exist" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Could not delete package from: %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "Do you really want to remove this %1?" + +#~ msgid "Applets furniture" +#~ msgstr "Applets furniture" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "Explorer UI for adding widgets" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "User interface for the views that will show containments" + +#~ msgid "Default layout file" +#~ msgstr "Default layout file" + +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "Default plugins for containments, containmentActions, etc." + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "Error message shown when an applet fails to load" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "QML component that shows an applet in a popup" + +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "QML component for the configuration dialog for applets" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "QML component for the configuration dialog for containments" + +#~ msgid "Panel configuration UI" +#~ msgstr "Panel configuration UI" + +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "QML component for choosing an alternate applet" + +#~ msgid "" +#~ "A UI for writing, loading and running desktop scripts in the current live " +#~ "session" +#~ msgstr "" +#~ "A UI for writing, loading and running desktop scripts in the current live " +#~ "session" diff --git a/po/eo/libplasma6.po b/po/eo/libplasma6.po new file mode 100644 index 0000000..df20fe1 --- /dev/null +++ b/po/eo/libplasma6.po @@ -0,0 +1,345 @@ +# translation of libplasma6.pot to esperanto +# Copyright (C) 2014 Free Software Foundation, Inc. +# This file is distributed under the same license as the plasma-framework package. +# Oliver Kellogg , 2023. +# +msgid "" +msgstr "" +"Project-Id-Version: plasma-framework\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-05-31 13:26+0200\n" +"Last-Translator: Oliver Kellogg \n" +"Language-Team: esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: translate-po (https://github.com/zcribe/translate-po)\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Pli da agoj" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Malvastigi" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Vastigi" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Pasvorto" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Serĉi…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Serĉi" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Malplenigi serĉon" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Nekonata" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Aktivigi fenestraĵon %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Forigi %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Eniri redaktan reĝimon" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Agordi %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Ŝlosi fenestraĵojn" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Malŝlosi fenestraĵojn" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Eliri redaktan reĝimon" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Ĉu aŭ ne krei surdiskan kaŝmemoron por la etoso." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"La maksimuma grandeco de la surdiska Etoso-kaŝmemoro en kilobajtoj. Notu, ke " +"ĉi tiuj dosieroj estas malabundaj dosieroj, do la maksimuma grandeco eble ne " +"estas uzata. Agordi pli grandan grandecon do ofte estas sufiĉe sekura." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Montri alternativojn..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Fenestraĵo forigita" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "La fenestraĵo \"%1\" estis forigita." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panelo forigita" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Panelo estis forigita." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Labortablo forigita" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Labortablo estis forigita." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Malfari" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Agordoj de fenestraĵoj" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Forigi ĉi tiun fenestraĵon" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Forigi ĉi tiun panelon" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Forigi ĉi tiun agadon" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Agado-Agordoj" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Ne eblis trovi petitan komponanton: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "La radika objekto de %1 devas esti de tipo ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "La radika objekto de %1 devas esti de tipo PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Nekonata Apleto" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Ĉi Fenestraĵo estis skribita por nekonata pli malnova versio de Plasma kaj " +"ne estas kongrua kun Plasma %1. Bonvolu kontakti la aŭtoron de la fenestraĵo " +"por ĝisdatigita versio." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 ne estas kongrua kun Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Ĉi Fenestraĵo estis skribita por Plasma %1 kaj ne estas kongrua kun Plasma " +"%2. Bonvolu kontakti la aŭtoron de la fenestraĵo por ĝisdatigita versio." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Ĉi Fenestraĵo estis skribita por Plasma %1 kaj ne estas kongrua kun Plasma " +"%2. Bonvolu ĝisdatigi Plasma por uzi la fenestraĵon." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Pardonon, estis eraro ŝargante %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Eraro dum ŝargo de QML-dosiero: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Eraro dum ŝargo de Apleto: pako %1 ne ekzistas." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 Agordoj" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 Agordoj" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma Pako" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Instali" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Paka Instalado Malsukcesis" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "La pako, kiun vi ĵus faligis, estas nevalida." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Fenestraĵoj" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Aldoni %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Aldoni piktogramon" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Tapeto" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Agordi %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Enhavo perdiĝis" + +#~ msgid "Add Widgets..." +#~ msgstr "Aldoni fenestraĵojn..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Ne eblis malfermi la %1 pakaĵon necesan por la %2 fenestraĵo." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Kunhavigi fenestraĵon en la reto permesas al vi aliri ĉi tiun fenestraĵon " +#~ "de alia komputilo kiel teleregilo." + +#~ msgid "Share this widget on the network" +#~ msgstr "Kunhavigi ĉi tiun fenestraĵon en la reto" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Permesi al ĉiuj libere aliri ĉi tiun fenestraĵon" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Nevalida (nula) servo, ne povas fari ajnajn operaciojn." diff --git a/po/es/libplasma6.po b/po/es/libplasma6.po new file mode 100644 index 0000000..489d77d --- /dev/null +++ b/po/es/libplasma6.po @@ -0,0 +1,1103 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# SPDX-FileCopyrightText: 2013, 2014, 2015, 2016, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Eloy Cuadra +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-24 12:23+0200\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 24.05.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Más acciones" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Contraer" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Expandir" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Contraseña" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Buscar..." + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Buscar" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Borrar búsqueda" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Desconocido" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Activar el elemento gráfico %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Eliminar %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Entrar en el modo de edición" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Configurar %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Bloquear elementos gráficos" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Desbloquear elementos gráficos" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Salir del modo de edición" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Si se debe crear o no una caché en el disco para el tema." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"El tamaño máximo en kilobytes de la caché en disco para el tema. Tenga en " +"cuenta que estos archivos están muy dispersos, por lo que es posible que no " +"se utilice el tamaño máximo. Por este motivo, suele ser bastante seguro " +"especificar un tamaño mayor." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Mostrar alternativas..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Elemento gráfico eliminado" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Se ha eliminado el elemento gráfico «%1»." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panel eliminado" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Se ha eliminado un panel." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Escritorio eliminado" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Se ha eliminado un escritorio." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Deshacer" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Preferencias del elemento gráfico" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Eliminar este elemento gráfico" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Eliminar este panel" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Eliminar esta actividad" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Preferencias de la actividad" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Añadir o gestionar elementos gráficos..." + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "No se ha podido encontrar el componente solicitado: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "El elemento raíz de %1 debe ser de tipo ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "El elemento raíz de %1 debe ser de tipo PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Miniaplicación desconocida" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Este elemento gráfico fue escrito para una versión de Plasma más antigua y " +"no es compatible con Plasma %1. Póngase en contacto con el autor del " +"elemento gráfico para obtener una versión actualizada." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 no es compatible con Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Este elemento gráfico fue escrito para Plasma %1 y no es compatible con " +"Plasma %2. Póngase en contacto con el autor del elemento gráfico para " +"obtener una versión actualizada." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Este elemento gráfico fue escrito para Plasma %1 y no es compatible con " +"Plasma %2. Actualice Plasma para poder usar este elemento gráfico." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Lo sentimos: ha ocurrido un error al cargar %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Error al cargar archivo QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Error cargando miniaplicación: el paquete %1 no existe." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — Preferencias de %2" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Preferencias de %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Paquete de Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Instalar" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "La instalación del paquete ha fallado" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "El paquete que acaba de soltar no es válido." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Elementos gráficos" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Añadir %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Añadir icono" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Fondo de escritorio" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Definir %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Contenido soltado" + +#~ msgid "Add Widgets..." +#~ msgstr "Añadir elementos gráficos..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "" +#~ "No se ha podido abrir el paquete %1 que necesita el elemento gráfico %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Si comparte un elemento gráfico en la red podrá acceder a él desde otro " +#~ "equipo como un mando a distancia." + +#~ msgid "Share this widget on the network" +#~ msgstr "Compartir este elemento gráfico en la red" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "" +#~ "Permitir que todos puedan acceder libremente a este elemento gráfico" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Servicio no válido (nulo); no puede realizar operaciones." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "El elemento gráfico %1 no ha definido el motor de scripts a usar." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Varios" + +#~ msgid "Main Script File" +#~ msgstr "Archivo de script principal" + +#~ msgid "Tests" +#~ msgstr "Pruebas" + +#~ msgid "Images" +#~ msgstr "Imágenes" + +#~ msgid "Themed Images" +#~ msgstr "Imágenes temáticas" + +#~ msgid "Configuration Definitions" +#~ msgstr "Definiciones de la configuración" + +#~ msgid "User Interface" +#~ msgstr "Interfaz de usuario" + +#~ msgid "Data Files" +#~ msgstr "Archivos de datos" + +#~ msgid "Executable Scripts" +#~ msgstr "Scripts ejecutables" + +#~ msgid "Screenshot" +#~ msgstr "Captura de pantalla" + +#~ msgid "Translations" +#~ msgstr "Traducciones" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Modelo de páginas de interfaz de usuario de configuración" + +#~ msgid "Configuration XML file" +#~ msgstr "Archivo XML de configuración" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Expansor personalizado para miniaplicaciones compactas" + +#~ msgid "Images for dialogs" +#~ msgstr "Imágenes para diálogos" + +#~ msgid "Generic dialog background" +#~ msgstr "Fondo general de los diálogos" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Tema para el diálogo de fin de sesión" + +#~ msgid "Wallpaper packages" +#~ msgstr "Paquetes de fondos del escritorio" + +#~ msgid "Images for widgets" +#~ msgstr "Imágenes para los elementos gráficos" + +#~ msgid "Background image for widgets" +#~ msgstr "Imagen de fondo para los elementos gráficos" + +#~ msgid "Analog clock face" +#~ msgstr "Carátula del reloj analógico" + +#~ msgid "Background image for panels" +#~ msgstr "Imagen de fondo para los paneles" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Fondo para los elementos gráficos" + +#~ msgid "Background image for tooltips" +#~ msgstr "Imagen de fondo para las ayudas emergentes" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Imágenes opacas para los diálogos" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Fondo opaco general para los diálogos" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Tema opaco para el diálogo de fin de sesión" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Imágenes opacas para los elementos gráficos" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Imagen opaca de fondo para los paneles" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Imagen opaca de fondo para las ayudas emergentes" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Archivo de configuración de KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Descripciones del servicio" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "" +#~ "No se ha podido crear en motor de scripts de %1 para el elemento gráfico " +#~ "%2." + +#~ msgid "Script initialization failed" +#~ msgstr "La inicialización del script ha fallado" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Festividades" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Eventos" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Por hacer" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Otros" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Mes anterior" + +#~ msgid "Previous Year" +#~ msgstr "Año anterior" + +#~ msgid "Previous Decade" +#~ msgstr "Década anterior" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Hoy" + +#~ msgid "Reset calendar to today" +#~ msgstr "Reiniciar el calendario a hoy" + +#~ msgid "Next Month" +#~ msgstr "Mes siguiente" + +#~ msgid "Next Year" +#~ msgstr "Año siguiente" + +#~ msgid "Next Decade" +#~ msgstr "Década siguiente" + +#~ msgid "Days" +#~ msgstr "Días" + +#~ msgid "Months" +#~ msgstr "Meses" + +#~ msgid "Years" +#~ msgstr "Años" + +#~ msgid "OK" +#~ msgstr "Aceptar" + +#~ msgid "Cancel" +#~ msgstr "Cancelar" + +#~ msgid "Run the Associated Application" +#~ msgstr "Ejecutar la aplicación asociada" + +#~ msgid "Open with %1" +#~ msgstr "Abrir con %1" + +#~ msgid "Accessibility" +#~ msgstr "Accesibilidad" + +#~ msgid "Application Launchers" +#~ msgstr "Lanzadores de aplicaciones" + +#~ msgid "Astronomy" +#~ msgstr "Astronomía" + +#~ msgid "Date and Time" +#~ msgstr "Fecha y hora" + +#~ msgid "Development Tools" +#~ msgstr "Herramientas de desarrollo" + +#~ msgid "Education" +#~ msgstr "Educación" + +#~ msgid "Environment and Weather" +#~ msgstr "Entorno y meteorología" + +#~ msgid "Examples" +#~ msgstr "Ejemplos" + +#~ msgid "File System" +#~ msgstr "Sistema de archivos" + +#~ msgid "Fun and Games" +#~ msgstr "Juegos y diversión" + +#~ msgid "Graphics" +#~ msgstr "Gráficos" + +#~ msgid "Language" +#~ msgstr "Idioma" + +#~ msgid "Mapping" +#~ msgstr "Mapas" + +#~ msgid "Miscellaneous" +#~ msgstr "Varios" + +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + +#~ msgid "Online Services" +#~ msgstr "Servicios en línea" + +#~ msgid "Productivity" +#~ msgstr "Productividad" + +#~ msgid "System Information" +#~ msgstr "Información del sistema" + +#~ msgid "Utilities" +#~ msgstr "Utilidades" + +#~ msgid "Windows and Tasks" +#~ msgstr "Ventanas y tareas" + +#~ msgid "Clipboard" +#~ msgstr "Portapapeles" + +#~ msgid "Tasks" +#~ msgstr "Tareas" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Editar %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Preferencias por omisión para el tema, etc." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Esquema de color a usar en las aplicaciones." + +#~ msgid "Preview Images" +#~ msgstr "Vista previa de imágenes" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Vista previa del gestor de inicio de sesión" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Vista previa de la pantalla de bloqueo" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Vista previa del selector de usuario" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Vista previa del selector de escritorio virtual" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Vista previa de la pantalla de anuncio" + +#~ msgid "Preview for KRunner" +#~ msgstr "Vista previa de KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Vista previa de las decoraciones de la ventana" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Vista previa del selector de ventanas" + +#~ msgid "Login Manager" +#~ msgstr "Gestor de inicio de sesión" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Script principal para el gestor de inicio de sesión" + +#~ msgid "Logout Dialog" +#~ msgstr "Diálogo de cierre de sesión" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Script principal para el diálogo de cierre de sesión" + +#~ msgid "Screenlocker" +#~ msgstr "Bloqueador de pantalla" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Script principal para la pantalla de bloqueo" + +#~ msgid "UI for fast user switching" +#~ msgstr "Interfaz para cambio rápido de usuario" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Guion principal para el selector de usuario" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Selector de escritorio virtual" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Guion principal para el selector de escritorio virtual" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Notificaciones sobre la pantalla" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Guion principal para las notificaciones sobre la pantalla" + +#~ msgid "Splash Screen" +#~ msgstr "Pantalla anunciadora" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Guion principal para la pantalla de bienvenida" + +#~ msgid "KRunner UI" +#~ msgstr "Interfaz de KRunner" + +#~ msgid "Main Script KRunner" +#~ msgstr "Guion principal de KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Decoración de ventanas" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Guion principal para la decoración de ventanas" + +#~ msgid "Window Switcher" +#~ msgstr "Selector de ventana" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Guion principal para el selector de ventana" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Finalizar la personalización del diseño" + +#~ msgid "Customize Layout..." +#~ msgstr "Personalizar el diseño..." + +#~ msgid "Fetching file type..." +#~ msgstr "Obteniendo el tipo de archivo..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Opciones de %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Eliminar este %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Preferencias de %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Preferencias de %1..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Imágenes en color de baja resolución para los diálogos" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Fondo general en color de baja resolución para los diálogos" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Tema en color de baja resolución para el diálogo de fin de sesión" + +#~ msgid "Low color background image for widgets" +#~ msgstr "" +#~ "Imagen de fondo en color de baja resolución para los elementos gráficos" + +#~ msgid "Low color analog clock face" +#~ msgstr "Carátula en color de baja resolución del reloj analógico" + +#~ msgid "Low color background image for panels" +#~ msgstr "Imagen de fondo en color de baja resolución para los paneles" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Fondo en color de baja resolución para los elementos gráficos" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "" +#~ "Imagen de fondo en color de baja resolución para las ayudas emergentes" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Gestor de paquetes de Plasma" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Generar un resumen criptográfico SHA1 para el paquete de la " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Para instalar o eliminar; opera en los paquetes instalados para todos los " +#~ "usuarios" + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "El tipo del paquete; por ejemplo: tema, imagen de fondo, plasmoide, motor " +#~ "de datos, lanzador, plantilla de diseño, etc." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Instalar el paquete en " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Mostrar información sobre el paquete " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Actualizar el paquete en " + +#~ msgid "List installed packages" +#~ msgstr "Listar los paquetes instalados" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "Listar todos los tipos de paquetes conocidos que se pueden instalar" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Eliminar el paquete llamado " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Ruta absoluta a la raíz del paquete. Si no se indica, se buscará en los " +#~ "directorios de datos estándar de esta sesión de KDE." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "" +#~ "No se ha podido generar el resumen criptográfico del paquete para %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "Resumen criptográfico SHA1 para el paquete en %1: «%2»" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "fondo de escritorio" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoide" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "paquete" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "tema" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "motor de datos" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "lanzador" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "Complemento de fondo de escritorio" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "aspecto visual" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "intérprete de órdenes" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "plantilla de diseño" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "efecto de kwin" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "Selector de ventanas" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "guion de kwin" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "" +#~ "No se ha podido encontrar un instalador adecuado para los paquetes de " +#~ "tipo %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "Listando tipos de servicios: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Error: el complemento %1 no está instalado." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Se necesita instalar, eliminar, modernizar o listar." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Error: no se pueden encontrar los metadatos del complemento: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Mostrando información del paquete: %1" + +#~ msgid " Name : %1" +#~ msgstr " Nombre : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Comentario : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Complemento : %1" + +#~ msgid " Author : %1" +#~ msgstr " Autor : %1" + +#~ msgid " Path : %1" +#~ msgstr " Ruta : %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Las opciones «packageroot» y «global» están en conflicto; por favor, " +#~ "seleccione solo una." + +#~ msgid "Addon Name" +#~ msgstr "Nombre del complemento" + +#~ msgid "Service Type" +#~ msgstr "Tipo de servicio" + +#~ msgid "Path" +#~ msgstr "Ruta" + +#~ msgid "Type Argument" +#~ msgstr "Argumento del tipo" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Tipos de paquetes que se pueden instalar con esta herramienta:" + +#~ msgid "Built in:" +#~ msgstr "Integrado:" + +#~ msgid "DataEngine" +#~ msgstr "Motor de datos" + +#~ msgid "Layout Template" +#~ msgstr "Plantilla de distribución" + +#~ msgid "Look and Feel" +#~ msgstr "Aspecto visual" + +#~ msgid "Package" +#~ msgstr "Paquete" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoide" + +#~ msgid "Runner" +#~ msgstr "Lanzador" + +#~ msgid "Shell" +#~ msgstr "Intérprete" + +#~ msgid "Theme" +#~ msgstr "Tema" + +#~ msgid "Wallpaper Images" +#~ msgstr "Imágenes de fondo del escritorio" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Fondo de escritorio animado" + +#~ msgid "KWin Effect" +#~ msgstr "Efecto de KWin" + +#~ msgid "KWin Window Switcher" +#~ msgstr "Selector de ventana de KWin" + +#~ msgid "KWin Script" +#~ msgstr "Guion de KWin" + +#~ msgid "Provided by plugins:" +#~ msgstr "Proporcionado por los complementos:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Proporcionado por los archivos .desktop:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "%1 actualizado con éxito" + +#~ msgid "Successfully installed %1" +#~ msgstr "%1 instalado con éxito" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Error: la instalación de %1 ha fallado; %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Actualizando paquete desde archivo: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "%1 desinstalado con éxito" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Error: la desinstalación de %1 ha fallado; %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "No se puede cargar el instalador para paquetes del tipo %1. El error " +#~ "devuelto ha sido: %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "No se ha podido crear el directorio raíz del paquete: %1" + +#~ msgid "No such file: %1" +#~ msgstr "No existe el archivo: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "" +#~ "No se a podido abrir el archivo del paquete; formato de archivo " +#~ "comprimido no admitido: %1 %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "No se ha podido abrir el archivo del paquete: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "No hay un archivo de metadatos en el paquete: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "No se ha especificado el nombre del complemento del paquete: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "" +#~ "El nombre %1 del complemento de paquete contiene caracteres no válidos" + +#~ msgid "%1 already exists" +#~ msgstr "%1 ya existe" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "No se ha podido mover el paquete al destino: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "No se ha podido copiar el paquete en el destino: %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "No se ha podido crear el directorio de servicio local: %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "No se ha podido registrar el paquete como servicio (esto no es " +#~ "necesariamente fatal): %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 no existe" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "No se ha podido borrar el paquete de: %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "¿Realmente desea eliminar este %1?" + +#~ msgid "Applets furniture" +#~ msgstr "Accesorios de miniaplicaciones" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "Interfaz de exploración para añadir elementos gráficos" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "Interfaz de usuario para las vistas que mostrarán los contenedores" + +#~ msgid "Default layout file" +#~ msgstr "Archivo de disposición por omisión" + +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "" +#~ "Complementos por omisión para contenedores, acciones de contenedores, etc." + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "" +#~ "Mensaje de error mostrado cuando la miniaplicación falla al cargarse" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "" +#~ "Componente QML que muestra una miniaplicación en una ventana emergente" + +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Representación compacta de una miniaplicación cuando se contrae en una " +#~ "ventana emergente, como por ejemplo un icono. Las miniaplicaciones pueden " +#~ "redefinir este comportamiento." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "" +#~ "Componente QML para el diálogo de configuración de las miniaplicaciones" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "Componente QML para el diálogo de configuración de los contenedores" + +#~ msgid "Panel configuration UI" +#~ msgstr "Interfaz de configuración del panel" + +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "Componente QML para seleccionar una miniaplicación alternativa" + +#~ msgid "" +#~ "A UI for writing, loading and running desktop scripts in the current live " +#~ "session" +#~ msgstr "" +#~ "Una interfaz de usuario para escribir, cargar y ejecutar guiones del " +#~ "escritorio en la sesión actual" + +#~ msgid "Theme preview thumbnail" +#~ msgstr "Miniatura de la vista previa del tema" + +#~ msgid "Ok" +#~ msgstr "Aceptar" + +#~ msgid "search term" +#~ msgstr "término a buscar" + +#~ msgid "Unnamed" +#~ msgstr "Sin nombre" + +#~ msgid "Panel" +#~ msgstr "Panel" diff --git a/po/et/libplasma6.po b/po/et/libplasma6.po new file mode 100644 index 0000000..817fbed --- /dev/null +++ b/po/et/libplasma6.po @@ -0,0 +1,959 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2016, 2019. +# Mihkel Tõnnov , 2020, 2021. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2021-09-05 15:52+0200\n" +"Last-Translator: Mihkel Tõnnov \n" +"Language-Team: Estonian <>\n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 21.08.1\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Veel toiminguid" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Tundmatu" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Aktiveeri %1 vidin" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Eemalda %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Sisene kohandamisrežiimi" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Seadista apletti %1 ..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Lukusta vidinad" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Eemalda vidinate lukustus" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Välju kohandamisrežiimist" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Kas luua teemale kettal puhver või mitte." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Teema kettapuhvri maksimaalne suurus kilobaitides. Pane tähele, et tegu on " +"hajusfailiga, nii et maksimaalset suurust küllap ei kasutatagi. Seepärast " +"võib suurema suuruse määramist pidada üpris turvaliseks valikuks." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Näita alternatiive ..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Vidin eemaldatud" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Vidin \"%1\" eemaldati." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Paneel eemaldatud" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Paneel eemaldati." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Töölaud eemaldatud" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Töölaud eemaldati." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Võta tagasi" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Vidina seadistused" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Eemalda see vidin" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Eemalda see paneel" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Eemalda see tegevus" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Tegevuse seadistused" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Nõutud komponenti ei leitud: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Tundmatu aplett" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Tõrge QML-faili laadimisel: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package inexistent. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Tõrge apleti laadimisel: paketti ei ole olemas. %1" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "%1 seadistused" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 seadistused" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma pakett" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Paigalda" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Paketi paigaldamine nurjus" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Lohistatud pakett on vigane." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Vidinad" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Lisa %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Lisa ikoon" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Taustapilt" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Määra taustapildiks %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Kohale lohistati sisu" + +#~ msgid "Add Widgets..." +#~ msgstr "Lisa vidinaid ..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Vidinale %2 vajaliku paketi %1 avamine nurjus." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Vidina jagamine võrgus lubab sul kasutada seda vidinat ka mõnest teisest " +#~ "arvutist." + +#~ msgid "Share this widget on the network" +#~ msgstr "Vidina jagamine võrgus" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Kõik võivad takistusteta vidinat kasutada" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Vigane (tühi) teenus, ühtegi toimingut ei saa teostada." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Vidin %1 ei määratle, millist skriptimootorit kasutada." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Muu" + +#~ msgid "Main Script File" +#~ msgstr "Peamine skriptifail" + +#~ msgid "Tests" +#~ msgstr "Testid" + +#~ msgid "Images" +#~ msgstr "Pildid" + +#~ msgid "Themed Images" +#~ msgstr "Teemaga pildid" + +#~ msgid "Configuration Definitions" +#~ msgstr "Seadistamise definitsioonid" + +#~ msgid "User Interface" +#~ msgstr "Kasutajaliides" + +#~ msgid "Data Files" +#~ msgstr "Andmefailid" + +#~ msgid "Executable Scripts" +#~ msgstr "Käivitatavad skriptid" + +#~ msgid "Screenshot" +#~ msgstr "Ekraanipilt" + +#~ msgid "Translations" +#~ msgstr "Tõlked" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Seadistuse UI lehekülgede mudel" + +#~ msgid "Configuration XML file" +#~ msgstr "Seadistuse XML-fail" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Kompaktsete aplettide kohandatav laiendaja" + +#~ msgid "Images for dialogs" +#~ msgstr "Dialoogide pildid" + +#~ msgid "Generic dialog background" +#~ msgstr "Üldine dialoogi taust" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Väljalogimisdialoogi teema" + +#~ msgid "Wallpaper packages" +#~ msgstr "Taustapildipaketid" + +#~ msgid "Images for widgets" +#~ msgstr "Vidinate pildid" + +#~ msgid "Background image for widgets" +#~ msgstr "Vidinate taustapilt" + +#~ msgid "Analog clock face" +#~ msgstr "Analoogkella esiplaan" + +#~ msgid "Background image for panels" +#~ msgstr "Paneelide taustapilt" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Graafikavidinate taust" + +#~ msgid "Background image for tooltips" +#~ msgstr "Kohtspikrite taustapilt" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Dialoogide läbipaistmatud pildid" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Üldine läbipaistmatu dialoogi taust" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Väljalogimisdialoogi läbipaistmatu teema" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Vidinate läbipaistmatud pildid" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Paneelide läbipaistmatu taustapilt" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Kohtspikrite läbipaistmatu taustapilt" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme seadistusfail" + +#~ msgid "Service Descriptions" +#~ msgstr "Teenuse kirjeldused" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "%1 skriptimootori loomine vidinale %2 nurjus." + +#~ msgid "Script initialization failed" +#~ msgstr "Skripti initsialiseerimine nurjus" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Pühad" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Sündmused" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Ülesanded" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Muu" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Eelmine kuu" + +#~ msgid "Previous Year" +#~ msgstr "Eelmine aasta" + +#~ msgid "Previous Decade" +#~ msgstr "Eelmine kümnend" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Täna" + +#~ msgid "Reset calendar to today" +#~ msgstr "Lähtesta kalender tänasele" + +#~ msgid "Next Month" +#~ msgstr "Järgmine kuu" + +#~ msgid "Next Year" +#~ msgstr "Järgmine aasta" + +#~ msgid "Next Decade" +#~ msgstr "Järgmine kümnend" + +#~ msgid "Days" +#~ msgstr "Päevad" + +#~ msgid "Months" +#~ msgstr "Kuud" + +#~ msgid "Years" +#~ msgstr "Aastad" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "Loobu" + +#~ msgid "Run the Associated Application" +#~ msgstr "Käivita seostatud rakendus" + +#~ msgid "Open with %1" +#~ msgstr "Ava rakendusega %1" + +#~ msgid "Accessibility" +#~ msgstr "Hõlbustus" + +#~ msgid "Application Launchers" +#~ msgstr "Rakenduste käivitajad" + +#~ msgid "Astronomy" +#~ msgstr "Astronoomia" + +#~ msgid "Date and Time" +#~ msgstr "Kuupäev ja kellaaeg" + +#~ msgid "Development Tools" +#~ msgstr "Arendustööriistad" + +#~ msgid "Education" +#~ msgstr "Haridus" + +#~ msgid "Environment and Weather" +#~ msgstr "Keskkond ja ilm" + +#~ msgid "Examples" +#~ msgstr "Näited" + +#~ msgid "File System" +#~ msgstr "Failisüsteem" + +#~ msgid "Fun and Games" +#~ msgstr "Lõbu ja mängud" + +#~ msgid "Graphics" +#~ msgstr "Graafika" + +#~ msgid "Language" +#~ msgstr "Keel" + +#~ msgid "Mapping" +#~ msgstr "Geograafia" + +#~ msgid "Miscellaneous" +#~ msgstr "Muu" + +#~ msgid "Multimedia" +#~ msgstr "Multimeedia" + +#~ msgid "Online Services" +#~ msgstr "Võrguteenused" + +#~ msgid "Productivity" +#~ msgstr "Loometegevus" + +#~ msgid "System Information" +#~ msgstr "Süsteemi teave" + +#~ msgid "Utilities" +#~ msgstr "Tööriistad" + +#~ msgid "Windows and Tasks" +#~ msgstr "Aknad ja ülesanded" + +#~ msgid "Clipboard" +#~ msgstr "Lõikepuhver" + +#~ msgid "Tasks" +#~ msgstr "Ülesanded" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Muuda %1 ..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Teema jne vaikimisi seadistused." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Rakendustest kasutatav värviskeem." + +#~ msgid "Preview Images" +#~ msgstr "Piltide eelvaatlus" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Sisselogimishalduri eelvaatlus" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Lukustusekraani eelvaatlus" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Kasutaja vahetaja eelvaatlus" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Virtuaalsete töölaudade vahetaja eelvaatlus" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Tiitelkuva eelvaatlus" + +#~ msgid "Preview for KRunner" +#~ msgstr "KRunneri eelvaatlus" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Akna dekoratsioonide eelvaatlus" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Aknavahetaja eelvaatlus" + +#~ msgid "Login Manager" +#~ msgstr "Sisselogimise haldur" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Sisselogimise haldur peamine skript" + +#~ msgid "Logout Dialog" +#~ msgstr "Väljalogimisdialoog" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Väljalogimisdialoogi peamine skript" + +#~ msgid "Screenlocker" +#~ msgstr "Ekraani lukustaja" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Lukustusekraani peamine skript" + +#~ msgid "UI for fast user switching" +#~ msgstr "Kasutajaliides kiireks kasutaja vahetamiseks" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Kasutaja vahetaja peamine skript" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Virtuaalsete töölaudade vahetaja" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Virtuaalsete töölaudade vahetaja peamine skript" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Ekraanimärguanded" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Ekraanimärguannete peamine skript" + +#~ msgid "Splash Screen" +#~ msgstr "Tiitelkuva" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Tiitelkuva peamine skript" + +#~ msgid "KRunner UI" +#~ msgstr "KRunneri kasutajaliides" + +#~ msgid "Main Script KRunner" +#~ msgstr "KRunneri peamine skript" + +#~ msgid "Window Decoration" +#~ msgstr "Akna dekoratsioonid" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Akna dekoratsioonide peamine skript" + +#~ msgid "Window Switcher" +#~ msgstr "Aknavahetaja" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Aknavahetaja peamine skript" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Lõpeta paigutuse kohandamine" + +#~ msgid "Customize Layout..." +#~ msgstr "Kohanda paigutust ..." + +#~ msgid "Fetching file type..." +#~ msgstr "Failitüübi hankimine..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1 valikud" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Apleti %1 seadistused" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Apleti %1 seadistused..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Dialoogide vähevärvilised pildid" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Üldine vähevärviline dialoogi taust" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Väljalogimisdialoogi vähevärviline teema" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Vidinate vähevärviline taustapilt" + +#~ msgid "Low color analog clock face" +#~ msgstr "Analoogkella vähevärviline esiplaan" + +#~ msgid "Low color background image for panels" +#~ msgstr "Paneelide vähevärviline taustapilt" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Graafikavidinate vähevärviline taust" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Kohtspikrite vähevärviline taustapilt" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Plasma paketihaldur" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "SHA1 räsi genereerimine paketile asukohas " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Paigaldamise või eemaldamise korral käsitleb pakette, mis on paigaldatud " +#~ "kõigi kasutajate jaoks." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Paketi tüüp, nt. teema, taustapilt, plasmoid, andmemootor, käivitaja, " +#~ "paigutusemall vms." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Paketi paigaldamine asukohas " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Paketi teabe näitamine" + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Paketi uuendamine asukohas " + +#~ msgid "List installed packages" +#~ msgstr "Paigaldatud pakettide loetlemine" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "Kõigi teadaolevate paigaldatavate paketitüüpide näitamine" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Paketi eemaldamine" + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Pakettide juurasukoha absoluutne asukoht. Kui seda ei anta, otsitakse " +#~ "antud KDE seansi standardsetest andmekataloogidest." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Paketi räsi genereerimine %1 jaoks nurjus" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "SHA1 räsi paketile asukohas %1: '%2'" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "taustapilt" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "pakett" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "teema" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "andmemootor" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "käivitaja" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "taustapildiplugin" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "välimus" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "kest" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "paigutusemall" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "kwiniefekt" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "aknavahetaja" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "kwiniskript" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "Paketile tüübiga %1 ei leitud sobivat paigaldajat" + +#~ msgid "Listing service types: %1" +#~ msgstr "Teenusetüüpide loend: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Tõrge: plugin %1 ei ole paigaldatud." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Nõutav on kas install, remove, upgrade või list." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Tõrge: plugina metaandmeid ei leitud: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Paketi teabe näitamine: %1" + +#~ msgid " Name : %1" +#~ msgstr " Nimi : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Kommentaar : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Plugin : %1" + +#~ msgid " Author : %1" +#~ msgstr " Autor : %1" + +#~ msgid " Path : %1" +#~ msgstr " Asukoht : %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Paketi juurasukoht ja globaalsed valikud on konfliktis, palun vali neist " +#~ "ainult üks." + +#~ msgid "Addon Name" +#~ msgstr "Lisandi nimi" + +#~ msgid "Service Type" +#~ msgstr "Teenuse tüüp" + +#~ msgid "Path" +#~ msgstr "Asukoht" + +#~ msgid "Type Argument" +#~ msgstr "Tüübi argument" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Selle tööriistaga paigaldatavate pakettide tüübid:" + +#~ msgid "Built in:" +#~ msgstr "Sisseehitatud:" + +#~ msgid "DataEngine" +#~ msgstr "Andmemootor" + +#~ msgid "Layout Template" +#~ msgstr "Paigutusemall" + +#~ msgid "Look and Feel" +#~ msgstr "Välimus" + +#~ msgid "Package" +#~ msgstr "Pakett" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoid" + +#~ msgid "Runner" +#~ msgstr "Käivitaja" + +#~ msgid "Shell" +#~ msgstr "Kest" + +#~ msgid "Theme" +#~ msgstr "Teema" + +#~ msgid "Wallpaper Images" +#~ msgstr "Taustapildid" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Animeeritud taustapilt" + +#~ msgid "KWin Effect" +#~ msgstr "KWini efekt" + +#~ msgid "KWin Window Switcher" +#~ msgstr "KWini aknavahetaja" + +#~ msgid "KWin Script" +#~ msgstr "KWini skript" + +#~ msgid "Provided by plugins:" +#~ msgstr "Pluginate pakutavad:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr ".desktop-failide pakutavad:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "%1 edukalt uuendatud" + +#~ msgid "Successfully installed %1" +#~ msgstr "%1 edukalt paigaldatud" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Tõrge: %1 paigaldamine nurjus: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Paketi uuendamine failist: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "%1 edukalt eemaldatud" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Tõrge: %1 eemaldamine nurjus: %2" diff --git a/po/eu/libplasma6.po b/po/eu/libplasma6.po new file mode 100644 index 0000000..42d35eb --- /dev/null +++ b/po/eu/libplasma6.po @@ -0,0 +1,732 @@ +# Translation for libplasma6.po to Euskara/Basque (eu). +# Copyright (C) 2017-2024 This file is copyright: +# This file is distributed under the same license as the plasma-framework package. +# SPDX-FileCopyrightText: 2023, 2024 KDE euskaratzeko proiektuko arduraduna +# +# Translators: +# Osoitz , 2017. +# Iñigo Salvador Azurmendi , 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024. +# Ander Elortondo , 2017. +msgid "" +msgstr "" +"Project-Id-Version: plasma-framework\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-23 10:57+0200\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 24.05.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Ekintza gehiago" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Tolestu" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Zabaldu" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Pasahitza" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Bilatu..." + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Bilatu" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Garbitu bilaketa" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Ezezaguna" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Aktibatu %1 trepeta" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Kendu %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Sartu editatzeko modura" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Konfiguratu %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Giltzatu trepetak" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Giltzapetik askatu trepetak" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Irten editatzeko modutik" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Gaiarentzako diskoan cachea sortu behar den hala ez." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Diskoan gaiaren cacheak izango duen gehienezko neurria kilobytetan. Jakizu " +"fitxategi hauek 'sparse' fitxategiak direla, beraz balitekeela gehienezko " +"neurria ez erabiltzea. Neurri handiagoa ezartzea beraz segurua izaten da." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Erakutsi ordezko aukerak..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Trepeta kendu da" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "\"%1\" trepeta kendu da." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panela kenduta" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Panel bat kendu da." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Mahaigaina kenduta" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Mahaigain bat kendu da." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Desegin" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Trepetaren ezarpenak" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Kendu trepeta hau" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Kendu panel hau" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Ezabatu jarduera hau" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Jarduera-ezarpenak" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Trepetak gehitu edo kudeatu..." + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Ezin izan da aurkitu eskautako osagaia: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "%1(e)(r)en erro elementua «ContaimentItem» motakoa izan behar du" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "%1(e)(r)en erro elementua «PlasmoidItem» motakoa izan behar da" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Aplikaziotxo ezezaguna" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Trepeta hori Plasmaren bertsio ezezagun baterako idatzi zen eta ez da Plasma " +"%1(e)rekin bateragarria. Mesedez, eguneratu Plasma trepeta erabili ahal " +"izateko." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 ez da bateragarria Plasma %2(r)ekin" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Trepeta hori Plasma %1(e)rako idatzi zen eta ez da Plasma %2(e)rekin " +"bateragarria. Mesedez, jar zaitez trepetaren egilearekin harremanean " +"eguneratutako bertsio baterako." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Trepeta hori Plasma %1(e)rako idatzi zen eta ez da Plasma %2(e)rekin " +"bateragarria. Mesedez, eguneratu Plasma trepeta erabili ahal izateko." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Barkatu! %1 zamatzean errore bat egon da." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Errorea QML fitxategia zamatzean: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Aplikaziotxoa zamatzeko errorea: %1 paketea ez da existitzen." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 ezarpenak" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 ezarpenak" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasmaren paketea" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Instalatu" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Paketearen instalazioak huts egin du" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Jaregin duzun paketea baliogabea da." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Trepetak" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Erantsi %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Erantsi ikono bat" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Horma-papera" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Ezarri %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Edukia jaregin da" + +#~ msgid "Add Widgets..." +#~ msgstr "Gehitu trepetak..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Ezin izan da ireki %2 trepetak behar duen %1 paketea" + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Trepeta bat sarean partekatzeak trepeta beste ordenagailu batetik " +#~ "atzitzea eta urrunetik kontrolatzea ahalbidetzen dizu." + +#~ msgid "Share this widget on the network" +#~ msgstr "Partekatu trepeta hau sarean" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Baimendu guztiei trepeta hau oztopo gabe atzitzea" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Zerbitzu baliogabea (nulua), ezin da ekintzarik burutu." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "%1 trepetak ez du zein ScriptEngine erabili zehaztu." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Beste zenbait" + +#~ msgid "Main Script File" +#~ msgstr "Script fitxategi nagusia" + +#~ msgid "Tests" +#~ msgstr "Probak" + +#~ msgid "Images" +#~ msgstr "Irudiak" + +#~ msgid "Themed Images" +#~ msgstr "Gaidun irudiak" + +#~ msgid "Configuration Definitions" +#~ msgstr "Konfigurazioaren definizioak" + +#~ msgid "User Interface" +#~ msgstr "Erabiltzailaren interfazea" + +#~ msgid "Data Files" +#~ msgstr "Datu-fitxategiak" + +#~ msgid "Executable Scripts" +#~ msgstr "Script exekutagarriak" + +#~ msgid "Screenshot" +#~ msgstr "Pantaila-argazkia" + +#~ msgid "Translations" +#~ msgstr "Itzulpenak" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Konfigurazio interfaze-orrien modeloa" + +#~ msgid "Configuration XML file" +#~ msgstr "XML konfigurazio-fitxategia" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Norberak finkatutako hedagailua aplikaziotxo trinkoentzat" + +#~ msgid "Images for dialogs" +#~ msgstr "Elkarrizketentzako irudiak" + +#~ msgid "Generic dialog background" +#~ msgstr "Elkarrizketa generikoentzako atzealdea" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Saio-amaitzeko elkarrizketaren gaia" + +#~ msgid "Wallpaper packages" +#~ msgstr "Horma-papereko irudiak" + +#~ msgid "Images for widgets" +#~ msgstr "Trepetentzako irudiak" + +#~ msgid "Background image for widgets" +#~ msgstr "Atzeko planoaren irudia trepetentzako" + +#~ msgid "Analog clock face" +#~ msgstr "Ordulari analogikoaren esfera" + +#~ msgid "Background image for panels" +#~ msgstr "Atzeko planoaren irudia panelentzako" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Trepeta grafikoentzako atzealdea" + +#~ msgid "Background image for tooltips" +#~ msgstr "Tresna-argibideentzako atzealdeko irudia" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Elkarrizketentzako irudi opakoa" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Elkarrizketa generikoentzako atzealde opakoa" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Gai opakoa saio-amaitzeko elkarrizketan" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Trepetetentzako irudi opakoak" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Atzeko planoaren irudi opakoa panelentzako" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Tresna-argibideentzako atzealdeko irudi opakoa" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme konfigurazio-fitxategia" + +#~ msgid "Service Descriptions" +#~ msgstr "Zerbitzu-deskripzioak" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Ezin izan da %1 ScriptEngine bat sortu %2 trepetarentzat." + +#~ msgid "Script initialization failed" +#~ msgstr "Script-aren hasieratzeak huts egin du" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Jaiegunak" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Gertaerak" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Zereginak" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Bestelakoak" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%2 %1" + +#~ msgid "Previous Month" +#~ msgstr "Aurreko hilabetea" + +#~ msgid "Previous Year" +#~ msgstr "Aurreko urtea" + +#~ msgid "Previous Decade" +#~ msgstr "Aurreko hamarkada" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Gaur" + +#~ msgid "Reset calendar to today" +#~ msgstr "Ekarri egutegia gaurko egunera" + +#~ msgid "Next Month" +#~ msgstr "Hurrengo hilabetea" + +#~ msgid "Next Year" +#~ msgstr "Hurrengo urtea" + +#~ msgid "Next Decade" +#~ msgstr "Hurrengo hamarkada" + +#~ msgid "Days" +#~ msgstr "Egunak" + +#~ msgid "Months" +#~ msgstr "Hilabeteak" + +#~ msgid "Years" +#~ msgstr "Urteak" + +#~ msgid "OK" +#~ msgstr "Ados" + +#~ msgid "Cancel" +#~ msgstr "Utzi" + +#~ msgid "Run the Associated Application" +#~ msgstr "Exekutatu elkartutako aplikazioa" + +#~ msgid "Open with %1" +#~ msgstr "Ireki %1(r)ekin" + +#~ msgid "Accessibility" +#~ msgstr "Irisgarritasuna" + +#~ msgid "Application Launchers" +#~ msgstr "Aplikazio-abiarazleak" + +#~ msgid "Astronomy" +#~ msgstr "Astronomia" + +#~ msgid "Date and Time" +#~ msgstr "Data eta ordua" + +#~ msgid "Development Tools" +#~ msgstr "Garatzaile-tresnak" + +#~ msgid "Education" +#~ msgstr "Hezkuntza" + +#~ msgid "Environment and Weather" +#~ msgstr "Ingurunea eta eguraldia" + +#~ msgid "Examples" +#~ msgstr "Adibideak" + +#~ msgid "File System" +#~ msgstr "Fitxategi-sistema" + +#~ msgid "Fun and Games" +#~ msgstr "Dibertsioa eta jolasak" + +#~ msgid "Graphics" +#~ msgstr "Grafikoak" + +#~ msgid "Language" +#~ msgstr "Hizkuntza" + +#~ msgid "Mapping" +#~ msgstr "Mapaketa" + +#~ msgid "Miscellaneous" +#~ msgstr "Bestelakoa" + +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + +#~ msgid "Online Services" +#~ msgstr "Lineako zerbitzuak" + +#~ msgid "Productivity" +#~ msgstr "Produktibitatea" + +#~ msgid "System Information" +#~ msgstr "Sistemaren informazioa" + +#~ msgid "Utilities" +#~ msgstr "Erabilgarriak" + +#~ msgid "Windows and Tasks" +#~ msgstr "Leihoak eta atazak " + +#~ msgid "Clipboard" +#~ msgstr "Arbela" + +#~ msgid "Tasks" +#~ msgstr "Atazak" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Editatu %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Ezarpen lehenetsiak gaientzake, eta abar." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Aplikaziekin erabili beharreko kolore-eskema." + +#~ msgid "Preview Images" +#~ msgstr "Aurreikusi irudiak" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Saio-hasteko kudeatzailearen aurrebista" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Pantaila-giltzatuaren aurrebista" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Erabitzaile-aldatzailearen aurrebista" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Alegiazko mahagain aldatzailearen aurrebista" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Plast-pantailaren aurrebista" + +#~ msgid "Preview for KRunner" +#~ msgstr "KRunner-ren aurrebista" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Lehio-apainduren aurrebista" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Lehio-aldatzailearen aurrebista" + +#~ msgid "Login Manager" +#~ msgstr "Saio-hasteko kudeatzailea" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Saio-hasteko kudeatzailearen script nagusia" + +#~ msgid "Logout Dialog" +#~ msgstr "Saio-amaitzeko elkarrizketa" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Saio-amaitzeko elkarrizketaren script nagusia" + +#~ msgid "Screenlocker" +#~ msgstr "Pantaila-giltzatzailea" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Pantaila-giltzatzearen script nagusia" + +#~ msgid "UI for fast user switching" +#~ msgstr "Erabiltzaile-aldaketa azkarrerako erabiltzaile-interfazea" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Erabiltzaile-aldatzailearen script nagusia" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Alegiazko mahaigain aldatzailea" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Alegiazko mahaigain aldatzailearen script nagusia" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Pantailan bistaratzeko jakinarazpenak" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Pantailan bistaratzeko jakinarazpenen script nagusia" + +#~ msgid "Splash Screen" +#~ msgstr "Plast-pantaila" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Plast-pantailaren script nagusia" + +#~ msgid "KRunner UI" +#~ msgstr "KRunner-ren erabiltzaile-interfazea" + +#~ msgid "Main Script KRunner" +#~ msgstr "KRunner-ren script nagusia" + +#~ msgid "Window Decoration" +#~ msgstr "Leiho-apaindura" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Leiho-apaindura script nagusia" + +#~ msgid "Window Switcher" +#~ msgstr "Leiho-aldatzailea" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Leiho-aldatzaile script-nagusia" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Amaitu antolamendua norbere erara egokitzea" + +#~ msgid "Customize Layout..." +#~ msgstr "Egokitu antolamendua norbere erara..." + +#~ msgid "Fetching file type..." +#~ msgstr "Fitxategi mota eskuratzen..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1 Aukerak" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "%1 ezarpenak" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "%1 ezarpenak..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Kolore baxuko irudiak elkarrizketentzako" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Elkarrizketa generikoentzako kolore baxuko atzealde" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Kolore baxuko gaia saio-amaitzeko elkarrizketan" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Kolore baxuko atzeko planoaren irudia trepetentzako" + +#~ msgid "Low color analog clock face" +#~ msgstr "Kolore baxuko ordulari analogikoaren esfera" + +#~ msgid "Low color background image for panels" +#~ msgstr "Kolore baxuko atzeko planoaren irudia panelentzako" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Kolore baxuko atzealdea trepeta grafikoentzako" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Kolore baxuko atzealdeko irudia tresna-iradokizuentzat" diff --git a/po/fi/libplasma6.po b/po/fi/libplasma6.po new file mode 100644 index 0000000..55e90f3 --- /dev/null +++ b/po/fi/libplasma6.po @@ -0,0 +1,1247 @@ +# Translation of plasmapkg.po to Finnish +# Copyright © 2011, 2012 This_file_is_part_of_KDE +# This file is distributed under the same license as the kde-runtime package. +# Teemu Rytilahti , 2008. +# Teemu Rytilahti , 2008, 2009. +# Tommi Nieminen , 2010, 2011, 2014, 2018, 2019, 2020, 2021, 2022, 2023, 2024. +# Jorma Karvonen , 2011. +# Lasse Liehu , 2011, 2012, 2013, 2014, 2015, 2016, 2019, 2020, 2022. +# +# KDE Finnish translation sprint participants: +# Author: Lliehu +msgid "" +msgstr "" +"Project-Id-Version: plasmapkg\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-04-08 19:58+0300\n" +"Last-Translator: Tommi Nieminen \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-POT-Import-Date: 2012-12-01 22:22:16+0000\n" +"X-Generator: Lokalize 22.12.3\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Lisää toimintoja" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Supista" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Laajenna" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Salasana" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Etsi…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Etsi" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Tyhjennä haku" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Tuntematon" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Aktivoi sovelma %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Poista %1|/|Poista $[yleisnimi_pienellä %1]" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Siirry muokkaustilaan" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Asetukset: %1…|/|$[gen %1] asetukset…" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Lukitse sovelmat" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Poista sovelmien lukitus" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Poistu muokkaustilasta" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Luodaanko teemaa varten levylle välimuisti." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Teemavälimuistin enimmäiskoko levyllä kilotavuina. Huomaa, että nämä ovat " +"ns. harvoja tiedostoja, joten enimmäiskokoa ei saavuteta. Suuren koon " +"asettaminen on siis yleensä aika turvallista." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Näytä vaihtoehdot…" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Sovelma poistettu" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Sovelma ”%1” on poistettu." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Paneeli poistettu" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Paneeli on poistettu." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Työpöytä poistettu" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Työpöytä on poistettu." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Kumoa" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Sovelman asetukset" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Poista tämä sovelma" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Poista tämä paneeli" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Poista tämä aktiviteetti" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Aktiviteetin asetukset" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Pyydettyä komponenttia ei löytynyt: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "%1: juuritietueen on oltava ContainmentItem-tyyppinen" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "%1: juuritietueen on oltava PlasmoidItem-tyyppinen" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Tuntematon sovelma" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Sovelma on kirjoitettu tuntemattomalle vanhalle Plasma-versiolle eikä ole " +"yhteensopiva Plasma-version %1 kanssa. Ota yhteyttä sovelman tekijään ja " +"pyydä päivitetty versio." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 ei ole yhteensopiva Plasma-version %2 kanssa" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Sovelma on kirjoitettu Plasma-versiolle %1 eikä ole yhteensopiva Plasma-" +"version %2 kanssa. Ota yhteyttä sovelman tekijään ja pyydä päivitetty versio." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Sovelma on kirjoitettu Plasma-versiolle %1 eikä ole yhteensopiva Plasma-" +"version %2 kanssa. Päivitä Plasma, jotta sovelmaa voisi käyttää." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Pahoittelut! Latauksessa tapahtui virhe: %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "QML-tiedoston avaaminen epäonnistui: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package does not exist. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Virhe ladattaessa sovelmaa: pakettia ei ole olemassa. %1" + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 – Asetukset – %2" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Asetukset: %1|/|$[gen %1] asetukset" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma-paketti" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Asenna" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Paketin asennus epäonnistui" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Pudottamasi paketti on virheellinen." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Sovelmat" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Lisää %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Lisää kuvake" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Tausta" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Aseta %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Sisältö pudotettu" + +#~ msgid "Add Widgets..." +#~ msgstr "Lisää sovelmia…" + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Sovelman %2 tarvitsemaa pakettia %1 ei voitu avata." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Sovelman jakaminen verkossa sallii sinun käyttää sovelmaa etänä toiselta " +#~ "tietokoneelta." + +#~ msgid "Share this widget on the network" +#~ msgstr "Jaa sovelma verkossa" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Salli kaikille vapaa pääsy tähän sovelmaan" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Viallinen (tyhjä) palvelu: ei kykene mihinkään toimintoon." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "%1-sovelma ei määrittänyt käytettävää ScriptEngineä." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Sekalaiset" + +#~ msgid "Main Script File" +#~ msgstr "Pääskriptitiedosto" + +#~ msgid "Tests" +#~ msgstr "Testit" + +#~ msgid "Images" +#~ msgstr "Kuvat" + +#~ msgid "Themed Images" +#~ msgstr "Teemakuvat" + +#~ msgid "Configuration Definitions" +#~ msgstr "Asetusmäärittelyt" + +#~ msgid "User Interface" +#~ msgstr "Käyttöliittymä" + +#~ msgid "Data Files" +#~ msgstr "Datatiedostot" + +#~ msgid "Executable Scripts" +#~ msgstr "Suoritettavat skriptit" + +#~ msgid "Screenshot" +#~ msgstr "Kuvakaappaus" + +#~ msgid "Translations" +#~ msgstr "Käännökset" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Asetussivujen käyttöliittymän datamalli" + +#~ msgid "Configuration XML file" +#~ msgstr "Asetusten XML-tiedosto" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Mukautettu laajennin tiiviille sovelmille" + +#~ msgid "Images for dialogs" +#~ msgstr "Kyselyikkunakuvat" + +#~ msgid "Generic dialog background" +#~ msgstr "Yleinen ikkunatausta" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Uloskirjautumisikkunan teema" + +#~ msgid "Wallpaper packages" +#~ msgstr "Taustakuvapaketit" + +#~ msgid "Images for widgets" +#~ msgstr "Sovelmien kuvat" + +#~ msgid "Background image for widgets" +#~ msgstr "Sovelmien taustakuva" + +#~ msgid "Analog clock face" +#~ msgstr "Analoginen kellotaulu" + +#~ msgid "Background image for panels" +#~ msgstr "Paneelien taustakuva" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Mittarisovelmien tausta" + +#~ msgid "Background image for tooltips" +#~ msgstr "Työkaluvihjeiden taustakuva" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Kyselyikkunoiden läpinäkymättömät kuvat" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Yleisten kyselyikkunoiden läpinäkymättömät kuvat" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Läpinäkymätön teema uloskirjautumisikkunalle" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Sovelmien läpinäkymättömät kuvat" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Paneelien läpinäkymätön taustakuva" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Työkaluvihjeiden läpinäkymätön taustakuva" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme-asetustiedosto" + +#~ msgid "Service Descriptions" +#~ msgstr "Palvelujen kuvaukset" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Sovelman %2 tarvitsemaa skriptimoottoria %1 ei voitu luoda." + +#~ msgid "Script initialization failed" +#~ msgstr "Skriptin alustus epäonnistui" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Vapaapäivät" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Tapahtumat" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Tehtävät" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Muut" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Edellinen kuukausi" + +#~ msgid "Previous Year" +#~ msgstr "Edellinen vuosi" + +#~ msgid "Previous Decade" +#~ msgstr "Edellinen vuosikymmen" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Tänään" + +#~ msgid "Reset calendar to today" +#~ msgstr "Palauta kalenteri tänäiseen" + +#~ msgid "Next Month" +#~ msgstr "Seuraava kuukausi" + +#~ msgid "Next Year" +#~ msgstr "Seuraava vuosi" + +#~ msgid "Next Decade" +#~ msgstr "Seuraava vuosikymmen" + +#~ msgid "Days" +#~ msgstr "Päivät" + +#~ msgid "Months" +#~ msgstr "Kuukaudet" + +#~ msgid "Years" +#~ msgstr "Vuodet" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "Peru" + +#~ msgid "Run the Associated Application" +#~ msgstr "Suorita liitetty sovellus" + +#~ msgid "Open with %1" +#~ msgstr "Avaa ohjelmalla %1" + +#~ msgid "Accessibility" +#~ msgstr "Esteettömyys" + +#~ msgid "Application Launchers" +#~ msgstr "Sovelluskäynnistimet" + +#~ msgid "Astronomy" +#~ msgstr "Tähtitiede" + +#~ msgid "Date and Time" +#~ msgstr "Aika ja päiväys" + +#~ msgid "Development Tools" +#~ msgstr "Kehitystyökalut" + +#~ msgid "Education" +#~ msgstr "Opiskelu" + +#~ msgid "Environment and Weather" +#~ msgstr "Sää ja ympäristö" + +#~ msgid "Examples" +#~ msgstr "Esimerkit" + +#~ msgid "File System" +#~ msgstr "Tiedostojärjestelmä" + +#~ msgid "Fun and Games" +#~ msgstr "Pelit ja viihde" + +#~ msgid "Graphics" +#~ msgstr "Grafiikka" + +#~ msgid "Language" +#~ msgstr "Kieli" + +#~ msgid "Mapping" +#~ msgstr "Kartat" + +#~ msgid "Miscellaneous" +#~ msgstr "Sekalaiset" + +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + +#~ msgid "Online Services" +#~ msgstr "Verkkopalvelut" + +#~ msgid "Productivity" +#~ msgstr "Tuottavuus" + +#~ msgid "System Information" +#~ msgstr "Järjestelmätiedot" + +#~ msgid "Utilities" +#~ msgstr "Työkalut" + +#~ msgid "Windows and Tasks" +#~ msgstr "Ikkunat ja tehtävät" + +#~ msgid "Clipboard" +#~ msgstr "Leikepöytä" + +#~ msgid "Tasks" +#~ msgstr "Tehtävät" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Muokkaa: %1…|/|Muokkaa $[yleisnimi_pienellä $[part %1] ]…" + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Teeman jne. oletusasetukset" + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Sovellusten väriteema." + +#~ msgid "Preview Images" +#~ msgstr "Esikatselukuvat" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Kirjautumisruudun esikatselu" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Lukitusnäytön esikatselu" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Käyttäjänvaihdon esikatselu" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Virtuaalityöpöydän valitsimen esikatselu" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Tervetuloruudun esikatselu" + +#~ msgid "Preview for KRunner" +#~ msgstr "KRunnerin esikatselu" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Ikkunan kehyksen esikatselu" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Ikkunanvalitsimen esikatselu" + +#~ msgid "Login Manager" +#~ msgstr "Kirjautumisruutu" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Kirjautumisruudun pääskripti" + +#~ msgid "Logout Dialog" +#~ msgstr "Uloskirjautumisikkuna" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Uloskirjautumisikkunan pääskripti" + +#~ msgid "Screenlocker" +#~ msgstr "Näyttölukko" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Lukitusnäytön pääskripti" + +#~ msgid "UI for fast user switching" +#~ msgstr "Nopean käyttäjänvaihdon käyttöliittymä" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Käyttäjänvaihdon pääskripti" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Virtuaalityöpöydän valitsin" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Virtuaalityöpöydän valitsimen pääskripti" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Kuvaruutuilmoitukset" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Kuvaruutuilmoitusten pääskripti" + +#~ msgid "Splash Screen" +#~ msgstr "Tervetuloruutu" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Tervetuloruudun pääskripti" + +#~ msgid "KRunner UI" +#~ msgstr "KRunnerin käyttöliittymä" + +#~ msgid "Main Script KRunner" +#~ msgstr "KRunnerin pääskripti" + +#~ msgid "Window Decoration" +#~ msgstr "Ikkunan kehys" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Ikkunan kehyksen pääskripti" + +#~ msgid "Window Switcher" +#~ msgstr "Ikkunanvalitsin" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Ikkunanvalitsimen pääskripti" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Lopeta asettelun mukautus" + +#~ msgid "Customize Layout..." +#~ msgstr "Mukauta asettelua…" + +#~ msgid "Fetching file type..." +#~ msgstr "Noudetaan tiedostotyyppiä…" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Asetukset: %1|/|$[gen %1] asetukset" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Poista tämä %1|/|Poista tämä $[yleisnimi_pienellä %1]" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Asetukset: %1|/|$[gen %1] asetukset" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Asetukset: %1…|/|$[gen %1] asetukset…" + +#~ msgid "Low color images for dialogs" +#~ msgstr "Kyselyikkunoiden vähäväriset kuvat" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Vähävärinen yleinen ikkunatausta" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Vähävärinen uloskirjautumisikkunateema " + +#~ msgid "Low color background image for widgets" +#~ msgstr "Sovelmien vähävärinen taustakuva" + +#~ msgid "Low color analog clock face" +#~ msgstr "Vähävärinen analoginen kellotaulu" + +#~ msgid "Low color background image for panels" +#~ msgstr "Vähävärinen paneelien taustakuva" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Mittarisovelmien vähävärinen tausta" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Työkaluvihjeiden vähävärinen taustakuva" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Plasman paketinhallintaohjelma" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Luo paketin SHA1-tiiviste" + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "Asentaa ja poistaa kaikille käyttäjille asennettuja paketteja." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Paketin tyyppi, esim. teema, tausta, plasmoidi, tietomoottori, " +#~ "suoritusohjelma, asettelumallipohja jne." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Asenna paketti kohteeseen " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Näytä paketin tiedot" + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Päivitä paketti kohteeseen " + +#~ msgid "List installed packages" +#~ msgstr "Näytä asennetut paketit" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "Luettele kaikki tunnetut asennettavissa olevat pakettityypit" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Poista -niminen paketti" + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Absoluuttinen polku paketin juureen. Jos tätä ei ole määriteltynä, niin " +#~ "KDE:n oletustietohakemistoja käytetään sen sijasta." + +# %1: polku +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Paketin %1 tiivisteen luonti epäonnistui" + +# %1: polku +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "Paketin %1 SHA1-tiiviste: \"%2\"" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "tausta" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoidi" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "paketti" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "teema" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "tietomoottori" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "suoritusohjelma" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "taustaliitännäinen" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "ulkoasujatuntuma" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "kuori" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "asettelumallipohja" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "kwin-tehoste" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "ikkunanvalitsin" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "kwin-skripti" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "Paketille, jonka tyyppi on %1, ei löytynyt sopivaa asennusohjelmaa" + +#~ msgid "Listing service types: %1" +#~ msgstr "Luetellaan palvelutyypit: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Virhe: Liitännäistä %1 ei ole asennettuna." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Joko asennus, poisto tai luettelointi on pakollinen." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Virhe: Liitännäisen metatietoja ei löydy: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Näytetään paketin %1 tiedot" + +#~ msgid " Name : %1" +#~ msgstr " Nimi : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Kommentti : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Liitännäinen : %1" + +#~ msgid " Author : %1" +#~ msgstr " Tekijä : %1" + +#~ msgid " Path : %1" +#~ msgstr " Polku : %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Paketin juurikansio ja järjestelmänlaajuiset valinnat ovat ristiriidassa: " +#~ "valitse toinen." + +#~ msgid "Addon Name" +#~ msgstr "Lisäosan nimi" + +#~ msgid "Service Type" +#~ msgstr "Palvelutyyppi" + +#~ msgid "Path" +#~ msgstr "Polku" + +#~ msgid "Type Argument" +#~ msgstr "Tyyppiparametri" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Tällä työkalulla asennettavissa olevat pakettityypit:" + +#~ msgid "Built in:" +#~ msgstr "Sisäänrakennettu:" + +#~ msgid "DataEngine" +#~ msgstr "Tietomoottori" + +#~ msgid "Layout Template" +#~ msgstr "Asettelumallipohja" + +#~ msgid "Look and Feel" +#~ msgstr "Ulkoasu ja tuntuma" + +#~ msgid "Package" +#~ msgstr "Paketti" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoidi" + +#~ msgid "Runner" +#~ msgstr "Suoritusohjelma" + +#~ msgid "Shell" +#~ msgstr "Kuori" + +#~ msgid "Theme" +#~ msgstr "Teema" + +#~ msgid "Wallpaper Images" +#~ msgstr "Taustakuvat" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Animoitu tausta" + +#~ msgid "KWin Effect" +#~ msgstr "KWin-tehoste" + +#~ msgid "KWin Window Switcher" +#~ msgstr "KWin-ikkunanvalitsin" + +#~ msgid "KWin Script" +#~ msgstr "KWin-skripti" + +#~ msgid "Provided by plugins:" +#~ msgstr "Liitännäisten tarjoamat:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr ".desktop-tiedostojen tarjoamat:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "Paketti %1 päivitettiin onnistuneesti" + +#~ msgid "Successfully installed %1" +#~ msgstr "Paketti %1 asennettiin onnistuneesti" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Virhe: Paketin %1 asennus epäonnistui: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Päivitetään paketti tiedostosta: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Paketin %1 asennuksen poisto onnistui" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Virhe: Paketin %1 asennuksen poisto epäonnistui: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Pakettityypille %1 sopivaa asennusohjelmaa ei voitu ladata. Virhe: %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Paketin juurikansion luonti epäonnistui: %1" + +#~ msgid "No such file: %1" +#~ msgstr "Tiedostoa ei ole olemassa: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "" +#~ "Pakettitiedoston avaaminen epäonnistui. Arkiston tiedostomuotoa ei tueta: " +#~ "%1 %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "Pakettitiedoston avaaminen epäonnistui: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "Ei metatietoja paketissa: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "Paketin liitännäisen nimeä ei ole annettu: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "Paketin liitännäisen nimessä %1 on virheellisiä merkkejä" + +#~ msgid "%1 already exists" +#~ msgstr "%1 on jo olemassa" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Paketin siirtäminen kohteeseen %1 epäonnistui" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Paketin kopiointi kohteeseen %1 epäonnistui" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Paikallisen palvelukansion %1 luonti epäonnistui" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "Pakettia ei saatu rekisteröityä palveluksi (virhe ei ole välttämättä " +#~ "vakava): %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 ei ole olemassa" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Paketin poistaminen epäonnistui: %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "" +#~ "Haluatko varmasti poistaa tämän: %1?|/|Haluatko varmasti poistaa tämän " +#~ "$[yleisnimi_pienellä $[gen %1] ]?" + +#~ msgid "Applets furniture" +#~ msgstr "Sovelmien sisustus" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "Selainkäyttöliittymä sovelmien lisäämiseen" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "Käyttöliittymä näkymille, jotka näyttävät sovelmasäiliöitä" + +#~ msgid "Default layout file" +#~ msgstr "Oletusasettelutiedosto" + +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "" +#~ "Oletusliitännäiset sovelmasäiliöille, sovelmasäiliöiden toiminnoille jne." + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "Virheviesti, joka näytetään, kun sovelman lataaminen epäonnistuu" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "QML-komponentti, joka näyttää sovelman ponnahdusikkunana" + +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Sovelman kompakti esitystapa. Sitä käytetään, kun sovelma on " +#~ "pienennettynä ponnahdusikkunassa kuten esimerkiksi kuvakkeena. Sovelmat " +#~ "voivat korvata tämän komponentin." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "Sovelmien asetusikkunoiden QML-komponentti" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "Sovelmasäiliöiden asetusikkunoiden QML-komponentti" + +#~ msgid "Panel configuration UI" +#~ msgstr "Paneelin asetusten käyttöliittymä" + +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "QML-komponentti vaihtoehtoisen sovelman valitsemiseen" + +#~ msgid "Ok" +#~ msgstr "OK" + +#~ msgid "search term" +#~ msgstr "hakusana" + +#~ msgid "Unnamed" +#~ msgstr "Nimetön" + +# pmap: =:gen=Paneelin: +# pmap: =:yleisnimi=kyllä: +#~ msgid "Panel" +#~ msgstr "Paneeli" + +#~ msgid "Shortcut Settings" +#~ msgstr "Pikanäppäinasetukset" + +#~ msgid "Settings" +#~ msgstr "Asetukset" + +#~ msgctxt "@title:window" +#~ msgid "%1 Settings" +#~ msgstr "Sovelman %1 asetukset|/|$[gen %1] asetukset" + +#~ msgid "Keyboard Shortcut" +#~ msgstr "Pikanäppäin" + +# Tiedosto, jossa kuvataan asetusten käyttöliittymä. +#~ msgid "Main Config UI File" +#~ msgstr "Asetusten pääkäyttöliittymätiedosto" + +# ContainmentActions is a class name +#~ msgid "Unknown ContainmentActions" +#~ msgstr "Tuntematon ContainmentActions" + +#~ msgid "This plugin needs to be configured" +#~ msgstr "Tämä liitännäinen vaatii asettamista" + +#~ msgid "Animation scripts" +#~ msgstr "Animaatioskriptit" + +#~ msgid "This object could not be created." +#~ msgstr "Tätä sovelmaa ei voitu luoda." + +#~ msgid "" +#~ "This object could not be created for the following reason:

%1

" +#~ msgstr "Tätä sovelmaa ei voitu luoda seuraavasta syystä:

%1

" + +#~ msgid "" +#~ "There was an error attempting to exec the associated application with " +#~ "this widget." +#~ msgstr "Virhe yritettäessä suorittaa sovelmaan kytkettyä sovellusta." + +#~ msgctxt "Error message, access to a remote service failed." +#~ msgid "Invalid token." +#~ msgstr "Virheellinen merkki." + +#~ msgctxt "Error message, access to a remote service failed." +#~ msgid "Matching password required." +#~ msgstr "Salasanojen tulee täsmätä." + +#~ msgctxt "Error message, access to a remote service failed." +#~ msgid "Access denied." +#~ msgstr "Pääsy kielletty." + +#~ msgid "Unknown error." +#~ msgstr "Tuntematon virhe." + +#~ msgctxt "" +#~ "%1 is the name of a plasmoid, %2 the name of the machine that plasmoid is " +#~ "published on" +#~ msgid "%1 on %2" +#~ msgstr "%1 kohteessa %2" + +#~ msgid "Share" +#~ msgstr "Jakaminen" + +#~ msgid "Job no longer valid, operation is not enabled." +#~ msgstr "Työ ei ole enää kelvollinen: toimenpidettä ei ole sallittu." + +#~ msgid "Job no longer valid, invalid parameters." +#~ msgstr "Työ ei ole enää kelvollinen: virheelliset parametrit." + +#~ msgid "Timeout." +#~ msgstr "Aikakatkaisu." + +#~ msgid "Server sent an invalid plasmoid package." +#~ msgstr "Palvelin lähetti virheellisen plasmoidipaketin." + +#~ msgid "You are about to open a remote widget on your system.
" +#~ msgstr "Olet avaamassa etäsovelmaa järjestelmässäsi.
" + +#~ msgid "" +#~ msgstr "
" + +#~ msgid "" +#~ msgstr "" + +#~ msgid "" +#~ "" +#~ msgstr "" + +#~ msgid "" +#~ "" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ msgstr "" +#~ "" + +#~ msgid "
Name:  %1
Nimi:  %1
Description:  %1
Kuvaus:  %1
Author:  %1 <%2>
Tekijä:  %1 <%2>
Server:  %1
Palvelin:  %1
" +#~ msgstr "" + +#~ msgid "

Are you sure you want to open this widget on your system?" +#~ msgstr "

Haluatko varmasti avata tämän sovelman järjestelmässäsi?" + +#~ msgid "Remote Widget" +#~ msgstr "Etäsovelma" + +#~ msgid "Reject Widget" +#~ msgstr "Hylkää sovelma" + +#~ msgctxt "A remote widget was rejected by the user." +#~ msgid "User rejected" +#~ msgstr "Käyttäjä esti" + +#~ msgid "Timeout" +#~ msgstr "Aikakatkaisu" + +#~ msgid "" +#~ "Your system does not provide support for the 'remote widgets' feature. " +#~ "Access Failed." +#~ msgstr "Järjestelmäsi ei tue etäsovelmapiirrettä. Käyttö epäonnistui." + +#~ msgid "Allow everybody access to %1." +#~ msgstr "Salli kaikille pääsy palveluun %1." + +#~ msgid "Deny everybody access to %1" +#~ msgstr "Torju kaikilta pääsy palveluun %1." + +#~ msgid "Allow %1 access to all services." +#~ msgstr "Salli käyttäjälle %1 pääsy kaikkiin palveluihin." + +#~ msgid "Deny %1 access to all services." +#~ msgstr "Torju käyttäjältä %1 pääsy kaikkiin palveluihin." + +#~ msgid "Allow access to %1, by %2." +#~ msgstr "Salli käyttäjän %2 pääsy palveluun %1." + +#~ msgid "Deny access to %1, by %2." +#~ msgstr "Torju käyttäjän %2 pääsy palveluun %1." + +#~ msgid "Allow access to %1, by %2?" +#~ msgstr "Sallitaanko käyttäjän %2 pääsy palveluun %1?" + +#~ msgid "You have requested access to the %1 hosted at %2." +#~ msgstr "Olet pyytänyt pääsyä palveluun %1 palvelimella %2." + +#~ msgid "Incoming connection request" +#~ msgstr "Saapuva yhteyspyyntö" + +#~ msgid "Connect with remote widget" +#~ msgstr "Yhdistä etäsovelmaan" + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not locate the %1 package required for the %2 widget." +#~ msgstr "Sovelman %2 tarvitsemaa pakettia %1 ei löytynyt." diff --git a/po/fr/libplasma6.po b/po/fr/libplasma6.po new file mode 100644 index 0000000..d88ff44 --- /dev/null +++ b/po/fr/libplasma6.po @@ -0,0 +1,1271 @@ +# translation of plasmapkg.po to Français +# translation of plasmapkg.po to +# French translations for l package. +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the l package. +# Julien Richard-Foy , 2008, 2009, 2010. +# Sébastien Renard , 2008, 2012. +# Sébastien Renard , 2012, 2014. +# SPDX-FileCopyrightText: 2013, 2024 Xavier Besnard +# Joëlle Cornavin , 2013. +# Vincent PINON , 2014. +# Maxime Corteel , 2015. +# Simon Depiets , 2017, 2018, 2019. +# SPDX-FileCopyrightText: 2020, 2021, 2022, 2023 Xavier Besnard +# Xavier Besnard , 2023. +# +msgid "" +msgstr "" +"Project-Id-Version: plasmapkg\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-25 11:46+0200\n" +"Last-Translator: Xavier Besnard \n" +"Language-Team: French >\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Accelerator-Marker: &\n" +"X-Environment: kde\n" +"X-Generator: Lokalize 23.08.5\n" +"X-Text-Markup: kde4\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Plus d'actions" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Réduire" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Développer" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Mot de passe" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Rechercher..." + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Rechercher" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Effacer une recherche" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Inconnu" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Activer le composant graphique %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Supprimer %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Démarrer en mode d'édition" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Configurer %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Verrouiller les composants graphiques" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Déverrouiller les composants graphiques" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Quitter le mode d'édition" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Créer ou non un cache pour le thème sur le disque." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"La taille maximum pour le stockage du cache de Thème en kilo-octet. Veuillez " +"noter que ces fichiers sont fragmentés, la taille maximale pourrait ne pas " +"être utilisée. Il est souvent plus sûr de spécifier une taille plus grande." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Afficher les alternatives..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Composant graphique supprimé" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Le composant graphique « %1 » a été supprimé." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Tableau de bord supprimé" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Un tableau de bord a été supprimé." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Bureau supprimé" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Un bureau a été supprimé" + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Annuler" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Paramètres du composant graphique" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Supprimer ce composant graphique" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Supprimer ce panneau" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Supprimer cette activité" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Paramètre de l'activité" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Ajouter ou gérer des composants graphiques…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Impossible de trouver le composant demandé : %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "L'élément racine de %1doit être de type « ContaimentItem »." + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "L'élément racine de %1doit être de type « PlasmoidItem »" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Applet inconnue" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Ce composant graphique a été écrit pour une ancienne version inconnue de " +"Plasma. Il est incompatible avec la version %1 de Plasma. Veuillez contacter " +"l'auteur du composant graphique pour une version à jour." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 est non compatible avec Plasma %2." + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Ce composant graphique a été écrit pour Plasma %1. Il est incompatible avec " +"Plasma %2. Veuillez contacter l'auteur du composant graphique pour une " +"version à jour." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Ce composant graphique a été écrit pour Plasma %1. Il est incompatible avec " +"Plasma %2. Veuillez mettre à jour Plasma pour pouvoir utiliser ce composant " +"graphique." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Désolé ! Une erreur est survenue durant le chargement de %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Erreur du chargement du fichier « QML » : %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Erreur du chargement de l'applet : le paquet %1 n'existe pas." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "Paramètres %1 — %2" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Paramètres %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Paquet Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Installer" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Échec de l'installation du paquet" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Le paquet que vous venez de déposer n'est pas valable." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Composants graphiques" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Ajouter %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Ajouter une icône" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Fond d'écran" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Appliquer %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Contenu déposé" + +#~ msgid "Add Widgets..." +#~ msgstr "Ajouter des composants graphiques..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "" +#~ "Impossible d'ouvrir le paquet %1 requis par le composant graphique %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Partager un composant graphique sur le réseau vous permet d'accéder à ce " +#~ "composant depuis un autre ordinateur en tant que commande à distance." + +#~ msgid "Share this widget on the network" +#~ msgstr "Partager ce composant graphique sur le réseau" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "" +#~ "Permettre à tous le monde d'accéder librement à ce composant graphique" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "" +#~ "Service non valable (Null), aucune opération ne peut être effectuée." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "" +#~ "Le composant graphique %1 n'a pas défini le moteur de script à utiliser." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Divers" + +#~ msgid "Main Script File" +#~ msgstr "Script principal" + +#~ msgid "Tests" +#~ msgstr "Tests" + +#~ msgid "Images" +#~ msgstr "Images" + +#~ msgid "Themed Images" +#~ msgstr "Images thématiques" + +#~ msgid "Configuration Definitions" +#~ msgstr "Définition de configuration" + +#~ msgid "User Interface" +#~ msgstr "Interface utilisateur" + +#~ msgid "Data Files" +#~ msgstr "Fichiers de données" + +#~ msgid "Executable Scripts" +#~ msgstr "Scripts exécutables" + +#~ msgid "Screenshot" +#~ msgstr "Capture d'écran" + +#~ msgid "Translations" +#~ msgstr "Traductions" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Interface utilisateur de configuration des modèles de pages" + +#~ msgid "Configuration XML file" +#~ msgstr "Fichier XML de configuration" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Extenseur personnalisé pour les applets synthétiques" + +#~ msgid "Images for dialogs" +#~ msgstr "Images pour la boîte de dialogue" + +#~ msgid "Generic dialog background" +#~ msgstr "Arrière plan générique de la boîte de dialogue" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Thème de la boîte de dialogue de déconnexion" + +#~ msgid "Wallpaper packages" +#~ msgstr "Paquets de fonds d'écran" + +#~ msgid "Images for widgets" +#~ msgstr "Images des composants graphiques" + +#~ msgid "Background image for widgets" +#~ msgstr "Image de fond des composants graphiques" + +#~ msgid "Analog clock face" +#~ msgstr "Cadran de l'horloge analogique" + +#~ msgid "Background image for panels" +#~ msgstr "Image de fond des panneaux" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Arrière plan des composants graphiques" + +#~ msgid "Background image for tooltips" +#~ msgstr "Image de fond pour les infobulles" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Images opaque des boîtes de dialogue" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Fond opaque générique de la boîte de dialogue" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Thème opaque pour la boîte de dialogue de déconnexion" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Images opaque des composants graphiques" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Image de fond opaque pour les panneaux" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Image de fond opaque pour les infobulles" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Fichier de configuration de KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Descriptions du service" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "" +#~ "Impossible de créer un moteur de script %1 pour le composant graphique %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Échec du script d'initialisation" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Vacances" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Évènements" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "À faire" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Autre" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Mois précédent" + +#~ msgid "Previous Year" +#~ msgstr "Année précédente" + +#~ msgid "Previous Decade" +#~ msgstr "Décennie précédente" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Aujourd'hui" + +#~ msgid "Reset calendar to today" +#~ msgstr "Réinitialiser le calendrier à aujourd'hui" + +#~ msgid "Next Month" +#~ msgstr "Mois suivant" + +#~ msgid "Next Year" +#~ msgstr "Année suivante" + +#~ msgid "Next Decade" +#~ msgstr "Décennie suivante" + +#~ msgid "Days" +#~ msgstr "Jours" + +#~ msgid "Months" +#~ msgstr "Mois" + +#~ msgid "Years" +#~ msgstr "Années" + +#~ msgid "OK" +#~ msgstr "Ok" + +#~ msgid "Cancel" +#~ msgstr "Annuler" + +#~ msgid "Run the Associated Application" +#~ msgstr "Lancer l'application associée" + +#~ msgid "Open with %1" +#~ msgstr "Ouvrir avec %1" + +#~ msgid "Accessibility" +#~ msgstr "Accessibilité" + +#~ msgid "Application Launchers" +#~ msgstr "Lanceurs d'application" + +#~ msgid "Astronomy" +#~ msgstr "Astronomie" + +#~ msgid "Date and Time" +#~ msgstr "Date et heure" + +#~ msgid "Development Tools" +#~ msgstr "Outils de Développement" + +#~ msgid "Education" +#~ msgstr "Éducation" + +#~ msgid "Environment and Weather" +#~ msgstr "Environnement et météo" + +#~ msgid "Examples" +#~ msgstr "Exemples" + +#~ msgid "File System" +#~ msgstr "Système de fichiers" + +#~ msgid "Fun and Games" +#~ msgstr "Jeux et divertissement" + +#~ msgid "Graphics" +#~ msgstr "Graphique" + +#~ msgid "Language" +#~ msgstr "Langage" + +#~ msgid "Mapping" +#~ msgstr "Cartographie" + +#~ msgid "Miscellaneous" +#~ msgstr "Divers" + +#~ msgid "Multimedia" +#~ msgstr "Multimédia" + +#~ msgid "Online Services" +#~ msgstr "Services en ligne" + +#~ msgid "Productivity" +#~ msgstr "Productivité" + +#~ msgid "System Information" +#~ msgstr "Informations système" + +#~ msgid "Utilities" +#~ msgstr "Utilitaires" + +#~ msgid "Windows and Tasks" +#~ msgstr "Fenêtres et tâches" + +#~ msgid "Clipboard" +#~ msgstr "Presse-papier" + +#~ msgid "Tasks" +#~ msgstr "Tâches" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Modifier %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Paramètres par défaut des thèmes, etc." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Schéma de couleur à utiliser avec les applications." + +#~ msgid "Preview Images" +#~ msgstr "Aperçu des images" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Aperçu du gestionnaire de connexion" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Aperçu du verrouillage de l'écran" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Aperçu du changeur d'utilisateur" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Aperçu du changeur de bureau virtuel" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Aperçu de l'écran de démarrage" + +#~ msgid "Preview for KRunner" +#~ msgstr "Aperçu de KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Aperçu des décorations de fenêtre" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Aperçu du changeur de fenêtre" + +#~ msgid "Login Manager" +#~ msgstr "Gestionnaire de connexion" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Script principal pour le gestionnaire de connexion" + +#~ msgid "Logout Dialog" +#~ msgstr "Boîte de dialogue de déconnexion" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Script principal pour la boîte de dialogue de déconnexion" + +#~ msgid "Screenlocker" +#~ msgstr "Verrouillage d'écran" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Script principal pour verrouiller l'écran" + +#~ msgid "UI for fast user switching" +#~ msgstr "Interface pour le changement rapide d'utilisateur" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Script principal pour le changeur d'utilisateur" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Changeur de bureau virtuel" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Script principal pour le changeur de bureau virtuel" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Affichage à l'écran des notifications" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Script principal pour l'affichage à l'écran des notifications" + +#~ msgid "Splash Screen" +#~ msgstr "Écran de démarrage " + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Script principal pour l'écran de démarrage" + +#~ msgid "KRunner UI" +#~ msgstr "Interface de KRunner" + +#~ msgid "Main Script KRunner" +#~ msgstr "Script principal de KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Décoration de la fenêtre" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Script principal pour la décoration des fenêtres" + +#~ msgid "Window Switcher" +#~ msgstr "Changeur de fenêtre" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Script principal pour le changeur de fenêtre" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Terminer la personnalisation de la disposition" + +#~ msgid "Customize Layout..." +#~ msgstr "Personnaliser la disposition..." + +#~ msgid "Fetching file type..." +#~ msgstr "Réception du type du fichier..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Options de %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Supprimer ce %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Paramètres de %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Paramètres de %1..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Images de faible couleurs pour les boîtes de dialogue" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Fond de faible couleurs pour les boîtes de dialogue" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Thème de faible couleurs pour la boîte de dialogue de déconnexion" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Image de fond de faible couleurs pour les composants graphiques" + +#~ msgid "Low color analog clock face" +#~ msgstr "Cadrant d'horloge de faible couleurs" + +#~ msgid "Low color background image for panels" +#~ msgstr "Image de fond de faible couleurs pour les panneaux" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Fond de faible couleurs pour les composants graphiques" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Image de fond de faible couleurs pour les infobulles" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Gestionnaire de paquets pour Plasma" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Générer un hachage SHA1 pour le paquet à " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Cela fonctionne pour l'installation ou la suppression des paquets " +#~ "installés pour tous les utilisateurs." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Le type du paquet, par exemple, thème, fond d'écran, composant graphique, " +#~ "moteur de recherche, lanceur, modèle de disposition, etc." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Installer le paquet à " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Afficher les informations sur le paquet " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Mettre à jour le paquet à " + +#~ msgid "List installed packages" +#~ msgstr "Lister les paquets installés" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "Liste l'ensemble des types de paquets pouvant être installés" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Supprimer le paquet nommé " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Emplacement absolu de la racine des paquets. Si ce champ est omis, alors, " +#~ "les dossiers standards de données de cette session KDE seront utilisés." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Impossible de générer un hachage de paquet pour %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "Hachage SHA1 pour le paquet à %1 : %2" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "fond d'écran" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "composant graphique" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "paquet" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "thème" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "moteur de recherche" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "lanceur" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "module externe pour fond d'écran" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "apparence" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "interpréteur" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "modèle de disposition" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "Effet KWin" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "changeur de fenêtre" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "script KWin" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "" +#~ "Impossible de trouver un installateur convenable pour un paquet de type %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "Listage des types de services : %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Erreur : le module externe %1 n'est pas installé." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "" +#~ "L'une des actions suivantes est requise : « install », « remove », " +#~ "« upgrade » ou « list »." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Erreur : le module externe de métadonnées est introuvable : %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Affichage des informations pour le paquet : %1" + +#~ msgid " Name : %1" +#~ msgstr " Nom : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Commentaire : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Module externe : %1" + +#~ msgid " Author : %1" +#~ msgstr " Auteur : %1" + +#~ msgid " Path : %1" +#~ msgstr " Emplacement : %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Les options globales et de « package-root » sont en conflit. Veuillez " +#~ "n'en sélectionner qu'une seule." + +#~ msgid "Addon Name" +#~ msgstr "Nom de module" + +#~ msgid "Service Type" +#~ msgstr "Type de service" + +#~ msgid "Path" +#~ msgstr "Emplacement" + +#~ msgid "Type Argument" +#~ msgstr "Argument de type" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Les types de paquets installables avec cet outil :" + +#~ msgid "Built in:" +#~ msgstr "Compilé par :" + +#~ msgid "DataEngine" +#~ msgstr "Moteur de recherche" + +#~ msgid "Layout Template" +#~ msgstr "Modèle de disposition" + +#~ msgid "Look and Feel" +#~ msgstr "Apparence" + +#~ msgid "Package" +#~ msgstr "Paquet" + +#~ msgid "Plasmoid" +#~ msgstr "Composant graphique" + +#~ msgid "Runner" +#~ msgstr "Lanceur" + +#~ msgid "Shell" +#~ msgstr "Interpréteur" + +#~ msgid "Theme" +#~ msgstr "Thème" + +#~ msgid "Wallpaper Images" +#~ msgstr "Fonds d'écran" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Fond d'écran animé" + +#~ msgid "KWin Effect" +#~ msgstr "Effets KWin" + +#~ msgid "KWin Window Switcher" +#~ msgstr "Changeur de fenêtre KWin" + +#~ msgid "KWin Script" +#~ msgstr "Script KWin" + +#~ msgid "Provided by plugins:" +#~ msgstr "Fourni par les modules externes :" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Fourni par les fichiers « .desktop » :" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "Mise à niveau réussie de %1" + +#~ msgid "Successfully installed %1" +#~ msgstr "Installation réussie de %1" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Erreur : l'installation de %1 a échoué : %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Mise à niveau du paquet depuis un fichier : %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Désinstallation réussie de %1" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Erreur : la désinstallation de %1 a échoué : %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Impossible de charger un installateur pour un paquet de type %1. L'erreur " +#~ "reportée était : %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Impossible de créer le paquet dossier racine : %1" + +#~ msgid "No such file: %1" +#~ msgstr "Aucun fichier : %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "" +#~ "Impossible d'ouvrir le fichier de paquet, le format d'archive n'est pas " +#~ "accepté : %1 %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "Impossible d'ouvrir le fichier du paquet : %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "Aucun fichier de métadonnées dans le paquet : %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "Nom du module externe non spécifié : %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "Le nom du module externe %1 contient des caractères non valables" + +#~ msgid "%1 already exists" +#~ msgstr "%1 existe déjà" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Impossible de déplacer le paquet à destination : %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Impossible de copier le paquet à destination : %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Impossible de créer le dossier de service local : %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "Impossible d'inscrire le paquet en tant que service (ce n'est pas " +#~ "nécessairement fatal) : %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 n'existe pas" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Impossible de supprimer le paquet depuis : %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "Voulez-vous vraiment supprimer : %1 ?" + +#~ msgid "Applets furniture" +#~ msgstr "Applets décoratives" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "Explorateur pour ajouter des composants graphiques" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "Interface utilisateur pour la vue qui affichera les contenus" + +#~ msgid "Default layout file" +#~ msgstr "Fichier de disposition par défaut" + +#, fuzzy +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "" +#~ "Modules externes par défaut pour les conteneurs, actions des conteneurs, " +#~ "etc." + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "" +#~ "Message d'erreur affiché lorsqu'une applet ne parvient pas à se charger" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "Composant QML montrant une applet dans un menu contextuel" + +#, fuzzy +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Représentation compacte pour une applet ouvrant une popup, sous forme " +#~ "d'icône par exemple. Les applets peuvent passer outre ce composant." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "" +#~ "Composant QML de la boîte de dialogue de configuration pour les applets" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "" +#~ "Composant QML de la boîte de dialogue de configuration pour les contenus" + +#~ msgid "Panel configuration UI" +#~ msgstr "Panneau de configuration" + +#, fuzzy +#~| msgid "QML component for the configuration dialog for applets" +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "" +#~ "Composant QML de la boîte de dialogue de configuration pour les applets" + +#~ msgid "search term" +#~ msgstr "terme à rechercher" + +#~ msgid "Unnamed" +#~ msgstr "Sans nom" + +#~ msgid "Panel" +#~ msgstr "Panneau" + +#~ msgctxt "" +#~ "%1 is the name of a plasmoid, %2 the name of the machine that plasmoid is " +#~ "published on" +#~ msgid "%1 on %2" +#~ msgstr "%1 sur %2" + +#~ msgid "Settings" +#~ msgstr "Configuration" + +#~ msgid "Unknown ContainmentActions" +#~ msgstr "Actions de conteneur inconnues" + +#~ msgid "Shortcut Settings" +#~ msgstr "Configuration des raccourcis" + +#, fuzzy +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not locate the %1 package required for the %2 widget." +#~ msgstr "" +#~ "Impossible de trouver le paquetage %1 requis par le composant graphique " +#~ "%2." + +#~ msgctxt "@title:window" +#~ msgid "%1 Settings" +#~ msgstr "Configuration de : %1" + +#~ msgid "Keyboard Shortcut" +#~ msgstr "Raccourci clavier" + +#~ msgid "Share" +#~ msgstr "Partager" + +#~ msgid "This object could not be created." +#~ msgstr "Impossible de créer cet objet." + +#~ msgid "" +#~ "This object could not be created for the following reason:

%1

" +#~ msgstr "" +#~ "Impossible de créer cet objet pour la raison suivante :

%1

" + +#~ msgid "" +#~ "There was an error attempting to exec the associated application with " +#~ "this widget." +#~ msgstr "" +#~ "Une erreur s'est produite en essayant de lancer l'application associée à " +#~ "ce composant graphique." + +#~ msgid "This plugin needs to be configured" +#~ msgstr "Ce module externe a besoin d'être configuré" + +#~ msgctxt "Error message, access to a remote service failed." +#~ msgid "Invalid token." +#~ msgstr "Jeton non valable" + +#~ msgctxt "Error message, access to a remote service failed." +#~ msgid "Matching password required." +#~ msgstr "Un mot de passe concordant est nécessaire." + +#~ msgctxt "Error message, access to a remote service failed." +#~ msgid "Access denied." +#~ msgstr "Accès refusé." + +#~ msgid "Unknown error." +#~ msgstr "Erreur inconnue." + +#~ msgid "Main Config UI File" +#~ msgstr "Fichier de l'interface de configuration principale" + +#~ msgid "Animation scripts" +#~ msgstr "Scripts d'animation" + +#~ msgid "Job no longer valid, operation is not enabled." +#~ msgstr "La tâche n'est plus valable, l'opération est désactivée." + +#~ msgid "Job no longer valid, invalid parameters." +#~ msgstr "La tâche n'est plus valable, configuration erronée." + +#~ msgid "Timeout." +#~ msgstr "Temps d'attente dépassé" + +#~ msgid "Server sent an invalid plasmoid package." +#~ msgstr "Le serveur a envoyé un paquetage de composant graphique non valable" + +#~ msgid "You are about to open a remote widget on your system.
" +#~ msgstr "" +#~ "Vous allez ouvrir un composant graphique distant sur votre système.
" + +#~ msgid "" +#~ msgstr "
" + +#~ msgid "" +#~ msgstr "" + +#~ msgid "" +#~ "" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ "" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ msgstr "" +#~ "" + +#~ msgid "
Name:  %1
Nom :   %1
Description:  %1
Description :   %1
Author:  %1 <%2>
Auteur :   %1 <%2>
Server:  %1
Serveur :   %1
" +#~ msgstr "" + +#~ msgid "

Are you sure you want to open this widget on your system?" +#~ msgstr "" +#~ "

Voulez-vous vraiment ouvrir ce composant graphique sur votre " +#~ "système ?" + +#~ msgid "Remote Widget" +#~ msgstr "Composant graphique distant" + +#~ msgid "Reject Widget" +#~ msgstr "Rejeter le composant graphique" + +#~ msgid "Timeout" +#~ msgstr "Temps d'attente dépassé" + +#~ msgid "" +#~ "Your system does not provide support for the 'remote widgets' feature. " +#~ "Access Failed." +#~ msgstr "" +#~ "Votre système ne prend pas en charge la fonctionnalité « composants " +#~ "graphiques distants ». L'accès a échoué." + +#~ msgid "Allow everybody access to %1." +#~ msgstr "Autoriser tout le monde à accéder à %1." + +#~ msgid "Deny everybody access to %1" +#~ msgstr "Interdire à tout le monde l'accès à %1." + +#~ msgid "Allow %1 access to all services." +#~ msgstr "Autoriser %1 à accéder à tous les services." + +#~ msgid "Deny %1 access to all services." +#~ msgstr "Interdire à %1 l'accès à tous les services." + +#~ msgid "Allow access to %1, by %2." +#~ msgstr "Autoriser %2 à accéder à %1." + +#~ msgid "Deny access to %1, by %2." +#~ msgstr "Interdire à %2 l'accès à %1." + +#~ msgid "Allow access to %1, by %2?" +#~ msgstr "Autoriser %2 à accéder à %1 ?" + +#~ msgid "You have requested access to the %1 hosted at %2." +#~ msgstr "Vous avez demandé à accéder à %1 hébergé sur %2." + +#~ msgid "Incoming connection request" +#~ msgstr "Demande de connexion entrante" + +#~ msgid "Connect with remote widget" +#~ msgstr "Se connecter au composant graphique distant" diff --git a/po/gd/libplasma6.po b/po/gd/libplasma6.po new file mode 100644 index 0000000..2b4738b --- /dev/null +++ b/po/gd/libplasma6.po @@ -0,0 +1,959 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# GunChleoc , 2015, 2016. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2016-04-30 12:08+0100\n" +"Last-Translator: GunChleoc \n" +"Language-Team: Fòram na Gàidhlig\n" +"Language: gd\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : " +"(n > 2 && n < 20) ? 2 : 3;\n" +"X-Generator: Virtaal 0.7.1\n" +"X-Project-Style: kde\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Chan eil fhios" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Gnìomhach Widget %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, fuzzy, kde-format +#| msgctxt "%1 is the name of the applet" +#| msgid "Remove this %1" +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Thoir air falbh an %1 seo" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Glais na Widgets" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Thoir a' ghlas far Widgets" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "" +"Co-dhiù an dèid tasgadan a chruthachadh air an diosg airson an ùrlair seo " +"gus nach dèid." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Am meud as motha ann an cileabaidht aig an tasgadan air an diosg airson an " +"ùrlair. Thoir an aire gu bheil na faidhlichean seo gann, mar sin dh'fhaoidte " +"nach dèid am meud as motha a chleachdadh. Bidh e gu math sàbhailte mar a " +"trice ma shònraicheas tu meud nas motha." + +#: plasma/private/applet_p.cpp:119 +#, fuzzy, kde-format +#| msgid "Alternatives..." +msgid "Show Alternatives..." +msgstr "Roghainnean eile..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Chaidh widget a thoirt air falbh" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Chaidh an widget \"%1\" a thoirt air falbh." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Chaidh panail a thoirt air falbh" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Chaidh panail a thoirt air falbh." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Chaidh deasg a thoirt air falbh" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Chaidh deasg a thoirt air falbh." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Neo-dhèan" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Roghainnean an widget" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Thoir air falbh an widget seo" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Thoir air falbh a' phanail seo" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Thoir air falbh a' ghnìomhachd seo" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Roghainnean na gnìomhachd" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Cha do lorg sinn a' cho-phàirt a dh'iarr thu: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, fuzzy, kde-format +#| msgid "Unknown" +msgid "Unknown Applet" +msgstr "Chan eil fhios" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, fuzzy, kde-format +#| msgid "Error loading QML file: %1" +msgid "Error loading QML file: %1 %2" +msgstr "Mearachd a' luchdadh faidhle QML: %1" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package inexistent. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Mearachd a' luchdadh aplaid: chan eil a' phacaid ann. %1" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "Roghainnean %1" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Roghainnean %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Pacaid Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Stàlaich" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Dh’fhàillig le stàladh na pacaide" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Tha a' phacaid a leig thu às mì-dligheach." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Widgets" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, fuzzy, kde-format +#| msgid "Icon" +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Ìomhaigheag" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Pàipear-balla" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Chaidh an t-susbaint a leigeil às" + +#~ msgid "Add Widgets..." +#~ msgstr "Cuir widgets ris..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "" +#~ "Cha b' urrainn dhuinn pacaid %1 fhosgladh a tha riatanach airson an " +#~ "widget %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Ma cho-roinneas tu widget air an lìonra, 's urrainn dhut an widget " +#~ "inntrigeadh o choimpiutair eile mar inneal-smachd cèin." + +#~ msgid "Share this widget on the network" +#~ msgstr "Co-roinn an widget seo air an lìonra" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Leig leis a h-uile duine an widget seo inntrigeadh gu saor" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "" +#~ "Seirbheis mhì-dhligheach (null), chan urrainn dhuinn obrachadh sam bith a " +#~ "dhèanamh." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "" +#~ "Cha do shònraich an widget %1 dè an ScriptEngine a thèid a chleachdadh." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Eile" + +#~ msgid "Main Script File" +#~ msgstr "Prìomh-fhaidhle an sgriobt" + +#~ msgid "Tests" +#~ msgstr "Deuchainnean" + +#~ msgid "Images" +#~ msgstr "Dealbhan" + +#~ msgid "Themed Images" +#~ msgstr "Dealbhan ùrlair" + +#~ msgid "Configuration Definitions" +#~ msgstr "Mìneachaidhean rèiteachaidh" + +#~ msgid "User Interface" +#~ msgstr "Eadar-aghaidh" + +#~ msgid "Data Files" +#~ msgstr "Faidhlichean dàta" + +#~ msgid "Executable Scripts" +#~ msgstr "Sgriobtaichean so-ghnìomhach" + +#~ msgid "Screenshot" +#~ msgstr "Glacadh-sgrìn" + +#~ msgid "Translations" +#~ msgstr "Eadar-theangachaidhean" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Modal duilleig airson rèiteachadh UI" + +#~ msgid "Configuration XML file" +#~ msgstr "Faidhle rèiteachaidh XML" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Meudaichear gnàthaichte dha dh'aplaidean teannta" + +#~ msgid "Images for dialogs" +#~ msgstr "Dealbhan airson còmhraidhean" + +#~ msgid "Generic dialog background" +#~ msgstr "Cùlaibh còmhraidh coitcheann" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Ùrlar airson còmhradh clàraidh a-mach" + +#~ msgid "Wallpaper packages" +#~ msgstr "Pacaidean phàipearan-balla" + +#~ msgid "Images for widgets" +#~ msgstr "Dealbhan airson widgets" + +#~ msgid "Background image for widgets" +#~ msgstr "Dealbhan cùlaibh airson widgets" + +#~ msgid "Analog clock face" +#~ msgstr "Uaireadair aodannail" + +#~ msgid "Background image for panels" +#~ msgstr "Dealbhan cùlaibh airson panailean" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Cùlaibh airson grafaigeachd widgets" + +#~ msgid "Background image for tooltips" +#~ msgstr "Dealbhan cùlaibh airson gliocasan-sgrìn" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Dealbhan do-lèirsinneach airson còmhraidhean" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Cùlaibh còmhraidh do-lèirsinneach coitcheann" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Ùrlar do-lèirsinneach airson còmhradh clàraidh a-mach" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Dealbhan do-lèirsinneach airson widgets" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Dealbhan cùlaibh do-lèirsinneach airson panailean" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Dealbhan cùlaibh do-lèirsinneach airson gliocasan-sgrìn" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Faidhle rèiteachadh KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Tuairisgeulan sheirbheisean" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "" +#~ "Cha b' urrainn dhuinn ScriptEngine %1 a chruthachadh airson an widget %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Dh'fhàillig le tòiseachadh an sgriobt" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Saor-làithean" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Tachartasan" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Rud ri dhèanamh" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Eile" + +#~ msgid "Previous Month" +#~ msgstr "Am mìos roimhe" + +#~ msgid "Previous Year" +#~ msgstr "Am bliadhna roimhe" + +#~ msgid "Previous Decade" +#~ msgstr "An deichead roimhe" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "An-diugh" + +#~ msgid "Reset calendar to today" +#~ msgstr "Ath-suidhich am mìosachan air an-diugh" + +#~ msgid "Next Month" +#~ msgstr "An ath-mhìos" + +#~ msgid "Next Year" +#~ msgstr "An ath-bhliadhna" + +#~ msgid "Next Decade" +#~ msgstr "An ath-dheichead" + +#, fuzzy +#~| msgid "Next Month" +#~ msgid "Months" +#~ msgstr "An ath-mhìos" + +#~ msgid "OK" +#~ msgstr "Ceart ma-thà" + +#~ msgid "Cancel" +#~ msgstr "Sguir dheth" + +#~ msgid "Run the Associated Application" +#~ msgstr "Ruith an aplacaid co-cheangailte" + +#~ msgid "Open with %1" +#~ msgstr "Fosgail le %1" + +#~ msgid "Accessibility" +#~ msgstr "So-ruigsinneachd" + +#~ msgid "Application Launchers" +#~ msgstr "Lòinsearan aplacaidean" + +#~ msgid "Astronomy" +#~ msgstr "Reul-eòlas" + +#~ msgid "Date and Time" +#~ msgstr "Ceann-là 's àm" + +#~ msgid "Development Tools" +#~ msgstr "Innealan leasachaidh" + +#~ msgid "Education" +#~ msgstr "Foghlam" + +#~ msgid "Environment and Weather" +#~ msgstr "An t-àrainneachd 's an aimsir" + +#~ msgid "Examples" +#~ msgstr "Buill-eisimpleir" + +#~ msgid "File System" +#~ msgstr "Siostam fhaidhlichean" + +#~ msgid "Fun and Games" +#~ msgstr "Tlachd is geamannan" + +#~ msgid "Graphics" +#~ msgstr "Grafaigeachd" + +#~ msgid "Language" +#~ msgstr "Cànan" + +#~ msgid "Mapping" +#~ msgstr "Mapachadh" + +#~ msgid "Miscellaneous" +#~ msgstr "Eile" + +#~ msgid "Multimedia" +#~ msgstr "Ioma-mheadhanan" + +#~ msgid "Online Services" +#~ msgstr "Seirbheisean air loidhne" + +#~ msgid "Productivity" +#~ msgstr "Dèanadas" + +#~ msgid "System Information" +#~ msgstr "Fiosrachadh an t-siostaim" + +#~ msgid "Utilities" +#~ msgstr "Goireasan" + +#~ msgid "Windows and Tasks" +#~ msgstr "Uinneagan is saothraichean" + +#~ msgid "Clipboard" +#~ msgstr "Stòr-bhòrd" + +#~ msgid "Tasks" +#~ msgstr "Saothraichean" + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Bun-roghainnean airson an ùrlair is msaa." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "An sgeama dhathan a thèid a chleachdadh airson aplacaidean." + +#~ msgid "Preview Images" +#~ msgstr "Dealbhan ro-sheallaidh" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Ro-shealladh air manaidsear a' chlàraidh a-steach" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Ro-shealladh air an sgrìn-ghlasaidh" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Ro-shealladh air suidsear nan cleachdaichean" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Ro-shealladh air suidsear nan deasgan bhiortail" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Ro-shealladh air an sgrìn splash" + +#~ msgid "Preview for KRunner" +#~ msgstr "Ro-shealladh air KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Ro-shealladh air sgeadachadh nan uinneagan" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Ro-shealladh air suidsear nan uinneagan" + +#~ msgid "Login Manager" +#~ msgstr "Manaidsear a' chlàraidh a-steach" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Prìomh-sgriobt airson manaidsear a' chlàraidh a-steach" + +#~ msgid "Logout Dialog" +#~ msgstr "Còmhradh a' chlàraidh a-mach" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Prìomh-sgriobt airson còmhradh a' chlàraidh a-mach" + +#~ msgid "Screenlocker" +#~ msgstr "Inneal-glasaidh na sgrìn" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Prìomh-sgriobt airson inneal-glasaidh na sgrìn" + +#~ msgid "UI for fast user switching" +#~ msgstr "Eadar-aghaidh airson grad-suidse nan cleachdaichean" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Prìomh-sgriobt airson suidsear nan cleachdaichean" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Suidsear nan deasgan bhiortail" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Prìomh-sgriobt airson suidsear nan deasgan bhiortail" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Brathan air an sgrìn" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Prìomh-sgriobt airson brathan air an sgrìn" + +#~ msgid "Splash Screen" +#~ msgstr "Sgrìn splash" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Prìomh-sgriobt airson na sgrìn splash" + +#~ msgid "KRunner UI" +#~ msgstr "Eadar-aghaidh KRunner" + +#~ msgid "Main Script KRunner" +#~ msgstr "Prìomh-sgriobt KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Sgeadachadh nan uinneagan" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Prìomh-sgriobt airson sgeadachadh nan uinneagan" + +#~ msgid "Window Switcher" +#~ msgstr "Suidsear nan uinneagan" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Prìomh-sgriobt airson suidsear nan uinneagan" + +#~ msgid "Fetching file type..." +#~ msgstr "A' faighinn seòrsa an fhaidhle..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Roghainnean %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Roghainnean %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Roghainnean %1..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Dealbhan le dathan laga airson còmhraidhean" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Cùlaibh còmhraidh le dathan laga coitcheann" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Ùrlar le dathan laga airson còmhradh clàraidh a-mach" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Dealbhan cùlaibh le dathan laga airson widgets" + +#~ msgid "Low color analog clock face" +#~ msgstr "Uaireadair aodannail le dathan laga" + +#~ msgid "Low color background image for panels" +#~ msgstr "Dealbhan cùlaibh le dathan laga airson panailean" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Cùlaibh le dathan laga airson grafaigeachd widgets" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Dealbhan cùlaibh le dathan laga airson gliocasan-sgrìn" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Manaidsear pacaidean Plasma" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Gin hais SHA1airson na pacaid air " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Airson stàladh no toirt air falbh, obraichidh e air pacaidean a chaidh a " +#~ "stàladh airson a h-uile cleachdaiche." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "An seòrsa de phacaid, can ùrlar, pàipear-balla, plasmoid, dataengine, " +#~ "runner, teamplaid co-dhealbhachd, is msaa." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Stàlaich a' phacaid air " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Seall fiosrachadh na pacaid " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Àrdaich a' phacaid air " + +#~ msgid "List installed packages" +#~ msgstr "Seall na pacaidean air an stàladh" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "Seall a h-uile seòrsa de phacaid a ghabhas stàladh" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Thoir air falbh a' phacaid air a tha " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Slighe absaloideach gu freumh na pacaid. Mura deach a sholar, thèid lorg " +#~ "sna pasganan dàta stannardach airson an t-seisein KDE seo 'na àite." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Cha deach leinn hais a ghintinn airson na pacaid %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "Hais SHA1 airson na pacaid aig %1: \"%2\"" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "pàipear-balla" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "pacaid" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "ùrlar" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "dataengine" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "runner" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "plugan pàipeir-bhalla" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "coltas" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "shell" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "teamplaid co-dhealbhachd" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "kwineffect" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "suidsear nan uinneagan" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "kwinscript" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "" +#~ "Cha deach leinn inneal-stàlaidh iomchaidh a lorg airson pacaid dhen t-" +#~ "seòrsa %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "A' sealltainn seòrsaichean de sheirbheisean: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Mearachd: Cha deach am plugan %1 a stàladh." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Tha feum air stàladh, toirt air falbh, àrdachadh no sealladh." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Mearachd: Chan urrainn dhuinn meata-dàta a' plugain a lorg: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "A' sealltainn fiosrachadh na pacaid: %1" + +#~ msgid " Name : %1" +#~ msgstr " Ainm : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Beachd : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Plugan : %1" + +#~ msgid " Author : %1" +#~ msgstr " Ùghdar : %1" + +#~ msgid " Path : %1" +#~ msgstr " Slighe : %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Tha freumh na pacaid is na roghainnean coitcheann an còmhstri a chèile, " +#~ "feuch nach tagh thu ach aonan." + +#~ msgid "Addon Name" +#~ msgstr "Ainm an tuilleadain" + +#~ msgid "Service Type" +#~ msgstr "Seòrsa na seirbheise" + +#~ msgid "Path" +#~ msgstr "Slighe" + +#~ msgid "Type Argument" +#~ msgstr "Argamaid an t-seòrsa" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Seòrsaichean de phacaidean a ghabhas stàladh leis an inneal seo:" + +#~ msgid "Built in:" +#~ msgstr "Chaidh a thogail ann an:" + +#~ msgid "DataEngine" +#~ msgstr "DataEngine" + +#~ msgid "Layout Template" +#~ msgstr "Teamplaid co-dhealbhachd" + +#~ msgid "Look and Feel" +#~ msgstr "Coltas" + +#~ msgid "Package" +#~ msgstr "Pacaid" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoid" + +#~ msgid "Runner" +#~ msgstr "Runner" + +#~ msgid "Shell" +#~ msgstr "Shell" + +#~ msgid "Theme" +#~ msgstr "Ùrlar" + +#~ msgid "Wallpaper Images" +#~ msgstr "Dealbhan pàipeir-bhalla" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Pàipear-balla beòthaichte" + +#~ msgid "KWin Effect" +#~ msgstr "Èifeachd KWin" + +#~ msgid "KWin Window Switcher" +#~ msgstr "Suidsear uinneagan KWin" + +#~ msgid "KWin Script" +#~ msgstr "Sgriobt KWin" + +#~ msgid "Provided by plugins:" +#~ msgstr "'Ga solar le plugain:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "'Ga sholar le faidhlichean .desktop:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "Chaidh %1 àrdachadh gu soirbheachail" + +#~ msgid "Successfully installed %1" +#~ msgstr "Chaidh %1 a stàladh gu soirbheachail" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Mearachd: Dh'fhàillig le stàladh %1: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Ag àrdachadh pacaid on fhaidhle: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Chaidh %1 a dhì-stàladh gu soirbheachail" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Mearachd: Dh'fhàillig le dì-stàladh %1: %2" diff --git a/po/gl/libplasma6.po b/po/gl/libplasma6.po new file mode 100644 index 0000000..02e000e --- /dev/null +++ b/po/gl/libplasma6.po @@ -0,0 +1,1072 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Marce Villarino , 2013, 2014. +# Adrián Chaves Fernández , 2015, 2016, 2017. +# SPDX-FileCopyrightText: 2023, 2024 Adrián Chaves (Gallaecio) +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-25 15:42+0200\n" +"Last-Translator: Adrián Chaves (Gallaecio) \n" +"Language-Team: Proxecto Trasno (proxecto@trasno.gal)\n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 24.05.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Máis accións" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Pregar" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Expandir" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Contrasinal" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Buscar…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Buscar" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Borrar a busca" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Descoñecido" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Activar o trebello de %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Retirar %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Activar o modo de edición" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Configurar %1…" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Trancar os trebellos" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Desatrancar os trebellos" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Desactivar o modo de edición" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Indica se debe ou non crearse unha caché no disco para o tema." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"O tamaño máximo da caché en disco do tema, en kilobytes. Lembre que estes " +"ficheiros son dispersos, polo que poida que non se use o tamaño máximo, polo " +"que pór un tamaño maior a miúdo é seguro." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Amosar as alternativas…" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Retirouse o trebello" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Retirouse o trebello «%1»." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Retirouse o panel" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Retirouse un panel." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Retirouse un escritorio" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Retirouse un escritorio." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Desfacer" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Configuración do trebello" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Retirar este trebello" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Retirar este panel" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Retirar esta actividade" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Configuración da actividade" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Engadir ou xestionar trebellos…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Non foi posíbel atopar o compoñente pedido: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "O elemento raíz de %1 debe ser de tipo «ContainmentItem»." + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "O elemento raíz de %1 debe ser de tipo «PlasmoidItem»." + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Trebello descoñecido" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"O trebello escribiuse para unha versión anterior e descoñecida de Plasma e " +"non é compatíbel con Plasma %1. Solicite a quen fixo o trebello unha versión " +"actualizada." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 non é compatíbel con Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"O trebello escribiuse para Plasma %1 e non é compatíbel con Plasma %2. " +"Solicite a quen fixo o trebello unha versión actualizada." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"O trebello escribiuse para Plasma %1 e non é compatíbel con Plasma %2. " +"Actualice Plasma para usar o trebello." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Produciuse un erro ao cargar %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Produciuse un erro ao cargar o ficheiro QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "" +"Produciuse un erro ao cargar o miniaplicativo: o paquete %1 non existe." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — Configuración de %2" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Configuración de %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Paquete de Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Instalar" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "A instalación do paquete fallou" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "O paquete que soltou é incorrecto." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Trebellos" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Engadir %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Engadir unha icona" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Fondo de escritorio" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Definir %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Soltouse contido" + +#~ msgid "Add Widgets..." +#~ msgstr "Engadir trebellos…" + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Non foi posíbel abrir o paquete %1 requirido polo trebello %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Compartir un trebello na rede permítelle acceder a este trebello desde " +#~ "outro computador como se for un control remoto." + +#~ msgid "Share this widget on the network" +#~ msgstr "Compartir este trebello na rede." + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Permitirlle a todo o mundo acceder libremente a este trebello." + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "" +#~ "O servizo é incorrecto (nulo); non se pode realizar ningunha operación." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "O trebello %1 non define que ScriptEngine usar." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Diversos" + +#~ msgid "Main Script File" +#~ msgstr "Ficheiro de script principal" + +#~ msgid "Tests" +#~ msgstr "Probas" + +#~ msgid "Images" +#~ msgstr "Imaxes" + +#~ msgid "Themed Images" +#~ msgstr "Imaxes con tema" + +#~ msgid "Configuration Definitions" +#~ msgstr "Definicións de configuración" + +#~ msgid "User Interface" +#~ msgstr "Interface de usuario" + +#~ msgid "Data Files" +#~ msgstr "Ficheiros de datos" + +#~ msgid "Executable Scripts" +#~ msgstr "Scripts executábeis" + +#~ msgid "Screenshot" +#~ msgstr "Captura de pantalla" + +#~ msgid "Translations" +#~ msgstr "Traducións" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Modelo de páxinas de configuración da UI" + +#~ msgid "Configuration XML file" +#~ msgstr "Ficheiro XML de configuración" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Expansor personalizado para miniaplicativos compactos" + +#~ msgid "Images for dialogs" +#~ msgstr "Imaxes para diálogos" + +#~ msgid "Generic dialog background" +#~ msgstr "Fondo de diálogo xenérico" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Tema do diálogo de saída" + +#~ msgid "Wallpaper packages" +#~ msgstr "Paquetes de fondo de escritorio" + +#~ msgid "Images for widgets" +#~ msgstr "Imaxes para trebellos" + +#~ msgid "Background image for widgets" +#~ msgstr "Imaxe de fondo para os trebellos" + +#~ msgid "Analog clock face" +#~ msgstr "Aspecto do reloxo analóxico" + +#~ msgid "Background image for panels" +#~ msgstr "Imaxe de fondo para os paneis" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Fondo dos trebellos de debuxo" + +#~ msgid "Background image for tooltips" +#~ msgstr "Imaxe de fondo para as axudas" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Imaxes opacas para diálogos" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Fondo opaco de diálogo xenérico" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Tema opaco para o diálogo de saída" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Imaxes opacas para os trebellos" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Imaxe opaca de fondo para os paneis" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Imaxe opaca de fondo para as axudas" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Ficheiro de configuración de KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Descricións de servizo" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Non se puido crear un ScriptEngine de %1 para o trebello %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Fallou a inicialización do script" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Vacacións" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Eventos" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Por facer" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Outros" + +#~ msgid "Previous Month" +#~ msgstr "Mes anterior" + +#~ msgid "Previous Year" +#~ msgstr "Ano anterior" + +#~ msgid "Previous Decade" +#~ msgstr "Década anterior" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Hoxe" + +#~ msgid "Reset calendar to today" +#~ msgstr "Devolver o calendario a hoxe" + +#~ msgid "Next Month" +#~ msgstr "Seguinte mes" + +#~ msgid "Next Year" +#~ msgstr "Seguinte ano" + +#~ msgid "Next Decade" +#~ msgstr "Seguinte década" + +#, fuzzy +#~| msgid "Next Month" +#~ msgid "Months" +#~ msgstr "Seguinte mes" + +#~ msgid "OK" +#~ msgstr "Aceptar" + +#~ msgid "Cancel" +#~ msgstr "Cancelar" + +#~ msgid "Run the Associated Application" +#~ msgstr "Executar a aplicación asociada" + +#~ msgid "Open with %1" +#~ msgstr "Abrir con %1" + +#~ msgid "Accessibility" +#~ msgstr "Accesibilidade" + +#~ msgid "Application Launchers" +#~ msgstr "Iniciadores de aplicacións" + +#~ msgid "Astronomy" +#~ msgstr "Astronomía" + +#~ msgid "Date and Time" +#~ msgstr "Data e hora" + +#~ msgid "Development Tools" +#~ msgstr "Ferramentas de desenvolvemento" + +#~ msgid "Education" +#~ msgstr "Educación" + +#~ msgid "Environment and Weather" +#~ msgstr "Medio ambiente e clima" + +#~ msgid "Examples" +#~ msgstr "Exemplos" + +#~ msgid "File System" +#~ msgstr "Sistema de ficheiros" + +#~ msgid "Fun and Games" +#~ msgstr "Lecer e xogos" + +#~ msgid "Graphics" +#~ msgstr "Gráficos" + +#~ msgid "Language" +#~ msgstr "Idioma" + +#~ msgid "Mapping" +#~ msgstr "Mapas" + +#~ msgid "Miscellaneous" +#~ msgstr "Diversos" + +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + +#~ msgid "Online Services" +#~ msgstr "Servizos en Internet" + +#~ msgid "Productivity" +#~ msgstr "Produtividade" + +#~ msgid "System Information" +#~ msgstr "Información do sistema" + +#~ msgid "Utilities" +#~ msgstr "Utensilios" + +#~ msgid "Windows and Tasks" +#~ msgstr "Xanelas e tarefas" + +#~ msgid "Clipboard" +#~ msgstr "Portapapeis" + +#~ msgid "Tasks" +#~ msgstr "Tarefas" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Editar %1…" + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Configuración predeterminada do tema etc." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Esquema de cores para usar nas aplicacións." + +#~ msgid "Preview Images" +#~ msgstr "Vista previa das imaxes" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Vista previa do xestor de acceso" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Vista previa do bloqueo da pantalla" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Vista previa do cambiador de usuario" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Vista previa do Conmutador de escritorio virtual" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Vista previa da Pantalla de benvida" + +#~ msgid "Preview for KRunner" +#~ msgstr "Vista previa de KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Vista previa da decoración da xanela" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Vista previa do selector de xanelas" + +#~ msgid "Login Manager" +#~ msgstr "Xestor de acceso" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Script principal do xestor de acceso" + +#~ msgid "Logout Dialog" +#~ msgstr "Diálogo de saída" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Script principal do diálogo de saída" + +#~ msgid "Screenlocker" +#~ msgstr "Screenlocker" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Script principal do bloqueo da pantalla" + +#~ msgid "UI for fast user switching" +#~ msgstr "UI para o cambio rápido de usuario" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Script principal do conmutador de usuario" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Selector de escritorio virtual" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Script principal do selector de escritorio virtual" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Notificacións visualizadas na pantalla" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Script principal das notificacións visualizadas na pantalla" + +#~ msgid "Splash Screen" +#~ msgstr "Pantalla de benvida" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Script principal da Pantalla de benvida" + +#~ msgid "KRunner UI" +#~ msgstr "UI de KRunner" + +#~ msgid "Main Script KRunner" +#~ msgstr "Script principal de KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Decoración da xanela" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Script principal da decoración da xanela" + +#~ msgid "Window Switcher" +#~ msgstr "Selector de xanelas" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Script principal do selector de xanelas" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Rematar de personalizar a disposición" + +#~ msgid "Customize Layout..." +#~ msgstr "Personalizar a disposición…" + +#~ msgid "Fetching file type..." +#~ msgstr "Estase a obter o tipo do ficheiro…" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Opcións de %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Retirar este %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Configuración de %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Configuración de %1…" + +#~ msgid "Low color images for dialogs" +#~ msgstr "Imaxes de pouca cor para os diálogos" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Fondo xenérico de pouca cor para os diálogos" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Tema de pouca cor para o diálogo de saída" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Imaxe de fondo de pouca cor para os trebellos" + +#~ msgid "Low color analog clock face" +#~ msgstr "Aspecto de pouca cor do reloxo analóxico" + +#~ msgid "Low color background image for panels" +#~ msgstr "Imaxe de fondo de pouca cor para os paneis" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Fondos de pouca cor para os trebellos de debuxo" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Imaxe de fondo de pouca cor para as axudas" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Xestor de paquetes de Plasma" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Xera un hash SHA1 para o paquete en " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Para instalar ou desinstalar, opera en paquetes instalados para todos os " +#~ "usuarios." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "O tipo do paquete, por ex. tema, fondo de escritorio, plasmoide, motor de " +#~ "dados, executor, modelo de disposición etc." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Instalar o paquete en " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Mostrar información do paquete " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Anovar o paquete en " + +#~ msgid "List installed packages" +#~ msgstr "Listar os paquetes instalados" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "Lista todos os tipos coñecidos de paquete que se poden instalar." + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Desinstalar o paquete chamado " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "A ruta absoluta á raíz do paquete. Se non se indica, entón buscarase nos " +#~ "directorios estándar para datos desta sesión de KDE." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Produciuse un erro ao xerar un hash de paquete para %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "Hash SHA1 para o paquete en %1: «%2»" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "fondo de escritorio" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoide" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "paquete" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "tema" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "motor de datos" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "executor" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "wallpaperplugin" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "aparencia e comportamento" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "shell" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "modelo de disposición" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "efecto de kwin" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "troco de escritorio" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "script de kwin" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "" +#~ "Non foi posíbel atopar un instalador apropiado para o paquete do tipo %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "Lista dos tipos de servizo: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Erro: O complemento %1 non está instalado." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Requírese unha de install, remove, upgrade ou list." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Erro: Non se atoparon os metadatos do complemento: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Mostrar información do paquete: %1" + +#~ msgid " Name : %1" +#~ msgstr " Nome: %1" + +#~ msgid " Comment : %1" +#~ msgstr " Comentario: %1" + +#~ msgid " Plugin : %1" +#~ msgstr "Complemento: %1" + +#~ msgid " Author : %1" +#~ msgstr " Autor: %1" + +#~ msgid " Path : %1" +#~ msgstr " Ruta: %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "As opcións globais e as de packageroot están en conflito entre si, " +#~ "escolla só unha delas." + +#~ msgid "Addon Name" +#~ msgstr "Nome do engadido" + +#~ msgid "Service Type" +#~ msgstr "Tipo de servizo" + +#~ msgid "Path" +#~ msgstr "Ruta" + +#~ msgid "Type Argument" +#~ msgstr "Tipo do argumento" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Tipos de paquete instalábeis con esta utilidade:" + +#~ msgid "Built in:" +#~ msgstr "Incorporado:" + +#~ msgid "DataEngine" +#~ msgstr "Motor de datos" + +#~ msgid "Layout Template" +#~ msgstr "Modelo de disposición" + +#~ msgid "Look and Feel" +#~ msgstr "Aparencia e comportamento" + +#~ msgid "Package" +#~ msgstr "Paquete" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoide" + +#~ msgid "Runner" +#~ msgstr "Executor" + +#~ msgid "Shell" +#~ msgstr "Shell" + +#~ msgid "Theme" +#~ msgstr "Tema" + +#~ msgid "Wallpaper Images" +#~ msgstr "Fondos de escritorio" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Fondo de escritorio animado" + +#~ msgid "KWin Effect" +#~ msgstr "Efecto de KWin" + +#~ msgid "KWin Window Switcher" +#~ msgstr "Selector de xanela do KWin" + +#~ msgid "KWin Script" +#~ msgstr "Script do KWin" + +#~ msgid "Provided by plugins:" +#~ msgstr "Fornecido por complementos:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Fornecido por ficheiros .desktop:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "%1 anovouse con éxito" + +#~ msgid "Successfully installed %1" +#~ msgstr "%1 instalouse satisfactoriamente" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Erro: a instalación de %1 fallou: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Actualización do paquete do ficheiro: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "%1 desinstalouse con éxito" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Erro: A desinstalación de %1 fallou: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Non foi posíbel achar un instalador axeitado para o paquete do tipo %1. " +#~ "Informouse do erro: %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Non foi posíbel crear o directorio raíz do paquete: %1" + +#~ msgid "No such file: %1" +#~ msgstr "Non existe o ficheiro: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "" +#~ "Non foi posíbel abrir o ficheiro do paquete, o formato do arquivo non é " +#~ "compatíbel: %1 %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "Non foi posíbel abrir o ficheiro do paquete: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "Non hai ficheiro de metadatos no paquete: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "Non se indicou o nome do complemento do paquete: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "O nome %1 do complemento do paquete contén caracteres non válidos" + +#~ msgid "%1 already exists" +#~ msgstr "%1 xa existe" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Non foi posíbel mover o paquete ao destino: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Non foi posíbel copiar o paquete ao destino: %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Non foi posíbel crear o directorio do servizo local: %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "Non foi posíbel rexistrar o paquete como un servizo (este non é " +#~ "necesariamente un erro fatal): %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 non existe" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Non foi posíbel eliminar o paquete de: %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "Desexa realmente eliminar este %1?" + +#~ msgid "Applets furniture" +#~ msgstr "Mostrario de applets" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "Un explorador para engadir wigdets" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "Interface de usuario para as vistas que mostra contedores" + +#~ msgid "Default layout file" +#~ msgstr "Ficheiro da disposición predeterminada" + +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "" +#~ "Complementos predeterminados para contedores, containmentActions etc" + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "Mensaxe de erro que se mostra cando unha applet non consegue cargar" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "Compoñente de QML que mostra unha applet nunha xanela emerxente" + +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Unha representación compacta dunha applet cando se contrae nun elemento " +#~ "emerxente, por exemplo como unha icona. As applets poden sobrescribir " +#~ "esta compoñente." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "Compoñente QML para o diálogo de configuración das applets" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "Compoñente QML para o diálogo de configuración dos contedores" + +#~ msgid "Panel configuration UI" +#~ msgstr "UI de configuración do panel" + +#, fuzzy +#~| msgid "QML component for the configuration dialog for applets" +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "Compoñente QML para o diálogo de configuración das applets" + +#~ msgid "Ok" +#~ msgstr "Aceptar" + +#, fuzzy +#~ msgid "search term" +#~ msgstr "termo a buscar" diff --git a/po/he/libplasma6.po b/po/he/libplasma6.po new file mode 100644 index 0000000..1417bf5 --- /dev/null +++ b/po/he/libplasma6.po @@ -0,0 +1,496 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Elkana Bardugo , 2016. +# Elkana Bardugo , 2017. #zanata +# SPDX-FileCopyrightText: 2023, 2024 Yaron Shahrabani +msgid "" +msgstr "" +"Project-Id-Version: libplasma5\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-23 07:06+0300\n" +"Last-Translator: Yaron Shahrabani \n" +"Language-Team: צוות התרגום של KDE ישראל\n" +"Language: he\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && " +"n % 10 == 0) ? 2 : 3));\n" +"X-Generator: Lokalize 24.05.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "פעולות נוספות" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "צמצום" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "הרחבה" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "סיסמה" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "חיפוש…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "חיפוש" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "פינוי החיפוש" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "לא ידוע" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "הפעלת יישומון %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "הסרת %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "כניסה למצב עריכה" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "הגדרת %1…" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "נעילת יישומונים" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "שחרור יישומונים" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "יציאה ממצב עריכה" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "האם ליצור מטמון בכונן לערכת העיצוב." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"הגודל המרבי של מטמון ערכות עיצוב על הכונן הוא בקילובתים. נא לשים שהקבצים " +"האלה הם דלילים, לכן סביר להניח שלא ייעשה שימוש במלוא הגודל שהוגדר. הגדרת " +"גודל גדול יותר היא בדרך כלל די בטוחה." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "הצגת חלופות…" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "יישומון הוסר" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "היישומון „%1” הוסר." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "לוח הוסר" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "לוח הוסר." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "שולחן עבודה הוסר" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "שולחן עבודה הוסר." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "החזרה" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "הגדרות יישומון" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "הסרת יישומון זה" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "הסרת לוח זה" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "הסרת פעילות זו" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "הגדרות פעילות" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "הוספת או ניהול יישומונים…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "לא ניתן למצוא את הרכיב המבוקש: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "פריט הבסיס של %1 חייב להיות מסוג ContaimentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "פריט הבסיס של %1 חייב להיות מסוג PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "יישומון לא ידוע" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"היישומון הזה נכתב לגרסה ישנה יותר ולא ידועה של פלזמה ואין נתמך בפלזמה %1. נא " +"ליצור קשר עם יוצרי היישומון לאספקת גרסה עדכנית." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 לא נתמך בפלזמה %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"היישומון נכתב לפלזמה %1 ואינו נתמך בפלזמה %2. נא ליצור קשר עם יוצרי היישומון " +"לאספקת גרסה עדכנית" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"היישומון הזה נכתב לפלזמה %1 ואינו נתמך בפלזמה %2. נא לעדכן את פלזמה כדי " +"להשתמש ביישומון." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "הייתה שגיאה בטעינת %1, עמך הסליחה!" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "שגיאה בטעינת קובץ QML‏: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "שגיאה בטעינת יישומונית: החבילה %1 לא קיימת." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — הגדרות %2" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "הגדרות %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "חבילת פלזמה" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "התקנה" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "התקנת החבילה נכשלה" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "החבילה שהרגע גררת שגויה." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "יישומונים" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "הוספת %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "הוספת סמל" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "תמונת רקע" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "הגדרת %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "התוכן נגרר" + +#~ msgid "Add Widgets..." +#~ msgstr "הוספת יישומונים…" + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "לא ניתן לפתוח את החבילה %1 שנחוצה ליישומון %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "שיתוף היישומון הזה ברשת מאפשר לך לגשת ליישומון הזה ממחשב אחר כשליטה מרחוק." + +#~ msgid "Share this widget on the network" +#~ msgstr "שיתוף היישומון הזה ברשת" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "לאפשר לכולם לגשת ליישומון הזה בחופשיות" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "שירות (אפס) לא ידוע, אי אפשר לבצע פעולות." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "היישומון %1 לא הגדיר באיזה מנוע סקריפטים (ScriptEngine) להשתמש." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "שונות" + +#~ msgid "Tests" +#~ msgstr "בדיקות" + +#~ msgid "Images" +#~ msgstr "תמונות" + +#~ msgid "User Interface" +#~ msgstr "ממשק משתמש" + +#~ msgid "Data Files" +#~ msgstr "קובצי נתונים" + +#~ msgid "Executable Scripts" +#~ msgstr "סקריפט בר־הרצה" + +#~ msgid "Screenshot" +#~ msgstr "צילום מסך" + +#~ msgid "Translations" +#~ msgstr "תרגומים" + +#~ msgid "Background image for panels" +#~ msgstr "תמונת רקע ללוחות" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "חגים" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "אירועים" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "אחר" + +#~ msgid "Previous Month" +#~ msgstr "חודש קודם" + +#~ msgid "Previous Year" +#~ msgstr "שנה קודמת" + +#~ msgid "Previous Decade" +#~ msgstr "העשור הקודם" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "היום" + +#~ msgid "Next Month" +#~ msgstr "חודש הבא" + +#~ msgid "Next Year" +#~ msgstr "שנה הבאה" + +#~ msgid "Next Decade" +#~ msgstr "העשור הבא" + +#, fuzzy +#~| msgid "Next Month" +#~ msgid "Months" +#~ msgstr "חודש הבא" + +#~ msgid "OK" +#~ msgstr "אישור" + +#~ msgid "Cancel" +#~ msgstr "בטל" + +#~ msgid "Open with %1" +#~ msgstr "פתח באמצעות %1" + +#~ msgid "Accessibility" +#~ msgstr "נגישות" + +#~ msgid "Application Launchers" +#~ msgstr "משגר יישומים" + +#~ msgid "Astronomy" +#~ msgstr "אסטרונומיה" + +#~ msgid "Date and Time" +#~ msgstr "זמן ותאריך" + +#~ msgid "Development Tools" +#~ msgstr "כלי פיתוח" + +#~ msgid "Education" +#~ msgstr "חינוך" + +#~ msgid "Environment and Weather" +#~ msgstr "אווירה ומזג האוויר" + +#~ msgid "Examples" +#~ msgstr "דוגמאות" + +#~ msgid "File System" +#~ msgstr "מערכת קבצים" + +#~ msgid "Fun and Games" +#~ msgstr "כיף ומשחקים" + +#~ msgid "Graphics" +#~ msgstr "גרפיקה" + +#~ msgid "Language" +#~ msgstr "שפה" + +#~ msgid "Mapping" +#~ msgstr "מיפוי" + +#~ msgid "Miscellaneous" +#~ msgstr "שונות" + +#~ msgid "Multimedia" +#~ msgstr "מדיה" + +#~ msgid "System Information" +#~ msgstr "מידע מערכת" + +#~ msgid "Utilities" +#~ msgstr "כלים" + +#~ msgid "Windows and Tasks" +#~ msgstr "חלונות ומשימות" + +#~ msgid "Clipboard" +#~ msgstr "לוח העתקה" + +#~ msgid "Tasks" +#~ msgstr "משימות" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "אפשרויות %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "הגדרות %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "הגדרות %1..." diff --git a/po/hu/libplasma6.po b/po/hu/libplasma6.po new file mode 100644 index 0000000..030d7e2 --- /dev/null +++ b/po/hu/libplasma6.po @@ -0,0 +1,1082 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Balázs Úr , 2013, 2014. +# Kristóf Kiszel , 2014, 2015, 2019. +# Kiszel Kristóf , 2017, 2018, 2020, 2021. +# SPDX-FileCopyrightText: 2024 Kristof Kiszel +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-09-22 21:52+0200\n" +"Last-Translator: Kristof Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 24.08.0\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "További műveletek" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Összecsukás" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Kibontás" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Jelszó" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Keresés…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Keresés" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Keresés törlése" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Ismeretlen" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "%1 felületi elem aktiválása" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "A(z) %1 eltávolítása" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Belépés a szerkesztőmódba" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "A(z) %1 beállítása…" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Felületi elemek zárolása" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Felületi elemek feloldása" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Kilépés a szerkesztőmódból" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Hozzon-e létre gyorsítótárat a lemezen a témához, vagy sem." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"A téma gyorsítótárának maximális mérete, kilobájtban megadva. Ezek a fájlok " +"ritkán használtak, vagyis a maximális méret nem mindig lesz kihasználva, " +"ugyanakkor biztonságosabb nagyobb méretet beállítani." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Alternatívák megjelenítése…" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Elem eltávolítva" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "A(z) „%1” elem eltávolításra került." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panel eltávolítva" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Egy panel eltávolításra került." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Asztal eltávolítva" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Egy asztal eltávolításra került." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Visszavonás" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Felületi elem beállítások" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Felületi elem eltávolítása" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Panel eltávolítása" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Aktivitás eltávolítása" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Tevékenység beállítások" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Elemek hozzáadása vagy kezelése…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "A kért komponens nem található: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "A(z) %1 gyökérelemének ContainmentItem típusúnak kell lennie" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "A(z) %1 gyökérelemének PlasmoidItem típusúnak kell lennie" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Ismeretlen kisalkalmazás" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Az elem a Plasma egy régebbi, ismeretlen verziójához készült, és nem " +"kompatibilis a Plasma %1 verzióval. Lépjen kapcsolatba a szerzőjével egy " +"frissített verzióért." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "A(z) %1 nem kompatibilis a Plasma %2 verzióval" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Az elem a Plasma %1 verziójához készült, és nem kompatibilis a Plasma %2 " +"verzióval. Lépjen kapcsolatba a szerzőjével egy frissített verzióért." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Az elem a Plasma %1 verziójához készült, és nem kompatibilis a Plasma %2 " +"verzióval. Frissítse a Plasmát az elem használatához." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Hiba történt a(z) %1 betöltésekor." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Hiba a QML fájl betöltése közben: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Hiba a kisalkalmazás betöltésekor: a(z) %1 csomag nem létezik." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 beállításai" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Beállítások: %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma csomag" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Telepítés" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Sikertelen csomagtelepítés" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "A most ejtett csomag érvénytelen." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Elemek" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "A(z) %1 hozzáadása" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Ikon hozzáadása" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Háttérkép" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "A(z) %1 beállítása" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Tartalom ejtve" + +#~ msgid "Add Widgets..." +#~ msgstr "Felületi elemek hozzáadása…" + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Nem sikerült megnyitni ezt a csomagot: %1. Igénylő elem: %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "A felületi elemek hálózaton történő megosztásakor lehetővé teszi ehhez a " +#~ "felületi elemhez való hozzáférést másik számítógépről mint távirányítóról." + +#~ msgid "Share this widget on the network" +#~ msgstr "Felületi elem megosztása a hálózaton" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Bárki számára szabad hozzáférést enged ehhez a felületi elemhez" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "" +#~ "Érvénytelen (null) szolgáltatás, nem végezhető el semmilyen művelet." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "" +#~ "A(z) %1 felületi elem nem határozta meg, hogy melyik ScriptEngine-t " +#~ "használja." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Egyebek" + +#~ msgid "Main Script File" +#~ msgstr "Fő szkriptfájl" + +#~ msgid "Tests" +#~ msgstr "Tesztek" + +#~ msgid "Images" +#~ msgstr "Képek" + +#~ msgid "Themed Images" +#~ msgstr "Témázott képek" + +#~ msgid "Configuration Definitions" +#~ msgstr "Beállításdefiníciók" + +#~ msgid "User Interface" +#~ msgstr "Felhasználói felület" + +#~ msgid "Data Files" +#~ msgstr "Adatfájlok" + +#~ msgid "Executable Scripts" +#~ msgstr "Végrehajtható szkriptek" + +#~ msgid "Screenshot" +#~ msgstr "Képernyőkép" + +#~ msgid "Translations" +#~ msgstr "Fordítások" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Beállító felhasználói felület oldalmodellek" + +#~ msgid "Configuration XML file" +#~ msgstr "XML beállítófájl" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Egyéni kiterjesztő kompakt kisalkalmazásokhoz" + +#~ msgid "Images for dialogs" +#~ msgstr "Képek párbeszédablakokhoz" + +#~ msgid "Generic dialog background" +#~ msgstr "Általános párbeszédablak-háttér" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Téma a kijelentkező párbeszédablakhoz" + +#~ msgid "Wallpaper packages" +#~ msgstr "Háttérképcsomagok" + +#~ msgid "Images for widgets" +#~ msgstr "Képek a felületi elemekhez" + +#~ msgid "Background image for widgets" +#~ msgstr "Háttérkép a felületi elemekhez" + +#~ msgid "Analog clock face" +#~ msgstr "Analóg óralap" + +#~ msgid "Background image for panels" +#~ msgstr "Háttérkép panelekhez" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Háttérkép grafikus felületi elemekhez" + +#~ msgid "Background image for tooltips" +#~ msgstr "Háttérkép buboréksúgókhoz" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Átlátszatlan képek párbeszédablakokhoz" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Átlátszatlan általános párbeszédablak háttér" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Átlátszatlan téma a kijelentkező párbeszédablakhoz" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Átlátszatlan képek felületi elemekhez" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Átlátszatlan háttérkép panelekhez" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Átlátszatlan háttérkép buboréksúgókhoz" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme beállítófájl" + +#~ msgid "Service Descriptions" +#~ msgstr "Szolgáltatásleírások" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Nem sikerült megnyitni ezt a szkriptmodult: %1. Igénylő elem: %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Nem sikerült inicializálni a szkriptet" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Ünnepnapok" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Események" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Tennivaló" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Egyéb" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%2 %1" + +#~ msgid "Previous Month" +#~ msgstr "Előző hónap" + +#~ msgid "Previous Year" +#~ msgstr "Előző év" + +#~ msgid "Previous Decade" +#~ msgstr "Előző évtized" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Ma" + +#~ msgid "Reset calendar to today" +#~ msgstr "Naptára visszaállítása a mai napra" + +#~ msgid "Next Month" +#~ msgstr "Következő hónap" + +#~ msgid "Next Year" +#~ msgstr "Következő év" + +#~ msgid "Next Decade" +#~ msgstr "Következő évtized" + +#~ msgid "Days" +#~ msgstr "Napok" + +#~ msgid "Months" +#~ msgstr "Hónapok" + +#~ msgid "Years" +#~ msgstr "Évek" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "Mégsem" + +#~ msgid "Run the Associated Application" +#~ msgstr "A társított alkalmazás futtatása" + +#~ msgid "Open with %1" +#~ msgstr "Megnyitás ezzel: %1" + +#~ msgid "Accessibility" +#~ msgstr "Akadálymentesítés" + +#~ msgid "Application Launchers" +#~ msgstr "Alkalmazásindítók" + +#~ msgid "Astronomy" +#~ msgstr "Csillagászat" + +#~ msgid "Date and Time" +#~ msgstr "Dátum és idő" + +#~ msgid "Development Tools" +#~ msgstr "Fejlesztőeszközök" + +#~ msgid "Education" +#~ msgstr "Oktatás" + +#~ msgid "Environment and Weather" +#~ msgstr "Környezet és időjárás" + +#~ msgid "Examples" +#~ msgstr "Példák" + +#~ msgid "File System" +#~ msgstr "Fájlrendszer" + +#~ msgid "Fun and Games" +#~ msgstr "Játék és szórakozás" + +#~ msgid "Graphics" +#~ msgstr "Grafika" + +#~ msgid "Language" +#~ msgstr "Nyelv" + +#~ msgid "Mapping" +#~ msgstr "Térképek" + +#~ msgid "Miscellaneous" +#~ msgstr "Egyebek" + +#~ msgid "Multimedia" +#~ msgstr "Multimédia" + +#~ msgid "Online Services" +#~ msgstr "Internetes szolgáltatások" + +#~ msgid "Productivity" +#~ msgstr "Termelékenység" + +#~ msgid "System Information" +#~ msgstr "Rendszer információk" + +#~ msgid "Utilities" +#~ msgstr "Segédprogramok" + +#~ msgid "Windows and Tasks" +#~ msgstr "Ablakok és feladatok" + +#~ msgid "Clipboard" +#~ msgstr "Vágólap" + +#~ msgid "Tasks" +#~ msgstr "Feladatok" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "A(z) %1 szerkesztése…" + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Alapértelmezett beállítások témákhoz, stb." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Az alkalmazások által használandó színséma." + +#~ msgid "Preview Images" +#~ msgstr "Előnézeti képek" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Előnézet a bejelentkezéskezelőhöz" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Előnézet a zárolóképernyőhöz" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Előnézet a felhasználóváltóhoz" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Előnézet a virtuálisasztal-váltóhoz" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Előnézet a nyitóképernyőhöz" + +#~ msgid "Preview for KRunner" +#~ msgstr "Előnézet a KRunnerhöz" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Előnézet az ablakdekorációkhoz" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Előnézet az ablakváltóhoz" + +#~ msgid "Login Manager" +#~ msgstr "Bejelentkezéskezelő" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "A bejelentkezéskezelő fő szkriptje" + +#~ msgid "Logout Dialog" +#~ msgstr "Kijelentkező párbeszédablak" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "A kijelentkező párbeszédablak fő szkriptje" + +#~ msgid "Screenlocker" +#~ msgstr "Képernyőzár" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "A zárolóképernyő fő szkriptje" + +#~ msgid "UI for fast user switching" +#~ msgstr "Felhasználói felület gyors felhasználóváltáshoz" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "A felhasználóváltó fő szkriptje" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Virtuálisasztal-váltó" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "A virtuálisasztal-váltó fő szkriptje" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Képernyőn megjelenő értesítések" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "A képernyőn megjelenő értesítések fő szkriptje" + +#~ msgid "Splash Screen" +#~ msgstr "Nyitóképernyő" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "A nyitóképernyő fő szkriptje" + +#~ msgid "KRunner UI" +#~ msgstr "KRunner UI" + +#~ msgid "Main Script KRunner" +#~ msgstr "A KRunner fő szkriptje" + +#~ msgid "Window Decoration" +#~ msgstr "Ablakdekoráció" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Az ablakdekoráció fő szkriptje" + +#~ msgid "Window Switcher" +#~ msgstr "Ablakváltó" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Az ablakváltó fő szkriptje" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Kilépés" + +#~ msgid "Customize Layout..." +#~ msgstr "Elrendezés testre szabása…" + +#~ msgid "Fetching file type..." +#~ msgstr "Fájltípus lekérése…" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1 beállításai" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Eltávolítás: %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "%1 beállításai" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "A(z) %1 beállításai…" + +#~ msgid "Low color images for dialogs" +#~ msgstr "Kevés színt használó képek párbeszédablakokhoz" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Kevés színt használó általános párbeszédablak háttér" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Kevés színt használó téma a kijelentkező párbeszédablakhoz" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Kevés színt használó háttérkép felületi elemekhez" + +#~ msgid "Low color analog clock face" +#~ msgstr "Kevés színt használó analóg óralap" + +#~ msgid "Low color background image for panels" +#~ msgstr "Kevés színt használó háttérkép panelekhez" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Kevés színt használó háttér grafikus felületi elemekhez" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Kevés színt használó háttérkép buboréksúgókhoz" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Kezelőprogram Plasma-csomagokhoz" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "SHA1 összeg generálása ehhez a csomaghoz: " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Telepítéshez és eltávolításhoz, a mindenki számára elérhetően telepített " +#~ "csomagokhoz." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "A csomag típusa, például téma, háttérkép, plazmoid, adatmodul, indító, " +#~ "elrendezéssablon, stb." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Csomag telepítése innen: " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "A(z) csomag adatainak megjelenítése" + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Csomag frissítése innen: " + +#~ msgid "List installed packages" +#~ msgstr "Telepített csomagok listázása" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "Az összes telepíthető csomagtípus listázása" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "A(z) csomag eltávolítása" + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "A csomag teljes elérési útja. Ha nincs megadva, akkor először a KDE-" +#~ "munkamenet standard mappái lesznek végignézve." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Nem sikerült ellenőrző összeget generálni ehhez: %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "A(z) %1 helyen lévő csomag SHA1 összege: „%2”" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "háttérkép" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plazmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "csomag" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "téma" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "adatmodul" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "futtató" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "háttérképbővítmény" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "megjelenés" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "felület" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "elrendezéssablon" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "kwin effektus" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "ablakváltó" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "kwin szkript" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "Nem található telepítő a(z) %1 csomagtípushoz" + +#~ msgid "Listing service types: %1" +#~ msgstr "Szolgáltatástípusok listázása: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Hiba: a(z) %1 bővítmény nincs telepítve." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "" +#~ "Az install, remove, upgrade vagy list paraméterek valamelyikének megadása " +#~ "szükséges." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Hiba: nem találhatók a bővítmény metaadatai: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Csomag adatainak megjelenítése: %1" + +#~ msgid " Name : %1" +#~ msgstr " Név : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Megjegyzés : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Bővítmény : %1" + +#~ msgid " Author : %1" +#~ msgstr " Szerző : %1" + +#~ msgid " Path : %1" +#~ msgstr " Elérési út : %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "A packageroot és global opciók ütköznek egymással, csak egyet használjon " +#~ "a kettő közül!" + +#~ msgid "Addon Name" +#~ msgstr "Bővítménynév" + +#~ msgid "Service Type" +#~ msgstr "Szolgáltatástípus" + +#~ msgid "Path" +#~ msgstr "Elérési út" + +#~ msgid "Type Argument" +#~ msgstr "Típusargumentum" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Az ezzel az eszközzel telepíthető csomagtípusok:" + +#~ msgid "Built in:" +#~ msgstr "Beépített:" + +#~ msgid "DataEngine" +#~ msgstr "Adatmodul" + +#~ msgid "Layout Template" +#~ msgstr "Elrendezéssablon" + +#~ msgid "Look and Feel" +#~ msgstr "Megjelenés" + +#~ msgid "Package" +#~ msgstr "Csomag" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoid" + +#~ msgid "Runner" +#~ msgstr "Indító" + +#~ msgid "Shell" +#~ msgstr "Felület" + +#~ msgid "Theme" +#~ msgstr "Téma" + +#~ msgid "Wallpaper Images" +#~ msgstr "Háttérképek" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Animált háttérkép" + +#~ msgid "KWin Effect" +#~ msgstr "KWin effektus" + +#~ msgid "KWin Window Switcher" +#~ msgstr "KWin ablakváltó" + +#~ msgid "KWin Script" +#~ msgstr "KWin szkript" + +#~ msgid "Provided by plugins:" +#~ msgstr "Bővítmények által biztosított:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr ".desktop fájlok által biztosított:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "Sikeresen frissítve: %1" + +#~ msgid "Successfully installed %1" +#~ msgstr "Sikeresen telepítve: %1" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Hiba: a(z) %1 telepítése meghiúsult: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Csomag frissítése fájlból: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Sikeresen eltávolítva: %1" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Hiba: a(z) %1 eltávolítása meghiúsult: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Nem lehet betölteni a telepítőt a(z) %1 csomagtípushoz. A hiba oka: %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Nem sikerült létrehozni a csomag gyökérkönyvtárát: %1" + +#~ msgid "No such file: %1" +#~ msgstr "Nincs ilyen fájl: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "" +#~ "Nem sikerült megnyitni a csomagfájlt, nem támogatott archívumformátum: %1 " +#~ "%2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "Nem sikerült megnyitni a csomagfájlt: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "Nincs metaadat fájl a csomagban: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "A csomag bővítményneve nincs megadva: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "A csomag bővítményneve (%1) érvénytelen karaktereket tartalmaz" + +#~ msgid "%1 already exists" +#~ msgstr "%1 már létezik" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Nem sikerült áthelyezni a csomagot a célra: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Nem sikerült átmásolni a csomagot a célra: %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Nem sikerült helyi szolgáltatásmappát létrehozni: %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "Nem sikerült regisztrálni a csomagot szolgáltatásként (ez nem " +#~ "szükségszerűen végzetes): %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 nem létezik" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Nem sikerült törölni a csomagot innen: %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "Biztosan el szeretné távolítani ezt: %1?" + +#~ msgid "Applets furniture" +#~ msgstr "Kisalkalmazások bútor" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "Felfedező felhasználói felület felületi elemek hozzáadásához" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "" +#~ "Felhasználói felület olyan nézetekhez, amelyek elhatárolásokat " +#~ "tartalmaznak" + +#~ msgid "Default layout file" +#~ msgstr "Alapértelmezett elrendezésfájl" + +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "" +#~ "Alapértelmezett bővítmények tartalmazó elemekhez, műveletekhez, stb." + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "Hibaüzenet jelenik meg, amikor egy kisalkalmazás nem tud betöltődni" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "" +#~ "Olyan QML komponens, amely egy kisalkalmazást jelenít meg felugró ablakban" + +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Egy kisalkalmazás kompakt reprezentációja összecsukott állapotban " +#~ "(például ikonként). A kisalkalmazások felülírhatják ezt a komponenst." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "QML komponens a kisalkalmazások beállító párbeszédablakához" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "QML komponens az elhatárolások beállító párbeszédablakához" + +#~ msgid "Panel configuration UI" +#~ msgstr "Panelbeállítás felhasználói felület" + +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "QML komponens alternatív kisalkalmazások választásához" + +#~ msgid "" +#~ "A UI for writing, loading and running desktop scripts in the current live " +#~ "session" +#~ msgstr "" +#~ "Felhasználói felület asztali szkriptek írásához, betöltéséhez és " +#~ "futtatásához a jelenlegi munkamenetben" diff --git a/po/ia/libplasma6.po b/po/ia/libplasma6.po new file mode 100644 index 0000000..e0d7746 --- /dev/null +++ b/po/ia/libplasma6.po @@ -0,0 +1,1072 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# SPDX-FileCopyrightText: 2014, 2016, 2017, 2019, 2020, 2021, 2022, 2023, 2024 G.Sora +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-09-02 15:54+0200\n" +"Last-Translator: giovanni \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 23.08.5\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Altere actiones" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Plica" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Expande" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Contrasigno" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Cerca…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Cerca" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Netta cerca" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Incognite" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Activa %1 Widget" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Remove %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Entra modo de modificar" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Configura %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Bloca Widgets" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Disbloca Widgets" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Exi modo de modificar" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Si crear o no un cache sur le disco per le thema." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Le maxime grandor del cache de Thema sur le disco in kilobytes. Nota que " +"iste files es files sparse, assi quw le maxime grandor pote non esser " +"utilisate. Ergo fixar un dimension plus grande sovente es assatis secur." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Monstra Alternativas..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Widget Removite" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Le widget \"%1\" ha essite removite." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Pannello removite" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Un pannello ha essit eremovite." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Scriptorio removite" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Un scriptorio ha essite removite." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Annulla" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Preferentias de widget" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Remove iste widget" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Remove iste pannello" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Remove iste activitate" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Preferentias de activitate" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Adde o Gere Widgets…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Il non pote trovar componente requirite:%1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Le elemento radice de %1 debe esser de typo ContaimentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Le elemento radice de %1 debe esser de typo PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Applet Incognite" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Iste Widget esseva scribite per unversion vetule incognoscite de Plasma e " +"non es compatibile con Plasma %1. Per favor tu continge le autor del widget " +"per un version actualisate." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 non es compatibile con Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Iste Widget esseva scribite per Plasma %1 e non es compatibile con Plasma " +"%2. Per favor tu continge le autor del widget per un version actualisate." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Iste Widget esseva scribite per Plasma %1 e non es compatibile con Plasma " +"%2. Per favor tu actualisa Plasma per usar le widget." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Desolate! Il habeva un error a cargar %1" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Error quando on carga file QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Error quando on carga Applet: pacchetto %1 non existe. " + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 Preferentias" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 Preferentias" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Pacchetto de Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Installa" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Initialization de pacchetto falleva" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "le pacchetto que tu lassava cader es invalide." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Widgets" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Adde %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Adde Icone" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Tapete de papiro" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Fixa %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Contento lassate cader" + +#~ msgid "Add Widgets..." +#~ msgstr "Adde Widgets..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Il non pote aperir le pacchetto %1 requirite pro le widget %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Compartir un widget sur le rete permitte te de acceder a iste widget ex " +#~ "un altere computator como un controlo remote." + +#~ msgid "Share this widget on the network" +#~ msgstr "Comparti iste widget sur le rete" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Permitte a omne de acceder liberemente a iste widget" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Servicio Invalide (null), il non pote exequer alcun operationes." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Le widget %1 non definiva qual ScriptEngine usar." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Miscellanea" + +#~ msgid "Main Script File" +#~ msgstr "File de script principal" + +#~ msgid "Tests" +#~ msgstr "Provas" + +#~ msgid "Images" +#~ msgstr "Images" + +#~ msgid "Themed Images" +#~ msgstr "Imagines in themas" + +#~ msgid "Configuration Definitions" +#~ msgstr "Definitiones de configuration" + +#~ msgid "User Interface" +#~ msgstr "Interfacie de usator" + +#~ msgid "Data Files" +#~ msgstr "Files de datos" + +#~ msgid "Executable Scripts" +#~ msgstr "Scripts executabile" + +#~ msgid "Screenshot" +#~ msgstr "Instantanee de schermo" + +#~ msgid "Translations" +#~ msgstr "Traductiones" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Modello de paginas de configuration UI" + +#~ msgid "Configuration XML file" +#~ msgstr "File de configuration XML" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Expanditor personalisate per applets compacte" + +#~ msgid "Images for dialogs" +#~ msgstr "Imagines per dialogos" + +#~ msgid "Generic dialog background" +#~ msgstr "Fundo de dialogo generic" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Thema pro le dialogo de clausura de session" + +#~ msgid "Wallpaper packages" +#~ msgstr "Pacchettos de tapete de papiro" + +#~ msgid "Images for widgets" +#~ msgstr "Imagines per widgets" + +#~ msgid "Background image for widgets" +#~ msgstr "Imagines de fundo pro widgets" + +#~ msgid "Analog clock face" +#~ msgstr "Facie de horologio analogic" + +#~ msgid "Background image for panels" +#~ msgstr "Imagine de fundo pro pannellos" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Fundo pro widgets de graphicos" + +#~ msgid "Background image for tooltips" +#~ msgstr "Imagine de fundo pro consilios" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Imagine opac pro dialogos" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Fundo opac de dialogo generic" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Thema opac pro le dialogo de clausura de session" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Imagines opac per widgets" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Imagine de fundo opac pro pannellos" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Imagine de fundo opac pro consilios" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "File de configuration de KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Descriptiones de servicio" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Il non pote crear un ScriptEngine %1 pro le widget %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Initialization de script falleva" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Dies feriate" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Eventos" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Agenda o De Facer" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Altere" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Mense Precedente" + +#~ msgid "Previous Year" +#~ msgstr "Anno Precedente" + +#~ msgid "Previous Decade" +#~ msgstr "Decennio previe" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Hodie" + +#~ msgid "Reset calendar to today" +#~ msgstr "Remonta calendario a hodie" + +#~ msgid "Next Month" +#~ msgstr "Mense proxime" + +#~ msgid "Next Year" +#~ msgstr "Anno proxime" + +#~ msgid "Next Decade" +#~ msgstr "Proxime decennio" + +#~ msgid "Days" +#~ msgstr "Dies" + +#~ msgid "Months" +#~ msgstr "Menses" + +#~ msgid "Years" +#~ msgstr "Annos" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "Cancella" + +#~ msgid "Run the Associated Application" +#~ msgstr "Exeque le application associate" + +#~ msgid "Open with %1" +#~ msgstr "Aperi con %1" + +#~ msgid "Accessibility" +#~ msgstr "Accessibilitate" + +#~ msgid "Application Launchers" +#~ msgstr "Lanceatores de application" + +#~ msgid "Astronomy" +#~ msgstr "Astronomia" + +#~ msgid "Date and Time" +#~ msgstr "Data e Tempore" + +#~ msgid "Development Tools" +#~ msgstr "Instrumentos de disveloppamento" + +#~ msgid "Education" +#~ msgstr "Education" + +#~ msgid "Environment and Weather" +#~ msgstr "Ambiente e Tempore" + +#~ msgid "Examples" +#~ msgstr "Exemplos" + +#~ msgid "File System" +#~ msgstr "Systema de file" + +#~ msgid "Fun and Games" +#~ msgstr "Divertimento e Jocos" + +#~ msgid "Graphics" +#~ msgstr "Graphiches" + +#~ msgid "Language" +#~ msgstr "Linguage" + +#~ msgid "Mapping" +#~ msgstr "Mappar" + +#~ msgid "Miscellaneous" +#~ msgstr "Miscellanea" + +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + +#~ msgid "Online Services" +#~ msgstr "Servicios in linea" + +#~ msgid "Productivity" +#~ msgstr "Productivitate" + +#~ msgid "System Information" +#~ msgstr "Information de Systema" + +#~ msgid "Utilities" +#~ msgstr "Utilitates" + +#~ msgid "Windows and Tasks" +#~ msgstr "Fenestras e Cargas" + +#~ msgid "Clipboard" +#~ msgstr "Area de transferentia" + +#~ msgid "Tasks" +#~ msgstr "Cargas" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Edita %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Preferentias predefinite pro thema, etc." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Schema de color de usar per applicationes." + +#~ msgid "Preview Images" +#~ msgstr "Imagines de vista preliminar" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Vista preliminar per le Gerente de Accesso" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Vista preliminar per le schermo de bloco" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Vista preliminar per le commutator de usator" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Vista preliminar per le commutator de scriptorio virtual" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Vista preliminar per le schermo de Splash" + +#~ msgid "Preview for KRunner" +#~ msgstr "Vista preliminar per KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Vista preliminar per le decorationes de fenestra" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Vista preliminar per le commutator de fenestra" + +#~ msgid "Login Manager" +#~ msgstr "Gerente de Accesso" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Script principal per Gertente de Accesso" + +#~ msgid "Logout Dialog" +#~ msgstr "Dialogo de abandono (logout)" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Script principal per le dialogo de abandono (logout)" + +#~ msgid "Screenlocker" +#~ msgstr "Blocator de schermo" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Script principal per schermo de bloco" + +#~ msgid "UI for fast user switching" +#~ msgstr "UI per commutation rapide de usator" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Script principal per commutator de usator" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Commutator de scriptorio virtual" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Script principal per le commutator de scriptorio virtual" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Notificationes de monstrator sur schermo" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Script principal per Notificationes de monstrator sur schermo" + +#~ msgid "Splash Screen" +#~ msgstr "Schermo de Splash" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Script principal per schermo de splash" + +#~ msgid "KRunner UI" +#~ msgstr "UI de KRunner" + +#~ msgid "Main Script KRunner" +#~ msgstr "Script principal de KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Decoration de fenestra" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Script principal per decoration de fenestra" + +#~ msgid "Window Switcher" +#~ msgstr "Commutator de fenestra" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Script principal per commutator de fenestra" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Termina Personalisar le disposition" + +#~ msgid "Customize Layout..." +#~ msgstr "Personaliza disposition ..." + +#~ msgid "Fetching file type..." +#~ msgstr "Reportar typo de file..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1 Optiones" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Remove iste %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "%1 Preferentias" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "%1 Preferentias..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Imagines de color clar per dialogos" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Fundo de dialogo generic de color clar" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Thema de color clar pro le dialogo de clausura de session" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Imagines de fundo de color clar pro widgets" + +#~ msgid "Low color analog clock face" +#~ msgstr "Facie de horologio analogic de color clar" + +#~ msgid "Low color background image for panels" +#~ msgstr "Imagine de fundo de color clar pro pannellos" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Fundo de color clar pro widgets de graphicos" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Imagine de fundo de color clar pro consilios" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Gerente de Pacchettos de Plasma" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Genera un hash SHA1 per le pacchetto a " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Pro installar o remover, il opera sur pacchettos installate pro omne " +#~ "usatores." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Le typo de pacchetto, pro ex. thema, tapete de papiro, plasmoid, " +#~ "dataengine, runner, patrono de disposition, etc." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Installa le pacchetto a " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Monstra information de pacchetto " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Actualisa le pacchetto a " + +#~ msgid "List installed packages" +#~ msgstr "Lista pacchettos installate" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "" +#~ "Il lista omne cognoscite typos de pacchettos que pote esser installate" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Remove le pacchetto appellate " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Percurso absolute al radice de pacchetto. Si il non es fornite, in vice " +#~ "essera cercate le directorios standard de datos pro iste session de KDE." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Il falleva a generar un pacchetto hash per %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "Hash SHA1 per pacchetto a %1: '%2'" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "Tapete de papiro" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "package" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "Thema" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "dataengine (motor de datos)" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "runner (cursor)" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "wallpaperplugin" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "lookandfeel" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "Shell" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "patrono de disposition (layout-template)" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "kwineffect" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "commutator de fenestra" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "script de kwin" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "" +#~ "Il non pote trovar un convenibile installator pro pacchettos de typo %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "Listante typos de servicio: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Error: Plugin %1 non es installate." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Il es requirite un de installar, remover, actualisar o listar." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Error: non pote trovar metadata de plugin: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Monstrante information pro pacchetto: %1" + +#~ msgid " Name : %1" +#~ msgstr " Nomine : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Commento : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Plugin %1" + +#~ msgid " Author : %1" +#~ msgstr " Autor : %1" + +#~ msgid " Path : %1" +#~ msgstr " Percurso: %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Le radice de pacchetto e le optiones global conflige, pro favor tu selige " +#~ "solmente uno." + +#~ msgid "Addon Name" +#~ msgstr "Nomine de adder" + +#~ msgid "Service Type" +#~ msgstr "Typo de servicio" + +#~ msgid "Path" +#~ msgstr "Percurso" + +#~ msgid "Type Argument" +#~ msgstr "Argumento de typo" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Typos de pacchettos que es installable con iste instrumento:" + +#~ msgid "Built in:" +#~ msgstr "Includite:" + +#~ msgid "DataEngine" +#~ msgstr "DataEngine (motor de datos)" + +#~ msgid "Layout Template" +#~ msgstr "Patrono de disposition (layout-template)" + +#~ msgid "Look and Feel" +#~ msgstr "Semblantia" + +#~ msgid "Package" +#~ msgstr "Pacchetto" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoid" + +#~ msgid "Runner" +#~ msgstr "Runnex (Executor)" + +#~ msgid "Shell" +#~ msgstr "Shell" + +#~ msgid "Theme" +#~ msgstr "Thema" + +#~ msgid "Wallpaper Images" +#~ msgstr "Images de tapete de papiro" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Tapete de papiro animate" + +#~ msgid "KWin Effect" +#~ msgstr "Effecto de KWin" + +#~ msgid "KWin Window Switcher" +#~ msgstr "Commutator de fenestra de KWin" + +#~ msgid "KWin Script" +#~ msgstr "Script de KWin" + +#~ msgid "Provided by plugins:" +#~ msgstr "Fornite per plugins:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Fornite per files .desktop:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "Actualisate con successo %1" + +#~ msgid "Successfully installed %1" +#~ msgstr "Installate con successo %1" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Error: installation de %1 falleva: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Actualisante pacchetto ex file: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Deinstallate con successo %1" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Error: deinstallation de %1 falleva: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Il non pote cargar installator pro pacchetto de typo %1. Le error " +#~ "reportate esseva: %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Non pote crear directorio radice de pacchetto: %1" + +#~ msgid "No such file: %1" +#~ msgstr "Necun file como %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "" +#~ "Non pote aperir file de pacchetto, formato de archivo non supportate: %1 " +#~ "%2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "Non pote aperir file de pacchetto: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "Necun file de metadata in pacchetto: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "Nomine de plugin de pacchetto non specificate: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "Nomine de plugin %1 contine charracteres invalide" + +#~ msgid "%1 already exists" +#~ msgstr "%1 jam existe." + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Non pote mover pacchetto a destination: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Non pote copiar pacchetto a destination: %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Non pote crear directorio de servicio local: %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "Non pote registrar pacchetto como servicio (isto non necessariemente es " +#~ "fatal): %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 non existe" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Non pot edeler pacchetto ex: %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "Tu realmente vole remover iste %1?" + +#~ msgid "Applets furniture" +#~ msgstr "Accessorio de applets" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "UI de Explorer (explorator) pro adder widgets" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "" +#~ "Interfacie de usator pro vista que montrara containments (contentos)" + +#~ msgid "Default layout file" +#~ msgstr "File de disposition (layout) predefinite" + +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "Plugins predefinite per containments, containmentActions, etc." + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "Message de error monstrate quando un applets falle cargar se" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "Componente d eQML que monstra un applet in un popup" + +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Representation compacte de un applet quando il plica in un popup, pro " +#~ "exemplo como un icone. Applets pote ultrapassar iste componente." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "Componente QML per le dialogo de configuration pro applets" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "Componente QML per le dialogo de configuration per containments" + +#~ msgid "Panel configuration UI" +#~ msgstr "UI de configuration de pannello" + +#, fuzzy +#~| msgid "QML component for the configuration dialog for applets" +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "Componente QML per le dialogo de configuration pro applets" + +#~ msgid "Ok" +#~ msgstr "OK" diff --git a/po/id/libplasma6.po b/po/id/libplasma6.po new file mode 100644 index 0000000..25d3a54 --- /dev/null +++ b/po/id/libplasma6.po @@ -0,0 +1,702 @@ +# Indonesian translations for plasmapkg package. +# Copyright (C) 2010 This_file_is_part_of_KDE +# This file is distributed under the same license as the plasmapkg package. +# Andhika Padmawan , 2010-2014. +# Wantoyo , 2017, 2018, 2019, 2021, 2022. +# Linerly , 2022. +# Aziz Adam Adrian <4.adam.adrian@gmail.com>, 2022. +# +msgid "" +msgstr "" +"Project-Id-Version: plasmapkg\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2022-06-14 10:56+0700\n" +"Last-Translator: Aziz Adam Adrian <4.adam.adrian@gmail.com>\n" +"Language-Team: Indonesian \n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 22.04.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Aksi selebihnya" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Sandi" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Cari…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Cari" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Tidak diketahui" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Aktifkan Widget %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Hapus %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Masuki Mode Edit" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Konfigurasikan %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Kunci Widget" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Buka Kunci Widget" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Keluarkan Mode Edit" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "" +"Apakah iya atau tidak untuk menciptakan sebuah cache on-disk untuk tema." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Ukuran maksimum cache Tema yang ada di disk dalam kilobita. Perhatikan bahwa " +"file ini adalah file yang jarang, jadi ukuran maksimal mungkin tidak " +"digunakan. Dengan ukuran yang lebih besar maka biasanya cukup aman." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Tampilkan Alternatifnya..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Widget Dihapus" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Widget \"%1\" telah dihapus." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panel Dihapus" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Sebuah panel telah dihapus." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Desktop Dihapus" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Sebuah desktop telah dihapus." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Urung" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Pengaturan Widget" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Hapus Widget ini" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Hapus panel ini" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Hapus Activity ini" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Pengaturan Activity" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Tidak dapat menemukan komponen yang diminta: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Applet tak diketahui" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Galat pemuatan file QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package inexistent. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Error Memuat Applet: tak beradanya paket. %1" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "Pengaturan %1" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Pengaturan %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Paket Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Instal" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Gagal Penginstalan Paket" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Paket yang baru saja Anda taruh adalah tidak absah." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Widgets" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Tambah %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Tambahkan Ikon" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Wallpaper" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Set %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Isi yang ditaruh" + +#~ msgid "Add Widgets..." +#~ msgstr "Tambah Widget..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Tidak dapat membuka paket %1 yang diperlukan terhadap widget %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Berbagi widget di jaringan memperkenankanmu mengakses widget ini dari " +#~ "komputer lainnya sebagai kendali jarak jauh." + +#~ msgid "Share this widget on the network" +#~ msgstr "Bagikan widget ini pada jaringan" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Perkenankan siapa saja untuk akses secara bebas widget ini" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Layanan (null) tidak absah, tidak bisa melakukan operasi apa pun." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Widget %1 tidak mendefinisikan ScriptEngine mana yang digunakan." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Beraneka" + +#~ msgid "Main Script File" +#~ msgstr "File Skrip Utama" + +#~ msgid "Tests" +#~ msgstr "Ujian" + +#~ msgid "Images" +#~ msgstr "Citra" + +#~ msgid "Themed Images" +#~ msgstr "Citra Bertema" + +#~ msgid "Configuration Definitions" +#~ msgstr "Konfigurasi Definisi" + +#~ msgid "User Interface" +#~ msgstr "Antarmuka Pengguna" + +#~ msgid "Data Files" +#~ msgstr "File Data" + +#~ msgid "Executable Scripts" +#~ msgstr "Skrip Dapat Dieksekusi" + +#~ msgid "Screenshot" +#~ msgstr "Screenshot" + +#~ msgid "Translations" +#~ msgstr "Terjemahan" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Konfigurasi model halaman UI" + +#~ msgid "Configuration XML file" +#~ msgstr "Konfigurasi file XML" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Pembentang kustom untuk applet tersusun rapat" + +#~ msgid "Images for dialogs" +#~ msgstr "Citra untuk dialog" + +#~ msgid "Generic dialog background" +#~ msgstr "Latarbelakang dialog generik" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Tema untuk dialog logout" + +#~ msgid "Wallpaper packages" +#~ msgstr "Paket-paket wallpaper" + +#~ msgid "Images for widgets" +#~ msgstr "Citra untuk widget" + +#~ msgid "Background image for widgets" +#~ msgstr "Citra latarbelakang untuk widget" + +#~ msgid "Analog clock face" +#~ msgstr "Muka jam analog" + +#~ msgid "Background image for panels" +#~ msgstr "Citra latarbelakang untuk panel" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Latarbelakang untuk menggrafik widget" + +#~ msgid "Background image for tooltips" +#~ msgstr "Citra latarbelakang untuk tip alat" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Citra kekusaman untuk dialog" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Latarbelakang dialog generik kekusaman" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Tema kekusaman untuk dialog logout" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Citra kekusaman untuk widget" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Citra latarbelakang kekusaman untuk panel" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Citra latarbelakang kekusaman untuk tip alat" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "File konfigurasi KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Deskripsi Layanan" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Tidak dapat menciptakan sebuah ScriptEngine %1 terhadap widget %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Gagal pemasangan skrip" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Hari Raya" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Peristiwa" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Kegiatan" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Lainnya" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Bulan Kemarin" + +#~ msgid "Previous Year" +#~ msgstr "Tahun Kemarin" + +#~ msgid "Previous Decade" +#~ msgstr "Dasawarsa Kemarin" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Hari Ini" + +#~ msgid "Reset calendar to today" +#~ msgstr "Set ulang kalender ke hari ini" + +#~ msgid "Next Month" +#~ msgstr "Bulan Depan" + +#~ msgid "Next Year" +#~ msgstr "Tahun Depan" + +#~ msgid "Next Decade" +#~ msgstr "Dasawarsa Depan" + +#~ msgid "Days" +#~ msgstr "Hari" + +#~ msgid "Months" +#~ msgstr "Bulan" + +#~ msgid "Years" +#~ msgstr "Tahun" + +#~ msgid "OK" +#~ msgstr "Oke" + +#~ msgid "Cancel" +#~ msgstr "Batal" + +#~ msgid "Run the Associated Application" +#~ msgstr "Jalankan Aplikasi Yang Berhubungan" + +#~ msgid "Open with %1" +#~ msgstr "Buka dengan %1" + +#~ msgid "Accessibility" +#~ msgstr "Aksesibilitas" + +#~ msgid "Application Launchers" +#~ msgstr "Peluncur Aplikasi" + +#~ msgid "Astronomy" +#~ msgstr "Ilmu Perbintangan" + +#~ msgid "Date and Time" +#~ msgstr "Tanggal dan Waktu" + +#~ msgid "Development Tools" +#~ msgstr "Peralatan Pengembangan" + +#~ msgid "Education" +#~ msgstr "Edukasi" + +#~ msgid "Environment and Weather" +#~ msgstr "Environment dan Cuaca" + +#~ msgid "Examples" +#~ msgstr "Contoh" + +#~ msgid "File System" +#~ msgstr "Sistem File" + +#~ msgid "Fun and Games" +#~ msgstr "Hiburan dan Permainan" + +#~ msgid "Graphics" +#~ msgstr "Grafik" + +#~ msgid "Language" +#~ msgstr "Bahasa" + +#~ msgid "Mapping" +#~ msgstr "Pemetaan" + +#~ msgid "Miscellaneous" +#~ msgstr "Beraneka" + +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + +#~ msgid "Online Services" +#~ msgstr "Layanan Online" + +#~ msgid "Productivity" +#~ msgstr "Produktifitas" + +#~ msgid "System Information" +#~ msgstr "Informasi Sistem" + +#~ msgid "Utilities" +#~ msgstr "Utilitas" + +#~ msgid "Windows and Tasks" +#~ msgstr "Window dan Tugas" + +#~ msgid "Clipboard" +#~ msgstr "Papan-klip" + +#~ msgid "Tasks" +#~ msgstr "Tugas" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Edit %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Pengesetan baku untuk tema, dll." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Skema warna untuk digunakan terhadap aplikasi." + +#~ msgid "Preview Images" +#~ msgstr "Citra Pratinjau" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Pratinjau untuk Pengelola Login" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Pratinjau untuk Layar Kunci " + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Pratinjau untuk Pengalih Pengguna" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Pratinjau untuk Pengalih Desktop Virtual" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Pratinjau untuk Layar Splash" + +#~ msgid "Preview for KRunner" +#~ msgstr "Pratinjau untuk KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Pratinjau untuk Dekorasi Window" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Pratinjau untuk Pengalih Window" + +#~ msgid "Login Manager" +#~ msgstr "Pengelola Login" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Skrip Utama untuk Pengelola Login" + +#~ msgid "Logout Dialog" +#~ msgstr "Dialog Logout" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Skrip Utama untuk Dialog Logout" + +#~ msgid "Screenlocker" +#~ msgstr "Screenlocker" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Skrip Utama untuk Layar Kunci " + +#~ msgid "UI for fast user switching" +#~ msgstr "UI untuk mempercepat peralihan pengguna" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Skrip Utama untuk Pengalih Pengguna" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Pengalih Desktop Virtual" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Skrip Utama untuk Pengalih Desktop Virtual" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "OSD Notifikasi" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Skrip Utama untuk OSD Notifikasi" + +#~ msgid "Splash Screen" +#~ msgstr "Layar Splash" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Skrip Utama untuk Layar Splash" + +#~ msgid "KRunner UI" +#~ msgstr "UI KRunner" + +#~ msgid "Main Script KRunner" +#~ msgstr "Skrip Utama KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Dekorasi Window" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Skrip Utama untuk Dekorasi Window" + +#~ msgid "Window Switcher" +#~ msgstr "Pengalih Window" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Skrip Utama untuk Pengalih Window" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Selesai Mengkutomisasi Tataletak" + +#~ msgid "Customize Layout..." +#~ msgstr "Kustomisasikan Tataletak..." + +#~ msgid "Fetching file type..." +#~ msgstr "Penarikan tipe file ..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Opsi %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Setelan %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Setelan %1..." diff --git a/po/is/libplasma6.po b/po/is/libplasma6.po new file mode 100644 index 0000000..250d9f0 --- /dev/null +++ b/po/is/libplasma6.po @@ -0,0 +1,344 @@ +# Copyright (C) 2024 This file is copyright: +# This file is distributed under the same license as the libplasma package. +# +# SPDX-FileCopyrightText: 2024 Guðmundur Erlingsson +msgid "" +msgstr "" +"Project-Id-Version: libplasma\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-03-18 15:34+0000\n" +"Last-Translator: Guðmundur Erlingsson \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 23.08.3\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Fleiri aðgerðir" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Fella saman" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Víkka út" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Lykilorð" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Leita…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Leita" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Hreinsa leit" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Óþekkt" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Virkja %1 græju" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Fjarlægja %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Opna breytiham" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Grunnstilla %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Læsa græjum" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Aflæsa græjum" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Loka breytiham" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Hvort það eigi að útbúa biðminni á diski fyrir þemað eða ekki." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Hámarksstærð biðminnis á diski fyrir þema í kílóbætum. Athugaðu að þessar " +"skrár eru strjálar og ná því líklega sjaldan hámarksstærðinni. Það er því " +"oftast öruggt að velja stærri stærð." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Sýna aðra valkosti…" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Græja fjarlægð" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Græjan \"%1\" var fjarlægð." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Skjáborðsstika fjarlægð" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Skjáborðsstikan var fjarlægð." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Skjáborð fjarlægt" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Skjáborð var fjarlægt." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Afturkalla" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Græjustillingar" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Fjarlægja þessa græju" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Fjarlægja þessa skjáborðsstiku" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Fjarlægja þessa athöfn" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Athafnastillingar" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Fann ekki umbeðna einingu: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Rótaratriðið %1 verður að vera af gerðinni ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Rótaratriðið %1 verður að vera af gerðinni PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Óþekkt smáforrit" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Þessi græja var gerð fyrir óþekkta eldri útgáfu af Plasma og virkar ekki í " +"Plasma %1. Hafðu samband við höfund græjunnar til að fá uppfærða útgáfu." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 er ekki samhæfð við Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Þessi græja var gerð fyrir %1 og virkar ekki í %2. Hafðu samband við höfund " +"græjunnar til að fá uppfærða útgáfu." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Þessi græja var gerð fyrir Plasma %1 og virkar ekki í Plasma %2. Uppfærðu " +"Plasma til að geta notað græjuna." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Því miður kom upp villa við að hlaða inn %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Villa við að hlaða inn QML-skrá: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package does not exist. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Villa við að hlaða inn smáforriti: pakki er ekki til. %1" + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 stillingar" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 stillingar" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma-pakki" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Setja upp" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Uppsetning á pakka mistókst" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Pakkinn sem þú slepptir er ógildur." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Græjur" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Bæta við %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Bæta við tákni" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Veggfóður" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Velja %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Innihaldi sleppt" + +#~ msgid "Add Widgets..." +#~ msgstr "Bæta við græju..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Gat ekki opnað pakkann %1 sem er nauðsynlegur fyrir %2 græjuna." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Ef græja er samnýtt á netinu getur þú fengið aðgang að þessari græju úr " +#~ "annarri tölvu sem fjarstýringu." + +#~ msgid "Share this widget on the network" +#~ msgstr "Samnýta þessa græju á netinu" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Leyfa öllum að fá aðgang að þessari græju" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Ógild (null) þjónusta, get ekki framkvæmt neinar aðgerðir." diff --git a/po/it/libplasma6.po b/po/it/libplasma6.po new file mode 100644 index 0000000..17537e8 --- /dev/null +++ b/po/it/libplasma6.po @@ -0,0 +1,1430 @@ +# translation of plasmapkg.po to Italian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Federico Zenith , 2008. +# Federico Zenith , 2008, 2009, 2010, 2011, 2012. +# SPDX-FileCopyrightText: 2014, 2015, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Vincenzo Reale +# +msgid "" +msgstr "" +"Project-Id-Version: plasmapkg\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-24 10:45+0200\n" +"Last-Translator: Vincenzo Reale \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 24.05.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Altre azioni" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Contrai" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Espandi" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Password" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Cerca…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Cerca" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Cancella la ricerca" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Sconosciuto" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Attiva oggetto %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Rimuovi %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Entra in modalità di modifica" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Configura %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Blocca oggetti" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Sblocca oggetti" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Esci dalla modalità di modifica" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Se creare o meno una cache su disco per il tema" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"La dimensione massima della cache su disco del tema in kilobyte. Nota che " +"questi file sono file sparsi, perciò la dimensione massima potrebbe non " +"essere utilizzata. L'impostazione di una dimensione maggiore è sicura nella " +"maggior parte dei casi." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Mostra alternative..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Oggetto rimosso" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "L'oggetto «%1» è stato rimosso." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Pannello rimosso" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Un pannello è stato rimosso." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Desktop rimosso" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Un desktop è stato rimosso." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Annulla" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Impostazioni degli oggetti" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Rimuovi questo oggetto" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Rimuovi questo pannello" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Rimuovi questa attività" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Impostazioni delle attività" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Aggiungi o gestisci oggetti..." + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Impossibile trovare il componente richiesto: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "L'elemento radice di %1 deve essere di tipo ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "L'elemento radice di %1 deve essere di tipo PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Applet sconosciuta" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Questo oggetto è stato scritto per una versione precedente sconosciuta di " +"Plasma e non è compatibile con Plasma %1. Contatta l'autore dell'oggetto per " +"una versione aggiornata." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 non è compatibile con Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Questo oggetto è stato scritto per Plasma %1 e non è compatibile con Plasma " +"%2.Contatta l'autore dell'oggetto per una versione aggiornata." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Questo oggetto è stato scritto per Plasma %1 e non è compatibile con Plasma " +"%2. Aggiorna Plasma per poter utilizzare l'oggetto." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Spiacenti! Si è verificato un errore durante il caricamento di %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Errore durante il caricamento del file QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Errore durante il caricamento dell'applet: il pacchetto %1 non esiste." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — Impostazioni di %2" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Impostazioni di %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Pacchetto di Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Installa" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Installazione pacchetto non riuscita" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Il pacchetto appena rilasciato non è valido." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Oggetti" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Aggiungi %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Aggiungi icona" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Sfondo" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Imposta %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Contenuto scartato" + +#~ msgid "Add Widgets..." +#~ msgstr "Aggiungi oggetti..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Non riesco ad aprire il pacchetto %1 richiesto dall'oggetto %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Condividere un oggetto sulla rete ti permette di accedere a questo " +#~ "oggetto da un altro computer come un telecomando." + +#~ msgid "Share this widget on the network" +#~ msgstr "Condividi questo oggetto nella rete" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Permetti a tutti di accedere liberamente a questo oggetto" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "" +#~ "Servizio non valido (assente), non è possibile eseguire alcuna operazione." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "L'oggetto %1 non specifica quale motore di script utilizzare." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Varie" + +#~ msgid "Main Script File" +#~ msgstr "File di script principale" + +#~ msgid "Tests" +#~ msgstr "Test" + +#~ msgid "Images" +#~ msgstr "Immagini" + +#~ msgid "Themed Images" +#~ msgstr "Immagini a tema" + +#~ msgid "Configuration Definitions" +#~ msgstr "Definizioni della configurazione" + +#~ msgid "User Interface" +#~ msgstr "Interfaccia utente" + +#~ msgid "Data Files" +#~ msgstr "File di dati" + +#~ msgid "Executable Scripts" +#~ msgstr "Script eseguibili" + +#~ msgid "Screenshot" +#~ msgstr "Schermata" + +#~ msgid "Translations" +#~ msgstr "Traduzioni" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Modello delle pagine dell'interfaccia di configurazione" + +#~ msgid "Configuration XML file" +#~ msgstr "File XML di configurazione" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Estensore personalizzato per le applet compatte" + +#~ msgid "Images for dialogs" +#~ msgstr "Immagini per le finestre di dialogo" + +#~ msgid "Generic dialog background" +#~ msgstr "Sfondo finestra di dialogo generica" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Tema per la finestra di dialogo di uscita" + +#~ msgid "Wallpaper packages" +#~ msgstr "Pacchetti di sfondi" + +#~ msgid "Images for widgets" +#~ msgstr "Immagini per gli oggetti" + +#~ msgid "Background image for widgets" +#~ msgstr "Immagine di sfondo per gli oggetti" + +#~ msgid "Analog clock face" +#~ msgstr "Aspetto orologio analogico" + +#~ msgid "Background image for panels" +#~ msgstr "Immagine di sfondo per i pannelli" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Sfondo per elementi grafici" + +#~ msgid "Background image for tooltips" +#~ msgstr "Immagine di sfondo per i suggerimenti" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Immagini opache per finestre di dialogo" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Sfondo finestra di dialogo generica opaco" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Tema opaco per la finestra di dialogo di uscita" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Immagini opache per gli oggetti" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Immagine di sfondo opaca per i pannelli" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Immagine di sfondo opaca per i suggerimenti" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "File di configurazione di KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Descrizioni del servizio" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Non riesco a creare il motore di script %1 per l'oggetto %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Inizializzazione script non riuscita" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Festività" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Eventi" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Da fare" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Altro" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Mese precedente" + +#~ msgid "Previous Year" +#~ msgstr "Anno precedente" + +#~ msgid "Previous Decade" +#~ msgstr "Decennio precedente" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Oggi" + +#~ msgid "Reset calendar to today" +#~ msgstr "Ripristina il calendario a oggi" + +#~ msgid "Next Month" +#~ msgstr "Mese successivo" + +#~ msgid "Next Year" +#~ msgstr "Anno successivo" + +#~ msgid "Next Decade" +#~ msgstr "Decennio successivo" + +#~ msgid "Days" +#~ msgstr "Giorni" + +#~ msgid "Months" +#~ msgstr "Mesi" + +#~ msgid "Years" +#~ msgstr "Anni" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "Annulla" + +#~ msgid "Run the Associated Application" +#~ msgstr "Esegui l'applicazione associata" + +#~ msgid "Open with %1" +#~ msgstr "Apri con %1" + +#~ msgid "Accessibility" +#~ msgstr "Accessibilità" + +#~ msgid "Application Launchers" +#~ msgstr "Menu per il lancio delle applicazioni" + +#~ msgid "Astronomy" +#~ msgstr "Astronomia" + +#~ msgid "Date and Time" +#~ msgstr "Data e orario" + +#~ msgid "Development Tools" +#~ msgstr "Strumenti di sviluppo" + +#~ msgid "Education" +#~ msgstr "Didattica" + +#~ msgid "Environment and Weather" +#~ msgstr "Ambiente e meteo" + +#~ msgid "Examples" +#~ msgstr "Esempi" + +#~ msgid "File System" +#~ msgstr "Filesystem" + +#~ msgid "Fun and Games" +#~ msgstr "Divertimento e giochi" + +#~ msgid "Graphics" +#~ msgstr "Grafica" + +#~ msgid "Language" +#~ msgstr "Lingua" + +#~ msgid "Mapping" +#~ msgstr "Mappe" + +#~ msgid "Miscellaneous" +#~ msgstr "Varie" + +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + +#~ msgid "Online Services" +#~ msgstr "Servizi in rete" + +#~ msgid "Productivity" +#~ msgstr "Produttività" + +#~ msgid "System Information" +#~ msgstr "Informazioni sul sistema" + +#~ msgid "Utilities" +#~ msgstr "Accessori" + +#~ msgid "Windows and Tasks" +#~ msgstr "Finestre e attività" + +#~ msgid "Clipboard" +#~ msgstr "Appunti" + +#~ msgid "Tasks" +#~ msgstr "Attività" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Modifica %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Impostazioni predefinite per il tema, ecc." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Schema di colore da utilizzare per le applicazioni." + +#~ msgid "Preview Images" +#~ msgstr "Anteprima immagini" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Anteprima per il gestore degli accessi" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Anteprima per blocca schermo" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Anteprima per scambia utenti" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Anteprima per scambia desktop virtuali" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Anteprima per la schermata d'avvio" + +#~ msgid "Preview for KRunner" +#~ msgstr "Anteprima per KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Anteprima per decorazioni delle finestre" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Anteprima per scambia finestre" + +#~ msgid "Login Manager" +#~ msgstr "Gestore degli accessi" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Script principale per il gestore degli accessi" + +#~ msgid "Logout Dialog" +#~ msgstr "Finestra di dialogo di uscita" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Script principale per la finestra di dialogo uscita" + +#~ msgid "Screenlocker" +#~ msgstr "Blocca schermo" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Script principale per blocca schermo" + +#~ msgid "UI for fast user switching" +#~ msgstr "Interfaccia per il cambio rapido dell'utente" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Script principale per scambia utenti" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Scambia desktop virtuali" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Script principale per scambia desktop virtuali" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Notifiche OSD" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Script principale per le notifiche OSD" + +#~ msgid "Splash Screen" +#~ msgstr "Schermata d'avvio" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Script principale per la schermata d'avvio" + +#~ msgid "KRunner UI" +#~ msgstr "Interfaccia di KRunner" + +#~ msgid "Main Script KRunner" +#~ msgstr "Script principale di KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Decorazione delle finestre" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Script principale per decorazioni delle finestre" + +#~ msgid "Window Switcher" +#~ msgstr "Scambia finestre" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Script principale per scambia finestre" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Termina la personalizzazione della disposizione" + +#~ msgid "Customize Layout..." +#~ msgstr "Disposizione personalizzata..." + +#~ msgid "Fetching file type..." +#~ msgstr "Recupero del tipo di file in corso..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Opzioni di %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Rimuovi %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Impostazioni di %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Impostazioni di %1..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Immagini a bassa risoluzione per le finestre di dialogo" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Sfondo a bassa risoluzione finestra di dialogo generica" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Tema a bassa risoluzione per la finestra di dialogo di uscita" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Immagine di sfondo a bassa risoluzione per gli oggetti" + +#~ msgid "Low color analog clock face" +#~ msgstr "Aspetto orologio analogico a bassa risoluzione" + +#~ msgid "Low color background image for panels" +#~ msgstr "Immagine di sfondo a bassa risoluzione per i pannelli" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Sfondo a bassa risoluzione per elementi grafici" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Immagine di sfondo a bassa risoluzione per i suggerimenti" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Gestore di pacchetti di Plasma" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Genera un codice di controllo SHA1 per il pacchetto nel " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Per l'installazione o la rimozione, opera sui pacchetti installati per " +#~ "tutti gli utenti." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Il tipo di pacchetto, per esempio tema, sfondo, plasmoide, motore di " +#~ "dati, esecutore, modello di disposizione, eccetera." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Installa il pacchetto nel " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Mostra informazioni per il pacchetto " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Aggiorna il pacchetto nel " + +#~ msgid "List installed packages" +#~ msgstr "Elenca pacchetti installati" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "Elenca tutti i tipi di pacchetti noti che si possono installare" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Rimuovi il pacchetto chiamato " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Percorso assoluto alla radice dei pacchetti. Se non indicato, si cercherà " +#~ "nelle cartelle dei dati standard per questa sessione di KDE." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "" +#~ "Generazione di un codice di controllo di pacchetto non riuscita per %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "Codice di controllo SHA1 per il pacchetto a %1: «%2»" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "sfondo" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoide" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "pacchetto" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "tema" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "motore di dati" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "esecutore" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "estensione per sfondo" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "aspetto" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "shell" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "modello di disposizione" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "effetto di KWin" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "scambia finestre" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "script di KWin" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "" +#~ "Impossibile trovare un installatore adatto per il pacchetto di tipo %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "Elenco dei tipi di servizio: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Errore: l'estensione %1 non è installata." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Si richiede uno tra installa, aggiorna, rimuovi o elenca." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Errore: impossibile trovare metadati dell'estensione: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Visualizzazione informazioni per il pacchetto: %1" + +#~ msgid " Name : %1" +#~ msgstr " Nome: %1" + +#~ msgid " Comment : %1" +#~ msgstr " Commento: %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Estensione: %1" + +#~ msgid " Author : %1" +#~ msgstr " Autore: %1" + +#~ msgid " Path : %1" +#~ msgstr " Percorso: %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "La radice del pacchetto e le opzioni globali sono in conflitto, " +#~ "selezionane una sola." + +#~ msgid "Addon Name" +#~ msgstr "Nome dell'aggiunta" + +#~ msgid "Service Type" +#~ msgstr "Tipo di servizio" + +#~ msgid "Path" +#~ msgstr "Percorso" + +#~ msgid "Type Argument" +#~ msgstr "Argomento di tipo" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Tipi di pacchetti installabili con questo strumento:" + +#~ msgid "Built in:" +#~ msgstr "Integrati:" + +#~ msgid "DataEngine" +#~ msgstr "Motore di dati" + +#~ msgid "Layout Template" +#~ msgstr "Modello di disposizione" + +#~ msgid "Look and Feel" +#~ msgstr "Aspetto" + +#~ msgid "Package" +#~ msgstr "Pacchetto" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoide" + +#~ msgid "Runner" +#~ msgstr "Esecutore" + +#~ msgid "Shell" +#~ msgstr "Shell" + +#~ msgid "Theme" +#~ msgstr "Tema" + +#~ msgid "Wallpaper Images" +#~ msgstr "Immagini di sfondo" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Sfondo animato" + +#~ msgid "KWin Effect" +#~ msgstr "Effetto di KWin" + +#~ msgid "KWin Window Switcher" +#~ msgstr "Scambia finestre di KWin" + +#~ msgid "KWin Script" +#~ msgstr "Script di KWin" + +#~ msgid "Provided by plugins:" +#~ msgstr "Forniti dalle estensioni:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Forniti dai file .desktop:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "Aggiornamento di %1 riuscito." + +#~ msgid "Successfully installed %1" +#~ msgstr "Installazione di %1 riuscita." + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Errore: I'installazione di %1 non è riuscita: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Aggiornamento pacchetto da file: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Disinstallazione di %1 riuscita." + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Errore: disinstallazione di %1 non è riuscita: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Impossibile caricare l'installatore per il pacchetto di tipo %1. È stato " +#~ "segnalato l'errore: %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Impossibile creare la cartella radice del pacchetto: %1" + +#~ msgid "No such file: %1" +#~ msgstr "Nessun file: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "" +#~ "Impossibile aprire il file del pacchetto, formato di archivio non " +#~ "supportato: %1 %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "Impossibile aprire il file del pacchetto: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "Nessun file di metadati nel pacchetto: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "Nome dell'estensione del pacchetto non specificato: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "" +#~ "Il nome dell'estensione del pacchetto %1 contiene caratteri non validi" + +#~ msgid "%1 already exists" +#~ msgstr "%1 esiste già" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Impossibile spostare il pacchetto nella destinazione: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Impossibile copiare il pacchetto nella destinazione: %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Impossibile creare la cartella locale del servizio: %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "Impossibile registrare il pacchetto come servizio (non è strettamente un " +#~ "problema): %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 non esiste" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Impossibile eliminare il pacchetto da: %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "Vuoi veramente rimuovere %1?" + +#, fuzzy +#~| msgid "Default configuration" +#~ msgid "Default layout file" +#~ msgstr "Configurazione predefinita" + +#, fuzzy +#~| msgid "Default configuration" +#~ msgid "Panel configuration UI" +#~ msgstr "Configurazione predefinita" + +#, fuzzy +#~| msgid "&Ok" +#~ msgid "Ok" +#~ msgstr "&Ok" + +#~ msgid "search term" +#~ msgstr "Cerca termine" + +#~ msgid "animation() takes one argument" +#~ msgstr "animation() ha bisogno di un argomento" + +#~ msgid "%1 is not a known animation type" +#~ msgstr "%1 non è un tipo di animazione conosciuto" + +#~ msgid "Unable to load the widget" +#~ msgstr "Non è possibile caricare l'oggetto" + +#~ msgid "Panel" +#~ msgstr "Pannello" + +#~ msgid "&OK" +#~ msgstr "&OK" + +#~ msgid "&Yes" +#~ msgstr "&Sì" + +#~ msgid "&No" +#~ msgstr "&No" + +#~ msgid "&Cancel" +#~ msgstr "&Annulla" + +#~ msgid "Settings" +#~ msgstr "Impostazioni" + +#~ msgctxt "@title:window" +#~ msgid "%1 Settings" +#~ msgstr "Impostazioni di %1" + +#~ msgid "Keyboard Shortcut" +#~ msgstr "Scorciatoia da tastiera" + +#~ msgctxt "" +#~ "%1 is the name of a plasmoid, %2 the name of the machine that plasmoid is " +#~ "published on" +#~ msgid "%1 on %2" +#~ msgstr "%1 su %2" + +#~ msgid "This object could not be created." +#~ msgstr "Questo oggetto non può essere creato." + +#~ msgid "" +#~ "This object could not be created for the following reason:

%1

" +#~ msgstr "" +#~ "Questo oggetto non può essere creato per la seguente ragione:

%1

" + +#~ msgid "This plugin needs to be configured" +#~ msgstr "Questa estensione dev'essere configurata" + +#~ msgid "Unknown ContainmentActions" +#~ msgstr "ContainmentActions sconosciuto" + +#~ msgid "Shortcut Settings" +#~ msgstr "Impostazioni scorciatoie" + +#~ msgid "Unnamed" +#~ msgstr "Senza nome" + +#~ msgid "Show this group." +#~ msgstr "Mostra questo gruppo." + +#~ msgid "Hide this group." +#~ msgstr "Nascondi questo gruppo." + +#~ msgid "Expand this widget" +#~ msgstr "Espandi questo oggetto" + +#~ msgid "Collapse this widget" +#~ msgstr "Riduci questo oggetto" + +#~ msgid "Reattach" +#~ msgstr "Ancora" + +#~ msgid "Close" +#~ msgstr "Chiudi" + +#~ msgid "This system does not support OpenGL widgets." +#~ msgstr "Questo sistema non supporta gli oggetti OpenGL." + +#~ msgid "Your machine does not support OpenGL widgets." +#~ msgstr "La tua macchina non supporta gli oggetti OpenGL." + +#~ msgctxt "A non-functional package" +#~ msgid "Invalid" +#~ msgstr "Non valido" + +#~ msgid "" +#~ "There was an error attempting to exec the associated application with " +#~ "this widget." +#~ msgstr "" +#~ "C'è stato un errore durante il tentativo di eseguire l'applicazione " +#~ "associata con questo oggetto." + +#~ msgctxt "Error message, access to a remote service failed." +#~ msgid "Invalid token." +#~ msgstr "Token non valido." + +#~ msgctxt "Error message, access to a remote service failed." +#~ msgid "Matching password required." +#~ msgstr "È necessario che le password corrispondano." + +#~ msgctxt "Error message, access to a remote service failed." +#~ msgid "Access denied." +#~ msgstr "Accesso negato." + +#~ msgid "Unknown error." +#~ msgstr "Errore sconosciuto." + +#~ msgid "Main Config UI File" +#~ msgstr "File dell'interfaccia di configurazione principale" + +#~ msgid "Animation scripts" +#~ msgstr "Script di animazione" + +#~ msgid "Recommended wallpaper file" +#~ msgstr "Sfondo desktop raccomandato" + +#~ msgid "" +#~ "Enter a password below. Enter the same password on the device to which " +#~ "you are trying to connect." +#~ msgstr "" +#~ "Digita una password qua sotto. Scrivi la stessa password nel dispositivo " +#~ "che vuoi cercare di connettere." + +#~ msgid "Allow this user access to any service" +#~ msgstr "Permetti a questo utente l'accesso a qualsiasi servizio" + +#~ msgid "Remember this user" +#~ msgstr "Rimuovi questo utente" + +#~ msgid "Incoming connection request" +#~ msgstr "Richiesta di connessione in entrata" + +#~ msgid "Connect with remote widget" +#~ msgstr "Connettiti con oggetto remoto" + +#~ msgid "Job no longer valid, operation is not enabled." +#~ msgstr "Lavoro non più valido, l'operazione non è attivata." + +#~ msgid "Job no longer valid, invalid parameters." +#~ msgstr "Lavoro non più valido, parametri non validi." + +#~ msgid "Timeout." +#~ msgstr "Tempo scaduto." + +#~ msgid "Server sent an invalid plasmoid package." +#~ msgstr "Il server ha inviato un pacchetto plasmoide invalido." + +#~ msgid "You are about to open a remote widget on your system.
" +#~ msgstr "Stai per aprire un oggetto remoto sul tuo sistema.
" + +#~ msgid "" +#~ msgstr "
" + +#~ msgid "" +#~ msgstr "" + +#~ msgid "" +#~ "" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ "" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ msgstr "" + +#~ msgid "
Name:  %1
Nome:  %1
Description:  %1
Descrizione:  %1
Author:  %1 <%2>
Autore:  %1 <%2>
Server:  %1
Server:  %1
" +#~ msgstr "" + +#~ msgid "

Are you sure you want to open this widget on your system?" +#~ msgstr "

Sei sicuro di voler aprire questo oggetto sul tuo sistema?" + +#~ msgid "Remote Widget" +#~ msgstr "Rimuovi oggetto" + +#~ msgid "Reject Widget" +#~ msgstr "Rifiuta oggetto" + +#~ msgid "User rejected" +#~ msgstr "Rifiutato dall'utente" + +#~ msgid "Timeout" +#~ msgstr "Tempo scaduto" + +#~ msgid "" +#~ "Your system does not provide support for the 'remote widgets' feature. " +#~ "Access Failed." +#~ msgstr "" +#~ "Il tuo sistema non fornisce supporto per la funzionalità 'oggetti " +#~ "remoti'. Accesso fallito." + +#~ msgid "Allow everybody access to %1." +#~ msgstr "Permetti a tutti l'accesso a %1." + +#~ msgid "Deny everybody access to %1" +#~ msgstr "Nega a tutti l'accesso a %1" + +#~ msgid "Allow %1 access to all services." +#~ msgstr "Permetti a %1 di accedere a tutti i servizi." + +#~ msgid "Deny %1 access to all services." +#~ msgstr "Impedisci a %1 di accedere a tutti i servizi." + +#~ msgid "Allow access to %1, by %2." +#~ msgstr "Permetti accesso a %1, da %2." + +#~ msgid "Deny access to %1, by %2." +#~ msgstr "Nega accesso a %1, da %2." + +#~ msgid "Allow access to %1, by %2?" +#~ msgstr "Permetti accesso a %1, da %2?" + +#~ msgid "You have requested access to the %1 hosted at %2." +#~ msgstr "Hai richiesto l'accesso per %1 ospitato a %2." + +#~ msgid "Unknown Wallpaper" +#~ msgstr "Sfondo sconosciuto" + +#~ msgid "Share" +#~ msgstr "Condividi" + +#~ msgid "Yes" +#~ msgstr "Sì" + +#~ msgid "No" +#~ msgstr "No" + +#~ msgid "This menu needs to be configured" +#~ msgstr "Questo menu deve essere configurato" + +#~ msgid "Tool Box" +#~ msgstr "Casella degli strumenti" + +#~ msgid "" +#~ "Click to access configuration options and controls, or to add more " +#~ "widgets to the %1." +#~ msgstr "" +#~ "Fai clic per accedere alle opzioni di configurazione e ai controlli, o " +#~ "per aggiungere altri oggetti al %1." + +#~ msgid "Panel Tool Box" +#~ msgstr "Casella degli strumenti del pannello" + +#~ msgid "" +#~ "Click to access size, location and hiding controls as well as to add new " +#~ "widgets to the panel." +#~ msgstr "" +#~ "Fai clic per accedere ai controlli di dimensione, posizione e visibilità " +#~ "oppure per aggiungere nuovi oggetti al pannello." + +#~ msgid "%1 Activity" +#~ msgstr "Attività %1" + +#~ msgid "Unknown Activity" +#~ msgstr "Attività sconosciuta" + +#~ msgid "Zoom In" +#~ msgstr "Ingrandisci" + +#~ msgid "Appearance Settings" +#~ msgstr "Impostazioni dell'aspetto" + +#~ msgid "Zoom Out" +#~ msgstr "Riduci" + +#~ msgid "Background image for plasmoids" +#~ msgstr "Immagine di sfondo per gli oggetti" + +#~ msgid "Low color background image for plasmoids" +#~ msgstr "Immagine di sfondo a bassa risoluzione per gli oggetti" + +#~ msgid "All Widgets" +#~ msgstr "Tutti gli oggetti" + +#~ msgid "My Favorite Widgets" +#~ msgstr "I miei oggetti preferiti" + +#~ msgid "Widgets I Have Used Before" +#~ msgstr "Oggetti che ho usato prima" + +#~ msgid "Currently Running Widgets" +#~ msgstr "Oggetti attualmente in esecuzione" + +#~ msgid "Categories:" +#~ msgstr "Categorie:" + +#~ msgid "Add Widget" +#~ msgstr "Aggiungi oggetto" + +#~ msgid "Install New Widgets" +#~ msgstr "Installa nuovi oggetti" + +#~ msgid "Download From Internet" +#~ msgstr "Scarica da Internet" + +#~ msgid "Close the dialog" +#~ msgstr "Chiudi la finestra di dialogo" + +#~ msgid "" +#~ "When clicking Close, this dialog will be closed with no " +#~ "further action taken." +#~ msgstr "" +#~ "Quando fai clic su Chiudi, questa finestra viene chiusa senza " +#~ "possibilità di compiere ulteriori azioni." + +#~ msgid "Add selected widgets" +#~ msgstr "Aggiungi gli oggetti selezionati" + +#~ msgid "" +#~ "When clicking Add Widget, the selected widgets will be added " +#~ "to your desktop." +#~ msgstr "" +#~ "Quando fai clic su Aggiungi elemento, gli oggetti selezionati " +#~ "vengono aggiunti nel tuo desktop." + +#~ msgid "Install new widgets" +#~ msgstr "Installa nuovi oggetti" + +#~ msgid "" +#~ "Selecting Get New Widgets will show a window that allows you " +#~ "to download new widgets directly from the Internet, while Install From " +#~ "File allows you to add new widgets from files you have on disk." +#~ msgstr "" +#~ "Quando selezioni Ottieni nuovi oggetti ti appare una finestra " +#~ "che ti permette di scaricare nuovi oggetti direttamente da Internet, " +#~ "mentre Installa da File ti permette di aggiungere nuovi oggetti dai file " +#~ "che sono presenti nel disco." + +#~ msgid "Next Applet" +#~ msgstr "Prossima applet" + +#~ msgid "Null Engine" +#~ msgstr "Nessun motore" + +#~ msgctxt "EMAIL OF TRANSLATORS" +#~ msgid "Your emails" +#~ msgstr "marcello.anni@alice.it" + +#~ msgid "Enter search phrase here" +#~ msgstr "Digita la frase di ricerca qua" + +#~ msgid "Select the type of widget to install from the list below." +#~ msgstr "Seleziona il tipo di oggetto da installare dalla lista seguente." + +#~ msgid "Plasmoid: Native plasma widget" +#~ msgstr "Plasmoide: oggetto plasma nativo" + +#~ msgid "Install New Widget From File" +#~ msgstr "Installa un nuovo oggetto da file" + +#~ msgid "Select File" +#~ msgstr "Seleziona file" + +#~ msgid "Applet browser dialog" +#~ msgstr "Finestra di navigazione delle applet" + +#~ msgid "Plasma Applet Browser" +#~ msgstr "Navigatore delle applet di Plasma" + +#~ msgid "(C) 2008, Aaron Seigo" +#~ msgstr "(C) 2008, Aaron Seigo" + +#~ msgid "Aaron Seigo" +#~ msgstr "Aaron Seigo" + +#~ msgid "Original author" +#~ msgstr "Autore originale" + +#~ msgid "Back- and foregrounds for clickable icons" +#~ msgstr "Sfondo e primo piano per le icone cliccabili" diff --git a/po/ja/libplasma6.po b/po/ja/libplasma6.po new file mode 100644 index 0000000..ade279c --- /dev/null +++ b/po/ja/libplasma6.po @@ -0,0 +1,324 @@ +# Fuminobu Takeyama , 2016. +# Tomohiro Hyakutake , 2019. +# Ryuichi Yamada , 2022, 2023. +# Fumiaki Okushi , 2011, 2016, 2022. +msgid "" +msgstr "" +"Project-Id-Version: plasmapkg\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-09-11 19:39+0900\n" +"Last-Translator: UTUMI Hirosi \n" +"Language-Team: Japanese \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" +"X-Generator: Poedit 3.4.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "その他のアクション" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "折りたたむ" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "展開する" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "パスワード" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "検索..." + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "検索" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "検索をクリア" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "不明" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "%1 ウィジェットを有効化" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "%1を削除" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "編集モードに入る" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "%1を設定..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "ウィジェットをロック" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "ウィジェットのロックを解除" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "編集モードから出る" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "テーマのためにディスク上にキャッシュを作成するかどうか。" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"ディスク上のテーマキャッシュの最大サイズ (キロバイト) です。これらのファイル" +"はスパースファイルなので、設定された最大サイズが使用されない可能性があること" +"に注意してください。したがって、より大きなサイズを設定することが、多くの場合" +"安全です。" + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "代替を表示..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "ウィジェットの削除" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "\"%1\" ウィジェットが削除されました。" + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "パネルの削除" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "パネルが削除されました。" + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "デスクトップの削除" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "デスクトップが削除されました。" + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "元に戻す" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "ウィジェットの設定" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "このウィジェットを削除" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "このパネルを削除" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "このアクティビティを削除" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "アクティビティの設定" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "ウィジェットを追加または管理..." + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "要求されたコンポーネントが見つかりませんでした: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "%1 のルート項目は ContainmentItem タイプである必要があります" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "%1 のルート項目は PlasmoidItem タイプである必要があります" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "不明なアプレット" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"このウィジェットは不明な古いバージョンの Plasma 用に作成されているため、" +"Plasma %1 とは互換性がありません。アップデート版についてはウィジェットの作成" +"者に問い合わせてください。" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 は Plasma %2 と互換性がありません" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"このウィジェットは Plasma %1 用に作成されており、Plasma %2 とは互換性がありま" +"せん。アップデート版についてはウィジェットの作成者に問い合わせてください。" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"このウィジェットは Plasma %1 用に作成されているため、Plasma %2 とは互換性があ" +"りません。ウィジェットを使用するには Plasma をアップデートしてください。" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "申し訳ありません。%1 の読み込み中にエラーが発生しました。" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "QML ファイルの読み込みに失敗しました: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "" +"アプレットの読み込み中にエラーが発生しました: パッケージ %1 は存在しません。" + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 設定" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 の設定" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma パッケージ" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "インストール" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "パッケージのインストールに失敗" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "あなたがドロップしたパッケージは無効です。" + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "ウィジェット" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "%1 を追加 " + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "アイコンを追加" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "壁紙" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "%1 を設定" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "コンテンツがドロップされました" diff --git a/po/ka/libplasma6.po b/po/ka/libplasma6.po new file mode 100644 index 0000000..3c40dc0 --- /dev/null +++ b/po/ka/libplasma6.po @@ -0,0 +1,572 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the plasma-framework package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: plasma-framework\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-09-11 05:26+0200\n" +"Last-Translator: Temuri Doghonadze \n" +"Language-Team: Georgian \n" +"Language: ka\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.3.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "დამატებითი მოქმედებები" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "აკეცვა" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "გაფართოება" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "პაროლი" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "ძებნა…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "ძებნა" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "ძიების გასუფთავება" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "უცნობი" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "ვიჯეტის აქტივაცია: %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "%1-ის წაშლა" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "ჩასწორების რეჟიმი" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "%1-ის მორგება..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "ვიჯეტების დაბლოკვა" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "ვიჯეტების განბლოკვა" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "ჩასწორების რეჟიმიდან გასვლა" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "თემისთვის დისკზე მდებარე ქეშის შეიქმნება, თუ არა." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"დისკზე მდებარე თემის ქეშის მაქსიმალური ზომა, კილობაიტებში. დაიმახსოვრეთ, რომ " +"ეს ფაილები დამატებითი ფაილებია, ასე რომ მაქსიმალურ ზომას ვერ მიუთითეთ. ასე " +"რომ, უფრო მეტი ზომის მითითება ჩვეულებრივ საკმაოდ უსაფრთხოა." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "ალტერნატივების ჩვენება…" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "ვიჯეტი წაშლილია" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "ვიჯეტი \"%1\" წაიშალა." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "პანელი წაშლილია" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "პანელი წაშლილია." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "სამუშაო მაგიდა წაშლილია" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "სამუშაო მაგიდა წაშლილია." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "დაბრუნება" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "ვიჯეტის მორგება" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "ვიჯეტის წაშლა" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "პანელის წაშლა" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "აქტივობის წაშლა" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "აქტივობის მორგება" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "ვიჯეტების დამატება და მართვა…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "მოთხოვნილი კომპონენტის პოვნა ვერ მოხერხდა: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "%1-ის ძირეული ელემენტის ტიპი ContaimentItem უნდა იყოს" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "%1-ის ძირეული ელემენტის ტიპი PlasmoidItem უნდა იყოს" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "უცნობი აპლეტი" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"ვიჯეტი დაწერილია Plasma-ის უცნობი, ძველი ვერსიისთვის და Plasma %1-სთან " +"თავსებადი არაა. ვიჯეტის განახლებული ვერსიისთვის დაუკავშირდით ავტორს." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 თავსებადი არაა Plasma %2-სთან" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"ვიჯეტი დაწერილია Plasma %1-სთვს და Plasma %2-სთან თავსებადი არაა. ვიჯეტის " +"განახლებული ვერსიისთვის ავტორს დაუკავშირდით." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"ვიჯეტი დაწერილია Plasma %1-სთვის და Plasma %2-თან თავსებადი არაა. ვიჯეტის " +"გამოსაყენებლად განაახლეთ Plasma." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "%1-ის ჩატვირთვის შეცდომა." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "QML ფაილის ჩატვირთვის შეცდომა: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "აპლეტის ჩატვირთვის შეცდომა: პაკეტი %1 არ არსებობს." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 მორგება" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1-ის მორგება" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma-ის პაკეტი" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "დაყენება" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "პაკეტის დაყენების შეცდომა" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "მითითებული პაკეტი არასწორია." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "ვიჯეტები" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "%1-ის დამატება" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "ხატულის დამატება" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "ფონური სურათი" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "%1-ის დაყენება" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "შემცველობა მოცილებულია" + +#~ msgid "Add Widgets..." +#~ msgstr "ვიჯეტების დამატება..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "%2 ვიჯეტისთვის საჭირო %1 პაკეტის გახნა შეუძლებელია." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "ვიჯეტის ქსელში გაზიარება საშუალებას გაძლევთ, ეს ვიჯეტი სხვა კომპიუტერიდან " +#~ "პულტის როლში დაიმატოთ." + +#~ msgid "Share this widget on the network" +#~ msgstr "ვიჯეტის ქსელში გაზიარება" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "ვიჯეტთან წვდომის ყველასთვის მიცემა" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "არასწორ (ცარიელ) სერვისს ოპერაციების შესრულება არ შეუძლია." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "%1 ვიჯეტში ScriptEngine მითითებული არაა." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "სხვადასხვა" + +#~ msgid "Main Script File" +#~ msgstr "მთავარი სკრიპტის ფაილები" + +#~ msgid "Tests" +#~ msgstr "ტესტი" + +#~ msgid "Images" +#~ msgstr "გამოსახულებები" + +#~ msgid "Themed Images" +#~ msgstr "თემატური გამოსახულებები" + +#~ msgid "Configuration Definitions" +#~ msgstr "კონფიგურაციის აღწერები" + +#~ msgid "User Interface" +#~ msgstr "სამომხმარებლო ინტერფეისი" + +#~ msgid "Data Files" +#~ msgstr "მონაცემების ფაილები" + +#~ msgid "Executable Scripts" +#~ msgstr "შესრულებადი სკრიპტები" + +#~ msgid "Screenshot" +#~ msgstr "ეკრანის ანაბეჭდი" + +#~ msgid "Translations" +#~ msgstr "თარგმანები" + +#~ msgid "Configuration UI pages model" +#~ msgstr "კონფიგურაციის UI-ის გვერდების მოდელი" + +#~ msgid "Configuration XML file" +#~ msgstr "კონფიგურაციის XML ფაილი" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "პატარა აპლეტების გამდიდებელი" + +#~ msgid "Images for dialogs" +#~ msgstr "ფანჯრის სურათები" + +#~ msgid "Generic dialog background" +#~ msgstr "ჩვეულებრივი ფანჯრის ფონი" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "გასვლის ფანჯრის თემა" + +#~ msgid "Wallpaper packages" +#~ msgstr "ფონის სურათების პაკეტები" + +#~ msgid "Images for widgets" +#~ msgstr "გამოსახულებები ვიჯეტებისთვის" + +#~ msgid "Background image for widgets" +#~ msgstr "ფონის სურათი ვიჯეტებისთვის" + +#~ msgid "Analog clock face" +#~ msgstr "ანალოგური საათის სახე" + +#~ msgid "Background image for panels" +#~ msgstr "ფონის სურათი პანელებისთვის" + +#~ msgid "Background for graphing widgets" +#~ msgstr "ფონის სურათი ვიჯეტების დასახატად" + +#~ msgid "Background image for tooltips" +#~ msgstr "მინიშნებების ფონის სურათი" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "გაუმჭვირვალე სურათი ფანჯრებისთვის" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "გაუმჭვირვალე ჩვეულებრივი ფანჯრის ფონი" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "გაუმჭვირვალე თემა გასვლის ფანჯრისთვის" + +#~ msgid "Opaque images for widgets" +#~ msgstr "გაუმჭვირვალე სურათი ვიჯეტებისთვის" + +#~ msgid "Opaque background image for panels" +#~ msgstr "გაუმჭვირვალე ფონის სურათი პანელებისთვის" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "გაუმჭვირვალე ფონის სურათი მინიშნებებისთვის" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme -ის კონფიგურაციის ფაილი" + +#~ msgid "Service Descriptions" +#~ msgstr "სერვისების აღწერებ" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "%2 ვიჯეტისთვის %1 ScriptEngine-ის შექმნა შეუძლებელია." + +#~ msgid "Script initialization failed" +#~ msgstr "სკრიპტის ინიციალიზაციის შეცდომა" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "დასვენებები" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "მოვლენები" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "განრიგის სია" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "სხვები" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "წინა თვე" + +#~ msgid "Previous Year" +#~ msgstr "წინა წელი" + +#~ msgid "Previous Decade" +#~ msgstr "წინა ათწლეული" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "დღეს" + +#~ msgid "Reset calendar to today" +#~ msgstr "კალენდრის დღევანდელ დღეზე გადართვა" + +#~ msgid "Next Month" +#~ msgstr "ბოლო თვე" + +#~ msgid "Next Year" +#~ msgstr "გაისად" + +#~ msgid "Next Decade" +#~ msgstr "შემდეგ ათწლეულში" + +#~ msgid "Days" +#~ msgstr "დღე" + +#~ msgid "Months" +#~ msgstr "თვე" + +#~ msgid "Years" +#~ msgstr "წელი" + +#~ msgid "OK" +#~ msgstr "დიახ" + +#~ msgid "Cancel" +#~ msgstr "გაუქმენა" + +#~ msgid "Run the Associated Application" +#~ msgstr "შესაბამისი აპლიკაციის გაშვება" + +#~ msgid "Open with %1" +#~ msgstr "%1-ით გახსნა" + +#~ msgid "Accessibility" +#~ msgstr "წვდომადობა" + +#~ msgid "Astronomy" +#~ msgstr "ასტრონომია" + +#~ msgid "Date and Time" +#~ msgstr "თარიღი და დრო" + +#~ msgid "Development Tools" +#~ msgstr "პროგრამირების ხელსაწყოები" + +#~ msgid "Education" +#~ msgstr "განათლება" + +#~ msgid "Examples" +#~ msgstr "მაგალითები" + +#~ msgid "File System" +#~ msgstr "ფაილური სისტემა" + +#~ msgid "Graphics" +#~ msgstr "გრაფიკა" + +#~ msgid "Language" +#~ msgstr "ენა" + +#~ msgid "Miscellaneous" +#~ msgstr "სხვადასხვა" + +#~ msgid "Multimedia" +#~ msgstr "მულტიმედია" + +#~ msgid "Online Services" +#~ msgstr "ონლაინ სერვისები" + +#~ msgid "Productivity" +#~ msgstr "პროდუქტიულობა" + +#~ msgid "System Information" +#~ msgstr "ინფორმაცის სისტემის შესახებ" + +#~ msgid "Utilities" +#~ msgstr "ხელსაწყოები" + +#~ msgid "Windows and Tasks" +#~ msgstr "ფანჯრები და ამოცანები" + +#~ msgid "Clipboard" +#~ msgstr "გაცვლის ბაფერი" + +#~ msgid "Tasks" +#~ msgstr "ამოცანები" diff --git a/po/ko/libplasma6.po b/po/ko/libplasma6.po new file mode 100644 index 0000000..e876ae9 --- /dev/null +++ b/po/ko/libplasma6.po @@ -0,0 +1,963 @@ +# Translation of plasmapkg to Korean. +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the kdebase package. +# SPDX-FileCopyrightText: 2008, 2009, 2010, 2011, 2012, 2014, 2015, 2016, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Shinjo Park +# +msgid "" +msgstr "" +"Project-Id-Version: plasmapkg\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-20 00:30+0200\n" +"Last-Translator: Shinjo Park \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Lokalize 23.08.5\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "더 많은 동작" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "접기" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "펴기" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "암호" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "검색…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "검색" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "검색 지우기" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "알 수 없음" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "%1 위젯 활성화하기" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "%1 삭제" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "편집 모드 들어가기" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "%1 설정..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "위젯 잠금" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "위젯 잠금 풀기" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "편집 모드 끝내기" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "테마의 디스크 캐시를 생성할 수 있는지 여부입니다." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"킬로바이트 단위의 디스크 테마 캐시 최대 크기입니다. 이 파일은 스파스 파일이므" +"로 최대 크기까지 도달하지 않을 수도 있습니다. 크게 설정하여도 무방합니다." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "대체 항목 보기..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "위젯 삭제됨" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "위젯 \"%1\"이(가) 삭제되었습니다." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "패널 삭제됨" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "패널이 삭제되었습니다." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "바탕 화면 삭제됨" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "바탕 화면이 삭제되었습니다." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "실행 취소" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "위젯 설정" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "이 위젯 삭제하기" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "이 패널 삭제하기" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "이 활동 삭제하기" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "활동 설정" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "요청한 구성 요소를 찾을 수 없습니다: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "%1의 루트 항목은 ContainmentItem 형식이어야 함" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "%1의 루트 항목은 PlasmoidItem 형식이어야 함" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "알 수 없는 애플릿" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"이 위젯은 알 수 없는 과거 Plasma 버전을 위해서 작성되었으며 Plasma %1 버전과 " +"호환되지 않습니다. 위젯 개발자에게 업데이트된 버전에 대해서 문의하십시오." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1은(는) Plasma %2와(과) 호환되지 않음" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"이 위젯은 Plasma %1 버전을 위해서 작성되었으며 Plasma %2 버전과 호환되지 않습" +"니다. 위젯 개발자에게 업데이트된 버전에 대해서 문의하십시오." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"이 위젯은 Plasma %1 버전을 위해서 작성되었으며 Plasma %2 버전과 호환되지 않습" +"니다. 위젯을 사용하려면 Plasma를 업데이트하십시오." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "죄송합니다! %1을(를) 불러오는 동안 오류가 발생했습니다." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "QML 파일을 불러오는 중 오류 발생: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "애플릿을 불러오는 중 오류 발생: %1 패키지가 없음." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 설정" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 설정" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma 패키지" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "설치" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "패키지 설치 실패" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "끌어다 놓은 패키지가 잘못되었습니다." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "위젯" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "%1 추가" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "아이콘 추가" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "배경 그림" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "%1 설정" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "내용 드롭됨" + +#~ msgid "Add Widgets..." +#~ msgstr "위젯 추가..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "%2 위젯에 필요한 패키지 %1을(를) 열 수 없습니다." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "위젯을 네트워크로 공유하면 다른 컴퓨터에서 원격으로 위젯을 제어할 수 있습" +#~ "니다." + +#~ msgid "Share this widget on the network" +#~ msgstr "이 위젯을 네트워크로 공유하기" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "모든 사람이 위젯에 자유롭게 접근하도록 하기" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "잘못된(빈) 서비스, 작업을 수행할 수 없습니다." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "%1 위젯에서 사용할 스크립트 엔진을 지정하지 않았습니다." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "기타" + +#~ msgid "Main Script File" +#~ msgstr "주 스크립트 파일" + +#~ msgid "Tests" +#~ msgstr "시험" + +#~ msgid "Images" +#~ msgstr "그림" + +#~ msgid "Themed Images" +#~ msgstr "테마의 그림" + +#~ msgid "Configuration Definitions" +#~ msgstr "설정 정의" + +#~ msgid "User Interface" +#~ msgstr "사용자 인터페이스" + +#~ msgid "Data Files" +#~ msgstr "데이터 파일" + +#~ msgid "Executable Scripts" +#~ msgstr "실행 가능한 스크립트" + +#~ msgid "Screenshot" +#~ msgstr "스크린샷" + +#~ msgid "Translations" +#~ msgstr "번역" + +#~ msgid "Configuration UI pages model" +#~ msgstr "설정 UI 페이지 모델" + +#~ msgid "Configuration XML file" +#~ msgstr "설정 XML 파일" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "작은 애플릿의 사용자 정의 확장 도구" + +#~ msgid "Images for dialogs" +#~ msgstr "대화 상자의 그림" + +#~ msgid "Generic dialog background" +#~ msgstr "일반 대화 상자 배경" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "로그아웃 대화 상자의 테마" + +#~ msgid "Wallpaper packages" +#~ msgstr "배경 그림 패키지" + +#~ msgid "Images for widgets" +#~ msgstr "위젯의 그림" + +#~ msgid "Background image for widgets" +#~ msgstr "위젯 배경 그림" + +#~ msgid "Analog clock face" +#~ msgstr "아날로그 시계 그림" + +#~ msgid "Background image for panels" +#~ msgstr "패널 배경 그림" + +#~ msgid "Background for graphing widgets" +#~ msgstr "그래프를 그리는 위젯의 배경" + +#~ msgid "Background image for tooltips" +#~ msgstr "풍선 도움말 배경 그림" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "대화 상자의 불투명한 그림" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "일반 대화 상자의 불투명한 배경" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "로그아웃 대화 상자의 불투명한 테마" + +#~ msgid "Opaque images for widgets" +#~ msgstr "위젯의 불투명한 그림" + +#~ msgid "Opaque background image for panels" +#~ msgstr "패널의 불투명한 기본 배경 그림" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "풍선 도움말의 불투명한 기본 배경 그림" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme 설정 파일" + +#~ msgid "Service Descriptions" +#~ msgstr "서비스 설명" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "%2 위젯에 필요한 스크립트 엔진 %1을(를) 열 수 없습니다." + +#~ msgid "Script initialization failed" +#~ msgstr "스크립트 초기화 실패" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "공휴일" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "이벤트" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "할 일" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "기타" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%2년 %1" + +#~ msgid "Previous Month" +#~ msgstr "이전 달" + +#~ msgid "Previous Year" +#~ msgstr "이전 해" + +#~ msgid "Previous Decade" +#~ msgstr "이전 10년" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "오늘" + +#~ msgid "Reset calendar to today" +#~ msgstr "오늘로 달력 초기화" + +#~ msgid "Next Month" +#~ msgstr "다음 달" + +#~ msgid "Next Year" +#~ msgstr "다음 해" + +#~ msgid "Next Decade" +#~ msgstr "다음 10년" + +#~ msgid "Days" +#~ msgstr "날짜" + +#~ msgid "Months" +#~ msgstr "달" + +#~ msgid "Years" +#~ msgstr "연도" + +#~ msgid "OK" +#~ msgstr "확인" + +#~ msgid "Cancel" +#~ msgstr "취소" + +#~ msgid "Run the Associated Application" +#~ msgstr "연결된 프로그램을 실행합니다" + +#~ msgid "Open with %1" +#~ msgstr "%1(으)로 열기" + +#~ msgid "Accessibility" +#~ msgstr "접근성" + +#~ msgid "Application Launchers" +#~ msgstr "프로그램 실행기" + +#~ msgid "Astronomy" +#~ msgstr "천문학" + +#~ msgid "Date and Time" +#~ msgstr "날짜와 시간" + +#~ msgid "Development Tools" +#~ msgstr "개발 도구" + +#~ msgid "Education" +#~ msgstr "교육" + +#~ msgid "Environment and Weather" +#~ msgstr "환경과 날씨" + +#~ msgid "Examples" +#~ msgstr "예제" + +#~ msgid "File System" +#~ msgstr "파일 시스템" + +#~ msgid "Fun and Games" +#~ msgstr "재미와 게임" + +#~ msgid "Graphics" +#~ msgstr "그래픽" + +#~ msgid "Language" +#~ msgstr "언어" + +#~ msgid "Mapping" +#~ msgstr "지도 및 지리" + +#~ msgid "Miscellaneous" +#~ msgstr "기타" + +#~ msgid "Multimedia" +#~ msgstr "멀티미디어" + +#~ msgid "Online Services" +#~ msgstr "온라인 서비스" + +#~ msgid "Productivity" +#~ msgstr "생산성" + +#~ msgid "System Information" +#~ msgstr "시스템 정보" + +#~ msgid "Utilities" +#~ msgstr "유틸리티" + +#~ msgid "Windows and Tasks" +#~ msgstr "창과 작업" + +#~ msgid "Clipboard" +#~ msgstr "클립보드" + +#~ msgid "Tasks" +#~ msgstr "작업" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "%1 편집..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "테마 등의 기본 설정" + +#~ msgid "Color scheme to use for applications." +#~ msgstr "모든 프로그램에 사용할 색 배열입니다." + +#~ msgid "Preview Images" +#~ msgstr "미리 보기 그림" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "로그인 관리자 미리 보기" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "잠금 화면 미리 보기" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "사용자 전환기 미리 보기" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "가상 바탕 화면 전환기 미리 보기" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "시작 화면 미리 보기" + +#~ msgid "Preview for KRunner" +#~ msgstr "KRunner 미리 보기" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "창 장식 미리 보기" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "창 전환기 미리 보기" + +#~ msgid "Login Manager" +#~ msgstr "로그인 관리자" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "로그인 관리자 주 스크립트 파일" + +#~ msgid "Logout Dialog" +#~ msgstr "로그아웃 대화 상자" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "로그아웃 대화 상자 주 스크립트 파일" + +#~ msgid "Screenlocker" +#~ msgstr "화면 잠금 도구" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "잠금 화면 주 스크립트 파일" + +#~ msgid "UI for fast user switching" +#~ msgstr "빠른 사용자 전환 인터페이스" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "사용자 전환기 주 스크립트 파일" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "가상 바탕 화면 전환기" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "가상 바탕 화면 전환기 주 스크립트" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "OSD 알림" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "OSD 알림 주 스크립트" + +#~ msgid "Splash Screen" +#~ msgstr "시작 화면" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "시작 화면 주 스크립트 파일" + +#~ msgid "KRunner UI" +#~ msgstr "KRunner UI" + +#~ msgid "Main Script KRunner" +#~ msgstr "KRunner 주 스크립트 파일" + +#~ msgid "Window Decoration" +#~ msgstr "창 장식" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "창 장식 주 스크립트" + +#~ msgid "Window Switcher" +#~ msgstr "창 전환기" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "창 전환기 주 스크립트 파일" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "레이아웃 사용자 정의 끝내기" + +#~ msgid "Customize Layout..." +#~ msgstr "레이아웃 사용자 정의..." + +#~ msgid "Fetching file type..." +#~ msgstr "파일 형식 가져오는 중..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1 옵션" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "%1 설정" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "%1 설정..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "대화 상자의 색상 수가 적은 그림" + +#~ msgid "Low color generic dialog background" +#~ msgstr "일반 대화 상자의 색상 수가 적은 배경" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "로그아웃 대화 상자의 색상 수가 적은 테마" + +#~ msgid "Low color background image for widgets" +#~ msgstr "위젯의 색상 수가 적은 배경 그림" + +#~ msgid "Low color analog clock face" +#~ msgstr "아날로그 시계의 색상 수가 적은 그림" + +#~ msgid "Low color background image for panels" +#~ msgstr "패널의 색상 수가 적은 배경 그림" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "그래핑 위젯의 색상 수가 적은 배경 그림" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "풍선 도움말의 색상 수가 적은 배경 그림" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Plasma 패키지 관리자" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "에 있는 패키지의 SHA1 해시 생성하기" + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "모든 사용자의 패키지를 설치, 삭제합니다." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "테마, 배경 그림, Plasmoid, 데이터 엔진, 실행기, 레이아웃 템플릿 등의 패키" +#~ "지 종류입니다." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "패키지를 에 설치하기" + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "패키지 의 정보 보기" + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "의 패키지 업그레이드하기" + +#~ msgid "List installed packages" +#~ msgstr "설치한 패키지 목록 보이기" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "설치할 수 있는 모든 패키지 종류를 표시합니다" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr " 패키지 삭제하기" + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "패키지 루트로부터의 절대 경로입니다. 지정되지 않으면 이 KDE 세션의 표준 데" +#~ "이터 디렉터리를 찾습니다." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "%1의 패키지 해시를 생성할 수 없음" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "%1에 있는 패키지의 SHA1 해시: '%2'" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "배경 화면" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "패키지" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "테마" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "데이터 엔진" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "실행기" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "wallpaperplugin" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "모습과 느낌" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "셸" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "레이아웃 템플릿" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "kwineffect" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "windowswitcher" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "kwinscript" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "패키지 종류 %1에 대한 적절한 설치기를 찾을 수 없습니다" + +#~ msgid "Listing service types: %1" +#~ msgstr "다음 서비스 종류에 대한 목록: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "오류: 플러그인 %1이(가) 설치되지 않았습니다." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "설치, 삭제, 업그레이드, 표시 중 하나가 필요합니다." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "오류: 플러그인 메타데이터를 찾을 수 없음: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "패키지 정보 표시 중: %1" + +#~ msgid " Name : %1" +#~ msgstr " 이름: %1" + +#~ msgid " Comment : %1" +#~ msgstr " 설명: %1" + +#~ msgid " Plugin : %1" +#~ msgstr " 플러그인: %1" + +#~ msgid " Author : %1" +#~ msgstr " 작성자: %1" + +#~ msgid " Path : %1" +#~ msgstr " 경로: %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "packageroot와 global 옵션은 서로 충돌하므로 둘 중 하나만 선택하십시오." + +#~ msgid "Addon Name" +#~ msgstr "추가 기능 이름" + +#~ msgid "Service Type" +#~ msgstr "서비스 종류" + +#~ msgid "Path" +#~ msgstr "경로" + +#~ msgid "Type Argument" +#~ msgstr "인자를 입력하십시오" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "이 도구로 설치할 수 있는 패키지 종류:" + +#~ msgid "Built in:" +#~ msgstr "내장됨:" + +#~ msgid "DataEngine" +#~ msgstr "데이터 엔진" + +#~ msgid "Layout Template" +#~ msgstr "레이아웃 템플릿" + +#~ msgid "Look and Feel" +#~ msgstr "모습과 느낌" + +#~ msgid "Package" +#~ msgstr "패키지" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoid" + +#~ msgid "Runner" +#~ msgstr "실행기" + +#~ msgid "Shell" +#~ msgstr "셸" + +#~ msgid "Theme" +#~ msgstr "테마" + +#~ msgid "Wallpaper Images" +#~ msgstr "배경 그림" + +#~ msgid "Animated Wallpaper" +#~ msgstr "애니메이션 배경 그림" + +#~ msgid "KWin Effect" +#~ msgstr "KWin 효과" + +#~ msgid "KWin Window Switcher" +#~ msgstr "KWin 창 전환기" + +#~ msgid "KWin Script" +#~ msgstr "KWin 스크립트" + +#~ msgid "Provided by plugins:" +#~ msgstr "플러그인이 제공함:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr ".desktop 파일이 제공함:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "%1을(를) 업그레이드했습니다" + +#~ msgid "Successfully installed %1" +#~ msgstr "%1을(를) 성공적으로 설치했습니다" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "오류: %1 설치 실패: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "파일에서 패키지 업그레이드 중: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "%1을(를) 성공적으로 삭제했습니다" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "오류: %1 삭제 실패: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "패키지 종류 %1에 대한 설치기를 불러올 수 없습니다. 오류: %2" diff --git a/po/lt/libplasma6.po b/po/lt/libplasma6.po new file mode 100644 index 0000000..a54a139 --- /dev/null +++ b/po/lt/libplasma6.po @@ -0,0 +1,967 @@ +# Lithuanian translations for l package. +# Copyright (C) 2014 This_file_is_part_of_KDE +# This file is distributed under the same license as the l package. +# +# Automatically generated, 2014. +# Liudas Ališauskas , 2014. +# Mindaugas Baranauskas , 2015. +msgid "" +msgstr "" +"Project-Id-Version: l 10n\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-25 23:28+0300\n" +"Last-Translator: Moo <<>>\n" +"Language-Team: lt \n" +"Language: lt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : n%10>=2 && (n%100<10 || n" +"%100>=20) ? 1 : n%10==0 || (n%100>10 && n%100<20) ? 2 : 3);\n" +"X-Generator: Poedit 3.4.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Daugiau veiksmų" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Suskleisti" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Išskleisti" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Slaptažodis" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Ieškoti…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Paieška" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Išvalyti paiešką" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Nežinoma" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Aktyvuoti %1 valdiklį" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Pašalinti %1|/|Pašalinti $[get-case galininkas %1]" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Įjungti taisymo veikseną" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Konfigūruoti %1...|/|Konfigūruoti $[get-case galininkas %1]..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Užrakinti valdiklius" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Atrakinti valdiklius" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Išjungti taisymo veikseną" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Ar įrašyti apipavidalinimo podėlį diske." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Didžiausias apipavidalinimo podėlio dydis diske, kilobaitais. Atminkite, kad " +"failai yra reti masyvai, tad didžiausias dydis gali būti ir nenaudojamas. " +"Dažniausiai, yra saugiau nurodyti didesnį dydį." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Rodyti alternatyvas..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Valdiklis pašalintas" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Valdiklis „%1“ yra pašalintas." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Skydelis pašalintas" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Skydelis yra pašalintas." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Darbalaukis pašalintas" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Darbalaukis yra pašalintas." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Atšaukti" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Valdiklių nuostatos" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Šalinti šį valdiklį" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Šalinti šį skydelį" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Šalinti šią veiklą" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Veiklos nuostatos" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Pridėti ar tvarkyti valdiklius…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Nepavyko rasti užklausto komponento: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "%1 šakninis elementas privalo būti ContainmentItem tipo" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "%1 šakninis elementas privalo būti PlasmoidItem tipo" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Nežinoma programėlė" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Šis valdiklis buvo sukurtas senesnei nežinomai Plasma versijai ir nėra " +"suderinamas su Plasma %1. Norėdami gauti atnaujintą valdiklio versiją, " +"susisiekite su valdiklio kūrėju." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 yra nesuderinamas su Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Šis valdiklis buvo sukurtas Plasma %1 versijai ir nėra suderinamas su Plasma " +"%2. Norėdami gauti atnaujintą valdiklio versiją, susisiekite su valdiklio " +"kūrėju." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Šis valdiklis buvo sukurtas Plasma %1 versijai ir nėra suderinamas su Plasma " +"%2. Norėdami naudoti valdiklį, atnaujinkite Plasma versiją." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Apgailestaujame! Įkeliant %1, įvyko klaida." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Klaida įkeliant QML failą: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Klaida įkeliant programėlę: paketo %1 nėra." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 – Nuostatos: %2|/|%1 – $[get-case Kilmininkas %2] nuostatos" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Nuostatos: %1|/|$[get-case Kilmininkas %1] nuostatos" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma paketas" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Įdiegti" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Nepavyko įdiegti paketo" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Jūsų numestas paketas yra neteisingas." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Valdikliai" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Pridėti %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Pridėti piktogramą" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Darbalaukio fonas" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Nustatyti %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Numestas turinys" + +#~ msgid "Add Widgets..." +#~ msgstr "Pridėti valdiklių..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Nepavyko atverti %1 paketo, reikalingo valdikliui „%2“." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Valdiklio bendrinimas tinkle leidžia jums pasiekti šį valdiklį iš kito " +#~ "kompiuterio kaip nuotolinį valdymą." + +#~ msgid "Share this widget on the network" +#~ msgstr "Bendrinti šį valdiklį tinkle" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Leisti visiems laisvai gauti prieigą prie šio valdiklio" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Neteisinga (nulinė) tarnyba, nepavyksta atlikti jokių operacijų." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Valdiklis „%1“ neapibrėžė, kurį scenarijų variklį naudoti." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Įvairios" + +#~ msgid "Main Script File" +#~ msgstr "Pagrindinis scenarijaus failas" + +#~ msgid "Tests" +#~ msgstr "Testai" + +#~ msgid "Images" +#~ msgstr "Paveikslai" + +#~ msgid "Themed Images" +#~ msgstr "Apipavidalinimų paveikslai" + +#~ msgid "Configuration Definitions" +#~ msgstr "Konfigūravimo apibrėžimai" + +#~ msgid "User Interface" +#~ msgstr "Naudotojo sąsaja" + +#~ msgid "Data Files" +#~ msgstr "Duomenų failai" + +#~ msgid "Executable Scripts" +#~ msgstr "Vykdomieji scenarijai" + +#~ msgid "Screenshot" +#~ msgstr "Ekrano kopija" + +#~ msgid "Translations" +#~ msgstr "Vertimai" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Konfigūracinis naudotojo sąsajos puslapių modelis" + +#~ msgid "Configuration XML file" +#~ msgstr "Konfigūracinis XML failas" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Tinkintas kompaktiškų programėlių skleidiklis" + +#~ msgid "Images for dialogs" +#~ msgstr "Dialogų paveikslai" + +#~ msgid "Generic dialog background" +#~ msgstr "Bendrinis dialogo fonas" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Atsijungimo dialogo apipavidalinimas" + +#~ msgid "Wallpaper packages" +#~ msgstr "Darbalaukio fonų paketai" + +#~ msgid "Images for widgets" +#~ msgstr "Valdiklių paveikslai" + +#~ msgid "Background image for widgets" +#~ msgstr "Valdiklių foniniai paveikslai" + +#~ msgid "Analog clock face" +#~ msgstr "Analoginio laikrodžio ciferblatas" + +#~ msgid "Background image for panels" +#~ msgstr "Skydelių foninis paveikslas" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Grafikų valdiklių fonas" + +#~ msgid "Background image for tooltips" +#~ msgstr "Foninis paaiškinimų paveikslas" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Neskaidrūs dialogų paveikslai" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Neskaidrus bendrinis dialogo fonas" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Neskaidrus atsijungimo dialogo apipavidalinimas" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Neskaidrūs valdiklių paveikslai" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Neskaidrus foninis skydelių paveikslas" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Neskaidrus foninis paaiškinimų paveikslas" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme konfigūracijos failas" + +#~ msgid "Service Descriptions" +#~ msgstr "Paslaugų aprašai" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Nepavyko sukurti %1 scenarijaus variklio valdikliui „%2“." + +#~ msgid "Script initialization failed" +#~ msgstr "Nepavyko inicijuoti scenarijaus" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Šventinės dienos" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Įvykiai" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Darbai" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Kita" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%2 %1" + +#~ msgid "Previous Month" +#~ msgstr "Ankstesnis mėnuo" + +#~ msgid "Previous Year" +#~ msgstr "Ankstesni metai" + +#~ msgid "Previous Decade" +#~ msgstr "Ankstesnis dešimtmetis" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Šiandien" + +#~ msgid "Reset calendar to today" +#~ msgstr "Atstatyti kalendorių į šiandieną" + +#~ msgid "Next Month" +#~ msgstr "Kitas mėnuo" + +#~ msgid "Next Year" +#~ msgstr "Kiti metai" + +#~ msgid "Next Decade" +#~ msgstr "Kitas dešimtmetis" + +#~ msgid "Days" +#~ msgstr "Dienos" + +#~ msgid "Months" +#~ msgstr "Mėnesiai" + +#~ msgid "Years" +#~ msgstr "Metai" + +#~ msgid "OK" +#~ msgstr "Gerai" + +#~ msgid "Cancel" +#~ msgstr "Atsisakyti" + +#~ msgid "Run the Associated Application" +#~ msgstr "Paleisti susietą programą" + +#~ msgid "Open with %1" +#~ msgstr "Atverti naudojant %1" + +#~ msgid "Accessibility" +#~ msgstr "Prieinamumas" + +#~ msgid "Application Launchers" +#~ msgstr "Programų paleidyklės" + +#~ msgid "Astronomy" +#~ msgstr "Astronomija" + +#~ msgid "Date and Time" +#~ msgstr "Data ir laikas" + +#~ msgid "Development Tools" +#~ msgstr "Programavimo įrankiai" + +#~ msgid "Education" +#~ msgstr "Švietimas" + +#~ msgid "Environment and Weather" +#~ msgstr "Aplinka ir orai" + +#~ msgid "Examples" +#~ msgstr "Pavyzdžiai" + +#~ msgid "File System" +#~ msgstr "Failų sistema" + +#~ msgid "Fun and Games" +#~ msgstr "Linksmybės ir žaidimai" + +#~ msgid "Graphics" +#~ msgstr "Grafika" + +#~ msgid "Language" +#~ msgstr "Kalba" + +#~ msgid "Mapping" +#~ msgstr "Atvaizdavimas" + +#~ msgid "Miscellaneous" +#~ msgstr "Įvairūs" + +#~ msgid "Multimedia" +#~ msgstr "Įvairialypė terpė" + +#~ msgid "Online Services" +#~ msgstr "Internetinės paslaugos" + +#~ msgid "Productivity" +#~ msgstr "Produktyvumas" + +#~ msgid "System Information" +#~ msgstr "Sistemos informacija" + +#~ msgid "Utilities" +#~ msgstr "Paslaugų programos" + +#~ msgid "Windows and Tasks" +#~ msgstr "Langai ir užduotys" + +#~ msgid "Clipboard" +#~ msgstr "Iškarpinė" + +#~ msgid "Tasks" +#~ msgstr "Užduotys" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Taisyti %1...|/|Taisyti $[get-case galininkas %1]..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Numatytosios apipavidalinimo nuostatos ir t.t." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Spalvų rinkinys, kurį naudoti programose." + +#~ msgid "Preview Images" +#~ msgstr "Paveikslų peržiūra" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Prisijungimo tvarkytuvės peržiūra" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Ekrano užrakto peržiūra" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Naudotojų perjungiklio peržiūra" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Virtualių darbalaukių perjungiklio peržiūra" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Prisistatymo lango peržiūra" + +#~ msgid "Preview for KRunner" +#~ msgstr "KRunner peržiūra" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Langų dekoracijų peržiūra" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Langų perjungiklio peržiūra" + +#~ msgid "Login Manager" +#~ msgstr "Prisijungimo tvarkytuvė" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Pagrindinis prisijungimo tvarkytuvės scenarijus" + +#~ msgid "Logout Dialog" +#~ msgstr "Atsijungimo dialogas" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Pagrindinis atsijungimo dialogo scenarijus" + +#~ msgid "Screenlocker" +#~ msgstr "Ekrano užraktas" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Pagrindinis ekrano užrakto scenarijus" + +#~ msgid "UI for fast user switching" +#~ msgstr "Naudotojo sąsaja greitam persijungimui tarp naudotojų" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Pagrindinis naudotojų perjungiklio scenarijus" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Virtualių darbalaukių perjungiklis" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Pagrindinis virtualių darbalaukių perjungiklio scenarijus" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Ekrane rodomi pranešimai" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Pagrindinis ekrane rodomų pranešimų scenarijus" + +#~ msgid "Splash Screen" +#~ msgstr "Prisistatymo langas" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Pagrindinis prisistatymo lango scenarijus" + +#~ msgid "KRunner UI" +#~ msgstr "KRunner naudotojo sąsaja" + +#~ msgid "Main Script KRunner" +#~ msgstr "Pagrindinis KRunner programos scenarijus" + +#~ msgid "Window Decoration" +#~ msgstr "Lango dekoracijos" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Pagrindinis langų dekoracijų scenarijus" + +#~ msgid "Window Switcher" +#~ msgstr "Langų perjungiklis" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Pagrindinis langų perjungiklio scenarijus" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Užbaigti išdėstymo tinkinimą" + +#~ msgid "Customize Layout..." +#~ msgstr "Tinkinti išdėstymą..." + +#~ msgid "Fetching file type..." +#~ msgstr "Gaunamas failo tipas..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1 parinktys|/|$[get-case Kilmininkas %1] parinktys" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Nuostatos: %1|/|$[get-case Kilmininkas %1] nuostatos" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Nuostatos: %1...|/|$[get-case Kilmininkas %1] nuostatos..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Mažo spalvingumo paveikslėliai dialogams" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Mažo spalvingumo bendras dialogo fonas" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Mažo spalvingumo atsijungimo dialogo tema" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Mažo spalvingumo fono paveikslėlis valdikliams" + +#~ msgid "Low color analog clock face" +#~ msgstr "Mažo spalvingumo analoginio laikrodžio ciferblatas" + +#~ msgid "Low color background image for panels" +#~ msgstr "Mažo spalvingumo fono paveikslėlis skydeliams" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Mažo spalvingumo grafikų valdikliams" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Mažo spalvingumo fono paveikslėlis patarimams" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Plazmos paketų tvarkytuvė" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Sukurti paketo SHA1 maišos santrauką " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Diegimui bei šalinimui, dirba su visiems naudotojams įdiegtais paketais" + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Paketo tipas, pvz., apipavidalinimas, darbalaukio fonas, plazmoidas, " +#~ "duomenų variklis, paleidiklis, išdėstymo šablonasir t.t." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Diegti paketą į " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Rodyti informaciją apie paketą" + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Atnaujinti paketą į " + +#~ msgid "List installed packages" +#~ msgstr "Įdiegtų paketų sąrašas" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "Parodyti visus galimus įdiegti paketų tipus" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Pašalinti paketą" + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Absoliutus kelias iki paketo šakninio aplanko. Jei nenurodyta, bus " +#~ "ieškoma šios KDE sesijos standartinių duomenų kataloguose." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Nepavyko sukurti %1 paketo maišos santraukos." + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "%1 paketo SHA1 santrauka: „%2“" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "darbalaukio fonas" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plazmoidas" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "paketas" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "apipavidalinimas" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "duomenų variklis" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "paleidiklis" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "darbalaukio fono papildinys" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "išvaizda ir turinys" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "apvalkalas" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "išdėstymo šablonas" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "langų efektas" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "langų perjungiklis" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "langų scenarijus" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "Paketo tipui %1 nepavyksta rasti tinkamos diegimo programos" + +#~ msgid "Listing service types: %1" +#~ msgstr "Pateikiami paslaugų tipai: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Klaida: neįdiegtas %1 papildinys." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Reikia nurodyti diegimą, šalinimą, atnaujinimą arba sąrašo rodymą." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Klaida: nepavyksta rasti papildinio meta duomenų: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Rodoma paketo informacija: %1" + +#~ msgid " Name : %1" +#~ msgstr " Pavadinimas : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Komentaras : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Papildinys : %1" + +#~ msgid " Author : %1" +#~ msgstr " Autorius : %1" + +#~ msgid " Path : %1" +#~ msgstr " Kelias : %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Packageroot ir globalios nuostatos prieštarauja viena kitoms, pasirinkite " +#~ "tik vieną." + +#~ msgid "Addon Name" +#~ msgstr "Papildinio pavadinimas" + +#~ msgid "Service Type" +#~ msgstr "Paslaugos tipas" + +#~ msgid "Path" +#~ msgstr "Kelias" + +#~ msgid "Type Argument" +#~ msgstr "Tipo argumentas" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Tipai paketų, kuriuos galima įdiegti šiuo įrankiu:" + +#~ msgid "Built in:" +#~ msgstr "Įtaisyta:" + +#~ msgid "DataEngine" +#~ msgstr "Duomenų variklis" + +#~ msgid "Layout Template" +#~ msgstr "Išdėstymo šablonas" + +#~ msgid "Look and Feel" +#~ msgstr "Išvaizda ir turinys" + +#~ msgid "Package" +#~ msgstr "Paketas" + +#~ msgid "Plasmoid" +#~ msgstr "Plazmoidas" + +#~ msgid "Runner" +#~ msgstr "Paleidiklis" + +#~ msgid "Shell" +#~ msgstr "Apvalkalas" + +#~ msgid "Theme" +#~ msgstr "Apipavidalinimas" + +#~ msgid "Wallpaper Images" +#~ msgstr "Darbalaukio fonai" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Animacinis darbalaukio fonas" + +#~ msgid "KWin Effect" +#~ msgstr "KWin efektas" + +#~ msgid "KWin Window Switcher" +#~ msgstr "KWin langų perjungiklis" + +#~ msgid "KWin Script" +#~ msgstr "KWin scenarijaus failas" + +#~ msgid "Provided by plugins:" +#~ msgstr "Teikiami papildiniai:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Teikiami .desktop failų:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "%1 sėkmingai atnaujintas" + +#~ msgid "Successfully installed %1" +#~ msgstr "%1 sėkmingai įdiegtas" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Nepavyko įdiegti %1: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Paketas atnaujinamas iš failo: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "%1 sėkmingai pašalintas" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Nepavyko pašalinti %1: %2" diff --git a/po/lv/libplasma6.po b/po/lv/libplasma6.po new file mode 100644 index 0000000..fbe7b60 --- /dev/null +++ b/po/lv/libplasma6.po @@ -0,0 +1,685 @@ +# Copyright (C) 2024 This file is copyright: +# This file is distributed under the same license as the plasma-framework package. +# +# Maris Nartiss , 2019. +# SPDX-FileCopyrightText: 2024 Toms Trasuns +msgid "" +msgstr "" +"Project-Id-Version: plasma-framework\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-22 16:58+0300\n" +"Last-Translator: Toms Trasuns \n" +"Language-Team: Latvian \n" +"Language: lv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : " +"2);\n" +"X-Generator: Lokalize 24.05.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Vairāk darbību" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Sakļaut" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Izvērst" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Parole" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Meklēt…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Meklēt" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Notīrīt meklēšanu" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Nezināms" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Aktivēt „%1“ logdaļu" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Noņemt „%1“" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Ieslēgt rediģēšanas režīmu" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Konfigurēt „%1“…" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Slēgt logdaļas" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Atslēgt logdaļas" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Iziet no rediģēšanas režīma" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Vai izveidot motīva kešatmiņu uz diska." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Maksimālais motīva kešatmiņas izmērs uz diska kilobaitos. Ņemiet vērā, ka " +"parasti šīs datnes ir nelielas un tādēļ maksimālais izmērs var netikt " +"izmantots. Tāpēc parasti ir droši norādīt lielu izmēru." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Parādīt alternatīvas…" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Logdaļa ir noņemta" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Logdaļa „%1“ ir noņemta." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panelis ir noņemts" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Ir noņemts panelis." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Darbvirsma ir noņemta" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Ir noņemta darbvirsma." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Atsaukt" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Logdaļas iestatījumi" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Noņemt šo logdaļu" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Noņemt šo paneli" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Noņemt šo aktivitāti" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Aktivitātes iestatījumi" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Neatrada pieprasīto komponenti: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Saknes vienumam „%1“ ir jābūt „ContainmentItem“ tipam" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Saknes vienumam „%1“ jābūt „PlasmoidItem“ tipam" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Nezināma sīklietotne" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Šī logdaļa ir izveidota nezināmai vecākai „Plasma“ versijai un nav " +"savietojama ar „Plasma“ %1. Sazinieties ar logdaļas autoru saistībā ar jaunu " +"versiju." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "„%1“ nav saderīgs ar „Plasma“ %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Šī logdaļa ir izveidota „Plasma“ %1 un nav savietojama ar „Plasma“ %2. " +"Sazinieties ar logdaļas autoru saistībā ar jaunu versiju." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Šī logdaļa ir izveidota „Plasma“ %1 un nav savietojama ar „Plasma“ %2. Lai " +"to izmantotu, atjauniniet „Plasma“." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Diemžēl, ielādējot „%1“, radās kļūda." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Kļūda, ielādējot QML datni: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Kļūda, ielādējot sīklietotni: „%1“ nepastāv." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "„%1“ — „%2“ Iestatījumi" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "„%1“ iestatījumi" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "„Plasma“ pakotne" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Instalēt" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Neizdevās instalēt pakotni" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Nomestā pakotne nav derīga." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Logdaļas" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Pievienot „%1“" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Pievienot ikonu" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Tapete" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Uzlikt „%1“" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Saturs ir nomests" + +#~ msgid "Add Widgets..." +#~ msgstr "Pievienot logdaļas…" + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "" +#~ "Nebija iespējams atvērt „%1“ pakotni, kas ir nepieciešama logdaļai „%2“." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Logdaļas kopīgošana tīklā ļauj citiem datoriem piekļūt šai logdaļai un " +#~ "tādējādi to izmantot kā tālvadības pulti." + +#~ msgid "Share this widget on the network" +#~ msgstr "Koplietot šo logdaļu tīklā" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Atļaut visiem brīvi piekļūt šai logdaļai." + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Nederīgs (null) serviss. Nav iespējams veikt darbības." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Logdaļa %1 nav definējusi izmantojamo ScriptEngine." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Dažādi" + +#~ msgid "Main Script File" +#~ msgstr "Galvenā skripta datne" + +#~ msgid "Tests" +#~ msgstr "Tests" + +#~ msgid "Images" +#~ msgstr "Attēli" + +#~ msgid "Themed Images" +#~ msgstr "Attēli pa tēmu" + +#~ msgid "Configuration Definitions" +#~ msgstr "Konfigurācijas definīcijas" + +#~ msgid "User Interface" +#~ msgstr "Lietotāja saskarne" + +#~ msgid "Data Files" +#~ msgstr "Datu datnes" + +#~ msgid "Executable Scripts" +#~ msgstr "Izpildāmie skripti" + +#~ msgid "Screenshot" +#~ msgstr "Ekrānuzņēmums" + +#~ msgid "Translations" +#~ msgstr "Tulkojumi" + +#~ msgid "Configuration UI pages model" +#~ msgstr "UI lapu konfigurācijas modelis" + +#~ msgid "Configuration XML file" +#~ msgstr "Konfigurācijas XML datne" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Pielāgots izpletējs kompaktām lietotnēm" + +#~ msgid "Images for dialogs" +#~ msgstr "Attēli priekš dialogiem" + +#~ msgid "Generic dialog background" +#~ msgstr "Vispārējs dialogu fons" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Atteikšanās dialoga tēma" + +#~ msgid "Wallpaper packages" +#~ msgstr "Tapešu pakotnes" + +#~ msgid "Images for widgets" +#~ msgstr "Attēli priekš logdaļām" + +#~ msgid "Background image for widgets" +#~ msgstr "Logdaļu fona attēls" + +#~ msgid "Analog clock face" +#~ msgstr "Analogais pulkstenis" + +#~ msgid "Background image for panels" +#~ msgstr "Paneļu fona attēls" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Zīmējošu logdaļu fons" + +#~ msgid "Background image for tooltips" +#~ msgstr "Paskaidres fona attēls" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Necaurspīdīgi attēli priekš dialogiem" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Vispārējs necaurspīdīgs dialogu fons" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Necaurspīdīga tēma atteikšanās dialogam" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Necaurspīdīgi attēli logdaļām" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Necaurspīdīgi attēli paneļiem" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Necaurspīdīgi attēli paskaidrēm" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme konfigurācijas datne" + +#~ msgid "Service Descriptions" +#~ msgstr "Servisu apraksti" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Nebija iespējams izveidot %1 ScriptEngine priekš logdaļas %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Nesekmīga skripta inicializācija" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Brīvdienas" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Notikumi" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Jāizdara" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Citi" + +#~ msgid "Previous Month" +#~ msgstr "Iepriekšējais mēnesis" + +#~ msgid "Previous Year" +#~ msgstr "Iepriekšējais gads" + +#~ msgid "Previous Decade" +#~ msgstr "Iepriekšējā dekāde" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Šodiena" + +#~ msgid "Reset calendar to today" +#~ msgstr "Pāriet uz šodienu" + +#~ msgid "Next Month" +#~ msgstr "Nākamais mēnesis" + +#~ msgid "Next Year" +#~ msgstr "Nākamais gads" + +#~ msgid "Next Decade" +#~ msgstr "Nākamā dekāde" + +#, fuzzy +#~| msgid "Next Month" +#~ msgid "Months" +#~ msgstr "Nākamais mēnesis" + +#~ msgid "OK" +#~ msgstr "Labi" + +#~ msgid "Cancel" +#~ msgstr "Atcelt" + +#~ msgid "Run the Associated Application" +#~ msgstr "Darbināt piesaistīto aplikāciju" + +#~ msgid "Open with %1" +#~ msgstr "Atvērt ar %1" + +#~ msgid "Accessibility" +#~ msgstr "Pieejamība" + +#~ msgid "Application Launchers" +#~ msgstr "Programmu palaidēji" + +#~ msgid "Astronomy" +#~ msgstr "Astronomija" + +#~ msgid "Date and Time" +#~ msgstr "Datums un laiks" + +#~ msgid "Development Tools" +#~ msgstr "Izstrādes rīki" + +#~ msgid "Education" +#~ msgstr "Izglītība" + +#~ msgid "Environment and Weather" +#~ msgstr "Vide un laikapstākļi" + +#~ msgid "Examples" +#~ msgstr "Piemēri" + +#~ msgid "File System" +#~ msgstr "Datņu sistēma" + +#~ msgid "Fun and Games" +#~ msgstr "Spēles un jautrība" + +#~ msgid "Graphics" +#~ msgstr "Grafika" + +#~ msgid "Language" +#~ msgstr "Valoda" + +#~ msgid "Mapping" +#~ msgstr "Kartēšana" + +#~ msgid "Miscellaneous" +#~ msgstr "Dažādi" + +#~ msgid "Multimedia" +#~ msgstr "Multivide" + +#~ msgid "Online Services" +#~ msgstr "Tiešsaistes servisi" + +#~ msgid "Productivity" +#~ msgstr "Produktivitāte" + +#~ msgid "System Information" +#~ msgstr "Sistēmas informācija" + +#~ msgid "Utilities" +#~ msgstr "Utilītas" + +#~ msgid "Windows and Tasks" +#~ msgstr "Logi un uzdevumi" + +#~ msgid "Clipboard" +#~ msgstr "Starpliktuve" + +#~ msgid "Tasks" +#~ msgstr "Uzdevumi" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Rediģēt %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Tēmu u.c. noklusējuma iestatījumi." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Lietotņu krāsu shēma." + +#~ msgid "Preview Images" +#~ msgstr "Priekšskatīt attēlus" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Pieteikšanās pārvaldnieka priekšskatījums" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Ekrānslēdzēja priekšskatījums" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Lietotāju pārslēdzēja priekšskatījums" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Virtuālo darbvirsmu pārslēdzēja priekšskatījums" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Uzplaiksnījumekrāna priekšskatījums" + +#~ msgid "Preview for KRunner" +#~ msgstr "KRunner priekšskatījums" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Logu dekorāciju priekšskatījums" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Logu pārslēdzēja priekšskatījums" + +#~ msgid "Login Manager" +#~ msgstr "Pieteikšanās pārvaldnieks" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Galvenais pieteikšanās pārvaldnieka skripts" + +#~ msgid "Logout Dialog" +#~ msgstr "Atteikšanās dialogs" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Galvenais atteikšanās dialoga skripts" + +#~ msgid "Screenlocker" +#~ msgstr "Ekrānslēdzējs" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Galvenais ekrānslēdzēja skripts" + +#~ msgid "UI for fast user switching" +#~ msgstr "Ātrs lietotāju pārslēdzējs" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Galvenais lietotāju pārslēdzēja skripts" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Virtuālo darbvirsmu pārslēdzējs" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Galvenais virtuālo darbvirsmu pārslēdzēja skripts" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Uz ekrāna rādāmie paziņojumi" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Galvenais uz ekrāna rādāmo paziņojumu skripts" + +#~ msgid "Splash Screen" +#~ msgstr "Uzplaiksnījuma ekrāns" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Galvenais uzplaiksnījuma ekrāna skripts" + +#~ msgid "KRunner UI" +#~ msgstr "KRunner UI" + +#~ msgid "Main Script KRunner" +#~ msgstr "Galvenais KRunner skripts" + +#~ msgid "Window Decoration" +#~ msgstr "Loga dekorācija" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Galvenais logu dekorāciju skripts" + +#~ msgid "Window Switcher" +#~ msgstr "Logu pārslēdzējs" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Galvenais logu pārslēdzēja skripts" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Pabeigt pielāgot izkārtojumu" + +#~ msgid "Customize Layout..." +#~ msgstr "Pielāgot izkārtojumu..." + +#~ msgid "Fetching file type..." +#~ msgstr "Iegūst datnes tipu..." diff --git a/po/ml/libplasma6.po b/po/ml/libplasma6.po new file mode 100644 index 0000000..e65ee76 --- /dev/null +++ b/po/ml/libplasma6.po @@ -0,0 +1,678 @@ +# Malayalam localization of libplasma5 +# Copyright (C) 2019 This file is copyright: +# This file is distributed under the same license as the plasma-framework package. +# ലക്ഷ്മി സുനില്‍ , 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: plasma-framework\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2019-12-14 15:16+0530\n" +"Last-Translator: Nithin S Sabu \n" +"Language-Team: Swathanthra|സ്വതന്ത്ര Malayalam|മലയാളം Computing|കമ്പ്യൂട്ടിങ്ങ് \n" +"Language: ml\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "അജ്ഞാതം" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "%1 വിഡ്ജറ്റ് സജീവമാക്കുക" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "%1 കളയുക" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "%1 സജ്ജീകരിക്കുക..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "വിഡ്ജറ്റുകൾ വെച്ചുറപ്പിക്കുക" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "വിഡ്ജറ്റുകളുടെ വിലക്കഴിക്കുക" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "പ്രമേയത്തിനായുള്ള ഓണ്‍-ഡിസ്ക് കാഷെ സൃഷ്ടിക്കണോ വേണ്ടയോ." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "മറ്റു മാര്‍ഗങ്ങള്‍ കാണിക്കുക..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "വിഡ്ജറ്റ് നീക്കംചെയ്യപ്പെട്ടു" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "%1 വിഡ്ജറ്റ് നീക്കംചെയ്യപ്പെട്ടിരിക്കുന്നു." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "പാളി നീക്കംചെയ്യപ്പെട്ടു" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "ഒരു പാളി നീക്കംചെയ്യപ്പെട്ടിരിക്കുന്നു." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "പണിയിടം നീക്കംചെയ്യപ്പെട്ടു" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "ഒരു പണിയിടം നീക്കംചെയ്യപ്പെട്ടിരിക്കുന്നു." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "തിരിച്ചെടുക്കുക" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "വിഡ്ജറ്റ് ക്രമീകരണങ്ങള്‍" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "ഈ വിഡ്ജറ്റ് നീക്കംചെയ്യുക" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "ഈ പാളി നീക്കംചെയ്യുക" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "ഈ പ്രവൃത്തി നീക്കംചെയ്യുക" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "പ്രവൃത്തി ക്രമീകരണങ്ങള്‍" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "ആവശ്യപ്പെട്ട ഘടകം കണ്ടെത്തുവാനായില്ല: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, fuzzy, kde-format +#| msgid "Unknown" +msgid "Unknown Applet" +msgstr "അജ്ഞാതം" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, fuzzy, kde-format +#| msgid "Error loading QML file: %1" +msgid "Error loading QML file: %1 %2" +msgstr "ക്യുഎംഎല്‍ ഫയല്‍ തുറക്കുന്നതിനിടയില്‍ പിശക്: %1" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package inexistent. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "ആപ്‌ലെറ്റ് ലോഡ് ചെയ്യുന്നതിൽ പിശക് : പാക്കേജ് നിലവിലില്ല. %1" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "%1 ക്രമീകരണങ്ങള്‍" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 ക്രമീകരണങ്ങള്‍" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "പ്ലാസ്മ പാക്കേജ്" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "ഇന്‍സ്റ്റാള്‍" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "പാക്കേജ് ഇന്‍സ്റ്റാളേഷന്‍ പരാജയപ്പെട്ടു" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "നിങ്ങളിപ്പോള്‍ നല്‍കിയ പാക്കേജ് സ്വീകാര്യമല്ല." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "വിഡ്ജറ്റുകള്‍" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "%1 ചേര്‍ക്കുക [വിഡ്ജറ്റ് ചേര്‍ക്കുക]" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "സൂചനാചിത്രങ്ങള്‍ ചേര്‍ക്കുക" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "പശ്ചാത്തലചിത്രം" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "%1 -നെ തീര്‍ച്ചപ്പെടുത്തുക" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "ഉള്ളടക്കം ഉപേക്ഷിക്കപ്പെട്ടു" + +#~ msgid "Add Widgets..." +#~ msgstr "വിഡ്ജറ്റ് ചേര്‍ക്കുക..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "%2 വിഡ്ജറ്റിനാവശ്യമായ %1 പാക്കേജ് തുറക്കാനായില്ല." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "ഒരു വി‍‍ഡ്ജറ്റ് ശൃഖലയില്‍ പങ്കുവയ്ക്കുന്നത് ആ വിഡ്ജറ്റ് വിദൂരത്തിലുള്ള മറ്റൊരു കമ്പ്യൂട്ടറില്‍ നിന്ന് " +#~ "നിയന്ത്രിക്കാന്‍ അനുവദിക്കുന്നു." + +#~ msgid "Share this widget on the network" +#~ msgstr "ഈ വിഡ്ജറ്റ് ശൃംഖലയില്‍ പങ്കുവയ്ക്കുക" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "എല്ലാവരേയും ഈ വിഡ്ജറ്റ് ഉപയോഗിക്കാന്‍ അനുവദിക്കുക" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "അസാധുവായ സേവനം, യാതൊരു പ്രക്രിയയും നിര്‍വഹിക്കാനാവുന്നില്ല." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "%1 വിഡ്ജറ്റ് ഏത് സ്ക്രിപ്റ്റ് എന്‍ജിനാണ് ഉപയോഗിക്കേണ്ടതെന്ന് നിര്‍വചിച്ചിട്ടില്ല." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "പലവക" + +#~ msgid "Main Script File" +#~ msgstr "പ്രധാനസ്ക്രിപ്റ്റ് ഫയല്‍" + +#~ msgid "Tests" +#~ msgstr "പരിശോധനകള്‍" + +#~ msgid "Images" +#~ msgstr "ചിത്രങ്ങള്‍" + +#~ msgid "Themed Images" +#~ msgstr "പ്രമേയമുള്ള ചിത്രങ്ങള്‍" + +#~ msgid "Configuration Definitions" +#~ msgstr "സജ്ജീകരണ നിര്‍വചനങ്ങള്‍" + +#~ msgid "User Interface" +#~ msgstr "സമ്പർക്കമുഖം" + +#~ msgid "Data Files" +#~ msgstr "ഡാറ്റ ഫയലുകള്‍" + +#~ msgid "Executable Scripts" +#~ msgstr "പ്രവര്‍ത്തിപ്പിക്കാവുന്ന സ്ക്രിപ്റ്റുകള്‍" + +#~ msgid "Screenshot" +#~ msgstr "സ്ക്രീന്‍ഷോട്ട്" + +#~ msgid "Translations" +#~ msgstr "പരിഭാഷ" + +#~ msgid "Configuration UI pages model" +#~ msgstr "സജ്ജീകരണ സമ്പർക്കമുഖങ്ങളുടെ മാതൃക" + +#~ msgid "Configuration XML file" +#~ msgstr "സജ്ജീകരണ എക്സ് എം എൽ ഫയൽ" + +#~ msgid "Images for dialogs" +#~ msgstr "ഡയലോഗിനായുള്ള ചിത്രങ്ങള്‍" + +#~ msgid "Generic dialog background" +#~ msgstr "പൊതുവായ ഡയലോഗ് പശ്ചാത്തലം" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "പുറത്തിറങ്ങുന്നതിനുള്ള ഡയലോഗിന്റെ പ്രമേയം" + +#~ msgid "Wallpaper packages" +#~ msgstr "പശ്ചാത്തലചിത്രപാക്കേജുകള്‍" + +#~ msgid "Images for widgets" +#~ msgstr "വിഡ്ജറ്റുകള്‍ക്കായുള്ള ചിത്രങ്ങള്‍" + +#~ msgid "Background image for widgets" +#~ msgstr "വിഡ്ജറ്റുകള്‍ക്കായുള്ള പശ്ചാത്തലചിത്രം" + +#~ msgid "Analog clock face" +#~ msgstr "അനലോഗ് ഘടികാരപ്രതലം" + +#~ msgid "Background image for panels" +#~ msgstr "പാളികള്‍ക്കായുള്ള പശ്ചാത്തലചിത്രം" + +#~ msgid "Background for graphing widgets" +#~ msgstr "ഗ്രാഫിംഗ് വിഡ്ജറ്റുകള്‍ക്കായുള്ള പശ്ചാത്തലചിത്രം" + +#~ msgid "Background image for tooltips" +#~ msgstr "സൂചനകള്‍ക്കുള്ള പശ്ചാത്തലചിത്രം" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "ഡയലോഗുകൾക്കുള്ള അതാര്യ ചിത്രങ്ങൾ" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "പൊതുവായ ഡയലോഗുകളുടെ അതാര്യ പശ്ചാത്തലം" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "ലോഗൗട്ട് ഡയലോഗിനായുള്ള അതാര്യ പ്രമേയം" + +#~ msgid "Opaque images for widgets" +#~ msgstr "വിഡ്ജറ്റിനായുള്ള അതാര്യ ചിത്രങ്ങള്‍" + +#~ msgid "Opaque background image for panels" +#~ msgstr "പാളികള്‍ക്കായുള്ള അതാര്യ പശ്ചാത്തലചിത്രം" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "സൂചനകള്‍ക്കുള്ള അതാര്യപശ്ചാത്തലചിത്രം" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "കെ കളര്‍സ്കീം സജ്ജീകരണ ഫയ" + +#~ msgid "Service Descriptions" +#~ msgstr "സേവനവിവരണം" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "%2 വിഡ്ജറ്റിനു വേണ്ട %1 സ്ക്രിപ്റ്റ് എന്‍ജിന്‍ സൃഷ്ടിക്കുവാനായില്ല." + +#~ msgid "Script initialization failed" +#~ msgstr "സ്ക്രിപ്റ്റ് ആരംഭിക്കല്‍ പരാജയപ്പെട്ടു" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "അവധിദിനങ്ങള്‍" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "പരിപാടികള്‍" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "ചെയ്യാനുള്ളവ" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "മറ്റുള്ളവ" + +#~ msgid "Previous Month" +#~ msgstr "മുന്‍മാസം" + +#~ msgid "Previous Year" +#~ msgstr "മുന്‍വര്‍ഷം" + +#~ msgid "Previous Decade" +#~ msgstr "മുന്‍ദശാബ്ദം" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "ഇന്ന്" + +#~ msgid "Reset calendar to today" +#~ msgstr "കലണ്ടര്‍ ഇന്നത്തേക്ക്മാറ്റുക" + +#~ msgid "Next Month" +#~ msgstr "അടുത്തമാസം" + +#~ msgid "Next Year" +#~ msgstr "അടുത്തവര്‍ഷം" + +#~ msgid "Next Decade" +#~ msgstr "അടുത്തദശാബ്ദം" + +#, fuzzy +#~| msgid "Next Month" +#~ msgid "Months" +#~ msgstr "അടുത്തമാസം" + +#~ msgid "OK" +#~ msgstr "ശരി" + +#~ msgid "Cancel" +#~ msgstr "റദ്ദാക്കുക" + +#~ msgid "Run the Associated Application" +#~ msgstr "ബന്ധപ്പെട്ട ആപ്ലിക്കേഷന്‍ പ്രവര്‍ത്തിപ്പിക്കുക" + +#~ msgid "Open with %1" +#~ msgstr "%1-ഓടുകൂടി തുറക്കുക" + +#~ msgid "Accessibility" +#~ msgstr "പ്രാപ്യത" + +#~ msgid "Application Launchers" +#~ msgstr "ആപ്ലിക്കേഷന്‍ ലോഞ്ചര്‍" + +#~ msgid "Astronomy" +#~ msgstr "ജ്യോതിശാസ്ത്രം" + +#~ msgid "Date and Time" +#~ msgstr "തീയതിയും സമയവും" + +#~ msgid "Development Tools" +#~ msgstr "വികസനത്തിനായുള്ള ഉപകരണങ്ങ" + +#~ msgid "Education" +#~ msgstr "വിദ്യാഭ്യാസം" + +#~ msgid "Environment and Weather" +#~ msgstr "പരിസരവും കാലാവസ്ഥയും" + +#~ msgid "Examples" +#~ msgstr "ഉദാഹരണങ്ങള്‍" + +#~ msgid "File System" +#~ msgstr "ഫയല്‍ സിസ്റ്റം" + +#~ msgid "Fun and Games" +#~ msgstr "കേളിയും കളികളും" + +#~ msgid "Graphics" +#~ msgstr "ഗ്രാഫിക്സ്" + +#~ msgid "Language" +#~ msgstr "ഭാഷ" + +#~ msgid "Mapping" +#~ msgstr "മാപ്പിംഗ്" + +#~ msgid "Miscellaneous" +#~ msgstr "പലവക" + +#~ msgid "Multimedia" +#~ msgstr "മള്‍ട്ടിമീഡിയ" + +#~ msgid "Online Services" +#~ msgstr "ഓണ്‍ലൈന്‍ സേവനങ്ങള്‍" + +#~ msgid "Productivity" +#~ msgstr "ഉത്പാദനക്ഷമത" + +#~ msgid "System Information" +#~ msgstr "സിസ്റ്റം അറിവ്" + +#~ msgid "Utilities" +#~ msgstr "ഉപകരണങ്ങൾ" + +#~ msgid "Windows and Tasks" +#~ msgstr "ജാലകങ്ങളും ജോലികളും" + +#~ msgid "Clipboard" +#~ msgstr "ഓര്‍മ്മച്ചെപ്പ്" + +#~ msgid "Tasks" +#~ msgstr "ജോലികള്‍" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "%1 ചിട്ടപ്പെടുത്തുക..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "പ്രമേയത്തിനും മറ്റുമുള്ള സഹജമായ ക്രമീകരണങ്ങള്‍." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "ആപ്ലിക്കേഷനുപയോഗിക്കുന്ന നിറപദ്ധതി." + +#~ msgid "Preview Images" +#~ msgstr "ചിത്രങ്ങളുടെ തിരനോട്ടം" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "പ്രവേശന മാനേജരുടെ പൂർവദൃശ്യം" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "പൂട്ടുന്ന സ്‌ക്രീനിന്റെ പൂർവദൃശ്യം" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "ഉപയോക്താവിനെ മാറ്റുന്നതിന്റെ പൂർവദൃശ്യം" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "സാങ്കല്പിക പണിയിടം മാറ്റുന്നതിന്റെ പൂർവദൃശ്യം" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "സ്പ്ളാഷ് സ്‌ക്രീനിന്റെ പൂർവദൃശ്യം" + +#~ msgid "Preview for KRunner" +#~ msgstr "കെറണ്ണറിന്റെ പൂർവദൃശ്യം" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "ജാലക അലങ്കാരങ്ങളുടെ പൂർവദൃശ്യം" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "ജാലകം മാറ്റുന്നതിന്റെ പൂർവദൃശ്യം" + +#~ msgid "Login Manager" +#~ msgstr "പ്രവേശന മാനേജര്‍" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "പ്രവേശന മാനേജരുടെ പ്രധാന സ്ക്രിപ്റ്റ്" + +#~ msgid "Logout Dialog" +#~ msgstr "പുറത്തുകടക്കാനുള്ള ഡയലോഗ്" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "പുറത്തേക്കു കടക്കാനുള്ള ഡയലോഗിന്റെ പ്രധാന സ്ക്രിപ്റ്റ്" + +#~ msgid "Screenlocker" +#~ msgstr "സ്ക്രീൻ പൂട്ട്" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "സ്ക്രീൻ പൂട്ടിന്റെ പ്രധാന സ്ക്രിപ്റ്റ്" + +#~ msgid "UI for fast user switching" +#~ msgstr "ഉപയോക്താവിനെ വേഗത്തിൽ മാറ്റുന്നതിനുള്ള സമ്പർക്കം" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "ഉപയോക്താവിനെ മാറ്റുന്നതിനുള്ള പ്രധാന സ്ക്രിപ്റ്റ്" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "സാങ്കല്‍പ്പിക പണിയിടം മാറ്റുക" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "സാങ്കല്പിക പണിയിടം മാറ്റുന്നതിന്റെ പ്രധാന സ്ക്രിപ്റ്റ്" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "ഓൺ-സ്ക്രീൻ പ്രദർശനത്തിന്റെ അറിയിപ്പുകൾ" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "ഓൺ-സ്ക്രീൻ പ്രദർശനത്തിന്റെ പ്രധാന സ്ക്രിപ്റ്റ്" + +#~ msgid "Splash Screen" +#~ msgstr "സ്പ്ളാഷ് സ്ക്രീൻ" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "സ്പ്ളാഷ് സ്‌ക്രീനിനുള്ള പ്രധാന സ്ക്രിപ്റ്റ്" + +#~ msgid "KRunner UI" +#~ msgstr "കെ റണ്ണർ സമ്പർക്കമുഖം" + +#~ msgid "Main Script KRunner" +#~ msgstr "കെ റണ്ണറിനുള്ള പ്രധാന സ്ക്രിപ്റ്റ്" + +#~ msgid "Window Decoration" +#~ msgstr "ജാലകത്തിനായുള്ള അലങ്കാരങ്ങള്‍" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "ജാലക അലങ്കാരങ്ങൾക്കുള്ള പ്രധാന സ്ക്രിപ്റ്റ്" + +#~ msgid "Window Switcher" +#~ msgstr "ജാലകം മാറുക" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "ജാലകം മാറ്റുന്നതിനുള്ള പ്രധാന സ്ക്രിപ്റ്റ്" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "ഘടന രൂപീകരണം പൂർത്തിയാക്കുക" + +#~ msgid "Customize Layout..." +#~ msgstr "ഘടന ഇച്ഛാനുസൃതംരൂപപ്പെടുത്തുക..." + +#~ msgid "Fetching file type..." +#~ msgstr "ഫയല്‍ തരം ലഭ്യമാക്കുന്നു..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1 സാധ്യതകള്‍" diff --git a/po/mr/libplasma6.po b/po/mr/libplasma6.po new file mode 100644 index 0000000..715017f --- /dev/null +++ b/po/mr/libplasma6.po @@ -0,0 +1,669 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Chetan Khona , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2013-03-09 14:27+0530\n" +"Last-Translator: Chetan Khona \n" +"Language-Team: Marathi \n" +"Language: mr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Generator: Lokalize 1.5\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "अपरिचीत" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "" + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "" + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "" + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "कार्यपध्दती संयोजना" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, fuzzy, kde-format +#| msgid "Unknown" +msgid "Unknown Applet" +msgstr "अपरिचीत" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, fuzzy, kde-format +#| msgid "Error loading QML file: %1" +msgid "Error loading QML file: %1 %2" +msgstr "QML फाईल दाखल करतेवेळी त्रुटी : %1" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgctxt "%1 is the name of the applet" +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "%1 संयोजना" + +#: plasmaquick/configview.cpp:232 +#, fuzzy, kde-format +#| msgctxt "%1 is the name of the applet" +#| msgid "%1 Settings" +msgid "%1 Settings" +msgstr "%1 संयोजना" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, fuzzy, kde-format +#| msgid "Plasma Package Manager" +msgid "Plasma Package" +msgstr "प्लाज्मा पॅकेज व्यवस्थापक" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, fuzzy, kde-format +#| msgid "Error: Installation of %1 failed: %2" +msgid "Package Installation Failed" +msgstr "त्रुटी : %1 ची प्रतिष्ठापना करण्यास अपयश: %2" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "" + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "किरकोळ" + +#~ msgid "Main Script File" +#~ msgstr "मुख्य स्क्रिप्ट फाईल" + +#~ msgid "Images" +#~ msgstr "प्रतिमा" + +#, fuzzy +#~| msgid "Images" +#~ msgid "Themed Images" +#~ msgstr "प्रतिमा" + +#~ msgid "Configuration Definitions" +#~ msgstr "संयोजना व्याख्या" + +#~ msgid "User Interface" +#~ msgstr "वापरकर्ता संवाद" + +#~ msgid "Data Files" +#~ msgstr "डेटा फाईल्स" + +#~ msgid "Executable Scripts" +#~ msgstr "एक्जीक्यूटेबल स्क्रिप्ट्स" + +#~ msgid "Translations" +#~ msgstr "भाषांतर" + +#~ msgid "Accessibility" +#~ msgstr "सुलभता" + +#~ msgid "Date and Time" +#~ msgstr "दिनांक व वेळ" + +#~ msgid "Education" +#~ msgstr "शिक्षण" + +#~ msgid "Examples" +#~ msgstr "उदाहरण" + +#~ msgid "File System" +#~ msgstr "फाईल प्रणाली" + +#~ msgid "Graphics" +#~ msgstr "आलेखीय" + +#~ msgid "Language" +#~ msgstr "भाषा" + +#~ msgid "Mapping" +#~ msgstr "जुळवणी" + +#~ msgid "Miscellaneous" +#~ msgstr "किरकोळ" + +#~ msgid "Multimedia" +#~ msgstr "मल्टीमीडिया" + +#~ msgid "Utilities" +#~ msgstr "उपकार्यक्रम" + +#, fuzzy +#~| msgid "Images" +#~ msgid "Preview Images" +#~ msgstr "प्रतिमा" + +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script for Login Manager" +#~ msgstr "मुख्य स्क्रिप्ट फाईल" + +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "मुख्य स्क्रिप्ट फाईल" + +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script for Lock Screen" +#~ msgstr "मुख्य स्क्रिप्ट फाईल" + +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script for User Switcher" +#~ msgstr "मुख्य स्क्रिप्ट फाईल" + +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script for Splash Screen" +#~ msgstr "मुख्य स्क्रिप्ट फाईल" + +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script KRunner" +#~ msgstr "मुख्य स्क्रिप्ट फाईल" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1 पर्याय" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "%1 संयोजना" + +#, fuzzy +#~| msgctxt "%1 is the name of the applet" +#~| msgid "%1 Settings" +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "%1 संयोजना" + +#~ msgid "Plasma Package Manager" +#~ msgstr "प्लाज्मा पॅकेज व्यवस्थापक" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr " येथे या पॅकेज साठी SHA1 hash तयार करा" + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "प्रतिष्ठापन करण्याकरिता किंवा काढून टाकण्याकरिता. हे सर्व वापरकर्त्यानी प्रतिष्ठापीत " +#~ "केलेल्या पॅकेजेस वर काम करते." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "पॅकेजचा प्रकार. उदा. शैली, वॉलपेपर, प्लाज्मोइड, डेटाइंजिन, रनर, मांडणी-नमूना ई." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr " येथे पॅकेज प्रतिष्ठापीत करा" + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "पॅकेजविषयी माहिती दर्शवा " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr " येथे पॅकेज अद्ययावत करा" + +#~ msgid "List installed packages" +#~ msgstr "प्रतिष्ठापन झालेल्या पॅकेजेसची यादी" + +#, fuzzy +#~| msgid "lists all known Package types that can be installed" +#~ msgid "List all known package types that can be installed" +#~ msgstr "प्रतिष्ठापन होऊ शकणाऱ्या सर्व पॅकेज प्रकारांची यादी करा" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr " या नावाचे पॅकेज काढून टाका" + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "पॅकेज रूट करिता परम मार्ग. जर हा पुरविला नाही, तर या KDE सत्राच्या प्रमाणित डेटा " +#~ "संचयीका शोधल्या जातील." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "%1 करिता पॅकेज hash तयार करण्यास अपयश" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "%1 येथील पॅकेजचे SHA1 hash : '%2'" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "वॉलपेपर" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "प्लाज्मोइड" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "पॅकेज" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "शैली" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "डेटाइंजिन" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "रनर" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "वॉलपेपर प्लगइन" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "मांडणी-नमूना" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "के-विन परिणाम" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "चौकट बदल" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "के-विन स्क्रिप्ट" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "%1 या पॅकेज प्रकारासाठी योग्य प्रतिष्ठापना कार्यक्रम सापडला नाही" + +#~ msgid "Listing service types: %1" +#~ msgstr "सेवा प्रकारांची यादी करत आहे : %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "त्रुटी : %1 हे प्लगइन प्रतिष्ठापीत झालेले नाही." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "प्रतिष्ठापन, काढून टाका, अद्ययावत करा किंवा यादी यापैकी एकाची गरज आहे." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "त्रुटी : प्लगइन मेटाडेटा सापडत नाही: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "पॅकेजची माहिती दर्शवित आहे : %1" + +#~ msgid " Name : %1" +#~ msgstr " नाव : %1" + +#~ msgid " Comment : %1" +#~ msgstr " टीप : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " प्लगइन : %1" + +#~ msgid " Author : %1" +#~ msgstr " लेखक : %1" + +#~ msgid " Path : %1" +#~ msgstr " मार्ग : %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "पॅकेजरूट व जागतिक पर्याय यांचा मतभेद आहे. कृपया फक्त एक निवडा." + +#~ msgid "Addon Name" +#~ msgstr "अधिक नाव" + +#~ msgid "Service Type" +#~ msgstr "सेवा प्रकार" + +#~ msgid "Path" +#~ msgstr "मार्ग" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "या साधनाने प्रतिष्ठापीत करता येण्याजोगे पॅकेज प्रकार :" + +#~ msgid "Built in:" +#~ msgstr "अंतर्भूत :" + +#, fuzzy +#~| msgid "Data Files" +#~ msgid "DataEngine" +#~ msgstr "डेटा फाईल्स" + +#~ msgid "Layout Template" +#~ msgstr "मांडणी नमूना" + +#~ msgid "Package" +#~ msgstr "पॅकेज" + +#~ msgid "Plasmoid" +#~ msgstr "प्लाज्मोइड" + +#~ msgid "Runner" +#~ msgstr "रनर" + +#~ msgid "Theme" +#~ msgstr "शैली" + +#~ msgid "Wallpaper Images" +#~ msgstr "वॉलपेपर प्रतिमा" + +#~ msgid "KWin Effect" +#~ msgstr "के-विन परिणाम" + +#~ msgid "KWin Window Switcher" +#~ msgstr "के-विन चौकट बदल" + +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "KWin Script" +#~ msgstr "मुख्य स्क्रिप्ट फाईल" + +#~ msgid "Provided by plugins:" +#~ msgstr "प्लगइनने पुरविलेले :" + +#~ msgid "Provided by .desktop files:" +#~ msgstr ".desktop फाईल्सने पुरविलेले :" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "यशस्वीरित्या अद्ययावत केले %1" + +#~ msgid "Successfully installed %1" +#~ msgstr "%1 हे यशस्वीरित्या प्रतिष्ठापीत केले" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "त्रुटी : %1 ची प्रतिष्ठापना करण्यास अपयश: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "पॅकेज या फाईल वरून अद्ययावत करत आहे : %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "यशस्वीरित्या अप्रतिष्ठापीत केले %1" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "त्रुटी : %1 ची अप्रतिष्ठापना करण्यास अपयश: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "%1 या पॅकेज प्रकारासाठी प्रतिष्ठापना कार्यक्रम लोड होऊ शकला नाही. ही त्रुटी होती : " +#~ "%2" + +#~ msgid "%1 already exists" +#~ msgstr "%1 आधीपासूनच अस्तित्वात आहे." + +#~ msgid "%1 does not exist" +#~ msgstr "%1 अस्तित्वात नाही." + +#~ msgid "Unnamed" +#~ msgstr "निनावी" + +#~ msgid "Panel" +#~ msgstr "पटल" diff --git a/po/nb/libplasma6.po b/po/nb/libplasma6.po new file mode 100644 index 0000000..a89472c --- /dev/null +++ b/po/nb/libplasma6.po @@ -0,0 +1,316 @@ +# Translation of libplasma6 to Norwegian Bokmål +# +# Bjørn Steensrud , 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015. +# Øystein Steffensen-Alværvik , 2018. +msgid "" +msgstr "" +"Project-Id-Version: plasmapkg\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-03-09 12:43+0100\n" +"Last-Translator: Karl Ove Hufthammer \n" +"Language-Team: Norwegian Bokmål \n" +"Language: nb\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 23.08.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Ukjent" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Aktiver elementet %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Sett opp «%1» …" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Lås elementer" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Lås opp elementer" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Om et mellomlager på disk skal opprettes for temaet." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Maksimal størrelse for tema-mellomlager på disk i kilobyte. Merk at disse " +"filene har mye tomrom, så maksimal størrelse blir kanskje ikke brukt. Det er " +"derfor ofte ganske trygt å oppgi stor størrelse." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Skjermelement fjernet" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Elementet «%1» er tatt bort." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panel fjernet" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Et panel er tatt bort." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Skrivebord tatt bort" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Et skrivebord er tatt bort." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Angre" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Elementinnstillinger" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Fjern dette elementet" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Fjern dette panelet" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Fjern denne aktiviteten" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Aktivitetsinnstillinger" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Fant ikke den etterspurte komponenten: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Feil ved lasting av miniprogram: pakke finnes ikke: %1" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +msgid "%1 — %2 Settings" +msgstr "%1-innstillinger" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1-innstillinger" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Installer" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Elementer" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Bakgrunnsbilde" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "" diff --git a/po/nds/libplasma6.po b/po/nds/libplasma6.po new file mode 100644 index 0000000..c9dc085 --- /dev/null +++ b/po/nds/libplasma6.po @@ -0,0 +1,1020 @@ +# Translation of plasmapkg.po to Low Saxon +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Sönke Dibbern , 2008, 2009, 2014. +# Manfred Wiese , 2009, 2010, 2011, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: plasmapkg\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2014-08-13 22:05+0200\n" +"Last-Translator: Sönke Dibbern \n" +"Language-Team: Low Saxon \n" +"Language: nds\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Nich begäng" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Lüttprogramm „%1“ anmaken" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, fuzzy, kde-format +#| msgctxt "@title:window %1 is the name of the containment" +#| msgid "Remove %1" +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "„%1“ wegmaken" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Lüttprogrammen afsluten" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Lüttprogrammen opsluten" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "" +"Gifft an, wat för't Muster en Twischenspieker op de Fastplaat bruukt warrt." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"De Hööchstgrött vun den Muster-Twischenspieker op de Fastplaat in Kilobytes. " +"Disse Dateien sünd verdeelt Dateien, ehr Hööchstgrott warrt villicht gor " +"nich bruukt. En höger Grött is dorüm faken ok seker." + +#: plasma/private/applet_p.cpp:119 +#, fuzzy, kde-format +#| msgid "Alternatives..." +msgid "Show Alternatives..." +msgstr "Alternativen..." + +#: plasma/private/applet_p.cpp:232 +#, fuzzy, kde-format +#| msgid "Widgets explorer UI" +msgid "Widget Removed" +msgstr "Lüttprogrammkieker-Böversiet" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "" + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "" + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "" + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Lüttprogramm-Instellen" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Dit Lüttprogramm wegmaken" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Dit Paneel wegmaken" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Disse Aktiviteet wegmaken" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Aktiviteteninstellen" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Anfraagt Komponent lett sik nich finnen: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, fuzzy, kde-format +#| msgid "Unknown" +msgid "Unknown Applet" +msgstr "Nich begäng" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, fuzzy, kde-format +#| msgid "Error loading QML file: %1" +msgid "Error loading QML file: %1 %2" +msgstr "Fehler bi't Laden vun en QML-Datei: %1" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package inexistent. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Fehler bi't Laden vun en Lüttprogramm: Dat gifft dat Paket nich. %1" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "%1-Instellen" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1-Instellen" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, fuzzy, kde-format +#| msgid "Plasma Package Manager" +msgid "Plasma Package" +msgstr "Pleger för Plasma-Paketen" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, fuzzy, kde-format +#| msgid "Script initialization failed" +msgid "Package Installation Failed" +msgstr "Torechtmaken vun't Skript is fehlslaan" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Lüttprogrammen" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, fuzzy, kde-format +#| msgid "Icon" +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Lüttbild" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Achtergrundbild" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "" + +#~ msgid "Add Widgets..." +#~ msgstr "Lüttprogrammen tofögen..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "" +#~ "Dat Paket „%1“, dat noot deit för't Lüttprogramm „%2“, lett sik nich " +#~ "opmaken." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Na't Apenmaken vun en Lüttprogramm in't Nettwark kannst Du dor vun en " +#~ "anner Reekner ut op togriepen." + +#~ msgid "Share this widget on the network" +#~ msgstr "Dit Lüttprogramm in't Nettwark apenmaken" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Jan un Allemann den Togriep op dit Lüttprogramm verlöven" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Leeg oder keen Deenst, keen Akschonen lett sik utföhren." + +#, fuzzy +#~| msgid "The %2 widget did not define which ScriptEngine to use." +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "" +#~ "Dat Lüttprogramm „%2“ hett den Skriptkarn, de bruukt warrn schall, nich " +#~ "angeven." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Anner Saken" + +#~ msgid "Main Script File" +#~ msgstr "Hööft-Skriptdatei" + +#~ msgid "Images" +#~ msgstr "Biller" + +#~ msgid "Themed Images" +#~ msgstr "Musterbiller" + +#~ msgid "Configuration Definitions" +#~ msgstr "Instellen-Daten" + +#~ msgid "User Interface" +#~ msgstr "Böversiet" + +#~ msgid "Data Files" +#~ msgstr "Datendateien" + +#~ msgid "Executable Scripts" +#~ msgstr "Utföhrbor Skripten" + +#, fuzzy +#~| msgid "Screenlocker" +#~ msgid "Screenshot" +#~ msgstr "Schirmafsluten" + +#~ msgid "Translations" +#~ msgstr "Översetten" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Modell vun Instellen-Böversietsieden" + +#~ msgid "Configuration XML file" +#~ msgstr "XML-Instellendatei" + +#~ msgid "Images for dialogs" +#~ msgstr "Biller för Dialogen" + +#~ msgid "Generic dialog background" +#~ msgstr "Normaal Dialoogachtergrund" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Muster för den Afmelldialoog" + +#~ msgid "Wallpaper packages" +#~ msgstr "Achtergrundbiller-Paketen" + +#~ msgid "Images for widgets" +#~ msgstr "Biller för Lüttprogrammen" + +#~ msgid "Background image for widgets" +#~ msgstr "Achtergrundbild för Lüttprogrammen" + +#~ msgid "Analog clock face" +#~ msgstr "Analoogklock-Utsehn" + +#~ msgid "Background image for panels" +#~ msgstr "Achtergrundbild för Paneels" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Achtergrund för graafsch Lüttprogrammen" + +#~ msgid "Background image for tooltips" +#~ msgstr "Achtergrundbild för Kortinfos" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Decken Biller för Dialogen" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Decken normaal Dialoogachtergrund" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Decken Muster för den Afmelldialoog" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Decken Biller för Lüttprogrammen" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Decken Achtergrundbild för Paneels" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Decken Achtergrundbild för Kortinfos" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme-Instellendatei" + +#~ msgid "Service Descriptions" +#~ msgstr "Deenstbeschrieven" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "De %1-Skriptkarn för't Lüttprogramm „%2“ lett sik nich opstellen." + +#~ msgid "Script initialization failed" +#~ msgstr "Torechtmaken vun't Skript is fehlslaan" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "Afbreken" + +#~ msgid "Run the Associated Application" +#~ msgstr "Dat tohören Programm utföhren" + +#~ msgid "Open with %1" +#~ msgstr "Mit %1 opmaken" + +#~ msgid "Accessibility" +#~ msgstr "Toganghülp" + +#~ msgid "Application Launchers" +#~ msgstr "Programmopropers" + +#~ msgid "Astronomy" +#~ msgstr "Astronomie" + +#~ msgid "Date and Time" +#~ msgstr "Datum un Tiet" + +#~ msgid "Development Tools" +#~ msgstr "Utwickeln-Warktüüch" + +#~ msgid "Education" +#~ msgstr "Lehren" + +#~ msgid "Environment and Weather" +#~ msgstr "Ümwelt un Weder" + +#~ msgid "Examples" +#~ msgstr "Bispelen" + +#~ msgid "File System" +#~ msgstr "Dateisysteem" + +#~ msgid "Fun and Games" +#~ msgstr "Högen un Spelen" + +#~ msgid "Graphics" +#~ msgstr "Grafik" + +#~ msgid "Language" +#~ msgstr "Spraak" + +#~ msgid "Mapping" +#~ msgstr "Koorten" + +#~ msgid "Miscellaneous" +#~ msgstr "Anner Saken" + +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + +#~ msgid "Online Services" +#~ msgstr "Tokoppel-Deensten" + +#~ msgid "Productivity" +#~ msgstr "Produzeren" + +#~ msgid "System Information" +#~ msgstr "Systeem-Informatschonen" + +#~ msgid "Utilities" +#~ msgstr "Warktüüch" + +#~ msgid "Windows and Tasks" +#~ msgstr "Finstern un Programmen" + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Standardinstellen för't Muster usw." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Klöörschema för Programmen" + +#~ msgid "Preview Images" +#~ msgstr "Vöransichtbiller" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Vöransicht vun den Anmellpleger" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Vöransicht för den Afsluutschirm" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Vöransicht för de Brukerwesseln" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Vöransicht för de Schriefdischwesseln" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Vöransicht för den Startschirm" + +#~ msgid "Preview for KRunner" +#~ msgstr "Vöransicht för KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Vöransicht för de Finsterdekoreren" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Vöransicht för de Finsterwesseln" + +#~ msgid "Login Manager" +#~ msgstr "Anmellpleger" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Hööftskript för den Anmellpleger" + +#~ msgid "Logout Dialog" +#~ msgstr "Afmelldialoog" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Hööftskript för den Afmelldialoog" + +#~ msgid "Screenlocker" +#~ msgstr "Schirmafsluten" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Hööftskript för den Afsluutschirm" + +#~ msgid "UI for fast user switching" +#~ msgstr "Böversiet för't gaue Brukerwesseln" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Hööftskript för de Brukerwesseln" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Schriefdischwesseln" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Hööftskript för de Schriefdischwesseln" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Op-Schirm-Dorstellbescheden" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Hööftskript för Op-Schirm-Dorstellbescheden" + +#~ msgid "Splash Screen" +#~ msgstr "Startschirm" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Hööftskript för den Startschirm" + +#~ msgid "KRunner UI" +#~ msgstr "KRunner-Böversiet" + +#~ msgid "Main Script KRunner" +#~ msgstr "KRunner-Hööftskript" + +#~ msgid "Window Decoration" +#~ msgstr "Finsterdekoreren" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Hööftskript för Finsterdekoreren" + +#~ msgid "Window Switcher" +#~ msgstr "Finsterwesseln" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Hööftskript för de Finsterwesseln" + +#~ msgid "Fetching file type..." +#~ msgstr "Dateityp warrt haalt..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1-Optschonen" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "„%1“ wegmaken" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "%1-Instellen" + +#, fuzzy +#~| msgctxt "%1 is the name of the applet" +#~| msgid "%1 Settings" +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "%1-Instellen" + +#~ msgid "Low color images for dialogs" +#~ msgstr "Sietklöör-Biller för Dialogen" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Normaal Sietklöör-Achtergrund för Dialogen" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Sietklöör-Muster för den Afmelldialoog" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Sietklöör-Achtergrundbild för Lüttprogrammen" + +#~ msgid "Low color analog clock face" +#~ msgstr "Sietklöör-Utsehn för de Analoogklock" + +#~ msgid "Low color background image for panels" +#~ msgstr "Sietklöör-Achtergrundbild för Paneels" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Sietklöör-Achtergrund för graafsch Lüttprogrammen" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Sietklöör-Achtergrundbild för Kortinfos" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Pleger för Plasma-Paketen" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "" +#~ "De SHA1-Pröövsumm för dat Paket ünner den Padd lett sik nich " +#~ "opstellen." + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Bi't Installeren un Wegmaken gellt dat för Paketen, de för all Brukers " +#~ "installeert sünd" + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "De Typ vun't Paket, a.B. Muster, Achtergrundbild, Plasma-Lüttprogramm, " +#~ "Datenkarn, Dreger, Anornen-Vörlaag usw." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Dat Paket ünner den Padd installeren" + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Informatschonen to Paket wiesen" + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Dat Paket ünner den Padd opfrischen" + +#~ msgid "List installed packages" +#~ msgstr "Installeert Paketen oplisten" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "All begäng Pakettypen wiesen, de sik installeren laat." + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Dat Paket mit den Naam wegmaken" + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Afsoluut Padd na de Paketwörtel. Wenn nich angeven, warrt de Standard-" +#~ "Datenornern för dissen KDE-Törn dörkeken." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Pröövsumm för Paket \"%1\" lett sik nich opstellen." + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "SHA1-Pröövsumm för dat Paket ünner %1: %2" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "Achtergrundbild" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "Plasma-Lüttprogramm" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "Paket" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "Muster" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "Datenkarn" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "Dreger" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "Achtergrundbild-Moduul" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "Utsehn" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "Konsool" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "Anornen-Vörlaag" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "KWin-Effekt" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "Finsterwesseln" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "KWin-Skript" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "Keen passen Installeerprogramm för Pakettyp \"%1\" funnen" + +#~ msgid "Listing service types: %1" +#~ msgstr "Deensttypen oplisten: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Fehler: Moduul \"%1\" is nich installeert." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Du muttst wat installeren, wegmaken, opfrischen oder oplisten." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Fehler: Moduul-Metadaten laat sik nich finnen: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Informatschonen wiesen för Paket: %1" + +#~ msgid " Name : %1" +#~ msgstr " Naam: %1" + +#~ msgid " Comment : %1" +#~ msgstr " Kommentar: %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Moduul: %1" + +#~ msgid " Author : %1" +#~ msgstr " Autor: %1" + +#~ msgid " Path : %1" +#~ msgstr " Padd: %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "De Optschonen \"packageroot\" un \"global\" passt nich tosamen. Bruuk dor " +#~ "bitte bloots een vun." + +#~ msgid "Addon Name" +#~ msgstr "Verwiedern-Naam" + +#~ msgid "Service Type" +#~ msgstr "Deenst-Typ" + +#~ msgid "Path" +#~ msgstr "Padd" + +#~ msgid "Type Argument" +#~ msgstr "Typ-Argument" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Pakettypen, de sik mit dit Warktüüch installeren laat:" + +#~ msgid "Built in:" +#~ msgstr "Inbuut:" + +#~ msgid "DataEngine" +#~ msgstr "Datenkarn" + +#~ msgid "Layout Template" +#~ msgstr "Anornen-Vörlaag" + +#~ msgid "Look and Feel" +#~ msgstr "Utsehn un Bedenen" + +#~ msgid "Package" +#~ msgstr "Paket" + +#~ msgid "Plasmoid" +#~ msgstr "Plasma-Lüttprogramm" + +#~ msgid "Runner" +#~ msgstr "Dreger" + +#~ msgid "Shell" +#~ msgstr "Konsool" + +#~ msgid "Theme" +#~ msgstr "Muster" + +#~ msgid "Wallpaper Images" +#~ msgstr "Achtergrundbiller" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Animeert Achtergrundbild" + +#~ msgid "KWin Effect" +#~ msgstr "KWin-Effekt" + +#~ msgid "KWin Window Switcher" +#~ msgstr "KWin-Finsterwesseln" + +#~ msgid "KWin Script" +#~ msgstr "KWin-Skript" + +#~ msgid "Provided by plugins:" +#~ msgstr "Vun Modulen praatstellt:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Vun \".desktop\"-Dateien praatstellt:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "%1 mit Spood opgradeert" + +#~ msgid "Successfully installed %1" +#~ msgstr "%1 mit Spood installeert" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Fehler: Installeren vun \"%1\" fehlslaan: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Paket opgraderen ut Datei: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "%1 mit Spood deinstalleert" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Fehler: Deinstalleren vun \"%1\" is fehlslaan: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Dat Installeerprogramm för den Pakettyp \"%1\" lett sik nich laden. De " +#~ "torüchgeven Fehler weer: %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Wörtelverteken vun't Paket lett sik nich opstellen: %1" + +#~ msgid "No such file: %1" +#~ msgstr "Datei nich funnen: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "" +#~ "De Paketdatei lett sik nich opmaken, dat Archievformaat warrt nich " +#~ "ünnerstütt: %1 %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "De Paketdatei lett sik nich opmaken: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "Keen Metadaten-Datein binnen't Paket: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "Naam vun't Paketmoduul nich angeven: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "Paketmoduul-Naam „%1“ bargt leeg Tekens" + +#~ msgid "%1 already exists" +#~ msgstr "„%1“ gifft dat al" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Paket lett sik nich na't Teel verschuven: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Paket lett sik nich na't Teel koperen: %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Lokaal Deenstorner lett sik nich opstellen: %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "Paket lett sik nich as Deenst inmellen (is nich jümmers en swoor Fehler): " +#~ "%1" + +#~ msgid "%1 does not exist" +#~ msgstr "„%1“ gifft dat nich." + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Paket lett sik nich wegdoon ut: %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "Wullt Du „%1“ redig wegmaken?" + +#~ msgid "Applets furniture" +#~ msgstr "Lüttprogramm-Möbelmang" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "Kieker-Böversiet för't Tofögen vun Lüttprogrammen" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "Böversiet för de Ansichten, de Gelatsen wiest" + +#~ msgid "Default layout file" +#~ msgstr "Standard-Böversietdatei" + +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "Standardmoduul för Gelatsen, Gelaatsakschonen usw." + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "" +#~ "Fehlermellen de wiest warrt, wenn sik en Lüttprogramm nich laden lett" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "QML-Komponent, de en Lüttprogramm binnen en Opduker wiest" + +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Drang Dorstellen för en Lüttprogramm, dat binnen en Opduker tosamenfooldt " +#~ "is, a.B. as en Lüttbild. Lüttprogrammen köönt disse Komponent övergahn." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "QML-Komponent för den Instellendialoog vun Lüttprogrammen" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "QML-Komponent för den Instellendialoog vun Gelatsen" + +#~ msgid "Panel configuration UI" +#~ msgstr "Paneelinstellen-Böversiet" + +#, fuzzy +#~| msgid "QML component for the configuration dialog for applets" +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "QML-Komponent för den Instellendialoog vun Lüttprogrammen" + +#~ msgid "Theme preview thumbnail" +#~ msgstr "Muster-Vöransichtbild" + +#~ msgid "Ok" +#~ msgstr "OK" + +#~ msgid "search term" +#~ msgstr "Söökutdruck" diff --git a/po/nl/libplasma6.po b/po/nl/libplasma6.po new file mode 100644 index 0000000..2e726e2 --- /dev/null +++ b/po/nl/libplasma6.po @@ -0,0 +1,1084 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# SPDX-FileCopyrightText: 2014, 2015, 2016, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Freek de Kruijf +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-23 12:10+0200\n" +"Last-Translator: Freek de Kruijf \n" +"Language-Team: \n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 24.05.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Meer acties" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Invouwen" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Uitvouwen" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Wachtwoord" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Zoeken…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Zoeken" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Zoeken wissen" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Onbekend" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Widget %1 activeren" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "%1 verwijderen" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Bewerkingsmodus ingaan" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "%1 configureren..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Widgets vergrendelen" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Widgets ontgrendelen" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Bewerkingsmodus sluiten" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Of al dan niet een cache voor het thema op schijf moet worden gemaakt." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"De maximale grootte van de de cache voor het thema op schijf in kilobytes. " +"Merk op dat deze bestanden sparse-bestanden zijn, zodat de maximale grootte " +"niet in gebruikt hoeft te zijn. Instellen van een grotere is daarom vaak " +"behoorlijk veilig." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Alternatieven tonen..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "widget is verwijderd" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Het widget \"%1\" is verwijderd." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Paneel is verwijderd." + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Een paneel is verwijderd." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Bureaublad is verwijderd." + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Een bureaublad is verwijderd." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Ongedaan maken" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Widget-instellingen" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Dit widget verwijderen" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Dit paneel verwijderen" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Deze activiteit verwijderen" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Instellingen voor activiteiten" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Widgets toevoegen of beheren…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Kon gevraagd component niet vinden: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Het hoofditem van %1 moet van het type ContainmentItem zijn" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Het hoofditem van %1 moet van het type PlasmoidItem zijn" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Onbekend applet" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Dit widget is geschreven voor een onbekende oudere versie van Plasma en is " +"niet compatibel met Plasma %1. Neem contact op met de auteur van het widget " +"voor een bijgewerkte versie." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 is niet compatibel met Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Dit widget is geschreven voor Plasma %1 en is niet compatibel met Plasma %2. " +"Neem contact op met de auteur van het widget voor een bijgewerkte versie." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Dit widget is geschreven voor Plasma %1 en is niet compatibel met Plasma %2. " +"Werk Plasma bij om het widget te kunnen gebruiken." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Sorry! Er was een fout bij laden van %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Fout bij het laden van QML-bestand: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Fout bij laden van Applet: pakket %1 bestaat niet." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 - %2 instellingen" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 instellingen" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma-pakket" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Installeren" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Pakketinstallatie is mislukt" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Het pakket dat u zojuist liet vallen is ongeldig." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Widgets" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "%1 toevoegen" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Pictogram toevoegen" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Achtergrondafbeelding" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "%1 instellen" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Inhoud vervallen" + +#~ msgid "Add Widgets..." +#~ msgstr "Widgets toevoegen..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "" +#~ "Kon het pakket %1 niet openen. Dit pakket is nodig voor de widget %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Delen van een widget in het netwerk staat u toe om toegang te hebben tot " +#~ "dit widget vanaf een andere computer zoals een afstandsbediening." + +#~ msgid "Share this widget on the network" +#~ msgstr "Deel dit widget in het netwerk" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Sta iedereen vrij toe om toegang te hebben tot dit widget" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "" +#~ "Ongeldige (null) dienst. Er kan geen enkele operatie worden uitgevoerd." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Het widget %1 definieerde niet welke ScriptEngine te gebruiken." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Diversen" + +#~ msgid "Main Script File" +#~ msgstr "Hoofd-scriptbestand" + +#~ msgid "Tests" +#~ msgstr "Testen" + +#~ msgid "Images" +#~ msgstr "Afbeeldingen" + +#~ msgid "Themed Images" +#~ msgstr "Afbeeldingen met thema" + +#~ msgid "Configuration Definitions" +#~ msgstr "Configuratiedefinities" + +#~ msgid "User Interface" +#~ msgstr "Gebruikersinterface" + +#~ msgid "Data Files" +#~ msgstr "Gegevensbestanden" + +#~ msgid "Executable Scripts" +#~ msgstr "Uitvoerbare scripts" + +#~ msgid "Screenshot" +#~ msgstr "Schermafdruk" + +#~ msgid "Translations" +#~ msgstr "Vertalingen" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Instellingen van het paginamodel van de UI" + +#~ msgid "Configuration XML file" +#~ msgstr "XML-configuratiebestand" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Aangepaste vergroter voor compacte applets" + +#~ msgid "Images for dialogs" +#~ msgstr "Afbeeldingen voor dialogen" + +#~ msgid "Generic dialog background" +#~ msgstr "Generieke dialoogachtergrond" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Thema voor de afmelddialoog" + +#~ msgid "Wallpaper packages" +#~ msgstr "Pakketten met achtergrondafbeeldingen" + +#~ msgid "Images for widgets" +#~ msgstr "Afbeeldingen voor widgets" + +#~ msgid "Background image for widgets" +#~ msgstr "Achtergrondafbeelding voor widgets" + +#~ msgid "Analog clock face" +#~ msgstr "Analoge klok" + +#~ msgid "Background image for panels" +#~ msgstr "Achtergrondafbeelding voor panelen" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Achtergrond voor grafische elementen" + +#~ msgid "Background image for tooltips" +#~ msgstr "Achtergrondafbeelding voor tekstballonnen" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Ondoorzichtige afbeeldingen voor dialogen" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Achtergrond voor generieke ondoorzichtige dialoog" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Ondoorzichtig thema voor de afmelddialoog" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Ondoorzichtige afbeeldingen voor widgets" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Ondoorzichtige achtergrondafbeelding voor panelen" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Ondoorzichtige achtergrondafbeelding voor tekstballonnen" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme-configuratiebestand" + +#~ msgid "Service Descriptions" +#~ msgstr "Service-beschrijvingen" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Kon geen %1-ScriptEngine aanmaken voor de widget %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Script-initialisatie is mislukt" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Vakantiedagen" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Gebeurtenissen" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Taken" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Overig" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Vorige maand" + +#~ msgid "Previous Year" +#~ msgstr "Vorig jaar" + +#~ msgid "Previous Decade" +#~ msgstr "Vorige decade" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Vandaag" + +#~ msgid "Reset calendar to today" +#~ msgstr "Zet de agenda terug op vandaag" + +#~ msgid "Next Month" +#~ msgstr "Volgende maand" + +#~ msgid "Next Year" +#~ msgstr "Volgend jaar" + +#~ msgid "Next Decade" +#~ msgstr "Volgende decade" + +#~ msgid "Days" +#~ msgstr "Dagen" + +#~ msgid "Months" +#~ msgstr "Maanden" + +#~ msgid "Years" +#~ msgstr "Jaren" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "Annuleren" + +#~ msgid "Run the Associated Application" +#~ msgstr "Draai het geassocieerde programma" + +#~ msgid "Open with %1" +#~ msgstr "Openen met %1" + +#~ msgid "Accessibility" +#~ msgstr "Toegankelijkheid" + +#~ msgid "Application Launchers" +#~ msgstr "Programmastarters" + +#~ msgid "Astronomy" +#~ msgstr "Astronomie" + +#~ msgid "Date and Time" +#~ msgstr "Datum en tijd" + +#~ msgid "Development Tools" +#~ msgstr "Ontwikkelhulpmiddelen" + +#~ msgid "Education" +#~ msgstr "Onderwijs" + +#~ msgid "Environment and Weather" +#~ msgstr "Milieu en weer" + +#~ msgid "Examples" +#~ msgstr "Voorbeelden" + +#~ msgid "File System" +#~ msgstr "Bestandssysteem" + +#~ msgid "Fun and Games" +#~ msgstr "Plezier en spellen" + +#~ msgid "Graphics" +#~ msgstr "Grafisch" + +#~ msgid "Language" +#~ msgstr "Taal" + +#~ msgid "Mapping" +#~ msgstr "Overeenkomsten" + +#~ msgid "Miscellaneous" +#~ msgstr "Diversen" + +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + +#~ msgid "Online Services" +#~ msgstr "Online-diensten" + +#~ msgid "Productivity" +#~ msgstr "Productiviteit" + +#~ msgid "System Information" +#~ msgstr "Systeeminformatie" + +#~ msgid "Utilities" +#~ msgstr "Hulpmiddelen" + +#~ msgid "Windows and Tasks" +#~ msgstr "Vensters en taken" + +#~ msgid "Clipboard" +#~ msgstr "Klembord" + +#~ msgid "Tasks" +#~ msgstr "Taken" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "%1 bewerken..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Standaard instellingen voor het thema, etc." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Te gebruiken kleurenschema voor toepassingen." + +#~ msgid "Preview Images" +#~ msgstr "Voorbeeldafbeeldingen" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Voorbeeld van het aanmeldscherm" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Voorbeeld van het vergrendelingsscherm" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Voorbeeld van het wisselen van gebruiker" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Voorbeeld van het virtueel bureaublad omschakelaar" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Voorbeeld van het opstartscherm" + +#~ msgid "Preview for KRunner" +#~ msgstr "Voorbeeld van KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Voorbeeld van de vensterdecoraties" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Voorbeeld van vensterwisselaar" + +#~ msgid "Login Manager" +#~ msgstr "Aanmeldscherm" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Hoofdscript van aanmeldbeheerder" + +#~ msgid "Logout Dialog" +#~ msgstr "Afmelddialoog" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Hoofdscript voor de afmelddialoog" + +#~ msgid "Screenlocker" +#~ msgstr "Schermvergrendelaar" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Hoofdscript van het vergrendelingsscherm" + +#~ msgid "UI for fast user switching" +#~ msgstr "UI voor snel wisselen van gebruiker" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Hoofdscript van het wisselen van gebruiker" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Virtueel bureaublad omschakelaar" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Hoofdscript van de virtueel bureaublad omschakelaar" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Op het scherm te tonen meldingen" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Hoofdscript van op het scherm te tonen meldingen" + +#~ msgid "Splash Screen" +#~ msgstr "Opstartscherm" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Hoofdscript van het opstartscherm" + +#~ msgid "KRunner UI" +#~ msgstr "KRunner UI" + +#~ msgid "Main Script KRunner" +#~ msgstr "Hoofd-script van KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Vensterdecoratie" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Hoofdscript van vensterdecoratie" + +#~ msgid "Window Switcher" +#~ msgstr "Vensterwisselaar" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Hoofdscript van het wisselen van venster" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Aanpassen van opmaak afmaken" + +#~ msgid "Customize Layout..." +#~ msgstr "Opmaak aanpassen..." + +#~ msgid "Fetching file type..." +#~ msgstr "Bestandstype ophalen..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1 opties" + +#~ msgid "SVG scalable preview" +#~ msgstr "SVG schaalbaar voorbeeld" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Dit %1 verwijderen" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "%1 instellingen" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Instellingen van %1..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Lage-kleuren-afbeeldingen voor dialogen" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Lage-kleuren-achtergrond voor generiek dialoog" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Lage-kleuren-thema voor de afmelddialoog" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Lage-kleuren-achtergrondafbeelding voor widgets" + +#~ msgid "Low color analog clock face" +#~ msgstr "Lage-kleuren analoge klok" + +#~ msgid "Low color background image for panels" +#~ msgstr "Lage-kleuren-achtergrondafbeelding voor panelen" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Lage-kleuren-achtergrond voor grafische beeldelementen" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Lage-kleuren-achtergrondafbeelding voor tekstballonnen" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Plasma-pakketbeheerder" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Een SHA1-hash genereren voor het pakket in " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Voor installeren of verwijderen, van toepassing op pakketten die " +#~ "beschikbaar gemaakt zijn voor alle gebruikers." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Het type pakket; zoals thema, bureaubladachtergrond, plasmoid, " +#~ "gegevensengine, starter, indelingssjabloon, etc." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Installeer het pakket op " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Informatie voor pakket tonen" + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Het pakket in bijwerken" + +#~ msgid "List installed packages" +#~ msgstr "Geïnstalleerde pakketten tonen" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "Toont alle bekende typen pakketten die geïnstalleerd kunnen worden" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Verwijder het pakket genaamd " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Absoluut pad naar de hoofdmap van het pakket. Indien niet opgegeven " +#~ "zullen de standaard gegevensmappen voor deze KDE-sessie worden doorzocht." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Genereren van een pakket-hash voor %1 is mislukt" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "SHA1-hash voor het pakket op %1: '%2'" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "bureaubladachtergrond" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "pakket" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "thema" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "gegevensengine" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "starter" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "bureaubladachtergrond-plugin" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "look-and-feel" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "shell" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "indelingssjabloon" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "kwineffect" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "vensteromschakelaar" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "kwinscript" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "Kon geen geschikte installeerder vinden voor pakket van het type %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "Servicetypen tonen: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Fout: plug-in %1 is niet geïnstalleerd." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "" +#~ "Eén van installeren, verwijderen, opwaarderen of weergeven is vereist." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Fout: kan de plug-in voor metadata niet vinden: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Informatie voor pakket wordt getoond: %1" + +#~ msgid " Name : %1" +#~ msgstr " Naam : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Toelichting : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Plug-in : %1" + +#~ msgid " Author : %1" +#~ msgstr " Auteur : %1" + +#~ msgid " Path : %1" +#~ msgstr " Pad : %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "De hoofdmap van het pakket en globale opties zijn met elkaar in conflict, " +#~ "slechts één selecteren." + +#~ msgid "Addon Name" +#~ msgstr "Addon-naam" + +#~ msgid "Service Type" +#~ msgstr "Type service" + +#~ msgid "Path" +#~ msgstr "Pad" + +#~ msgid "Type Argument" +#~ msgstr "Type argument" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Pakkettypen die met dit hulpmiddel zijn te installeren:" + +#~ msgid "Built in:" +#~ msgstr "Ingebouwd:" + +#~ msgid "DataEngine" +#~ msgstr "Gegevensengine" + +#~ msgid "Layout Template" +#~ msgstr "Indelingssjabloon" + +#~ msgid "Look and Feel" +#~ msgstr "Uiterlijk en gedrag" + +#~ msgid "Package" +#~ msgstr "Pakket" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoid" + +#~ msgid "Runner" +#~ msgstr "Starter" + +#~ msgid "Shell" +#~ msgstr "Shell" + +#~ msgid "Theme" +#~ msgstr "Thema" + +#~ msgid "Wallpaper Images" +#~ msgstr "Bureaubladachtergronden" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Bewegende achtergrondafbeelding" + +#~ msgid "KWin Effect" +#~ msgstr "KWin-effect" + +#~ msgid "KWin Window Switcher" +#~ msgstr "KWin-vensterwisselaar" + +#~ msgid "KWin Script" +#~ msgstr "KWin-script" + +#~ msgid "Provided by plugins:" +#~ msgstr "Door plug-ins geleverd:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Geleverd door .desktop-bestanden:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "%1 is met succes opgewaardeerd" + +#~ msgid "Successfully installed %1" +#~ msgstr "%1 met succes geïnstalleerd" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Fout: installatie van %1 is mislukt: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Pakket opwaarderen uit bestand: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Installatie van %1 met succes ongedaan gemaakt" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Fout: installatie van %1 ongedaan maken is mislukt: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Kon geen geschikte installeerder vinden voor pakket van het type %1. De " +#~ "foutmelding was: %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Kon de hoofdmap van het pakket niet aanmaken: %1" + +#~ msgid "No such file: %1" +#~ msgstr "Geen bestand: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "" +#~ "Kon bestand van pakket niet openen, niet ondersteund archiefformaat: %1 %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "Kon bestand van pakket niet openen: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "Geen bestand met metagegevens in pakket: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "Naam van plug-in van pakket niet gespecificeerd: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "Naam van plug-in %1 van pakket bevat ongeldige tekens" + +#~ msgid "%1 already exists" +#~ msgstr "%1 bestaat al" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Kon pakket niet naar zijn bestemming verplaatsen: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Kon pakket niet naar zijn bestemming kopiëren: %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Kon de lokale servicemap niet aanmaken: %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "Kon pakket niet als service registreren (dit is niet noodzakelijk " +#~ "fataal): %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 bestaat niet" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Kon pakket niet verwijderen uit: %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "Wilt u %1 verwijderen?" + +#~ msgid "Applets furniture" +#~ msgstr "Meubilair voor applets" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "Verkenner-UI voor toevoegen van widgets" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "Gebruikersinterface voor de weergave die containers zullen tonen" + +#~ msgid "Default layout file" +#~ msgstr "Bestand voor standaard indeling" + +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "Standaard plug-ins voor containers, containeracties, etc." + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "Getoonde foutmelding wanneer het laden van een applet mislukt" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "QML-component die een applet in een popup toont" + +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Compacte weergave van een applet wanneer ingevouwen in een popup, " +#~ "bijvoorbeeld als een pictogram. Applets kunnen over deze component heen " +#~ "gaan." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "QML-component voor de instellingendialoog voor applets" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "QML-component voor de instellingendialoog voor containers" + +#~ msgid "Panel configuration UI" +#~ msgstr "UI voor de configuratie van een paneel" + +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "QML-component voor het kiezen van aan alternatief applet" + +#~ msgid "" +#~ "A UI for writing, loading and running desktop scripts in the current live " +#~ "session" +#~ msgstr "" +#~ "Een UI voor schrijven, laden en uitvoeren van bureaubladscripts in de " +#~ "huidige actieve sessie" + +#~ msgid "Theme preview thumbnail" +#~ msgstr "Miniatuurvoorbeeld van thema" + +#~ msgid "Ok" +#~ msgstr "OK" diff --git a/po/nn/libplasma6.po b/po/nn/libplasma6.po new file mode 100644 index 0000000..2d6bfe6 --- /dev/null +++ b/po/nn/libplasma6.po @@ -0,0 +1,338 @@ +# Translation of libplasma6 to Norwegian Nynorsk +# +# Eirik U. Birkeland , 2008, 2009, 2010, 2011. +msgid "" +msgstr "" +"Project-Id-Version: plasmapkg\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-25 12:18+0200\n" +"Last-Translator: Karl Ove Hufthammer \n" +"Language-Team: Norwegian Nynorsk \n" +"Language: nn\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 24.11.70\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Fleire handlingar" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Fald saman" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Fald ut" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Passord" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Søk …" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Søk" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Tøm søkjefeltet" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Ukjend" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Start %1-elementet" + +# Eks.: +# Fjern panelet +# Fjern denne globale menyen +# +# Men viss det ikkje finst ei tilhøyrande oppføring i scripts/frameworks/ki18n5/skjermelement.pmap, vert det heller: +# Fjern «Panel» +# Fjern «Global meny» +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Fjern «%1»|/|Fjern $[pron %1] $[bunden %1]" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Start tilpassing" + +# Eks.: +# Set opp panelet +# Set opp den globale menyen +# +# Men viss det ikkje finst ei tilhøyrande oppføring i scripts/frameworks/ki18n5/skjermelement.pmap, vert det heller: +# Set opp «Panel» +# Set opp «Global meny» +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Set opp «%1» …|/|Set opp $[dobbelbest %1]$[bunden %1] …" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Lås elementa" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Lås opp elementa" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Avslutt tilpassing" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Om det skal lagast eit snøgglager på disken for temaet." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Maksstorleiken på snøgglageret for temaet i kilobyte. Merk at desse filene " +"er kompakte, så maksstorleiken vert gjerne ikkje brukt. Det er derfor ofte " +"trygt å bruka ein stor verdi her." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Vis alternativ …" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Skjermelement fjerna" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Skjermelementet «%1» vart fjerna." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panel fjerna" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Eit panel vart fjerna." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Skrivebord fjerna" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Eit skrivebord vart fjerna." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Angra" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Set opp element" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Fjern dette elementet" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Fjern dette panelet" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Fjern denne aktiviteten" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Aktivitetsoppsett" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Legg til eller juster element …" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Fann ikkje etterspurd komponent: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Rotelement til %1 må vera av typen ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Rotelement til %1 må vera av typen PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Ukjent element" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Dette skjermelementet er laga for ein eldre versjon av Plasma og er ikkje " +"kompatibelt med Plasma %1. Ta kontakt med utviklaren av skjerm­elementet for " +"å skaffa ein oppdatert versjon." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 er ikkje kompatibel med Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Dette skjermelementet er laga for Plasma versjon %1 og er ikkje kompatibelt " +"med Plasma %2. Ta kontakt med utviklaren av skjerm­elementet for å skaffa ein " +"oppdatert versjon." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Dette skjermelementet er laga for Plasma versjon %1 og er ikkje kompatibelt " +"med Plasma %2. Oppdater Plasma-versjonen din for å ta elementet i bruk." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Det oppstod dessverre ein feil ved lasting av %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Feil ved lasting av QML-fil: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Feil ved lasting av skjermelement: pakken %1 finst ikkje." + +# i18n("%1 — %2 Settings", itemTitle.toString(), applet.data()->title()) +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 – innstillingar for %2" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Set opp «%1»|/|Set opp $[dobbelbest %1]$[bunden %1]" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma-pakke" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Installer" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Feil ved pakkeinstallering" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Pakken du sleppte er ugyldig." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Skjermelement" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Legg til %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Legg til ikon" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Bakgrunnsbilete" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Set %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Innhald sleppt" diff --git a/po/pa/libplasma6.po b/po/pa/libplasma6.po new file mode 100644 index 0000000..2eb5998 --- /dev/null +++ b/po/pa/libplasma6.po @@ -0,0 +1,868 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# SPDX-FileCopyrightText: 2014, 2015, 2018, 2022, 2024 A S Alam +# Aman Alam , 2020. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-01-28 19:51-0600\n" +"Last-Translator: A S Alam \n" +"Language-Team: Punjabi \n" +"Language: pa\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 23.08.4\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "ਹੋਰ ਕਾਰਵਾਈਆਂ" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "ਸਮੇਟੋ" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "ਫੈਲਾਓ" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "ਪਾਸਵਰਡ" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "…ਖੋਜੋ" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "ਖੋਜੋ" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "ਖੋਜ ਮਿਟਾਓ" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "ਅਣਜਾਣ" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "%1 ਵਿਦਜੈਟ ਸਰਗਰਮ ਕਰੋ" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "%1 ਨੂੰ ਹਟਾਓ" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "ਸੋਧ ਢੰਗ ਵਿੱਚ ਜਾਓ" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "%1 ਸੰਰਚਨਾ..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "ਵਿਦਜੈਟ ਲਾਕ ਕਰੋ" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "ਵਿਦਜੈਟ ਅਣ-ਲਾਕ ਕਰੋ" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "ਸੋਧ ਢੰਗ ਤੋਂ ਬਾਹਰ" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "ਬਦਲ ਦਿਖਾਓ..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "ਵਿਦਜੈਟ ਹਟਾਇਆ" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "ਵਿਦਜੈਟ \"%1\" ਨੂੰ ਹਟਾਇਆ ਗਿਆ।" + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "ਪੈਨਲ ਹਟਾਇਆ" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "ਪੈਨਲ ਹਟਾਇਆ ਜਾ ਚੁੱਕਾ ਹੈ।" + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "ਡੈਸਕਟਾਪ ਹਟਾਇਆ" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "ਡੈਸਕਟਾਪ ਹਟਾਇਆ ਜਾ ਚੁੱਕਿਆ ਹੈ।" + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "ਵਾਪਿਸ" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "ਵਿਦਜੈਟ ਸੈਟਿੰਗ" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "ਇਹ ਵਿਦਜੈਟ ਹਟਾਓ" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "ਇਹ ਪੈਨਲ ਹਟਾਓ" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "ਇਹ ਸਰਗਰਮੀ ਹਟਾਓ" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "ਸਰਗਰਮੀ ਸੈਟਿੰਗਾਂ" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "ਲੋੜੀਦਾ ਭਾਗ ਲੱਭਿਆ ਨਹੀਂ ਜਾ ਸਕਿਆ: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "ਅਣਪਛਾਤਾ ਐਪਲਿਟ" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "QML ਫਾਇਲ ਲੋਡ ਕਰਨ ਵਿੱਚ ਗਲਤੀ: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "%1 ਸੈਟਿੰਗਾਂ" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 ਸੈਟਿੰਗਾਂ" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "ਪਲਾਜ਼ਮਾ ਪੈਕੇਜ" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "ਇੰਸਟਾਲ ਕਰੋ" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "ਪੈਕੇਜ ਇੰਸਟਾਲੇਸ਼ਨ ਅਸਫ਼ਲ ਹੈ" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "ਵਿਦਜੈੱਟ" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "%1 ਜੋੜੋ" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "ਆਈਕਾਨ ਜੋੜੋ" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "ਵਾਲਪੇਪਰ" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "%1 ਸੈੱਟ ਕਰੋ" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "" + +#~ msgid "Add Widgets..." +#~ msgstr "...ਵਿਦਜੈੱਟ ਸ਼ਾਮਿਲ" + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "ਨੈੱਟਵਰਕ ਉੱਤੇ ਵਿਦਜੈੱਟ ਨੂੰ ਸਾਂਝਾ ਕਰਨ ਨਾਲ ਤੁਸੀਂ ਇਸ ਵਿਦਜੈੱਟ ਨੂੰ ਹੋਰ ਕੰਪਿਊਟਰ ਤੋਂ ਰਿਮੋਟ ਕੰਟਰੋਲ ਵਜੋਂ ਅਸੈੱਸ " +#~ "ਮਨਜ਼ੂਰ ਕਰਦੇ ਹੋ।" + +#~ msgid "Share this widget on the network" +#~ msgstr "ਇਹ ਵਿਦਜੈੱਟ ਨੈੱਟਵਰਕ ਉੱਤੇ ਸਾਂਝਾ ਕਰੋ" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "ਹਰੇਕ ਨੂੰ ਇਹ ਵਿਦਜੈੱਟ ਵਰਤਣ ਦਿਓ" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "ਗਲਤ (ਨਲ) ਸਰਵਿਸ, ਕੋਈ ਵੀ ਓਪਰੇਸ਼ਨ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।" + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "ਫੁਟਕਲ" + +#~ msgid "Main Script File" +#~ msgstr "ਮੁੱਖ ਸਕ੍ਰਿਪਟ ਫਾਈਲ" + +#~ msgid "Tests" +#~ msgstr "ਟੈਸਟ" + +#~ msgid "Images" +#~ msgstr "ਚਿੱਤਰ" + +#~ msgid "Themed Images" +#~ msgstr "ਥੀਮ ਚਿੱਤਰ" + +#~ msgid "User Interface" +#~ msgstr "ਵਰਤੋਂਕਾਰ ਇੰਟਰਫੇਸ" + +#~ msgid "Data Files" +#~ msgstr "ਡਾਟਾ ਫਾਈਲਾਂ" + +#~ msgid "Executable Scripts" +#~ msgstr "ਚੱਲਣਯੋਗ ਸਕ੍ਰਿਪਟਾਂ" + +#~ msgid "Screenshot" +#~ msgstr "ਸਕਰੀਨਸ਼ਾਟ" + +#~ msgid "Translations" +#~ msgstr "ਉਲੱਥੇ" + +#~ msgid "Configuration XML file" +#~ msgstr "ਸੰਰਚਨਾ XML ਫਾਈਲ" + +#~ msgid "Images for dialogs" +#~ msgstr "ਡਾਈਲਾਗਾਂ ਲਈ ਚਿੱਤਰ" + +#~ msgid "Generic dialog background" +#~ msgstr "ਆਮ ਡਾਈਲਾਗ ਬੈਕਗਰਾਊਂਡ" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "ਲਾਗਆਉਟ ਡਾਈਲਾਗ ਲਈ ਥੀਮ" + +#~ msgid "Wallpaper packages" +#~ msgstr "ਵਾਲਪੇਪਰ ਪੈਕੇਜ" + +#~ msgid "Images for widgets" +#~ msgstr "ਵਿਦਜੈੱਟ ਲਈ ਚਿੱਤਰ" + +#~ msgid "Background image for widgets" +#~ msgstr "ਵਿਦਜੈੱਟਾਂ ਲਈ ਬੈਕਗਰਾਊਂਡ ਚਿੱਤਰ" + +#~ msgid "Analog clock face" +#~ msgstr "ਐਨਾਲਾਗ ਘੜੀ ਫੇਸ" + +#~ msgid "Background image for panels" +#~ msgstr "ਪੈਨਲਾਂ ਲਈ ਬੈਕਗਰਾਊਂਡ ਚਿੱਤਰ" + +#~ msgid "Background for graphing widgets" +#~ msgstr "ਗਰਾਫਿਕ ਵਾਲੇ ਵਿਦਜੈੱਟਾਂ ਲਈ ਬੈਕਗਰਾਊਂਡ" + +#~ msgid "Background image for tooltips" +#~ msgstr "ਟੂਲ-ਟਿੱਪ ਲਈ ਬੈਕਗਰਾਊਂਡ ਚਿੱਤਰ" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "ਡਾਈਲਾਗਾਂ ਲਈ ਧੁੰਦਲੇ ਚਿੱਤਰ" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "ਲਾਗਆਉਟ ਡਾਈਲਾਗ ਲਈ ਧੁੰਦਲਾ ਥੀਮ" + +#~ msgid "Opaque images for widgets" +#~ msgstr "ਵਿਦਜੈੱਟ ਲਈ ਧੁੰਦਲੇ ਚਿੱਤਰ" + +#~ msgid "Opaque background image for panels" +#~ msgstr "ਪੈਨਲਾਂ ਲਈ ਧੁੰਦਲਾ ਬੈਕਗਰਾਊਂਡ ਚਿੱਤਰ" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "ਟੂਲ-ਟਿੱਪ ਲਈ ਧੁੰਦਲਾ ਬੈਕਗਰਾਊਂਡ ਚਿੱਤਰ" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme ਸੰਰਚਨਾ ਫਾਈਲ" + +#~ msgid "Service Descriptions" +#~ msgstr "ਸਰਵਿਸ ਵੇਰਵਾ" + +#~ msgid "Script initialization failed" +#~ msgstr "ਸਕ੍ਰਿਪਟ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਫੇਲ੍ਹ" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "ਛੁੱਟੀਆਂ" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "ਸਮਾਗਮ" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "ਟੂ-ਡੂ" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "ਹੋਰ" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "ਪਿਛਲਾ ਮਹੀਨਾ" + +#~ msgid "Previous Year" +#~ msgstr "ਪਿਛਲਾ ਸਾਲ" + +#~ msgid "Previous Decade" +#~ msgstr "ਪਿਛਲਾ ਦਹਾਕਾ" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "ਅੱਜ" + +#~ msgid "Reset calendar to today" +#~ msgstr "ਕੈਲੰਡਰ ਨੂੰ ਅੱਜ ਲਈ ਮੁੜ-ਸੈੱਟ ਕਰੋ" + +#~ msgid "Next Month" +#~ msgstr "ਅਗਲਾ ਮਹੀਨਾ" + +#~ msgid "Next Year" +#~ msgstr "ਅਗਲਾ ਸਾਲ" + +#~ msgid "Next Decade" +#~ msgstr "ਅਗਲਾ ਦਹਾਕਾ" + +#~ msgid "Days" +#~ msgstr "ਦਿਨ" + +#~ msgid "Months" +#~ msgstr "ਮਹੀਨੇ" + +#~ msgid "Years" +#~ msgstr "ਸਾਲ" + +#~ msgid "OK" +#~ msgstr "ਠੀਕ ਹੈ" + +#~ msgid "Cancel" +#~ msgstr "ਰੱਦ ਕਰੋ" + +#~ msgid "Run the Associated Application" +#~ msgstr "ਸੰਬੰਧਿਤ ਐਪਲੀਕੇਸ਼ਨ ਚਲਾਓ" + +#~ msgid "Open with %1" +#~ msgstr "%1 ਨਾਲ ਖੋਲ੍ਹੋ" + +#~ msgid "Accessibility" +#~ msgstr "ਅਸੈੱਸਬਿਲਟੀ" + +#~ msgid "Application Launchers" +#~ msgstr "ਐਪਲੀਕੇਸ਼ਨ ਲਾਂਚਰ" + +#~ msgid "Astronomy" +#~ msgstr "ਗਰੈਹ ਵਿਦਿਆ" + +#~ msgid "Date and Time" +#~ msgstr "ਮਿਤੀ ਅਤੇ ਟਾਈਮ" + +#~ msgid "Development Tools" +#~ msgstr "ਡਿਵੈਲਪਮੈਂਟ ਟੂਲ" + +#~ msgid "Education" +#~ msgstr "ਸਿੱਖਿਆ" + +#~ msgid "Environment and Weather" +#~ msgstr "ਵਾਤਾਵਰਨ ਤੇ ਮੌਸਮ" + +#~ msgid "Examples" +#~ msgstr "ਮਿਸਾਲਾਂ" + +#~ msgid "File System" +#~ msgstr "ਫਾਈਲ-ਸਿਸਟਮ" + +#~ msgid "Fun and Games" +#~ msgstr "ਮੌਜ ਮਸਤੀ ਤੇ ਖੇਡਾਂ" + +#~ msgid "Graphics" +#~ msgstr "ਗਰਾਫਿਕਸ" + +#~ msgid "Language" +#~ msgstr "ਭਾਸ਼ਾ" + +#~ msgid "Mapping" +#~ msgstr "ਮੈਪਿੰਗ" + +#~ msgid "Miscellaneous" +#~ msgstr "ਫੁਟਕਲ" + +#~ msgid "Multimedia" +#~ msgstr "ਮਲਟੀਮੀਡਿਆ" + +#~ msgid "Online Services" +#~ msgstr "ਆਨਲਾਈਨ ਸੇਵਾਵਾਂ" + +#~ msgid "Productivity" +#~ msgstr "ਪਰੋਡਕਟਵਿਟੀ" + +#~ msgid "System Information" +#~ msgstr "ਸਿਸਟਮ ਜਾਣਕਾਰੀ" + +#~ msgid "Utilities" +#~ msgstr "ਸਹੂਲਤਾਂ" + +#~ msgid "Windows and Tasks" +#~ msgstr "ਵਿੰਡੋਜ਼ ਤੇ ਟਾਸਕ" + +#~ msgid "Clipboard" +#~ msgstr "ਕਲਿੱਪਬੋਰਡ" + +#~ msgid "Tasks" +#~ msgstr "ਟਾਸਕ" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "%1 ਨੂੰ ਸੋਧੋ..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "ਥੀਮ ਆਦਿ ਲਈ ਡਿਫਾਲਟ ਸੈਟਿੰਗਾਂ" + +#~ msgid "Color scheme to use for applications." +#~ msgstr "ਐਪਲੀਕੇਸ਼ਨ ਵਾਸਤੇ ਵਰਤਣ ਲਈ ਰੰਗ ਸਕੀਮ ਹੈ।" + +#~ msgid "Preview Images" +#~ msgstr "ਚਿੱਤਰ ਝਲਕ" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "ਲਾਗਇਨ ਮੈਨੇਜਰ ਲਈ ਝਲਕ" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "ਲਾਕ ਸਕਰੀਨ ਲਈ ਝਲਕ" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "ਵਰਚੁਅਲ ਡੈਸਕ ਸਵਿੱਚ ਲਈ ਝਲਕ" + +#~ msgid "Preview for KRunner" +#~ msgstr "ਕੇਰਨਰ ਲਈ ਝਲਕ" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "ਵਿੰਡੋ ਸਜਾਵਟਾਂ ਲਈ ਝਲਕ" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "ਵਿੰਡੋ ਸਵਿੱਚਰ ਲਈ ਝਲਕ" + +#~ msgid "Login Manager" +#~ msgstr "ਲਾਗ-ਇਨ ਮੈਨੇਜਰ" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "ਲਾਗ-ਇਨ ਮੈਨੇਜਰ ਲਈ ਮੁੱਖ ਸਕ੍ਰਿਪਟ" + +#~ msgid "Logout Dialog" +#~ msgstr "ਲਾਗਆਉਟ ਡਾਈਲਾਗ" + +#~ msgid "Screenlocker" +#~ msgstr "ਸਕਰੀਨਲਾਕਰ" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "ਵਰਤੋਂਕਾਰ ਸਵਿੱਚਰ ਲਈ ਮੁੱਖ ਸਕ੍ਰਿਪਟ" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "ਵਰਚੁਅਲ ਡੈਸਕਟਾਪ ਸਵਿੱਚਰ" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "ਫ਼ਰਜ਼ੀ ਡੈਸਕਟਾਪ ਸਵਿੱਚਰ ਲਈ ਮੁੱਖ ਸਕ੍ਰਿਪਟ" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "ਸਕਰੀਨ ਉੱਤੇ ਸੂਚਨਾਵਾਂ ਝਲਕ" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "ਆਨ-ਸਕਰੀਨ ਡਿਸਪਲੇਅ ਨੋਟੀਫਿਕੇਸ਼ਨਾਂ ਲਈ ਮੁੱਖ ਸਕ੍ਰਿਪਟ" + +#~ msgid "Splash Screen" +#~ msgstr "ਸਵਾਗਤੀ ਸਕਰੀਨ" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "ਸਵਾਗਤੀ ਸਕਰੀਨ ਲਈ ਮੁੱਖ ਸਕ੍ਰਿਪਟ" + +#~ msgid "KRunner UI" +#~ msgstr "ਕੇ-ਰਨਰ UI" + +#~ msgid "Main Script KRunner" +#~ msgstr "ਕੇ-ਰਨਰ ਲਈ ਮੁੱਖ ਸਕ੍ਰਿਪਟ" + +#~ msgid "Window Decoration" +#~ msgstr "ਵਿੰਡੋ ਸਜਾਵਟ" + +#~ msgid "Window Switcher" +#~ msgstr "ਵਿੰਡੋ ਸਵਿੱਚਰ" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "ਖਾਕੇ ਨੂੰ ਕਸਟਮਾਈਜ਼ ਪੂਰਾ" + +#~ msgid "Customize Layout..." +#~ msgstr "ਖਾਕੇ ਨੂੰ ਕਸਟਮਾਈਜ਼ ਕਰੋ..." + +#~ msgid "Fetching file type..." +#~ msgstr "...ਫਾਈਲ ਕਿਸਮ ਲਈ ਜਾ ਰਹੀ ਹੈ" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1 ਚੋਣਾਂ" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "ਇਹ %1 ਹਟਾਓ" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "%1 ਸੈਟਿੰਗਾਂ" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "...%1 ਸੈਟਿੰਗਾਂ" + +#~ msgid "Low color images for dialogs" +#~ msgstr "ਡਾਈਲਾਗਾਂ ਲਈ ਘੱਟ ਰੰਗ ਚਿੱਤਰ" + +#~ msgid "Low color generic dialog background" +#~ msgstr "ਘੱਟ ਰੰਗ ਆਮ ਡਾਈਲਾਗ ਬੈਕਗਰਾਊਂਡ" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "ਲਾਗਆਉਟ ਡਾਈਲਾਗ ਲਈ ਘੱਟ ਰੰਗ ਥੀਮ" + +#~ msgid "Low color background image for widgets" +#~ msgstr "ਵਿਦਜੈੱਟ ਲਈ ਘੱਟ ਰੰਗ ਬੈਕਗਰਾਊਂਡ ਚਿੱਤਰ" + +#~ msgid "Low color analog clock face" +#~ msgstr "ਘੱਟ ਰੰਗ ਐਨਾਲਾਗ ਘੜੀ ਫੇਸ" + +#~ msgid "Low color background image for panels" +#~ msgstr "ਪੈਨਲਾਂ ਲਈ ਘੱਟ ਰੰਗ ਬੈਕਗਰਾਊਂਡ ਚਿੱਤਰ" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "ਗਰਾਫਿਕਸ ਵਿਦਜੈੱਟਾਂ ਲਈ ਘੱਟ ਰੰਗ ਬੈਕਗਰਾਊਂਡ" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "ਟੂਲ-ਟਿੱਪ ਲਈ ਘੱਟ ਰੰਗ ਬੈਕਗਰਾਊਂਡ ਚਿੱਤਰ" + +#~ msgid "Plasma Package Manager" +#~ msgstr "ਪਲਾਜ਼ਮਾ ਪੈਕੇਜ ਮੈਨੇਜਰ" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr " ਉੱਤੇ ਪੈਕੇਜ ਲਈ SHA1 ਹੈਸ਼ ਬਣਾਓ" + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "ਸਭ ਯੂਜ਼ਰਾਂ ਲਈ ਇੰਸਟਾਲ ਕੀਤੇ ਪੈਕੇਜਾਂ ਉੱਤੇ ਇੰਸਟਾਲ ਜਾਂ ਹਟਾਓ ਓਪਰੇਸ਼ਨਾਂ ਲਈ" + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "ਪੈਕੇਜਾਂ ਦੀ ਟਾਈਪ, ਜਿਵੇਂ ਕਿ ਥੀਮ, ਵਾਲਪੇਪਰ, ਪਲਾਜ਼ਮੋਡ, ਡਾਟਾ-ਇੰਜਣ, ਰਨਰ, ਲੇਆਉਟ-ਟੈਪਲੇਟ ਆਦਿ।" + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr " ਉੱਤੇ ਪੈਕੇਜ ਇੰਸਟਾਲ" + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr " ਪੈਕੇਜ ਬਾਰੇ ਜਾਣਕਾਰੀ ਵੇਖੋ" + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr " ਉੱਤੇ ਪੈਕੇਜ ਅੱਪਗਰੇਡ" + +#~ msgid "List installed packages" +#~ msgstr "ਇੰਸਟਾਲ ਕੀਤੇ ਪੈਕੇਜ ਵੇਖੋ" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr " ਨਾਂ ਦਾ ਪੈਕੇਜ ਹਟਾਓ" + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "ਪੈਕੇਜ ਰੂਟ ਲਈ ਅਸਲੀ ਪਾਥ ਹੈ। ਜੇ ਇਹ ਨਾ ਦਿੱਤਾ ਤਾਂ ਇਸ KDE ਸ਼ੈਸ਼ਨ ਲਈ ਸਟੈਂਡਰਡ ਡਾਟਾ ਡਾਇਰੈਕਟਰੀਆਂ " +#~ "ਦੀ ਖੋਜ ਕੀਤੀ ਜਾਵੇਗੀ।" + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "%1 ਲਈ ਇੱਕ ਪੈਕੇਜ ਹੈਸ਼ ਤਿਆਰ ਕਰਨ ਲਈ ਫੇਲ੍ਹ ਹੈ" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "%1 ਉੱਤੇ ਪੈਕੇਜ ਲਈ SHA1 ਹੈਸ਼: '%2'" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "ਵਾਲਪੇਪਰ" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "ਪੈਕੇਜ" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "ਥੀਮ" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "ਡਾਟਾਇੰਜਣ" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "ਰਨਰ" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "ਵਾਲਪੇਪਰਪਲੱਗਇਨ" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "ਸ਼ੈੱਲ" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "ਗਲਤੀ: ਪਲੱਗਇਨ %1 ਇੰਸਟਾਲ ਨਹੀਂ ਹੈ।" + +#~ msgid " Name : %1" +#~ msgstr " ਨਾਂ : %1" + +#~ msgid " Comment : %1" +#~ msgstr " ਟਿੱਪਣੀ: %1" + +#~ msgid " Plugin : %1" +#~ msgstr " ਪਲੱਗਇਨ : %1" + +#~ msgid " Author : %1" +#~ msgstr " ਲੇਖਕ : %1" + +#~ msgid " Path : %1" +#~ msgstr " ਪਾਥ : %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "ਪੈਕੇਜਰਰੂਟ ਅਤੇ ਗਲੋਬਲ ਚੋਣਾਂ ਦਾ ਆਪਸ ਵਿੱਚ ਟਕਰਾ ਹੈ, ਕਿਸੇ ਇੱਕ ਦੀ ਚੋਣ ਕਰੋ ਜੀ।" + +#~ msgid "Addon Name" +#~ msgstr "ਐਡ-ਆਨ ਨਾਂ" + +#~ msgid "Service Type" +#~ msgstr "ਸਰਵਿਸ ਕਿਸਮ" + +#~ msgid "Path" +#~ msgstr "ਮਾਰਗ" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "ਇਹ ਟੂਲ ਨਾਲ ਇੰਸਟਾਲ ਹੋਣਯੋਗ ਪੈਕੇਜ ਕਿਸਮਾਂ:" + +#~ msgid "Built in:" +#~ msgstr "ਬਿਲਟ-ਇਨ:" + +#~ msgid "DataEngine" +#~ msgstr "ਡਾਟਾਇੰਜਣ" + +#~ msgid "Layout Template" +#~ msgstr "ਲੇਆਉਟ ਟੈਪਲੇਟ" + +#~ msgid "Look and Feel" +#~ msgstr "ਦਿੱਖ ਤੇ ਪਰਭਾਵ" + +#~ msgid "Package" +#~ msgstr "ਪੈਕੇਜ" + +#~ msgid "Runner" +#~ msgstr "ਰਨਰ" + +#~ msgid "Shell" +#~ msgstr "ਸ਼ੈੱਲ" + +#~ msgid "Theme" +#~ msgstr "ਥੀਮ" + +#~ msgid "Wallpaper Images" +#~ msgstr "ਵਾਲਪੇਪਰ ਚਿੱਤਰ" + +#~ msgid "Animated Wallpaper" +#~ msgstr "ਐਨੀਮੇਟਡ ਵਾਲਪੇਪਰ" + +#~ msgid "KWin Effect" +#~ msgstr "KWin ਪਰਭਾਵ" + +#~ msgid "KWin Window Switcher" +#~ msgstr "KWin ਵਿੰਡੋ ਸਵਿੱਚਰ" + +#~ msgid "KWin Script" +#~ msgstr "KWin ਸਕ੍ਰਿਪਟ" + +#~ msgid "Provided by plugins:" +#~ msgstr "ਪਲੱਗਇਨ ਦਿੱਤੇ ਗਏ:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr ".desktop ਫਾਈਲਾਂ ਵਲੋਂ ਦਿੱਤੇ:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "%1 ਕਾਮਯਾਬੀ ਨਾਲ ਅੱਪਗਰੇਡ ਕੀਤਾ" + +#~ msgid "Successfully installed %1" +#~ msgstr "%1 ਠੀਕ ਤਰ੍ਹਾਂ ਇੰਸਟਾਲ ਕੀਤਾ" + +#~ msgid "No such file: %1" +#~ msgstr "ਇੰਝ ਦੀ ਫਾਈਲ ਨਹੀਂ: %1" + +#~ msgid "Could not open package file: %1" +#~ msgstr "ਪੈਕੇਜ ਫਾਈਲ ਖੋਲ੍ਹੀ ਨਹੀਂ ਜਾ ਸਕੀ: %1" + +#~ msgid "%1 already exists" +#~ msgstr "%1 ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 ਮੌਜੂਦ ਨਹੀਂ" + +#~ msgid "Default layout file" +#~ msgstr "ਡਿਫਾਲਟ ਲੇਆਉਟ ਫਾਈਲ" + +#~ msgid "Panel configuration UI" +#~ msgstr "ਪਲਾਜ਼ਮਾ ਸੰਰਚਨਾ UI" diff --git a/po/pl/libplasma6.po b/po/pl/libplasma6.po new file mode 100644 index 0000000..d4ab343 --- /dev/null +++ b/po/pl/libplasma6.po @@ -0,0 +1,1083 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# SPDX-FileCopyrightText: 2014, 2015, 2016, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Łukasz Wojniłowicz +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-24 11:55+0200\n" +"Last-Translator: Łukasz Wojniłowicz \n" +"Language-Team: Polish \n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 23.08.5\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Więcej działań" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Zwiń" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Rozwiń" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Hasło" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Poszukaj..." + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Poszukaj" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Wyczyść wyszukane" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Nieznany" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Włącz element interfejsu: %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Usuń %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Wejdź do trybu dostosowywania" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Ustawienia %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Unieruchom elementy interfejsu" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Uwolnij elementy interfejsu" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Wyjdź z trybu dostosowywania" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Określa czy tworzyć pamięć podręczną dla dysku dla wystroju." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Największy rozmiar pamięci podręcznej na dysku w kilobajtach dla wystrojów. " +"Miej na uwadze, że pliki te są niewielki i największy rozmiar może zostać " +"niewykorzystany. Ustawienie większego rozmiaru jest zazwyczaj całkiem " +"bezpieczne." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Pokaż zamienniki..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Usunięto element interfejsu" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Element interfejsu \"%1\" został usunięty." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Usunięto panel." + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Panel został usunięty." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Usunięto pulpit." + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Pulpit został usunięty." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Cofnij" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Ustawienia elementu interfejsu" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Usuń ten element interfejsu" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Usuń ten panel" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Usuń tę aktywność" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Ustawienia aktywności" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Dodaj lub zarządzaj elementami interfejsu..." + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Nie można znaleźć żądanego składnika: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Główna rzecz %1 musi być rodzaju ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Główna rzecz %1 musi być rodzaju PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Nieznany aplet" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Ten element interfejsu został napisany dla nieznanej, starszej wersji Plazmy " +"i nie jest on zgodny z Plazmą %1. Zalecamy napisanie do jego autora z prośbą " +"o uaktualnienie do nowej wersji Plazmy." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 jest niezgodny z Plazmą %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Ten element interfejsu został napisany dla Plazmy %1 i nie jest on zgodny z " +"Plazmą %2. Zalecamy napisanie do jego autora z prośbą o uaktualnienie do " +"nowej wersji Plazmy." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Ten element interfejsu został napisany dla Plazmy %1 i nie jest on zgodny z " +"Plazmą %2. Uaktualnij swoją Plazmę, aby móc go używać." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Wybacz! Wystąpił błąd podczas wczytywania %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Błąd wczytywania pliku QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Błąd wczytywania apletu: pakiet %1 nie istnieje." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 Ustawienia" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 Ustawienia" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Pakiet Plazmy" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Wgraj" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Nie udało się wgrać pakietu" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Upuszczony pakiet jest nieprawidłowy." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Elementy interfejsu" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Dodaj %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Dodaj ikonę" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Tapeta" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Ustaw %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Upuszczono zawartość" + +#~ msgid "Add Widgets..." +#~ msgstr "Dodaj elementy interfejsu..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "" +#~ "Nie można otworzyć pakietu %1 wymaganego przez element interfejsu %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Współdzielenie elementu interfejsu w sieci pozwala uzyskać dostęp do tego " +#~ "elementu interfejsu z innego komputera jako pilota." + +#~ msgid "Share this widget on the network" +#~ msgstr "Współdziel ten element interfejsu w sieci" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Zezwól każdemu na dostęp do tego elementu interfejsu" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Niepoprawna (pusta) usługa. Nie można wykonać żadnej operacji." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "" +#~ "Element interfejsu %1 nie określił wykorzystywanego silnika skryptów." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Różne" + +#~ msgid "Main Script File" +#~ msgstr "Plik głównego skryptu" + +#~ msgid "Tests" +#~ msgstr "Testy" + +#~ msgid "Images" +#~ msgstr "Obrazy" + +#~ msgid "Themed Images" +#~ msgstr "Obrazy z motywem" + +#~ msgid "Configuration Definitions" +#~ msgstr "Definicje ustawień" + +#~ msgid "User Interface" +#~ msgstr "Układ sterowania użytkownika" + +#~ msgid "Data Files" +#~ msgstr "Pliki danych" + +#~ msgid "Executable Scripts" +#~ msgstr "Skrypty wykonywalne" + +#~ msgid "Screenshot" +#~ msgstr "Zrzut ekranu" + +#~ msgid "Translations" +#~ msgstr "Tłumaczenia" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Model stron ustawiania układu sterownia użytkownika" + +#~ msgid "Configuration XML file" +#~ msgstr "Plik ustawień XML" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Własne rozwinięcie dla kompaktowych apletów" + +#~ msgid "Images for dialogs" +#~ msgstr "Obrazy dla okien dialogowych" + +#~ msgid "Generic dialog background" +#~ msgstr "Zwykłe tło okien dialogowych" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Wystrój okna wylogowania" + +#~ msgid "Wallpaper packages" +#~ msgstr "Pakiety tapet" + +#~ msgid "Images for widgets" +#~ msgstr "Obrazy elementów interfejsu" + +#~ msgid "Background image for widgets" +#~ msgstr "Obraz tła elementów interfejsu" + +#~ msgid "Analog clock face" +#~ msgstr "Wygląd zegara analogowego" + +#~ msgid "Background image for panels" +#~ msgstr "Obraz tła paneli" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Tło elementów interfejsu związanych z grafiką" + +#~ msgid "Background image for tooltips" +#~ msgstr "Obraz tła dla podpowiedzi" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Nieprzezroczyste obrazy okien dialogowych" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Nieprzezroczyste zwykłe tło okien dialogowych" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Nieprzezroczysty wystrój okna wylogowania" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Nieprzezroczyste obrazy elementów interfejsu" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Nieprzezroczysty obraz tła paneli" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Nieprzezroczysty obraz tła dla podpowiedzi" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Plik ustawień KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Opis usługi" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "" +#~ "Nie można uruchomić modułu obsługi skryptów (ScriptEngine) %1 dla " +#~ "elementu interfejsu %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Nie udało się uruchomić skryptu" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Święta" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Wydarzenia" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Zadania" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Inne" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Poprzedni miesiąc" + +#~ msgid "Previous Year" +#~ msgstr "Poprzedni rok" + +#~ msgid "Previous Decade" +#~ msgstr "Poprzednia dekada" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Dzisiaj" + +#~ msgid "Reset calendar to today" +#~ msgstr "Wyzeruj kalendarz do dzisiaj" + +#~ msgid "Next Month" +#~ msgstr "Następny miesiąc" + +#~ msgid "Next Year" +#~ msgstr "Następny rok" + +#~ msgid "Next Decade" +#~ msgstr "Następna dekada" + +#~ msgid "Days" +#~ msgstr "Dni" + +#~ msgid "Months" +#~ msgstr "Miesiące" + +#~ msgid "Years" +#~ msgstr "Lata" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "Anuluj" + +#~ msgid "Run the Associated Application" +#~ msgstr "Uruchom powiązany program" + +#~ msgid "Open with %1" +#~ msgstr "Otwórz w %1" + +#~ msgid "Accessibility" +#~ msgstr "Dostępność" + +#~ msgid "Application Launchers" +#~ msgstr "Uruchamiacze programów" + +#~ msgid "Astronomy" +#~ msgstr "Astronomia" + +#~ msgid "Date and Time" +#~ msgstr "Data i czas" + +#~ msgid "Development Tools" +#~ msgstr "Narzędzia programistów" + +#~ msgid "Education" +#~ msgstr "Edukacja" + +#~ msgid "Environment and Weather" +#~ msgstr "Pogoda i środowisko" + +#~ msgid "Examples" +#~ msgstr "Przykłady" + +#~ msgid "File System" +#~ msgstr "System plików" + +#~ msgid "Fun and Games" +#~ msgstr "Zabawy i gry" + +#~ msgid "Graphics" +#~ msgstr "Grafika" + +#~ msgid "Language" +#~ msgstr "Język" + +#~ msgid "Mapping" +#~ msgstr "Mapowanie" + +#~ msgid "Miscellaneous" +#~ msgstr "Różne" + +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + +#~ msgid "Online Services" +#~ msgstr "Usługi sieciowe" + +#~ msgid "Productivity" +#~ msgstr "Produktywność" + +#~ msgid "System Information" +#~ msgstr "Informacje systemowe" + +#~ msgid "Utilities" +#~ msgstr "Narzędzia" + +#~ msgid "Windows and Tasks" +#~ msgstr "Okna i zadania" + +#~ msgid "Clipboard" +#~ msgstr "Schowek" + +#~ msgid "Tasks" +#~ msgstr "Zadania" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Edytuj %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Domyślne ustawienia dla wystroju, itp." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Zestaw kolorów używanych w aplikacjach." + +#~ msgid "Preview Images" +#~ msgstr "Podgląd obrazów" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Podgląd dla ekranu logowania" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Podgląd dla ekranu blokującego" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Podgląd dla przełącznika użytkownika" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Podgląd dla przełącznika wirtualnego pulpitu" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Podgląd dla ekranu powitalnego" + +#~ msgid "Preview for KRunner" +#~ msgstr "Podgląd dla KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Podgląd wystroju okien" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Podgląd dla przełącznika okien" + +#~ msgid "Login Manager" +#~ msgstr "Ekran logowania" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Główny skrypt dla ekranu logowania" + +#~ msgid "Logout Dialog" +#~ msgstr "Okno dialogowe wylogowywania" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Główny skrypt dla okna dialogowego wylogowywania" + +#~ msgid "Screenlocker" +#~ msgstr "Blokada ekranu" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Główny skrypt dla blokady ekranu" + +#~ msgid "UI for fast user switching" +#~ msgstr "Układ sterownia do szybkiego przełączania użytkowników" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Główny skrypt dla przełącznika użytkowników" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Przełącznik wirtualnych pulpitów" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Główny skrypt dla przełącznika wirtualnych pulpitów" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Powiadomienia na wyświetlaczu" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Główny skrypt dla powiadomień na wyświetlaczu" + +#~ msgid "Splash Screen" +#~ msgstr "Ekran powitalny" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Główny skrypt dla ekranu powitalnego" + +#~ msgid "KRunner UI" +#~ msgstr "Układ sterowania KRunner" + +#~ msgid "Main Script KRunner" +#~ msgstr "Główny skrypt dla KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Wygląd okien" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Główny skrypt dla wystroju okien" + +#~ msgid "Window Switcher" +#~ msgstr "Przełącznik okien" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Główny skrypt dla przełącznika okien" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Ukończ dostosowywanie układu" + +#~ msgid "Customize Layout..." +#~ msgstr "Dostosuj układ..." + +#~ msgid "Fetching file type..." +#~ msgstr "Pobieranie rodzaju pliku..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Opcje %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Usuń %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Ustawienia %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Ustawienia %1..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Obrazy o niskiej liczbie kolorów dla okien dialogowych" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Zwykłe tło o niskiej liczbie kolorów dla okien dialogowych" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Wystój o niskiej liczbie kolorów dla okna wylogowywania" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Obraz tła o niskiej liczbie kolorów dla elementów interfejsu" + +#~ msgid "Low color analog clock face" +#~ msgstr "Wygląd zegara analogowego o niskiej liczbie kolorów" + +#~ msgid "Low color background image for panels" +#~ msgstr "Obraz tła o niskiej liczbie barw dla paneli" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Tło o niskiej liczbie kolorów dla elementów interfejsu z wykresami" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Obraz tła o niskiej liczbie kolorów dla podpowiedzi" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Zarządzanie pakietami Plazmy" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Generuj hasz SHA1 dla pakietu przy " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Aby wgrywać lub usuwać, pracuje na pakietach wgranych dla wszystkich " +#~ "użytkowników." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Rodzaj pakietu, np. motyw, tapeta, plazmoid, silnik danych, program " +#~ "uruchamiający, schemat-układ itp." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Wgraj pakiet w " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Pokaż informacje o pakiecie " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Uaktualnij pakiet w " + +#~ msgid "List installed packages" +#~ msgstr "Wyszczególnij wgrane pakiety" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "" +#~ "Wyszczególnij wszystkie znanych rodzaje pakietów, które mogą być wgrane" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Usuń pakiet o nazwie " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Ścieżka bezwzględna do katalogu głównego pakietu. Jeśli jej nie podasz, " +#~ "standardowe katalogi danych sesji KDE zostaną przeszukane jako pierwsze." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Nieudane generowanie haszu pakietu dla %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "Skrót SHA1 dla pakietu przy %1: '%2'" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "tapeta" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plazmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "pakiet" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "wystrój" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "silnik danych" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "program uruchamiający" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "wtyczka tapety" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "wrażeniawzrokoweidotykowe" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "powłoka" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "szablon-układ" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "efektkwin" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "przełącznikokien" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "skryptkwin" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "Nie można znaleźć odpowiedniego instalatora pakietu rodzaju %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "Wyszczególnianie rodzajów usług: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Błąd: Wtyczka %1 nie jest wgrana." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Wymagane jest jedno z: install, remove, upgrade lub list." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Błąd: Nie można znaleźć metadanych wtyczki: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Pokazywanie informacji dla pakietu: %1" + +#~ msgid " Name : %1" +#~ msgstr " Nazwa : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Komentarz : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Wtyczka : %1" + +#~ msgid " Author : %1" +#~ msgstr " Autor : %1" + +#~ msgid " Path : %1" +#~ msgstr " Ścieżka : %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Opcje packageroot i global są ze sobą w konflikcie, proszę wybrać tylko " +#~ "jedną z nich." + +#~ msgid "Addon Name" +#~ msgstr "Nazwa dodatku" + +#~ msgid "Service Type" +#~ msgstr "Rodzaj usługi" + +#~ msgid "Path" +#~ msgstr "Ścieżka" + +#~ msgid "Type Argument" +#~ msgstr "Wpisz argument" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Rodzaje pakietów wgrywalnych z danym narzędziem:" + +#~ msgid "Built in:" +#~ msgstr "Wbudowane w:" + +#~ msgid "DataEngine" +#~ msgstr "Silnik danych" + +#~ msgid "Layout Template" +#~ msgstr "Szablon rozmieszczenia" + +#~ msgid "Look and Feel" +#~ msgstr "Wrażenia wzrokowe i dotykowe" + +#~ msgid "Package" +#~ msgstr "Pakiet" + +#~ msgid "Plasmoid" +#~ msgstr "Plazmoid" + +#~ msgid "Runner" +#~ msgstr "Program uruchamiający" + +#~ msgid "Shell" +#~ msgstr "Powłoka" + +#~ msgid "Theme" +#~ msgstr "Wystrój" + +#~ msgid "Wallpaper Images" +#~ msgstr "Obrazy tapet" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Animowana tapeta" + +#~ msgid "KWin Effect" +#~ msgstr "Efekt KWin" + +#~ msgid "KWin Window Switcher" +#~ msgstr "Przełącznik okien KWin" + +#~ msgid "KWin Script" +#~ msgstr "Skrypt KWin" + +#~ msgid "Provided by plugins:" +#~ msgstr "Dostarczone przez wtyczki:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Dostarczone przez pliki .desktop:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "Pomyślnie unowocześniono %1" + +#~ msgid "Successfully installed %1" +#~ msgstr "Pomyślnie wgrano %1" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Błąd: Nieudane wgrywanie %1: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Uaktualnianie pakietu z pliku: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Pomyślnie odinstalowano %1" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Błąd: Nieudane odinstalowywanie %1: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Nie można wczytać instalatora pakietu rodzaju %1. Zgłoszony błąd to: %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Nie można utworzyć głównego katalogu pakietów: %1" + +#~ msgid "No such file: %1" +#~ msgstr "Nie ma takiego pliku: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "" +#~ "Nie można otworzyć pliku pakietu, nieobsługiwany format archiwum: %1 %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "Nie można otworzyć pliku pakietu: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "Brak pliku metadanych w pakiecie: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "Nie podano nazwy wtyczki: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "Nazwa wtyczki %1 zawiera nieprawidłowe znaki" + +#~ msgid "%1 already exists" +#~ msgstr "%1 już istnieje" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Nie można przenieść pakietu do miejsca docelowego: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Nie można skopiować pakietu do miejsca docelowego: %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Nie można utworzyć lokalnego katalogu usługi: %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "Nie można zarejestrować pakietu jako usługi (niekoniecznie jest to błąd " +#~ "fatalny): %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 nie istnieje" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Nie można usunąć pakietu z: %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "Czy na pewno usunąć ten %1?" + +#~ msgid "Applets furniture" +#~ msgstr "Wystrój apletów" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "Układ sterowania dodawaniem elementów interfejsu" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "Układ sterowania dla widoków, które pokażą pojemniki" + +#~ msgid "Default layout file" +#~ msgstr "Plik domyślnego układu" + +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "Domyślne wtyczki dla pojemników, działań pojemników itp.." + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "Wiadomość błędu pokazywana przy nieudanym wczytywaniu apletu" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "Składnik QML, który pokazuje aplet w oknie wysuwanym" + +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Zwarte przedstawienie apletu w momencie jego zwinięcia w oknie wysuwanym, " +#~ "na przykład jako ikona. aplety mogą zastępować ten składnik." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "Składnik QML dla okna dialogowego ustawień dla apletów" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "Składnik QML dla okna dialogowego ustawień dla pojemników" + +#~ msgid "Panel configuration UI" +#~ msgstr "Układ sterowania ustawiania panelu" + +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "Składnik QML do wybierania alternatywnego apletu" + +#~ msgid "" +#~ "A UI for writing, loading and running desktop scripts in the current live " +#~ "session" +#~ msgstr "" +#~ "Układ sterowania do pisania, wczytywania i uruchamiania skryptów pulpitu " +#~ "w sesji na żywo" + +#~ msgid "Theme preview thumbnail" +#~ msgstr "Miniatura podglądu wystroju" + +#~ msgid "Ok" +#~ msgstr "Ok" diff --git a/po/pt/libplasma6.po b/po/pt/libplasma6.po new file mode 100644 index 0000000..9df82a3 --- /dev/null +++ b/po/pt/libplasma6.po @@ -0,0 +1,577 @@ +msgid "" +msgstr "" +"Project-Id-Version: libplasma\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2022-07-25 09:37+0100\n" +"Last-Translator: José Nuno Coelho Pires \n" +"Language-Team: Portuguese \n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-POFile-SpellExtra: KColorScheme Online QML animation Reassociar upgrade\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-POFile-SpellExtra: KWin KRunner windowswitcher list kwineffect desktop\n" +"X-POFile-SpellExtra: SHA install kwinscript\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Mais acções" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Fechar" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Expandir" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Senha" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Procurar…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Procurar" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Desconhecido" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Activar o Elemento %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Remover o %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Entrar no Modo de Edição" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Configurar o %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Bloquear os Elementos" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Desbloquear os Elementos" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Sair do Modo de Edição" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Se deve criar ou não uma 'cache' no disco para o tema." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"O tamanho máximo da 'cache' do tema no disco em 'quilobytes'. Lembre-se que " +"estes ficheiros são esparsos, pelo que o tamanho máximo poderá não ser " +"usado. A definição de um tamanho mais elevado será à partida bastante seguro." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Mostrar as Alternativas..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Elemento Removido" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "O elemento \"%1\" foi removido." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Painel Removido" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Foi removido um painel." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Ecrã Removido" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Foi removido um ecrã." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Desfazer" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Configuração do Elemento" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Remover este Elemento" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Remover este Painel" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Remover esta Actividade" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Configuração da Actividade" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Não foi possível encontrar o componente pedido: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Elemento Desconhecido" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Erro ao carregar o ficheiro QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package inexistent. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Erro ao carregar a 'applet': o pacote é inexistente. %1" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "Configuração do %1" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Configuração do %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Pacote do Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Instalar" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Falhou a Instalação do Pacote" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "O pacote que acabou de largar é inválido." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Elementos" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Adicionar um %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Adicionar um Ícone" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Papel de Parede" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Configurar o %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Conteúdo largado" + +#~ msgid "Add Widgets..." +#~ msgstr "Adicionar Elementos..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Não foi possível abrir o pacote %1 necessário para o elemento %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "A publicação de um elemento na rede permite-lhe aceder a este elemento a " +#~ "partir de outro computador, como se fosse um comando à distância." + +#~ msgid "Share this widget on the network" +#~ msgstr "Publicar este elemento na rede" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Permitir o acesso por todos a este elemento" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Serviço inválido (nulo); não é possível efectuar nenhuma operação." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "O elemento %1 não definiu qual o motor de programação a usar." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Diversos" + +#~ msgid "Main Script File" +#~ msgstr "Ficheiro Principal do Programa" + +#~ msgid "Tests" +#~ msgstr "Testes" + +#~ msgid "Images" +#~ msgstr "Imagens" + +#~ msgid "Themed Images" +#~ msgstr "Imagens com Tema" + +#~ msgid "Configuration Definitions" +#~ msgstr "Definições de Configuração" + +#~ msgid "User Interface" +#~ msgstr "Interface do Utilizador" + +#~ msgid "Data Files" +#~ msgstr "Ficheiros de Dados" + +#~ msgid "Executable Scripts" +#~ msgstr "Programas Executáveis" + +#~ msgid "Screenshot" +#~ msgstr "Imagem" + +#~ msgid "Translations" +#~ msgstr "Traduções" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Modelo de páginas UI de configuração" + +#~ msgid "Configuration XML file" +#~ msgstr "Ficheiro XML de Configuração" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Expansão personalizada para as 'applets' compactas" + +#~ msgid "Images for dialogs" +#~ msgstr "Imagens das janelas" + +#~ msgid "Generic dialog background" +#~ msgstr "Fundo genérico da janela" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Tema da janela de encerramento" + +#~ msgid "Wallpaper packages" +#~ msgstr "Pacotes de papel de parede" + +#~ msgid "Images for widgets" +#~ msgstr "Imagens dos elementos gráficos" + +#~ msgid "Background image for widgets" +#~ msgstr "Imagem de fundo dos elementos" + +#~ msgid "Analog clock face" +#~ msgstr "Face do relógio analógico" + +#~ msgid "Background image for panels" +#~ msgstr "Imagem de fundo dos painéis" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Fundo dos elementos gráficos" + +#~ msgid "Background image for tooltips" +#~ msgstr "Imagem de fundo das dicas" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Imagens opacas para as janelas" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Fundo opaco genérico da janela" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Tema opaco da janela de encerramento" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Imagens opacas dos elementos gráficos" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Imagem de fundo opaca dos painéis" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Imagem de fundo opaca das dicas" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Ficheiro de Configuração do KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Descrições do Serviço" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Não foi possível criar um Motor de Programa %1 para o elemento %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Falhou a inicialização do programa" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Feriados" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Eventos" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Por-Fazer" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Outros" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 de %2" + +#~ msgid "Previous Month" +#~ msgstr "Mês Anterior" + +#~ msgid "Previous Year" +#~ msgstr "Ano Anterior" + +#~ msgid "Previous Decade" +#~ msgstr "Década Anterior" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Hoje" + +#~ msgid "Reset calendar to today" +#~ msgstr "Repor o calendário para hoje" + +#~ msgid "Next Month" +#~ msgstr "Mês Seguinte" + +#~ msgid "Next Year" +#~ msgstr "Ano Seguinte" + +#~ msgid "Next Decade" +#~ msgstr "Década Seguinte" + +#~ msgid "Days" +#~ msgstr "Dias" + +#~ msgid "Months" +#~ msgstr "Meses" + +#~ msgid "Years" +#~ msgstr "Anos" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "Cancelar" + +#~ msgid "Run the Associated Application" +#~ msgstr "Executar a Aplicação Associada" + +#~ msgid "Open with %1" +#~ msgstr "Abrir com o %1" + +#~ msgid "Accessibility" +#~ msgstr "Acessibilidade" + +#~ msgid "Application Launchers" +#~ msgstr "Lançadores de Aplicações" + +#~ msgid "Astronomy" +#~ msgstr "Astronomia" + +#~ msgid "Date and Time" +#~ msgstr "Data e Hora" + +#~ msgid "Development Tools" +#~ msgstr "Ferramentas de Desenvolvimento" + +#~ msgid "Education" +#~ msgstr "Educação" + +#~ msgid "Environment and Weather" +#~ msgstr "Ambiente e Meteorologia" + +#~ msgid "Examples" +#~ msgstr "Exemplos" + +#~ msgid "File System" +#~ msgstr "Sistema de Ficheiros" + +#~ msgid "Fun and Games" +#~ msgstr "Diversão e Jogos" + +#~ msgid "Graphics" +#~ msgstr "Gráficos" + +#~ msgid "Language" +#~ msgstr "Linguagem" + +#~ msgid "Mapping" +#~ msgstr "Mapas" + +#~ msgid "Miscellaneous" +#~ msgstr "Diversos" + +#~ msgid "Multimedia" +#~ msgstr "Multimédia" + +#~ msgid "Online Services" +#~ msgstr "Serviços 'Online'" + +#~ msgid "Productivity" +#~ msgstr "Produtividade" + +#~ msgid "System Information" +#~ msgstr "Informações do Sistema" + +#~ msgid "Utilities" +#~ msgstr "Utilitários" + +#~ msgid "Windows and Tasks" +#~ msgstr "Janelas e Tarefas" + +#~ msgid "Clipboard" +#~ msgstr "Área de Transferência" + +#~ msgid "Tasks" +#~ msgstr "Tarefas" diff --git a/po/pt_BR/libplasma6.po b/po/pt_BR/libplasma6.po new file mode 100644 index 0000000..dcc0c34 --- /dev/null +++ b/po/pt_BR/libplasma6.po @@ -0,0 +1,711 @@ +# Translation of libplasma5.po to Brazilian Portuguese +# Copyright (C) 2013-2019 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# André Marcelo Alvarenga , 2013, 2014, 2015, 2016, 2018, 2019. +# Luiz Fernando Ranghetti , 2018, 2020, 2021, 2022, 2023, 2024. +msgid "" +msgstr "" +"Project-Id-Version: libplasma5\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-03-23 19:06-0300\n" +"Last-Translator: Luiz Fernando Ranghetti \n" +"Language-Team: Brazilian Portuguese \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 22.12.3\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Mais ações" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Recolher" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Expandir" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Senha" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Pesquisar..." + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Pesquisar" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Limpar pesquisa" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Desconhecido" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Ativar o widget %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Remover %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Entrar no modo de edição" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Configurar %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Bloquear widgets" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Desbloquear widgets" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Sair do modo de edição" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Se deve criar ou não um cache no disco para o tema." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"O tamanho máximo do cache do tema no disco em quilobytes. Lembre-se de que " +"esses arquivos são esparsos, sendo que o tamanho máximo poderá não ser " +"usado. A atribuição de um tamanho mais elevado normalmente é bastante seguro." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Mostrar alternativas..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Widget removido" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "O widget \"%1\" foi removido." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Painel removido" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Um painel foi removido." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Área de trabalho removida" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Uma área de trabalho foi removida." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Desfazer" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Configurações do widget" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Remover este widget" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Remover este painel" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Remover esta atividade" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Configurações da atividade" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Não foi possível encontrar o componente requisitado: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "O item raiz de %1 deve ser do tipo ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "O item raiz de %1 deve ser do tipo PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Miniaplicativo desconhecido" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Este widget foi escrito para uma versão antiga desconhecida do Plasma e não " +"é compatível com o Plasma %1. Entre em contato com o autor do widget para " +"obter uma versão atualizada." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 não é compatível com o Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Este widget foi escrito para o Plasma %1 e não é compatível com o Plasma %2. " +"Entre em contato com o autor do widget para obter uma versão atualizada." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Este widget foi escrito para o Plasma %1 e não é compatível com o Plasma %2. " +"Atualize o Plasma para usar o widget." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Desculpe! Ocorreu um erro ao carregar %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Ocorreu um erro ao carregar o arquivo QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package does not exist. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Erro ao carregar o miniaplicativo: O pacote não existe. %1" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "Configurações de %1" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Configurações de %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Pacotes do Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Instalar" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Ocorreu um erro na instalação do pacote" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "O pacote que acabou de soltar é inválido." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Widgets" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Adicionar %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Adicionar ícone" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Papel de parede" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Configurar %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Conteúdo solto" + +#~ msgid "Add Widgets..." +#~ msgstr "Adicionar widgets..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Não foi possível abrir o pacote %1, necessário para o widget %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "O compartilhamento de um widget na rede permite-lhe acessá-lo a partir de " +#~ "outro computador, como se fosse um controle remoto." + +#~ msgid "Share this widget on the network" +#~ msgstr "Compartilhar este widget na rede" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Permitir que todos tenham livre acesso a este widget" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Serviço inválido (null), não pode executar quaisquer operações." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "O widget %1 não define qual ScriptEngine usar." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Diversos" + +#~ msgid "Main Script File" +#~ msgstr "Arquivo principal do script" + +#~ msgid "Tests" +#~ msgstr "Testes" + +#~ msgid "Images" +#~ msgstr "Imagens" + +#~ msgid "Themed Images" +#~ msgstr "Imagens com tema" + +#~ msgid "Configuration Definitions" +#~ msgstr "Definições de configuração" + +#~ msgid "User Interface" +#~ msgstr "Interface do usuário" + +#~ msgid "Data Files" +#~ msgstr "Arquivos de dados" + +#~ msgid "Executable Scripts" +#~ msgstr "Scripts executáveis" + +#~ msgid "Screenshot" +#~ msgstr "Imagem" + +#~ msgid "Translations" +#~ msgstr "Traduções" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Modelo de página UI de configuração" + +#~ msgid "Configuration XML file" +#~ msgstr "Arquivo de configuração XML" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Expansão personalizada para miniaplicativos compactos" + +#~ msgid "Images for dialogs" +#~ msgstr "Imagens para os diálogos" + +#~ msgid "Generic dialog background" +#~ msgstr "Fundo genérico do diálogo" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Tema para o diálogo de encerramento" + +#~ msgid "Wallpaper packages" +#~ msgstr "Pacotes de papel de parede" + +#~ msgid "Images for widgets" +#~ msgstr "Imagens para os widgets" + +#~ msgid "Background image for widgets" +#~ msgstr "Imagem de fundo dos widgets" + +#~ msgid "Analog clock face" +#~ msgstr "Face do relógio analógico" + +#~ msgid "Background image for panels" +#~ msgstr "Imagem de fundo dos painéis" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Fundo dos elementos gráficos" + +#~ msgid "Background image for tooltips" +#~ msgstr "Imagem de fundo das dicas" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Imagens opacas para os diálogos" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Fundo opaco genérico do diálogo" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Tema opaco para o diálogo de encerramento" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Imagens opacas para os widgets" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Imagem de fundo opaca para os painéis" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Imagem de fundo opaca para as dicas" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Arquivo de configuração do KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Descrições dos serviços" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Não foi possível criar uma ScriptEngine %1, para o widget %2." + +#~ msgid "Script initialization failed" +#~ msgstr "A inicialização do script falhou" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Feriados" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Eventos" + +# Deve ficar no plural, porque trata-se de um título que engloba todas as tarefas de um determinado dia. (Alvarenga) +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Tarefas" + +# Deve ficar no plural, porque trata-se de um título que engloba todos os outros itens de calendário de um determinado dia. (Alvarenga) +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Outros" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Mês anterior" + +#~ msgid "Previous Year" +#~ msgstr "Ano anterior" + +#~ msgid "Previous Decade" +#~ msgstr "Década anterior" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Hoje" + +#~ msgid "Reset calendar to today" +#~ msgstr "Redefine o calendário para hoje" + +#~ msgid "Next Month" +#~ msgstr "Próximo mês" + +#~ msgid "Next Year" +#~ msgstr "Próximo ano" + +#~ msgid "Next Decade" +#~ msgstr "Próxima década" + +#~ msgid "Days" +#~ msgstr "Dias" + +#~ msgid "Months" +#~ msgstr "Meses" + +#~ msgid "Years" +#~ msgstr "Anos" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "Cancelar" + +#~ msgid "Run the Associated Application" +#~ msgstr "Executar o aplicativo associado" + +#~ msgid "Open with %1" +#~ msgstr "Abrir com %1" + +#~ msgid "Accessibility" +#~ msgstr "Acessibilidade" + +# Nome de categoria. (Alvarenga) +#~ msgid "Application Launchers" +#~ msgstr "Lançadores de Aplicativos" + +#~ msgid "Astronomy" +#~ msgstr "Astronomia" + +# Nome de categoria. (Alvarenga) +#~ msgid "Date and Time" +#~ msgstr "Data e Hora" + +# Nome de categoria. (Alvarenga) +#~ msgid "Development Tools" +#~ msgstr "Ferramentas de Desenvolvimento" + +#~ msgid "Education" +#~ msgstr "Educação" + +# Nome de categoria. (Alvarenga) +#~ msgid "Environment and Weather" +#~ msgstr "Ambiente e Tempo" + +#~ msgid "Examples" +#~ msgstr "Exemplos" + +# Nome de categoria. (Alvarenga) +#~ msgid "File System" +#~ msgstr "Sistema de Arquivos" + +# Nome de categoria. (Alvarenga) +#~ msgid "Fun and Games" +#~ msgstr "Jogos e Diversões" + +# Nome de categoria. (Alvarenga) +#~ msgid "Graphics" +#~ msgstr "Gráficos" + +# Nome de categoria. (Alvarenga) +#~ msgid "Language" +#~ msgstr "Idioma" + +#~ msgid "Mapping" +#~ msgstr "Mapeamento" + +#~ msgid "Miscellaneous" +#~ msgstr "Diversos" + +# Nome de categoria. (Alvarenga) +#~ msgid "Multimedia" +#~ msgstr "Multimídia" + +# Nome de categoria. (Alvarenga) +#~ msgid "Online Services" +#~ msgstr "Serviços Online" + +#~ msgid "Productivity" +#~ msgstr "Produtividade" + +# Nome de categoria. (Alvarenga) +#~ msgid "System Information" +#~ msgstr "Informações do Sistema" + +# Nome de categoria. (Alvarenga) +#~ msgid "Utilities" +#~ msgstr "Utilitários" + +# Nome de categoria. (Alvarenga) +#~ msgid "Windows and Tasks" +#~ msgstr "Janelas e Tarefas" + +# Nome de categoria. (Alvarenga) +#~ msgid "Clipboard" +#~ msgstr "Área de Transferência" + +# Nome de categoria. (Alvarenga) +#~ msgid "Tasks" +#~ msgstr "Tarefas" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Editar %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Configuração padrão do tema, etc." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Esquema de cores para usar nos aplicativos." + +#~ msgid "Preview Images" +#~ msgstr "Visualização de imagens" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Visualização do gerenciador de autenticação" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Visualização do bloqueio de tela" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Visualização do seletor de usuários" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Visualização do alternador de áreas de trabalho virtuais" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Visualização da tela de apresentação" + +#~ msgid "Preview for KRunner" +#~ msgstr "Visualização do KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Visualização das decorações das janelas" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Visualização do seletor de janelas" + +#~ msgid "Login Manager" +#~ msgstr "Gerenciador de autenticação" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Script principal do gerenciador de autenticação" + +#~ msgid "Logout Dialog" +#~ msgstr "Caixa de diálogo de desligamento" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Script principal da caixa de diálogo de desligamento" + +#~ msgid "Screenlocker" +#~ msgstr "Bloqueio de tela" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Script principal do bloqueio de tela" + +#~ msgid "UI for fast user switching" +#~ msgstr "Interface de mudança rápida de usuário" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Script principal do seletor de usuários" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Alternador de áreas de trabalho virtuais" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Script principal do alternador de áreas de trabalho virtuais" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Notificações visíveis na tela" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Script principal das notificações visíveis na tela" + +#~ msgid "Splash Screen" +#~ msgstr "Tela de apresentação" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Script principal da tela de apresentação" + +#~ msgid "KRunner UI" +#~ msgstr "Interface do KRunner" + +#~ msgid "Main Script KRunner" +#~ msgstr "Script principal do KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Decorações da janela" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Script principal da decoração de janelas" + +#~ msgid "Window Switcher" +#~ msgstr "Seletor de janelas" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Script principal do seletor de janelas" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Concluir a personalização do layout" + +#~ msgid "Customize Layout..." +#~ msgstr "Personalizar layout..." + +#~ msgid "Fetching file type..." +#~ msgstr "Obtendo o tipo de arquivo..." diff --git a/po/ro/libplasma6.po b/po/ro/libplasma6.po new file mode 100644 index 0000000..2f0e126 --- /dev/null +++ b/po/ro/libplasma6.po @@ -0,0 +1,784 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Sergiu Bivol , 2014, 2015, 2020, 2021, 2022, 2023, 2024. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-06-09 14:53+0100\n" +"Last-Translator: Sergiu Bivol \n" +"Language-Team: Romanian \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " +"20)) ? 1 : 2;\n" +"X-Generator: Lokalize 21.12.3\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Acțiuni suplimentare" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Restrânge" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Desfășoară" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Parolă" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Caută…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Caută" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Șterge căutarea" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Necunoscut" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Activează controlul %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Elimină %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Intră în regim de modificare" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Configurare %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Blochează controalele" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Deblochează controalele" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Ieși din regim de modificare" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Dacă să fie creată sau nu o prestocare pe disc a tematicii." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Dimensiunea maximă pe disc a prestocării tematicilor, în kilo-octeți. " +"Rețineți că acestea sunt fișiere „împrăștiate” (engleză: sparse), deci " +"dimensiunea maximă poate să nu fie utilizată. Stabilirea unei dimensiuni mai " +"mari este de obicei sigură." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Arată alternative..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Control eliminat" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Controlul grafic „%1” a fost eliminat." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panou eliminat" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Un panou a fost eliminat." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Birou eliminat" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "A fost eliminat un birou." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Desfă" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Configurări control" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Elimină acest control" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Elimină acest panou" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Elimină această activitate" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Configurări activitate" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Nu s-a putut găsi componenta cerută: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Elementul rădăcină al %1 trebuie să aibă tipul ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Elementul rădăcină al %1 trebuie să aibă tipul PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Miniaplicație necunoscută" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Acest control grafic a fost scris pentru o versiune Plasma necunoscută și nu " +"e compatibil cu Plasma %1. Contactați autorul controlului grafic pentru o " +"versiune mai nouă." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 nu e compatibil cu Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Acest control grafic a fost scris pentru Plasma %1 și nu e compatibil cu " +"Plasma %2. Contactați autorul controlului grafic pentru o versiune mai nouă." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Acest control grafic a fost scris pentru Plasma %1 și nu e compatibil cu " +"Plasma %2. Actualizați Plasma pentru a folosi controlul grafic." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Scuze! A intervenit o eroare la încărcarea %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Eroare la încărcarea fișierului QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Eroare la încărcarea miniaplicației: pachetul %1 nu există." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — Configurări %2" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Configurări %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Pachet Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Instalează" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Instalarea pachetului a eșuat" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Pachetul pe care tocmai l-ați lăsat nu e valid." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Controale grafice" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Adaugă %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Adaugă pictogramă" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Tapet" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Stabilește %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Conținut lăsat" + +#~ msgid "Add Widgets..." +#~ msgstr "Adaugă controale…" + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "" +#~ "Nu s-a putut deschide pachetul %1 necesar pentru controlul grafic %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Partajarea unui control grafic în rețea vă permite să accesați acest " +#~ "control de pe alt calculator ca telecomandă." + +#~ msgid "Share this widget on the network" +#~ msgstr "Partajează acest control în rețea" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Permite tuturor să acceseze liber acest control" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Serviciu nevalid (nul), nu se pot efectua operații de niciun fel." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Controlul grafic „%1” nu a definit un ScriptEngine de utilizat." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Diverse" + +#~ msgid "Main Script File" +#~ msgstr "Fișier-script principal" + +#~ msgid "Tests" +#~ msgstr "Teste" + +#~ msgid "Images" +#~ msgstr "Imagini" + +#~ msgid "Themed Images" +#~ msgstr "Imagini tematice" + +#~ msgid "Configuration Definitions" +#~ msgstr "Definiții de configurare" + +#~ msgid "User Interface" +#~ msgstr "Interfață cu utilizatorul" + +#~ msgid "Data Files" +#~ msgstr "Fișiere cu date" + +#~ msgid "Executable Scripts" +#~ msgstr "Scripturi executabile" + +#~ msgid "Screenshot" +#~ msgstr "Captură de ecran" + +#~ msgid "Translations" +#~ msgstr "Traduceri" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Model de pagină pentru interfața de configurare" + +#~ msgid "Configuration XML file" +#~ msgstr "Fișier de configurare XML" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Expandor personalizat pentru miniaplicații compacte" + +#~ msgid "Images for dialogs" +#~ msgstr "Imagini pentru dialoguri" + +#~ msgid "Generic dialog background" +#~ msgstr "Fundal universal pentru dialoguri" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Tematică pentru dialogul de ieșire" + +#~ msgid "Wallpaper packages" +#~ msgstr "Pachete cu fundaluri" + +#~ msgid "Images for widgets" +#~ msgstr "Imagini pentru controale" + +#~ msgid "Background image for widgets" +#~ msgstr "Imagine de fundal pentru controale" + +#~ msgid "Analog clock face" +#~ msgstr "Mutra ceasului analog" + +#~ msgid "Background image for panels" +#~ msgstr "Imagine de fundal pentru panouri" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Fundal pentru controale grafice" + +#~ msgid "Background image for tooltips" +#~ msgstr "Fundal pentru indicii" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Imagini opace pentru dialoguri" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Fundal generic opac pentru dialoguri" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Tematică opacă pentru dialogul de ieșire din sistem" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Imagini opace pentru controale" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Imagine de fundal opacă pentru panouri" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Imagine de fundal opacă pentru indicii" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Fișier de configurare KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Descriere servicii" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Nu s-a putut crea un ScriptEngine %1 pentru controlul grafic %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Inițializarea scriptului a eșuat" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Sărbători" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Evenimente" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Obiective" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Altele" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Luna trecută" + +#~ msgid "Previous Year" +#~ msgstr "Anul trecut" + +#~ msgid "Previous Decade" +#~ msgstr "Deceniul trecut" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Azi" + +#~ msgid "Reset calendar to today" +#~ msgstr "Reinițializează calendarul la azi" + +#~ msgid "Next Month" +#~ msgstr "Luna viitoare" + +#~ msgid "Next Year" +#~ msgstr "Anul viitor" + +#~ msgid "Next Decade" +#~ msgstr "Deceniul viitor" + +#~ msgid "Days" +#~ msgstr "Zile" + +#~ msgid "Months" +#~ msgstr "Luni" + +#~ msgid "Years" +#~ msgstr "Ani" + +#~ msgid "OK" +#~ msgstr "Bine" + +#~ msgid "Cancel" +#~ msgstr "Renunță" + +#~ msgid "Run the Associated Application" +#~ msgstr "Rulează aplicația asociată" + +#~ msgid "Open with %1" +#~ msgstr "Deschide cu %1" + +#~ msgid "Accessibility" +#~ msgstr "Accesibilitate" + +#~ msgid "Application Launchers" +#~ msgstr "Lansatori de aplicații" + +#~ msgid "Astronomy" +#~ msgstr "Astronomie" + +#~ msgid "Date and Time" +#~ msgstr "Data și ora" + +#~ msgid "Development Tools" +#~ msgstr "Unelte de dezvoltare" + +#~ msgid "Education" +#~ msgstr "Educație" + +#~ msgid "Environment and Weather" +#~ msgstr "Mediu și vreme" + +#~ msgid "Examples" +#~ msgstr "Exemple" + +#~ msgid "File System" +#~ msgstr "Sistem de fișiere" + +#~ msgid "Fun and Games" +#~ msgstr "Distracție și jocuri" + +#~ msgid "Graphics" +#~ msgstr "Grafică" + +#~ msgid "Language" +#~ msgstr "Limbă" + +#~ msgid "Mapping" +#~ msgstr "Cartografie" + +#~ msgid "Miscellaneous" +#~ msgstr "Diverse" + +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + +#~ msgid "Online Services" +#~ msgstr "Servicii online" + +#~ msgid "Productivity" +#~ msgstr "Productivitate" + +#~ msgid "System Information" +#~ msgstr "Informații despre sistem" + +#~ msgid "Utilities" +#~ msgstr "Utilitare" + +#~ msgid "Windows and Tasks" +#~ msgstr "Ferestre și sarcini" + +#~ msgid "Clipboard" +#~ msgstr "Clipboard" + +#~ msgid "Tasks" +#~ msgstr "Sarcini" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Modificare %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Configurări implicite pentru tematică, etc." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Schemă de culori de folosit pentru aplicații." + +#~ msgid "Preview Images" +#~ msgstr "Previzualizare imagini" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Previzualizare pentru gestionarul de autentificare" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Previzualizare pentru ecranul de blocare" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Previzualizare pentru comutatorul de utilizatori" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Previzualizare pentru comutatorul de birouri virtuale" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Previzualizare pentru ecranul de întâmpinare" + +#~ msgid "Preview for KRunner" +#~ msgstr "Previzualizare pentru KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Previzualizare pentru decorațiile ferestrelor" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Previzualizare pentru comutatorul de ferestre" + +#~ msgid "Login Manager" +#~ msgstr "Gestionar de autentificare" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Script principal pentru gestionarul de autentificare" + +#~ msgid "Logout Dialog" +#~ msgstr "Ecran de ieșire" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Script principal pentru dialogul de ieșire" + +#~ msgid "Screenlocker" +#~ msgstr "Blocare ecran" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Script principal pentru ecranul de blocare" + +#~ msgid "UI for fast user switching" +#~ msgstr "Interfață pentru comutare rapidă între utilizatori" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Script principal pentru comutare între utilizatori" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Comutator de birouri virtuale" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Script principal pentru comutatorul de birouri virtuale" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Notificări afișate pe ecran" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Script principal pentru notificări pe ecran" + +#~ msgid "Splash Screen" +#~ msgstr "Ecran de întâmpinare" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Script principal pentru ecranul de întâmpinare" + +#~ msgid "KRunner UI" +#~ msgstr "Interfață KRunner" + +#~ msgid "Main Script KRunner" +#~ msgstr "Script principal KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Decorații de fereastră" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Script principal pentru decorații de fereastră" + +#~ msgid "Window Switcher" +#~ msgstr "Comutator de ferestre" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Script principal pentru comutare între ferestre" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Termină personalizarea aranjamentului" + +#~ msgid "Customize Layout..." +#~ msgstr "Personalizare aranjament..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Opțiuni %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Elimină %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Configurări %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Configurări %1..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Imagini în culori reduse pentru dialoguri" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "tapet" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "pachet" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "temă" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "motor de date" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "lansator" + +#~ msgid " Name : %1" +#~ msgstr " Denumire : %1" + +#~ msgid " Comment : %1" +#~ msgstr "Comentariu : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Extensie : %1" + +#~ msgid " Author : %1" +#~ msgstr " Autor : %1" + +#~ msgid " Path : %1" +#~ msgstr " Cale : %1" + +#~ msgid "Service Type" +#~ msgstr "Tip serviciu" + +#~ msgid "Path" +#~ msgstr "Cale" + +#~ msgid "Package" +#~ msgstr "Pachet" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoid" + +#~ msgid "Runner" +#~ msgstr "Lansator" + +#~ msgid "Theme" +#~ msgstr "Temă" + +#~ msgid "Wallpaper Images" +#~ msgstr "Imagini-tapet" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Tapet animat" + +#~ msgid "KWin Effect" +#~ msgstr "Efect KWin" + +#~ msgid "KWin Script" +#~ msgstr "Script KWin" + +#~ msgid "%1 already exists" +#~ msgstr "%1 există deja" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 nu există" diff --git a/po/ru/libplasma6.po b/po/ru/libplasma6.po new file mode 100644 index 0000000..6ba8290 --- /dev/null +++ b/po/ru/libplasma6.po @@ -0,0 +1,1386 @@ +# translation of libplasma.po to Russian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# SPDX-FileCopyrightText: 2018, 2019, 2020, 2021, 2022, 2024 Alexander Yavorsky +# Nick Shaforostoff , 2007, 2008, 2009. +# Albert R. Valiev , 2008. +# Albert R. Valiev , 2008. +# Leonid Kanter , 2008. +# Andrey Cherepanov , 2008, 2009. +# Nick Shaforostoff , 2009, 2016. +# Alexander Potashev , 2010, 2011, 2014, 2015, 2016, 2019. +# Alexander Lakhin , 2013. +# Yuri Efremov , 2013. +# Александр Яворский , 2018. +# Alexander Yavorsky , 2024. +msgid "" +msgstr "" +"Project-Id-Version: libplasma\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-09-15 13:46+0300\n" +"Last-Translator: Alexander Yavorsky \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 21.08.3\n" +"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n" +"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Больше действий" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Свернуть" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Развернуть" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Пароль" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Введите текст для поиска…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Поиск" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Очистить поиск" + +# Unknown Plasma widget (e.g. when it fails to load.) --aspotashev +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Неизвестный" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Сделать виджет «%1» активным" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Удалить виджет «%1»" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Режим редактирования" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Настроить виджет «%1»..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Заблокировать виджеты" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Разблокировать виджеты" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Выйти из режима редактирования" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Создавать ли на диске кэш для темы." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Максимальный размер кэша темы на диске в килобайтах. Кэш хранится в " +"разреженных файлах, и на диске может быть не использован указанный " +"максимальный объём. Поэтому увеличение этого параметра обычно безопасно." + +# In context menu of a widget. --aspotashev +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Взаимозаменяемые виджеты..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Виджет удалён" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Удалён виджет «%1»." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Удаление панели" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Панель удалена." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Рабочий стол удалён" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Удалён рабочий стол." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Отменить" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Настроить виджет" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Удалить виджет" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Удалить панель" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Удалить комнату" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Настроить комнату" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Добавить или изменить виджеты…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Невозможно найти компонент %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Объект, корневой для %1, должен иметь тип ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Объект, корневой для %1, должен иметь тип PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Неизвестный виджет" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Этот виджет предназначен для устаревшей версии Plasma и не может работать в " +"Plasma %1. Напомните автору виджета о необходимости подготовить обновлённую " +"версию виджета." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "Виджет «%1» не совместим с Plasma версии %2." + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Этот виджет предназначен для Plasma версии %1 и не может работать в Plasma " +"%2. Напомните автору виджета о необходимости подготовить обновлённую версию " +"виджета." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Этот виджет предназначен для Plasma версии %1 и не может работать в Plasma " +"%2. Обновите используемую версию Plasma для использования этого виджета." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Ошибка загрузки %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Ошибка загрузки файла QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Ошибка загрузки виджета: пакет «%1» не существует." + +# BUGME: what is the context? window title or page header? --aspotashev +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — параметры %2" + +# BUGME: what is the context? window title or page header? --aspotashev +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Настройка виджета «%1»" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Пакет Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Установить" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Ошибка установки пакета" + +# BUGME: what does "dropped" mean here? --aspotashev +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Некорректный пакет." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Виджеты" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Добавить виджет «%1»" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Добавить значок" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Обои" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Использовать «%1»" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Перетаскивание элемента" + +#~ msgid "Add Widgets..." +#~ msgstr "Добавить виджеты..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Не удалось открыть пакет «%1», необходимый для виджета «%2»." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Открытие удалённого доступа к виджету позволяет работать с ним на других " +#~ "компьютерах." + +#~ msgid "Share this widget on the network" +#~ msgstr "Разрешить удалённый доступ к этому виджету" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Разрешить свободный доступ для всех" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Ошибка при использовании службы." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "" +#~ "Для виджета %1 не указано, какой язык программирования и программный " +#~ "интерфейс (API) он использует." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Разное" + +#~ msgid "Main Script File" +#~ msgstr "Основной файл скрипта" + +# BUGME: for glossary: "тесты"/"испытания"/"проверочные программы"? --aspotashev +#~ msgid "Tests" +#~ msgstr "Тесты" + +#~ msgid "Images" +#~ msgstr "Изображения" + +#~ msgid "Themed Images" +#~ msgstr "Изображения тем" + +#~ msgid "Configuration Definitions" +#~ msgstr "Определения параметров" + +#~ msgid "User Interface" +#~ msgstr "Пользовательский интерфейс" + +#~ msgid "Data Files" +#~ msgstr "Файлы данных" + +#~ msgid "Executable Scripts" +#~ msgstr "Исполняемые скрипты" + +#~ msgid "Screenshot" +#~ msgstr "Снимок экрана" + +#~ msgid "Translations" +#~ msgstr "Переводы" + +# Another translation "Файл описания страниц диалога настройки" has poorer readability --aspotashev +#~ msgid "Configuration UI pages model" +#~ msgstr "Файл, описывающий страницы диалога настройки" + +#~ msgid "Configuration XML file" +#~ msgstr "Файл настройки в XML" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Раскрывающееся окно для компактных виджетов" + +#~ msgid "Images for dialogs" +#~ msgstr "Изображения для диалогов" + +#~ msgid "Generic dialog background" +#~ msgstr "Фон стандартных диалогов" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Тема экрана выхода из системы" + +#~ msgid "Wallpaper packages" +#~ msgstr "Пакеты с обоями" + +#~ msgid "Images for widgets" +#~ msgstr "Изображения для виджетов" + +#~ msgid "Background image for widgets" +#~ msgstr "Фоновое изображение для виджетов" + +#~ msgid "Analog clock face" +#~ msgstr "Циферблат аналоговых часов" + +#~ msgid "Background image for panels" +#~ msgstr "Фоновое изображение для панелей" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Фоновое изображение для диаграмм" + +#~ msgid "Background image for tooltips" +#~ msgstr "Фоновое изображение для подсказок" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Непрозрачные изображения для диалогов" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Непрозрачный фон для стандартных диалогов" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Непрозрачная тема экрана выхода из системы" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Непрозрачные изображения для виджетов" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Непрозрачное фоновое изображение для панелей" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Непрозрачное фоновое изображение для подсказок" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Файл схемы цветов" + +#~ msgid "Service Descriptions" +#~ msgstr "Описания служб" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Не удалось создать движок %1, необходимый для виджета «%2»." + +#~ msgid "Script initialization failed" +#~ msgstr "Ошибка открытия скрипта" + +# BUGME: please fix Ukrainian translation --aspotashev +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Праздники" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "События" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Задачи" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Другое" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Предыдущий месяц" + +#~ msgid "Previous Year" +#~ msgstr "Предыдущий год" + +#~ msgid "Previous Decade" +#~ msgstr "Предыдущее десятилетие" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Сегодня" + +#~ msgid "Reset calendar to today" +#~ msgstr "Перейти к сегодняшнему дню" + +#~ msgid "Next Month" +#~ msgstr "Следующий месяц" + +#~ msgid "Next Year" +#~ msgstr "Следующий год" + +#~ msgid "Next Decade" +#~ msgstr "Следующее десятилетие" + +#~ msgid "Days" +#~ msgstr "Дни" + +#~ msgid "Months" +#~ msgstr "Месяцы" + +#~ msgid "Years" +#~ msgstr "Годы" + +#~ msgid "OK" +#~ msgstr "ОК" + +#~ msgid "Cancel" +#~ msgstr "Отмена" + +#~ msgid "Run the Associated Application" +#~ msgstr "Запустить соответствующее приложение" + +#~ msgid "Open with %1" +#~ msgstr "Открыть в %1" + +#~ msgid "Accessibility" +#~ msgstr "Специальные возможности" + +#~ msgid "Application Launchers" +#~ msgstr "Запуск приложений" + +#~ msgid "Astronomy" +#~ msgstr "Астрономия" + +#~ msgid "Date and Time" +#~ msgstr "Дата и время" + +#~ msgid "Development Tools" +#~ msgstr "Средства разработки" + +#~ msgid "Education" +#~ msgstr "Образование" + +#~ msgid "Environment and Weather" +#~ msgstr "Погода" + +#~ msgid "Examples" +#~ msgstr "Примеры" + +#~ msgid "File System" +#~ msgstr "Файловая система" + +#~ msgid "Fun and Games" +#~ msgstr "Игры и развлечения" + +#~ msgid "Graphics" +#~ msgstr "Графика" + +#~ msgid "Language" +#~ msgstr "Лингвистика" + +#~ msgid "Mapping" +#~ msgstr "Картография" + +#~ msgid "Miscellaneous" +#~ msgstr "Разное" + +#~ msgid "Multimedia" +#~ msgstr "Мультимедиа" + +#~ msgid "Online Services" +#~ msgstr "Интернет-службы" + +#~ msgid "Productivity" +#~ msgstr "Офис" + +#~ msgid "System Information" +#~ msgstr "Сведения о системе" + +#~ msgid "Utilities" +#~ msgstr "Утилиты" + +#~ msgid "Windows and Tasks" +#~ msgstr "Окна и задачи" + +#~ msgid "Clipboard" +#~ msgstr "Буфер обмена" + +#~ msgid "Tasks" +#~ msgstr "Задания" + +# BUGME: what is the different between "edit ..." and "configure ..."? +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Изменить «%1»..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Стандартные параметры темы и т.п." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Цветовая схема для приложений." + +#~ msgid "Preview Images" +#~ msgstr "Изображения для предварительного просмотра" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Предварительный просмотр экрана входа в систему" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Предварительный просмотр заблокированного экрана" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Предварительный просмотр переключателя пользователей" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Предварительный просмотр переключателя рабочих столов" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Предварительный просмотр загрузочного экрана" + +#~ msgid "Preview for KRunner" +#~ msgstr "Предварительный просмотр диалога поиска и запуска" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Предварительный просмотр оформления окон" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Предварительный просмотр переключателя окон" + +#~ msgid "Login Manager" +#~ msgstr "Экран входа в систему" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Главный сценарий экрана входа в систему" + +#~ msgid "Logout Dialog" +#~ msgstr "Диалог завершения работы" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Главный сценарий диалога завершения работы" + +#~ msgid "Screenlocker" +#~ msgstr "Блокировщик экрана" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Главный сценарий блокировщика экрана" + +#~ msgid "UI for fast user switching" +#~ msgstr "Переключатель пользователей" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Главный сценарий переключателя пользователей" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Переключатель рабочих столов" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Главный сценарий переключателя рабочих столов" + +# BUGME: please clarify how they look like and where they are used --aspotashev +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Всплывающие уведомления" + +# BUGME: please clarify how they look like and where they are used --aspotashev +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Главный сценарий всплывающих уведомлений" + +#~ msgid "Splash Screen" +#~ msgstr "Загрузочный экран" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Главный сценарий загрузочного экрана" + +#~ msgid "KRunner UI" +#~ msgstr "Диалог поиска и запуска" + +#~ msgid "Main Script KRunner" +#~ msgstr "Главный сценарий диалога поиска и запуска" + +#~ msgid "Window Decoration" +#~ msgstr "Оформление окон" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Главный сценарий оформления окон" + +#~ msgid "Window Switcher" +#~ msgstr "Переключатель окон" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Главный сценарий переключателя окон" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Закончить размещение виджетов" + +#~ msgid "Customize Layout..." +#~ msgstr "Настроить расположение виджетов..." + +#~ msgid "Fetching file type..." +#~ msgstr "Определение типа файла..." + +# It's a menu with actions. --aspotashev +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Настроить виджет «%1»" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Удалить виджет «%1»" + +# It's an action. --aspotashev +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Настроить виджет «%1»" + +# It's an action. --aspotashev +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Настроить виджет «%1»..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Изображения с малым количеством цветов для диалогов" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Фон с малым количеством цветов для стандартных диалогов" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Тема с малым количеством цветов для экрана выхода из системы" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Фоновое изображение для виджетов с малым количеством цветов" + +#~ msgid "Low color analog clock face" +#~ msgstr "Циферблат аналоговых часов с малым количеством цветов" + +#~ msgid "Low color background image for panels" +#~ msgstr "Фоновое изображение с малым количеством цветов для панелей" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Фоновое изображение с малым количеством цветов для диаграмм" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Фоновое изображение с малым количеством цветов для подсказок" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Управление пакетами Plasma" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Создать хэш SHA1 для пакета в " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Установка, просмотр и удаление пакетов Plasma для всех пользователей." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Тип пакета, например, тема (theme), обои (wallpaper), виджет (plasmoid), " +#~ "источник данных (dataengine), расширение поиска (runner), шаблон " +#~ "размещения (layout-template) и так далее." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Установить пакет в " + +# BUGME: developers are wrong: and should be translated, but it should be done in sync with translation of the same placeholder in command line options, e.g. +# " -u, --upgrade Обновить пакет в " -> " -u, --upgrade <путь> Обновить пакет в <путь>" --aspotashev +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Показать информацию о пакете " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Обновить пакет в " + +#~ msgid "List installed packages" +#~ msgstr "Список установленных пакетов" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "Список всех доступных для установки типов пакетов" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Удалить установленный пакет " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Путь к корневому каталогу установленных пакетов. Если не указан, будет " +#~ "использован стандартный каталог данных KDE." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Ошибка создания хэша пакета для %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "Хэш SHA1 для пакета в %1: «%2»" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "обои" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "виджет" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "пакет" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "тема" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "источник_данных" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "пускатель" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "модуль_обоев" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "оформление" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "оболочка" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "шаблон_размещения" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "графический_эффект" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "переключатель_окон" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "сценарий_kwin" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "Не удалось найти модуль установки для пакета типа «%1»" + +#~ msgid "Listing service types: %1" +#~ msgstr "Список типов служб: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Ошибка: модуль «%1» не установлен." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Необходимо указать одну из команд install, remove, upgrade или list" + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Ошибка: не удалось найти метаданные модуля «%1»" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Сведения о пакете %1:" + +#~ msgid " Name : %1" +#~ msgstr " Название: %1" + +#~ msgid " Comment : %1" +#~ msgstr " Комментарий: %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Модуль: %1" + +#~ msgid " Author : %1" +#~ msgstr " Автор: %1" + +#~ msgid " Path : %1" +#~ msgstr " Путь: %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Путь к корневому каталогу пакета конфликтует с глобальными параметрами. " +#~ "Выберите один вариант." + +#~ msgid "Addon Name" +#~ msgstr "Название дополнения" + +#~ msgid "Service Type" +#~ msgstr "Тип службы" + +#~ msgid "Path" +#~ msgstr "Путь" + +#~ msgid "Type Argument" +#~ msgstr "Название для аргументов" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "" +#~ "С помощью этого инструмента можно установить пакеты следующих типов:" + +#~ msgid "Built in:" +#~ msgstr "Встроенная поддержка:" + +#~ msgid "DataEngine" +#~ msgstr "Источник данных" + +#~ msgid "Layout Template" +#~ msgstr "Шаблон размещения" + +#~ msgid "Look and Feel" +#~ msgstr "Оформление" + +#~ msgid "Package" +#~ msgstr "Пакет" + +#~ msgid "Plasmoid" +#~ msgstr "Виджет" + +#~ msgid "Runner" +#~ msgstr "Модуль KRunner" + +#~ msgid "Shell" +#~ msgstr "Оболочка" + +#~ msgid "Theme" +#~ msgstr "Тема" + +#~ msgid "Wallpaper Images" +#~ msgstr "Изображение обоев" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Анимированные обои" + +#~ msgid "KWin Effect" +#~ msgstr "Эффект KWin" + +#~ msgid "KWin Window Switcher" +#~ msgstr "Переключатель окон для KWin" + +#~ msgid "KWin Script" +#~ msgstr "Сценарий KWin" + +#~ msgid "Provided by plugins:" +#~ msgstr "Поддерживается модулями:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Поддерживается файлами .desktop:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "Пакет обновлён: %1" + +#~ msgid "Successfully installed %1" +#~ msgstr "Пакет установлен: %1" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Ошибка установки пакета %1: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Обновление пакета из файла: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Пакет удалён: %1" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Ошибка удаления пакета %1: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Не удалось запустить модуль установки для пакета типа «%1». Ошибка: %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Не удалось создать корневой каталог пакета: %1" + +#~ msgid "No such file: %1" +#~ msgstr "Нет такого файла: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "Не удалось открыть пакет %1: неподдерживаемый формат архива %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "Не удалось открыть пакет: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "Нет файла метаданных в пакете: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "В пакете не указано имя модуля: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "Имя модуля «%1», указанное в пакете, содержит недопустимые символы" + +#~ msgid "%1 already exists" +#~ msgstr "Файл или каталог %1 уже существует" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Не удалось переместить пакет в следующий каталог: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Не удалось скопировать пакет в следующий каталог: %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Не удалось создать локальный каталог службы: %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "Не удалось зарегистрировать пакет как службу (эта ошибка не всегда имеет " +#~ "серьёзные последствия): %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 не существует" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Ошибка удаления пакета из: %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "Удалить виджет «%1»?" + +# BUGME: what is "furniture"? Is it OK to have identical descriptions for two directories "applet" and "configuration"? --aspotashev +#~ msgid "Applets furniture" +#~ msgstr "Расстановка виджетов" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "Пользовательский интерфейс выбора виджета" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "Пользовательский интерфейс для обзора контейнеров" + +#~ msgid "Default layout file" +#~ msgstr "Стандартная схема расположения виджетов" + +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "" +#~ "Стандартные модули для контейнеров, наборов действий для контейнеров и т." +#~ "п." + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "Диалог сообщения об ошибке при неудачной попытке загрузки виджета" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "Компонент на QML для показа виджета во всплывающем окне" + +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Компактное представление виджета, свёрнутого из всплывающего окна, " +#~ "например — в значок. Виджеты могут заменить этот компонент." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "Компонент на QML для диалога настройки виджета" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "Компонент на QML для диалога настройки контейнера" + +# BUGME: panel configuration UI does not look like a normal "окно", how to say it better in Russian? --aspotashev +#~ msgid "Panel configuration UI" +#~ msgstr "Окно настройки панели" + +#, fuzzy +#~| msgid "QML component for the configuration dialog for applets" +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "Компонент на QML для диалога настройки виджета" + +#~ msgid "animation() takes one argument" +#~ msgstr "Функция animation() принимает один аргумент" + +#~ msgid "%1 is not a known animation type" +#~ msgstr "Неизвестный тип анимации «%1»" + +#~ msgid "Unable to load the widget" +#~ msgstr "Не удалось загрузить виджет" + +#~ msgid "Panel" +#~ msgstr "Панель" + +#~ msgid "&OK" +#~ msgstr "&ОК" + +#~ msgid "&Yes" +#~ msgstr "&Да" + +#~ msgid "&No" +#~ msgstr "&Нет" + +#~ msgid "&Cancel" +#~ msgstr "О&тмена" + +#~ msgid "Settings" +#~ msgstr "Настройка" + +#~ msgctxt "@title:window" +#~ msgid "%1 Settings" +#~ msgstr "Настройка виджета «%1»" + +#~ msgid "Keyboard Shortcut" +#~ msgstr "Комбинация клавиш" + +#~ msgctxt "" +#~ "%1 is the name of a plasmoid, %2 the name of the machine that plasmoid is " +#~ "published on" +#~ msgid "%1 on %2" +#~ msgstr "%1 на %2" + +#~ msgid "This object could not be created." +#~ msgstr "Не удалось создать объект." + +#~ msgid "" +#~ "This object could not be created for the following reason:

%1

" +#~ msgstr "Не удалось создать объект по следующей причине:

%1

" + +#~ msgid "This plugin needs to be configured" +#~ msgstr "Это действие необходимо настроить" + +#~ msgid "Unknown ContainmentActions" +#~ msgstr "Неизвестный набор действий для контейнера" + +#~ msgid "Shortcut Settings" +#~ msgstr "Настроить комбинации клавиш" + +#~ msgid "Unnamed" +#~ msgstr "Без имени" + +#~ msgid "Show this group." +#~ msgstr "Показать эту группу" + +#~ msgid "Hide this group." +#~ msgstr "Скрыть эту группу" + +#~ msgid "Expand this widget" +#~ msgstr "Развернуть виджет" + +#~ msgid "Collapse this widget" +#~ msgstr "Свернуть виджет" + +#~ msgid "Reattach" +#~ msgstr "Встроить" + +#~ msgid "Close" +#~ msgstr "Закрыть" + +#~ msgid "This system does not support OpenGL widgets." +#~ msgstr "Система не поддерживает виджеты OpenGL." + +#~ msgid "Your machine does not support OpenGL widgets." +#~ msgstr "Компьютер не поддерживает виджеты OpenGL." + +#~ msgctxt "A non-functional package" +#~ msgid "Invalid" +#~ msgstr "Пакет с ошибкой" + +#~ msgid "" +#~ "There was an error attempting to exec the associated application with " +#~ "this widget." +#~ msgstr "Не удалось запустить соответствующее этому виджету приложение." + +#~ msgctxt "Error message, access to a remote service failed." +#~ msgid "Invalid token." +#~ msgstr "Недопустимый идентификатор подключения." + +#~ msgctxt "Error message, access to a remote service failed." +#~ msgid "Matching password required." +#~ msgstr "Неправильный пароль." + +#~ msgctxt "Error message, access to a remote service failed." +#~ msgid "Access denied." +#~ msgstr "Доступ запрещён." + +#~ msgid "Unknown error." +#~ msgstr "Неизвестная ошибка." + +#~ msgid "Main Config UI File" +#~ msgstr "Основной файл диалога настройки" + +#~ msgid "Animation scripts" +#~ msgstr "Сценарии анимации" + +#~ msgid "Recommended wallpaper file" +#~ msgstr "Рекомендованные обои" + +#~ msgid "" +#~ "Enter a password below. Enter the same password on the device to which " +#~ "you are trying to connect." +#~ msgstr "" +#~ "Введите пароль ниже. На компьютере, к которому вы подключаетесь, должен " +#~ "быть введён такой же пароль." + +#~ msgid "Allow this user access to any service" +#~ msgstr "Разрешить этому пользователю доступ ко всем службам" + +#~ msgid "Remember this user" +#~ msgstr "Запомнить этого пользователя" + +#~ msgid "Incoming connection request" +#~ msgstr "Запрос на подключение" + +#~ msgid "Connect with remote widget" +#~ msgstr "Подключение к удалённому виджету" + +#~ msgid "Job no longer valid, operation is not enabled." +#~ msgstr "Недопустимая задача: операция не разрешена." + +#~ msgid "Job no longer valid, invalid parameters." +#~ msgstr "Недопустимая задача: недопустимые параметры." + +#~ msgid "Timeout." +#~ msgstr "Время ожидания истекло." + +#~ msgid "Server sent an invalid plasmoid package." +#~ msgstr "Не удалось открыть пакет с виджетом, полученный от сервера." + +#~ msgid "You are about to open a remote widget on your system.
" +#~ msgstr "" +#~ "Вы собираетесь открыть удалённо доступный виджет на этом компьютере.
" + +#~ msgid "" +#~ msgstr "
" + +#~ msgid "" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ "" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ "" +#~ msgstr "" +#~ "" + +#~ msgid "" +#~ msgstr "" + +#~ msgid "
Name:  %1
Название:  %1
Description:  %1
Описание:  %1
Author:  %1 <%2>
Автор:  %1 <%2>
Server:  %1
Сервер:  %1
" +#~ msgstr "" + +#~ msgid "

Are you sure you want to open this widget on your system?" +#~ msgstr "

Открыть виджет на этом компьютере?" + +#~ msgid "Remote Widget" +#~ msgstr "Подключение к удалённому виджету" + +#~ msgid "Reject Widget" +#~ msgstr "Не открывать" + +#~ msgid "User rejected" +#~ msgstr "Пользователь запретил открытие этого виджета" + +#~ msgid "Timeout" +#~ msgstr "Время ожидания истекло." + +#~ msgid "" +#~ "Your system does not provide support for the 'remote widgets' feature. " +#~ "Access Failed." +#~ msgstr "" +#~ "Ваша система не поддерживает удалённый доступ к виджетам на других " +#~ "компьютерах." + +#~ msgid "Allow everybody access to %1." +#~ msgstr "Разрешить всем доступ к %1." + +#~ msgid "Deny everybody access to %1" +#~ msgstr "Запретить всем доступ к %1." + +#~ msgid "Allow %1 access to all services." +#~ msgstr "Разрешить пользователю %1 доступ ко всем службам." + +#~ msgid "Deny %1 access to all services." +#~ msgstr "Запретить пользователю %1 доступ ко всем службам." + +#~ msgid "Allow access to %1, by %2." +#~ msgstr "Разрешить пользователю %2 доступ к %1." + +#~ msgid "Deny access to %1, by %2." +#~ msgstr "Запретить пользователю %2 доступ к %1." + +#~ msgid "Allow access to %1, by %2?" +#~ msgstr "Разрешить пользователю %2 доступ к %1?" + +#~ msgid "You have requested access to the %1 hosted at %2." +#~ msgstr "Вы запросили доступ к %1 на %2." + +#~ msgid "search term" +#~ msgstr "поисковый запрос" + +#~ msgid "Unknown Wallpaper" +#~ msgstr "Неизвестные обои" + +#~ msgid "Share" +#~ msgstr "Удалённый доступ" + +#~ msgid "Ok" +#~ msgstr "ОК" + +#~ msgid "Yes" +#~ msgstr "Да" + +#~ msgid "No" +#~ msgstr "Нет" + +#~ msgid "This menu needs to be configured" +#~ msgstr "Это меню необходимо настроить" + +#~ msgid "Tool Box" +#~ msgstr "Инструменты Plasma" + +#~ msgid "" +#~ "Click to access configuration options and controls, or to add more " +#~ "widgets to the %1." +#~ msgstr "" +#~ "Нажмите здесь для настройки рабочего пространства Plasma или добавления " +#~ "новых виджетов в %1." + +#~ msgid "Panel Tool Box" +#~ msgstr "Настройка панели" + +#~ msgid "" +#~ "Click to access size, location and hiding controls as well as to add new " +#~ "widgets to the panel." +#~ msgstr "" +#~ "Нажмите здесь для настройки панели и добавления на неё новых виджетов." + +#~ msgid "%1 Activity" +#~ msgstr "Комната: %1" + +#~ msgid "Unknown Activity" +#~ msgstr "Неизвестная комната" + +#~ msgid "Zoom In" +#~ msgstr "Приблизить" + +#~ msgid "Zoom Out" +#~ msgstr "Отдалить" + +#~ msgid "Appearance Settings" +#~ msgstr "Внешний вид" + +#~ msgid "Background image for plasmoids" +#~ msgstr "Фоновое изображение для виджетов" + +#~ msgid "Low color background image for plasmoids" +#~ msgstr "Фоновое изображение с малым количеством цветов для виджетов" diff --git a/po/sa/libplasma6.po b/po/sa/libplasma6.po new file mode 100644 index 0000000..6be85cf --- /dev/null +++ b/po/sa/libplasma6.po @@ -0,0 +1,344 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the plasma-framework package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: plasma-framework\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2023-09-22 09:52+0530\n" +"Last-Translator: \n" +"Language-Team: Sanskrit \n" +"Language: sa\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.3.2\n" +"Plural-Forms: nplurals=2; plural=(n>2);\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "अधिकानि क्रियाः" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "संव्लीयते" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "वर्धयति" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "गुप्तपद" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "अन्वेषण…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "अन्वेषण" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "अज्ञात्" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "%1 विजेट् सक्रियताम्" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "%1 निष्कासयन्तु" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "सम्पादनविधिं प्रविशन्तु" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "%1 विन्यस्यताम्..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "विजेट् तालान्" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "विजेट् मुक्तं कुर्वन्तु" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "सम्पादन विधितः निर्गच्छन्तु" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "विषयस्य कृते भण्डारणसञ्चयस्य निर्माणं कर्तव्यं वा न वा।." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"भण्डारणस्थस्य विषयसञ्चयस्य अधिकतमः आकारः kilobyte मध्ये । ध्यानं कुर्वन्तु यत् एताः " +"सञ्चिकाः विरलसञ्चिकाः सन्ति, अतः अधिकतमस्य आकारस्य उपयोगः न भवितुं शक्नोति । अतः " +"बृहत्तरं आकारं निरूपयत् करणं प्रायः अत्यन्तं सुरक्षितं भवति ।." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "विकल्पान् दर्शयतु..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "विजेट् निष्कासितम्" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "\"%1\" इति विजेट् निष्कासितम् ।." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "फलकं निष्कासितम्" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "एकं फलकं निष्कासितम् अस्ति।." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "कार्यमुखं निष्कासितम्" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "एकः कार्यमुखः निष्कासितः अस्ति।." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "अपाकरोति" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "विजेट् समायोजननि" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "एतत् विजेट् निष्कासयन्तु" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "एतत् फलकं निष्कासयन्तु" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "एतत् क्रियाकलापं निष्कासयन्तु" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "क्रियाकलाप समायोजननि" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "अनुरोधितं घटकं न प्राप्नोत्: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, fuzzy, kde-format +#| msgid "The root item of %1 must be of type ContaimentItem" +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "%1 इत्यस्य मूलवस्तु ContaimentItem इति प्रकारस्य भवितुमर्हति" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "%1 इत्यस्य मूलवस्तु PlasmoidItem प्रकारस्य भवितुम् अर्हति" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "अज्ञात् Applet" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "QML सञ्चिकायाः आरोपयने त्रुटिः: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package inexistent. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Applet आरोपयने त्रुटिः: संकुलं अस्तित्वं नास्ति । %1" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "%1 समायोजननि" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 समायोजननि" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma सम्पुट" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "प्रतिस्थायतु" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "संकुलस्थापनं विफलम्" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "भवता इदानीं यत् संकुलं पातितम् तत् अमान्यम् अस्ति ।." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "विजेटस्" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "%1 योजयन्तु" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "चिह्नं योजयतु" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "दीवार्पत्तिः" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "%1 निरूपयतु" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "सामग्रीं पातितम्" + +#~ msgid "Add Widgets..." +#~ msgstr "विजेट्स् योजयन्तु..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "%2 विजेट् कृते आवश्यकं %1 संकुलं उद्घाटयितुं न शक्तम् ।." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "जालपुटे विजेट् साझाकरणेन अन्यस्मात् सङ्गणकात् दूरनियन्त्रणरूपेण एतत् विजेट् प्राप्तुं शक्यते ।." + +#~ msgid "Share this widget on the network" +#~ msgstr "एतत् विजेट् संजाले साझां कुर्वन्तु" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "सर्वेषां कृते एतत् विजेट् स्वतन्त्रतया प्राप्तुं अनुमतिं ददातु" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "अमान्य (लुप्तमूल्य) सेवा, किमपि कार्यं कर्तुं न शक्नोति ।." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "" +#~ "%1 विजेट् इत्यनेन कस्य ScriptEngine इत्यस्य उपयोगः करणीयः इति न परिभाषितम् ।." diff --git a/po/sk/libplasma6.po b/po/sk/libplasma6.po new file mode 100644 index 0000000..787fb78 --- /dev/null +++ b/po/sk/libplasma6.po @@ -0,0 +1,1072 @@ +# translation of libplasma.po to Slovak +# Roman Paholik , 2012, 2013, 2014, 2015, 2016. +# Mthw , 2019. +# Matej Mrenica , 2019, 2020, 2021, 2022, 2023. +# Dusan Kazik , 2020. +msgid "" +msgstr "" +"Project-Id-Version: libplasma\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2023-01-11 11:24+0100\n" +"Last-Translator: Matej Mrenica \n" +"Language-Team: Slovak \n" +"Language: sk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 22.12.1\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Viac akcií" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Zbaliť" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Rozbaliť" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Heslo" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Hľadať..." + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Hľadať" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Neznáme" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Aktivovať miniaplikáciu %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Odstrániť %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Prejsť do režimu úprav" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Nastaviť %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Uzamknúť miniaplikácie" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Odomknúť miniaplikácie" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Ukončiť režim úprav" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Či vytvoriť cache na disku pre tému." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Maximálna veľkosť cache na disku pre tému v kilobajtoch. Tieto súbory sú " +"dosť riedke, teda maximálna veľkosť sa nemusí použiť. Nastavenie väčšej " +"veľkosti je však bezpečné." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Zobraziť alternatívy..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Miniaplikácia bola odstránená" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Miniaplikácia \"%1\" bola odstránená." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panel odstránený" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Panel bol odstránený." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Pracovná plocha odstránená" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Plocha bola odstránená." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Späť" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Nastavenia miniaplikácie" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Odstrániť túto miniaplikáciu" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Odstrániť tento panel" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Odstrániť túto aktivitu" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Nastavenia aktivity" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Nepodarilo sa nájsť požadovaný komponent: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Neznámy applet" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Chyba čítania súboru QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package inexistent. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Chyba načítania appletu: balík neexistuje. %1" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "Nastavenia %1" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Nastavenia %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma balík" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Inštalovať" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Inštalácia balíčka zlyhala" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Balík, ktorý ste pustili, je neplatný." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Miniaplikácie" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Pridať %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Pridať ikonu" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Tapeta" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Nastaviť %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Obsah zahodený" + +#~ msgid "Add Widgets..." +#~ msgstr "Pridať miniaplikácie..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Nepodarilo sa otvoriť balík %1 potrebný pre miniaplikáciu %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Zdieľanie miniaplikácie v sieti umožňuje vzdialený prístup a ovládanie " +#~ "tejto miniaplikácie z iného počítača." + +#~ msgid "Share this widget on the network" +#~ msgstr "Zdieľať túto miniaplikáciu v sieti" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Povoliť všetkým voľný prístup k tejto miniaplikácii" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Neplatná (prázdna) služba, nie je možné vykonať žiadnu operáciu." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Miniaplikácia %1 nedefinuje, ktorý ScriptEngine sa má použiť." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Rôzne" + +#~ msgid "Main Script File" +#~ msgstr "Hlavný súbor skriptu" + +#~ msgid "Tests" +#~ msgstr "Testy" + +#~ msgid "Images" +#~ msgstr "Obrázky" + +#~ msgid "Themed Images" +#~ msgstr "Témované obrázky" + +#~ msgid "Configuration Definitions" +#~ msgstr "Definície konfigurácie" + +#~ msgid "User Interface" +#~ msgstr "Užívateľské rozhranie" + +#~ msgid "Data Files" +#~ msgstr "Dátové súbory" + +#~ msgid "Executable Scripts" +#~ msgstr "Spustiteľné skripty" + +#~ msgid "Screenshot" +#~ msgstr "Snímka obrazovky" + +#~ msgid "Translations" +#~ msgstr "Preklady" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Nastavene modelu UI stránok" + +#~ msgid "Configuration XML file" +#~ msgstr "Konfiguračný XML súbor" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Vlastný expander pre kompaktné applety" + +#~ msgid "Images for dialogs" +#~ msgstr "Obrázky pre dialógy" + +#~ msgid "Generic dialog background" +#~ msgstr "Všeobecné pozadie dialógu" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Téma pre dialóg odhlásenia" + +#~ msgid "Wallpaper packages" +#~ msgstr "Balíky tapiet" + +#~ msgid "Images for widgets" +#~ msgstr "Obrázky pre miniaplikácie" + +#~ msgid "Background image for widgets" +#~ msgstr "Obrázok pozadia pre miniaplikácie" + +#~ msgid "Analog clock face" +#~ msgstr "Vzhľad analógových hodín" + +#~ msgid "Background image for panels" +#~ msgstr "Obrázok pozadia pre panely" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Pozadie pre miniaplikácie s grafom" + +#~ msgid "Background image for tooltips" +#~ msgstr "Obrázok pozadia pre rady" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Nepriehľadné obrázky pre dialógy" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Všeobecné nepriehľadné pozadie dialógu" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Nepriehľadná téma pre dialóg odhlásenia" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Nepriehľadné obrázky pre miniaplikácie" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Nepriehľadný obrázok pozadia pre panely" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Nepriehľadný obrázok pozadia pre rady" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Konfiguračný súbor KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Popisy služby" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "" +#~ "Nepodarilo sa vytvoriť skriptovacie rozhranie %1 pre miniaplikáciu %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Inicializácia skriptu zlyhala" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Sviatky" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Udalosti" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Úloha" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Iné" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Predchádzajúci mesiac" + +#~ msgid "Previous Year" +#~ msgstr "Predchádzajúci rok" + +#~ msgid "Previous Decade" +#~ msgstr "Predošlá dekáda" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Dnes" + +#~ msgid "Reset calendar to today" +#~ msgstr "Vynulovať kalendár na dnes" + +#~ msgid "Next Month" +#~ msgstr "Nasledujúci mesiac" + +#~ msgid "Next Year" +#~ msgstr "Nasledujúci rok" + +#~ msgid "Next Decade" +#~ msgstr "Ďalšia dekáda" + +#~ msgid "Days" +#~ msgstr "Dni" + +#~ msgid "Months" +#~ msgstr "Mesiace" + +#~ msgid "Years" +#~ msgstr "Roky" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "Zrušiť" + +#~ msgid "Run the Associated Application" +#~ msgstr "Spustiť priradenú aplikáciu" + +#~ msgid "Open with %1" +#~ msgstr "Otvoriť pomocou %1" + +#~ msgid "Accessibility" +#~ msgstr "Prístupnosť" + +#~ msgid "Application Launchers" +#~ msgstr "Spúšťače aplikácií" + +#~ msgid "Astronomy" +#~ msgstr "Astronómia" + +#~ msgid "Date and Time" +#~ msgstr "Dátum a čas" + +#~ msgid "Development Tools" +#~ msgstr "Vývojové nástroje" + +#~ msgid "Education" +#~ msgstr "Vzdelávanie" + +#~ msgid "Environment and Weather" +#~ msgstr "Prostredie a počasie" + +#~ msgid "Examples" +#~ msgstr "Príklady" + +#~ msgid "File System" +#~ msgstr "Súborový systém" + +#~ msgid "Fun and Games" +#~ msgstr "Zábava a hry" + +#~ msgid "Graphics" +#~ msgstr "Grafika" + +#~ msgid "Language" +#~ msgstr "Jazyk" + +#~ msgid "Mapping" +#~ msgstr "Kartografia" + +#~ msgid "Miscellaneous" +#~ msgstr "Rôzne" + +#~ msgid "Multimedia" +#~ msgstr "Multimédiá" + +#~ msgid "Online Services" +#~ msgstr "Online služby" + +#~ msgid "Productivity" +#~ msgstr "Produktivita" + +#~ msgid "System Information" +#~ msgstr "Informácie o systéme" + +#~ msgid "Utilities" +#~ msgstr "Nástroje" + +#~ msgid "Windows and Tasks" +#~ msgstr "Okná a úlohy" + +#~ msgid "Clipboard" +#~ msgstr "Schránka" + +#~ msgid "Tasks" +#~ msgstr "Úlohy" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Upraviť %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Predvolené nastavenia pre tému atď." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Farebná schéma na použitie pre aplikácie." + +#~ msgid "Preview Images" +#~ msgstr "Náhľad obrázkov" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Náhľad pre správcu prihlásenia" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Náhľad pre zamknutie obrazovky" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Náhľad pre prepínač používateľov" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Náhľad pre prepínač virtuálnych plôch" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Náhľad pre úvodnú obrazovku" + +#~ msgid "Preview for KRunner" +#~ msgstr "Náhľad pre KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Náhľad pre dekorácie okien" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Náhľad pre prepínač okien" + +#~ msgid "Login Manager" +#~ msgstr "Správca prihlásenia" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Hlavný skript pre správcu prihlásenia" + +#~ msgid "Logout Dialog" +#~ msgstr "Dialóg odhlásenia" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Hlavný skript pre dialóg odhlásenia" + +#~ msgid "Screenlocker" +#~ msgstr "Zamykač obrazovky" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Hlavný skript pre zamknutie obrazovky" + +#~ msgid "UI for fast user switching" +#~ msgstr "UI pre rýchle prepínanie používateľov" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Hlavný skript pre prepínač používateľov" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Prepínač virtuálnych plôch" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Hlavný skript pre prepínač virtuálnych plôch" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Upozornenia na obrazovke" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Hlavný skript pre upozornenia na obrazovke" + +#~ msgid "Splash Screen" +#~ msgstr "Úvodná obrazovka" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Hlavný skript pre úvodnú obrazovku" + +#~ msgid "KRunner UI" +#~ msgstr "KRunner UI" + +#~ msgid "Main Script KRunner" +#~ msgstr "Hlavný skript KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Dekorácie okien" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Hlavný skript pre dekorácie okien" + +#~ msgid "Window Switcher" +#~ msgstr "Prepínač okien" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Hlavný skript pre prepínač používateľov" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Dokončiť prispôsobenie rozloženia" + +#~ msgid "Customize Layout..." +#~ msgstr "Prispôsobiť rozloženie..." + +#~ msgid "Fetching file type..." +#~ msgstr "Sťahuje sa typ súboru..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Voľby %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Odstrániť - %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Nastavenia %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Nastavenia %1..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Nízkofarebné obrázky pre dialógy" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Nízkofarebné všeobecné pozadie dialógu" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Nízkofarebná téma pre dialóg odhlásenia" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Nízkofarebný obrázok pozadia pre widgety" + +#~ msgid "Low color analog clock face" +#~ msgstr "Nízkofarebný vzhľad analógových hodín" + +#~ msgid "Low color background image for panels" +#~ msgstr "Nízkofarebný obrázok pozadia pre panely" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Nízkofarebné pozadie pre widgety s grafom" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Nízkofarebný obrázok pozadia pre rady" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Správca balíčkov Plasmy" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Generovať SHA1 hash pre balíček na " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Pre inštaláciu alebo odstránenie balíčkov inštalovaných pre všetkých " +#~ "užívateľov." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Typ balíčka, napr. theme, wallpaper, plasmoid, dataengine, runner, layout-" +#~ "template, atď." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Nainštaluje balíček z " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Zobraziť informácie balíka " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Aktualizuje balíček z " + +#~ msgid "List installed packages" +#~ msgstr "Vypíše nainštalované balíčky" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "Vypísať všetky známe typy balíčkov, ktoré je možné nainštalovať" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Odstráni balíček s názvom " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Absolútna cesta ku koreňu balíka. Ak nie je zadaná, prehľadajú sa " +#~ "štandardné dátové adresáre pre toto KDE sedenie." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Zlyhalo generovanie hashu balíčka pre %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "SHA1 hash pre balíček na %1: '%2'" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "wallpaper" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "balík" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "téma" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "dataengine" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "runner" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "wallpaperplugin" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "lookandfeel" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "shell" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "layout-template" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "kwineffect" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "windowswitcher" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "kwinscript" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "Nepodarilo sa nájsť vhodný inštalátor pre balíček typu %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "Vypisujem typy služieb: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Chyba: Plugin %1 nie je nainštalovaný." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Je vyžadovaná inštalácia, odstránenie, aktualizácia, alebo výpis." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Chyba: Nemôžem nájsť metadáta pluginu: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Zobrazujem informácie pre balík: %1" + +#~ msgid " Name : %1" +#~ msgstr " Názov : %1" + +#~ msgid " Comment : %1" +#~ msgstr " Komentár : %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Plugin : %1" + +#~ msgid " Author : %1" +#~ msgstr " Autor : %1" + +#~ msgid " Path : %1" +#~ msgstr " Cesta : %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Možnosti packageroot a global sú navzájom v konflikte. Použite iba jednu " +#~ "z nich." + +#~ msgid "Addon Name" +#~ msgstr "Názov addonu" + +#~ msgid "Service Type" +#~ msgstr "Typ služby" + +#~ msgid "Path" +#~ msgstr "Cesta" + +#~ msgid "Type Argument" +#~ msgstr "Napísať argument" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Typy balíčkov, ktoré môžete nainštalovať pomocou tohto nástroja:" + +#~ msgid "Built in:" +#~ msgstr "Vstavané:" + +#~ msgid "DataEngine" +#~ msgstr "DataEngine" + +#~ msgid "Layout Template" +#~ msgstr "Šablóna rozloženia" + +#~ msgid "Look and Feel" +#~ msgstr "Vzhľad a nastavenie" + +#~ msgid "Package" +#~ msgstr "Balík" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoid" + +#~ msgid "Runner" +#~ msgstr "Runner" + +#~ msgid "Shell" +#~ msgstr "Shell" + +#~ msgid "Theme" +#~ msgstr "Téma" + +#~ msgid "Wallpaper Images" +#~ msgstr "Obrázky tapety" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Animovaná tapeta" + +#~ msgid "KWin Effect" +#~ msgstr "Efekt KWin" + +#~ msgid "KWin Window Switcher" +#~ msgstr "Prepínač okien KWin" + +#~ msgid "KWin Script" +#~ msgstr "KWin skript" + +#~ msgid "Provided by plugins:" +#~ msgstr "Poskytované modulmi:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Poskytované súbormi .desktop:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "Úspešne aktualizované %1" + +#~ msgid "Successfully installed %1" +#~ msgstr "Úspešne nainštalované %1" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Chyba: Inštalácia %1 zlyhala: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Aktualizujem balík zo súboru: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Úspešne odinštalované %1" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Chyba: Odinštalácia %1 zlyhala: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Nepodarilo sa načítať inštalátor pre balíček typu %1. Bola hlásená chyba: " +#~ "%2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Nemôžem vytvoriť koreňový adresár balíka: %1" + +#~ msgid "No such file: %1" +#~ msgstr "Súbor neexistuje: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "Nemôžem otvoriť súbor balíka, nepodporovaný formát archívu: %1 %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "Nemôžem otvoriť súbor balíka: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "Žiadne metadáta v balíku: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "Nie je zadaný názov balíka pluginu: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "Názov balíka pluginu %1 obsahuje neplatné znaky" + +#~ msgid "%1 already exists" +#~ msgstr "%1 už existuje" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Nemôžem presunúť balík do cieľa: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Nemôžem kopírovať balík do cieľa: %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Nemôžem vytvoriť miestny adresár služby: %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "Nemôžem zaregistrovať balík ako službu (toto nie je nevyhnutne kritické): " +#~ "%1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 neexistuje" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Nemôžem vymazať balík z: %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "Naozaj chcete odstrániť %1?" + +#~ msgid "Applets furniture" +#~ msgstr "Nábytok appletov" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "UI prehliadača pre pridávania widgetov" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "Používateľské rozhranie pre pohľady, ktoré zobrazia obsah" + +#~ msgid "Default layout file" +#~ msgstr "Súbor predvoleného rozloženia" + +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "Predvolené pluginy pre obsah, akcie obsahu atď." + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "Zobrazená chybová správa, keď zlyhá načítanie appletu" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "QML komponent, ktorý zobrazí applet vo vyskakovacom okne" + +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Kompaktná reprezentácia appletu, keď je zbalený v okne, napríklad ako " +#~ "ikona. Applety môžu prepísať tento komponent." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "QML komponent pre dialóg nastavenia pre applety" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "QML komponent pre dialóg nastavenia pre obsah" + +#~ msgid "Panel configuration UI" +#~ msgstr "UI konfiguračného panelu" + +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "QML komponent pre výber alternatívneho appletu" + +#~ msgid "" +#~ "A UI for writing, loading and running desktop scripts in the current live " +#~ "session" +#~ msgstr "" +#~ "UI na písanie, načítavanie a spúšťanie desktopových skriptov v aktuálnom " +#~ "sedení" + +#~ msgid "Theme preview thumbnail" +#~ msgstr "Miniatúra náhľadu témy" + +#~ msgid "Ok" +#~ msgstr "Ok" diff --git a/po/sl/libplasma6.po b/po/sl/libplasma6.po new file mode 100644 index 0000000..a6a3a11 --- /dev/null +++ b/po/sl/libplasma6.po @@ -0,0 +1,590 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the plasma-framework package. +# +# +# Andrej Mernik , 2014, 2015, 2016. +# Matjaž Jeran , 2019, 2020, 2021, 2022. +# Martin Srebotnjak , 2022. +# Jure Repinc , 2024. +msgid "" +msgstr "" +"Project-Id-Version: plasma-framework\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-23 06:34+0200\n" +"Last-Translator: Matjaž Jeran \n" +"Language-Team: LUGOS\n" +"Language: sl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n" +"%100==4 ? 3 : 0);\n" +"Translator: Andrej Mernik \n" +"X-Generator: Poedit 3.4.4\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Več dejavnosti" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Podri" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Razširi" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Geslo" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Poišči …" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Poišči" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Počisti iskanje" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Neznan" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Omogoči gradnik %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Odstrani %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Vstop v urejevalni način" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Nastavi %1 …" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Zakleni gradnike" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Odkleni gradnike" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Izhod iz urejevalnega načina" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Ali se naj za temo ustvari predpomnilnik na disku." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Največja velikost diskovnega predpomnilnika za temo v kilobajtih. Zapomnite " +"si, da so te datoteke raztresene, zato ni mogoče uporabiti največje " +"velikosti. Pogosto je varno, da nastavite večjo velikost." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Pokaži alternative …" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Gradnik odstranjen" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Gradnik '%1' je bil odstranjen." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Plošča odstranjena" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Plošča je bila odstranjena." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Namizje odstranjeno" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Namizje je bilo odstranjeno." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Razveljavi" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Nastavitve gradnika" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Odstrani ta gradnik" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Odstrani to ploščo" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Odstrani to dejavnost" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Nastavitve dejavnosti" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Dodaj ali upravljaj gradnike…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Ni bilo mogoče najti zahtevanega sestavnega dela: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Korenska postavka %1 mora biti zvrsti ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Korenska postavka %1 mora biti zvrsti ContaimentItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Neznan applet" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Ta gradnik je bil napisan za neznano starejšo različico Plasme in ni " +"združljiv s Plasmo %1. Obrnite se na avtorja pripomočka za posodobljeno " +"različico." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 ni združljiv s Plasmo %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Ta gradnik je bil napisan za Plasmo %1 in ni združljiv s Plasmo %2. Obrnite " +"se na avtorja pripomočka za posodobljeno različico." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Ta gradnik je bil napisan za Plasmo %1 in ni združljiv s Plasmo %2. " +"Posodobite Plasmo, če želite uporabljati ta gradnik." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Oprostite! Prišlo je do napake pri nalaganju %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Napaka pri nalaganju datoteke QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Napaka med nalaganjem apleta: paket %1 ne obstaja." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 Nastavitve" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Nastavitve za %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Paket za Plasmo" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Namesti" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Namestitev paketa ni uspela" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Pravkar spuščen paket ni veljaven." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Gradniki" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Dodaj %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Dodaj ikono" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Ozadje" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Postavi %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Vsebina spuščena" + +#~ msgid "Add Widgets..." +#~ msgstr "Dodaj gradnike ..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Ni bilo mogoče odpreti paketa %1, ki je zahtevan za gradnik %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Če gradnik daste v souporabo prek omrežja, lahko do njega dostopate in ga " +#~ "daljinsko upravljate z drugega računalnika." + +#~ msgid "Share this widget on the network" +#~ msgstr "Deli ta gradnik na omrežju" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Dovoli vsakomur, da prosto dostopa do tega gradnika" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Neveljavna (nična) storitev, ki ne more izvajati opravil." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Gradnik %1 ni določil kateri skriptni pogon bo uporabljen." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Razno" + +#~ msgid "Main Script File" +#~ msgstr "Glavna skriptna datoteka" + +#~ msgid "Tests" +#~ msgstr "Preizkusi" + +#~ msgid "Images" +#~ msgstr "Slike" + +#~ msgid "Themed Images" +#~ msgstr "Tematske slike" + +#~ msgid "Configuration Definitions" +#~ msgstr "Določila nastavitev" + +#~ msgid "User Interface" +#~ msgstr "Uporabniški vmesnik" + +#~ msgid "Data Files" +#~ msgstr "Datoteke s podatki" + +#~ msgid "Executable Scripts" +#~ msgstr "Izvedljivi skripti" + +#~ msgid "Screenshot" +#~ msgstr "Zaslonska slika" + +#~ msgid "Translations" +#~ msgstr "Prevodi" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Model strani nastavitvenega vmesnika" + +#~ msgid "Configuration XML file" +#~ msgstr "Datoteka XML z nastavitvami" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Razširilnik po meri za strnjene aplete" + +#~ msgid "Images for dialogs" +#~ msgstr "Slike za pogovorna okna" + +#~ msgid "Generic dialog background" +#~ msgstr "Splošno ozadje pogovornih oken" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Tema pogovornega okna za odjavo" + +#~ msgid "Wallpaper packages" +#~ msgstr "Paketi z ozadji" + +#~ msgid "Images for widgets" +#~ msgstr "Slike za gradnike" + +#~ msgid "Background image for widgets" +#~ msgstr "Slika ozadja za gradnike" + +#~ msgid "Analog clock face" +#~ msgstr "Slika za analogno uro" + +#~ msgid "Background image for panels" +#~ msgstr "Slika ozadja za pulte" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Ozadje za gradnike z grafi" + +#~ msgid "Background image for tooltips" +#~ msgstr "Slika ozadja za orodne namige" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Prekrivne slike za pogovorna okna" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Prekrivno splošno ozadje pogovornih oken" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Prekrivna tema pogovornega okna za odjavo" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Prekrivne slike za gradnike" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Prekrivna slika ozadja za pulte" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Prekrivna slika ozadja za orodne namige" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Nastavitvena datoteka KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Opisi storitev" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Ni bilo mogoče ustvariti skriptnega pogona %1 za gradnik %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Začenjanje skripta je spodletelo" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Prazniki" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Dogodki" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Za narediti" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Drugo" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Prejšnji mesec" + +#~ msgid "Previous Year" +#~ msgstr "Prejšnje leto" + +#~ msgid "Previous Decade" +#~ msgstr "Prejšnje desetletje" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Danes" + +#~ msgid "Reset calendar to today" +#~ msgstr "Ponastavi koledar na današnji dan" + +#~ msgid "Next Month" +#~ msgstr "Naslednji mesec" + +#~ msgid "Next Year" +#~ msgstr "Naslednje leto" + +#~ msgid "Next Decade" +#~ msgstr "Naslednje desetletje" + +#~ msgid "Days" +#~ msgstr "Dni" + +#~ msgid "Months" +#~ msgstr "Mesecev" + +#~ msgid "Years" +#~ msgstr "Let" + +#~ msgid "OK" +#~ msgstr "V redu" + +#~ msgid "Cancel" +#~ msgstr "Prekliči" + +#~ msgid "Run the Associated Application" +#~ msgstr "Zaženi povezan program" + +#~ msgid "Open with %1" +#~ msgstr "Odpri z %1" + +#~ msgid "Accessibility" +#~ msgstr "Dostopnost" + +#~ msgid "Application Launchers" +#~ msgstr "Zaganjalniki programov" + +#~ msgid "Astronomy" +#~ msgstr "Astronomija" + +#~ msgid "Date and Time" +#~ msgstr "Datum in čas" + +#~ msgid "Development Tools" +#~ msgstr "Razvojna orodja" + +#~ msgid "Education" +#~ msgstr "Izobraževanje" + +#~ msgid "Environment and Weather" +#~ msgstr "Okolje in vreme" + +#~ msgid "Examples" +#~ msgstr "Primeri" + +#~ msgid "File System" +#~ msgstr "Datotečni sistem" + +#~ msgid "Fun and Games" +#~ msgstr "Zabava in igre" + +#~ msgid "Graphics" +#~ msgstr "Grafika" + +#~ msgid "Language" +#~ msgstr "Jezik" + +#~ msgid "Mapping" +#~ msgstr "Kartiranje" + +#~ msgid "Miscellaneous" +#~ msgstr "Razno" + +#~ msgid "Multimedia" +#~ msgstr "Predstavnost" + +#~ msgid "Online Services" +#~ msgstr "Spletne storitve" + +#~ msgid "Productivity" +#~ msgstr "Učinkovitost" + +#~ msgid "System Information" +#~ msgstr "Podatki o sistemu" + +#~ msgid "Utilities" +#~ msgstr "Pripomočki" + +#~ msgid "Windows and Tasks" +#~ msgstr "Okna in opravila" + +#~ msgid "Clipboard" +#~ msgstr "Odložišče" + +#~ msgid "Tasks" +#~ msgstr "Opravila" diff --git a/po/sr/libplasma6.po b/po/sr/libplasma6.po new file mode 100644 index 0000000..dd16c58 --- /dev/null +++ b/po/sr/libplasma6.po @@ -0,0 +1,762 @@ +# Translation of libplasma5.po into Serbian. +# Chusslove Illich , 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017. +# Dalibor Djuric , 2009. +msgid "" +msgstr "" +"Project-Id-Version: libplasma5\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2016-03-20 15:24+0100\n" +"Last-Translator: Chusslove Illich \n" +"Language-Team: Serbian \n" +"Language: sr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n" +"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" +"X-Environment: kde\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Непознато" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Активирај виџет %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, fuzzy, kde-format +#| msgctxt "%1 is the name of the applet" +#| msgid "Remove this %1" +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "" +"Уклони овај %1|/|Уклони $[по-роду-броју %1 овај ову ово ове ове ова] $[аку " +"%1]" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Закључај виџете" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Откључај виџете" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Да ли направити кеш на диску за тему." + +# skip-rule: t-setting +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Највећа величина кеша теме на диску у килобајтима. Имајте на уму да су ови " +"фајлови ретки, тако да задата величина не мора бити потпуно искоришћена. " +"Зато је задавање веће вредности често сасвим безбедно." + +#: plasma/private/applet_p.cpp:119 +#, fuzzy, kde-format +#| msgid "Alternatives..." +msgid "Show Alternatives..." +msgstr "Алтернативе..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Виџет уклоњен" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Виџет „%1“ је уклоњен." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Панел уклоњен" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Панел је уклоњен." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Површ уклоњена" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Површ је уклоњена." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Опозови" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Поставке виџета" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Уклони овај виџет" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Уклони овај панел" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Уклони ову активност" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Поставке активности" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Не могу да нађем захтевану компоненту: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, fuzzy, kde-format +#| msgid "Unknown" +msgid "Unknown Applet" +msgstr "Непознато" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, fuzzy, kde-format +#| msgid "Error loading QML file: %1" +msgid "Error loading QML file: %1 %2" +msgstr "Грешка при учитавању КуМЛ фајла: %1" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package inexistent. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Грешка при учитавању аплета: пакет не постоји. %1" + +# >> %1 is provider name +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "Поставке %1|/|Поставке $[ген %1]" + +# >> %1 is provider name +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Поставке %1|/|Поставке $[ген %1]" + +# >> @title +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Плазма пакет" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Инсталирај" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Пропало инсталирање пакета" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Пакет који сте управо испустили није добар." + +# >> @title +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Виџети" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "" + +# >> @action +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, fuzzy, kde-format +#| msgid "Icon" +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Иконица" + +# >> @title +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Тапет" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Садржај превучен" + +#~ msgid "Add Widgets..." +#~ msgstr "Додај виџете..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Не могу да отворим пакет %1 неопходан за виџет %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Дељење виџета на мрежи омогућава вам да приступите том виџету са другог " +#~ "рачунара као даљинским управљачем." + +#~ msgid "Share this widget on the network" +#~ msgstr "Подели овај виџет на мрежи" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Дозволи свима слободан приступ овом виџету" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Неисправан (нулти) сервис, не може извршити никакву операцију." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Виџет %1 не дефинише који скриптни мотор треба за њега." + +# >> @item applet category +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "разно" + +# >> @item:intext +#~ msgid "Main Script File" +#~ msgstr "главни фајл скрипте" + +# >> @item:intext +#~ msgid "Tests" +#~ msgstr "пробе" + +# >> @item file/directory definition +#~ msgid "Images" +#~ msgstr "слике" + +# >> @item file/directory definition +#~ msgid "Themed Images" +#~ msgstr "тематске слике" + +# >> @item file/directory definition +#~ msgid "Configuration Definitions" +#~ msgstr "дефиниције поставе" + +# >> @item file/directory definition +#~ msgid "User Interface" +#~ msgstr "корисничко сучеље" + +# >> @item file/directory definition +#~ msgid "Data Files" +#~ msgstr "подаци" + +# >> @item file/directory definition +#~ msgid "Executable Scripts" +#~ msgstr "извршне скрипте" + +# >> @item file/directory definition +#~ msgid "Screenshot" +#~ msgstr "снимак екрана" + +# >> @item file/directory definition +#~ msgid "Translations" +#~ msgstr "преводи" + +# >> @item file/directory definition +#~ msgid "Configuration UI pages model" +#~ msgstr "модел УИ страница поставе" + +# >> @item file/directory definition +#~ msgid "Configuration XML file" +#~ msgstr "ИксМЛ фајл поставе" + +# >> @item file/directory definition +#~ msgid "Custom expander for compact applets" +#~ msgstr "посебни проширивач за сажете аплете" + +# >> @item file/directory definition +#~ msgid "Images for dialogs" +#~ msgstr "слике за дијалоге" + +# >> @item file/directory definition +#~ msgid "Generic dialog background" +#~ msgstr "генеричка позадина дијалога" + +# >> @item file/directory definition +#~ msgid "Theme for the logout dialog" +#~ msgstr "тема за одјавни дијалог" + +# >> @item file/directory definition +#~ msgid "Wallpaper packages" +#~ msgstr "пакети тапета" + +# >> @item file/directory definition +#~ msgid "Images for widgets" +#~ msgstr "слике за виџете" + +# >> @item file/directory definition +#~ msgid "Background image for widgets" +#~ msgstr "позадинска слика за виџете" + +# >> @item file/directory definition +#~ msgid "Analog clock face" +#~ msgstr "лице аналогног сата" + +# >> @item file/directory definition +#~ msgid "Background image for panels" +#~ msgstr "позадинска слика за панеле" + +# >> @item file/directory definition +#~ msgid "Background for graphing widgets" +#~ msgstr "позадина за цртачке виџете" + +# >> @item file/directory definition +#~ msgid "Background image for tooltips" +#~ msgstr "позадинска слика за облачиће" + +# >> @item file/directory definition +#~ msgid "Opaque images for dialogs" +#~ msgstr "непрозирне слике за дијалоге" + +# >> @item file/directory definition +#~ msgid "Opaque generic dialog background" +#~ msgstr "непрозирна генеричка позадина дијалога" + +# >> @item file/directory definition +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "непрозирна тема за одјавни дијалог" + +# >> @item file/directory definition +#~ msgid "Opaque images for widgets" +#~ msgstr "непрозирне слике за виџете" + +# >> @item file/directory definition +#~ msgid "Opaque background image for panels" +#~ msgstr "непрозирна позадинска слика за панеле" + +# >> @item file/directory definition +#~ msgid "Opaque background image for tooltips" +#~ msgstr "непрозирна позадинска слика за облачиће" + +# >> @item file/directory definition +#~ msgid "KColorScheme configuration file" +#~ msgstr "поставни фајл шеме боја" + +# >> @item file/directory definition +#~ msgid "Service Descriptions" +#~ msgstr "описи сервиса" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Не могу да створим скриптни мотор %1 за виџет %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Неуспело припремање скрипте" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Празници" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Догађаји" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Обавезе" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Друго" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Данас" + +#~ msgid "Reset calendar to today" +#~ msgstr "Ресетуј календар на данас" + +#~ msgid "Previous Month" +#~ msgstr "Претходни месец" + +#~ msgid "Next Month" +#~ msgstr "Наредни месец" + +#~ msgid "Previous Year" +#~ msgstr "Претходна година" + +#~ msgid "Next Year" +#~ msgstr "Наредна година" + +#~ msgid "Previous Decade" +#~ msgstr "Претходна деценија" + +#~ msgid "Next Decade" +#~ msgstr "Наредна деценија" + +#~ msgid "OK" +#~ msgstr "У реду" + +#~ msgid "Cancel" +#~ msgstr "Одустани" + +# >> @item applet category +#~ msgid "Accessibility" +#~ msgstr "приступачност" + +# >> @item applet category +#~ msgid "Application Launchers" +#~ msgstr "покретачи програма" + +# >> @item applet category +#~ msgid "Astronomy" +#~ msgstr "астрономија" + +# >> @item applet category +#~ msgid "Date and Time" +#~ msgstr "датум и време" + +# >> @item applet category +#~ msgid "Development Tools" +#~ msgstr "развојне алатке" + +# >> @item applet category +#~ msgid "Education" +#~ msgstr "образовање" + +# >> @item applet category +#~ msgid "Environment and Weather" +#~ msgstr "природа и време" + +# >> @item applet category +#~ msgid "Examples" +#~ msgstr "примери" + +# >> @item applet category +#~ msgid "File System" +#~ msgstr "фајл систем" + +# >> @item applet category +#~ msgid "Fun and Games" +#~ msgstr "забава и игре" + +# >> @item applet category +#~ msgid "Graphics" +#~ msgstr "графика" + +# >> @item applet category +#~ msgid "Language" +#~ msgstr "језик" + +# >> @item applet category +#~ msgid "Mapping" +#~ msgstr "картографија" + +# >> @item applet category +#~ msgid "Miscellaneous" +#~ msgstr "разно" + +# >> @item applet category +#~ msgid "Multimedia" +#~ msgstr "мултимедија" + +# >> @item applet category +#~ msgid "Online Services" +#~ msgstr "сервиси на вези" + +# >> @item applet category +#~ msgid "Productivity" +#~ msgstr "продуктивност" + +# >> @item applet category +#~ msgid "System Information" +#~ msgstr "подаци о систему" + +# >> @item applet category +#~ msgid "Utilities" +#~ msgstr "алатке" + +# >> @item applet category +#~ msgid "Windows and Tasks" +#~ msgstr "прозори и задаци" + +# >> @item applet category +#~ msgid "Clipboard" +#~ msgstr "клипборд" + +# >> @item applet category +#~ msgid "Tasks" +#~ msgstr "задаци" + +#~ msgid "Run the Associated Application" +#~ msgstr "Изврши придружени програм" + +#~ msgid "Open with %1" +#~ msgstr "Отвори помоћу %1|/|Отвори $[инс-п %1]" + +# >> @item file/directory definition +#~ msgid "Default settings for theme, etc." +#~ msgstr "подразумеване поставке за тему, итд." + +# >> @item file/directory definition +#~ msgid "Color scheme to use for applications." +#~ msgstr "шема боја у програмима" + +# >> @item file/directory definition +#~ msgid "Preview Images" +#~ msgstr "слике прегледа" + +# >> @item file/directory definition +#~ msgid "Preview for the Login Manager" +#~ msgstr "преглед за менаџер пријављивања" + +# >> @item file/directory definition +#~ msgid "Preview for the Lock Screen" +#~ msgstr "преглед за забравни екран" + +# >> @item file/directory definition +#~ msgid "Preview for the Userswitcher" +#~ msgstr "преглед за мењач корисника" + +# >> @item file/directory definition +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "преглед за мењач виртуелних површи" + +# >> @item file/directory definition +#~ msgid "Preview for Splash Screen" +#~ msgstr "преглед за уводни екран" + +# >> @item file/directory definition +#~ msgid "Preview for KRunner" +#~ msgstr "преглед за К‑извођач" + +# >> @item file/directory definition +#~ msgid "Preview for the Window Decorations" +#~ msgstr "преглед за декорације прозора" + +# >> @item file/directory definition +#~ msgid "Preview for Window Switcher" +#~ msgstr "преглед за мењач прозора" + +# >> @item file/directory definition +#~ msgid "Login Manager" +#~ msgstr "менаџер пријављивања" + +# >> @item file/directory definition +#~ msgid "Main Script for Login Manager" +#~ msgstr "главна скрипт за менаџер пријављивања" + +# >> @item file/directory definition +#~ msgid "Logout Dialog" +#~ msgstr "одјавни дијалог" + +# >> @item file/directory definition +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "главна скрипта за одјавни дијалог" + +# >> @item file/directory definition +#~ msgid "Screenlocker" +#~ msgstr "закључавач екрана" + +# >> @item file/directory definition +# rewrite-msgid: /Lock Screen/Screen Locker/ +#~ msgid "Main Script for Lock Screen" +#~ msgstr "главна скрипта за закључавач екрана" + +# >> @item file/directory definition +#~ msgid "UI for fast user switching" +#~ msgstr "сучеље за брзо мењање корисника" + +# >> @item file/directory definition +#~ msgid "Main Script for User Switcher" +#~ msgstr "главна скрипта за мењач корисника" + +# >> @item file/directory definition +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "мењач виртуелних површи" + +# >> @item file/directory definition +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "главна скрипта за мењач виртуелних површи" + +# >> @item file/directory definition +#~ msgid "On-Screen Display Notifications" +#~ msgstr "обавештења у екранском приказу" + +# >> @item file/directory definition +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "главна скрипта за обавештења у екранском приказу" + +# >> @item file/directory definition +#~ msgid "Splash Screen" +#~ msgstr "уводни екран" + +# >> @item file/directory definition +#~ msgid "Main Script for Splash Screen" +#~ msgstr "главна скрипта за уводни екран" + +# >> @item file/directory definition +#~ msgid "KRunner UI" +#~ msgstr "сучеље К‑извођача" + +# >> @item file/directory definition +#~ msgid "Main Script KRunner" +#~ msgstr "главна скрипта К‑извођача" + +# >> @item file/directory definition +#~ msgid "Window Decoration" +#~ msgstr "декорација прозора" + +# >> @item file/directory definition +#~ msgid "Main Script for Window Decoration" +#~ msgstr "главна скрипта за декорацију прозора" + +# >> @item file/directory definition +#~ msgid "Window Switcher" +#~ msgstr "мењач прозора" + +# >> @item file/directory definition +#~ msgid "Main Script for Window Switcher" +#~ msgstr "главна скрипта за мењач прозора" diff --git a/po/sr@ijekavian/libplasma6.po b/po/sr@ijekavian/libplasma6.po new file mode 100644 index 0000000..ad01f5d --- /dev/null +++ b/po/sr@ijekavian/libplasma6.po @@ -0,0 +1,762 @@ +# Translation of libplasma5.po into Serbian. +# Chusslove Illich , 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017. +# Dalibor Djuric , 2009. +msgid "" +msgstr "" +"Project-Id-Version: libplasma5\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2016-03-20 15:24+0100\n" +"Last-Translator: Chusslove Illich \n" +"Language-Team: Serbian \n" +"Language: sr@ijekavian\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n" +"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" +"X-Environment: kde\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Непознато" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Активирај виџет %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, fuzzy, kde-format +#| msgctxt "%1 is the name of the applet" +#| msgid "Remove this %1" +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "" +"Уклони овај %1|/|Уклони $[по-роду-броју %1 овај ову ово ове ове ова] $[аку " +"%1]" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Закључај виџете" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Откључај виџете" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Да ли направити кеш на диску за тему." + +# skip-rule: t-setting +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Највећа величина кеша теме на диску у килобајтима. Имајте на уму да су ови " +"фајлови ретки, тако да задата величина не мора бити потпуно искоришћена. " +"Зато је задавање веће вредности често сасвим безбедно." + +#: plasma/private/applet_p.cpp:119 +#, fuzzy, kde-format +#| msgid "Alternatives..." +msgid "Show Alternatives..." +msgstr "Алтернативе..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Виџет уклоњен" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Виџет „%1“ је уклоњен." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Панел уклоњен" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Панел је уклоњен." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Површ уклоњена" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Површ је уклоњена." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Опозови" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Поставке виџета" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Уклони овај виџет" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Уклони овај панел" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Уклони ову активност" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Поставке активности" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Не могу да нађем захтијевану компоненту: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, fuzzy, kde-format +#| msgid "Unknown" +msgid "Unknown Applet" +msgstr "Непознато" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, fuzzy, kde-format +#| msgid "Error loading QML file: %1" +msgid "Error loading QML file: %1 %2" +msgstr "Грешка при учитавању КуМЛ фајла: %1" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package inexistent. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Грешка при учитавању аплета: пакет не постоји. %1" + +# >> %1 is provider name +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "Поставке %1|/|Поставке $[ген %1]" + +# >> %1 is provider name +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Поставке %1|/|Поставке $[ген %1]" + +# >> @title +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Плазма пакет" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Инсталирај" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Пропало инсталирање пакета" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Пакет који сте управо испустили није добар." + +# >> @title +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Виџети" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "" + +# >> @action +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, fuzzy, kde-format +#| msgid "Icon" +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Иконица" + +# >> @title +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Тапет" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Садржај превучен" + +#~ msgid "Add Widgets..." +#~ msgstr "Додај виџете..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Не могу да отворим пакет %1 неопходан за виџет %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Дијељење виџета на мрежи омогућава вам да приступите том виџету са другог " +#~ "рачунара као даљинским управљачем." + +#~ msgid "Share this widget on the network" +#~ msgstr "Подијели овај виџет на мрежи" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Дозволи свима слободан приступ овом виџету" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Неисправан (нулти) сервис, не може извршити никакву операцију." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Виџет %1 не дефинише који скриптни мотор треба за њега." + +# >> @item applet category +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "разно" + +# >> @item:intext +#~ msgid "Main Script File" +#~ msgstr "главни фајл скрипте" + +# >> @item:intext +#~ msgid "Tests" +#~ msgstr "пробе" + +# >> @item file/directory definition +#~ msgid "Images" +#~ msgstr "слике" + +# >> @item file/directory definition +#~ msgid "Themed Images" +#~ msgstr "тематске слике" + +# >> @item file/directory definition +#~ msgid "Configuration Definitions" +#~ msgstr "дефиниције поставе" + +# >> @item file/directory definition +#~ msgid "User Interface" +#~ msgstr "корисничко сучеље" + +# >> @item file/directory definition +#~ msgid "Data Files" +#~ msgstr "подаци" + +# >> @item file/directory definition +#~ msgid "Executable Scripts" +#~ msgstr "извршне скрипте" + +# >> @item file/directory definition +#~ msgid "Screenshot" +#~ msgstr "снимак екрана" + +# >> @item file/directory definition +#~ msgid "Translations" +#~ msgstr "преводи" + +# >> @item file/directory definition +#~ msgid "Configuration UI pages model" +#~ msgstr "модел УИ страница поставе" + +# >> @item file/directory definition +#~ msgid "Configuration XML file" +#~ msgstr "ИксМЛ фајл поставе" + +# >> @item file/directory definition +#~ msgid "Custom expander for compact applets" +#~ msgstr "посебни проширивач за сажете аплете" + +# >> @item file/directory definition +#~ msgid "Images for dialogs" +#~ msgstr "слике за дијалоге" + +# >> @item file/directory definition +#~ msgid "Generic dialog background" +#~ msgstr "генеричка позадина дијалога" + +# >> @item file/directory definition +#~ msgid "Theme for the logout dialog" +#~ msgstr "тема за одјавни дијалог" + +# >> @item file/directory definition +#~ msgid "Wallpaper packages" +#~ msgstr "пакети тапета" + +# >> @item file/directory definition +#~ msgid "Images for widgets" +#~ msgstr "слике за виџете" + +# >> @item file/directory definition +#~ msgid "Background image for widgets" +#~ msgstr "позадинска слика за виџете" + +# >> @item file/directory definition +#~ msgid "Analog clock face" +#~ msgstr "лице аналогног сата" + +# >> @item file/directory definition +#~ msgid "Background image for panels" +#~ msgstr "позадинска слика за панеле" + +# >> @item file/directory definition +#~ msgid "Background for graphing widgets" +#~ msgstr "позадина за цртачке виџете" + +# >> @item file/directory definition +#~ msgid "Background image for tooltips" +#~ msgstr "позадинска слика за облачиће" + +# >> @item file/directory definition +#~ msgid "Opaque images for dialogs" +#~ msgstr "непрозирне слике за дијалоге" + +# >> @item file/directory definition +#~ msgid "Opaque generic dialog background" +#~ msgstr "непрозирна генеричка позадина дијалога" + +# >> @item file/directory definition +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "непрозирна тема за одјавни дијалог" + +# >> @item file/directory definition +#~ msgid "Opaque images for widgets" +#~ msgstr "непрозирне слике за виџете" + +# >> @item file/directory definition +#~ msgid "Opaque background image for panels" +#~ msgstr "непрозирна позадинска слика за панеле" + +# >> @item file/directory definition +#~ msgid "Opaque background image for tooltips" +#~ msgstr "непрозирна позадинска слика за облачиће" + +# >> @item file/directory definition +#~ msgid "KColorScheme configuration file" +#~ msgstr "поставни фајл шеме боја" + +# >> @item file/directory definition +#~ msgid "Service Descriptions" +#~ msgstr "описи сервиса" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Не могу да створим скриптни мотор %1 за виџет %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Неуспјело припремање скрипте" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Празници" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Догађаји" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Обавезе" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Друго" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Данас" + +#~ msgid "Reset calendar to today" +#~ msgstr "Ресетуј календар на данас" + +#~ msgid "Previous Month" +#~ msgstr "Претходни месец" + +#~ msgid "Next Month" +#~ msgstr "Наредни месец" + +#~ msgid "Previous Year" +#~ msgstr "Претходна година" + +#~ msgid "Next Year" +#~ msgstr "Наредна година" + +#~ msgid "Previous Decade" +#~ msgstr "Претходна деценија" + +#~ msgid "Next Decade" +#~ msgstr "Наредна деценија" + +#~ msgid "OK" +#~ msgstr "У реду" + +#~ msgid "Cancel" +#~ msgstr "Одустани" + +# >> @item applet category +#~ msgid "Accessibility" +#~ msgstr "приступачност" + +# >> @item applet category +#~ msgid "Application Launchers" +#~ msgstr "покретачи програма" + +# >> @item applet category +#~ msgid "Astronomy" +#~ msgstr "астрономија" + +# >> @item applet category +#~ msgid "Date and Time" +#~ msgstr "датум и време" + +# >> @item applet category +#~ msgid "Development Tools" +#~ msgstr "развојне алатке" + +# >> @item applet category +#~ msgid "Education" +#~ msgstr "образовање" + +# >> @item applet category +#~ msgid "Environment and Weather" +#~ msgstr "природа и вријеме" + +# >> @item applet category +#~ msgid "Examples" +#~ msgstr "примери" + +# >> @item applet category +#~ msgid "File System" +#~ msgstr "фајл систем" + +# >> @item applet category +#~ msgid "Fun and Games" +#~ msgstr "забава и игре" + +# >> @item applet category +#~ msgid "Graphics" +#~ msgstr "графика" + +# >> @item applet category +#~ msgid "Language" +#~ msgstr "језик" + +# >> @item applet category +#~ msgid "Mapping" +#~ msgstr "картографија" + +# >> @item applet category +#~ msgid "Miscellaneous" +#~ msgstr "разно" + +# >> @item applet category +#~ msgid "Multimedia" +#~ msgstr "мултимедија" + +# >> @item applet category +#~ msgid "Online Services" +#~ msgstr "сервиси на вези" + +# >> @item applet category +#~ msgid "Productivity" +#~ msgstr "продуктивност" + +# >> @item applet category +#~ msgid "System Information" +#~ msgstr "подаци о систему" + +# >> @item applet category +#~ msgid "Utilities" +#~ msgstr "алатке" + +# >> @item applet category +#~ msgid "Windows and Tasks" +#~ msgstr "прозори и задаци" + +# >> @item applet category +#~ msgid "Clipboard" +#~ msgstr "клипборд" + +# >> @item applet category +#~ msgid "Tasks" +#~ msgstr "задаци" + +#~ msgid "Run the Associated Application" +#~ msgstr "Изврши придружени програм" + +#~ msgid "Open with %1" +#~ msgstr "Отвори помоћу %1|/|Отвори $[инс-п %1]" + +# >> @item file/directory definition +#~ msgid "Default settings for theme, etc." +#~ msgstr "подразумеване поставке за тему, итд." + +# >> @item file/directory definition +#~ msgid "Color scheme to use for applications." +#~ msgstr "шема боја у програмима" + +# >> @item file/directory definition +#~ msgid "Preview Images" +#~ msgstr "слике прегледа" + +# >> @item file/directory definition +#~ msgid "Preview for the Login Manager" +#~ msgstr "преглед за менаџер пријављивања" + +# >> @item file/directory definition +#~ msgid "Preview for the Lock Screen" +#~ msgstr "преглед за забравни екран" + +# >> @item file/directory definition +#~ msgid "Preview for the Userswitcher" +#~ msgstr "преглед за мењач корисника" + +# >> @item file/directory definition +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "преглед за мењач виртуелних површи" + +# >> @item file/directory definition +#~ msgid "Preview for Splash Screen" +#~ msgstr "преглед за уводни екран" + +# >> @item file/directory definition +#~ msgid "Preview for KRunner" +#~ msgstr "преглед за К‑извођач" + +# >> @item file/directory definition +#~ msgid "Preview for the Window Decorations" +#~ msgstr "преглед за декорације прозора" + +# >> @item file/directory definition +#~ msgid "Preview for Window Switcher" +#~ msgstr "преглед за мењач прозора" + +# >> @item file/directory definition +#~ msgid "Login Manager" +#~ msgstr "менаџер пријављивања" + +# >> @item file/directory definition +#~ msgid "Main Script for Login Manager" +#~ msgstr "главна скрипт за менаџер пријављивања" + +# >> @item file/directory definition +#~ msgid "Logout Dialog" +#~ msgstr "одјавни дијалог" + +# >> @item file/directory definition +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "главна скрипта за одјавни дијалог" + +# >> @item file/directory definition +#~ msgid "Screenlocker" +#~ msgstr "закључавач екрана" + +# >> @item file/directory definition +# rewrite-msgid: /Lock Screen/Screen Locker/ +#~ msgid "Main Script for Lock Screen" +#~ msgstr "главна скрипта за закључавач екрана" + +# >> @item file/directory definition +#~ msgid "UI for fast user switching" +#~ msgstr "сучеље за брзо мењање корисника" + +# >> @item file/directory definition +#~ msgid "Main Script for User Switcher" +#~ msgstr "главна скрипта за мењач корисника" + +# >> @item file/directory definition +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "мењач виртуелних површи" + +# >> @item file/directory definition +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "главна скрипта за мењач виртуелних површи" + +# >> @item file/directory definition +#~ msgid "On-Screen Display Notifications" +#~ msgstr "обавештења у екранском приказу" + +# >> @item file/directory definition +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "главна скрипта за обавештења у екранском приказу" + +# >> @item file/directory definition +#~ msgid "Splash Screen" +#~ msgstr "уводни екран" + +# >> @item file/directory definition +#~ msgid "Main Script for Splash Screen" +#~ msgstr "главна скрипта за уводни екран" + +# >> @item file/directory definition +#~ msgid "KRunner UI" +#~ msgstr "сучеље К‑извођача" + +# >> @item file/directory definition +#~ msgid "Main Script KRunner" +#~ msgstr "главна скрипта К‑извођача" + +# >> @item file/directory definition +#~ msgid "Window Decoration" +#~ msgstr "декорација прозора" + +# >> @item file/directory definition +#~ msgid "Main Script for Window Decoration" +#~ msgstr "главна скрипта за декорацију прозора" + +# >> @item file/directory definition +#~ msgid "Window Switcher" +#~ msgstr "мењач прозора" + +# >> @item file/directory definition +#~ msgid "Main Script for Window Switcher" +#~ msgstr "главна скрипта за мењач прозора" diff --git a/po/sr@ijekavianlatin/libplasma6.po b/po/sr@ijekavianlatin/libplasma6.po new file mode 100644 index 0000000..bc3a4fa --- /dev/null +++ b/po/sr@ijekavianlatin/libplasma6.po @@ -0,0 +1,762 @@ +# Translation of libplasma5.po into Serbian. +# Chusslove Illich , 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017. +# Dalibor Djuric , 2009. +msgid "" +msgstr "" +"Project-Id-Version: libplasma5\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2016-03-20 15:24+0100\n" +"Last-Translator: Chusslove Illich \n" +"Language-Team: Serbian \n" +"Language: sr@ijekavianlatin\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n" +"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" +"X-Environment: kde\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Nepoznato" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Aktiviraj vidžet %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, fuzzy, kde-format +#| msgctxt "%1 is the name of the applet" +#| msgid "Remove this %1" +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "" +"Ukloni ovaj %1|/|Ukloni $[po-rodu-broju %1 ovaj ovu ovo ove ove ova] $[aku " +"%1]" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Zaključaj vidžete" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Otključaj vidžete" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Da li napraviti keš na disku za temu." + +# skip-rule: t-setting +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Najveća veličina keša teme na disku u kilobajtima. Imajte na umu da su ovi " +"fajlovi retki, tako da zadata veličina ne mora biti potpuno iskorišćena. " +"Zato je zadavanje veće vrednosti često sasvim bezbedno." + +#: plasma/private/applet_p.cpp:119 +#, fuzzy, kde-format +#| msgid "Alternatives..." +msgid "Show Alternatives..." +msgstr "Alternative..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Vidžet uklonjen" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Vidžet „%1“ je uklonjen." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panel uklonjen" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Panel je uklonjen." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Površ uklonjena" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Površ je uklonjena." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Opozovi" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Postavke vidžeta" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Ukloni ovaj vidžet" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Ukloni ovaj panel" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Ukloni ovu aktivnost" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Postavke aktivnosti" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Ne mogu da nađem zahtijevanu komponentu: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, fuzzy, kde-format +#| msgid "Unknown" +msgid "Unknown Applet" +msgstr "Nepoznato" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, fuzzy, kde-format +#| msgid "Error loading QML file: %1" +msgid "Error loading QML file: %1 %2" +msgstr "Greška pri učitavanju QML fajla: %1" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package inexistent. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Greška pri učitavanju apleta: paket ne postoji. %1" + +# >> %1 is provider name +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "Postavke %1|/|Postavke $[gen %1]" + +# >> %1 is provider name +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Postavke %1|/|Postavke $[gen %1]" + +# >> @title +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma paket" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Instaliraj" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Propalo instaliranje paketa" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Paket koji ste upravo ispustili nije dobar." + +# >> @title +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Vidžeti" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "" + +# >> @action +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, fuzzy, kde-format +#| msgid "Icon" +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Ikonica" + +# >> @title +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Tapet" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Sadržaj prevučen" + +#~ msgid "Add Widgets..." +#~ msgstr "Dodaj vidžete..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Ne mogu da otvorim paket %1 neophodan za vidžet %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Dijeljenje vidžeta na mreži omogućava vam da pristupite tom vidžetu sa " +#~ "drugog računara kao daljinskim upravljačem." + +#~ msgid "Share this widget on the network" +#~ msgstr "Podijeli ovaj vidžet na mreži" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Dozvoli svima slobodan pristup ovom vidžetu" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Neispravan (nulti) servis, ne može izvršiti nikakvu operaciju." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Vidžet %1 ne definiše koji skriptni motor treba za njega." + +# >> @item applet category +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "razno" + +# >> @item:intext +#~ msgid "Main Script File" +#~ msgstr "glavni fajl skripte" + +# >> @item:intext +#~ msgid "Tests" +#~ msgstr "probe" + +# >> @item file/directory definition +#~ msgid "Images" +#~ msgstr "slike" + +# >> @item file/directory definition +#~ msgid "Themed Images" +#~ msgstr "tematske slike" + +# >> @item file/directory definition +#~ msgid "Configuration Definitions" +#~ msgstr "definicije postave" + +# >> @item file/directory definition +#~ msgid "User Interface" +#~ msgstr "korisničko sučelje" + +# >> @item file/directory definition +#~ msgid "Data Files" +#~ msgstr "podaci" + +# >> @item file/directory definition +#~ msgid "Executable Scripts" +#~ msgstr "izvršne skripte" + +# >> @item file/directory definition +#~ msgid "Screenshot" +#~ msgstr "snimak ekrana" + +# >> @item file/directory definition +#~ msgid "Translations" +#~ msgstr "prevodi" + +# >> @item file/directory definition +#~ msgid "Configuration UI pages model" +#~ msgstr "model UI stranica postave" + +# >> @item file/directory definition +#~ msgid "Configuration XML file" +#~ msgstr "XML fajl postave" + +# >> @item file/directory definition +#~ msgid "Custom expander for compact applets" +#~ msgstr "posebni proširivač za sažete aplete" + +# >> @item file/directory definition +#~ msgid "Images for dialogs" +#~ msgstr "slike za dijaloge" + +# >> @item file/directory definition +#~ msgid "Generic dialog background" +#~ msgstr "generička pozadina dijaloga" + +# >> @item file/directory definition +#~ msgid "Theme for the logout dialog" +#~ msgstr "tema za odjavni dijalog" + +# >> @item file/directory definition +#~ msgid "Wallpaper packages" +#~ msgstr "paketi tapeta" + +# >> @item file/directory definition +#~ msgid "Images for widgets" +#~ msgstr "slike za vidžete" + +# >> @item file/directory definition +#~ msgid "Background image for widgets" +#~ msgstr "pozadinska slika za vidžete" + +# >> @item file/directory definition +#~ msgid "Analog clock face" +#~ msgstr "lice analognog sata" + +# >> @item file/directory definition +#~ msgid "Background image for panels" +#~ msgstr "pozadinska slika za panele" + +# >> @item file/directory definition +#~ msgid "Background for graphing widgets" +#~ msgstr "pozadina za crtačke vidžete" + +# >> @item file/directory definition +#~ msgid "Background image for tooltips" +#~ msgstr "pozadinska slika za oblačiće" + +# >> @item file/directory definition +#~ msgid "Opaque images for dialogs" +#~ msgstr "neprozirne slike za dijaloge" + +# >> @item file/directory definition +#~ msgid "Opaque generic dialog background" +#~ msgstr "neprozirna generička pozadina dijaloga" + +# >> @item file/directory definition +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "neprozirna tema za odjavni dijalog" + +# >> @item file/directory definition +#~ msgid "Opaque images for widgets" +#~ msgstr "neprozirne slike za vidžete" + +# >> @item file/directory definition +#~ msgid "Opaque background image for panels" +#~ msgstr "neprozirna pozadinska slika za panele" + +# >> @item file/directory definition +#~ msgid "Opaque background image for tooltips" +#~ msgstr "neprozirna pozadinska slika za oblačiće" + +# >> @item file/directory definition +#~ msgid "KColorScheme configuration file" +#~ msgstr "postavni fajl šeme boja" + +# >> @item file/directory definition +#~ msgid "Service Descriptions" +#~ msgstr "opisi servisa" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Ne mogu da stvorim skriptni motor %1 za vidžet %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Neuspjelo pripremanje skripte" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Praznici" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Događaji" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Obaveze" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Drugo" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Danas" + +#~ msgid "Reset calendar to today" +#~ msgstr "Resetuj kalendar na danas" + +#~ msgid "Previous Month" +#~ msgstr "Prethodni mesec" + +#~ msgid "Next Month" +#~ msgstr "Naredni mesec" + +#~ msgid "Previous Year" +#~ msgstr "Prethodna godina" + +#~ msgid "Next Year" +#~ msgstr "Naredna godina" + +#~ msgid "Previous Decade" +#~ msgstr "Prethodna decenija" + +#~ msgid "Next Decade" +#~ msgstr "Naredna decenija" + +#~ msgid "OK" +#~ msgstr "U redu" + +#~ msgid "Cancel" +#~ msgstr "Odustani" + +# >> @item applet category +#~ msgid "Accessibility" +#~ msgstr "pristupačnost" + +# >> @item applet category +#~ msgid "Application Launchers" +#~ msgstr "pokretači programa" + +# >> @item applet category +#~ msgid "Astronomy" +#~ msgstr "astronomija" + +# >> @item applet category +#~ msgid "Date and Time" +#~ msgstr "datum i vreme" + +# >> @item applet category +#~ msgid "Development Tools" +#~ msgstr "razvojne alatke" + +# >> @item applet category +#~ msgid "Education" +#~ msgstr "obrazovanje" + +# >> @item applet category +#~ msgid "Environment and Weather" +#~ msgstr "priroda i vrijeme" + +# >> @item applet category +#~ msgid "Examples" +#~ msgstr "primeri" + +# >> @item applet category +#~ msgid "File System" +#~ msgstr "fajl sistem" + +# >> @item applet category +#~ msgid "Fun and Games" +#~ msgstr "zabava i igre" + +# >> @item applet category +#~ msgid "Graphics" +#~ msgstr "grafika" + +# >> @item applet category +#~ msgid "Language" +#~ msgstr "jezik" + +# >> @item applet category +#~ msgid "Mapping" +#~ msgstr "kartografija" + +# >> @item applet category +#~ msgid "Miscellaneous" +#~ msgstr "razno" + +# >> @item applet category +#~ msgid "Multimedia" +#~ msgstr "multimedija" + +# >> @item applet category +#~ msgid "Online Services" +#~ msgstr "servisi na vezi" + +# >> @item applet category +#~ msgid "Productivity" +#~ msgstr "produktivnost" + +# >> @item applet category +#~ msgid "System Information" +#~ msgstr "podaci o sistemu" + +# >> @item applet category +#~ msgid "Utilities" +#~ msgstr "alatke" + +# >> @item applet category +#~ msgid "Windows and Tasks" +#~ msgstr "prozori i zadaci" + +# >> @item applet category +#~ msgid "Clipboard" +#~ msgstr "klipbord" + +# >> @item applet category +#~ msgid "Tasks" +#~ msgstr "zadaci" + +#~ msgid "Run the Associated Application" +#~ msgstr "Izvrši pridruženi program" + +#~ msgid "Open with %1" +#~ msgstr "Otvori pomoću %1|/|Otvori $[ins-p %1]" + +# >> @item file/directory definition +#~ msgid "Default settings for theme, etc." +#~ msgstr "podrazumevane postavke za temu, itd." + +# >> @item file/directory definition +#~ msgid "Color scheme to use for applications." +#~ msgstr "šema boja u programima" + +# >> @item file/directory definition +#~ msgid "Preview Images" +#~ msgstr "slike pregleda" + +# >> @item file/directory definition +#~ msgid "Preview for the Login Manager" +#~ msgstr "pregled za menadžer prijavljivanja" + +# >> @item file/directory definition +#~ msgid "Preview for the Lock Screen" +#~ msgstr "pregled za zabravni ekran" + +# >> @item file/directory definition +#~ msgid "Preview for the Userswitcher" +#~ msgstr "pregled za menjač korisnika" + +# >> @item file/directory definition +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "pregled za menjač virtuelnih površi" + +# >> @item file/directory definition +#~ msgid "Preview for Splash Screen" +#~ msgstr "pregled za uvodni ekran" + +# >> @item file/directory definition +#~ msgid "Preview for KRunner" +#~ msgstr "pregled za K‑izvođač" + +# >> @item file/directory definition +#~ msgid "Preview for the Window Decorations" +#~ msgstr "pregled za dekoracije prozora" + +# >> @item file/directory definition +#~ msgid "Preview for Window Switcher" +#~ msgstr "pregled za menjač prozora" + +# >> @item file/directory definition +#~ msgid "Login Manager" +#~ msgstr "menadžer prijavljivanja" + +# >> @item file/directory definition +#~ msgid "Main Script for Login Manager" +#~ msgstr "glavna skript za menadžer prijavljivanja" + +# >> @item file/directory definition +#~ msgid "Logout Dialog" +#~ msgstr "odjavni dijalog" + +# >> @item file/directory definition +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "glavna skripta za odjavni dijalog" + +# >> @item file/directory definition +#~ msgid "Screenlocker" +#~ msgstr "zaključavač ekrana" + +# >> @item file/directory definition +# rewrite-msgid: /Lock Screen/Screen Locker/ +#~ msgid "Main Script for Lock Screen" +#~ msgstr "glavna skripta za zaključavač ekrana" + +# >> @item file/directory definition +#~ msgid "UI for fast user switching" +#~ msgstr "sučelje za brzo menjanje korisnika" + +# >> @item file/directory definition +#~ msgid "Main Script for User Switcher" +#~ msgstr "glavna skripta za menjač korisnika" + +# >> @item file/directory definition +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "menjač virtuelnih površi" + +# >> @item file/directory definition +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "glavna skripta za menjač virtuelnih površi" + +# >> @item file/directory definition +#~ msgid "On-Screen Display Notifications" +#~ msgstr "obaveštenja u ekranskom prikazu" + +# >> @item file/directory definition +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "glavna skripta za obaveštenja u ekranskom prikazu" + +# >> @item file/directory definition +#~ msgid "Splash Screen" +#~ msgstr "uvodni ekran" + +# >> @item file/directory definition +#~ msgid "Main Script for Splash Screen" +#~ msgstr "glavna skripta za uvodni ekran" + +# >> @item file/directory definition +#~ msgid "KRunner UI" +#~ msgstr "sučelje K‑izvođača" + +# >> @item file/directory definition +#~ msgid "Main Script KRunner" +#~ msgstr "glavna skripta K‑izvođača" + +# >> @item file/directory definition +#~ msgid "Window Decoration" +#~ msgstr "dekoracija prozora" + +# >> @item file/directory definition +#~ msgid "Main Script for Window Decoration" +#~ msgstr "glavna skripta za dekoraciju prozora" + +# >> @item file/directory definition +#~ msgid "Window Switcher" +#~ msgstr "menjač prozora" + +# >> @item file/directory definition +#~ msgid "Main Script for Window Switcher" +#~ msgstr "glavna skripta za menjač prozora" diff --git a/po/sr@latin/libplasma6.po b/po/sr@latin/libplasma6.po new file mode 100644 index 0000000..236cb34 --- /dev/null +++ b/po/sr@latin/libplasma6.po @@ -0,0 +1,762 @@ +# Translation of libplasma5.po into Serbian. +# Chusslove Illich , 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017. +# Dalibor Djuric , 2009. +msgid "" +msgstr "" +"Project-Id-Version: libplasma5\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2016-03-20 15:24+0100\n" +"Last-Translator: Chusslove Illich \n" +"Language-Team: Serbian \n" +"Language: sr@latin\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n" +"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" +"X-Environment: kde\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Nepoznato" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Aktiviraj vidžet %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, fuzzy, kde-format +#| msgctxt "%1 is the name of the applet" +#| msgid "Remove this %1" +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "" +"Ukloni ovaj %1|/|Ukloni $[po-rodu-broju %1 ovaj ovu ovo ove ove ova] $[aku " +"%1]" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Zaključaj vidžete" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Otključaj vidžete" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Da li napraviti keš na disku za temu." + +# skip-rule: t-setting +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Najveća veličina keša teme na disku u kilobajtima. Imajte na umu da su ovi " +"fajlovi retki, tako da zadata veličina ne mora biti potpuno iskorišćena. " +"Zato je zadavanje veće vrednosti često sasvim bezbedno." + +#: plasma/private/applet_p.cpp:119 +#, fuzzy, kde-format +#| msgid "Alternatives..." +msgid "Show Alternatives..." +msgstr "Alternative..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Vidžet uklonjen" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Vidžet „%1“ je uklonjen." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panel uklonjen" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Panel je uklonjen." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Površ uklonjena" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Površ je uklonjena." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Opozovi" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Postavke vidžeta" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Ukloni ovaj vidžet" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Ukloni ovaj panel" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Ukloni ovu aktivnost" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Postavke aktivnosti" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Ne mogu da nađem zahtevanu komponentu: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, fuzzy, kde-format +#| msgid "Unknown" +msgid "Unknown Applet" +msgstr "Nepoznato" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, fuzzy, kde-format +#| msgid "Error loading QML file: %1" +msgid "Error loading QML file: %1 %2" +msgstr "Greška pri učitavanju QML fajla: %1" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package inexistent. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Greška pri učitavanju apleta: paket ne postoji. %1" + +# >> %1 is provider name +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "Postavke %1|/|Postavke $[gen %1]" + +# >> %1 is provider name +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Postavke %1|/|Postavke $[gen %1]" + +# >> @title +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma paket" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Instaliraj" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Propalo instaliranje paketa" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Paket koji ste upravo ispustili nije dobar." + +# >> @title +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Vidžeti" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "" + +# >> @action +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, fuzzy, kde-format +#| msgid "Icon" +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Ikonica" + +# >> @title +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Tapet" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Sadržaj prevučen" + +#~ msgid "Add Widgets..." +#~ msgstr "Dodaj vidžete..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Ne mogu da otvorim paket %1 neophodan za vidžet %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Deljenje vidžeta na mreži omogućava vam da pristupite tom vidžetu sa " +#~ "drugog računara kao daljinskim upravljačem." + +#~ msgid "Share this widget on the network" +#~ msgstr "Podeli ovaj vidžet na mreži" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Dozvoli svima slobodan pristup ovom vidžetu" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Neispravan (nulti) servis, ne može izvršiti nikakvu operaciju." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Vidžet %1 ne definiše koji skriptni motor treba za njega." + +# >> @item applet category +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "razno" + +# >> @item:intext +#~ msgid "Main Script File" +#~ msgstr "glavni fajl skripte" + +# >> @item:intext +#~ msgid "Tests" +#~ msgstr "probe" + +# >> @item file/directory definition +#~ msgid "Images" +#~ msgstr "slike" + +# >> @item file/directory definition +#~ msgid "Themed Images" +#~ msgstr "tematske slike" + +# >> @item file/directory definition +#~ msgid "Configuration Definitions" +#~ msgstr "definicije postave" + +# >> @item file/directory definition +#~ msgid "User Interface" +#~ msgstr "korisničko sučelje" + +# >> @item file/directory definition +#~ msgid "Data Files" +#~ msgstr "podaci" + +# >> @item file/directory definition +#~ msgid "Executable Scripts" +#~ msgstr "izvršne skripte" + +# >> @item file/directory definition +#~ msgid "Screenshot" +#~ msgstr "snimak ekrana" + +# >> @item file/directory definition +#~ msgid "Translations" +#~ msgstr "prevodi" + +# >> @item file/directory definition +#~ msgid "Configuration UI pages model" +#~ msgstr "model UI stranica postave" + +# >> @item file/directory definition +#~ msgid "Configuration XML file" +#~ msgstr "XML fajl postave" + +# >> @item file/directory definition +#~ msgid "Custom expander for compact applets" +#~ msgstr "posebni proširivač za sažete aplete" + +# >> @item file/directory definition +#~ msgid "Images for dialogs" +#~ msgstr "slike za dijaloge" + +# >> @item file/directory definition +#~ msgid "Generic dialog background" +#~ msgstr "generička pozadina dijaloga" + +# >> @item file/directory definition +#~ msgid "Theme for the logout dialog" +#~ msgstr "tema za odjavni dijalog" + +# >> @item file/directory definition +#~ msgid "Wallpaper packages" +#~ msgstr "paketi tapeta" + +# >> @item file/directory definition +#~ msgid "Images for widgets" +#~ msgstr "slike za vidžete" + +# >> @item file/directory definition +#~ msgid "Background image for widgets" +#~ msgstr "pozadinska slika za vidžete" + +# >> @item file/directory definition +#~ msgid "Analog clock face" +#~ msgstr "lice analognog sata" + +# >> @item file/directory definition +#~ msgid "Background image for panels" +#~ msgstr "pozadinska slika za panele" + +# >> @item file/directory definition +#~ msgid "Background for graphing widgets" +#~ msgstr "pozadina za crtačke vidžete" + +# >> @item file/directory definition +#~ msgid "Background image for tooltips" +#~ msgstr "pozadinska slika za oblačiće" + +# >> @item file/directory definition +#~ msgid "Opaque images for dialogs" +#~ msgstr "neprozirne slike za dijaloge" + +# >> @item file/directory definition +#~ msgid "Opaque generic dialog background" +#~ msgstr "neprozirna generička pozadina dijaloga" + +# >> @item file/directory definition +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "neprozirna tema za odjavni dijalog" + +# >> @item file/directory definition +#~ msgid "Opaque images for widgets" +#~ msgstr "neprozirne slike za vidžete" + +# >> @item file/directory definition +#~ msgid "Opaque background image for panels" +#~ msgstr "neprozirna pozadinska slika za panele" + +# >> @item file/directory definition +#~ msgid "Opaque background image for tooltips" +#~ msgstr "neprozirna pozadinska slika za oblačiće" + +# >> @item file/directory definition +#~ msgid "KColorScheme configuration file" +#~ msgstr "postavni fajl šeme boja" + +# >> @item file/directory definition +#~ msgid "Service Descriptions" +#~ msgstr "opisi servisa" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Ne mogu da stvorim skriptni motor %1 za vidžet %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Neuspelo pripremanje skripte" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Praznici" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Događaji" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Obaveze" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Drugo" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Danas" + +#~ msgid "Reset calendar to today" +#~ msgstr "Resetuj kalendar na danas" + +#~ msgid "Previous Month" +#~ msgstr "Prethodni mesec" + +#~ msgid "Next Month" +#~ msgstr "Naredni mesec" + +#~ msgid "Previous Year" +#~ msgstr "Prethodna godina" + +#~ msgid "Next Year" +#~ msgstr "Naredna godina" + +#~ msgid "Previous Decade" +#~ msgstr "Prethodna decenija" + +#~ msgid "Next Decade" +#~ msgstr "Naredna decenija" + +#~ msgid "OK" +#~ msgstr "U redu" + +#~ msgid "Cancel" +#~ msgstr "Odustani" + +# >> @item applet category +#~ msgid "Accessibility" +#~ msgstr "pristupačnost" + +# >> @item applet category +#~ msgid "Application Launchers" +#~ msgstr "pokretači programa" + +# >> @item applet category +#~ msgid "Astronomy" +#~ msgstr "astronomija" + +# >> @item applet category +#~ msgid "Date and Time" +#~ msgstr "datum i vreme" + +# >> @item applet category +#~ msgid "Development Tools" +#~ msgstr "razvojne alatke" + +# >> @item applet category +#~ msgid "Education" +#~ msgstr "obrazovanje" + +# >> @item applet category +#~ msgid "Environment and Weather" +#~ msgstr "priroda i vreme" + +# >> @item applet category +#~ msgid "Examples" +#~ msgstr "primeri" + +# >> @item applet category +#~ msgid "File System" +#~ msgstr "fajl sistem" + +# >> @item applet category +#~ msgid "Fun and Games" +#~ msgstr "zabava i igre" + +# >> @item applet category +#~ msgid "Graphics" +#~ msgstr "grafika" + +# >> @item applet category +#~ msgid "Language" +#~ msgstr "jezik" + +# >> @item applet category +#~ msgid "Mapping" +#~ msgstr "kartografija" + +# >> @item applet category +#~ msgid "Miscellaneous" +#~ msgstr "razno" + +# >> @item applet category +#~ msgid "Multimedia" +#~ msgstr "multimedija" + +# >> @item applet category +#~ msgid "Online Services" +#~ msgstr "servisi na vezi" + +# >> @item applet category +#~ msgid "Productivity" +#~ msgstr "produktivnost" + +# >> @item applet category +#~ msgid "System Information" +#~ msgstr "podaci o sistemu" + +# >> @item applet category +#~ msgid "Utilities" +#~ msgstr "alatke" + +# >> @item applet category +#~ msgid "Windows and Tasks" +#~ msgstr "prozori i zadaci" + +# >> @item applet category +#~ msgid "Clipboard" +#~ msgstr "klipbord" + +# >> @item applet category +#~ msgid "Tasks" +#~ msgstr "zadaci" + +#~ msgid "Run the Associated Application" +#~ msgstr "Izvrši pridruženi program" + +#~ msgid "Open with %1" +#~ msgstr "Otvori pomoću %1|/|Otvori $[ins-p %1]" + +# >> @item file/directory definition +#~ msgid "Default settings for theme, etc." +#~ msgstr "podrazumevane postavke za temu, itd." + +# >> @item file/directory definition +#~ msgid "Color scheme to use for applications." +#~ msgstr "šema boja u programima" + +# >> @item file/directory definition +#~ msgid "Preview Images" +#~ msgstr "slike pregleda" + +# >> @item file/directory definition +#~ msgid "Preview for the Login Manager" +#~ msgstr "pregled za menadžer prijavljivanja" + +# >> @item file/directory definition +#~ msgid "Preview for the Lock Screen" +#~ msgstr "pregled za zabravni ekran" + +# >> @item file/directory definition +#~ msgid "Preview for the Userswitcher" +#~ msgstr "pregled za menjač korisnika" + +# >> @item file/directory definition +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "pregled za menjač virtuelnih površi" + +# >> @item file/directory definition +#~ msgid "Preview for Splash Screen" +#~ msgstr "pregled za uvodni ekran" + +# >> @item file/directory definition +#~ msgid "Preview for KRunner" +#~ msgstr "pregled za K‑izvođač" + +# >> @item file/directory definition +#~ msgid "Preview for the Window Decorations" +#~ msgstr "pregled za dekoracije prozora" + +# >> @item file/directory definition +#~ msgid "Preview for Window Switcher" +#~ msgstr "pregled za menjač prozora" + +# >> @item file/directory definition +#~ msgid "Login Manager" +#~ msgstr "menadžer prijavljivanja" + +# >> @item file/directory definition +#~ msgid "Main Script for Login Manager" +#~ msgstr "glavna skript za menadžer prijavljivanja" + +# >> @item file/directory definition +#~ msgid "Logout Dialog" +#~ msgstr "odjavni dijalog" + +# >> @item file/directory definition +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "glavna skripta za odjavni dijalog" + +# >> @item file/directory definition +#~ msgid "Screenlocker" +#~ msgstr "zaključavač ekrana" + +# >> @item file/directory definition +# rewrite-msgid: /Lock Screen/Screen Locker/ +#~ msgid "Main Script for Lock Screen" +#~ msgstr "glavna skripta za zaključavač ekrana" + +# >> @item file/directory definition +#~ msgid "UI for fast user switching" +#~ msgstr "sučelje za brzo menjanje korisnika" + +# >> @item file/directory definition +#~ msgid "Main Script for User Switcher" +#~ msgstr "glavna skripta za menjač korisnika" + +# >> @item file/directory definition +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "menjač virtuelnih površi" + +# >> @item file/directory definition +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "glavna skripta za menjač virtuelnih površi" + +# >> @item file/directory definition +#~ msgid "On-Screen Display Notifications" +#~ msgstr "obaveštenja u ekranskom prikazu" + +# >> @item file/directory definition +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "glavna skripta za obaveštenja u ekranskom prikazu" + +# >> @item file/directory definition +#~ msgid "Splash Screen" +#~ msgstr "uvodni ekran" + +# >> @item file/directory definition +#~ msgid "Main Script for Splash Screen" +#~ msgstr "glavna skripta za uvodni ekran" + +# >> @item file/directory definition +#~ msgid "KRunner UI" +#~ msgstr "sučelje K‑izvođača" + +# >> @item file/directory definition +#~ msgid "Main Script KRunner" +#~ msgstr "glavna skripta K‑izvođača" + +# >> @item file/directory definition +#~ msgid "Window Decoration" +#~ msgstr "dekoracija prozora" + +# >> @item file/directory definition +#~ msgid "Main Script for Window Decoration" +#~ msgstr "glavna skripta za dekoraciju prozora" + +# >> @item file/directory definition +#~ msgid "Window Switcher" +#~ msgstr "menjač prozora" + +# >> @item file/directory definition +#~ msgid "Main Script for Window Switcher" +#~ msgstr "glavna skripta za menjač prozora" diff --git a/po/sv/libplasma6.po b/po/sv/libplasma6.po new file mode 100644 index 0000000..660dfb3 --- /dev/null +++ b/po/sv/libplasma6.po @@ -0,0 +1,1083 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# SPDX-FileCopyrightText: 2014, 2015, 2016, 2018, 2019, 2020, 2021, 2022, 2024 Stefan Asserhäll +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-23 07:37+0200\n" +"Last-Translator: Stefan Asserhäll \n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 24.05.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Fler åtgärder" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Dra ihop" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Expandera" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Lösenord" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Sök…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Sök" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Rensa sökning" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Okänd" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Aktivera komponenten %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Ta bort %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Starta redigeringsläge" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Anpassa %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Lås grafiska komponenter" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Lås upp grafiska komponenter" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Avsluta redigeringsläge" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Om en diskcache ska skapas för temat eller inte." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Den maximala storleken hos temacachen på disk i kilobyte. Observera att " +"filerna är glesa, så den maximala storleken kanske inte används. Att ställa " +"in en större storlek är därför ofta helt säkert." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Visa alternativ..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Grafisk komponent borttagen" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Den grafiska komponenten \"%1\" har tagits bort." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panel borttagen" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "En panel har tagits bort." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Skrivbord borttaget" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Ett skrivbord har tagits bort." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Ångra" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Inställningar av grafiska komponenter" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Ta bort den här grafiska komponenten" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Ta bort panelen" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Ta bort aktiviteten" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Aktivitetsinställningar" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Lägg till eller hantera grafiska komponenter…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Kunde inte hitta begärd komponent: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Rotobjekt för %1 måste ha typen ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Rotobjekt för %1 måste ha typen PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Okänt miniprogram" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Den här grafiska komponenten är skriven för en okänd äldre version av Plasma " +"och är inte kompatibel med Plasma %1. Kontakta komponentens upphovsman för " +"en uppdaterad version." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 är inte kompatibel med Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Den här grafiska komponenten är skriven för Plasma %1 och är inte kompatibel " +"med Plasma %2. Kontakta komponentens upphovsman för en uppdaterad version." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Den här grafiska komponenten är skriven för Plasma %1 och är inte kompatibel " +"med Plasma %2. Uppdatera Plasma för att kunna använda komponenten." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Tyvärr uppstod ett fel vid laddning av %1." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Fel vid inläsning av QML-fil: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Fel vid inläsning av miniprogram: paketet %1 finns inte." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 inställningar" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Inställningar av %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma-paket" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Installera" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Paketinstallation misslyckades" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Paketet som just släpptes är ogiltigt." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Grafiska komponenter" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Lägg till %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Lägg till ikon" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Skrivbordsunderlägg" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Ställ in %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Innehåll släppt" + +#~ msgid "Add Widgets..." +#~ msgstr "Lägg till grafiska komponenter..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "" +#~ "Kunde inte öppna paketet %1 som krävs för den grafiska komponenten %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Att dela en grafisk komponent på nätverket låter dig komma åt komponenten " +#~ "från en annan dator som en fjärrkomponent." + +#~ msgid "Share this widget on the network" +#~ msgstr "Dela grafisk komponent på nätverket" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Tillåt alla att fritt komma åt grafisk komponent" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Ogiltig (tom) tjänst, kan inte utföra några åtgärder." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "" +#~ "Den grafiska komponenten %1 definierar inte vilket skriptgränssnitt som " +#~ "ska användas." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Diverse" + +#~ msgid "Main Script File" +#~ msgstr "Huvudskriptfil" + +#~ msgid "Tests" +#~ msgstr "Tester" + +#~ msgid "Images" +#~ msgstr "Bilder" + +#~ msgid "Themed Images" +#~ msgstr "Bilder med teman" + +#~ msgid "Configuration Definitions" +#~ msgstr "Inställningsdefinitioner" + +#~ msgid "User Interface" +#~ msgstr "Användargränssnitt" + +#~ msgid "Data Files" +#~ msgstr "Datafiler" + +#~ msgid "Executable Scripts" +#~ msgstr "Körbara skript" + +#~ msgid "Screenshot" +#~ msgstr "Skärmbild" + +#~ msgid "Translations" +#~ msgstr "Översättningar" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Modell för inställningssidor i användargränssnitt" + +#~ msgid "Configuration XML file" +#~ msgstr "XML-inställningsfil" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Egen expandering för kompakta miniprogram" + +#~ msgid "Images for dialogs" +#~ msgstr "Bilder för dialogrutor" + +#~ msgid "Generic dialog background" +#~ msgstr "Generell bakgrund för dialogrutor" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Tema för utloggningsdialogrutan" + +#~ msgid "Wallpaper packages" +#~ msgstr "Paket med skrivbordsunderlägg" + +#~ msgid "Images for widgets" +#~ msgstr "Bilder för grafiska komponenter" + +#~ msgid "Background image for widgets" +#~ msgstr "Bakgrundsbild för grafiska komponenter" + +#~ msgid "Analog clock face" +#~ msgstr "Urtavla för analog klocka" + +#~ msgid "Background image for panels" +#~ msgstr "Bakgrundsbild för paneler" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Bakgrund för diagramkomponenter" + +#~ msgid "Background image for tooltips" +#~ msgstr "Bakgrundsbild för verktygstips" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Ogenomskinliga bilder för dialogrutor" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Ogenomskinlig generell bakgrund för dialogrutor" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Ogenomskinligt tema för utloggningsdialogrutan" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Ogenomskinliga bilder för grafiska komponenter" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Ogenomskinlig bakgrundsbild för paneler" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Ogenomskinlig bakgrundsbild för verktygstips" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Inställningsfil för färgschema" + +#~ msgid "Service Descriptions" +#~ msgstr "Tjänstbeskrivningar" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "" +#~ "Kunde inte skapa skriptgränssnittet %1 för den grafiska komponenten %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Initiering av skript misslyckades" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Helger" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Händelser" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Uppgift" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Andra" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Föregående månad" + +#~ msgid "Previous Year" +#~ msgstr "Föregående år" + +#~ msgid "Previous Decade" +#~ msgstr "Föregående årtionde" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Idag" + +#~ msgid "Reset calendar to today" +#~ msgstr "Nollställ kalendern till idag" + +#~ msgid "Next Month" +#~ msgstr "Nästa månad" + +#~ msgid "Next Year" +#~ msgstr "Nästa år" + +#~ msgid "Next Decade" +#~ msgstr "Nästa årtionde" + +#~ msgid "Days" +#~ msgstr "Dagar" + +#~ msgid "Months" +#~ msgstr "Månader" + +#~ msgid "Years" +#~ msgstr "År" + +#~ msgid "OK" +#~ msgstr "Ok" + +#~ msgid "Cancel" +#~ msgstr "Avbryt" + +#~ msgid "Run the Associated Application" +#~ msgstr "Kör tillhörande program" + +#~ msgid "Open with %1" +#~ msgstr "Öppna med %1" + +#~ msgid "Accessibility" +#~ msgstr "Handikappstöd" + +#~ msgid "Application Launchers" +#~ msgstr "Programstartverktyg" + +#~ msgid "Astronomy" +#~ msgstr "Astronomi" + +#~ msgid "Date and Time" +#~ msgstr "Datum och tid" + +#~ msgid "Development Tools" +#~ msgstr "Utvecklingsverktyg" + +#~ msgid "Education" +#~ msgstr "Utbildning" + +#~ msgid "Environment and Weather" +#~ msgstr "Omgivning och väder" + +#~ msgid "Examples" +#~ msgstr "Exempel" + +#~ msgid "File System" +#~ msgstr "Filsystem" + +#~ msgid "Fun and Games" +#~ msgstr "Spel och annat kul" + +#~ msgid "Graphics" +#~ msgstr "Grafik" + +#~ msgid "Language" +#~ msgstr "Språk" + +#~ msgid "Mapping" +#~ msgstr "Kartor" + +#~ msgid "Miscellaneous" +#~ msgstr "Diverse" + +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + +#~ msgid "Online Services" +#~ msgstr "Nättjänster" + +#~ msgid "Productivity" +#~ msgstr "Produktivitet" + +#~ msgid "System Information" +#~ msgstr "Systeminformation" + +#~ msgid "Utilities" +#~ msgstr "Verktyg" + +#~ msgid "Windows and Tasks" +#~ msgstr "Fönster och aktiviteter" + +#~ msgid "Clipboard" +#~ msgstr "Klippbord" + +#~ msgid "Tasks" +#~ msgstr "Uppgifter" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Redigera %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Standardinställningar av teman, etc." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Färgschema att använda för program." + +#~ msgid "Preview Images" +#~ msgstr "Förhandsgranska bilder" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Förhandsgranskning av inloggningshanterare" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Förhandsgranskning av lås skärmen" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Förhandsgranskning av användarbyte" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Förhandsgranskning av byte av virtuellt skrivbord" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Förhandsgranskning av startskärm" + +#~ msgid "Preview for KRunner" +#~ msgstr "Förhandsgranskning av kör program" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Förhandsgranskning av fönsterdekorationer" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Förhandsgranskning av fönsterbyte" + +#~ msgid "Login Manager" +#~ msgstr "Inloggningshanterare" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Huvudskript för Inloggningshanterare" + +#~ msgid "Logout Dialog" +#~ msgstr "Utloggningsdialogruta" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Huvudskript för Utloggningsdialogruta" + +#~ msgid "Screenlocker" +#~ msgstr "Skärmlåsning" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Huvudskript för Lås skärmen" + +#~ msgid "UI for fast user switching" +#~ msgstr "Användargränssnitt för snabbt användarbyte" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Huvudskript för Användarbyte" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Byte av virtuellt skrivbord" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Huvudskript för Byte av virtuellt skrivbord" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Visa underrättelser på skärmen" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Huvudskript för Visa underrättelser på skärmen" + +#~ msgid "Splash Screen" +#~ msgstr "Startskärm" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Huvudskript för startskärm" + +#~ msgid "KRunner UI" +#~ msgstr "Användargränssnitt för Kör program" + +#~ msgid "Main Script KRunner" +#~ msgstr "Huvudskript för Kör program" + +#~ msgid "Window Decoration" +#~ msgstr "Fönsterdekoration" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Huvudskript för fönsterdekoration" + +#~ msgid "Window Switcher" +#~ msgstr "Fönsterbyte" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Huvudskript för fönsterbyte" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Slutför anpassning av layout" + +#~ msgid "Customize Layout..." +#~ msgstr "Anpassa layout..." + +#~ msgid "Fetching file type..." +#~ msgstr "Hämtar filtyp..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Alternativ för %1" + +#~ msgid "SVG scalable preview" +#~ msgstr "Skalbar SVG förhandsgranskning" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Ta bort %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Inställningar av %1" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Inställningar av %1..." + +#~ msgid "Low color images for dialogs" +#~ msgstr "Färgfattiga bilder för dialogrutor" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Färgfattig generell bakgrund för dialogrutor" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Färgfattigt tema för utloggningsdialogrutan" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Färgfattig bakgrundsbild för grafiska komponenter" + +#~ msgid "Low color analog clock face" +#~ msgstr "Färgfattig urtavla för analog klocka" + +#~ msgid "Low color background image for panels" +#~ msgstr "Färgfattig bakgrundsbild för paneler" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Färgfattig bakgrund för diagramkomponenter" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Färgfattig bakgrundsbild för verktygstips" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Pakethantering för Plasma" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Skapa ett SHA1-kondensat för paketet på " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Installation eller borttagning utförs med paket installerade för alla " +#~ "användare." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Pakettypen, t.ex. tema, skrivbordsunderlägg, plasmoid, datagränssnitt, " +#~ "körningsprogram, layoutmall, etc." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Installera paketet på " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Visar information om paket " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Uppgradera paketet på " + +#~ msgid "List installed packages" +#~ msgstr "Lista installerade paket" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "Listar alla kända pakettyper som kan installeras" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Ta bort paketet som heter " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Absolut sökväg till paketroten. Om den inte anges, används " +#~ "standarddatakatalogerna för KDE-sessionen istället." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Misslyckades skapa ett paketkondensat för %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "SHA1-kondensat för paket på %1: '%2'" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "skrivbordsunderlägg" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "paket" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "tema" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "datagränssnitt" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "körningsprogram" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "insticksprogram för skrivbordsunderlägg" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "utseende och känsla" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "skal" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "layout-mall" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "Kwin-effekt" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "fönsterbytare" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "Kwin-skript" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "Kunde inte hitta lämpligt installationsprogram för paket av typ %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "Listar tjänsttyper: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Fel: Insticksprogrammet %1 är inte installerat." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Antingen install, remove, upgrade eller list krävs." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Fel: Kan inte hitta insticksprogrammets metadata: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Visar information för paket: %1" + +#~ msgid " Name : %1" +#~ msgstr " Namn: %1" + +#~ msgid " Comment : %1" +#~ msgstr " Kommentar: %1" + +#~ msgid " Plugin : %1" +#~ msgstr "Insticksprogram: %1" + +#~ msgid " Author : %1" +#~ msgstr " Upphovsman: %1" + +#~ msgid " Path : %1" +#~ msgstr " Sökväg: %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Paketroten och globala alternativ står i konflikt med varandra, välj bara " +#~ "en." + +#~ msgid "Addon Name" +#~ msgstr "Tilläggets namn" + +#~ msgid "Service Type" +#~ msgstr "Tjänsttyp" + +#~ msgid "Path" +#~ msgstr "Sökväg" + +#~ msgid "Type Argument" +#~ msgstr "Typargument" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Typer av paket som kan installeras med det här verkyget:" + +#~ msgid "Built in:" +#~ msgstr "Inbyggda:" + +#~ msgid "DataEngine" +#~ msgstr "datagränssnitt" + +#~ msgid "Layout Template" +#~ msgstr "layout-mall" + +#~ msgid "Look and Feel" +#~ msgstr "Utseende och känsla" + +#~ msgid "Package" +#~ msgstr "Paket" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoid" + +#~ msgid "Runner" +#~ msgstr "Körprogram" + +#~ msgid "Shell" +#~ msgstr "Skal" + +#~ msgid "Theme" +#~ msgstr "Tema" + +#~ msgid "Wallpaper Images" +#~ msgstr "skrivbordsunderlägg" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Animerat skrivbordsunderlägg" + +#~ msgid "KWin Effect" +#~ msgstr "Kwin-effekt" + +#~ msgid "KWin Window Switcher" +#~ msgstr "Kwin-fönsterbyte" + +#~ msgid "KWin Script" +#~ msgstr "Kwin-skript" + +#~ msgid "Provided by plugins:" +#~ msgstr "Tillhandahållna av insticksprogram:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Tillhandahållna av skrivbordsfiler:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "Uppgraderade %1 med lyckat resultat" + +#~ msgid "Successfully installed %1" +#~ msgstr "Installerade %1 med lyckat resultat" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Fel: Installation av %1 misslyckades: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Uppgraderar paket från fil: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "Avinstallerade %1 med lyckat resultat" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Fel: Avinstallation av %1 misslyckades: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Kunde inte ladda installationsprogram för paket av typ %1. Felrapport: %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Kunde inte skapa paketets rotkatalog: %1" + +#~ msgid "No such file: %1" +#~ msgstr "Det finns ingen sådan fil: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "Kunde inte öppna paketfilen, arkivformatet stöds inte: %1 %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "Kunde inte öppna paketfilen: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "Ingen metadatafil i paketet: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "Paketets insticksprogramnamn är inte angivet: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "Paketets insticksprogramnamn %1 innehåller ogiltiga tecken" + +#~ msgid "%1 already exists" +#~ msgstr "%1 finns redan" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Kunde inte flytta paketet till målet: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Kunde inte kopiera paketet till målet: %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Kunde inte skapa lokal tjänstkatalog: %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "Kunde inte registrera paketet som tjänst (det är inte nödvändigtvis ett " +#~ "allvarligt fel): %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 finns inte" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Kunde inte ta bort paketet från: %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "Vill du verkligen ta bort %1?" + +#~ msgid "Applets furniture" +#~ msgstr "Miniprogrammets möbler" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "" +#~ "Användargränssnitt för utforskare för tillägg av grafiska komponenter" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "Användargränssnitt för vyerna som kommer att visa omgivningar" + +#~ msgid "Default layout file" +#~ msgstr "Standardlayoutfil" + +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "Standardinsticksprogram för omgivningar, omgivningsåtgärder, etc." + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "Felmeddelande som visas när laddning av ett miniprogram misslyckas" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "QML-komponent som visar ett miniprogram i ett dialogfönster" + +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Kompakt representation av ett miniprogram när det är ihopdraget i ett " +#~ "dialogfönster, exempelvis som en ikon. Miniprogram kan överskrida " +#~ "komponenten." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "QML-komponent för inställningsdialogrutan för miniprogram" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "QML-komponent för inställningsdialogrutan för omgivningar" + +#~ msgid "Panel configuration UI" +#~ msgstr "Användargränssnitt för panelinställning" + +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "QML-komponent för att välja ett alternativt miniprogram" + +#~ msgid "" +#~ "A UI for writing, loading and running desktop scripts in the current live " +#~ "session" +#~ msgstr "" +#~ "Ett användargränssnitt för att skriva, läsa in och köra skrivbordsskript " +#~ "i den aktuella pågående sessionen" + +#~ msgid "Theme preview thumbnail" +#~ msgstr "Miniatyrbild med förhandsgranskning av tema" + +#~ msgid "Ok" +#~ msgstr "Ok" diff --git a/po/ta/libplasma6.po b/po/ta/libplasma6.po new file mode 100644 index 0000000..442d6b5 --- /dev/null +++ b/po/ta/libplasma6.po @@ -0,0 +1,575 @@ +# Copyright (C) 2023 This file is copyright: +# This file is distributed under the same license as the plasma-framework package. +# +# SPDX-FileCopyrightText: 2021, 2022, 2023, 2024 Kishore G +msgid "" +msgstr "" +"Project-Id-Version: plasma-framework\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-09-07 21:00+0200\n" +"Last-Translator: Kishore G \n" +"Language-Team: Tamil \n" +"Language: ta\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 24.08.0\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "மேலும் செயல்கள்" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "சுருக்கு" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "விரி" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "கடவுச்சொல்" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "தேடு…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "தேடு" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "தேடலை காலியாக்கு" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "தெரியாதது" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "%1 பிளாஸ்மாய்டை செயல்படுத்து" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "%1 தனை நீக்கு" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "திருத்தும் பயன்முறையில் நுழை" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "%1 தனை அமை..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "பிளாஸ்மாய்டுகளை பூட்டு" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "பிளாஸ்மாய்டுகளை திருத்தவிடு" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "திருத்தும் பயன்முறையிலிருந்து வெளியேறு" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "தோற்றத்திட்டத்திற்கு வட்டில் தற்காலிக நினைவிடத்தை உருவாக்க வேண்டுமா." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "மாற்றுகள் காட்டு..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "பிளாஸ்மாய்ட் நீக்கப்பட்டது" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "\"%1\" என்ற பிளாஸ்மாய்ட் நீக்கப்பட்டது." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "பலகை நீக்கப்பட்டது" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "ஒரு பலகை நீக்கப்பட்டது." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "பணிமேடை நீக்கப்பட்டது" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "ஒரு பணிமேடை நீக்கப்பட்டது." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "செயல்நீக்கு" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "பிளாஸ்மாய்ட் அமைப்புகள்" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "இந்த பிளாஸ்மாய்டை நீக்கு" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "இந்த பலகையை நீக்கு" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "இந்த செயல்பாட்டை நீக்கு" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "செயல்பாடு அமைப்புகள்" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "பிளாஸ்மாய்டுகளை சேர் அல்லது நிர்வகி…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "கோரிய கூறை கண்டுபிடிக்க முடியவில்லை: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "%1 தனின் தாய் உருப்படி ContainmentItem வகையாக இருக்க வேண்டும்" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "%1 தனின் தாய் உருப்படி PlasmoidItem வகையாக இருக்க வேண்டும்" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "தெரியாத பிளாஸ்மாய்ட்" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"பிளாஸ்மாவின் கண்டறிய முடியாத பழைய பதிப்பிற்கு இந்த பிளாஸ்மாய்ட் எழுதப்பட்டுள்ளதால் %1 " +"பதிப்பில் இயங்காது. புதுப்பிக்கப்பட்ட பதிப்பை இதை இயற்றியவரிடம் கோரவும்." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1, பிளாஸ்மா %2-க்கு ஏற்புடையதல்ல" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"பிளாஸ்மாவின் %1 பதிப்பிற்கு இந்த பிளாஸ்மாய்ட் எழுதப்பட்டுள்ளதால் தற்போதைய %2 பதிப்பில் " +"இயங்காது. புதுப்பிக்கப்பட்ட பதிப்பை இதை இயற்றியவரிடம் கோரவும்." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"பிளாஸ்மாவின் %1 பதிப்பிற்கு இந்த பிளாஸ்மாய்ட் எழுதப்பட்டுள்ளதால் தற்போதைய %2 பதிப்பில் " +"இயங்காது. இதைப் பயன்படுத்த பிளாஸ்மாவைப் புதுப்பிக்கவும்." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "மன்னிக்கவும்! %1 என்பதை ஏற்றுவதில் சிக்கல் ஏற்பட்டது." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "QML கோப்பை ஏற்றுவதில் சிக்கல்: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "பிளாஸ்மாய்டை ஏற்றுவதில் சிக்கல்: %1 எனும் தொகுப்பு (package) இல்லை." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 அமைப்புகள்" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 அமைப்புகள்" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "பிளாஸ்மா தொகுப்பு" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "நிறுவு" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "தொகுப்பை நிறுவல் தோல்வியடைந்தது" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "நீங்கள் இட்ட தொகுப்பு செல்லுபடியாகாதது" + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "பிளாஸ்மாய்டுகள்" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "%1 தனை சேர்" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "சின்னத்தை சேர்" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "பின்னணிப் படம்" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "%1 தனை அமை" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "உள்ளடக்கம் போடப்பட்டது" + +#~ msgid "Add Widgets..." +#~ msgstr "பிளாஸ்மாய்டுகளை சேர்..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "%2 பிளாஸ்மாய்டுக்குத் தேவையான %1 எனும் தொகுப்பைத் திறக்க முடியவில்லை." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "ஒரு பிளாஸ்மாய்டை பிணையத்தில் பகிர்ந்தால், நீங்கள் அதை இன்னொரு கணினியிலிருந்து அணுகி " +#~ "அக்கணினியை தொலையியக்கியாக பயன்படுத்தலாம்." + +#~ msgid "Share this widget on the network" +#~ msgstr "பிளாஸ்மாய்டை பிணையத்தில் பகிர்" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "அனைவரையும் இந்த பிளாஸ்மாய்டை அணுக விடு" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "செல்லுபடியாகாத (null) சேவை, எந்த செயல்பாடுகளையும் செய்ய முடியாது." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "எந்த ScriptEngine-ஐ பயன்படுத்த வேண்டுமென்பதை %1 பிளாஸ்மாய்ட் குறிப்பிடவில்லை." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "மற்றவை" + +#~ msgid "Main Script File" +#~ msgstr "பிரதான சிறுநிரல் கோப்பு" + +#~ msgid "Tests" +#~ msgstr "சோதனைகள்" + +#~ msgid "Images" +#~ msgstr "படங்கள்" + +#~ msgid "Themed Images" +#~ msgstr "தோற்றத்திட்டத்தின் படங்கள்" + +#~ msgid "Configuration Definitions" +#~ msgstr "அமைப்புத்திட்டங்கள்" + +#~ msgid "User Interface" +#~ msgstr "பயனர் இடைமுகப்பு" + +#~ msgid "Data Files" +#~ msgstr "தரவு கோப்புகள்" + +#~ msgid "Executable Scripts" +#~ msgstr "இயக்கவல்ல சிறுநிரல்கள்" + +#~ msgid "Screenshot" +#~ msgstr "திரைப்பிடிப்பு" + +#~ msgid "Translations" +#~ msgstr "மொழிபெயர்ப்புகள்" + +#~ msgid "Images for dialogs" +#~ msgstr "துணை சாளரங்களுக்கான படங்கள்" + +#~ msgid "Generic dialog background" +#~ msgstr "துணை சாளரங்களுக்கான பின்புலம்" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "வெளியேற்ற சாளரத்திற்கான தோற்றத்திட்டம்" + +#~ msgid "Wallpaper packages" +#~ msgstr "பின்னணிப் படத் தொகுப்புகள்" + +#~ msgid "Images for widgets" +#~ msgstr "பிளாஸ்மாய்டுகளுக்கான படங்கள்" + +#~ msgid "Background image for widgets" +#~ msgstr "பிளாஸ்மாய்டுகளுக்கான பின்புலப் படம்" + +#~ msgid "Analog clock face" +#~ msgstr "முட்கடிகாரம்" + +#~ msgid "Background image for panels" +#~ msgstr "பலகைகளுக்கான பின்புலப் படம்" + +#~ msgid "Background for graphing widgets" +#~ msgstr "வரைபட பிளாஸ்மாய்டுகளுக்கான பின்புலப் படம்" + +#~ msgid "Background image for tooltips" +#~ msgstr "கருவித்துப்புகளுக்கான பின்புலப் படம்" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "சாளரங்களுக்கான ஒளிபுகா படங்கள்" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "ஒளிபுகா பொது சாளரப் பின்புலம்" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "வெளியேற்ற சாளரத்திற்கான ஒளிபுகா தோற்றத்திட்டம்" + +#~ msgid "Opaque images for widgets" +#~ msgstr "பிளாஸ்மாய்டுகளுக்கான ஒளிபுகா படங்கள்" + +#~ msgid "Opaque background image for panels" +#~ msgstr "பலகைகளுக்கான ஒளிபுகா பின்புலப் படம்" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "கருவித்துப்புகளுக்கான ஒளிபுகா பின்புலப் படம்" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme அமைப்புக்கோப்பு" + +#~ msgid "Service Descriptions" +#~ msgstr "சேவைகளின் விவரணங்கள்" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "%2 பிளாஸ்மாய்டுக்கான %1 ScriptEngine-ஐ உருவாக்க முடியவில்லை." + +#~ msgid "Script initialization failed" +#~ msgstr "சிறுநிரல் துவக்கம் தோல்வியடைந்தது" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "விடுமுறைகள்" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "நிகழ்வுகள் " + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "செய்ய வேண்டியவை" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "மற்றவை" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "முந்தைய மாதம்" + +#~ msgid "Previous Year" +#~ msgstr "முந்தைய ஆண்டு" + +#~ msgid "Previous Decade" +#~ msgstr "முந்தைய பத்தாண்டு" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "இன்று" + +#~ msgid "Reset calendar to today" +#~ msgstr "நாள்காட்டியை இன்றைய தேதிக்கு மீட்டமை" + +#~ msgid "Next Month" +#~ msgstr "அடுத்த மாதம்" + +#~ msgid "Next Year" +#~ msgstr "அடுத்த ஆண்டு" + +#~ msgid "Next Decade" +#~ msgstr "அடுத்த பத்தாண்டு" + +#~ msgid "Days" +#~ msgstr "நாட்கள்" + +#~ msgid "Months" +#~ msgstr "மாதங்கள்" + +#~ msgid "Years" +#~ msgstr "ஆண்டுகள்" + +#~ msgid "OK" +#~ msgstr "சரி" + +#~ msgid "Cancel" +#~ msgstr "ரத்து செய்" + +#~ msgid "Run the Associated Application" +#~ msgstr "தொடர்புள்ள செயலியை இயக்கு" + +#~ msgid "Open with %1" +#~ msgstr "%1 கொண்டு திற" + +#~ msgid "Accessibility" +#~ msgstr "அணுகல்தன்மை" + +#~ msgid "Application Launchers" +#~ msgstr "செயலி ஏவிகள்" + +#~ msgid "Astronomy" +#~ msgstr "வானியல்" + +#~ msgid "Date and Time" +#~ msgstr "தேதி மற்றும் நேரம்" + +#~ msgid "Development Tools" +#~ msgstr "உருவாக்கக் கருவிகள்" + +#~ msgid "Education" +#~ msgstr "கல்வி" + +#~ msgid "Environment and Weather" +#~ msgstr "சுற்றுச்சூழல் மற்றும் வானிலை" + +#~ msgid "Examples" +#~ msgstr "எடுத்துக்காட்டுகள்" + +#~ msgid "File System" +#~ msgstr "கோப்பு முறைமை" + +#~ msgid "Fun and Games" +#~ msgstr "விளையாட்டுகள்" + +#~ msgid "Graphics" +#~ msgstr "வரைகலை" + +#~ msgid "Language" +#~ msgstr "மொழி" + +#~ msgid "Mapping" +#~ msgstr "நிலப்படவியல்" + +#~ msgid "Miscellaneous" +#~ msgstr "மற்றவை" + +#~ msgid "Multimedia" +#~ msgstr "பல்லூடகம்" + +#~ msgid "Online Services" +#~ msgstr "இணைய சேவைகள்" + +#~ msgid "Productivity" +#~ msgstr "வேலை" + +#~ msgid "System Information" +#~ msgstr "கணினி விவரங்கள்" + +#~ msgid "Utilities" +#~ msgstr "பயனுள்ளவை" + +#~ msgid "Windows and Tasks" +#~ msgstr "சாளரங்கள் மற்றும் பணிகள்" + +#~ msgid "Clipboard" +#~ msgstr "பிடிப்புப்பலகை" + +#~ msgid "Tasks" +#~ msgstr "பணிகள்" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "%1 தனை திருத்து..." diff --git a/po/tg/libplasma6.po b/po/tg/libplasma6.po new file mode 100644 index 0000000..59764b8 --- /dev/null +++ b/po/tg/libplasma6.po @@ -0,0 +1,688 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the plasma-framework package. +# +# Victor Ibragimov , 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: plasma-framework\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2020-09-19 11:42+0500\n" +"Last-Translator: Victor Ibragimov \n" +"Language-Team: English \n" +"Language: tg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 20.04.2\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Номаълум" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Фаъол кардани виҷети %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Тоза кардани %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Гузариш ба реҷаи тағйирдиҳӣ" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Танзимоти %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Қулф кардани виҷетҳо" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Кушодани қулфи виҷетҳо" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Баромад аз реҷаи тағйирдиҳӣ" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "" +"Имконияти эҷодкунии зерҳофизаи мавзӯъро дар диски компютерӣ муайян мекунад." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Андозаи калонтарини зерҳофизаи мавзӯъ дар диски компютерӣ дар килобайтҳо " +"ҳисоб карда мешавад. Ба назар гиред, ки файлҳо алоҳида нигоҳ дошта мешаванд, " +"бинобар ин андозаи калонтарин метавонад истифода бурда нашавад. Танзимкунии " +"андозаи калонтар ба ҳамин сабаб безарар аст." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Намоиш додани имконоти дигар..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Виҷет тоза шуд" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Виҷети \"%1\" тоза карда шуд." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Лавҳа тоза шуд" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Лавҳа тоза карда шуд." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Мизи корӣ тоза шуд" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Мизи корӣ тоза карда шуд." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Ботил сохтан" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Танзимоти виҷетҳо" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Тоза кардани ин виҷет" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Тоза кардани ин лавҳа" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Тоза кардани ин фаъолият" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Танзимоти фаъолиятҳо" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Унсури дархостшуда ёфт нашуд: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, fuzzy, kde-format +#| msgid "Unknown" +msgid "Unknown Applet" +msgstr "Номаълум" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, fuzzy, kde-format +#| msgid "Error loading QML file: %1" +msgid "Error loading QML file: %1 %2" +msgstr "Хатои боркунии файли QML: %1" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package inexistent. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Хатои боркунии зербарнома: баста вуҷуд надорад. %1" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "Танзимоти %1" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Танзимоти %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Бастаи Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Насб кардан" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Насбкунии баста қатъ шуд" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Бастае, ки шумо интихоб кардед, беэътибор аст." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Виҷетҳо" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Илова кардани %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Илова кардани нишона" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Тасвири замина" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Танзим кардани %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Ҳаракаткунии муҳтаво" + +#~ msgid "Add Widgets..." +#~ msgstr "Илова кардани виҷетҳо..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Бастаи %1, ки барои виҷети %2 лозим аст, кушода нашуд." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Мубодилакунии виҷет тавассути шабака иҷозат медиҳад. то тавонед ба ин " +#~ "виҷет аз компютери дурдаст, монанди идоракунии дурдаст, дастрасӣ пайдо " +#~ "кунед." + +#~ msgid "Share this widget on the network" +#~ msgstr "Мубодилакунии ин виҷет тавассути шабака" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "" +#~ "Иҷозат диҳед, то ки ҳар як кас тавонад ба ин виҷет дастрасӣ пайдо кунад" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Хидмати (null) беэътибор ягон амалиётро иҷро карда наметавонад." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "" +#~ "Виҷети %1 наметавонад, ки ScriptEngine-ро барои истифода муайян намояд." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Барномаҳои гуногун" + +#~ msgid "Main Script File" +#~ msgstr "Файли нақши асосӣ" + +#~ msgid "Tests" +#~ msgstr "Санҷишҳо" + +#~ msgid "Images" +#~ msgstr "Тасвирҳо" + +#~ msgid "Themed Images" +#~ msgstr "Тасвирҳои мавзӯӣ" + +#~ msgid "Configuration Definitions" +#~ msgstr "Таърифҳои танзимот" + +#~ msgid "User Interface" +#~ msgstr "Воситаи корбарӣ" + +#~ msgid "Data Files" +#~ msgstr "Файлҳои иттилоотӣ" + +#~ msgid "Executable Scripts" +#~ msgstr "Нақшҳои иҷрошаванда" + +#~ msgid "Screenshot" +#~ msgstr "Акси экран" + +#~ msgid "Translations" +#~ msgstr "Тарҷумаҳо" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Танзимоти намунаи саҳифаҳои UI" + +#~ msgid "Configuration XML file" +#~ msgstr "Файли танзимии XML" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Васеъкунандаи фармоишӣ барои зербарномаҳои ҷафс" + +#~ msgid "Images for dialogs" +#~ msgstr "Тасвирҳо барои равзанаҳои гуфтугӯ" + +#~ msgid "Generic dialog background" +#~ msgstr "Тасвири заминаи равзанаи гуфтугӯи умумӣ" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Мавзӯъ барои равзанаи гуфтугӯи баромад аз низом" + +#~ msgid "Wallpaper packages" +#~ msgstr "Бастаҳои тасвири замина" + +#~ msgid "Images for widgets" +#~ msgstr "Тасвирҳо барои виҷетҳо" + +#~ msgid "Background image for widgets" +#~ msgstr "Тасвири пасзамина барои виҷетҳо" + +#~ msgid "Analog clock face" +#~ msgstr "Лавҳаи соати рақамӣ" + +#~ msgid "Background image for panels" +#~ msgstr "Тасвири пасзамина барои лавҳаҳо" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Пасзамина барои виҷетҳои намудсозӣ" + +#~ msgid "Background image for tooltips" +#~ msgstr "Тасвири пасзамина барои маслиҳатҳо" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Тасвирҳои нoшаффoф барои равзанаҳои гуфтугӯ" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Тасвири заминаи нoшаффoфи равзанаи гуфтугӯи умумӣ" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Мавзӯи нoшаффoф барои равзанаи гуфтугӯи баромад аз низом" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Тасвирҳои нoшаффoф барои виҷетҳо" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Тасвири пасзаминаи нoшаффoф барои лавҳаҳо" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Тасвири пасзаминаи нoшаффoф барои маслиҳатҳо" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Файли танзимии KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Тавсифи хидматҳо" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "%1 ScriptEngine барои виҷети %2 эҷод карда нашуд." + +#~ msgid "Script initialization failed" +#~ msgstr "Омодасозии нақш қатъ шуд" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Идҳо" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Рӯйдодҳо" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Рӯйхати вазифаҳо" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Дигар" + +#~ msgid "Previous Month" +#~ msgstr "Моҳи гузашта" + +#~ msgid "Previous Year" +#~ msgstr "Соли гузашта" + +#~ msgid "Previous Decade" +#~ msgstr "Даҳсолагии гузашта" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Имрӯз" + +#~ msgid "Reset calendar to today" +#~ msgstr "Тақвимро ба имрӯз бозсозӣ кунед" + +#~ msgid "Next Month" +#~ msgstr "Моҳи оянда" + +#~ msgid "Next Year" +#~ msgstr "Соли оянда" + +#~ msgid "Next Decade" +#~ msgstr "Даҳсолагии оянда" + +#, fuzzy +#~| msgid "Next Month" +#~ msgid "Months" +#~ msgstr "Моҳи оянда" + +#~ msgid "OK" +#~ msgstr "ХУБ" + +#~ msgid "Cancel" +#~ msgstr "Бекор кардан" + +#~ msgid "Run the Associated Application" +#~ msgstr "Иҷро кардани барномаи марбут" + +#~ msgid "Open with %1" +#~ msgstr "Кушодан ба воситаи %1" + +#~ msgid "Accessibility" +#~ msgstr "Қобилияти дастрасӣ" + +#~ msgid "Application Launchers" +#~ msgstr "Оғозкунандаи барномаҳо" + +#~ msgid "Astronomy" +#~ msgstr "Ситopашинoсӣ" + +#~ msgid "Date and Time" +#~ msgstr "Вақт ва сана" + +#~ msgid "Development Tools" +#~ msgstr "Абзорҳои барномарезӣ" + +#~ msgid "Education" +#~ msgstr "Илму маърифат" + +#~ msgid "Environment and Weather" +#~ msgstr "Муҳити атроф ва обу ҳаво" + +#~ msgid "Examples" +#~ msgstr "Мисолҳо" + +#~ msgid "File System" +#~ msgstr "Низоми файлӣ" + +#~ msgid "Fun and Games" +#~ msgstr "Дилхушӣ ва бозиҳо" + +#~ msgid "Graphics" +#~ msgstr "Графика" + +#~ msgid "Language" +#~ msgstr "Забон" + +#~ msgid "Mapping" +#~ msgstr "Нақшакашӣ" + +#~ msgid "Miscellaneous" +#~ msgstr "Барномаҳои гуногун" + +#~ msgid "Multimedia" +#~ msgstr "Мултимедиа" + +#~ msgid "Online Services" +#~ msgstr "Хизматҳои онлайн" + +#~ msgid "Productivity" +#~ msgstr "Самаранокӣ" + +#~ msgid "System Information" +#~ msgstr "Иттилооти низом" + +#~ msgid "Utilities" +#~ msgstr "Барномаҳои муфид" + +#~ msgid "Windows and Tasks" +#~ msgstr "Равзанаҳо ва вазифаҳо" + +#~ msgid "Clipboard" +#~ msgstr "Ҳофизаи муваққатӣ" + +#~ msgid "Tasks" +#~ msgstr "Вазифаҳо" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Таҳрир кардани %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Танзимоти стандартӣ барои мавзӯъ ва ғайра." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Нақшаи рангҳо барои истифода дар барномаҳо." + +#~ msgid "Preview Images" +#~ msgstr "Пешнамоиши тасвирҳо" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Пешнамоиш барои мудири воридшавӣ" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Пешнамоиш барои экрани қулф" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Пешнамоиш барои ивазкунандаи корбар" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Пешнамоиш барои ивазкунандаи мизи кории виртуалӣ" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Пешнамоиш барои экрани дурахшон" + +#~ msgid "Preview for KRunner" +#~ msgstr "Пешнамоиш барои KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Пешнамоиш барои ороишҳои равзана" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Пешнамоиш барои ивазкунандаи равзана" + +#~ msgid "Login Manager" +#~ msgstr "Мудири воридшавӣ" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Нақши асосӣ барои мудири воридшавӣ" + +#~ msgid "Logout Dialog" +#~ msgstr "Равзанаи гуфтугӯи баромад аз низом" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Нақши асосӣ барои равзанаи гуфтугӯи баромад аз низом" + +#~ msgid "Screenlocker" +#~ msgstr "Қулфкунандаи экран" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Нақши асосӣ барои экрани қулф" + +#~ msgid "UI for fast user switching" +#~ msgstr "Воситаи корбарӣ барои ивазкунии тезкори корбар" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Нақши асосӣ барои ивазкунандаи корбар" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Ивазкунандаи мизи кории виртуалӣ" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Нақши асосӣ барои ивазкунандаи мизи кории виртуалӣ" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Намоиши огоҳиномаҳо дар экран" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Нақши асосӣ барои намоиши огоҳиномаҳо дар экран" + +#~ msgid "Splash Screen" +#~ msgstr "Экрани дурахшон" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Нақши асосӣ барои экрани дурахшон" + +#~ msgid "KRunner UI" +#~ msgstr "Воситаи корбарии KRunner" + +#~ msgid "Main Script KRunner" +#~ msgstr "Нақши асосии KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Ороиши равзана" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Нақши асосӣ барои ороиши равзана" + +#~ msgid "Window Switcher" +#~ msgstr "Ивазкунандаи равзана" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Нақши асосӣ барои ивазкунандаи равзана" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Анҷом додани тарҳбандии фармоишӣ" + +#~ msgid "Customize Layout..." +#~ msgstr "Тарҳбандии фармоишӣ..." + +#~ msgid "Fetching file type..." +#~ msgstr "Бозёбии навъи файл..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Имконоти %1" diff --git a/po/tr/libplasma6.po b/po/tr/libplasma6.po new file mode 100644 index 0000000..c81b5d8 --- /dev/null +++ b/po/tr/libplasma6.po @@ -0,0 +1,350 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Volkan, 2013. +# Volkan Gezer , 2013, 2014, 2015, 2017, 2022. +# Kaan Ozdincer , 2014. +# SPDX-FileCopyrightText: 2022, 2023, 2024 Emir SARI +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-25 20:47+0300\n" +"Last-Translator: Emir SARI \n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 24.11.70\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Daha Fazla Eylem" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Daralt" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Genişlet" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Parola" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Ara…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Ara" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Aramayı temizle" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Bilinmeyen" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Araç takımını etkinleştir: %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Kaldır: %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Düzenleme Kipine Gir" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Yapılandır: %1…" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Araç Takımlarını Kilitle" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Araç Takımlarının Kilidini Aç" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Düzenleme Kipinden Çık" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Tema için disk üzerinde önbellek oluşturulup oluşturulmayacağı." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Kilobyte türünden diskteki tema önbelleğinin en büyük boyutu. Bu dosyalar " +"diskte tanımlanan boyutu hemen kullanmadıklarından en büyük boyut " +"kullanılmıyor olabilir. Genellikle daha büyük boyut atamak güvenli sayılır." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Alternatifleri Göster…" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Araç Takımı Kaldırıldı" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "“%1” araç takımı kaldırıldı." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Panel Kaldırıldı" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Bir panel kaldırıldı." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Masaüstü Kaldırıldı" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Bir masaüstü kaldırıldı." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Geri Al" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Araç Takımı Ayarları" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Bu araç takımını kaldır" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Bu Paneli Kaldır" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Bu Etkinliği Kaldır" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Etkinlik Ayarları" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Araç Takımları Ekle veya Yönet…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "İstenilen bileşen bulunamadı: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "%1 kök ögesi, ContainmentItem türünde olmalıdır" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "%1 kök ögesi, PlasmoidItem türünde olmalıdır" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Bilinmeyen Uygulamacık" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Bu araç takımı Plasma’nın bilinmeyen eski bir sürümü için yazıldı ve Plasma " +"%1 ile uyumlu değil. Güncel bir sürüm için araç takımının yazarıyla " +"iletişime geçin." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1, Plasma %2 ile uyumlu değil" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Bu araç takımı Plasma %1 için yazıldı ve Plasma %2 ile uyumlu değil. Güncel " +"bir sürüm için araç takımının yazarıyla iletişime geçin." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Bu araç takımı Plasma %1 için yazıldı ve Plasma %2 ile uyumlu değil. Araç " +"takımını kullanmak için lütfen Plasma’yı güncelleyin." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Üzgünüm! %1 yüklenirken bir hata oluştu." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "QML dosyası yüklenirken hata: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Uygulamacık yüklenirken hata: %1 paketi yok." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 Ayarları" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 Ayarları" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma Paketi" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Kur" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Paket Kurulumu Başarısız" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Az önce bıraktığınız paket geçersiz." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Araç Takımları" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Ekle: %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Simge Ekle" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Duvar Kağıdı" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Ayarla: %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "İçerik bırakıldı" + +#~ msgid "Add Widgets..." +#~ msgstr "Araç Takımları Ekle…" + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "%2 araç takımı için gereken %1 paketi açılamadı." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Ağ üzerinden bir araç takımı paylaştığınızda, bu araç takımına ağ " +#~ "üzerindeki diğer bir bilgisayar uzaktan erişebilir." + +#~ msgid "Share this widget on the network" +#~ msgstr "Bu araç takımını ağda paylaş" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Bu araç takımına herkesin erişmesine izin ver" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Geçersiz (boş) hizmet, hiçbir işlem yapamaz." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "%1 araç takımı kullanılacak Betik İşletkesi'ni tanımlamadı." diff --git a/po/ug/libplasma6.po b/po/ug/libplasma6.po new file mode 100644 index 0000000..88a905f --- /dev/null +++ b/po/ug/libplasma6.po @@ -0,0 +1,783 @@ +# Uyghur translation for libplasma. +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Gheyret Kenji , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: libplasma\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2013-09-08 07:05+0900\n" +"Last-Translator: Gheyret Kenji \n" +"Language-Team: Uyghur \n" +"Language: ug\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "نامەلۇم" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "%1 Widget نى ئاكتىپلا" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, fuzzy, kde-format +#| msgctxt "%1 is the name of the applet" +#| msgid "Remove this %1" +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "بۇ %1 نى چىقىرىۋەت" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Widget قۇلۇپلا" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "ۋىجېتلارنى قۇلۇپسىزلا" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "" + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "" + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "" + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Widget تەڭشەكلەر" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Widget نى چىقىرىۋەت" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "بۇ تاختىنى چىقىرىۋەت" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "بۇ پائالىيەتنى چىقىرىۋەت" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "پائالىيەت تەڭشىكى" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "لازىملىق بۆلەكنى تاپالمىدى: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:557 +#, fuzzy, kde-format +#| msgid "Unknown" +msgid "Unknown Applet" +msgstr "نامەلۇم" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgctxt "%1 is the name of the applet" +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "%1 تەڭشىكى" + +#: plasmaquick/configview.cpp:232 +#, fuzzy, kde-format +#| msgctxt "%1 is the name of the applet" +#| msgid "%1 Settings" +msgid "%1 Settings" +msgstr "%1 تەڭشىكى" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, fuzzy, kde-format +#| msgid "Plasma Package Manager" +msgid "Plasma Package" +msgstr "پلازما بوغچا باشقۇرغۇچ" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, fuzzy, kde-format +#| msgid "Script initialization failed" +msgid "Package Installation Failed" +msgstr "قوليازمىنى دەسلەپلەشتۈرەلمىدى" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, fuzzy, kde-format +#| msgid "Lock Widgets" +msgid "Widgets" +msgstr "Widget قۇلۇپلا" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, fuzzy, kde-format +#| msgid "Icon" +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "سىنبەلگە" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, fuzzy, kde-format +#| msgid "Wallpaper packages" +msgid "Wallpaper" +msgstr "تام قەغەز بوغچالارى" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "" + +#~ msgid "Add Widgets..." +#~ msgstr "Widget قوش…" + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "%2 widget قا زۆرۈر بولغان %1 بوغچىنى ئاچالمىدى." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "توردا widget ھەمبەھىر سىزنىڭ باشقا كومپيۇتېردىمۇ بۇ widget نى يىراقتىن " +#~ "زىيارەت قىلىشىڭىزغا يول قويىدۇ." + +#~ msgid "Share this widget on the network" +#~ msgstr "بۇ widget نى توردا ھەمبەھىرلە" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "" +#~ "ھەر قانداق ئىشلەتكۈچىنىڭ بۇ widget نى ئەركىن زىيارەت قىلىشىغا يول قوي" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "" +#~ "ئىناۋەتسىز (null) مۇلازىمەت، ھەر قانداق مەشغۇلاتنى ئىجرا قىلالمايدۇ." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "باشقىلار" + +#~ msgid "Main Script File" +#~ msgstr "ئاساسىي قوليازما ھۆججىتى" + +#~ msgid "Images" +#~ msgstr "سۈرەتلەر" + +#~ msgid "Themed Images" +#~ msgstr "ئۆرنەكلىك سۈرەتلەر" + +#~ msgid "Configuration Definitions" +#~ msgstr "سەپلىمە ئېنىقلىمىسى" + +#~ msgid "User Interface" +#~ msgstr "كۆرۈنمەيۈز" + +#~ msgid "Data Files" +#~ msgstr "سانلىق-مەلۇمات ھۆججەتلىرى" + +#~ msgid "Executable Scripts" +#~ msgstr "ئىجراچان قوليازمىلار" + +#~ msgid "Translations" +#~ msgstr "تەرجىمىسى" + +#~ msgid "Configuration XML file" +#~ msgstr "سەپلىمە XML ھۆججەت" + +#~ msgid "Images for dialogs" +#~ msgstr "سۆزلەشكۈنىڭ سۈرەتلىرى" + +#~ msgid "Generic dialog background" +#~ msgstr "ئادەتتىكى سۆزلەشكۈ تەگلىكى" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "تىزىمدىن چىقىش سۆزلەشكۈنىڭ ئۆرنەكى" + +#~ msgid "Wallpaper packages" +#~ msgstr "تام قەغەز بوغچالارى" + +#~ msgid "Images for widgets" +#~ msgstr "widget نىڭ سۈرەتلىرى" + +#~ msgid "Background image for widgets" +#~ msgstr "widget نىڭ تەگلىك سۈرەتلىرى" + +#~ msgid "Analog clock face" +#~ msgstr "تەقلىدىي سائەت يۈزى" + +#~ msgid "Background image for panels" +#~ msgstr "تاختىنىڭ تەگلىك سۈرەتلىرى" + +#~ msgid "Background for graphing widgets" +#~ msgstr "گرافىكىلىق widget نىڭ تەگلىكى" + +#~ msgid "Background image for tooltips" +#~ msgstr "قورال ئەسكەرتىشىنىڭ تەگلىك سۈرىتى" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "سۆزلەشكۈنىڭ سۈزۈك سۈرەتلىرى" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "ئادەتتىكى سۆزلەشكۈنىڭ سۈزۈك تەگلىكى" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "تىزىمدىن چىقىش سۆزلەشكۈنىڭ سۈزۈك ئۆرنەكى" + +#~ msgid "Opaque images for widgets" +#~ msgstr "widget نىڭ سۈزۈك سۈرەتلىرى" + +#~ msgid "Opaque background image for panels" +#~ msgstr "تاختىنىڭ سۈزۈك تەگلىك سۈرەتلىرى" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "قورال ئەسكەرتىشىنىڭ سۈزۈك تەگلىك سۈرەتلىرى" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme سەپلىمە ھۆججىتى" + +#~ msgid "Service Descriptions" +#~ msgstr "مۇلازىمەت چۈشەندۈرۈشى" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "%2 widget نىڭ %1 قوليازما ماتورىنى قۇرالمىدى." + +#~ msgid "Script initialization failed" +#~ msgstr "قوليازمىنى دەسلەپلەشتۈرەلمىدى" + +#~ msgid "Run the Associated Application" +#~ msgstr "باغلىنىشلىق پروگراممىنى ئىجرا قىل" + +#~ msgid "Accessibility" +#~ msgstr "ياردەم ئىقتىدارى" + +#~ msgid "Application Launchers" +#~ msgstr "پروگرامما ئىجرا قىلغۇچ" + +#~ msgid "Astronomy" +#~ msgstr "ئاسترونومىيە" + +#~ msgid "Date and Time" +#~ msgstr "چېسلا ۋە ۋاقىت" + +#~ msgid "Development Tools" +#~ msgstr "ئىجادكارلار قورالى" + +#~ msgid "Education" +#~ msgstr "مائارىپ" + +#~ msgid "Environment and Weather" +#~ msgstr "مۇھىت ۋە ھاۋارايى" + +#~ msgid "Examples" +#~ msgstr "مىساللار" + +#~ msgid "File System" +#~ msgstr "ھۆججەت سىستېمىسى" + +#~ msgid "Fun and Games" +#~ msgstr "ئويۇن ۋە تاماشا" + +#~ msgid "Graphics" +#~ msgstr "گرافىك" + +#~ msgid "Language" +#~ msgstr "تىل" + +#~ msgid "Mapping" +#~ msgstr "خەرىتىلە" + +#~ msgid "Miscellaneous" +#~ msgstr "باشقىلار" + +#~ msgid "Multimedia" +#~ msgstr "كۆپ ۋاسىتە" + +#~ msgid "Online Services" +#~ msgstr "توردىكى مۇلازىمەتلەر" + +#~ msgid "Productivity" +#~ msgstr "ئىشلەپچىقىرىش ئۈنۈمى" + +#~ msgid "System Information" +#~ msgstr "سىستېما ئۇچۇرى" + +#~ msgid "Utilities" +#~ msgstr "قوراللار" + +#~ msgid "Windows and Tasks" +#~ msgstr "كۆزنەك ۋە ۋەزىپىلەر" + +#, fuzzy +#~| msgid "Themed Images" +#~ msgid "Preview Images" +#~ msgstr "ئۆرنەكلىك سۈرەتلەر" + +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script for Login Manager" +#~ msgstr "ئاساسىي قوليازما ھۆججىتى" + +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "ئاساسىي قوليازما ھۆججىتى" + +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script for Lock Screen" +#~ msgstr "ئاساسىي قوليازما ھۆججىتى" + +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script for User Switcher" +#~ msgstr "ئاساسىي قوليازما ھۆججىتى" + +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script for Splash Screen" +#~ msgstr "ئاساسىي قوليازما ھۆججىتى" + +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "Main Script KRunner" +#~ msgstr "ئاساسىي قوليازما ھۆججىتى" + +#~ msgid "Fetching file type..." +#~ msgstr "ھۆججەت تىپىغا ئېرىشىۋاتىدۇ…" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1 تاللانما" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "بۇ %1 نى چىقىرىۋەت" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "%1 تەڭشىكى" + +#, fuzzy +#~| msgctxt "%1 is the name of the applet" +#~| msgid "%1 Settings" +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "%1 تەڭشىكى" + +#~ msgid "Low color images for dialogs" +#~ msgstr "سۆزلەشكۈنىڭ تۆۋەن رەڭلىك سۈرەتلىرى" + +#~ msgid "Low color generic dialog background" +#~ msgstr "ئادەتتىكى سۆزلەشكۈنىڭ تۆۋەن رەڭلىك تەگلىكى" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "تىزىمدىن چىقىش سۆزلەشكۈنىڭ تۆۋەن رەڭلىك ئۆرنەكى" + +#~ msgid "Low color background image for widgets" +#~ msgstr "widget نىڭ تۆۋەن رەڭلىك تەگلىك سۈرىتى" + +#~ msgid "Low color analog clock face" +#~ msgstr "تۆۋەن رەڭلىك تەقلىدىي سائەت يۈزى" + +#~ msgid "Low color background image for panels" +#~ msgstr "تاختىنىڭ تۆۋەن رەڭلىك تەگلىك سۈرىتى" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "گرافىكىلىق widget نىڭ تۆۋەن رەڭلىك تەگلىكى" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "قورال ئەسكەرتىشنىڭ تۆۋەن رەڭلىك تەگلىك سۈرىتى" + +#~ msgid "Plasma Package Manager" +#~ msgstr "پلازما بوغچا باشقۇرغۇچ" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr " دىكى بوغچا ئۈچۈن SHA1 ئالاھىدىلىك كودى ھاسىل قىلىش" + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "ھەممە ئىشلەتكۈچىگە نىسبەتەن يېڭى بوغچا ئورنىتىش ياكى ئورنىتىلغان بوغچىنى " +#~ "چىقىرىۋېتىش مەشغۇلاتى بىلەن تەمىنلەيدۇ." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "بوغچىنىڭ تىپى، مەسىلەن ئۆرنەك، تام قەغەز، plasmoid، سانلىق-مەلۇمات " +#~ "ماتورى، ئىجراچى، جايلاشتۇرۇش قېلىپى قاتارلىق." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr " دىكى بوغچىنى ئورنىتىش" + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr " دىكى بوغچىنى يۈكسەلدۈرۈش" + +#, fuzzy +#~| msgid "Wallpaper packages" +#~ msgid "List installed packages" +#~ msgstr "تام قەغەز بوغچالارى" + +#, fuzzy +#~| msgid "lists all known Package types that can be installed" +#~ msgid "List all known package types that can be installed" +#~ msgstr "مەلۇملۇق ئورناتقىلى بولىدىغان ھەممە بوغچا تىپى تىزىمىنى كۆرسىتىدۇ" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr " ئاتلىق بوغچىنى چىقىرىۋەت" + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "بوغچا مۇندەرىجە شېخىنىڭ مۇتلەق يولى. ئەگەر تەمىنلەنمىسە، ئۇنداقتا بۇ " +#~ "قېتىملىق KDE ئەڭگىمەنىڭ ئۆلچەملىك سانلىق-مەلۇمات مۇندەرىجىسىنى ئىزدەيدۇ." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "%1 ئۈچۈن ئالاھىدىلىك كودى ھاسىل قىلىش مەغلۇپ بولدى" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "%1 دىكى بوغچىنىڭ SHA1 ئالاھىدىلىك كودى: ‹%2›" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "تام قەغىزى" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "plasmoid" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "بوغچا" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "ئۆرنەك" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "سانلىق-مەلۇمات ماتورى" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "ئىجرا قىلغۇچى" + +#, fuzzy +#~| msgid "Wallpaper packages" +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "تام قەغەز بوغچالارى" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "جايلاشتۇرۇش قېلىپى" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "kwineffect" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "windowswitcher" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "kwinscript" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "بوغچا تىپى %1 غا ماس كېلىدىغان بوغچا ئورناتقۇچنى تاپالمىدى" + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "" +#~ "ئاز دېگەندە بىر ئورنىتىش، چىقىرىۋېتىش، يۈكسەلدۈرۈش ياكى تىزىمىنى " +#~ "كۆرسىتىشنى تەلەپ قىلىدۇ." + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "بوغچا شېخى ۋە ئومۇمىيەت تاللانمىسى ئۆزئارا توقۇنۇشىدۇ، بىرىنىلا تاللاڭ." + +#~ msgid "Addon Name" +#~ msgstr "قىستۇرما ئاتى" + +#~ msgid "Service Type" +#~ msgstr "مۇلازىمەت تىپى" + +#~ msgid "Path" +#~ msgstr "يول" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "بۇ قورالنى ئىشلىتىپ ئورناتقىلى بولىدىغان بوغچا تىپى:" + +#~ msgid "Built in:" +#~ msgstr "ئۆزىدىكى:" + +#, fuzzy +#~| msgid "Data Files" +#~ msgid "DataEngine" +#~ msgstr "سانلىق-مەلۇمات ھۆججەتلىرى" + +#~ msgid "Layout Template" +#~ msgstr "جايلاشتۇرۇش قېلىپى" + +#~ msgid "Look and Feel" +#~ msgstr "كۆرۈنۈش ۋە تۇيغۇ" + +#~ msgid "Package" +#~ msgstr "بوغچا" + +#~ msgid "Plasmoid" +#~ msgstr "Plasmoid" + +#~ msgid "Runner" +#~ msgstr "ئىجرا قىلغۇچى" + +#~ msgid "Shell" +#~ msgstr "Shell" + +#~ msgid "Theme" +#~ msgstr "ئۆرنەك" + +#, fuzzy +#~| msgid "Wallpaper packages" +#~ msgid "Wallpaper Images" +#~ msgstr "تام قەغەز بوغچالارى" + +#~ msgid "KWin Effect" +#~ msgstr "KWin ئۈنۈمى" + +#~ msgid "KWin Window Switcher" +#~ msgstr "KWin كۆزنەك ئالماشتۇرغۇچ" + +#, fuzzy +#~| msgid "Main Script File" +#~ msgid "KWin Script" +#~ msgstr "ئاساسىي قوليازما ھۆججىتى" + +#~ msgid "Provided by plugins:" +#~ msgstr "قىستۇرما تەمىنلىگەن:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr ".desktop ھۆججەت تەمىنلىگەن" + +#~ msgid "Successfully installed %1" +#~ msgstr "%1 مۇۋەپپەقىيەتلىك ئورنىتىلدى" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "بوغچا تىپى %1 بولغان بوغچا ئورناتقۇچنى تاپالمىدى. مەلۇم قىلغان خاتالىق: %2" + +#~ msgid "search term" +#~ msgstr "ئىزدەش تۈرى" diff --git a/po/uk/libplasma6.po b/po/uk/libplasma6.po new file mode 100644 index 0000000..45ce215 --- /dev/null +++ b/po/uk/libplasma6.po @@ -0,0 +1,1085 @@ +# Translation of libplasma5.po to Ukrainian +# Copyright (C) 2018-2021 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Yuri Chornoivan , 2013, 2014, 2015, 2016, 2018, 2019, 2020, 2021, 2022, 2023, 2024. +msgid "" +msgstr "" +"Project-Id-Version: libplasma5\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-23 09:19+0300\n" +"Last-Translator: Yuri Chornoivan \n" +"Language-Team: Ukrainian \n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n" +"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Lokalize 23.04.3\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Додаткові дії" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Згорнути" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Розгорнути" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Пароль" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Шукати…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Пошук" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "Спорожнити поле пошуку" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Невідомий" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Задіяти віджет «%1»" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Вилучити аплет «%1»" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Увійти до режиму редагування" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Налаштувати «%1»…" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Заблокувати віджети" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Розблокувати віджети" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Вийти з режиму редагування" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Визначає, чи слід створювати кеш теми на диску." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Максимальний розмір кешу теми на диску у кілобайтах. Зауважте, що файли кешу " +"є доволі рідкісними, отже, максимальний обсяг може бути і не використано. " +"Тому встановлення більшого розміру забезпечить безпечне користування темами." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Показати альтернативи…" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Віджет вилучено" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Віджет «%1» було вилучено." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Панель вилучено" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Панель було вилучено." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Стільницю вилучено" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Стільницю було вилучено." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Вернути" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Параметри віджета" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Вилучити цей віджет" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Вилучити цю панель" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Вилучити цей простір дій" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Налаштувати простір дій" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "Додати віджети або керувати ними…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Не вдалося знайти потрібного компонента: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Кореневий запис %1 має належати до типу ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Кореневий запис %1 має належати до типу PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Невідомий аплет" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"Цей віджет було написано для невідомої застарілої версії Плазми, він є " +"несумісним із Плазмою %1. Будь ласка, зв'яжіться з автором віджета, щоб " +"отримати оновлену версію." + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 є несумісним із Плазмою %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"Цей віджет було написано для Плазми %1, він є несумісним із Плазмою %2. Будь " +"ласка, зв'яжіться з автором віджета, щоб отримати оновлену версію." + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"Цей віджет було написано для Плазми %1, він є несумісним із Плазмою %2. Будь " +"ласка, оновіть Плазму, щоб користуватися цим віджетом." + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "Вибачте! Під час спроби завантажити %1 сталася помилка." + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Помилка під час завантаження файла QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "Помилка під час спроби завантажити аплет: пакунка %1 не існує." + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — Параметри %2" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Налаштувати віджет «%1»" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Пакунок Плазми" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Встановити" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Не вдалося встановити пакунок" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Скинутий вами пакунок є некоректним." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Віджети" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Додати %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Додати піктограму" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Шпалери" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Встановити %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Скинуто дані" + +#~ msgid "Add Widgets..." +#~ msgstr "Додати віджети..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Не вдалося відкрити пакунок %1, потрібний для віджета %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Оприлюднення віджета у мережі надасть вам змогу отримувати доступ до " +#~ "цього віджета з іншого комп’ютера для віддаленого керування." + +#~ msgid "Share this widget on the network" +#~ msgstr "Оприлюднити цей віджет у мережі" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Дозволити доступ будь-кому вільний доступ до цього віджета" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Некоректна (нульова) служба, не вдалося виконати жодних дій." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "" +#~ "Віджетом %1 не визначено, який з рушіїв скриптів (ScriptEngine) " +#~ "використовувати." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Різне" + +#~ msgid "Main Script File" +#~ msgstr "Головний файл скрипту" + +#~ msgid "Tests" +#~ msgstr "Тести" + +#~ msgid "Images" +#~ msgstr "Зображення" + +#~ msgid "Themed Images" +#~ msgstr "Тематичні зображення" + +#~ msgid "Configuration Definitions" +#~ msgstr "Визначення налаштування" + +#~ msgid "User Interface" +#~ msgstr "Інтерфейс користувача" + +#~ msgid "Data Files" +#~ msgstr "Файли даних" + +#~ msgid "Executable Scripts" +#~ msgstr "Скрипти" + +#~ msgid "Screenshot" +#~ msgstr "Знімок вікна" + +#~ msgid "Translations" +#~ msgstr "Переклади" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Модель сторінок налаштовування інтерфейсу" + +#~ msgid "Configuration XML file" +#~ msgstr "XML-файл налаштування" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Нетиповий доповнювач для компактних аплетів" + +#~ msgid "Images for dialogs" +#~ msgstr "Зображення для вікон" + +#~ msgid "Generic dialog background" +#~ msgstr "Загальне тло вікна" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Тема для вікна виходу" + +#~ msgid "Wallpaper packages" +#~ msgstr "Пакунки зображень тла стільниці" + +#~ msgid "Images for widgets" +#~ msgstr "Зображення для віджетів" + +#~ msgid "Background image for widgets" +#~ msgstr "Зображення тла для віджетів" + +#~ msgid "Analog clock face" +#~ msgstr "Циферблат аналогового годинника" + +#~ msgid "Background image for panels" +#~ msgstr "Зображення тла для панелей" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Тло для віджетів графіки" + +#~ msgid "Background image for tooltips" +#~ msgstr "Зображення тла для підказок" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Непрозорі зображення для діалогових вікон" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Непрозоре тло типового діалогового вікна" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Непрозора тема для вікна виходу" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Непрозорі зображення для віджетів" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Непрозоре зображення для тла панелей" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Непрозоре зображення для тла підказок" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Файл налаштування KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Описи служб" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Не вдалося створити рушій скриптів %1 для віджета %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Спроба ініціалізації скрипту завершилася невдало" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Вихідні дні" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Події" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Завдання" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Інше" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Попередній місяць" + +#~ msgid "Previous Year" +#~ msgstr "Попередній рік" + +#~ msgid "Previous Decade" +#~ msgstr "Попередня декада" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Сьогодні" + +#~ msgid "Reset calendar to today" +#~ msgstr "Сьогоднішній день у календарі" + +#~ msgid "Next Month" +#~ msgstr "Наступний місяць" + +#~ msgid "Next Year" +#~ msgstr "Наступний рік" + +#~ msgid "Next Decade" +#~ msgstr "Наступна декада" + +#~ msgid "Days" +#~ msgstr "Дні" + +#~ msgid "Months" +#~ msgstr "Місяці" + +#~ msgid "Years" +#~ msgstr "Роки" + +#~ msgid "OK" +#~ msgstr "Гаразд" + +#~ msgid "Cancel" +#~ msgstr "Скасувати" + +#~ msgid "Run the Associated Application" +#~ msgstr "Запустити пов’язану програму" + +#~ msgid "Open with %1" +#~ msgstr "Відкрити за допомогою %1" + +#~ msgid "Accessibility" +#~ msgstr "Доступність" + +#~ msgid "Application Launchers" +#~ msgstr "Інструменти запуску програм" + +#~ msgid "Astronomy" +#~ msgstr "Астрономія" + +#~ msgid "Date and Time" +#~ msgstr "Дата і час" + +#~ msgid "Development Tools" +#~ msgstr "Інструменти для розробки" + +#~ msgid "Education" +#~ msgstr "Освіта" + +#~ msgid "Environment and Weather" +#~ msgstr "Середовище і погода" + +#~ msgid "Examples" +#~ msgstr "Приклади" + +#~ msgid "File System" +#~ msgstr "Файлова система" + +#~ msgid "Fun and Games" +#~ msgstr "Забавки та ігри" + +#~ msgid "Graphics" +#~ msgstr "Графіка" + +#~ msgid "Language" +#~ msgstr "Мова" + +#~ msgid "Mapping" +#~ msgstr "Картографія" + +#~ msgid "Miscellaneous" +#~ msgstr "Різне" + +#~ msgid "Multimedia" +#~ msgstr "Мультимедіа" + +#~ msgid "Online Services" +#~ msgstr "Мережеві служби" + +#~ msgid "Productivity" +#~ msgstr "Офісні програми" + +#~ msgid "System Information" +#~ msgstr "Системна інформація" + +#~ msgid "Utilities" +#~ msgstr "Інструменти" + +#~ msgid "Windows and Tasks" +#~ msgstr "Вікна і завдання" + +#~ msgid "Clipboard" +#~ msgstr "Буфер обміну" + +#~ msgid "Tasks" +#~ msgstr "Завдання" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Змінити %1…" + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Типові параметри для теми тощо." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Схема кольорів, яку слід використовувати для вікон програм." + +#~ msgid "Preview Images" +#~ msgstr "Ескізи зображень" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Ескіз засобу керування входом до системи" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Ескіз вікна блокування" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Ескіз засобу перемикання користувачів" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Ескіз засобу перемикання віртуальних стільниць" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Ескіз вікна вітання" + +#~ msgid "Preview for KRunner" +#~ msgstr "Ескіз для KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Ескіз для обрамлення вікон" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Ескіз засобу перемикання вікон" + +#~ msgid "Login Manager" +#~ msgstr "Керування входом до системи" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Основний скрипт засобу керування входом до системи" + +#~ msgid "Logout Dialog" +#~ msgstr "Діалогове вікно виходу з системи" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Основний скрипт діалогового вікна виходу з системи" + +#~ msgid "Screenlocker" +#~ msgstr "Засіб блокування екрана" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Основний скрипт засобу блокування екрана" + +#~ msgid "UI for fast user switching" +#~ msgstr "Інтерфейс для швидкого перемикання користувачів" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Основний скрипт засобу перемикання користувачів" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Перемикач віртуальних стільниць" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Основний скрипт засобу перемикання віртуальних стільниць" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Екранні сповіщення" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Основний скрипт засобу показу екранних сповіщень" + +#~ msgid "Splash Screen" +#~ msgstr "Вікно вітання" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Основний скрипт вікна вітання" + +#~ msgid "KRunner UI" +#~ msgstr "Інтерфейс KRunner" + +#~ msgid "Main Script KRunner" +#~ msgstr "Основний скрипт KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Обрамлення вікон" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Основний скрипт засобу керування обрамленням вікон" + +#~ msgid "Window Switcher" +#~ msgstr "Перемикач вікон" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Основний скрипт засобу перемикання вікон" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Завершити налаштовування компонування" + +#~ msgid "Customize Layout..." +#~ msgstr "Налаштувати компонування…" + +#~ msgid "Fetching file type..." +#~ msgstr "Отримання типу файла..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "Налаштування віджета «%1»" + +#~ msgid "SVG scalable preview" +#~ msgstr "Попередній перегляд масштабованого SVG" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "Remove this %1" +#~ msgstr "Вилучити віджет «%1»" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings" +#~ msgstr "Налаштувати віджет «%1»" + +#~ msgctxt "%1 is the name of the applet" +#~ msgid "%1 Settings..." +#~ msgstr "Параметри віджета «%1»…" + +#~ msgid "Low color images for dialogs" +#~ msgstr "Малокольорові зображення для діалогових вікон" + +#~ msgid "Low color generic dialog background" +#~ msgstr "Малокольорові зображення для типового вікна" + +#~ msgid "Low color theme for the logout dialog" +#~ msgstr "Малокольорова тема для вікна виходу" + +#~ msgid "Low color background image for widgets" +#~ msgstr "Малокольорові зображення для тла віджетів" + +#~ msgid "Low color analog clock face" +#~ msgstr "Малокольоровий циферблат аналогового годинника" + +#~ msgid "Low color background image for panels" +#~ msgstr "Малокольорові зображення для тла панелей" + +#~ msgid "Low color background for graphing widgets" +#~ msgstr "Малокольорове зображення для тла віджетів-графіків" + +#~ msgid "Low color background image for tooltips" +#~ msgstr "Малокольорове зображення для тла підказок" + +#~ msgid "Plasma Package Manager" +#~ msgstr "Керування пакунками Плазми" + +#~ msgctxt "Do not translate " +#~ msgid "Generate a SHA1 hash for the package at " +#~ msgstr "Визначити хеш SHA1 для пакунка за адресою " + +#~ msgid "For install or remove, operates on packages installed for all users." +#~ msgstr "" +#~ "Для встановлення і вилучення, працює з пакунками, встановленими для всіх " +#~ "користувачів." + +#~ msgctxt "" +#~ "theme, wallpaper, etc. are keywords, but they may be translated, as both " +#~ "versions are recognized by the application (if translated, should be same " +#~ "as messages with 'package type' context below)" +#~ msgid "" +#~ "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, " +#~ "layout-template, etc." +#~ msgstr "" +#~ "Тип пакунка, наприклад theme (тема), wallpaper (тло стільниці), plasmoid " +#~ "(плазмоїд), dataengine (рушій даних), runner (система запуску), layout-" +#~ "template (шаблон компонування) тощо." + +#~ msgctxt "Do not translate " +#~ msgid "Install the package at " +#~ msgstr "Встановити пакунок до " + +#~ msgctxt "Do not translate " +#~ msgid "Show information of package " +#~ msgstr "Показ даних щодо пакунка " + +#~ msgctxt "Do not translate " +#~ msgid "Upgrade the package at " +#~ msgstr "Оновити пакунок до " + +#~ msgid "List installed packages" +#~ msgstr "Показати список встановлених пакунків" + +#~ msgid "List all known package types that can be installed" +#~ msgstr "" +#~ "Показати список усіх відомих типів пакунків, які програма може " +#~ "встановлювати" + +#~ msgctxt "Do not translate " +#~ msgid "Remove the package named " +#~ msgstr "Вилучити пакунок з назвою " + +#~ msgid "" +#~ "Absolute path to the package root. If not supplied, then the standard " +#~ "data directories for this KDE session will be searched instead." +#~ msgstr "" +#~ "Абсолютний шлях до кореня пакунків. Якщо його не вказано, для пошуку буде " +#~ "використано стандартні каталоги даних цього сеансу KDE." + +#~ msgid "Failed to generate a Package hash for %1" +#~ msgstr "Не вдалося визначити хеш пакунка для %1" + +#~ msgid "SHA1 hash for Package at %1: '%2'" +#~ msgstr "Хеш SHA1 для пакунка за адресою %1: «%2»" + +#~ msgctxt "package type" +#~ msgid "wallpaper" +#~ msgstr "шпалери" + +#~ msgctxt "package type" +#~ msgid "plasmoid" +#~ msgstr "плазмоїд" + +#~ msgctxt "package type" +#~ msgid "package" +#~ msgstr "пакунок" + +#~ msgctxt "package type" +#~ msgid "theme" +#~ msgstr "тема" + +#~ msgctxt "package type" +#~ msgid "dataengine" +#~ msgstr "рушій даних" + +#~ msgctxt "package type" +#~ msgid "runner" +#~ msgstr "засіб запуску" + +#~ msgctxt "package type" +#~ msgid "wallpaperplugin" +#~ msgstr "додаток шпалер" + +#~ msgctxt "package type" +#~ msgid "lookandfeel" +#~ msgstr "вигляд і поведінка" + +#~ msgctxt "package type" +#~ msgid "shell" +#~ msgstr "оболонка" + +#~ msgctxt "package type" +#~ msgid "layout-template" +#~ msgstr "шаблон компонування" + +#~ msgctxt "package type" +#~ msgid "kwineffect" +#~ msgstr "kwineffect" + +#~ msgctxt "package type" +#~ msgid "windowswitcher" +#~ msgstr "windowswitcher" + +#~ msgctxt "package type" +#~ msgid "kwinscript" +#~ msgstr "kwinscript" + +#~ msgid "Could not find a suitable installer for package of type %1" +#~ msgstr "Не вдалося знайти програми встановлення для пакунка типу %1" + +#~ msgid "Listing service types: %1" +#~ msgstr "Будуємо список типів служб: %1" + +#~ msgid "Error: Plugin %1 is not installed." +#~ msgstr "Помилка: додаток %1 не встановлено." + +#~ msgctxt "" +#~ "No option was given, this is the error message telling the user he needs " +#~ "at least one, do not translate install, remove, upgrade nor list" +#~ msgid "One of install, remove, upgrade or list is required." +#~ msgstr "Слід вказати одну з дій: встановити, вилучити або показати список." + +#~ msgid "Error: Can't find plugin metadata: %1" +#~ msgstr "Помилка: не вдалося знайти метаданих додатка: %1" + +#~ msgid "Showing info for package: %1" +#~ msgstr "Показуємо дані щодо пакунка: %1" + +#~ msgid " Name : %1" +#~ msgstr " Назва: %1" + +#~ msgid " Comment : %1" +#~ msgstr " Коментар: %1" + +#~ msgid " Plugin : %1" +#~ msgstr " Додаток: %1" + +#~ msgid " Author : %1" +#~ msgstr " Автор: %1" + +#~ msgid " Path : %1" +#~ msgstr " Шлях: %1" + +#~ msgctxt "" +#~ "The user entered conflicting options packageroot and global, this is the " +#~ "error message telling the user he can use only one" +#~ msgid "" +#~ "The packageroot and global options conflict each other, please select " +#~ "only one." +#~ msgstr "" +#~ "Виявлено конфлікт між кореневою текою пакунка і загальними параметрами. " +#~ "Будь ласка, визначіть, яке з налаштувань є правильним." + +#~ msgid "Addon Name" +#~ msgstr "Назва додатка" + +#~ msgid "Service Type" +#~ msgstr "Тип служби" + +#~ msgid "Path" +#~ msgstr "Шлях" + +#~ msgid "Type Argument" +#~ msgstr "Аргумент типу" + +#~ msgid "Package types that are installable with this tool:" +#~ msgstr "Типи пакунків, які здатна встановлювати ця програма:" + +#~ msgid "Built in:" +#~ msgstr "Вбудовані:" + +#~ msgid "DataEngine" +#~ msgstr "Рушій даних" + +#~ msgid "Layout Template" +#~ msgstr "Шаблон компонування" + +#~ msgid "Look and Feel" +#~ msgstr "Вигляд і поведінка" + +#~ msgid "Package" +#~ msgstr "Пакунок" + +#~ msgid "Plasmoid" +#~ msgstr "Плазмоїд" + +#~ msgid "Runner" +#~ msgstr "Засіб для запуску" + +#~ msgid "Shell" +#~ msgstr "Оболонка" + +#~ msgid "Theme" +#~ msgstr "Тема" + +#~ msgid "Wallpaper Images" +#~ msgstr "Зображення шпалер" + +#~ msgid "Animated Wallpaper" +#~ msgstr "Анімовані шпалери" + +#~ msgid "KWin Effect" +#~ msgstr "Ефект KWin" + +#~ msgid "KWin Window Switcher" +#~ msgstr "Перемикач вікон KWin" + +#~ msgid "KWin Script" +#~ msgstr "Скрипт KWin" + +#~ msgid "Provided by plugins:" +#~ msgstr "Керовані додатками:" + +#~ msgid "Provided by .desktop files:" +#~ msgstr "Керовані файлами .desktop:" + +#~ msgid "Successfully upgraded %1" +#~ msgstr "%1 успішно оновлено" + +#~ msgid "Successfully installed %1" +#~ msgstr "%1 успішно встановлено" + +#~ msgid "Error: Installation of %1 failed: %2" +#~ msgstr "Помилка: спроба встановлення %1 зазнала невдачі: %2" + +#~ msgid "Upgrading package from file: %1" +#~ msgstr "Оновлення пакунка з файла: %1" + +#~ msgid "Successfully uninstalled %1" +#~ msgstr "%1 успішно вилучено" + +#~ msgid "Error: Uninstallation of %1 failed: %2" +#~ msgstr "Помилка: спроба вилучення %1 зазнала невдачі: %2" + +#~ msgid "" +#~ "Could not load installer for package of type %1. Error reported was: %2" +#~ msgstr "" +#~ "Не вдалося знайти програми встановлення для пакунка типу %1. Повідомлення " +#~ "помилки: %2" + +#~ msgid "Could not create package root directory: %1" +#~ msgstr "Не вдалося створити кореневий каталог пакунка: %1" + +#~ msgid "No such file: %1" +#~ msgstr "Такого файла не існує: %1" + +#~ msgid "Could not open package file, unsupported archive format: %1 %2" +#~ msgstr "" +#~ "Не вдалося відкрити файл пакунка, непідтримуваний формат архіву: %1 %2" + +#~ msgid "Could not open package file: %1" +#~ msgstr "Не вдалося відкрити файл пакунка: %1" + +#~ msgid "No metadata file in package: %1" +#~ msgstr "У пакунку не виявлено файла метаданих: %1" + +#~ msgid "Package plugin name not specified: %1" +#~ msgstr "Не вказано назви додатка у пакунку: %1" + +#~ msgid "Package plugin name %1 contains invalid characters" +#~ msgstr "Назва додатка у пакунку %1 містить некоректні символи" + +#~ msgid "%1 already exists" +#~ msgstr "%1 вже існує" + +#~ msgid "Could not move package to destination: %1" +#~ msgstr "Не вдалося пересунути пакунок до його місця призначення: %1" + +#~ msgid "Could not copy package to destination: %1" +#~ msgstr "Не вдалося скопіювати пакунок до його місця призначення: %1" + +#~ msgid "Could not create local service directory: %1" +#~ msgstr "Не вдалося створити каталог локальної служби: %1" + +#~ msgid "" +#~ "Could not register package as service (this is not necessarily fatal): %1" +#~ msgstr "" +#~ "Не вдалося зареєструвати пакунок як службу (така помилка не обов’язково є " +#~ "критичною): %1" + +#~ msgid "%1 does not exist" +#~ msgstr "%1 не існує" + +#~ msgid "Could not delete package from: %1" +#~ msgstr "Не вдалося вилучити пакунок з %1" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Do you really want to remove this %1?" +#~ msgstr "Ви справді бажаєте вилучити %1?" + +#~ msgid "Applets furniture" +#~ msgstr "Компоненти аплетів" + +#~ msgid "Explorer UI for adding widgets" +#~ msgstr "Графічний інтерфейс перегляду для додавання віджетів" + +#~ msgid "User interface for the views that will show containments" +#~ msgstr "" +#~ "Інтерфейс користувача для панелей перегляду, які показують вміст " +#~ "контейнерів" + +#~ msgid "Default layout file" +#~ msgstr "Типовий файл компонування" + +#~ msgid "Default plugins for containments, containmentActions, etc." +#~ msgstr "Типові додатки для контейнерів, дій з контейнерами тощо" + +#~ msgid "Error message shown when an applet fails to load" +#~ msgstr "" +#~ "Повідомлення про помилку, яке буде показано, якщо аплет не вдалося " +#~ "завантажити" + +#~ msgid "QML component that shows an applet in a popup" +#~ msgstr "Компонент QML, який показує аплет у контекстному вікні" + +#~ msgid "" +#~ "Compact representation of an applet when collapsed in a popup, for " +#~ "instance as an icon. Applets can override this component." +#~ msgstr "" +#~ "Компактне представлення аплету, якщо його згорнуто у контекстне вікно, " +#~ "наприклад піктограму. Аплети можуть перевизначати цей компонент." + +#~ msgid "QML component for the configuration dialog for applets" +#~ msgstr "Компонент QML діалогового вікна налаштовування для аплетів" + +#~ msgid "QML component for the configuration dialog for containments" +#~ msgstr "Компонент QML діалогового вікна налаштовування для контейнерів" + +#~ msgid "Panel configuration UI" +#~ msgstr "Інтерфейс налаштовування панелей" + +#~ msgid "QML component for choosing an alternate applet" +#~ msgstr "Компонент QML для вибору альтернативного аплету" + +#~ msgid "" +#~ "A UI for writing, loading and running desktop scripts in the current live " +#~ "session" +#~ msgstr "" +#~ "Графічний інтерфейс для написання, завантаження та виконання скриптів " +#~ "стільниці у поточному сеансі" diff --git a/po/vi/libplasma6.po b/po/vi/libplasma6.po new file mode 100644 index 0000000..38df02d --- /dev/null +++ b/po/vi/libplasma6.po @@ -0,0 +1,684 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the plasma-framework package. +# +# Phu Hung Nguyen , 2020, 2021, 2022, 2023. +msgid "" +msgstr "" +"Project-Id-Version: plasma-framework\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2023-10-24 10:41+0200\n" +"Last-Translator: Phu Hung Nguyen \n" +"Language-Team: Vietnamese \n" +"Language: vi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Lokalize 23.04.3\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "Các hành động khác" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "Thu gọn" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "Mở rộng" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "Mật khẩu" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "Tìm kiếm…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "Tìm kiếm" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "Không rõ" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "Kích hoạt phụ kiện %1" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "Xoá bỏ %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "Đi vào Chế độ Sửa" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "Cấu hình %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "Khoá các phụ kiện" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "Bỏ khoá các phụ kiện" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "Thoát khỏi chế độ sửa" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "Có tạo bộ nhớ sẵn trên đĩa cho chủ đề này hay không." + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"Kích thước tối đa của bộ nhớ sẵn trên đĩa cho chủ đề, tính theo ki-lô byte. " +"Lưu ý rằng các tệp này là các tệp thưa, nên kích thước tối đa kia có thể sẽ " +"không bị đạt đến. Vì vậy, đặt một kích thước lớn thường cũng không gây vấn " +"đề gì." + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "Hiện các lựa chọn khác..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "Đã xoá bỏ phụ kiện" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "Phụ kiện \"%1\" đã bị xoá bỏ." + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "Đã xoá bỏ bảng" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "Một bảng đã bị xoá bỏ." + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "Đã xoá bỏ bàn làm việc" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "Một bàn làm việc đã bị xoá bỏ." + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "Đảo ngược" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "Thiết lập phụ kiện" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "Xoá bỏ phụ kiện này" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "Xoá bỏ bảng này" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "Xoá bỏ Hoạt động này" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "Thiết lập Hoạt động" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "Không tìm thấy thành phần được yêu cầu: %1" + +#: plasmaquick/appletquickitem.cpp:544 +#, fuzzy, kde-format +#| msgid "The root item of %1 must be of type ContaimentItem" +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "Phần tử gốc của %1 phải thuộc kiểu ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "Phần tử gốc của %1 phải thuộc kiểu PlasmaItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "Tiểu ứng dụng không rõ" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "Lỗi tải tệp QML: %1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, fuzzy, kde-format +#| msgid "Error loading Applet: package inexistent. %1" +msgid "Error loading Applet: package %1 does not exist." +msgstr "Lỗi tải tiểu ứng dụng: gói không tồn tại. %1" + +#: plasmaquick/configview.cpp:231 +#, fuzzy, kde-format +#| msgid "%1 Settings" +msgid "%1 — %2 Settings" +msgstr "Thiết lập %1" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "Thiết lập %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Gói Plasma" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "Cài đặt" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "Cài đặt gói thất bại" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "Gói mà bạn vừa thả không hợp lệ." + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "Phụ kiện" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "Thêm %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "Thêm biểu tượng" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "Phông nền" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "Đặt %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "Nội dung được thả" + +#~ msgid "Add Widgets..." +#~ msgstr "Thêm phụ kiện..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "Không mở được gói %1 cần để dùng cho phụ kiện %2." + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "" +#~ "Việc chia sẻ một phụ kiện trong mạng cho phép bạn truy cập phụ kiện này " +#~ "từ một máy tính khác như là một điều khiển từ xa." + +#~ msgid "Share this widget on the network" +#~ msgstr "Chia sẻ phụ kiện này trong mạng" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "Cho phép mọi người tự do truy cập phụ kiện này" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "Dịch vụ không hợp lệ (null), không thực hiện được thao tác nào." + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "Phụ kiện %1 không xác định sẽ dùng ScriptEngine nào." + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "Hỗn hợp" + +#~ msgid "Main Script File" +#~ msgstr "Tệp kịch bản chính" + +#~ msgid "Tests" +#~ msgstr "Bài kiểm thử" + +#~ msgid "Images" +#~ msgstr "Ảnh" + +#~ msgid "Themed Images" +#~ msgstr "Ảnh theo chủ đề" + +#~ msgid "Configuration Definitions" +#~ msgstr "Định nghĩa cấu hình" + +#~ msgid "User Interface" +#~ msgstr "Giao diện người dùng" + +#~ msgid "Data Files" +#~ msgstr "Tệp dữ liệu" + +#~ msgid "Executable Scripts" +#~ msgstr "Kịch bản thực thi được" + +#~ msgid "Screenshot" +#~ msgstr "Ảnh chụp màn hình" + +#~ msgid "Translations" +#~ msgstr "Bản dịch" + +#~ msgid "Configuration UI pages model" +#~ msgstr "Mô hình các trang giao diện cấu hình" + +#~ msgid "Configuration XML file" +#~ msgstr "Tệp XML cấu hình" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "Bộ mở rộng tự chọn cho các tiểu ứng dụng gọn" + +#~ msgid "Images for dialogs" +#~ msgstr "Ảnh cho hộp thoại" + +#~ msgid "Generic dialog background" +#~ msgstr "Nền hộp thoại trơn" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "Chủ đề cho hộp thoại đăng xuất" + +#~ msgid "Wallpaper packages" +#~ msgstr "Gói phông nền" + +#~ msgid "Images for widgets" +#~ msgstr "Ảnh cho phụ kiện" + +#~ msgid "Background image for widgets" +#~ msgstr "Ảnh nền cho phụ kiện" + +#~ msgid "Analog clock face" +#~ msgstr "Mặt đồng hồ kim" + +#~ msgid "Background image for panels" +#~ msgstr "Ảnh nền cho bảng" + +#~ msgid "Background for graphing widgets" +#~ msgstr "Nền cho phụ kiện vẽ biểu đồ" + +#~ msgid "Background image for tooltips" +#~ msgstr "Ảnh nền cho chú giải" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "Ảnh đục cho hộp thoại" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "Nền hộp thoại trơn đục" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "Chủ đề đục cho hộp thoại đăng xuất" + +#~ msgid "Opaque images for widgets" +#~ msgstr "Ảnh đục cho phụ kiện" + +#~ msgid "Opaque background image for panels" +#~ msgstr "Ảnh nền đục cho bảng" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "Ảnh nền đục cho chú giải" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "Tệp cấu hình KColorScheme" + +#~ msgid "Service Descriptions" +#~ msgstr "Mô tả dịch vụ" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "Không tạo được một ScriptEngine %1 cho phụ kiện %2." + +#~ msgid "Script initialization failed" +#~ msgstr "Khởi tạo kịch bản thất bại" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "Ngày lễ" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "Sự kiện" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "Cần làm" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "Khác" + +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%1 %2" + +#~ msgid "Previous Month" +#~ msgstr "Tháng trước" + +#~ msgid "Previous Year" +#~ msgstr "Năm trước" + +#~ msgid "Previous Decade" +#~ msgstr "Thập kỉ trước" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "Hôm nay" + +#~ msgid "Reset calendar to today" +#~ msgstr "Đặt lại lịch về hôm nay" + +#~ msgid "Next Month" +#~ msgstr "Tháng sau" + +#~ msgid "Next Year" +#~ msgstr "Năm sau" + +#~ msgid "Next Decade" +#~ msgstr "Thập kỉ sau" + +#~ msgid "Days" +#~ msgstr "Ngày" + +#~ msgid "Months" +#~ msgstr "Tháng" + +#~ msgid "Years" +#~ msgstr "Năm" + +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "Cancel" +#~ msgstr "Huỷ" + +#~ msgid "Run the Associated Application" +#~ msgstr "Chạy ứng dụng liên kết" + +#~ msgid "Open with %1" +#~ msgstr "Mở bằng %1" + +#~ msgid "Accessibility" +#~ msgstr "Hỗ trợ truy cập" + +#~ msgid "Application Launchers" +#~ msgstr "Các mục khởi chạy ứng dụng" + +#~ msgid "Astronomy" +#~ msgstr "Thiên văn học" + +#~ msgid "Date and Time" +#~ msgstr "Ngày giờ" + +#~ msgid "Development Tools" +#~ msgstr "Công cụ phát triển" + +#~ msgid "Education" +#~ msgstr "Giáo dục" + +#~ msgid "Environment and Weather" +#~ msgstr "Môi trường và Thời tiết" + +#~ msgid "Examples" +#~ msgstr "Ví dụ" + +#~ msgid "File System" +#~ msgstr "Hệ thống tệp" + +#~ msgid "Fun and Games" +#~ msgstr "Giải trí và trò chơi" + +#~ msgid "Graphics" +#~ msgstr "Đồ hoạ" + +#~ msgid "Language" +#~ msgstr "Ngôn ngữ" + +#~ msgid "Mapping" +#~ msgstr "Bản đồ" + +#~ msgid "Miscellaneous" +#~ msgstr "Hỗn hợp" + +#~ msgid "Multimedia" +#~ msgstr "Đa phương tiện" + +#~ msgid "Online Services" +#~ msgstr "Dịch vụ trực tuyến" + +#~ msgid "Productivity" +#~ msgstr "Năng suất" + +#~ msgid "System Information" +#~ msgstr "Thông tin hệ thống" + +#~ msgid "Utilities" +#~ msgstr "Tiện ích" + +#~ msgid "Windows and Tasks" +#~ msgstr "Cửa sổ và Tác vụ" + +#~ msgid "Clipboard" +#~ msgstr "Bảng nháp" + +#~ msgid "Tasks" +#~ msgstr "Tác vụ" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "Sửa %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "Thiết lập mặc định cho chủ đề, v.v." + +#~ msgid "Color scheme to use for applications." +#~ msgstr "Quy hoạch màu dùng cho các ứng dụng." + +#~ msgid "Preview Images" +#~ msgstr "Ảnh xem thử" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "Xem thử cho trình quản lí đăng nhập" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "Xem thử cho màn hình khoá" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "Xem thử cho trình chuyển người dùng" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "Xem thử cho trình chuyển bàn làm việc ảo" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "Xem thử cho màn hình khởi động" + +#~ msgid "Preview for KRunner" +#~ msgstr "Xem thử cho KRunner" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "Xem thử cho các trang trí cửa sổ" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "Xem thử cho trình chuyển cửa sổ" + +#~ msgid "Login Manager" +#~ msgstr "Trình quản lí đăng nhập" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "Kịch bản chính cho trình quản lí đăng nhập" + +#~ msgid "Logout Dialog" +#~ msgstr "Hộp thoại đăng xuất" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "Kịch bản chính cho hộp thoại đăng xuất" + +#~ msgid "Screenlocker" +#~ msgstr "Trình khoá màn hình" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "Kịch bản chính cho màn hình khoá" + +#~ msgid "UI for fast user switching" +#~ msgstr "Giao diện để chuyển người dùng nhanh" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "Kịch bản chính cho trình chuyển người dùng" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "Trình chuyển bàn làm việc ảo" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "Kịch bản chính cho trình chuyển bàn làm việc ảo" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "Thông báo trong ô hiện nổi" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "Kịch bản chính cho thông báo trong ô hiện nổi" + +#~ msgid "Splash Screen" +#~ msgstr "Màn hình khởi động" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "Kịch bản chính cho màn hình khởi động" + +#~ msgid "KRunner UI" +#~ msgstr "Giao diện KRunner" + +#~ msgid "Main Script KRunner" +#~ msgstr "Kịch bản chính cho KRunner" + +#~ msgid "Window Decoration" +#~ msgstr "Trang trí cửa sổ" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "Kịch bản chính cho trang trí cửa sổ" + +#~ msgid "Window Switcher" +#~ msgstr "Trình chuyển cửa sổ" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "Kịch bản chính cho trình chuyển cửa sổ" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "Hoàn tất tuỳ biến bố cục" + +#~ msgid "Customize Layout..." +#~ msgstr "Tuỳ biến bố cục..." diff --git a/po/zh_CN/libplasma6.po b/po/zh_CN/libplasma6.po new file mode 100644 index 0000000..aaf54d0 --- /dev/null +++ b/po/zh_CN/libplasma6.po @@ -0,0 +1,318 @@ +msgid "" +msgstr "" +"Project-Id-Version: kdeorg\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-04-23 19:24\n" +"Last-Translator: \n" +"Language-Team: Chinese Simplified\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Crowdin-Project: kdeorg\n" +"X-Crowdin-Project-ID: 269464\n" +"X-Crowdin-Language: zh-CN\n" +"X-Crowdin-File: /kf6-stable/messages/libplasma/libplasma6.pot\n" +"X-Crowdin-File-ID: 50190\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "更多操作" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "折叠" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "展开" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "密码" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "搜索…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "搜索" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "清除搜索内容" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "未知" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "激活 %1 挂件" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "移除 %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "进入编辑模式" + +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "配置 %1..." + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "锁定挂件" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "解锁挂件" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "退出编辑模式" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "是否创建主题的磁盘缓存。" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"保存在磁盘中的主题缓存的最大体积,单位为 KB。注意:缓存文件是稀疏文件,因此不" +"一定能够完全利用设置的最大体积。设置一个较大的体积会比较安全。" + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "显示替代部件..." + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "挂件已移除" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "挂件“%1”已移除。" + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "面板已移除" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "已移除面板。" + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "桌面已移除" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "已移除桌面。" + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "撤销" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "挂件设置" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "移除此挂件" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "移除此面板" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "移除此活动" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "活动设置" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "添加或者管理挂件…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "无法找到所需组件:%1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "%1 的根项目必须是 ContainmentItem 类型" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "%1 的根项目必须是 PlasmoidItem 类型" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "未知小程序" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"此挂件是为未知的旧版 Plasma 编写的,它与 Plasma %1 不兼容。请联系挂件的作者获" +"取新版挂件。" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 不兼容 Plasma %2" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"此挂件是为 Plasma %1 编写的,它与 Plasma %2 不兼容。请联系挂件的作者获取新版" +"挂件。" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"此挂件是为 Plasma %1 编写的,它与 Plasma %2 不兼容。请升级 Plasma 桌面环境以" +"使用此挂件。" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "对不起,加载 %1 时发生错误。" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "加载 QML 文件出错:%1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "加载小程序出错:软件包 %1 不存在。" + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 设置" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 设置" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma 软件包" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "安装" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "软件包安装失败" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "您刚刚拖放的软件包无效。" + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "挂件" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "添加 %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "添加图标" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "壁纸" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "设置 %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "内容已拖放" diff --git a/po/zh_TW/libplasma6.po b/po/zh_TW/libplasma6.po new file mode 100644 index 0000000..1e3bc9b --- /dev/null +++ b/po/zh_TW/libplasma6.po @@ -0,0 +1,696 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Franklin, 2014. +# Franklin Weng , 2015. +# Jeff Huang , 2016. +# pan93412 , 2018, 2019. +# SPDX-FileCopyrightText: 2022, 2023, 2024 Kisaragi Hiu +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2024-08-23 00:41+0000\n" +"PO-Revision-Date: 2024-08-25 01:44+0900\n" +"Last-Translator: Kisaragi Hiu \n" +"Language-Team: Traditional Chinese \n" +"Language: zh_TW\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Lokalize 24.04.70\n" + +#: declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml:81 +#, kde-format +msgid "More actions" +msgstr "更多動作" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Collapse" +msgstr "折疊" + +#: declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml:524 +#, kde-format +msgctxt "@action:button" +msgid "Expand" +msgstr "展開" + +#: declarativeimports/plasmaextracomponents/qml/PasswordField.qml:49 +#, kde-format +msgid "Password" +msgstr "密碼" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:60 +#, kde-format +msgid "Search…" +msgstr "搜尋…" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:62 +#, kde-format +msgid "Search" +msgstr "搜尋" + +#: declarativeimports/plasmaextracomponents/qml/SearchField.qml:73 +#, kde-format +msgid "Clear search" +msgstr "清除搜尋" + +#: plasma/applet.cpp:293 +#, kde-format +msgid "Unknown" +msgstr "未知" + +#: plasma/applet.cpp:736 +#, kde-format +msgid "Activate %1 Widget" +msgstr "啟動 %1 元件" + +#: plasma/containment.cpp:97 plasma/private/applet_p.cpp:101 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Remove %1" +msgstr "移除 %1" + +#: plasma/containment.cpp:103 plasma/corona.cpp:360 plasma/corona.cpp:481 +#, kde-format +msgid "Enter Edit Mode" +msgstr "進入編輯模式" + +# %1 是譯文,沒有空格比較好。如果有遇到太多是原文而需要空格或標點符號的情況的話可以改用「設定「%1」…」之類的。 +# --Kisaragi +#: plasma/containment.cpp:106 plasma/private/applet_p.cpp:106 +#, kde-format +msgctxt "%1 is the name of the applet" +msgid "Configure %1..." +msgstr "設定%1…" + +#: plasma/corona.cpp:309 plasma/corona.cpp:466 +#, kde-format +msgid "Lock Widgets" +msgstr "鎖定元件" + +#: plasma/corona.cpp:309 +#, kde-format +msgid "Unlock Widgets" +msgstr "解除鎖定元件" + +#: plasma/corona.cpp:358 +#, kde-format +msgid "Exit Edit Mode" +msgstr "離開編輯模式" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:9 +#, kde-format +msgid "Whether or not to create an on-disk cache for the theme." +msgstr "是否要建立一個主題的磁碟快取。" + +#. i18n: ectx: label, entry, group (CachePolicies) +#: plasma/data/kconfigxt/libplasma-theme-global.kcfg:14 +#, kde-format +msgid "" +"The maximum size of the on-disk Theme cache in kilobytes. Note that these " +"files are sparse files, so the maximum size may not be used. Setting a " +"larger size is therefore often quite safe." +msgstr "" +"磁碟中主題快取的最大大小,以 KB 為單位。注意這些檔案通常不會用到最大大小,因" +"此設大一點是安全的。" + +#: plasma/private/applet_p.cpp:119 +#, kde-format +msgid "Show Alternatives..." +msgstr "顯示替代選擇…" + +#: plasma/private/applet_p.cpp:232 +#, kde-format +msgid "Widget Removed" +msgstr "元件已移除" + +#: plasma/private/applet_p.cpp:233 +#, kde-format +msgid "The widget \"%1\" has been removed." +msgstr "元件 \"%1\" 已移除。" + +#: plasma/private/applet_p.cpp:237 +#, kde-format +msgid "Panel Removed" +msgstr "面板已移除" + +#: plasma/private/applet_p.cpp:238 +#, kde-format +msgid "A panel has been removed." +msgstr "面板已被移除。" + +#: plasma/private/applet_p.cpp:241 +#, kde-format +msgid "Desktop Removed" +msgstr "桌面已移除" + +#: plasma/private/applet_p.cpp:242 +#, kde-format +msgid "A desktop has been removed." +msgstr "桌面已被移除。" + +#: plasma/private/applet_p.cpp:245 +#, kde-format +msgid "Undo" +msgstr "復原" + +#: plasma/private/applet_p.cpp:336 +#, kde-format +msgid "Widget Settings" +msgstr "元件設定" + +#: plasma/private/applet_p.cpp:343 +#, kde-format +msgid "Remove this Widget" +msgstr "移除此元件" + +#: plasma/private/containment_p.cpp:58 +#, kde-format +msgid "Remove this Panel" +msgstr "移除此面板" + +#: plasma/private/containment_p.cpp:60 +#, kde-format +msgid "Remove this Activity" +msgstr "移除此活動" + +#: plasma/private/containment_p.cpp:66 +#, kde-format +msgid "Activity Settings" +msgstr "活動設定" + +#: plasma/private/containment_p.cpp:78 +#, kde-format +msgid "Add or Manage Widgets…" +msgstr "新增或管理元件…" + +#: plasma/private/containment_p.cpp:197 +#, kde-format +msgid "Could not find requested component: %1" +msgstr "找不到請求的組件:%1" + +#: plasmaquick/appletquickitem.cpp:544 +#, kde-format +msgid "The root item of %1 must be of type ContainmentItem" +msgstr "%1 的根項目必須為型態 ContainmentItem" + +#: plasmaquick/appletquickitem.cpp:549 +#, kde-format +msgid "The root item of %1 must be of type PlasmoidItem" +msgstr "%1 的根項目必須為型態 PlasmoidItem" + +#: plasmaquick/appletquickitem.cpp:557 +#, kde-format +msgid "Unknown Applet" +msgstr "不明小程式" + +#: plasmaquick/appletquickitem.cpp:571 +#, kde-format +msgid "" +"This Widget was written for an unknown older version of Plasma and is not " +"compatible with Plasma %1. Please contact the widget's author for an updated " +"version." +msgstr "" +"這個元件是供某個未知的舊版 Plasma 用的,與 Plasma %1 不相容。請與元件作者聯" +"絡,待其發佈更新版本。" + +#: plasmaquick/appletquickitem.cpp:574 plasmaquick/appletquickitem.cpp:581 +#: plasmaquick/appletquickitem.cpp:587 +#, kde-format +msgid "%1 is not compatible with Plasma %2" +msgstr "%1 與 Plasma %2 不相容" + +#: plasmaquick/appletquickitem.cpp:578 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please contact the widget's author for an updated version." +msgstr "" +"這個元件是供 Plasma %1 用的,與 Plasma %2 不相容。請與元件作者聯絡,待其發佈" +"更新版本。" + +#: plasmaquick/appletquickitem.cpp:584 +#, kde-format +msgid "" +"This Widget was written for Plasma %1 and is not compatible with Plasma %2. " +"Please update Plasma in order to use the widget." +msgstr "" +"這個元件是供 Plasma %1 用的,與 Plasma %2 不相容。請更新 Plasma 來使用它。" + +#: plasmaquick/appletquickitem.cpp:593 plasmaquick/appletquickitem.cpp:615 +#, kde-format +msgid "Sorry! There was an error loading %1." +msgstr "很抱歉!載入 %1 時發生錯誤。" + +#: plasmaquick/appletquickitem.cpp:610 +#, kde-format +msgid "Error loading QML file: %1 %2" +msgstr "載入 QML 檔時發生錯誤:%1 %2" + +#: plasmaquick/appletquickitem.cpp:613 +#, kde-format +msgid "Error loading Applet: package %1 does not exist." +msgstr "載入小程式時發生錯誤:軟體包 %1 不存在。" + +#: plasmaquick/configview.cpp:231 +#, kde-format +msgid "%1 — %2 Settings" +msgstr "%1 — %2 設定" + +#: plasmaquick/configview.cpp:232 +#, kde-format +msgid "%1 Settings" +msgstr "%1 設定" + +#: plasmaquick/plasmoid/containmentitem.cpp:569 +#, kde-format +msgid "Plasma Package" +msgstr "Plasma 套件包" + +#: plasmaquick/plasmoid/containmentitem.cpp:573 +#, kde-format +msgid "Install" +msgstr "安裝" + +#: plasmaquick/plasmoid/containmentitem.cpp:584 +#, kde-format +msgid "Package Installation Failed" +msgstr "套件包安裝失敗" + +#: plasmaquick/plasmoid/containmentitem.cpp:600 +#, kde-format +msgid "The package you just dropped is invalid." +msgstr "您放入的套件包無效。" + +#: plasmaquick/plasmoid/containmentitem.cpp:609 +#: plasmaquick/plasmoid/containmentitem.cpp:678 +#, kde-format +msgid "Widgets" +msgstr "元件" + +#: plasmaquick/plasmoid/containmentitem.cpp:614 +#, kde-format +msgctxt "Add widget" +msgid "Add %1" +msgstr "增加 %1" + +#: plasmaquick/plasmoid/containmentitem.cpp:628 +#: plasmaquick/plasmoid/containmentitem.cpp:682 +#, kde-format +msgctxt "Add icon widget" +msgid "Add Icon" +msgstr "增加圖示" + +#: plasmaquick/plasmoid/containmentitem.cpp:640 +#, kde-format +msgid "Wallpaper" +msgstr "桌布" + +#: plasmaquick/plasmoid/containmentitem.cpp:650 +#, kde-format +msgctxt "Set wallpaper" +msgid "Set %1" +msgstr "設定 %1" + +#: plasmaquick/plasmoid/dropmenu.cpp:29 +#, kde-format +msgid "Content dropped" +msgstr "已放入的內容" + +#~ msgid "Add Widgets..." +#~ msgstr "新增元件..." + +#~ msgctxt "Package file, name of the widget" +#~ msgid "Could not open the %1 package required for the %2 widget." +#~ msgstr "無法開啟 %2 元件所需要的套件包 %1。" + +#~ msgid "" +#~ "Sharing a widget on the network allows you to access this widget from " +#~ "another computer as a remote control." +#~ msgstr "在網路上分享元件能讓您存取另一台電腦上的此元件。" + +#~ msgid "Share this widget on the network" +#~ msgstr "將此元件分享在網路上" + +#~ msgid "Allow everybody to freely access this widget" +#~ msgstr "允許所有人自由存取此元件" + +#~ msgctxt "Error message, tried to start an invalid service" +#~ msgid "Invalid (null) service, can not perform any operations." +#~ msgstr "不合法的(空白的)服務,無法執行任何操作。" + +#~ msgid "The %1 widget did not define which ScriptEngine to use." +#~ msgstr "%1 元件未定義使用哪個文稿引擎。" + +#~ msgctxt "misc category" +#~ msgid "Miscellaneous" +#~ msgstr "雜項" + +#~ msgid "Main Script File" +#~ msgstr "主文稿檔" + +#~ msgid "Tests" +#~ msgstr "測試" + +#~ msgid "Images" +#~ msgstr "影像" + +#~ msgid "Themed Images" +#~ msgstr "主題影像" + +#~ msgid "Configuration Definitions" +#~ msgstr "設定定義" + +#~ msgid "User Interface" +#~ msgstr "使用者介面" + +#~ msgid "Data Files" +#~ msgstr "資料檔" + +#~ msgid "Executable Scripts" +#~ msgstr "執行文稿" + +#~ msgid "Screenshot" +#~ msgstr "螢幕快照" + +#~ msgid "Translations" +#~ msgstr "翻譯" + +#~ msgid "Configuration UI pages model" +#~ msgstr "設定介面頁面模型" + +#~ msgid "Configuration XML file" +#~ msgstr "設定 XML 檔" + +#~ msgid "Custom expander for compact applets" +#~ msgstr "自訂緊湊的小工具的展開器" + +#~ msgid "Images for dialogs" +#~ msgstr "對話框影像" + +#~ msgid "Generic dialog background" +#~ msgstr "一般對話框主題" + +#~ msgid "Theme for the logout dialog" +#~ msgstr "登出對話框主題" + +#~ msgid "Wallpaper packages" +#~ msgstr "桌布包" + +#~ msgid "Images for widgets" +#~ msgstr "元件影像" + +#~ msgid "Background image for widgets" +#~ msgstr "元件背景影像" + +#~ msgid "Analog clock face" +#~ msgstr "類比時鐘外觀" + +#~ msgid "Background image for panels" +#~ msgstr "面板背景影像" + +#~ msgid "Background for graphing widgets" +#~ msgstr "背景的圖形元件" + +#~ msgid "Background image for tooltips" +#~ msgstr "工具提示背景影像" + +#~ msgid "Opaque images for dialogs" +#~ msgstr "對話框的不透明影像" + +#~ msgid "Opaque generic dialog background" +#~ msgstr "不透明的一般對話框背景" + +#~ msgid "Opaque theme for the logout dialog" +#~ msgstr "登出對話框的不透明主題" + +#~ msgid "Opaque images for widgets" +#~ msgstr "元件的不透明影像" + +#~ msgid "Opaque background image for panels" +#~ msgstr "面板的不透明背景影像" + +#~ msgid "Opaque background image for tooltips" +#~ msgstr "工具提示的不透明背景影像" + +#~ msgid "KColorScheme configuration file" +#~ msgstr "KColorScheme 設定檔" + +#~ msgid "Service Descriptions" +#~ msgstr "服務描述" + +#~ msgctxt "" +#~ "API or programming language the widget was written in, name of the widget" +#~ msgid "Could not create a %1 ScriptEngine for the %2 widget." +#~ msgstr "無法建立 %2 元件所需要的 %1 文稿引擎。" + +#~ msgid "Script initialization failed" +#~ msgstr "文稿初始化失敗" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Holidays" +#~ msgstr "假日" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Events" +#~ msgstr "事件" + +#~ msgctxt "Agenda listview section title" +#~ msgid "Todo" +#~ msgstr "待辦事項" + +#~ msgctxt "Means 'Other calendar items'" +#~ msgid "Other" +#~ msgstr "其他" + +#, fuzzy +#~ msgctxt "Format: month year" +#~ msgid "%1 %2" +#~ msgstr "%2 %1" + +#~ msgid "Previous Month" +#~ msgstr "上個月" + +#~ msgid "Previous Year" +#~ msgstr "去年" + +#~ msgid "Previous Decade" +#~ msgstr "前一個十年" + +#~ msgctxt "Reset calendar to today" +#~ msgid "Today" +#~ msgstr "今天" + +#~ msgid "Reset calendar to today" +#~ msgstr "重設行事曆到今天" + +#~ msgid "Next Month" +#~ msgstr "下個月" + +#~ msgid "Next Year" +#~ msgstr "明年" + +#~ msgid "Next Decade" +#~ msgstr "下一個十年" + +#~ msgid "Days" +#~ msgstr "日" + +#~ msgid "Months" +#~ msgstr "月" + +#~ msgid "Years" +#~ msgstr "年" + +#~ msgid "OK" +#~ msgstr "確定" + +#~ msgid "Cancel" +#~ msgstr "取消" + +#~ msgid "Run the Associated Application" +#~ msgstr "執行相關的應用程式" + +#~ msgid "Open with %1" +#~ msgstr "用 %1 開啟" + +#~ msgid "Accessibility" +#~ msgstr "無障礙輔助" + +#~ msgid "Application Launchers" +#~ msgstr "應用程式啟動器" + +#~ msgid "Astronomy" +#~ msgstr "天文學" + +#~ msgid "Date and Time" +#~ msgstr "日期與時間" + +#~ msgid "Development Tools" +#~ msgstr "程式開發工具" + +#~ msgid "Education" +#~ msgstr "教育" + +#~ msgid "Environment and Weather" +#~ msgstr "環境與天氣" + +#~ msgid "Examples" +#~ msgstr "範例" + +#~ msgid "File System" +#~ msgstr "檔案系統" + +#~ msgid "Fun and Games" +#~ msgstr "娛樂與遊戲" + +#~ msgid "Graphics" +#~ msgstr "圖形" + +#~ msgid "Language" +#~ msgstr "語言" + +#~ msgid "Mapping" +#~ msgstr "地圖" + +#~ msgid "Miscellaneous" +#~ msgstr "雜項" + +#~ msgid "Multimedia" +#~ msgstr "多媒體" + +#~ msgid "Online Services" +#~ msgstr "線上服務" + +#~ msgid "Productivity" +#~ msgstr "效率" + +#~ msgid "System Information" +#~ msgstr "系統資訊" + +#~ msgid "Utilities" +#~ msgstr "實用工具" + +#~ msgid "Windows and Tasks" +#~ msgstr "視窗與工作" + +#~ msgid "Clipboard" +#~ msgstr "剪貼簿" + +#~ msgid "Tasks" +#~ msgstr "工作" + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "Edit %1..." +#~ msgstr "編輯 %1..." + +#~ msgid "Default settings for theme, etc." +#~ msgstr "主題等的預設設定。" + +#~ msgid "Color scheme to use for applications." +#~ msgstr "應用程式使用的配色。" + +#~ msgid "Preview Images" +#~ msgstr "預覽影像" + +#~ msgid "Preview for the Login Manager" +#~ msgstr "登入管理員預覽" + +#~ msgid "Preview for the Lock Screen" +#~ msgstr "螢幕鎖定預覽" + +#~ msgid "Preview for the Userswitcher" +#~ msgstr "使用者切換器預覽" + +#~ msgid "Preview for the Virtual Desktop Switcher" +#~ msgstr "虛擬桌面切換器預覽" + +#~ msgid "Preview for Splash Screen" +#~ msgstr "開始畫面預覽" + +#~ msgid "Preview for KRunner" +#~ msgstr "執行器預覽" + +#~ msgid "Preview for the Window Decorations" +#~ msgstr "視窗裝飾預覽" + +#~ msgid "Preview for Window Switcher" +#~ msgstr "視窗切換預覽" + +#~ msgid "Login Manager" +#~ msgstr "登入管理員" + +#~ msgid "Main Script for Login Manager" +#~ msgstr "登入管理員主文稿" + +#~ msgid "Logout Dialog" +#~ msgstr "登出對話框" + +#~ msgid "Main Script for Logout Dialog" +#~ msgstr "登出對話框的主文稿" + +#~ msgid "Screenlocker" +#~ msgstr "螢幕鎖定器" + +#~ msgid "Main Script for Lock Screen" +#~ msgstr "螢幕鎖定主文稿" + +#~ msgid "UI for fast user switching" +#~ msgstr "快速使用者切換介面" + +#~ msgid "Main Script for User Switcher" +#~ msgstr "使用者切換主文稿" + +#~ msgid "Virtual Desktop Switcher" +#~ msgstr "虛擬桌面切換器" + +#~ msgid "Main Script for Virtual Desktop Switcher" +#~ msgstr "虛擬桌面切換器主文稿" + +#~ msgid "On-Screen Display Notifications" +#~ msgstr "螢幕顯示通知" + +#~ msgid "Main Script for On-Screen Display Notifications" +#~ msgstr "螢幕顯示通知主文稿" + +#~ msgid "Splash Screen" +#~ msgstr "啟動畫面" + +#~ msgid "Main Script for Splash Screen" +#~ msgstr "啟動畫面主文稿" + +#~ msgid "KRunner UI" +#~ msgstr "執行器使用者介面" + +#~ msgid "Main Script KRunner" +#~ msgstr "執行器主文稿" + +#~ msgid "Window Decoration" +#~ msgstr "視窗裝飾" + +#~ msgid "Main Script for Window Decoration" +#~ msgstr "視窗裝飾主文稿" + +#~ msgid "Window Switcher" +#~ msgstr "視窗切換器" + +#~ msgid "Main Script for Window Switcher" +#~ msgstr "視窗切換器主文稿" + +#~ msgid "Finish Customizing Layout" +#~ msgstr "完成自訂配置" + +#~ msgid "Customize Layout..." +#~ msgstr "自訂配置..." + +#~ msgid "Fetching file type..." +#~ msgstr "抓取檔案型態..." + +#~ msgctxt "%1 is the name of the containment" +#~ msgid "%1 Options" +#~ msgstr "%1 選項" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..e82503e --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,10 @@ +add_subdirectory(desktoptheme) +add_subdirectory(plasma) +add_subdirectory(declarativeimports) +add_subdirectory(plasmaquick) + +ecm_qt_install_logging_categories( + EXPORT PLASMA + FILE plasma-framework.categories + DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR} +) diff --git a/src/Messages.sh b/src/Messages.sh new file mode 100644 index 0000000..2ec5f7a --- /dev/null +++ b/src/Messages.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +# Invoke the extractrc script on all .ui, .rc, and .kcfg files in the sources. +# The results are stored in a pseudo .cpp file to be picked up by xgettext. +lst=`find . -name \*.rc -o -name \*.ui -o -name \*.kcfg` +if [ -n "$lst" ] ; then + $EXTRACTRC $lst >> rc.cpp +fi + +# Run xgettext to extract strings from all source files. +$XGETTEXT `find . -name \*.cpp -o -name \*.h -o -name \*.qml` -o $podir/libplasma6.pot diff --git a/src/declarativeimports/CMakeLists.txt b/src/declarativeimports/CMakeLists.txt new file mode 100644 index 0000000..d945951 --- /dev/null +++ b/src/declarativeimports/CMakeLists.txt @@ -0,0 +1,30 @@ +add_subdirectory(core) +add_subdirectory(plasmaextracomponents) +add_subdirectory(kirigamiplasmastyle) + +set(QQC2_VERSION "6.${Qt6Quick_VERSION_MINOR}") + +# Find all the source qml files +FILE(GLOB_RECURSE inFiles RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}/plasmacomponents3/*") + + #for each file, replace @QQC2_VERSION@ with the version we found +FOREACH(infileName ${inFiles}) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/${infileName}" + "${CMAKE_CURRENT_BINARY_DIR}/${infileName}" + @ONLY + ) +ENDFOREACH(infileName) + +ecm_add_qml_module(org_kde_plasmacomponents3 URI "org.kde.plasma.components" VERSION 3.0 NO_PLUGIN) +file(GLOB _public_qml "${CMAKE_CURRENT_BINARY_DIR}/plasmacomponents3/*.qml") +ecm_target_qml_sources(org_kde_plasmacomponents3 VERSION 3.0 SOURCES ${_public_qml}) +file(GLOB _mobiletextselection_qml "${CMAKE_CURRENT_BINARY_DIR}/plasmacomponents3/mobiletextselection/*.qml" "${CMAKE_CURRENT_BINARY_DIR}/plasmacomponents3/mobiletextselection/qmldir") +ecm_target_qml_sources(org_kde_plasmacomponents3 VERSION 3.0 PATH mobiletextselection SOURCES ${_mobiletextselection_qml}) +file(GLOB _private_qml "${CMAKE_CURRENT_BINARY_DIR}/plasmacomponents3/private/*.qml") + +set_source_files_properties(${_private_qml} PROPERTIES QT_QML_INTERNAL_TYPE TRUE) + +ecm_target_qml_sources(org_kde_plasmacomponents3 VERSION 3.0 PATH private SOURCES ${_private_qml}) +ecm_finalize_qml_module(org_kde_plasmacomponents3 DESTINATION ${KDE_INSTALL_QMLDIR}) diff --git a/src/declarativeimports/core/CMakeLists.txt b/src/declarativeimports/core/CMakeLists.txt new file mode 100644 index 0000000..b23c4d7 --- /dev/null +++ b/src/declarativeimports/core/CMakeLists.txt @@ -0,0 +1,58 @@ +if(HAVE_X11 AND XCB_XCB_FOUND AND XCB_COMPOSITE_FOUND AND XCB_DAMAGE_FOUND) + set(HAVE_XCB_COMPOSITE TRUE) +else() + set(HAVE_XCB_COMPOSITE FALSE) +endif() + +configure_file(config-x11.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-x11.h) + +ecm_add_qml_module(corebindingsplugin URI "org.kde.plasma.core" VERSION 2.0 DEPENDENCIES QtCore QtQuick) + +target_sources(corebindingsplugin PRIVATE + action.cpp + corebindingsplugin.cpp + quicktheme.cpp + tooltiparea.cpp + tooltipdialog.cpp + windowthumbnail.cpp + ${RESOURCES} +) + +ecm_target_qml_sources(corebindingsplugin SOURCES + private/DefaultToolTip.qml + private/DialogBackground.qml +) + +target_link_libraries(corebindingsplugin PRIVATE + Qt6::Quick + Qt6::Qml + Qt6::Widgets + KF6::IconThemes + KF6::I18n + Qt6::Svg + KF6::WindowSystem + Plasma::Plasma + Plasma::PlasmaQuick + Wayland::Client +) + +if(HAVE_X11) + target_link_libraries(corebindingsplugin PRIVATE ${X11_LIBRARIES} XCB::XCB Qt6::GuiPrivate) + + if(XCB_COMPOSITE_FOUND AND XCB_DAMAGE_FOUND) + target_link_libraries(corebindingsplugin PRIVATE + XCB::DAMAGE + XCB::COMPOSITE + ) + endif() + + if(HAVE_GLX) + target_link_libraries(corebindingsplugin PRIVATE OpenGL::GLX) + endif() +endif() + +if(HAVE_EGL) + target_link_libraries(corebindingsplugin PRIVATE OpenGL::EGL) +endif() + +ecm_finalize_qml_module(corebindingsplugin DESTINATION ${KDE_INSTALL_QMLDIR}) diff --git a/src/declarativeimports/core/Mainpage.dox b/src/declarativeimports/core/Mainpage.dox new file mode 100644 index 0000000..6e58bfe --- /dev/null +++ b/src/declarativeimports/core/Mainpage.dox @@ -0,0 +1,33 @@ +/** @page core Plasma Core + +

import org.kde.plasma.core

+ +Uncreatable Types: +- \link Plasma::Types Types \endlink +- \link Units Units \endlink +- \link Plasma::QuickTheme Theme \endlink + +Types: +- \link Plasma::Svg Svg \endlink +- \link Plasma::FrameSvg FrameSvg \endlink +- \link Plasma::SvgItem SvgItem \endlink +- \link Plasma::FrameSvgItem FrameSvgItem \endlink + +- \link ColorScope ColorScope \endlink + +- \link PlasmaQuick::Dialog Dialog \endlink +- \link ToolTip ToolTipArea \endlink + +- \link Plasma::Service Service \endlink +- \link Plasma::ServiceJob ServiceJob \endlink + +- \link Plasma::ServiceOperationStatus ServiceOperationStatus \endlink + +- \link IconItem IconItem \endlink + +- \link Plasma::WindowThumbnail WindowThumbnail \endlink + +*/ + +// DOXYGEN_SET_PROJECT_NAME = PlasmaCore +// vim:ts=4:sw=4:expandtab:filetype=doxygen diff --git a/src/declarativeimports/core/action.cpp b/src/declarativeimports/core/action.cpp new file mode 100644 index 0000000..2adaf48 --- /dev/null +++ b/src/declarativeimports/core/action.cpp @@ -0,0 +1,131 @@ +/* + SPDX-FileCopyrightText: 2023 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "action.h" +#include + +IconGroup::IconGroup(ActionExtension *parent) + : QObject(parent) + , m_action(parent->action()) +{ +} + +IconGroup::~IconGroup() +{ +} + +void IconGroup::setName(const QString &name) +{ + if (name == m_name) { + return; + } + + m_name = name; + m_action->setIcon(QIcon::fromTheme(name)); + Q_EMIT nameChanged(); +} + +QString IconGroup::name() const +{ + return m_name; +} + +void IconGroup::setIcon(const QIcon &icon) +{ + m_action->setIcon(icon); + Q_EMIT iconChanged(); +} + +QIcon IconGroup::icon() const +{ + return m_action->icon(); +} + +ActionExtension::ActionExtension(QObject *parent) + : QObject(parent) + , m_action(qobject_cast(parent)) + , m_iconGroup(new IconGroup(this)) +{ +} + +ActionExtension::~ActionExtension() +{ +} + +bool ActionExtension::isSeparator() const +{ + return m_action->isSeparator(); +} + +void ActionExtension::setSeparator(bool separator) +{ + if (separator == m_action->isSeparator()) { + return; + } + + m_action->setSeparator(separator); + + Q_EMIT isSeparatorChanged(); +} + +void ActionExtension::setActionGroup(QActionGroup *group) +{ + if (group == m_action->actionGroup()) { + return; + } + + m_action->setActionGroup(group); + Q_EMIT actionGroupChanged(); +} + +QActionGroup *ActionExtension::actionGroup() const +{ + return m_action->actionGroup(); +} + +static QKeySequence variantToKeySequence(const QVariant &var) +{ + if (var.metaType().id() == QMetaType::Int) + return QKeySequence(static_cast(var.toInt())); + return QKeySequence::fromString(var.toString()); +} + +QVariant ActionExtension::shortcut() const +{ + return m_action->shortcut(); +} + +void ActionExtension::setShortcut(const QVariant &var) +{ + const QKeySequence seq = variantToKeySequence(var); + if (seq == m_action->shortcut()) { + return; + } + m_action->setShortcut(seq); + Q_EMIT shortcutChanged(); +} + +void ActionExtension::setMenu(QMenu *menu) +{ + if (menu == m_action->menu()) { + return; + } + + m_action->setMenu(menu); + Q_EMIT menuChanged(); +} + +QMenu *ActionExtension::menu() +{ + return m_action->menu(); +} + +QAction *ActionExtension::action() const +{ + return m_action; +} + +#include "moc_action.cpp" diff --git a/src/declarativeimports/core/action.h b/src/declarativeimports/core/action.h new file mode 100644 index 0000000..512af69 --- /dev/null +++ b/src/declarativeimports/core/action.h @@ -0,0 +1,101 @@ +/* + SPDX-FileCopyrightText: 2023 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMAACTION_H +#define PLASMAACTION_H + +#include +#include +#include +#include +#include +#include + +class QQuickItem; + +namespace PlasmaQuick +{ +class SharedQmlEngine; +} + +class ActionExtension; + +class IconGroup : public QObject +{ + Q_OBJECT + QML_ANONYMOUS + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(QIcon icon READ icon WRITE setIcon NOTIFY iconChanged) +public: + explicit IconGroup(ActionExtension *parent = nullptr); + ~IconGroup(); + + void setName(const QString &name); + QString name() const; + + QIcon icon() const; + void setIcon(const QIcon &icon); + +Q_SIGNALS: + void nameChanged(); + void iconChanged(); + +private: + QAction *m_action; + QString m_name; +}; + +class ActionExtension : public QObject +{ + Q_OBJECT + Q_PROPERTY(IconGroup *icon MEMBER m_iconGroup CONSTANT) + Q_PROPERTY(bool isSeparator READ isSeparator WRITE setSeparator NOTIFY isSeparatorChanged) + Q_PROPERTY(QActionGroup *actionGroup READ actionGroup WRITE setActionGroup NOTIFY actionGroupChanged) + Q_PROPERTY(QVariant shortcut READ shortcut WRITE setShortcut NOTIFY shortcutChanged) + Q_PROPERTY(QMenu *menu READ menu WRITE setMenu NOTIFY menuChanged) + +public: + explicit ActionExtension(QObject *parent = nullptr); + ~ActionExtension() override; + + bool isSeparator() const; + void setSeparator(bool setSeparator); + + void setActionGroup(QActionGroup *group); + QActionGroup *actionGroup() const; + + void setShortcut(const QVariant &var); + QVariant shortcut() const; + + void setMenu(QMenu *menu); + QMenu *menu(); + + QAction *action() const; + +Q_SIGNALS: + void isSeparatorChanged(); + void actionGroupChanged(); + void shortcutChanged(); + void menuChanged(); + +private: + QAction *m_action; + IconGroup *m_iconGroup; + QString m_icon; +}; + +class ActionGroup : public QActionGroup +{ + Q_OBJECT + QML_ELEMENT +public: + ActionGroup(QObject *parent = nullptr) + : QActionGroup(parent) + { + } +}; + +#endif diff --git a/src/declarativeimports/core/config-x11.h.cmake b/src/declarativeimports/core/config-x11.h.cmake new file mode 100644 index 0000000..2f543d5 --- /dev/null +++ b/src/declarativeimports/core/config-x11.h.cmake @@ -0,0 +1,2 @@ +#cmakedefine01 HAVE_X11 +#cmakedefine01 HAVE_XCB_COMPOSITE diff --git a/src/declarativeimports/core/corebindingsplugin.cpp b/src/declarativeimports/core/corebindingsplugin.cpp new file mode 100644 index 0000000..a5ad8e2 --- /dev/null +++ b/src/declarativeimports/core/corebindingsplugin.cpp @@ -0,0 +1,44 @@ +/* + SPDX-FileCopyrightText: 2009 Alan Alpert + SPDX-FileCopyrightText: 2010 Ménard Alexis + SPDX-FileCopyrightText: 2010 Marco Martin + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "corebindingsplugin.h" + +#include +#include +#include + +#include + +#include "action.h" + +void CoreBindingsPlugin::initializeEngine(QQmlEngine *engine, const char *uri) +{ + QQmlExtensionPlugin::initializeEngine(engine, uri); + + QQmlContext *context = engine->rootContext(); + + if (!context->contextObject()) { + KLocalizedContext *localizedContextObject = new KLocalizedContext(engine); + context->setContextObject(localizedContextObject); + } + // This ensures that importing plasmacore will make any KSvg use the current lasma theme + new Plasma::Theme(engine); +} + +void CoreBindingsPlugin::registerTypes(const char *uri) +{ + Q_ASSERT(uri == QByteArray("org.kde.plasma.core")); + + // HACK make properties like "opacity" work that are in REVISION 1 of QWindow + qmlRegisterRevision(uri, 2, 0); + qmlRegisterRevision(uri, 2, 0); + qmlRegisterExtendedType(uri, 2, 0, "Action"); +} + +#include "moc_corebindingsplugin.cpp" diff --git a/src/declarativeimports/core/corebindingsplugin.h b/src/declarativeimports/core/corebindingsplugin.h new file mode 100644 index 0000000..2aa7502 --- /dev/null +++ b/src/declarativeimports/core/corebindingsplugin.h @@ -0,0 +1,69 @@ +/* + SPDX-FileCopyrightText: 2009 Alan Alpert + SPDX-FileCopyrightText: 2010 Ménard Alexis + SPDX-FileCopyrightText: 2010 Marco Martin + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef COREBINDINGSPLUGIN_H +#define COREBINDINGSPLUGIN_H + +#include +#include +#include + +#include + +#include "appletpopup.h" +#include "dialog.h" + +struct TypesForeign { + Q_GADGET + QML_NAMED_ELEMENT(Types) + QML_UNCREATABLE("") + QML_FOREIGN(Plasma::Types) +}; + +struct PropertyMapForeign { + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQmlPropertyMap) +}; + +struct PlasmaWindowForeign { + Q_GADGET + QML_NAMED_ELEMENT(Window) + QML_FOREIGN(PlasmaQuick::PlasmaWindow) +}; + +struct AppletPopupForeign { + Q_GADGET + QML_NAMED_ELEMENT(AppletPopup) + QML_FOREIGN(PlasmaQuick::AppletPopup) +}; + +struct PopupPlasmaWindowForeign { + Q_GADGET + QML_NAMED_ELEMENT(PopupPlasmaWindow) + QML_FOREIGN(PlasmaQuick::PopupPlasmaWindow) +}; + +struct DialogForeign { + Q_GADGET + QML_NAMED_ELEMENT(Dialog) + QML_FOREIGN(PlasmaQuick::Dialog) +}; + +class CoreBindingsPlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") + +public: + void initializeEngine(QQmlEngine *engine, const char *uri) override; + void registerTypes(const char *uri) override; +}; + +#endif diff --git a/src/declarativeimports/core/private/DefaultToolTip.qml b/src/declarativeimports/core/private/DefaultToolTip.qml new file mode 100644 index 0000000..646c382 --- /dev/null +++ b/src/declarativeimports/core/private/DefaultToolTip.qml @@ -0,0 +1,75 @@ +/* + SPDX-FileCopyrightText: 2013-2015 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +/** + * Internal type containing the default layout of a tooltip. + */ +Item { + property Item toolTip + property int preferredTextWidth: Kirigami.Units.gridUnit * 20 + + implicitWidth: mainLayout.implicitWidth + Kirigami.Units.largeSpacing * 2 + implicitHeight: mainLayout.implicitHeight + Kirigami.Units.largeSpacing * 2 + + LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft + LayoutMirroring.childrenInherit: true + + Kirigami.Theme.colorSet: Kirigami.Theme.Window + Kirigami.Theme.inherit: false + + RowLayout { + id: mainLayout + anchors.centerIn: parent + anchors.margins: Kirigami.Units.largeSpacing + + spacing: Kirigami.Units.gridUnit + + Image { + source: toolTip ? toolTip.image : "" + visible: toolTip !== null && toolTip.image !== "" + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + } + + Kirigami.Icon { + animated: false + source: toolTip ? toolTip.icon : "" + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + visible: toolTip !== null && toolTip.icon !== "" && toolTip.image === "" && valid + Layout.preferredWidth: Kirigami.Units.iconSizes.medium + Layout.preferredHeight: Kirigami.Units.iconSizes.medium + } + + ColumnLayout { + Layout.maximumWidth: preferredTextWidth + spacing: 0 + + Kirigami.Heading { + level: 3 + Layout.fillWidth: true + elide: Text.ElideRight + wrapMode: Text.Wrap + text: toolTip ? toolTip.mainText : "" + textFormat: Text.PlainText + visible: text !== "" + } + + PlasmaComponents.Label { + Layout.fillWidth: true + wrapMode: Text.WordWrap + text: toolTip ? toolTip.subText : "" + textFormat: toolTip ? toolTip.textFormat : Text.AutoText + opacity: 0.6 + visible: text !== "" + maximumLineCount: 8 + } + } + } +} diff --git a/src/declarativeimports/core/private/DialogBackground.qml b/src/declarativeimports/core/private/DialogBackground.qml new file mode 100644 index 0000000..42c17dc --- /dev/null +++ b/src/declarativeimports/core/private/DialogBackground.qml @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2023 Marco Martin + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ + +import QtQuick +import org.kde.ksvg as KSvg + +/** + * Internal type used by DialogBackground in plasmaquick to load the actual + * background SVG. + */ +KSvg.FrameSvgItem { + anchors.fill: parent + imagePath: "widgets/background" +} diff --git a/src/declarativeimports/core/quicktheme.cpp b/src/declarativeimports/core/quicktheme.cpp new file mode 100644 index 0000000..4c71c66 --- /dev/null +++ b/src/declarativeimports/core/quicktheme.cpp @@ -0,0 +1,232 @@ +/* + SPDX-FileCopyrightText: 2006-2007 Aaron Seigo + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "quicktheme.h" + +namespace Plasma +{ +QuickTheme::QuickTheme(QObject *parent) + : Theme(parent) +{ + connect(this, &Theme::themeChanged, this, &QuickTheme::themeChangedProxy); +} + +QuickTheme::~QuickTheme() +{ +} + +QColor QuickTheme::textColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor); +} + +QColor QuickTheme::highlightColor() const +{ + return Plasma::Theme::color(Plasma::Theme::HighlightColor); +} + +QColor QuickTheme::highlightedTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::HighlightedTextColor); +} + +QColor QuickTheme::positiveTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::PositiveTextColor); +} + +QColor QuickTheme::neutralTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::NeutralTextColor); +} + +QColor QuickTheme::negativeTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::NegativeTextColor); +} + +QColor QuickTheme::disabledTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::DisabledTextColor); +} + +QColor QuickTheme::backgroundColor() const +{ + return Plasma::Theme::color(Plasma::Theme::BackgroundColor); +} + +QColor QuickTheme::buttonTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::ButtonColorGroup); +} + +QColor QuickTheme::buttonBackgroundColor() const +{ + return Plasma::Theme::color(Plasma::Theme::BackgroundColor, Plasma::Theme::ButtonColorGroup); +} + +QColor QuickTheme::buttonPositiveTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::ButtonColorGroup); +} + +QColor QuickTheme::buttonNeutralTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::ButtonColorGroup); +} + +QColor QuickTheme::buttonNegativeTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::ButtonColorGroup); +} + +QColor QuickTheme::linkColor() const +{ + return Plasma::Theme::color(Plasma::Theme::LinkColor); +} + +QColor QuickTheme::visitedLinkColor() const +{ + return Plasma::Theme::color(Plasma::Theme::VisitedLinkColor); +} + +QColor QuickTheme::buttonHoverColor() const +{ + return Plasma::Theme::color(Plasma::Theme::HoverColor, Plasma::Theme::ButtonColorGroup); +} + +QColor QuickTheme::buttonFocusColor() const +{ + return Plasma::Theme::color(Plasma::Theme::FocusColor, Plasma::Theme::ButtonColorGroup); +} + +QColor QuickTheme::buttonHighlightedTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::ButtonColorGroup); +} + +QColor QuickTheme::viewTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::ViewColorGroup); +} + +QColor QuickTheme::viewBackgroundColor() const +{ + return Plasma::Theme::color(Plasma::Theme::BackgroundColor, Plasma::Theme::ViewColorGroup); +} + +QColor QuickTheme::viewHoverColor() const +{ + return Plasma::Theme::color(Plasma::Theme::HoverColor, Plasma::Theme::ViewColorGroup); +} + +QColor QuickTheme::viewFocusColor() const +{ + return Plasma::Theme::color(Plasma::Theme::FocusColor, Plasma::Theme::ViewColorGroup); +} + +QColor QuickTheme::viewHighlightedTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::ViewColorGroup); +} + +QColor QuickTheme::viewPositiveTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::ViewColorGroup); +} + +QColor QuickTheme::viewNeutralTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::ViewColorGroup); +} + +QColor QuickTheme::viewNegativeTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::ViewColorGroup); +} + +QColor QuickTheme::complementaryTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::ComplementaryColorGroup); +} + +QColor QuickTheme::complementaryBackgroundColor() const +{ + return Plasma::Theme::color(Plasma::Theme::BackgroundColor, Plasma::Theme::ComplementaryColorGroup); +} + +QColor QuickTheme::complementaryHoverColor() const +{ + return Plasma::Theme::color(Plasma::Theme::HoverColor, Plasma::Theme::ComplementaryColorGroup); +} + +QColor QuickTheme::complementaryFocusColor() const +{ + return Plasma::Theme::color(Plasma::Theme::FocusColor, Plasma::Theme::ComplementaryColorGroup); +} + +QColor QuickTheme::complementaryHighlightedTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::ComplementaryColorGroup); +} + +QColor QuickTheme::complementaryPositiveTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::ComplementaryColorGroup); +} + +QColor QuickTheme::complementaryNeutralTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::ComplementaryColorGroup); +} + +QColor QuickTheme::complementaryNegativeTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::ComplementaryColorGroup); +} + +QColor QuickTheme::headerTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::HeaderColorGroup); +} + +QColor QuickTheme::headerBackgroundColor() const +{ + return Plasma::Theme::color(Plasma::Theme::BackgroundColor, Plasma::Theme::HeaderColorGroup); +} + +QColor QuickTheme::headerHoverColor() const +{ + return Plasma::Theme::color(Plasma::Theme::HoverColor, Plasma::Theme::HeaderColorGroup); +} + +QColor QuickTheme::headerFocusColor() const +{ + return Plasma::Theme::color(Plasma::Theme::FocusColor, Plasma::Theme::HeaderColorGroup); +} + +QColor QuickTheme::headerHighlightedTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::HeaderColorGroup); +} + +QColor QuickTheme::headerPositiveTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::HeaderColorGroup); +} + +QColor QuickTheme::headerNeutralTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::HeaderColorGroup); +} + +QColor QuickTheme::headerNegativeTextColor() const +{ + return Plasma::Theme::color(Plasma::Theme::TextColor, Plasma::Theme::HeaderColorGroup); +} +} + +#include "moc_quicktheme.cpp" diff --git a/src/declarativeimports/core/quicktheme.h b/src/declarativeimports/core/quicktheme.h new file mode 100644 index 0000000..63dab6f --- /dev/null +++ b/src/declarativeimports/core/quicktheme.h @@ -0,0 +1,350 @@ +/* + SPDX-FileCopyrightText: 2006-2007 Aaron Seigo + SPDX-FileCopyrightText: 2013 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMA_QUICKTHEME_H +#define PLASMA_QUICKTHEME_H + +#include + +#include +#include + +namespace Plasma +{ +/** + * @short Interface to the Plasma theme + * + * + * Plasma::Theme provides access to a common and standardized set of graphic + * elements stored in SVG format. This allows artists to create single packages + * of SVGs that will affect the look and feel of all workspace components. + * + * Plasma::Svg uses Plasma::Theme internally to locate and load the appropriate + * SVG data. Alternatively, Plasma::Theme can be used directly to retrieve + * file system paths to SVGs by name. + * + * Import Statement + * @code import org.kde.plasma.core @endcode + * @version 2.0 + */ +class QuickTheme : public Plasma::Theme +{ + Q_OBJECT + QML_NAMED_ELEMENT(Theme) + QML_SINGLETON + + // colors + Q_PROPERTY(QColor textColor READ textColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor highlightColor READ highlightColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor highlightedTextColor READ highlightedTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor backgroundColor READ backgroundColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor linkColor READ linkColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor visitedLinkColor READ visitedLinkColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor positiveTextColor READ positiveTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor neutralTextColor READ neutralTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor negativeTextColor READ negativeTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor disabledTextColor READ disabledTextColor NOTIFY themeChangedProxy) + + Q_PROPERTY(QColor buttonTextColor READ buttonTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor buttonBackgroundColor READ buttonBackgroundColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor buttonHoverColor READ buttonHoverColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor buttonFocusColor READ buttonFocusColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor buttonHighlightedTextColor READ buttonHighlightedTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor buttonPositiveTextColor READ buttonPositiveTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor buttonNeutralTextColor READ buttonNeutralTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor buttonNegativeTextColor READ buttonNegativeTextColor NOTIFY themeChangedProxy) + + Q_PROPERTY(QColor viewTextColor READ viewTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor viewBackgroundColor READ viewBackgroundColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor viewHoverColor READ viewHoverColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor viewFocusColor READ viewFocusColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor viewHighlightedTextColor READ viewHighlightedTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor viewPositiveTextColor READ viewPositiveTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor viewNeutralTextColor READ viewNeutralTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor viewNegativeTextColor READ viewNegativeTextColor NOTIFY themeChangedProxy) + + Q_PROPERTY(QColor complementaryTextColor READ complementaryTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor complementaryBackgroundColor READ complementaryBackgroundColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor complementaryHoverColor READ complementaryHoverColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor complementaryFocusColor READ complementaryFocusColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor complementaryHighlightedTextColor READ complementaryHighlightedTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor complementaryPositiveTextColor READ complementaryPositiveTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor complementaryNeutralTextColor READ complementaryNeutralTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor complementaryNegativeTextColor READ complementaryNegativeTextColor NOTIFY themeChangedProxy) + + Q_PROPERTY(QColor headerTextColor READ headerTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor headerBackgroundColor READ headerBackgroundColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor headerHoverColor READ headerHoverColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor headerFocusColor READ headerFocusColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor headerHighlightedTextColor READ headerHighlightedTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor headerPositiveTextColor READ headerPositiveTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor headerNeutralTextColor READ headerNeutralTextColor NOTIFY themeChangedProxy) + Q_PROPERTY(QColor headerNegativeTextColor READ headerNegativeTextColor NOTIFY themeChangedProxy) + +public: + explicit QuickTheme(QObject *parent = nullptr); + ~QuickTheme() override; + + /** + * @return The theme's colorscheme's text color + * @since 5.0 + */ + QColor textColor() const; + + /** + * @return The theme's colorscheme's highlight color + * @since 5.0 + */ + QColor highlightColor() const; + + /** + * @return The theme's colorscheme's highlighted text color + * @since 5.22 + */ + QColor highlightedTextColor() const; + + /** + * @return The theme's colorscheme's positive text color + * @since 5.22 + */ + QColor positiveTextColor() const; + + /** + * @return The theme's colorscheme's neutral text color + * @since 5.22 + */ + QColor neutralTextColor() const; + + /** + * @return The theme's colorscheme's negative text color + * @since 5.22 + */ + QColor negativeTextColor() const; + + /** + * @return The theme's colorscheme's disabled text color + * @since 5.64 + */ + QColor disabledTextColor() const; + + /** + * @return The theme's colorscheme's background color + * @since 5.0 + */ + QColor backgroundColor() const; + + /** + * @return The theme's colorscheme's color for text on buttons + * @since 5.0 + */ + QColor buttonTextColor() const; + + /** + * @return The theme's colorscheme's background color color of buttons + * @since 5.0 + */ + QColor buttonBackgroundColor() const; + + /** + * @return The theme's colorscheme's positive text color of buttons + * @since 5.22 + */ + QColor buttonPositiveTextColor() const; + + /** + * @return The theme's colorscheme's neutral text color of buttons + * @since 5.22 + */ + QColor buttonNeutralTextColor() const; + + /** + * @return The theme's colorscheme's negative text color of buttons + * @since 5.22 + */ + QColor buttonNegativeTextColor() const; + + /** + * @return The theme's colorscheme's link color + * @since 5.0 + */ + QColor linkColor() const; + + /** + * @return The theme's colorscheme's text color for visited links + * @since 5.0 + */ + QColor visitedLinkColor() const; + + /** + * @return The theme's colorscheme's color of hovered buttons + * @since 5.0 + */ + QColor buttonHoverColor() const; + + /** + * @return The theme's colorscheme's color of focused buttons + * @since 5.0 + */ + QColor buttonFocusColor() const; + + /** + * @return The theme's colorscheme's highlighted text color for buttons + * @since 5.22 + */ + QColor buttonHighlightedTextColor() const; + + /** + * @return The theme's colorscheme's text color in views + * @since 5.0 + */ + QColor viewTextColor() const; + + /** + * @return The theme's colorscheme's background color of views + * @since 5.0 + */ + QColor viewBackgroundColor() const; + + /** + * @return The theme's colorscheme's color of hovered views + * @since 5.0 + */ + QColor viewHoverColor() const; + + /** + * @return The theme's colorscheme's color of focused views + * @since 5.0 + */ + QColor viewFocusColor() const; + + /** + * @return The theme's colorscheme's highlighted text color for views + * @since 5.22 + */ + QColor viewHighlightedTextColor() const; + + /** + * @return The theme's colorscheme's positive text color of view + * @since 5.22 + */ + QColor viewPositiveTextColor() const; + + /** + * @return The theme's colorscheme's neutral text color of view + * @since 5.22 + */ + QColor viewNeutralTextColor() const; + + /** + * @return The theme's colorscheme's negative text color of view + * @since 5.22 + */ + QColor viewNegativeTextColor() const; + + /** + * @return The theme's colorscheme's text color of "complementary" areas + * @since 5.0 + */ + QColor complementaryTextColor() const; + + /** + * @return The theme's colorscheme's background color of "complementary" areas + * @since 5.0 + */ + QColor complementaryBackgroundColor() const; + + /** + * @return The theme's colorscheme's color of hovered "complementary" areas + * @since 5.0 + */ + QColor complementaryHoverColor() const; + + /** + * @return The theme's colorscheme's color of focused "complementary" areas + * @since 5.0 + */ + QColor complementaryFocusColor() const; + + /** + * @return The theme's colorscheme's highlighted text color for "complementary" areas + * @since 5.22 + */ + QColor complementaryHighlightedTextColor() const; + + /** + * @return The theme's colorscheme's positive text color of complementary + * @since 5.22 + */ + QColor complementaryPositiveTextColor() const; + + /** + * @return The theme's colorscheme's neutral text color of complementary + * @since 5.22 + */ + QColor complementaryNeutralTextColor() const; + + /** + * @return The theme's colorscheme's negative text color of complementary + * @since 5.22 + */ + QColor complementaryNegativeTextColor() const; + + /** + * @return The theme's colorscheme's text color of "header" areas + * @since 5.0 + */ + QColor headerTextColor() const; + + /** + * @return The theme's colorscheme's background color of "header" areas + * @since 5.0 + */ + QColor headerBackgroundColor() const; + + /** + * @return The theme's colorscheme's color of hovered "header" areas + * @since 5.0 + */ + QColor headerHoverColor() const; + + /** + * @return The theme's colorscheme's color of focused "header" areas + * @since 5.0 + */ + QColor headerFocusColor() const; + + /** + * @return The theme's colorscheme's highlighted text color for "header" areas + * @since 5.22 + */ + QColor headerHighlightedTextColor() const; + + /** + * @return The theme's colorscheme's positive text color of header + * @since 5.22 + */ + QColor headerPositiveTextColor() const; + + /** + * @return The theme's colorscheme's neutral text color of header + * @since 5.22 + */ + QColor headerNeutralTextColor() const; + + /** + * @return The theme's colorscheme's negative text color of header + * @since 5.22 + */ + QColor headerNegativeTextColor() const; + +Q_SIGNALS: + void themeChangedProxy(); +}; + +} // Plasma namespace + +#endif // multiple inclusion guard diff --git a/src/declarativeimports/core/tooltiparea.cpp b/src/declarativeimports/core/tooltiparea.cpp new file mode 100644 index 0000000..4b32cdb --- /dev/null +++ b/src/declarativeimports/core/tooltiparea.cpp @@ -0,0 +1,402 @@ +/* + SPDX-FileCopyrightText: 2011 Marco Martin + SPDX-FileCopyrightText: 2011 Artur Duque de Souza + SPDX-FileCopyrightText: 2013 Sebastian Kügler + SPDX-FileCopyrightText: 2023 David Edmundson + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "tooltiparea.h" +#include "appletquickitem.h" +#include "tooltipdialog.h" + +#include +#include +#include + +#include +#include +#include +#include + +ToolTipDialog *ToolTipArea::s_dialog = nullptr; +int ToolTipArea::s_dialogUsers = 0; + +ToolTipArea::ToolTipArea(QQuickItem *parent) + : QQuickItem(parent) + , m_tooltipsEnabledGlobally(false) + , m_containsMouse(false) + , m_location(Plasma::Types::Floating) + , m_textFormat(Qt::AutoText) + , m_active(true) + , m_interactive(false) + , m_timeout(-1) + , m_usingDialog(false) +{ + setAcceptHoverEvents(true); + setFiltersChildMouseEvents(true); + + m_showTimer.setSingleShot(true); + connect(&m_showTimer, &QTimer::timeout, this, &ToolTipArea::showToolTip); + + loadSettings(); + + const QString configFile = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QStringLiteral("/plasmarc"); + KDirWatch::self()->addFile(configFile); + QObject::connect(KDirWatch::self(), &KDirWatch::created, this, &ToolTipArea::settingsChanged); + QObject::connect(KDirWatch::self(), &KDirWatch::dirty, this, &ToolTipArea::settingsChanged); +} + +ToolTipArea::~ToolTipArea() +{ + if (s_dialog && s_dialog->owner() == this) { + s_dialog->setVisible(false); + } + + if (m_usingDialog) { + --s_dialogUsers; + } + + if (s_dialogUsers == 0) { + delete s_dialog; + s_dialog = nullptr; + } +} + +void ToolTipArea::settingsChanged(const QString &file) +{ + if (!file.endsWith(QLatin1String("plasmarc"))) { + return; + } + + KSharedConfig::openConfig(QStringLiteral("plasmarc"))->reparseConfiguration(); + loadSettings(); +} + +void ToolTipArea::loadSettings() +{ + KConfigGroup cfg = KConfigGroup(KSharedConfig::openConfig(QStringLiteral("plasmarc")), QStringLiteral("PlasmaToolTips")); + m_interval = cfg.readEntry("Delay", 700); + m_tooltipsEnabledGlobally = (m_interval > 0); +} + +QQuickItem *ToolTipArea::mainItem() const +{ + return m_mainItem.data(); +} + +ToolTipDialog *ToolTipArea::tooltipDialogInstance() +{ + if (!s_dialog) { + s_dialog = new ToolTipDialog; + } + + if (!m_usingDialog) { + s_dialogUsers++; + m_usingDialog = true; + } + + return s_dialog; +} + +void ToolTipArea::setMainItem(QQuickItem *mainItem) +{ + if (m_mainItem.data() != mainItem) { + m_mainItem = mainItem; + + Q_EMIT mainItemChanged(); + + if (!isValid() && s_dialog && s_dialog->owner() == this) { + s_dialog->setVisible(false); + } + } +} + +void ToolTipArea::showToolTip() +{ + if (!m_active) { + return; + } + + Q_EMIT aboutToShow(); + + ToolTipDialog *dlg = tooltipDialogInstance(); + + if (!mainItem()) { + setMainItem(dlg->loadDefaultItem()); + } + + // Unset the dialog's old contents before reparenting the dialog. + dlg->setMainItem(nullptr); + + Plasma::Types::Location location = m_location; + if (m_location == Plasma::Types::Floating) { + QQuickItem *p = parentItem(); + while (p) { + PlasmaQuick::AppletQuickItem *appletItem = qobject_cast(p); + if (appletItem) { + location = appletItem->applet()->location(); + break; + } + p = p->parentItem(); + } + } + + if (mainItem()) { + mainItem()->setProperty("toolTip", QVariant::fromValue(this)); + mainItem()->setVisible(true); + } + + connect(dlg, &ToolTipDialog::visibleChanged, this, &ToolTipArea::toolTipVisibleChanged, Qt::UniqueConnection); + + dlg->setHideTimeout(m_timeout); + dlg->setOwner(this); + dlg->setVisualParent(this); + dlg->setMainItem(mainItem()); + dlg->setInteractive(m_interactive); + + switch (location) { + case Plasma::Types::Floating: + case Plasma::Types::Desktop: + case Plasma::Types::FullScreen: + dlg->setFloating(true); + dlg->setPopupDirection(Qt::BottomEdge); + break; + case Plasma::Types::TopEdge: + dlg->setFloating(false); + dlg->setPopupDirection(Qt::BottomEdge); + break; + case Plasma::Types::BottomEdge: + dlg->setFloating(false); + dlg->setPopupDirection(Qt::TopEdge); + break; + case Plasma::Types::LeftEdge: + dlg->setFloating(false); + dlg->setPopupDirection(Qt::RightEdge); + break; + case Plasma::Types::RightEdge: + dlg->setFloating(false); + dlg->setPopupDirection(Qt::LeftEdge); + break; + } + + dlg->setVisible(true); + // In case the last owner triggered a dismiss but the dialog is still shown, + // showEvent won't be reached and the old timeout will still be effective. + // Call keepalive() to make it use the new timeout. + dlg->keepalive(); +} + +QString ToolTipArea::mainText() const +{ + return m_mainText; +} + +void ToolTipArea::setMainText(const QString &mainText) +{ + if (mainText == m_mainText) { + return; + } + + m_mainText = mainText; + Q_EMIT mainTextChanged(); + + if (!isValid() && s_dialog && s_dialog->owner() == this) { + s_dialog->setVisible(false); + } +} + +QString ToolTipArea::subText() const +{ + return m_subText; +} + +void ToolTipArea::setSubText(const QString &subText) +{ + if (subText == m_subText) { + return; + } + + m_subText = subText; + Q_EMIT subTextChanged(); + + if (!isValid() && s_dialog && s_dialog->owner() == this) { + s_dialog->setVisible(false); + } +} + +int ToolTipArea::textFormat() const +{ + return m_textFormat; +} + +void ToolTipArea::setTextFormat(int format) +{ + if (m_textFormat == format) { + return; + } + + m_textFormat = format; + Q_EMIT textFormatChanged(); +} + +Plasma::Types::Location ToolTipArea::location() const +{ + return m_location; +} + +void ToolTipArea::setLocation(Plasma::Types::Location location) +{ + if (m_location == location) { + return; + } + m_location = location; + Q_EMIT locationChanged(); +} + +void ToolTipArea::setActive(bool active) +{ + if (m_active == active) { + return; + } + + m_active = active; + if (!active) { + tooltipDialogInstance()->dismiss(); + } + Q_EMIT activeChanged(); +} + +void ToolTipArea::setInteractive(bool interactive) +{ + if (m_interactive == interactive) { + return; + } + + m_interactive = interactive; + + Q_EMIT interactiveChanged(); +} + +void ToolTipArea::setTimeout(int timeout) +{ + m_timeout = timeout; +} + +void ToolTipArea::hideToolTip() +{ + m_showTimer.stop(); + tooltipDialogInstance()->dismiss(); +} + +void ToolTipArea::hideImmediately() +{ + m_showTimer.stop(); + tooltipDialogInstance()->setVisible(false); +} + +QVariant ToolTipArea::icon() const +{ + if (m_icon.isValid()) { + return m_icon; + } else { + return QString(); + } +} + +void ToolTipArea::setIcon(const QVariant &icon) +{ + if (icon == m_icon) { + return; + } + + m_icon = icon; + Q_EMIT iconChanged(); +} + +QVariant ToolTipArea::image() const +{ + if (m_image.isValid()) { + return m_image; + } else { + return QString(); + } +} + +void ToolTipArea::setImage(const QVariant &image) +{ + if (image == m_image) { + return; + } + + m_image = image; + Q_EMIT imageChanged(); +} + +bool ToolTipArea::containsMouse() const +{ + return m_containsMouse; +} + +void ToolTipArea::setContainsMouse(bool contains) +{ + if (m_containsMouse != contains) { + m_containsMouse = contains; + Q_EMIT containsMouseChanged(); + } + if (!contains && tooltipDialogInstance()->owner() == this) { + tooltipDialogInstance()->dismiss(); + } +} + +void ToolTipArea::hoverEnterEvent(QHoverEvent *event) +{ + Q_UNUSED(event) + setContainsMouse(true); + + if (!m_tooltipsEnabledGlobally) { + return; + } + + if (!isValid()) { + return; + } + + if (tooltipDialogInstance()->isVisible()) { + // We signal the tooltipmanager that we're "potentially interested, + // and ask to keep it open for a bit, so other items get the chance + // to update the content before the tooltip hides -- this avoids + // flickering + // It need to be considered only when other items can deal with tooltip area + if (m_active) { + tooltipDialogInstance()->keepalive(); + // FIXME: showToolTip needs to be renamed in sync or something like that + showToolTip(); + } + } else { + m_showTimer.start(m_interval); + } +} + +void ToolTipArea::hoverLeaveEvent(QHoverEvent *event) +{ + Q_UNUSED(event) + setContainsMouse(false); + m_showTimer.stop(); +} + +bool ToolTipArea::childMouseEventFilter(QQuickItem *item, QEvent *event) +{ + if (event->type() == QEvent::MouseButtonPress) { + hideToolTip(); + } + return QQuickItem::childMouseEventFilter(item, event); +} + +bool ToolTipArea::isValid() const +{ + return m_mainItem || !mainText().isEmpty() || !subText().isEmpty(); +} + +#include "moc_tooltiparea.cpp" diff --git a/src/declarativeimports/core/tooltiparea.h b/src/declarativeimports/core/tooltiparea.h new file mode 100644 index 0000000..52da295 --- /dev/null +++ b/src/declarativeimports/core/tooltiparea.h @@ -0,0 +1,240 @@ +/* + SPDX-FileCopyrightText: 2011 Marco Martin + SPDX-FileCopyrightText: 2011 Artur Duque de Souza + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#ifndef TOOLTIPOBJECT_H +#define TOOLTIPOBJECT_H + +#include +#include +#include +#include +#include + +class QQuickItem; +class ToolTipDialog; + +/** + * An Item managing a Plasma-themed tooltip. It is rendered in its own window. + * You can either specify icon, mainText and subText, or a custom Component + * that will be put inside the tooltip. By default the tooltip will be + * rendered when hovering over the parent item. + * + * The item inside the ToolTipArea is loaded on demand and will be destroyed when the + * tooltip is being hidden. + * + * Example usage: + * @code + * import org.kde.plasma.core as PlasmaCore + * import org.kde.kirigami 2.20 as Kirigami + * + * Kirigami.Icon { + * PlasmaCore.ToolTipArea { + * mainText: i18n("Tooltip Title") + * subText: i18n("Some explanation.") + * icon: "plasma" + * // alternatively, you can specify your own component + * // to be loaded when the tooltip shows + * mainItem: YourCustomItem { } + * } + * } + * @endcode + * + * Import Statement + * @code import org.kde.plasma.core @endcode + * @version 2.0 + */ +class ToolTipArea : public QQuickItem +{ + Q_OBJECT + QML_ELEMENT + + /** + * The item shown inside the tooltip. + */ + Q_PROPERTY(QQuickItem *mainItem READ mainItem WRITE setMainItem NOTIFY mainItemChanged) + + /** + * The main text of this tooltip + */ + Q_PROPERTY(QString mainText READ mainText WRITE setMainText NOTIFY mainTextChanged) + + /** + * The description of this tooltip + */ + Q_PROPERTY(QString subText READ subText WRITE setSubText NOTIFY subTextChanged) + + /** + * how to handle the text format of the tooltip subtext: + * * Text.AutoText (default) + * * Text.PlainText + * * Text.StyledText + * * Text.RichText + * Note: in the default implementation the main text is always plain text + */ + Q_PROPERTY(int textFormat READ textFormat WRITE setTextFormat NOTIFY textFormatChanged) + + /** + * An icon for this tooltip, accepted values are an icon name, a QIcon, QImage or QPixmap + */ + Q_PROPERTY(QVariant icon READ icon WRITE setIcon NOTIFY iconChanged) + + /** + * Returns whether the mouse is inside the item + */ + Q_PROPERTY(bool containsMouse READ containsMouse NOTIFY containsMouseChanged) + + /** + * Plasma Location of the dialog window. Useful if this dialog is a popup for a panel + */ + Q_PROPERTY(Plasma::Types::Location location READ location WRITE setLocation NOTIFY locationChanged) + + /** + * TODO: single property for images? + * An image for this tooltip, accepted values are an icon name, a QIcon, QImage or QPixmap + */ + Q_PROPERTY(QVariant image READ image WRITE setImage NOTIFY imageChanged) + + /** + * Property that controls if a tooltips will show on mouse over. + * The default is true. + */ + Q_PROPERTY(bool active MEMBER m_active WRITE setActive NOTIFY activeChanged) + + /** + * If interactive is false (default), the tooltip will automatically hide + * itself as soon as the mouse leaves the tooltiparea, if is true, if the + * mouse leaves tooltiparea and goes over the tooltip itself, the tooltip + * won't hide, so it will be possible to interact with tooltip contents. + */ + Q_PROPERTY(bool interactive MEMBER m_interactive WRITE setInteractive NOTIFY interactiveChanged) + + /** + * Timeout in milliseconds after which the tooltip will hide itself. + * Set this value to -1 to never hide the tooltip automatically. + */ + Q_PROPERTY(int timeout MEMBER m_timeout WRITE setTimeout) + +public: + /// @cond INTERNAL_DOCS + explicit ToolTipArea(QQuickItem *parent = nullptr); + ~ToolTipArea() override; + + QQuickItem *mainItem() const; + void setMainItem(QQuickItem *mainItem); + + QString mainText() const; + void setMainText(const QString &mainText); + + QString subText() const; + void setSubText(const QString &subText); + + int textFormat() const; + void setTextFormat(int format); + + QVariant icon() const; + void setIcon(const QVariant &icon); + + QVariant image() const; + void setImage(const QVariant &image); + + Plasma::Types::Location location() const; + void setLocation(Plasma::Types::Location location); + + bool containsMouse() const; + void setContainsMouse(bool contains); + + void setActive(bool active); + + void setInteractive(bool interactive); + + void setTimeout(int timeout); + /// @endcond + +public Q_SLOTS: + + /** + * Shows the tooltip. + * @since 5.73 + */ + void showToolTip(); + + /** + * Hides the tooltip after a grace period if shown. Does not affect whether the tooltip area is active. + */ + void hideToolTip(); + + /** + * Hides the tooltip immediately, in comparison to hideToolTip. + * @since 5.84 + */ + void hideImmediately(); + +protected: + /// @cond INTERNAL_DOCS + bool childMouseEventFilter(QQuickItem *item, QEvent *event) override; + void hoverEnterEvent(QHoverEvent *event) override; + void hoverLeaveEvent(QHoverEvent *event) override; + + ToolTipDialog *tooltipDialogInstance(); + /// @endcond + +Q_SIGNALS: + void mainItemChanged(); + void mainTextChanged(); + void subTextChanged(); + void textFormatChanged(); + void iconChanged(); + void imageChanged(); + void containsMouseChanged(); + void locationChanged(); + void activeChanged(); + void interactiveChanged(); + /** + * Emitted just before the tooltip dialog is shown. + * + * @since 5.45 + */ + void aboutToShow(); + /** + * Emitted when the tooltip's visibility changes. + * + * @since 5.88 + */ + void toolTipVisibleChanged(bool toolTipVisible); + +private Q_SLOTS: + void settingsChanged(const QString &file); + +private: + bool isValid() const; + + void loadSettings(); + bool m_tooltipsEnabledGlobally; + bool m_containsMouse; + Plasma::Types::Location m_location; + QPointer m_mainItem; + QTimer m_showTimer; + QString m_mainText; + QString m_subText; + int m_textFormat; + QVariant m_image; + QVariant m_icon; + bool m_active; + bool m_interactive; + int m_interval; + int m_timeout; + + // ToolTipDialog is not a Q_GLOBAL_STATIC because QQuickwindows as global static + // are deleted too late after some stuff in the qml runtime has already been deleted, + // causing a crash on exit + bool m_usingDialog : 1; + static ToolTipDialog *s_dialog; + static int s_dialogUsers; +}; + +#endif diff --git a/src/declarativeimports/core/tooltipdialog.cpp b/src/declarativeimports/core/tooltipdialog.cpp new file mode 100644 index 0000000..3649705 --- /dev/null +++ b/src/declarativeimports/core/tooltipdialog.cpp @@ -0,0 +1,163 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "tooltipdialog.h" + +#include +#include +#include +#include +#include + +#include +#include + +#include "plasmashellwaylandintegration.h" + +ToolTipDialog::ToolTipDialog() + : PopupPlasmaWindow(QStringLiteral("widgets/tooltip")) + , m_qmlObject(nullptr) + , m_hideTimeout(-1) + , m_interactive(false) + , m_owner(nullptr) +{ + Qt::WindowFlags flags = Qt::WindowDoesNotAcceptFocus | Qt::WindowStaysOnTopHint; + if (KWindowSystem::isPlatformX11()) { + flags |= Qt::ToolTip | Qt::BypassWindowManagerHint; + } else { + flags |= Qt::FramelessWindowHint; + PlasmaShellWaylandIntegration::get(this)->setRole(QtWayland::org_kde_plasma_surface::role_tooltip); + } + setFlags(flags); + + m_hideTimer.setSingleShot(true); + connect(&m_hideTimer, &QTimer::timeout, this, [this]() { + setVisible(false); + }); + + connect(this, &PlasmaQuick::PlasmaWindow::mainItemChanged, this, [this]() { + if (m_lastMainItem) { + disconnect(m_lastMainItem, &QQuickItem::implicitWidthChanged, this, &ToolTipDialog::updateSize); + disconnect(m_lastMainItem, &QQuickItem::implicitHeightChanged, this, &ToolTipDialog::updateSize); + } + m_lastMainItem = mainItem(); + + if (!m_lastMainItem) { + return; + } + connect(m_lastMainItem, &QQuickItem::implicitWidthChanged, this, &ToolTipDialog::updateSize); + connect(m_lastMainItem, &QQuickItem::implicitHeightChanged, this, &ToolTipDialog::updateSize); + updateSize(); + }); +} + +ToolTipDialog::~ToolTipDialog() +{ +} + +void ToolTipDialog::updateSize() +{ + QScreen *s = screen(); + if (!s) { + return; + } + QSize popupSize = QSize(mainItem()->implicitWidth(), mainItem()->implicitHeight()); + popupSize = popupSize.grownBy(padding()); + popupSize = popupSize.boundedTo(s->geometry().size()); + if (!popupSize.isEmpty()) { + resize(popupSize); + } +} + +QQuickItem *ToolTipDialog::loadDefaultItem() +{ + if (!m_qmlObject) { + m_qmlObject = new PlasmaQuick::SharedQmlEngine(this); + } + + if (!m_qmlObject->rootObject()) { + m_qmlObject->setSourceFromModule("org.kde.plasma.core", "DefaultToolTip"); + } + + return qobject_cast(m_qmlObject->rootObject()); +} + +void ToolTipDialog::showEvent(QShowEvent *event) +{ + keepalive(); + + PlasmaQuick::PopupPlasmaWindow::showEvent(event); +} + +void ToolTipDialog::hideEvent(QHideEvent *event) +{ + m_hideTimer.stop(); + PlasmaQuick::PopupPlasmaWindow::hideEvent(event); +} + +bool ToolTipDialog::event(QEvent *e) +{ + if (e->type() == QEvent::Enter) { + if (m_interactive) { + m_hideTimer.stop(); + } + } else if (e->type() == QEvent::Leave) { + dismiss(); + } + + return PopupPlasmaWindow::event(e); +} + +QObject *ToolTipDialog::owner() const +{ + return m_owner; +} + +void ToolTipDialog::setOwner(QObject *owner) +{ + m_owner = owner; +} + +void ToolTipDialog::dismiss() +{ + m_hideTimer.start(200); +} + +void ToolTipDialog::keepalive() +{ + if (m_hideTimeout > 0) { + m_hideTimer.start(m_hideTimeout); + } else { + m_hideTimer.stop(); + } +} + +bool ToolTipDialog::interactive() +{ + return m_interactive; +} + +void ToolTipDialog::setInteractive(bool interactive) +{ + m_interactive = interactive; +} + +void ToolTipDialog::valueChanged(const QVariant &value) +{ + setPosition(value.toPoint()); +} + +void ToolTipDialog::setHideTimeout(int timeout) +{ + m_hideTimeout = timeout; +} + +int ToolTipDialog::hideTimeout() const +{ + return m_hideTimeout; +} + +#include "moc_tooltipdialog.cpp" diff --git a/src/declarativeimports/core/tooltipdialog.h b/src/declarativeimports/core/tooltipdialog.h new file mode 100644 index 0000000..0b976dc --- /dev/null +++ b/src/declarativeimports/core/tooltipdialog.h @@ -0,0 +1,70 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#ifndef TOOLTIPDIALOG_H +#define TOOLTIPDIALOG_H + +#include "popupplasmawindow.h" + +#include +#include +#include + +class QQuickItem; + +namespace PlasmaQuick +{ +class SharedQmlEngine; +} + +/** + * Internally used by Tooltip + */ +class ToolTipDialog : public PlasmaQuick::PopupPlasmaWindow +{ + Q_OBJECT + +public: + explicit ToolTipDialog(); + ~ToolTipDialog() override; + + QQuickItem *loadDefaultItem(); + + void dismiss(); + void keepalive(); + + bool interactive(); + void setInteractive(bool interactive); + + int hideTimeout() const; + void setHideTimeout(int timeout); + + /** + * Basically the last one who has shown the dialog + */ + QObject *owner() const; + void setOwner(QObject *owner); + +protected: + void showEvent(QShowEvent *event) override; + void hideEvent(QHideEvent *event) override; + bool event(QEvent *e) override; + +private Q_SLOTS: + void valueChanged(const QVariant &value); + +private: + void updateSize(); + + QPointer m_lastMainItem; + PlasmaQuick::SharedQmlEngine *m_qmlObject; + QTimer m_hideTimer; + int m_hideTimeout; + bool m_interactive; + QObject *m_owner; +}; + +#endif diff --git a/src/declarativeimports/core/windowthumbnail.cpp b/src/declarativeimports/core/windowthumbnail.cpp new file mode 100644 index 0000000..791217a --- /dev/null +++ b/src/declarativeimports/core/windowthumbnail.cpp @@ -0,0 +1,1014 @@ +/* + SPDX-FileCopyrightText: 2013 Martin Gräßlin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ +#include "windowthumbnail.h" +// KF5 +#include +#include +// Qt +#include +#include +#include +#include +#include +#include +#include + +// X11 +#if HAVE_XCB_COMPOSITE +#include +#if HAVE_GLX +#include +typedef void (*glXBindTexImageEXT_func)(Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list); +typedef void (*glXReleaseTexImageEXT_func)(Display *dpy, GLXDrawable drawable, int buffer); +#include // glx.h could include XLib.h +#endif +#if HAVE_EGL +typedef EGLImageKHR (*eglCreateImageKHR_func)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint *); +typedef EGLBoolean (*eglDestroyImageKHR_func)(EGLDisplay, EGLImageKHR); +typedef GLvoid (*glEGLImageTargetTexture2DOES_func)(GLenum, GLeglImageOES); +#endif // HAVE_EGL +#endif + +#include +#include + +namespace Plasma +{ +class DiscardTextureProviderRunnable : public QRunnable +{ +public: + explicit DiscardTextureProviderRunnable(WindowTextureProvider *provider) + : m_provider(provider) + { + } + + void run() override + { + delete m_provider; + } + +private: + WindowTextureProvider *m_provider; +}; + +#if HAVE_XCB_COMPOSITE + +#if HAVE_GLX +class DiscardGlxPixmapRunnable : public QRunnable +{ +public: + DiscardGlxPixmapRunnable(uint, QFunctionPointer, xcb_pixmap_t); + void run() override; + +private: + uint m_texture; + QFunctionPointer m_releaseTexImage; + xcb_pixmap_t m_glxPixmap; +}; + +DiscardGlxPixmapRunnable::DiscardGlxPixmapRunnable(uint texture, QFunctionPointer deleteFunction, xcb_pixmap_t pixmap) + : QRunnable() + , m_texture(texture) + , m_releaseTexImage(deleteFunction) + , m_glxPixmap(pixmap) +{ +} + +void DiscardGlxPixmapRunnable::run() +{ + if (m_glxPixmap != XCB_PIXMAP_NONE) { + Display *d = qGuiApp->nativeInterface()->display(); + ((glXReleaseTexImageEXT_func)(m_releaseTexImage))(d, m_glxPixmap, GLX_FRONT_LEFT_EXT); + glXDestroyPixmap(d, m_glxPixmap); + glDeleteTextures(1, &m_texture); + } +} +#endif // HAVE_GLX + +#if HAVE_EGL +class DiscardEglPixmapRunnable : public QRunnable +{ +public: + DiscardEglPixmapRunnable(uint, QFunctionPointer, EGLImageKHR); + void run() override; + +private: + uint m_texture; + QFunctionPointer m_eglDestroyImageKHR; + EGLImageKHR m_image; +}; + +DiscardEglPixmapRunnable::DiscardEglPixmapRunnable(uint texture, QFunctionPointer deleteFunction, EGLImageKHR image) + : QRunnable() + , m_texture(texture) + , m_eglDestroyImageKHR(deleteFunction) + , m_image(image) +{ +} + +void DiscardEglPixmapRunnable::run() +{ + if (m_image != EGL_NO_IMAGE_KHR) { + ((eglDestroyImageKHR_func)(m_eglDestroyImageKHR))(eglGetCurrentDisplay(), m_image); + glDeleteTextures(1, &m_texture); + } +} +#endif // HAVE_EGL +#endif // HAVE_XCB_COMPOSITE + +QSGTexture *WindowTextureProvider::texture() const +{ + return m_texture.get(); +} + +void WindowTextureProvider::setTexture(QSGTexture *texture) +{ + m_texture.reset(texture); + Q_EMIT textureChanged(); +} + +#if HAVE_XCB_COMPOSITE +std::optional WindowThumbnail::s_hasPixmapExtension = std::nullopt; +#endif + +WindowThumbnail::WindowThumbnail(QQuickItem *parent) + : QQuickItem(parent) + , QAbstractNativeEventFilter() +{ + setFlag(ItemHasContents); + + if (QGuiApplication *gui = dynamic_cast(QCoreApplication::instance())) { + m_xcb = (gui->platformName() == QLatin1String("xcb")); + if (m_xcb) { + gui->installNativeEventFilter(this); +#if HAVE_XCB_COMPOSITE + xcb_connection_t *c = qGuiApp->nativeInterface()->connection(); + xcb_prefetch_extension_data(c, &xcb_composite_id); + const auto *compositeReply = xcb_get_extension_data(c, &xcb_composite_id); + m_composite = (compositeReply && compositeReply->present); + + xcb_prefetch_extension_data(c, &xcb_damage_id); + const auto *reply = xcb_get_extension_data(c, &xcb_damage_id); + m_damageEventBase = reply->first_event; + if (reply->present) { + xcb_damage_query_version_unchecked(c, XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION); + } +#endif + } + } +} + +WindowThumbnail::~WindowThumbnail() +{ + if (m_xcb) { + QCoreApplication::instance()->removeNativeEventFilter(this); + stopRedirecting(); + } +} + +void WindowThumbnail::itemChange(ItemChange change, const ItemChangeData &data) +{ + switch (change) { + case ItemSceneChange: + if (m_scene) { + disconnect(m_scene.data(), &QWindow::visibleChanged, this, &WindowThumbnail::sceneVisibilityChanged); + } + m_scene = data.window; + if (m_scene) { + connect(m_scene.data(), &QWindow::visibleChanged, this, &WindowThumbnail::sceneVisibilityChanged); + // restart the redirection, it might not have been active yet + stopRedirecting(); + if (startRedirecting()) { + update(); + } + } + break; + + case ItemEnabledHasChanged: + Q_FALLTHROUGH(); + case ItemVisibleHasChanged: + if (data.boolValue) { + if (startRedirecting()) { + update(); + } + } else { + stopRedirecting(); + releaseResources(); + } + break; + + default: + break; + } + + QQuickItem::itemChange(change, data); +} + +void WindowThumbnail::releaseResources() +{ + QQuickWindow::RenderStage m_renderStage = QQuickWindow::NoStage; + if (m_textureProvider) { + window()->scheduleRenderJob(new DiscardTextureProviderRunnable(m_textureProvider), QQuickWindow::AfterSynchronizingStage); + m_textureProvider = nullptr; + } + +#if HAVE_XCB_COMPOSITE + +#if HAVE_GLX && HAVE_EGL + // only one (or none) should be set, but never both + Q_ASSERT(m_glxPixmap == XCB_PIXMAP_NONE || m_image == EGL_NO_IMAGE_KHR); +#endif + + // data is deleted in the render thread (with relevant GLX calls) + // note runnable may be called *after* this is deleted + // but the pointer is held by the WindowThumbnail which is in the main thread +#if HAVE_GLX + if (m_glxPixmap != XCB_PIXMAP_NONE) { + window()->scheduleRenderJob(new DiscardGlxPixmapRunnable(m_texture, m_releaseTexImage, m_glxPixmap), m_renderStage); + + m_glxPixmap = XCB_PIXMAP_NONE; + m_texture = 0; + } +#endif +#if HAVE_EGL + if (m_image != EGL_NO_IMAGE_KHR) { + window()->scheduleRenderJob(new DiscardEglPixmapRunnable(m_texture, m_eglDestroyImageKHR, m_image), m_renderStage); + m_image = EGL_NO_IMAGE_KHR; + m_texture = 0; + } +#endif +#endif +} + +// this method is invoked automagically from the render thread +// but with the GUI thread locked +// +void WindowThumbnail::invalidateSceneGraph() +{ + delete m_textureProvider; + m_textureProvider = nullptr; +#if HAVE_GLX + if (m_glxPixmap != XCB_PIXMAP_NONE) { + // runnable used just to share code with releaseResources, we're already in the render thread + // so run directly + auto runnable = new DiscardGlxPixmapRunnable(m_texture, m_releaseTexImage, m_glxPixmap); + runnable->run(); + m_glxPixmap = XCB_PIXMAP_NONE; + m_texture = 0; + } +#endif +#if HAVE_EGL + if (m_image != EGL_NO_IMAGE_KHR) { + auto runnable = new DiscardEglPixmapRunnable(m_texture, m_eglDestroyImageKHR, m_image); + runnable->run(); + m_image = EGL_NO_IMAGE_KHR; + m_texture = 0; + } +#endif +} + +uint32_t WindowThumbnail::winId() const +{ + return m_winId; +} + +void WindowThumbnail::setWinId(uint32_t winId) +{ + if (m_winId == winId) { + return; + } + if (KWindowSystem::isPlatformX11() && !KX11Extras::self()->hasWId(winId)) { + // invalid Id, don't updated + return; + } + if (window() && winId == window()->winId()) { + // don't redirect to yourself + return; + } + stopRedirecting(); + m_winId = winId; + + if (isEnabled() && isVisible()) { + startRedirecting(); + } + + Q_EMIT winIdChanged(); +} + +void WindowThumbnail::resetWinId() +{ + setWinId(0); +} + +qreal WindowThumbnail::paintedWidth() const +{ + return m_paintedSize.width(); +} + +qreal WindowThumbnail::paintedHeight() const +{ + return m_paintedSize.height(); +} + +bool WindowThumbnail::thumbnailAvailable() const +{ + return m_thumbnailAvailable; +} + +QSGNode *WindowThumbnail::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) +{ + Q_UNUSED(updatePaintNodeData) + + if (!m_textureProvider) { + m_textureProvider = new WindowTextureProvider(); + } + + if (!m_xcb || m_winId == 0 || (window() && window()->winId() == m_winId)) { + iconToTexture(m_textureProvider); + } else { + windowToTexture(m_textureProvider); + } + + QSGImageNode *node = static_cast(oldNode); + if (!node) { + node = window()->createImageNode(); + qsgnode_set_description(node, QStringLiteral("windowthumbnail")); + node->setFiltering(QSGTexture::Linear); + } + + node->setTexture(m_textureProvider->texture()); + const QSizeF size(node->texture()->textureSize().scaled(boundingRect().size().toSize(), Qt::KeepAspectRatio)); + if (size != m_paintedSize) { + m_paintedSize = size; + Q_EMIT paintedSizeChanged(); + } + const qreal x = boundingRect().x() + (boundingRect().width() - size.width()) / 2; + const qreal y = boundingRect().y() + (boundingRect().height() - size.height()) / 2; + node->setRect(QRectF(QPointF(x, y), size)); + return node; +} + +bool WindowThumbnail::nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) +{ + Q_UNUSED(result) + if (!m_xcb || !m_composite || eventType != QByteArrayLiteral("xcb_generic_event_t")) { + // currently we are only interested in XCB events + return false; + } +#if HAVE_XCB_COMPOSITE + xcb_generic_event_t *event = static_cast(message); + const uint8_t responseType = event->response_type & ~0x80; + if (responseType == m_damageEventBase + XCB_DAMAGE_NOTIFY) { + if (reinterpret_cast(event)->drawable == m_winId) { + m_damaged = true; + update(); + } + } else if (responseType == XCB_CONFIGURE_NOTIFY) { + if (reinterpret_cast(event)->window == m_winId) { + releaseResources(); + if (m_pixmap) { + xcb_free_pixmap(qGuiApp->nativeInterface()->connection(), m_pixmap); + m_pixmap = XCB_PIXMAP_NONE; + } + m_damaged = true; + update(); + } + } else if (responseType == XCB_MAP_NOTIFY) { + if (reinterpret_cast(event)->window == m_winId) { + releaseResources(); + m_damaged = true; + update(); + } + } +#else + Q_UNUSED(message) +#endif + // do not filter out any events, there might be further WindowThumbnails for the same window + return false; +} + +void WindowThumbnail::iconToTexture(WindowTextureProvider *textureProvider) +{ + QIcon icon; + if (KWindowSystem::isPlatformX11() && KX11Extras::self()->hasWId(m_winId)) { + icon = KX11Extras::self()->icon(m_winId, boundingRect().width(), boundingRect().height()); + } else { + // fallback to plasma icon + icon = QIcon::fromTheme(QStringLiteral("plasma")); + } + QImage image = icon.pixmap(boundingRect().size().toSize(), window()->devicePixelRatio()).toImage(); + textureProvider->setTexture(window()->createTextureFromImage(image, QQuickWindow::TextureCanUseAtlas)); +} + +#if HAVE_XCB_COMPOSITE +#if HAVE_GLX +bool WindowThumbnail::windowToTextureGLX(WindowTextureProvider *textureProvider) +{ + const auto openglContext = static_cast(window()->rendererInterface()->getResource(window(), QSGRendererInterface::OpenGLContextResource)); + if (openglContext) { + if (!m_openGLFunctionsResolved) { + resolveGLXFunctions(); + } + if (!m_bindTexImage || !m_releaseTexImage) { + return false; + } + if (m_glxPixmap == XCB_PIXMAP_NONE) { + xcb_connection_t *c = qGuiApp->nativeInterface()->connection(); + auto attrCookie = xcb_get_window_attributes_unchecked(c, m_winId); + auto geometryCookie = xcb_get_geometry_unchecked(c, m_pixmap); + QScopedPointer attr(xcb_get_window_attributes_reply(c, attrCookie, nullptr)); + QScopedPointer geo(xcb_get_geometry_reply(c, geometryCookie, nullptr)); + + if (attr.isNull()) { + return false; + } + + if (geo.isNull()) { + return false; + } + + m_depth = geo->depth; + m_visualid = attr->visual; + + if (!loadGLXTexture()) { + return false; + } + + textureProvider->setTexture( + QNativeInterface::QSGOpenGLTexture::fromNative(m_texture, window(), QSize(geo->width, geo->height), QQuickWindow::TextureCanUseAtlas)); + } + openglContext->functions()->glBindTexture(GL_TEXTURE_2D, m_texture); + bindGLXTexture(); + return true; + } + return false; +} +#endif // HAVE_GLX + +#if HAVE_EGL +bool WindowThumbnail::xcbWindowToTextureEGL(WindowTextureProvider *textureProvider) +{ + EGLContext context = eglGetCurrentContext(); + + if (context != EGL_NO_CONTEXT) { + if (!m_eglFunctionsResolved) { + resolveEGLFunctions(); + } + if (QByteArrayView((char *)glGetString(GL_RENDERER)).contains("llvmpipe")) { + return false; + } + if (!m_eglCreateImageKHR || !m_eglDestroyImageKHR || !m_glEGLImageTargetTexture2DOES) { + return false; + } + if (m_image == EGL_NO_IMAGE_KHR) { + xcb_connection_t *c = qGuiApp->nativeInterface()->connection(); + auto geometryCookie = xcb_get_geometry_unchecked(c, m_pixmap); + + const EGLint attribs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; + m_image = ((eglCreateImageKHR_func)(m_eglCreateImageKHR))(eglGetCurrentDisplay(), + EGL_NO_CONTEXT, + EGL_NATIVE_PIXMAP_KHR, + (EGLClientBuffer)(uintptr_t)m_pixmap, + attribs); + + if (m_image == EGL_NO_IMAGE_KHR) { + qDebug() << "failed to create egl image"; + return false; + } + + glGenTextures(1, &m_texture); + QScopedPointer geo(xcb_get_geometry_reply(c, geometryCookie, nullptr)); + QSize size; + if (!geo.isNull()) { + size.setWidth(geo->width); + size.setHeight(geo->height); + } + textureProvider->setTexture(QNativeInterface::QSGOpenGLTexture::fromNative(m_texture, window(), size, QQuickWindow::TextureCanUseAtlas)); + } + auto *openglContext = static_cast(window()->rendererInterface()->getResource(window(), QSGRendererInterface::OpenGLContextResource)); + openglContext->functions()->glBindTexture(GL_TEXTURE_2D, m_texture); + bindEGLTexture(); + return true; + } + return false; +} + +void WindowThumbnail::resolveEGLFunctions() +{ + EGLDisplay display = eglGetCurrentDisplay(); + if (display == EGL_NO_DISPLAY) { + return; + } + auto *context = static_cast(window()->rendererInterface()->getResource(window(), QSGRendererInterface::OpenGLContextResource)); + if (!s_hasPixmapExtension.has_value()) { +#if defined(__clang__) && __clang_major__ < 16 + QByteArray queryResult(eglQueryString(display, EGL_EXTENSIONS)); + auto extensions = queryResult.split(' '); +#else + QByteArrayView queryResult(eglQueryString(display, EGL_EXTENSIONS)); + auto extensions = queryResult | std::views::split(' '); +#endif + auto filter = [](const auto ext) { + return std::ranges::equal(ext, QByteArrayView("EGL_KHR_image")) || std::ranges::equal(ext, QByteArrayView("EGL_KHR_image_base")) + || std::ranges::equal(ext, QByteArrayView("EGL_KHR_image_pixmap")); + }; + s_hasPixmapExtension = std::ranges::any_of(extensions, filter); + } + + if (s_hasPixmapExtension.value()) { + qDebug() << "Have EGL texture from pixmap"; + m_eglCreateImageKHR = context->getProcAddress(QByteArrayLiteral("eglCreateImageKHR")); + m_eglDestroyImageKHR = context->getProcAddress(QByteArrayLiteral("eglDestroyImageKHR")); + m_glEGLImageTargetTexture2DOES = context->getProcAddress(QByteArrayLiteral("glEGLImageTargetTexture2DOES")); + } + m_eglFunctionsResolved = true; +} + +void WindowThumbnail::bindEGLTexture() +{ + ((glEGLImageTargetTexture2DOES_func)(m_glEGLImageTargetTexture2DOES))(GL_TEXTURE_2D, (GLeglImageOES)m_image); + resetDamaged(); +} +#endif // HAVE_EGL + +#endif // HAVE_XCB_COMPOSITE + +void WindowThumbnail::windowToTexture(WindowTextureProvider *textureProvider) +{ + if (!m_damaged && textureProvider->texture()) { + return; + } +#if HAVE_XCB_COMPOSITE + if (m_pixmap == XCB_PIXMAP_NONE) { + m_pixmap = pixmapForWindow(); + } + if (m_pixmap == XCB_PIXMAP_NONE) { + // create above failed + iconToTexture(textureProvider); + setThumbnailAvailable(false); + return; + } + bool fallbackToIcon = true; +#if HAVE_GLX + fallbackToIcon = !windowToTextureGLX(textureProvider); +#endif // HAVE_GLX +#if HAVE_EGL + if (fallbackToIcon) { + // if glx succeeded fallbackToIcon is false, thus we shouldn't try egl + fallbackToIcon = !xcbWindowToTextureEGL(textureProvider); + } +#endif // HAVE_EGL + if (fallbackToIcon) { + // just for safety to not crash + iconToTexture(textureProvider); + } + setThumbnailAvailable(!fallbackToIcon); +#else + iconToTexture(textureProvider); +#endif +} + +#if HAVE_XCB_COMPOSITE +xcb_pixmap_t WindowThumbnail::pixmapForWindow() +{ + if (!m_composite) { + return XCB_PIXMAP_NONE; + } + + xcb_connection_t *c = qGuiApp->nativeInterface()->connection(); + xcb_pixmap_t pix = xcb_generate_id(c); + auto cookie = xcb_composite_name_window_pixmap_checked(c, m_winId, pix); + QScopedPointer error(xcb_request_check(c, cookie)); + if (error) { + return XCB_PIXMAP_NONE; + } + return pix; +} + +#if HAVE_GLX +void WindowThumbnail::resolveGLXFunctions() +{ + auto *context = static_cast(window()->rendererInterface()->getResource(window(), QSGRendererInterface::OpenGLContextResource)); + auto display = qGuiApp->nativeInterface()->display(); + if (!s_hasPixmapExtension.has_value()) { + auto filter = [](const auto ext) { + return std::ranges::equal(ext, QByteArrayView("GLX_EXT_texture_from_pixmap")); + }; +#if defined(__clang__) && __clang_major__ < 16 + QByteArray queryResult(glXQueryExtensionsString(display, DefaultScreen(display))); + QList extensions = queryResult.split(' '); +#else + QByteArrayView queryResult(glXQueryExtensionsString(display, DefaultScreen(display))); + auto extensions = queryResult | std::views::split(' '); +#endif + s_hasPixmapExtension = std::ranges::any_of(extensions, filter); + } + if (s_hasPixmapExtension.value()) { + m_bindTexImage = context->getProcAddress(QByteArrayLiteral("glXBindTexImageEXT")); + m_releaseTexImage = context->getProcAddress(QByteArrayLiteral("glXReleaseTexImageEXT")); + } else { + qWarning() << "couldn't resolve GLX_EXT_texture_from_pixmap functions"; + } + m_openGLFunctionsResolved = true; +} + +void WindowThumbnail::bindGLXTexture() +{ + Display *d = qGuiApp->nativeInterface()->display(); + ((glXReleaseTexImageEXT_func)(m_releaseTexImage))(d, m_glxPixmap, GLX_FRONT_LEFT_EXT); + ((glXBindTexImageEXT_func)(m_bindTexImage))(d, m_glxPixmap, GLX_FRONT_LEFT_EXT, nullptr); + resetDamaged(); +} + +struct FbConfigInfo { + GLXFBConfig fbConfig; + int textureFormat; +}; + +struct GlxGlobalData { + GlxGlobalData() + { + xcb_connection_t *const conn = qGuiApp->nativeInterface()->connection(); + + // Fetch the render pict formats + reply = xcb_render_query_pict_formats_reply(conn, xcb_render_query_pict_formats_unchecked(conn), nullptr); + + // Init the visual ID -> format ID hash table + for (auto screens = xcb_render_query_pict_formats_screens_iterator(reply); screens.rem; xcb_render_pictscreen_next(&screens)) { + for (auto depths = xcb_render_pictscreen_depths_iterator(screens.data); depths.rem; xcb_render_pictdepth_next(&depths)) { + const xcb_render_pictvisual_t *visuals = xcb_render_pictdepth_visuals(depths.data); + const int len = xcb_render_pictdepth_visuals_length(depths.data); + + for (int i = 0; i < len; i++) { + visualPictFormatHash.insert(visuals[i].visual, visuals[i].format); + } + } + } + + // Init the format ID -> xcb_render_directformat_t* hash table + const xcb_render_pictforminfo_t *formats = xcb_render_query_pict_formats_formats(reply); + const int len = xcb_render_query_pict_formats_formats_length(reply); + + for (int i = 0; i < len; i++) { + if (formats[i].type == XCB_RENDER_PICT_TYPE_DIRECT) { + formatInfoHash.insert(formats[i].id, &formats[i].direct); + } + } + + // Init the visual ID -> depth hash table + const xcb_setup_t *setup = xcb_get_setup(conn); + + for (auto screen = xcb_setup_roots_iterator(setup); screen.rem; xcb_screen_next(&screen)) { + for (auto depth = xcb_screen_allowed_depths_iterator(screen.data); depth.rem; xcb_depth_next(&depth)) { + const int len = xcb_depth_visuals_length(depth.data); + const xcb_visualtype_t *visuals = xcb_depth_visuals(depth.data); + + for (int i = 0; i < len; i++) { + visualDepthHash.insert(visuals[i].visual_id, depth.data->depth); + } + } + } + } + + ~GlxGlobalData() + { + qDeleteAll(visualFbConfigHash); + std::free(reply); + } + + xcb_render_query_pict_formats_reply_t *reply; + QHash visualPictFormatHash; + QHash visualDepthHash; + QHash visualFbConfigHash; + QHash formatInfoHash; +}; + +Q_GLOBAL_STATIC(GlxGlobalData, g_glxGlobalData) + +static xcb_render_pictformat_t findPictFormat(xcb_visualid_t visual) +{ + GlxGlobalData *d = g_glxGlobalData; + return d->visualPictFormatHash.value(visual); +} + +static const xcb_render_directformat_t *findPictFormatInfo(xcb_render_pictformat_t format) +{ + GlxGlobalData *d = g_glxGlobalData; + return d->formatInfoHash.value(format); +} + +static int visualDepth(xcb_visualid_t visual) +{ + GlxGlobalData *d = g_glxGlobalData; + return d->visualDepthHash.value(visual); +} + +FbConfigInfo *getConfig(xcb_visualid_t visual) +{ + Display *dpy = qGuiApp->nativeInterface()->display(); + const xcb_render_pictformat_t format = findPictFormat(visual); + const xcb_render_directformat_t *direct = findPictFormatInfo(format); + + if (!direct) { + return nullptr; + } + + const int red_bits = qPopulationCount(direct->red_mask); + const int green_bits = qPopulationCount(direct->green_mask); + const int blue_bits = qPopulationCount(direct->blue_mask); + const int alpha_bits = qPopulationCount(direct->alpha_mask); + + const int depth = visualDepth(visual); + + const auto rgb_sizes = std::tie(red_bits, green_bits, blue_bits); + + const int attribs[] = {GLX_RENDER_TYPE, + GLX_RGBA_BIT, + GLX_DRAWABLE_TYPE, + GLX_WINDOW_BIT | GLX_PIXMAP_BIT, + GLX_X_VISUAL_TYPE, + GLX_TRUE_COLOR, + GLX_X_RENDERABLE, + True, + GLX_CONFIG_CAVEAT, + int(GLX_DONT_CARE), // The ARGB32 visual is marked non-conformant in Catalyst + GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, + int(GLX_DONT_CARE), + GLX_BUFFER_SIZE, + red_bits + green_bits + blue_bits + alpha_bits, + GLX_RED_SIZE, + red_bits, + GLX_GREEN_SIZE, + green_bits, + GLX_BLUE_SIZE, + blue_bits, + GLX_ALPHA_SIZE, + alpha_bits, + GLX_STENCIL_SIZE, + 0, + GLX_DEPTH_SIZE, + 0, + 0}; + + if (QByteArrayView((char *)glGetString(GL_RENDERER)).contains("llvmpipe")) { + return nullptr; + } + + int count = 0; + GLXFBConfig *configs = glXChooseFBConfig(dpy, DefaultScreen(dpy), attribs, &count); + if (count < 1) { + return nullptr; + } + + struct FBConfig { + GLXFBConfig config; + int depth; + int stencil; + int format; + }; + + QList candidates; + + for (int i = 0; i < count; i++) { + int red; + int green; + int blue; + glXGetFBConfigAttrib(dpy, configs[i], GLX_RED_SIZE, &red); + glXGetFBConfigAttrib(dpy, configs[i], GLX_GREEN_SIZE, &green); + glXGetFBConfigAttrib(dpy, configs[i], GLX_BLUE_SIZE, &blue); + + if (std::tie(red, green, blue) != rgb_sizes) { + continue; + } + + xcb_visualid_t visual; + glXGetFBConfigAttrib(dpy, configs[i], GLX_VISUAL_ID, (int *)&visual); + + if (visualDepth(visual) != depth) { + continue; + } + + int bind_rgb; + int bind_rgba; + glXGetFBConfigAttrib(dpy, configs[i], GLX_BIND_TO_TEXTURE_RGBA_EXT, &bind_rgba); + glXGetFBConfigAttrib(dpy, configs[i], GLX_BIND_TO_TEXTURE_RGB_EXT, &bind_rgb); + + if (!bind_rgb && !bind_rgba) { + continue; + } + + int texture_targets; + glXGetFBConfigAttrib(dpy, configs[i], GLX_BIND_TO_TEXTURE_TARGETS_EXT, &texture_targets); + + if ((texture_targets & GLX_TEXTURE_2D_BIT_EXT) == 0) { + continue; + } + + int depth; + int stencil; + glXGetFBConfigAttrib(dpy, configs[i], GLX_DEPTH_SIZE, &depth); + glXGetFBConfigAttrib(dpy, configs[i], GLX_STENCIL_SIZE, &stencil); + + int texture_format; + if (alpha_bits) { + texture_format = bind_rgba ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT; + } else { + texture_format = bind_rgb ? GLX_TEXTURE_FORMAT_RGB_EXT : GLX_TEXTURE_FORMAT_RGBA_EXT; + } + + candidates.append(FBConfig{configs[i], depth, stencil, texture_format}); + } + + XFree(configs); + + std::stable_sort(candidates.begin(), candidates.end(), [](const FBConfig &left, const FBConfig &right) { + if (left.depth < right.depth) { + return true; + } + + if (left.stencil < right.stencil) { + return true; + } + + return false; + }); + + FbConfigInfo *info = nullptr; + + if (!candidates.isEmpty()) { + const FBConfig &candidate = candidates.front(); + + info = new FbConfigInfo; + info->fbConfig = candidate.config; + info->textureFormat = candidate.format; + } + + return info; +} + +bool WindowThumbnail::loadGLXTexture() +{ + GLXContext glxContext = glXGetCurrentContext(); + if (!glxContext) { + return false; + } + + FbConfigInfo *info = nullptr; + + auto &hashTable = g_glxGlobalData->visualFbConfigHash; + auto it = hashTable.constFind(m_visualid); + + if (it != hashTable.constEnd()) { + info = *it; + } else { + info = getConfig(m_visualid); + hashTable.insert(m_visualid, info); + } + + if (!info) { + return false; + } + + glGenTextures(1, &m_texture); + + /* clang-format off */ + const int attrs[] = { + GLX_TEXTURE_FORMAT_EXT, + info->textureFormat, + GLX_MIPMAP_TEXTURE_EXT, + false, + GLX_TEXTURE_TARGET_EXT, + GLX_TEXTURE_2D_EXT, + XCB_NONE}; + /* clang-format on */ + + m_glxPixmap = glXCreatePixmap(qGuiApp->nativeInterface()->display(), info->fbConfig, m_pixmap, attrs); + + return true; +} +#endif + +#endif + +void WindowThumbnail::resetDamaged() +{ + m_damaged = false; +#if HAVE_XCB_COMPOSITE + if (m_damage == XCB_NONE) { + return; + } + xcb_damage_subtract(qGuiApp->nativeInterface()->connection(), m_damage, XCB_NONE, XCB_NONE); +#endif +} + +void WindowThumbnail::stopRedirecting() +{ + if (!m_xcb || !m_composite) { + return; + } +#if HAVE_XCB_COMPOSITE + xcb_connection_t *c = qGuiApp->nativeInterface()->connection(); + if (m_pixmap != XCB_PIXMAP_NONE) { + xcb_free_pixmap(c, m_pixmap); + m_pixmap = XCB_PIXMAP_NONE; + } + if (m_winId == XCB_WINDOW_NONE) { + return; + } + if (m_redirecting) { + xcb_composite_unredirect_window(c, m_winId, XCB_COMPOSITE_REDIRECT_AUTOMATIC); + } + m_redirecting = false; + if (m_damage == XCB_NONE) { + return; + } + xcb_damage_destroy(c, m_damage); + m_damage = XCB_NONE; +#endif +} + +bool WindowThumbnail::startRedirecting() +{ + if (!m_xcb || !m_composite || !window() || !window()->isVisible() || window()->winId() == m_winId || !isEnabled() || !isVisible()) { + return false; + } +#if HAVE_XCB_COMPOSITE + if (m_winId == XCB_WINDOW_NONE) { + return false; + } + xcb_connection_t *c = qGuiApp->nativeInterface()->connection(); + + // need to get the window attributes for the existing event mask + const auto attribsCookie = xcb_get_window_attributes_unchecked(c, m_winId); + + // redirect the window + xcb_composite_redirect_window(c, m_winId, XCB_COMPOSITE_REDIRECT_AUTOMATIC); + m_redirecting = true; + + // generate the damage handle + m_damage = xcb_generate_id(c); + xcb_damage_create(c, m_damage, m_winId, XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY); + + QScopedPointer attr(xcb_get_window_attributes_reply(c, attribsCookie, nullptr)); + uint32_t events = XCB_EVENT_MASK_STRUCTURE_NOTIFY; + if (!attr.isNull()) { + events = events | attr->your_event_mask; + } + // the event mask will not be removed again. We cannot track whether another component also needs STRUCTURE_NOTIFY (e.g. KWindowSystem). + // if we would remove the event mask again, other areas will break. + xcb_change_window_attributes(c, m_winId, XCB_CW_EVENT_MASK, &events); + // force to update the texture + m_damaged = true; + return true; +#else + return false; +#endif +} + +void WindowThumbnail::setThumbnailAvailable(bool thumbnailAvailable) +{ + if (m_thumbnailAvailable != thumbnailAvailable) { + m_thumbnailAvailable = thumbnailAvailable; + Q_EMIT thumbnailAvailableChanged(); + } +} + +void WindowThumbnail::sceneVisibilityChanged(bool visible) +{ + if (visible) { + if (startRedirecting()) { + update(); + } + } else { + stopRedirecting(); + releaseResources(); + } +} + +bool WindowThumbnail::isTextureProvider() const +{ + return true; +} + +QSGTextureProvider *WindowThumbnail::textureProvider() const +{ + // When Item::layer::enabled == true, QQuickItem will be a texture + // provider. In this case we should prefer to return the layer rather + // than our texture + if (QQuickItem::isTextureProvider()) { + return QQuickItem::textureProvider(); + } + + if (!m_textureProvider) { + m_textureProvider = new WindowTextureProvider(); + } + + return m_textureProvider; +} + +} // namespace + +#include "moc_windowthumbnail.cpp" diff --git a/src/declarativeimports/core/windowthumbnail.h b/src/declarativeimports/core/windowthumbnail.h new file mode 100644 index 0000000..0c2e772 --- /dev/null +++ b/src/declarativeimports/core/windowthumbnail.h @@ -0,0 +1,171 @@ +/* + SPDX-FileCopyrightText: 2013 Martin Gräßlin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ +#ifndef PLASMA_WINDOWTHUMBNAIL_H +#define PLASMA_WINDOWTHUMBNAIL_H +#include +#include + +#include + +// Qt +#include +#include +#include +#include +#include +#include +// xcb +#if HAVE_XCB_COMPOSITE +#include + +#if HAVE_EGL +#include +#include +#include // egl.h could include XLib.h + +#endif // HAVE_EGL + +#endif // HAVE_XCB_COMPOSITE +class KWindowInfo; + +namespace Plasma +{ +class WindowTextureProvider; + +/** + * @brief Renders a thumbnail for the window specified by the @c winId property. + * + * This declarative item is able to render a live updating thumbnail for the + * window specified by the given @c winId property. If it is not possible to get + * the thumbnail, the window's icon is rendered instead or in case that the window + * Id is invalid a generic fallback icon is used. + * + * The thumbnail does not necessarily fill out the complete geometry as the + * thumbnail gets scaled keeping the aspect ratio. This means the thumbnail gets + * rendered into the center of the item's geometry. + * + * Note: live updating thumbnails are only implemented on the X11 platform. On X11 + * a running compositor is not required as this item takes care of redirecting the + * window. For technical reasons the window's frame is not included on X11. + * + * If the window closes, the thumbnail does not get destroyed, which allows to have + * a window close animation. + * + * Example usage: + * @code + * WindowThumbnail { + * winId: 102760466 + * } + * @endcode + * + * Import Statement + * @code import org.kde.plasma.core @endcode + * @version 2.0 + */ +class WindowThumbnail : public QQuickItem, public QAbstractNativeEventFilter +{ + Q_OBJECT + QML_ELEMENT + Q_PROPERTY(uint winId READ winId WRITE setWinId RESET resetWinId NOTIFY winIdChanged) + Q_PROPERTY(qreal paintedWidth READ paintedWidth NOTIFY paintedSizeChanged) + Q_PROPERTY(qreal paintedHeight READ paintedHeight NOTIFY paintedSizeChanged) + Q_PROPERTY(bool thumbnailAvailable READ thumbnailAvailable NOTIFY thumbnailAvailableChanged) + +public: + explicit WindowThumbnail(QQuickItem *parent = nullptr); + ~WindowThumbnail() override; + bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override; + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) override; + + uint32_t winId() const; + void setWinId(uint32_t winId); + void resetWinId(); + + qreal paintedWidth() const; + qreal paintedHeight() const; + bool thumbnailAvailable() const; + + bool isTextureProvider() const override; + QSGTextureProvider *textureProvider() const override; + +Q_SIGNALS: + void winIdChanged(); + void paintedSizeChanged(); + void thumbnailAvailableChanged(); + +private Q_SLOTS: + void invalidateSceneGraph(); + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) override; + void releaseResources() override; + +private: + void iconToTexture(WindowTextureProvider *textureProvider); + void windowToTexture(WindowTextureProvider *textureProvider); + bool startRedirecting(); + void stopRedirecting(); + void resetDamaged(); + void setThumbnailAvailable(bool thumbnailAvailable); + void sceneVisibilityChanged(bool visible); + bool m_xcb = false; + bool m_composite = false; + QPointer m_scene; + uint32_t m_winId = 0; + QSizeF m_paintedSize; + bool m_thumbnailAvailable = false; + bool m_redirecting = false; + bool m_damaged = false; + mutable WindowTextureProvider *m_textureProvider = nullptr; +#if HAVE_XCB_COMPOSITE + xcb_pixmap_t pixmapForWindow(); + static std::optional s_hasPixmapExtension; + bool m_openGLFunctionsResolved = false; + uint8_t m_damageEventBase = 0; + xcb_damage_damage_t m_damage = XCB_NONE; + xcb_pixmap_t m_pixmap = XCB_PIXMAP_NONE; + + /*The following must *only* be used from the render thread*/ + uint m_texture; +#if HAVE_GLX + bool windowToTextureGLX(WindowTextureProvider *textureProvider); + void resolveGLXFunctions(); + bool loadGLXTexture(); + void bindGLXTexture(); + int m_depth = 0; + xcb_pixmap_t m_glxPixmap = XCB_PIXMAP_NONE; + xcb_visualid_t m_visualid = XCB_NONE; + QFunctionPointer m_bindTexImage = nullptr; + QFunctionPointer m_releaseTexImage = nullptr; +#endif // HAVE_GLX +#if HAVE_EGL + bool xcbWindowToTextureEGL(WindowTextureProvider *textureProvider); + void resolveEGLFunctions(); + void bindEGLTexture(); + bool m_eglFunctionsResolved = false; + EGLImageKHR m_image = EGL_NO_IMAGE_KHR; + QFunctionPointer m_eglCreateImageKHR = nullptr; + QFunctionPointer m_eglDestroyImageKHR = nullptr; + QFunctionPointer m_glEGLImageTargetTexture2DOES = nullptr; +#endif // HAVE_EGL +#endif +}; + +class WindowTextureProvider : public QSGTextureProvider +{ + Q_OBJECT + +public: + QSGTexture *texture() const override; + void setTexture(QSGTexture *texture); + +private: + std::unique_ptr m_texture; +}; + +} + +#endif // PLASMA_WINDOWTHUMBNAIL_H diff --git a/src/declarativeimports/kirigamiplasmastyle/AbstractApplicationHeader.qml b/src/declarativeimports/kirigamiplasmastyle/AbstractApplicationHeader.qml new file mode 100644 index 0000000..ce68f41 --- /dev/null +++ b/src/declarativeimports/kirigamiplasmastyle/AbstractApplicationHeader.qml @@ -0,0 +1,33 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + SPDY-FileCopyrightText: 2020 Jonah Brüchert + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.kirigami as Kirigami + +import "../../templates" as T +import "../../private" as KirigamiPrivate + +T.AbstractApplicationHeader { + id: root + + Kirigami.Theme.inherit: false + Kirigami.Theme.colorSet: Kirigami.Theme.Header + + background: Rectangle { + color: Kirigami.Theme.backgroundColor + KirigamiPrivate.EdgeShadow { + radius: Kirigami.Units.gridUnit * 0.5 + visible: root.separatorVisible + anchors { + right: parent.right + left: parent.left + top: parent.bottom + } + edge: Qt.TopEdge + } + } +} diff --git a/src/declarativeimports/kirigamiplasmastyle/CMakeLists.txt b/src/declarativeimports/kirigamiplasmastyle/CMakeLists.txt new file mode 100644 index 0000000..cdb1048 --- /dev/null +++ b/src/declarativeimports/kirigamiplasmastyle/CMakeLists.txt @@ -0,0 +1,27 @@ + +add_library(KirigamiPlasmaStyle MODULE ${org.kde.desktop_SRCS}) + +target_sources(KirigamiPlasmaStyle PRIVATE + plugin.cpp + units.cpp + plasmatheme.cpp +) + +target_link_libraries(KirigamiPlasmaStyle + PUBLIC + Qt6::Core + KF6::KirigamiPlatform + PRIVATE + Qt6::Qml + Qt6::Quick + KF6::ConfigWidgets + KF6::IconThemes + Plasma::Plasma +) + +install(TARGETS KirigamiPlasmaStyle DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf6/kirigami/platform) + +install(FILES + AbstractApplicationHeader.qml + DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kirigami/styles/Plasma +) diff --git a/src/declarativeimports/kirigamiplasmastyle/plasmatheme.cpp b/src/declarativeimports/kirigamiplasmastyle/plasmatheme.cpp new file mode 100644 index 0000000..5e45858 --- /dev/null +++ b/src/declarativeimports/kirigamiplasmastyle/plasmatheme.cpp @@ -0,0 +1,151 @@ +/* + SPDX-FileCopyrightText: 2023 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "plasmatheme.h" +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +PlasmaTheme::PlasmaTheme(QObject *parent) + : PlatformTheme(parent) +{ + setSupportsIconColoring(true); + + auto parentItem = qobject_cast(parent); + if (parentItem) { + connect(parentItem, &QQuickItem::enabledChanged, this, &PlasmaTheme::syncColors); + connect(parentItem, &QQuickItem::visibleChanged, this, [this, parentItem] { + if (!parentItem->isVisible()) { + return; + } + syncColors(); + }); + } + + setDefaultFont(qGuiApp->font()); + + KSharedConfigPtr ptr = KSharedConfig::openConfig(); + KConfigGroup general(ptr->group(QStringLiteral("general"))); + + setSmallFont(general.readEntry("smallestReadableFont", []() { + auto smallFont = qApp->font(); +#ifndef Q_OS_WIN + if (smallFont.pixelSize() != -1) { + smallFont.setPixelSize(smallFont.pixelSize() - 2); + } else { + smallFont.setPointSize(smallFont.pointSize() - 2); + } +#endif + return smallFont; + }())); + + syncColors(); + connect(&m_theme, &Plasma::Theme::themeChanged, this, &PlasmaTheme::syncColors); +} + +PlasmaTheme::~PlasmaTheme() +{ +} + +QIcon PlasmaTheme::iconFromTheme(const QString &name, const QColor &customColor) +{ + KIconColors colors(Plasma::Theme::globalPalette()); + KColorScheme colorScheme(QPalette::Active, KColorScheme::Window, Plasma::Theme::globalColorScheme()); + + colors.setPositiveText(colorScheme.foreground(KColorScheme::PositiveText).color().name()); + colors.setNeutralText(colorScheme.foreground(KColorScheme::NeutralText).color().name()); + colors.setNegativeText(colorScheme.foreground(KColorScheme::NegativeText).color().name()); + colors.setActiveText(colorScheme.foreground(KColorScheme::ActiveText).color().name()); + + if (customColor != Qt::transparent) { + colors.setText(customColor); + } + + return KDE::icon(name, colors); +} + +void PlasmaTheme::syncColors() +{ + if (QCoreApplication::closingDown()) { + return; + } + + Plasma::Theme::ColorGroup group; + switch (colorSet()) { + case View: + group = Plasma::Theme::ViewColorGroup; + break; + case Button: + group = Plasma::Theme::ButtonColorGroup; + break; + case Tooltip: + group = Plasma::Theme::ToolTipColorGroup; + break; + case Complementary: + group = Plasma::Theme::ComplementaryColorGroup; + break; + case Header: + group = Plasma::Theme::HeaderColorGroup; + break; + case Selection: // Plasma::Theme doesn't have selection group + case Window: + default: + group = Plasma::Theme::NormalColorGroup; + } + + // foreground + setTextColor(m_theme.color(Plasma::Theme::TextColor, group)); + setDisabledTextColor(m_theme.color(Plasma::Theme::DisabledTextColor, group)); + setHighlightedTextColor(m_theme.color(Plasma::Theme::HighlightedTextColor, group)); + // Plasma::Theme doesn't have ActiveText, use PositiveTextColor + setActiveTextColor(m_theme.color(Plasma::Theme::PositiveTextColor, group)); + setLinkColor(m_theme.color(Plasma::Theme::LinkColor, group)); + setVisitedLinkColor(m_theme.color(Plasma::Theme::VisitedLinkColor, group)); + setNegativeTextColor(m_theme.color(Plasma::Theme::NegativeTextColor, group)); + setNeutralTextColor(m_theme.color(Plasma::Theme::NeutralTextColor, group)); + setPositiveTextColor(m_theme.color(Plasma::Theme::PositiveTextColor, group)); + + // background + setBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group)); + setHighlightColor(m_theme.color(Plasma::Theme::HighlightColor, group)); + // Plasma::Theme doesn't have AlternateBackground + setAlternateBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group)); + + // Plasma::Theme doesn't have any different background color type + setActiveBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group)); + setLinkBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group)); + setVisitedLinkBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group)); + setNegativeBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group)); + setNeutralBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group)); + setPositiveBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group)); + + // decoration + setHoverColor(m_theme.color(Plasma::Theme::HoverColor, group)); + setFocusColor(m_theme.color(Plasma::Theme::FocusColor, group)); +} + +bool PlasmaTheme::event(QEvent *event) +{ + if (event->type() == Kirigami::Platform::PlatformThemeEvents::ColorSetChangedEvent::type) { + syncColors(); + } + + if (event->type() == Kirigami::Platform::PlatformThemeEvents::ColorGroupChangedEvent::type) { + syncColors(); + } + + return PlatformTheme::event(event); +} + +#include "moc_plasmatheme.cpp" diff --git a/src/declarativeimports/kirigamiplasmastyle/plasmatheme.h b/src/declarativeimports/kirigamiplasmastyle/plasmatheme.h new file mode 100644 index 0000000..11874fa --- /dev/null +++ b/src/declarativeimports/kirigamiplasmastyle/plasmatheme.h @@ -0,0 +1,40 @@ +/* + SPDX-FileCopyrightText: 2023 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMATHEME_H +#define PLASMATHEME_H + +#include + +#include +#include +#include +#include +#include +#include + +class KIconLoader; + +class PlasmaTheme : public Kirigami::Platform::PlatformTheme +{ + Q_OBJECT + +public: + explicit PlasmaTheme(QObject *parent = nullptr); + ~PlasmaTheme() override; + + Q_INVOKABLE QIcon iconFromTheme(const QString &name, const QColor &customColor = Qt::transparent) override; + + void syncColors(); + +protected: + bool event(QEvent *event) override; + +private: + Plasma::Theme m_theme; +}; + +#endif // PLASMATHEME_H diff --git a/src/declarativeimports/kirigamiplasmastyle/plugin.cpp b/src/declarativeimports/kirigamiplasmastyle/plugin.cpp new file mode 100644 index 0000000..64540c6 --- /dev/null +++ b/src/declarativeimports/kirigamiplasmastyle/plugin.cpp @@ -0,0 +1,33 @@ +/* + SPDX-FileCopyrightText: 2017 Marco Martin + SPDX-FileCopyrightText: 2021 Arjen Hiemstra + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "plugin.h" +#include "plasmatheme.h" +#include "units.h" + +Plugin::Plugin(QObject *parent) + : Kirigami::Platform::PlatformPluginFactory(parent) +{ +} + +Plugin::~Plugin() = default; + +Kirigami::Platform::PlatformTheme *Plugin::createPlatformTheme(QObject *parent) +{ + Q_UNUSED(parent); + // TODO: Implement a proper C++ version of PlatformTheme. This relies on fallback + // behaviour in Kirigami to load the Theme.qml file. + return new PlasmaTheme(parent); +} + +Kirigami::Platform::Units *Plugin::createUnits(QObject *parent) +{ + Q_ASSERT(parent); + return new Units(parent); +} + +#include "moc_plugin.cpp" diff --git a/src/declarativeimports/kirigamiplasmastyle/plugin.h b/src/declarativeimports/kirigamiplasmastyle/plugin.h new file mode 100644 index 0000000..f51ea4d --- /dev/null +++ b/src/declarativeimports/kirigamiplasmastyle/plugin.h @@ -0,0 +1,30 @@ +/* + SPDX-FileCopyrightText: 2017 Marco Martin + SPDX-FileCopyrightText: 2021 Arjen Hiemstra + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLUGIN_H +#define PLUGIN_H + +#include +#include + +class Plugin : public Kirigami::Platform::PlatformPluginFactory +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID PlatformPluginFactory_iid FILE "plugin.json") + + Q_INTERFACES(Kirigami::Platform::PlatformPluginFactory) + +public: + explicit Plugin(QObject *parent = nullptr); + ~Plugin() override; + + Kirigami::Platform::PlatformTheme *createPlatformTheme(QObject *parent) override; + Kirigami::Platform::Units *createUnits(QObject *parent) override; +}; + +#endif // PLUGIN_H diff --git a/src/declarativeimports/kirigamiplasmastyle/plugin.json b/src/declarativeimports/kirigamiplasmastyle/plugin.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/src/declarativeimports/kirigamiplasmastyle/plugin.json @@ -0,0 +1 @@ +{} diff --git a/src/declarativeimports/kirigamiplasmastyle/units.cpp b/src/declarativeimports/kirigamiplasmastyle/units.cpp new file mode 100644 index 0000000..27e321d --- /dev/null +++ b/src/declarativeimports/kirigamiplasmastyle/units.cpp @@ -0,0 +1,53 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + SPDX-FileCopyrightText: 2014 Sebastian Kügler + SPDX-FileCopyrightText: 2014 David Edmundson + SPDX-FileCopyrightText: 2021 Jonah Brüchert + + SPDX-License-Identifier: LGPL-2.0-or-later + +*/ + +#include "units.h" + +#include +#include + +constexpr int defaultLongDuration = 200; + +Units::Units(QObject *parent) + : Kirigami::Platform::Units(parent) + , m_animationSpeedWatcher(KConfigWatcher::create(KSharedConfig::openConfig())) +{ + connect(m_animationSpeedWatcher.data(), &KConfigWatcher::configChanged, this, [this](const KConfigGroup &group, const QByteArrayList &names) { + if (group.name() == QLatin1String("KDE") && names.contains(QByteArrayLiteral("AnimationDurationFactor"))) { + updateAnimationSpeed(); + } + }); + + updateAnimationSpeed(); +} + +// It'd be nice if we could somehow share this with core/units.cpp +void Units::updateAnimationSpeed() +{ + KConfigGroup generalCfg = KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("KDE")); + const qreal animationSpeedModifier = qMax(0.0, generalCfg.readEntry("AnimationDurationFactor", 1.0)); + + // Read the old longDuration value for compatibility + KConfigGroup cfg = KConfigGroup(KSharedConfig::openConfig(QStringLiteral("plasmarc")), QStringLiteral("Units")); + int longDuration = cfg.readEntry("longDuration", defaultLongDuration); + + longDuration = qRound(longDuration * animationSpeedModifier); + + // Animators with a duration of 0 do not fire reliably + // see Bug 357532 and QTBUG-39766 + longDuration = qMax(1, longDuration); + + setVeryShortDuration(longDuration / 4); + setShortDuration(longDuration / 2); + setLongDuration(longDuration); + setVeryLongDuration(longDuration * 2); +} + +#include "moc_units.cpp" diff --git a/src/declarativeimports/kirigamiplasmastyle/units.h b/src/declarativeimports/kirigamiplasmastyle/units.h new file mode 100644 index 0000000..b0f58db --- /dev/null +++ b/src/declarativeimports/kirigamiplasmastyle/units.h @@ -0,0 +1,29 @@ +/* + SPDX-FileCopyrightText: 2021 Jonah Brüchert + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef KIRIGAMIPLASMADESKTOPUNITS_H +#define KIRIGAMIPLASMADESKTOPUNITS_H + +#include + +#include + +#include + +class Units : public Kirigami::Platform::Units +{ + Q_OBJECT + +public: + explicit Units(QObject *parent = nullptr); + + void updateAnimationSpeed(); + +private: + KConfigWatcher::Ptr m_animationSpeedWatcher; +}; + +#endif diff --git a/src/declarativeimports/plasmacomponents3/AbstractButton.qml b/src/declarativeimports/plasmacomponents3/AbstractButton.qml new file mode 100644 index 0000000..9554893 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/AbstractButton.qml @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick.Templates as T + +T.AbstractButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) +} diff --git a/src/declarativeimports/plasmacomponents3/BusyIndicator.qml b/src/declarativeimports/plasmacomponents3/BusyIndicator.qml new file mode 100644 index 0000000..579bb02 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/BusyIndicator.qml @@ -0,0 +1,109 @@ +/* + SPDX-FileCopyrightText: 2014 Kai Uwe Broulik + SPDX-FileCopyrightText: 2016 Marco Martin + SPDX-FileCopyrightText: 2022 ivan tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore + +T.BusyIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + // BusyIndicator doesn't need padding since it has no background. + // A Control containing a BusyIndicator can have padding instead + // (e.g., a ToolBar, a Page or maybe a widget in a Plasma panel). + padding: 0 + + hoverEnabled: false + + contentItem: Item { + /* Binding on `visible` implicitly takes care of `control.visible`, + * `control.running` and `opacity > 0` at once. + * Also, don't animate at all if the user has disabled animations, + * and don't animate when window is hidden (which somehow does not + * affect items' visibility). + */ + readonly property bool animationShouldBeRunning: + visible + && Window.visibility !== Window.Hidden + && Kirigami.Units.longDuration > 1 + + /* implicitWidth and implicitHeight won't work unless they come + * from a child of the contentItem. No idea why. + */ + implicitWidth: Kirigami.Units.gridUnit * 2 + implicitHeight: Kirigami.Units.gridUnit * 2 + + // We can't bind directly to opacity, as Animator won't update its value immediately. + visible: control.running || opacityAnimator.running + opacity: control.running ? 1 : 0 + Behavior on opacity { + enabled: Kirigami.Units.shortDuration > 0 + OpacityAnimator { + id: opacityAnimator + duration: Kirigami.Units.shortDuration + easing.type: Easing.OutCubic + } + } + + // sync all busy animations so they start at a common place in the rotation + onAnimationShouldBeRunningChanged: startOrStopAnimation(); + + function startOrStopAnimation() { + if (rotationAnimator.running === animationShouldBeRunning) { + return; + } + if (animationShouldBeRunning) { + const date = new Date; + const ms = date.valueOf(); + const startAngle = ((ms % rotationAnimator.duration) / rotationAnimator.duration) * 360; + rotationAnimator.from = startAngle; + rotationAnimator.to = startAngle + 360 + } + rotationAnimator.running = animationShouldBeRunning; + } + + KSvg.SvgItem { + /* Do not use `anchors.fill: parent` in here or else + * the aspect ratio won't always be 1:1. + */ + anchors.centerIn: parent + width: Math.min(parent.width, parent.height) + height: width + + imagePath: "widgets/busywidget" + elementId: "busywidget" + + RotationAnimator on rotation { + id: rotationAnimator + from: 0 + to: 360 + // Not using a standard duration value because we don't want the + // animation to spin faster or slower based on the user's animation + // scaling preferences; it doesn't make sense in this context + duration: 2000 + loops: Animation.Infinite + // Initially false, will be set as appropriate after + // initialization. Can't be bound declaratively due to the + // procedural nature of to/from adjustments: order of + // assignments is crucial, as animator won't use new to/from + // values while running. + running: false + } + } + + Component.onCompleted: startOrStopAnimation(); + } +} diff --git a/src/declarativeimports/plasmacomponents3/Button.qml b/src/declarativeimports/plasmacomponents3/Button.qml new file mode 100644 index 0000000..6c3571b --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/Button.qml @@ -0,0 +1,54 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami +import "private" as Private +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore + +T.Button { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + topPadding: (background as Private.ButtonBackground)?.topMargin ?? undefined + leftPadding: (background as Private.ButtonBackground)?.leftMargin ?? undefined + rightPadding: (background as Private.ButtonBackground)?.rightMargin ?? undefined + bottomPadding: (background as Private.ButtonBackground)?.bottomMargin ?? undefined + + spacing: Kirigami.Units.smallSpacing + + hoverEnabled: !Kirigami.Settings.tabletMode + + Kirigami.MnemonicData.enabled: control.enabled && control.visible + Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.SecondaryControl + Kirigami.MnemonicData.label: control.text + + Shortcut { + //in case of explicit & the button manages it by itself + enabled: !(RegExp(/\&[^\&]/).test(control.text)) + sequence: control.Kirigami.MnemonicData.sequence + onActivated: control.clicked() + } + + Kirigami.Theme.inherit: flat + Kirigami.Theme.colorSet: Kirigami.Theme.Button + + contentItem: Private.ButtonContent { + labelText: control.Kirigami.MnemonicData.richTextLabel + button: control + } + + background: Private.ButtonBackground { + button: control + } +} diff --git a/src/declarativeimports/plasmacomponents3/CheckBox.qml b/src/declarativeimports/plasmacomponents3/CheckBox.qml new file mode 100644 index 0000000..be85b54 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/CheckBox.qml @@ -0,0 +1,68 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + SPDX-FileCopyrightText: 2022 ivan (@ratijas) tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami +import "private" as Private + +T.CheckBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding, + implicitIndicatorWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + baselineOffset: contentItem.y + contentItem.baselineOffset + spacing: Kirigami.Units.smallSpacing + hoverEnabled: true + + // Keeping old default smallMedium size for compatibility + // with UIs that currently expect that as the default size + icon.width: Kirigami.Units.iconSizes.smallMedium + icon.height: Kirigami.Units.iconSizes.smallMedium + + indicator: CheckIndicator { + x: (control.text || control.icon.name || control.icon.source) + ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) + : control.leftPadding + Math.round((control.availableWidth - width) / 2) + y: control.topPadding + Math.round((control.availableHeight - height) / 2) + + control: control + } + + contentItem: Private.IconLabel { + readonly property int effectiveIndicatorWidth: control.indicator && control.indicator.visible && control.indicator.width > 0 + ? control.indicator.width + control.spacing : 0 + + mirrored: control.mirrored + leftPadding: !control.mirrored ? effectiveIndicatorWidth : 0 + rightPadding: control.mirrored ? effectiveIndicatorWidth : 0 + + font: control.font + alignment: Qt.AlignLeft | Qt.AlignVCenter + display: control.display + spacing: control.spacing + iconItem.implicitWidth: control.icon.width + iconItem.implicitHeight: control.icon.height + iconItem.source: control.icon.name || control.icon.source + label.text: control.text + + Rectangle { // As long as we don't enable antialiasing, not rounding should be fine + parent: control.contentItem.label + width: Math.min(parent.width, parent.contentWidth) + height: 1 + anchors.left: parent.left + anchors.top: parent.bottom + color: Kirigami.Theme.highlightColor + visible: control.visualFocus + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/CheckDelegate.qml b/src/declarativeimports/plasmacomponents3/CheckDelegate.qml new file mode 100644 index 0000000..71905a8 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/CheckDelegate.qml @@ -0,0 +1,65 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + SPDX-FileCopyrightText: 2022 ivan (@ratijas) tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami +import org.kde.ksvg as KSvg +import "private" as Private + +T.CheckDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding, + implicitIndicatorWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + baselineOffset: contentItem.y + contentItem.baselineOffset + hoverEnabled: true + + topPadding: (background as KSvg.FrameSvgItem)?.margins.top ?? undefined + leftPadding: (background as KSvg.FrameSvgItem)?.margins.left ?? undefined + rightPadding: (background as KSvg.FrameSvgItem)?.margins.right ?? undefined + bottomPadding: (background as KSvg.FrameSvgItem)?.margins.bottom ?? undefined + + spacing: Kirigami.Units.smallSpacing + + icon.width: Kirigami.Units.iconSizes.sizeForLabels + icon.height: Kirigami.Units.iconSizes.sizeForLabels + + contentItem: Private.IconLabel { + readonly property int effectiveIndicatorWidth: control.indicator && control.indicator.visible && control.indicator.width > 0 + ? control.indicator.width + control.spacing : 0 + + mirrored: control.mirrored + leftPadding: !control.mirrored ? 0 : effectiveIndicatorWidth + rightPadding: control.mirrored ? 0 : effectiveIndicatorWidth + + font: control.font + alignment: Qt.AlignLeft + display: control.display + spacing: control.spacing + iconItem.implicitWidth: control.icon.width + iconItem.implicitHeight: control.icon.height + iconItem.source: control.icon.name || control.icon.source + label.text: control.text + } + + indicator: CheckIndicator { + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + Math.round((control.availableHeight - height) / 2) + + control: control + } + + background: Private.DefaultListItemBackground { + control: control + } +} diff --git a/src/declarativeimports/plasmacomponents3/CheckIndicator.qml b/src/declarativeimports/plasmacomponents3/CheckIndicator.qml new file mode 100644 index 0000000..11e7d2d --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/CheckIndicator.qml @@ -0,0 +1,72 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + SPDX-FileCopyrightText: 2022 ivan (@ratijas) tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T + +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami +import "private" as Private + +KSvg.FrameSvgItem { + id: root + + required property T.AbstractButton control + + imagePath: "widgets/button" + prefix: "normal" + implicitWidth: Kirigami.Units.iconSizes.small + implicitHeight: Kirigami.Units.iconSizes.small + opacity: control.enabled ? 1 : 0.6 + + Private.ButtonShadow { + anchors.fill: parent + showShadow: !control.down + } + + KSvg.SvgItem { + anchors.fill: parent + svg: KSvg.Svg { + id: checkmarkSvg + imagePath: "widgets/checkmarks" + } + elementId: "checkbox" + opacity: { + if (control instanceof T.CheckBox) { + switch (control.checkState) { + case Qt.Checked: + return 1; + case Qt.PartiallyChecked: + return 0.5; + default: + return 0; + } + } else { + return control.checked ? 1 : 0; + } + } + Behavior on opacity { + enabled: Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.InOutQuad + } + } + } + + Private.ButtonFocus { + anchors.fill: parent + showFocus: control.visualFocus && !control.down + } + + Private.ButtonHover { + anchors.fill: parent + showHover: control.hovered + } +} diff --git a/src/declarativeimports/plasmacomponents3/ComboBox.qml b/src/declarativeimports/plasmacomponents3/ComboBox.qml new file mode 100644 index 0000000..6f8a4a5 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/ComboBox.qml @@ -0,0 +1,214 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls as Controls +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami +import "private" as Private +import "mobiletextselection" as MobileTextSelection + +T.ComboBox { + id: control + + property real __indicatorMargin: control.indicator && control.indicator.visible && control.indicator.width > 0 ? control.spacing + indicator.width : 0 + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + baselineOffset: contentItem.y + contentItem.baselineOffset + + hoverEnabled: true + + topPadding: surfaceNormal.margins.top + leftPadding: surfaceNormal.margins.left + (!control.mirrored ? 0 : __indicatorMargin) + rightPadding: surfaceNormal.margins.right + (control.mirrored ? 0 : __indicatorMargin) + bottomPadding: surfaceNormal.margins.bottom + spacing: Kirigami.Units.smallSpacing + + delegate: ItemDelegate { + width: control.popup.width + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData + highlighted: control.highlightedIndex == index + property bool separatorVisible: false + } + + indicator: KSvg.SvgItem { + implicitWidth: Kirigami.Units.iconSizes.small + implicitHeight: implicitWidth + anchors { + right: parent.right + rightMargin: surfaceNormal.margins.right + verticalCenter: parent.verticalCenter + } + svg: KSvg.Svg { + imagePath: "widgets/arrows" + colorSet: KSvg.Svg.Button + } + elementId: "down-arrow" + } + + contentItem: T.TextField { + id: textField + implicitWidth: Math.ceil(contentWidth) + leftPadding + rightPadding + implicitHeight: Math.ceil(contentHeight) + topPadding + bottomPadding + padding: 0 + text: control.editable ? control.editText : control.displayText + + enabled: control.editable + autoScroll: control.editable + + readOnly: control.down || !control.editable + inputMethodHints: control.inputMethodHints + validator: control.validator + color: Kirigami.Theme.textColor + selectionColor: Kirigami.Theme.highlightColor + selectedTextColor: Kirigami.Theme.highlightedTextColor + + selectByMouse: !Kirigami.Settings.tabletMode + cursorDelegate: Kirigami.Settings.tabletMode ? mobileCursor : null + + font: control.font + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + opacity: control.enabled ? 1 : 0.3 + onFocusChanged: { + if (focus) { + MobileTextSelection.MobileTextActionsToolBar.controlRoot = textField; + } + } + + onTextChanged: MobileTextSelection.MobileTextActionsToolBar.shouldBeVisible = false; + onPressed: event => MobileTextSelection.MobileTextActionsToolBar.shouldBeVisible = true; + + onPressAndHold: event => { + if (!Kirigami.Settings.tabletMode) { + return; + } + forceActiveFocus(); + cursorPosition = positionAt(event.x, event.y); + selectWord(); + } + } + + Component { + id: mobileCursor + MobileTextSelection.MobileCursor { + target: textField + } + } + + MobileTextSelection.MobileCursor { + target: textField + selectionStartHandle: true + property var rect: textField.positionToRectangle(textField.selectionStart) + //FIXME: this magic values seem to be always valid, for every font,every dpi, every scaling + x: rect.x + 5 + y: rect.y + 6 + } + + background: KSvg.FrameSvgItem { + id: surfaceNormal + + anchors.fill: parent + + imagePath: control.editable ? "widgets/lineedit" : "widgets/button" + prefix: control.editable + ? "base" + : (control.down ? "pressed" : "normal") + + Private.ButtonShadow { + anchors.fill: parent + showShadow: !control.editable && !control.down + } + + Private.TextFieldFocus { + visible: control.editable + z: -1 + state: control.activeFocus ? "focus" : (control.hovered ? "hover" : "hidden") + anchors.fill: parent + } + + Private.ButtonFocus { + anchors.fill: parent + showFocus: control.activeFocus && !control.down + } + + Private.ButtonHover { + anchors.fill: parent + showHover: control.hovered && !control.down + } + + MouseArea { + anchors { + fill: parent + leftMargin: control.leftPadding + rightMargin: control.rightPadding + } + acceptedButtons: Qt.NoButton + onWheel: wheel => { + if (wheel.pixelDelta.y < 0 || wheel.angleDelta.y < 0) { + control.currentIndex = Math.min(control.currentIndex + 1, delegateModel.count -1); + } else { + control.currentIndex = Math.max(control.currentIndex - 1, 0); + } + control.activated(control.currentIndex); + } + } + } + + popup: T.Popup { + x: control.mirrored ? control.width - width : 0 + y: control.height + width: Math.max(control.width, 150) + implicitHeight: contentItem.implicitHeight + topMargin: 6 + bottomMargin: 6 + + contentItem: ListView { + id: listView + clip: true + implicitHeight: contentHeight + model: control.popup.visible ? control.delegateModel : null + currentIndex: control.highlightedIndex + highlightRangeMode: ListView.ApplyRange + highlightMoveDuration: 0 + // HACK: When the ComboBox is not inside a top-level Window, it's Popup does not inherit + // the LayoutMirroring options. This is a workaround to fix this by enforcing + // the LayoutMirroring options properly. + // QTBUG: https://bugreports.qt.io/browse/QTBUG-66446 + LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft + LayoutMirroring.childrenInherit: true + T.ScrollBar.vertical: Controls.ScrollBar { } + } + background: Kirigami.ShadowedRectangle { + anchors { + fill: parent + margins: -1 + } + radius: 2 + Kirigami.Theme.colorSet: Kirigami.Theme.View + Kirigami.Theme.inherit: false + color: Kirigami.Theme.backgroundColor + border { + color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.3) + width: 1 + } + shadow { + size: 4 + xOffset: 2 + yOffset: 2 + color: Qt.rgba(0, 0, 0, 0.3) + } + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/Container.qml b/src/declarativeimports/plasmacomponents3/Container.qml new file mode 100644 index 0000000..a3b0d8e --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/Container.qml @@ -0,0 +1,17 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T + +T.Container { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + (contentItem ? contentItem.implicitWidth : 0) + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + (contentItem ? contentItem.implicitHeight : 0) + topPadding + bottomPadding) +} diff --git a/src/declarativeimports/plasmacomponents3/Control.qml b/src/declarativeimports/plasmacomponents3/Control.qml new file mode 100644 index 0000000..1194436 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/Control.qml @@ -0,0 +1,17 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T + +T.Control { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) +} diff --git a/src/declarativeimports/plasmacomponents3/Dial.qml b/src/declarativeimports/plasmacomponents3/Dial.qml new file mode 100644 index 0000000..a70f445 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/Dial.qml @@ -0,0 +1,94 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami +import "private" as Private + +T.Dial { + id: control + + implicitWidth: Kirigami.Units.gridUnit * 5 + implicitHeight: implicitWidth + hoverEnabled: true + onPositionChanged: canvas.requestPaint() + + background:Canvas { + id: canvas + width: control.availableWidth + height: control.availableHeight + onPaint: { + var ctx = getContext("2d"); + ctx.reset(); + + var centreX = width / 2; + var centreY = height / 2; + + ctx.globalAlpha = 0.3; + ctx.beginPath(); + ctx.strokeStyle = control.Kirigami.Theme.textColor; + ctx.lineWidth=5; + ctx.arc(centreX, centreY, width/2.4, 0, 2*Math.PI, false); + ctx.stroke(); + ctx.globalAlpha = 1; + + ctx.beginPath(); + ctx.strokeStyle = control.Kirigami.Theme.highlightColor; + ctx.lineWidth=5; + ctx.arc(centreX, centreY, width/2.4, 0.7*Math.PI, 1.6*Math.PI * control.position - 1.25*Math.PI, false); + ctx.stroke(); + } + } + + KSvg.Svg { + id: grooveSvg + imagePath: "widgets/slider" + //FIXME: can this be made not necessary/less hacky? + colorSet: control.Kirigami.Theme.colorSet + } + handle: Item { + x: (control.width/2) + Math.cos((-(control.angle-90)*Math.PI)/180) * (control.width/2-width/2) - width/2 + y: (control.height/2) + Math.sin(((control.angle-90)*Math.PI)/180) * (control.height/2-height/2) - height/2 + + implicitHeight: Math.floor(Kirigami.Units.gridUnit * 1.6) + implicitWidth: implicitHeight + + Private.RoundShadow { + id: roundShadow + anchors.fill: parent + state: { + if (control.pressed) { + return "hidden" + } else if (control.hovered) { + return "hover" + } else if (control.activeFocus) { + return "focus" + } else { + return "shadow" + } + } + } + + KSvg.SvgItem { + svg: KSvg.Svg { + id: buttonSvg + imagePath: "widgets/actionbutton" + } + elementId: control.pressed ? "pressed" : "normal" + width: Math.floor(parent.height/2) * 2 + height: width + anchors.centerIn: parent + Behavior on opacity { + enabled: Kirigami.Units.longDuration > 0 + NumberAnimation { duration: Kirigami.Units.longDuration } + } + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/Dialog.qml b/src/declarativeimports/plasmacomponents3/Dialog.qml new file mode 100644 index 0000000..b203aa8 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/Dialog.qml @@ -0,0 +1,60 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore + +T.Dialog { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentWidth > 0 ? contentWidth + leftPadding + rightPadding : 0) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + contentWidth > 0 ? contentHeight + topPadding + bottomPadding : 0) + + contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0) + contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0) + + topPadding: (background as KSvg.FrameSvgItem)?.margins.top ?? undefined + leftPadding: (background as KSvg.FrameSvgItem)?.margins.left ?? undefined + rightPadding: (background as KSvg.FrameSvgItem)?.margins.right ?? undefined + bottomPadding: (background as KSvg.FrameSvgItem)?.margins.bottom ?? undefined + + enter: Transition { + NumberAnimation { + property: "opacity" + from: 0 + to: 1 + easing.type: Easing.InOutQuad + duration: Kirigami.Units.longDuration + } + } + + exit: Transition { + NumberAnimation { + property: "opacity" + from: 1 + to: 0 + easing.type: Easing.InOutQuad + duration: Kirigami.Units.longDuration + } + } + + contentItem: Item { } + + background: KSvg.FrameSvgItem { + implicitWidth: Kirigami.Units.gridUnit * 12 + imagePath: "widgets/background" + } + + footer: DialogButtonBox { + position: DialogButtonBox.Footer + } +} diff --git a/src/declarativeimports/plasmacomponents3/DialogButtonBox.qml b/src/declarativeimports/plasmacomponents3/DialogButtonBox.qml new file mode 100644 index 0000000..5b2be07 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/DialogButtonBox.qml @@ -0,0 +1,42 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami + +T.DialogButtonBox { + id: control + + implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding + implicitHeight: contentItem.implicitHeight + topPadding + bottomPadding + + spacing: Kirigami.Units.smallSpacing + + topPadding: (parent as T.Control)?.topPadding ?? undefined + leftPadding: (parent as T.Control)?.leftPadding ?? undefined + rightPadding: (parent as T.Control)?.rightPadding ?? undefined + bottomPadding: (parent as T.Control)?.bottomPadding ?? undefined + + alignment: Qt.AlignRight + + delegate: Button { + width: Math.min(implicitWidth, control.width / control.count - control.rightPadding - control.spacing * (control.count-1)) + } + + contentItem: ListView { + implicitWidth: contentWidth + implicitHeight: Kirigami.Units.gridUnit * 1.6 + + model: control.contentModel + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + snapMode: ListView.SnapToItem + } + + background: Item {} +} diff --git a/src/declarativeimports/plasmacomponents3/Drawer.qml b/src/declarativeimports/plasmacomponents3/Drawer.qml new file mode 100644 index 0000000..caeb2bb --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/Drawer.qml @@ -0,0 +1,65 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore + +T.Drawer { + id: control + + parent: T.ApplicationWindow.overlay + + implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding) + + contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0) + contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0) + + topPadding: control.edge === Qt.BottomEdge ? 1 : 0 + leftPadding: control.edge === Qt.RightEdge ? 1 : 0 + rightPadding: control.edge === Qt.LeftEdge ? 1 : 0 + bottomPadding: control.edge === Qt.TopEdge ? 1 : 0 + + background: KSvg.FrameSvgItem { + anchors { + fill: parent + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + implicitWidth: Kirigami.Units.gridUnit * 12 + imagePath: "widgets/background" + enabledBorders: { + switch (control.edge) { + case Qt.BottomEdge: + return KSvg.FrameSvgItem.TopBorder; + case Qt.RightEdge: + return KSvg.FrameSvgItem.LeftBorder; + case Qt.TopEdge: + return KSvg.FrameSvgItem.BottomBorder; + case Qt.LeftEdge: + default: + return KSvg.FrameSvgItem.RightBorder; + } + } + } + + enter: Transition { + SmoothedAnimation { + velocity: 5 + } + } + exit: Transition { + SmoothedAnimation { + velocity: 5 + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/Frame.qml b/src/declarativeimports/plasmacomponents3/Frame.qml new file mode 100644 index 0000000..33063ef --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/Frame.qml @@ -0,0 +1,30 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore + +T.Frame { + id: control + + implicitWidth: contentWidth + leftPadding + rightPadding + implicitHeight: contentHeight + topPadding + bottomPadding + + contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0) + contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0) + + padding: Kirigami.Units.smallSpacing + + background: KSvg.FrameSvgItem { + imagePath: "widgets/frame" + prefix: "plain" + } +} diff --git a/src/declarativeimports/plasmacomponents3/GroupBox.qml b/src/declarativeimports/plasmacomponents3/GroupBox.qml new file mode 100644 index 0000000..4f14911 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/GroupBox.qml @@ -0,0 +1,43 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.plasma.components as PlasmaComponents3 + +T.GroupBox { + id: control + + implicitWidth: contentWidth + leftPadding + rightPadding + implicitHeight: contentHeight + topPadding + bottomPadding + + contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0) + contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0) + + padding: 6 + topPadding: padding + (label && label.implicitWidth > 0 ? label.implicitHeight + spacing : 0) + + label: PlasmaComponents3.Label { + x: control.leftPadding + width: control.availableWidth + + text: control.title + font: control.font + enabled: control.enabled + elide: Text.ElideRight + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + } + + background: KSvg.FrameSvgItem { + imagePath: "widgets/frame" + prefix: "plain" + } +} diff --git a/src/declarativeimports/plasmacomponents3/ItemDelegate.qml b/src/declarativeimports/plasmacomponents3/ItemDelegate.qml new file mode 100644 index 0000000..5e85d4b --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/ItemDelegate.qml @@ -0,0 +1,52 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + SPDX-FileCopyrightText: 2022-2024 ivan (@ratijas) tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami +import org.kde.ksvg as KSvg +import "private" as Private + +T.ItemDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding, + implicitIndicatorWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + baselineOffset: contentItem.y + contentItem.baselineOffset + hoverEnabled: true + + topPadding: (background as KSvg.FrameSvgItem)?.margins.top ?? undefined + leftPadding: (background as KSvg.FrameSvgItem)?.margins.left ?? undefined + rightPadding: (background as KSvg.FrameSvgItem)?.margins.right ?? undefined + bottomPadding: (background as KSvg.FrameSvgItem)?.margins.bottom ?? undefined + + spacing: Kirigami.Units.smallSpacing + + icon.width: Kirigami.Units.iconSizes.sizeForLabels + icon.height: Kirigami.Units.iconSizes.sizeForLabels + + contentItem: Private.IconLabel { + mirrored: control.mirrored + font: control.font + alignment: Qt.AlignLeft + display: control.display + spacing: control.spacing + iconItem.implicitWidth: control.icon.width + iconItem.implicitHeight: control.icon.height + iconItem.source: control.icon.name || control.icon.source + label.text: control.text + } + + background: Private.DefaultListItemBackground { + control: control + } +} diff --git a/src/declarativeimports/plasmacomponents3/Label.qml b/src/declarativeimports/plasmacomponents3/Label.qml new file mode 100644 index 0000000..dff0209 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/Label.qml @@ -0,0 +1,29 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami + +T.Label { + id: control + + // Work around Qt bug where left aligned text is not right aligned + // in RTL mode unless horizontalAlignment is explicitly set. + // https://bugreports.qt.io/browse/QTBUG-95873 + horizontalAlignment: Text.AlignLeft + + activeFocusOnTab: false + + //font data is the system one by default + color: Kirigami.Theme.textColor + linkColor: Kirigami.Theme.linkColor + + opacity: enabled ? 1 : 0.6 + + Accessible.role: Accessible.StaticText + Accessible.name: text +} diff --git a/src/declarativeimports/plasmacomponents3/Menu.qml b/src/declarativeimports/plasmacomponents3/Menu.qml new file mode 100644 index 0000000..12c308e --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/Menu.qml @@ -0,0 +1,97 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami + +T.Menu { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem ? contentItem.implicitWidth + leftPadding + rightPadding : 0) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + contentItem ? contentItem.implicitHeight : 0) + topPadding + bottomPadding + + delegate: MenuItem { width: parent.width; onImplicitWidthChanged: control.contentItem.contentItem.childrenChanged() } + + margins: 0 + + topPadding: (background as KSvg.FrameSvgItem)?.margins.top ?? undefined + leftPadding: (background as KSvg.FrameSvgItem)?.margins.left ?? undefined + rightPadding: (background as KSvg.FrameSvgItem)?.margins.right ?? undefined + bottomPadding: (background as KSvg.FrameSvgItem)?.margins.bottom ?? undefined + + contentItem: ListView { + implicitHeight: contentHeight + property bool hasCheckables: false + property bool hasIcons: false + model: control.contentModel + + implicitWidth: { + var maxWidth = 0; + for (var i = 0; i < contentItem.children.length; ++i) { + maxWidth = Math.max(maxWidth, contentItem.children[i].implicitWidth); + } + return maxWidth; + } + + interactive: Window.window ? contentHeight + control.topPadding + control.bottomPadding > Window.window.height : false + clip: true + currentIndex: control.currentIndex || 0 + keyNavigationEnabled: true + keyNavigationWraps: true + + T.ScrollBar.vertical: ScrollBar {} + } + + Connections { + target: control.contentItem.contentItem + + function onChildrenChanged() { + for (var i in control.contentItem.contentItem.children) { + var child = control.contentItem.contentItem.children[i]; + if (child.checkable) { + control.contentItem.hasCheckables = true; + } + if (child.icon && child.icon.hasOwnProperty("name") && (child.icon.name.length > 0 || child.icon.source.length > 0)) { + control.contentItem.hasIcons = true; + } + } + } + } + + enter: Transition { + NumberAnimation { + property: "opacity" + from: 0 + to: 1 + easing.type: Easing.InOutQuad + duration: Kirigami.Units.shortDuration + } + } + + exit: Transition { + NumberAnimation { + property: "opacity" + from: 1 + to: 0 + easing.type: Easing.InOutQuad + duration: Kirigami.Units.shortDuration + } + } + + background: KSvg.FrameSvgItem { + imagePath: "widgets/background" + implicitWidth: Kirigami.Units.gridUnit * 8 + implicitHeight: Kirigami.Units.gridUnit * 2 + } +} diff --git a/src/declarativeimports/plasmacomponents3/MenuItem.qml b/src/declarativeimports/plasmacomponents3/MenuItem.qml new file mode 100644 index 0000000..5391484 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/MenuItem.qml @@ -0,0 +1,126 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami + +T.MenuItem { + id: controlRoot + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + leftPadding + rightPadding + (arrow ? arrow.implicitWidth : 0)) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(contentItem.implicitHeight, + indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + baselineOffset: contentItem.y + contentItem.baselineOffset + + leftPadding: highlight.margins.left + topPadding: highlight.margins.top + rightPadding: highlight.margins.right + bottomPadding: highlight.margins.bottom + spacing: Kirigami.Units.smallSpacing + hoverEnabled: true + + Kirigami.MnemonicData.enabled: controlRoot.enabled && controlRoot.visible + Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.MenuItem + Kirigami.MnemonicData.label: controlRoot.text + Shortcut { + //in case of explicit & the button manages it by itself + enabled: !(RegExp(/\&[^\&]/).test(controlRoot.text)) + sequence: controlRoot.Kirigami.MnemonicData.sequence + onActivated: { + if (controlRoot.checkable) { + controlRoot.toggle(); + } else { + controlRoot.clicked(); + } + } + } + + contentItem: RowLayout { + Item { + Layout.preferredWidth: (controlRoot.ListView.view && controlRoot.ListView.view.hasCheckables) || controlRoot.checkable ? controlRoot.indicator.width : Kirigami.Units.smallSpacing + } + Kirigami.Icon { + Layout.alignment: Qt.AlignVCenter + visible: (controlRoot.ListView.view && controlRoot.ListView.view.hasIcons) || (controlRoot.icon != undefined && (controlRoot.icon.name.length > 0 || controlRoot.icon.source.length > 0)) + source: controlRoot.icon ? (controlRoot.icon.name || controlRoot.icon.source) : "" + Layout.preferredHeight: Math.max(label.height, Kirigami.Units.iconSizes.small) + Layout.preferredWidth: Layout.preferredHeight + } + Label { + id: label + Layout.alignment: Qt.AlignVCenter + Layout.fillWidth: true + + text: controlRoot.Kirigami.MnemonicData.richTextLabel + font: controlRoot.font + elide: Text.ElideRight + visible: controlRoot.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + } + } + + arrow: Kirigami.Icon { + x: controlRoot.mirrored ? controlRoot.padding : controlRoot.width - width - controlRoot.padding + y: controlRoot.topPadding + (controlRoot.availableHeight - height) / 2 + source: controlRoot.mirrored ? "go-next-symbolic-rtl" : "go-next-symbolic" + width: Math.max(label.height, Kirigami.Units.iconSizes.small) + height: width + visible: controlRoot.subMenu + } + + indicator: Loader { + x: controlRoot.mirrored ? controlRoot.width - width - controlRoot.rightPadding : controlRoot.leftPadding + y: controlRoot.topPadding + Math.round((controlRoot.availableHeight - height) / 2) + + visible: controlRoot.checkable + sourceComponent: controlRoot.autoExclusive ? radioComponent : checkComponent + } + + Component { + id: radioComponent + RadioIndicator { + control: controlRoot + } + } + Component { + id: checkComponent + CheckIndicator { + control: controlRoot + } + } + + background: Item { + implicitWidth: Kirigami.Units.gridUnit * 8 + + KSvg.FrameSvgItem { + id: highlight + imagePath: "widgets/viewitem" + prefix: "hover" + anchors.fill: parent + opacity: { + if (controlRoot.highlighted || controlRoot.hovered || controlRoot.down) { + return 1 + } else { + return 0 + } + } + Behavior on opacity { + enabled: Kirigami.Units.shortDuration > 0 + NumberAnimation { + duration: Kirigami.Units.shortDuration + } + } + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/MenuSeparator.qml b/src/declarativeimports/plasmacomponents3/MenuSeparator.qml new file mode 100644 index 0000000..81f31fb --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/MenuSeparator.qml @@ -0,0 +1,30 @@ +/* + SPDX-FileCopyrightText: 2017 The Qt Company Ltd. + SPDX-FileCopyrightText: 2019 Alexander Stippich + SPDX-FileCopyrightText: 2021 Noah Davis + + SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-or-later +*/ + + +import QtQuick +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami + +T.MenuSeparator { + id: controlRoot + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + verticalPadding: Math.round(Kirigami.Units.smallSpacing / 2) + hoverEnabled: false + focusPolicy: Qt.NoFocus + contentItem: Rectangle { + // same as MenuItem background + implicitWidth: Kirigami.Units.gridUnit * 8 + implicitHeight: 1 + color: Kirigami.Theme.textColor + opacity: 0.2 + } +} diff --git a/src/declarativeimports/plasmacomponents3/Page.qml b/src/declarativeimports/plasmacomponents3/Page.qml new file mode 100644 index 0000000..5b1527e --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/Page.qml @@ -0,0 +1,19 @@ +/* + SPDX-FileCopyrightText: 2020 Niccolò Venerandi + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T + +T.Page { + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) +} diff --git a/src/declarativeimports/plasmacomponents3/PageIndicator.qml b/src/declarativeimports/plasmacomponents3/PageIndicator.qml new file mode 100644 index 0000000..dd1a32f --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/PageIndicator.qml @@ -0,0 +1,46 @@ +/* + SPDX-FileCopyrightText: 2018 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami + +T.PageIndicator { + id: control + + implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding + implicitHeight: contentItem.implicitHeight + topPadding + bottomPadding + + padding: Kirigami.Units.smallSpacing + spacing: Kirigami.Units.smallSpacing + + delegate: Rectangle { + implicitWidth: Kirigami.Units.largeSpacing + implicitHeight: implicitWidth + + radius: width + color: Kirigami.Theme.textColor + + opacity: index === currentIndex ? 0.9 : pressed ? 0.7 : 0.5 + Behavior on opacity { + enabled: Kirigami.Units.longDuration > 0 + OpacityAnimator { + duration: Kirigami.Units.longDuration + easing.type: Easing.InOutQuad + } + } + } + + contentItem: Row { + spacing: control.spacing + + Repeater { + model: control.count + delegate: control.delegate + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/Pane.qml b/src/declarativeimports/plasmacomponents3/Pane.qml new file mode 100644 index 0000000..40822eb --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/Pane.qml @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ + +import QtQuick.Templates as T + +T.Pane { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + //TODO: Add background? +} diff --git a/src/declarativeimports/plasmacomponents3/Popup.qml b/src/declarativeimports/plasmacomponents3/Popup.qml new file mode 100644 index 0000000..196542c --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/Popup.qml @@ -0,0 +1,56 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami + +T.Popup { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentWidth > 0 ? contentWidth + leftPadding + rightPadding : 0) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + contentWidth > 0 ? contentHeight + topPadding + bottomPadding : 0) + + contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0) + contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0) + + topPadding: (background as KSvg.FrameSvgItem)?.margins.top ?? undefined + leftPadding: (background as KSvg.FrameSvgItem)?.margins.left ?? undefined + rightPadding: (background as KSvg.FrameSvgItem)?.margins.right ?? undefined + bottomPadding: (background as KSvg.FrameSvgItem)?.margins.bottom ?? undefined + + enter: Transition { + NumberAnimation { + property: "opacity" + from: 0 + to: 1 + easing.type: Easing.InOutQuad + duration: Kirigami.Units.longDuration + } + } + + exit: Transition { + NumberAnimation { + property: "opacity" + from: 1 + to: 0 + easing.type: Easing.InOutQuad + duration: Kirigami.Units.longDuration + } + } + + contentItem: Item { } + + background: KSvg.FrameSvgItem { + implicitWidth: Kirigami.Units.gridUnit * 12 + imagePath: "widgets/background" + } +} diff --git a/src/declarativeimports/plasmacomponents3/ProgressBar.qml b/src/declarativeimports/plasmacomponents3/ProgressBar.qml new file mode 100644 index 0000000..20cc462 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/ProgressBar.qml @@ -0,0 +1,88 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami + +T.ProgressBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + hoverEnabled: false + + KSvg.Svg { + id: barSvg + imagePath: "widgets/bar_meter_horizontal" + // FIXME + colorSet: control.Kirigami.Theme.colorSet + } + + contentItem: Item { + implicitWidth: Kirigami.Units.gridUnit * 8 + implicitHeight: children[0].height + + KSvg.FrameSvgItem { + readonly property real indeterminateWidth: Math.round(control.availableWidth / 4) + property real indeterminateProgress: 0 + + imagePath: "widgets/bar_meter_horizontal" + prefix: "bar-active" + + LayoutMirroring.enabled: control.mirrored + anchors.left: parent.left + anchors.leftMargin: control.indeterminate ? indeterminateProgress * (control.availableWidth - indeterminateWidth) : 0 + anchors.verticalCenter: parent.verticalCenter + + // unlike Slider, this width is allowed to be less than its minimum (margins) size, in which case it would not render at all. + width: control.indeterminate ? indeterminateWidth : Math.round(control.position * control.availableWidth) + height: barSvg.hasElement("hint-bar-size") + ? barSvg.elementSize("hint-bar-size").height + : fixedMargins.top + fixedMargins.bottom + + visible: width >= fixedMargins.left + fixedMargins.right + + SequentialAnimation on indeterminateProgress { + loops: Animation.Infinite + running: control.indeterminate && control.contentItem.visible + + NumberAnimation { + duration: Kirigami.Units.humanMoment / 2 + easing.type: Easing.InOutSine + to: 1 + } + NumberAnimation { + duration: Kirigami.Units.humanMoment / 2 + easing.type: Easing.InOutSine + to: 0 + } + } + } + } + + background: Item { + implicitWidth: Kirigami.Units.gridUnit * 8 + implicitHeight: children[0].height + + KSvg.FrameSvgItem { + imagePath: "widgets/bar_meter_horizontal" + prefix: "bar-inactive" + + anchors.centerIn: parent + width: Math.max(parent.width, fixedMargins.left + fixedMargins.right) + height: barSvg.hasElement("hint-bar-size") + ? barSvg.elementSize("hint-bar-size").height + : fixedMargins.top + fixedMargins.bottom + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/README.md b/src/declarativeimports/plasmacomponents3/README.md new file mode 100644 index 0000000..34733c0 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/README.md @@ -0,0 +1,7 @@ +Plasma Components 3 is a style for QtQuick Controls 2. + +It is exported as an import so users can force a theme, but it is also available just as a style. + +This folder should only contain inherited templates from QQC2 desktop themes. There should be no new Components or properties. + +New API should be in either upstream QQC2 itself, PlasmaExtras, or Kirigami. diff --git a/src/declarativeimports/plasmacomponents3/RadioButton.qml b/src/declarativeimports/plasmacomponents3/RadioButton.qml new file mode 100644 index 0000000..9926635 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/RadioButton.qml @@ -0,0 +1,68 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + SPDX-FileCopyrightText: 2022 ivan (@ratijas) tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami +import "private" as Private + +T.RadioButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding, + implicitIndicatorWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + baselineOffset: contentItem.y + contentItem.baselineOffset + spacing: Kirigami.Units.smallSpacing + hoverEnabled: true + + icon.width: Kirigami.Units.iconSizes.sizeForLabels + icon.height: Kirigami.Units.iconSizes.sizeForLabels + + indicator: RadioIndicator { + x: (control.text || control.icon.name || control.icon.source) + ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) + : control.leftPadding + Math.round((control.availableWidth - width) / 2) + y: control.topPadding + Math.round((control.availableHeight - height) / 2) + + control: control + } + + contentItem: Private.IconLabel { + id: contentLabel + + readonly property int effectiveIndicatorWidth: control.indicator && control.indicator.visible && control.indicator.width > 0 + ? control.indicator.width + control.spacing : 0 + + mirrored: control.mirrored + leftPadding: !control.mirrored ? effectiveIndicatorWidth : 0 + rightPadding: control.mirrored ? effectiveIndicatorWidth : 0 + + font: control.font + alignment: Qt.AlignLeft | Qt.AlignVCenter + display: control.display + spacing: control.spacing + iconItem.implicitWidth: control.icon.width + iconItem.implicitHeight: control.icon.height + iconItem.source: control.icon.name || control.icon.source + label.text: control.text + + Rectangle { // As long as we don't enable antialiasing, not rounding should be fine + parent: contentLabel.label + width: Math.min(parent.width, contentLabel.label.contentWidth) + height: 1 + anchors.left: parent.left + anchors.top: parent.bottom + color: Kirigami.Theme.highlightColor + visible: control.visualFocus + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/RadioDelegate.qml b/src/declarativeimports/plasmacomponents3/RadioDelegate.qml new file mode 100644 index 0000000..adaa72c --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/RadioDelegate.qml @@ -0,0 +1,65 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + SPDX-FileCopyrightText: 2022 ivan (@ratijas) tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami +import org.kde.ksvg as KSvg +import "private" as Private + +T.RadioDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding, + implicitIndicatorWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + baselineOffset: contentItem.y + contentItem.baselineOffset + hoverEnabled: true + + topPadding: (background as KSvg.FrameSvgItem)?.margins.top ?? undefined + leftPadding: (background as KSvg.FrameSvgItem)?.margins.left ?? undefined + rightPadding: (background as KSvg.FrameSvgItem)?.margins.right ?? undefined + bottomPadding: (background as KSvg.FrameSvgItem)?.margins.bottom ?? undefined + + spacing: Kirigami.Units.smallSpacing + + icon.width: Kirigami.Units.iconSizes.sizeForLabels + icon.height: Kirigami.Units.iconSizes.sizeForLabels + + contentItem: Private.IconLabel { + readonly property int effectiveIndicatorWidth: control.indicator && control.indicator.visible && control.indicator.width > 0 + ? control.indicator.width + control.spacing : 0 + + mirrored: control.mirrored + leftPadding: !control.mirrored ? 0 : effectiveIndicatorWidth + rightPadding: control.mirrored ? 0 : effectiveIndicatorWidth + + font: control.font + alignment: Qt.AlignLeft + display: control.display + spacing: control.spacing + iconItem.implicitWidth: control.icon.width + iconItem.implicitHeight: control.icon.height + iconItem.source: control.icon.name || control.icon.source + label.text: control.text + } + + indicator: RadioIndicator { + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + Math.round((control.availableHeight - height) / 2) + + control: control + } + + background: Private.DefaultListItemBackground { + control: control + } +} diff --git a/src/declarativeimports/plasmacomponents3/RadioIndicator.qml b/src/declarativeimports/plasmacomponents3/RadioIndicator.qml new file mode 100644 index 0000000..252a124 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/RadioIndicator.qml @@ -0,0 +1,183 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + SPDX-FileCopyrightText: 2022 ivan (@ratijas) tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami +import "private" as P + +Item { + id: root + + required property T.AbstractButton control + + property size hintSize: radioButtonSvg.fromCurrentImageSet && radioButtonSvg.hasElement("hint-size") + ? radioButtonSvg.elementSize("hint-size") + : Qt.size(Kirigami.Units.iconSizes.small, Kirigami.Units.iconSizes.small) + + implicitWidth: hintSize.width + implicitHeight: hintSize.height + opacity: control.enabled ? 1 : 0.5 + layer.enabled: opacity < 1 + + KSvg.Svg { + id: radioButtonSvg + imagePath: "widgets/radiobutton" + } + + Loader { + anchors.fill: parent + sourceComponent: radioButtonSvg.fromCurrentImageSet + // Hardcode breeze-light and breeze-dark because fromCurrentImageSet is + // false for them. This is because they don't contain any SVGs and + // inherit all of them from the default theme. + || KSvg.ImageSet.imageSetName === "breeze-light" + || KSvg.ImageSet.imageSetName === "breeze-dark" + ? radiobuttonComponent : compatibilityComponent + } + + // Uses newer radiobutton.svg + Component { + id: radiobuttonComponent + KSvg.SvgItem { + svg: radioButtonSvg + elementId: "normal" + anchors.centerIn: parent + implicitWidth: naturalSize.width + implicitHeight: naturalSize.height + KSvg.SvgItem { + z: -1 + svg: radioButtonSvg + elementId: "shadow" + anchors.centerIn: parent + implicitWidth: naturalSize.width + implicitHeight: naturalSize.height + visible: opacity > 0 + opacity: enabled && !root.control.down + Behavior on opacity { + enabled: root.control.down && Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.OutCubic + } + } + } + KSvg.SvgItem { + svg: radioButtonSvg + elementId: "checked" + anchors.centerIn: parent + implicitWidth: naturalSize.width + implicitHeight: naturalSize.height + visible: opacity > 0 + opacity: (root.control.checked || root.control.down) + && !(root.control instanceof T.ItemDelegate && root.control.highlighted) + Behavior on opacity { + enabled: (root.control.checked || root.control.down) && Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.OutCubic + } + } + } + KSvg.SvgItem { + svg: radioButtonSvg + elementId: "focus" + anchors.centerIn: parent + implicitWidth: naturalSize.width + implicitHeight: naturalSize.height + visible: opacity > 0 + opacity: root.control.visualFocus + Behavior on opacity { + enabled: Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.OutCubic + } + } + } + KSvg.SvgItem { + svg: radioButtonSvg + elementId: "hover" + anchors.centerIn: parent + implicitWidth: naturalSize.width + implicitHeight: naturalSize.height + visible: opacity > 0 + opacity: root.control.hovered + Behavior on opacity { + enabled: root.control.hovered && Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.OutCubic + } + } + } + KSvg.SvgItem { + svg: radioButtonSvg + elementId: "symbol" + anchors.centerIn: parent + implicitWidth: naturalSize.width + implicitHeight: naturalSize.height + visible: scale > 0 + scale: root.control.checked + Behavior on scale { + enabled: Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.OutCubic + } + } + } + } + } + + // Uses older combination of actionbutton.svg and checkmarks.svg. + // NOTE: Do not touch this except to fix bugs. This is for compatibility. + Component { + id: compatibilityComponent + KSvg.SvgItem { + svg: KSvg.Svg { + id: buttonSvg + imagePath: "widgets/actionbutton" + } + elementId: "normal" + + anchors.centerIn: parent + implicitWidth: implicitHeight + implicitHeight: Kirigami.Units.iconSizes.small + + KSvg.SvgItem { + id: checkmark + svg: KSvg.Svg { + id: checkmarksSvg + imagePath: "widgets/checkmarks" + } + elementId: "radiobutton" + opacity: root.control.checked ? 1 : 0 + anchors { + fill: parent + } + Behavior on opacity { + enabled: Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.InOutQuad + } + } + } + P.RoundShadow { + anchors.fill: parent + z: -1 + state: root.control.activeFocus ? "focus" : (root.control.hovered ? "hover" : "shadow") + } + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/RangeSlider.qml b/src/declarativeimports/plasmacomponents3/RangeSlider.qml new file mode 100644 index 0000000..dd00aa4 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/RangeSlider.qml @@ -0,0 +1,100 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami +import "private" as Private + +T.RangeSlider { + id: control + + implicitWidth: control.orientation === Qt.Horizontal ? Kirigami.Units.gridUnit * 12 : Kirigami.Units.gridUnit * 1.6 + implicitHeight: control.orientation === Qt.Horizontal ? Kirigami.Units.gridUnit * 1.6 : Kirigami.Units.gridUnit * 12 + + KSvg.Svg { + id: grooveSvg + imagePath: "widgets/slider" + // FIXME + colorSet: control.Kirigami.Theme.colorSet + } + first.handle: Item { + property bool horizontal: control.orientation === Qt.Horizontal + x: Math.round(control.leftPadding + (horizontal ? control.first.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2)) + y: Math.round(control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.first.visualPosition * (control.availableHeight - height))) + + width: grooveSvg.hasElement("hint-handle-size") ? grooveSvg.elementSize("hint-handle-size").width : firstHandle.width + height: grooveSvg.hasElement("hint-handle-size") ? grooveSvg.elementSize("hint-handle-size").height : firstHandle.height + + Private.RoundShadow { + anchors.fill: firstHandle + imagePath: "widgets/slider" + focusElement: parent.horizontal ? "horizontal-slider-focus" : "vertical-slider-focus" + hoverElement: parent.horizontal ? "horizontal-slider-hover" : "vertical-slider-hover" + shadowElement: parent.horizontal ? "horizontal-slider-shadow" : "vertical-slider-shadow" + state: control.activeFocus ? "focus" : (control.hovered ? "hover" : "shadow") + } + KSvg.SvgItem { + id: firstHandle + anchors.centerIn: parent + width: naturalSize.width + height: naturalSize.height + svg: grooveSvg + elementId: parent.horizontal ? "horizontal-slider-handle" : "vertical-slider-handle" + } + } + + second.handle: Item { + property bool horizontal: control.orientation === Qt.Horizontal + x: control.leftPadding + (horizontal ? control.second.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.second.visualPosition * (control.availableHeight - height)) + + width: grooveSvg.hasElement("hint-handle-size") ? grooveSvg.elementSize("hint-handle-size").width : secondHandle.width + height: grooveSvg.hasElement("hint-handle-size") ? grooveSvg.elementSize("hint-handle-size").height : secondHandle.height + + Private.RoundShadow { + anchors.fill: secondHandle + imagePath: "widgets/slider" + focusElement: parent.horizontal ? "horizontal-slider-focus" : "vertical-slider-focus" + hoverElement: parent.horizontal ? "horizontal-slider-hover" : "vertical-slider-hover" + shadowElement: parent.horizontal ? "horizontal-slider-shadow" : "vertical-slider-shadow" + state: control.activeFocus ? "focus" : (control.hovered ? "hover" : "shadow") + } + KSvg.SvgItem { + id: secondHandle + anchors.centerIn: parent + width: naturalSize.width + height: naturalSize.height + svg: grooveSvg + elementId: parent.horizontal ? "horizontal-slider-handle" : "vertical-slider-handle" + } + } + + background: KSvg.FrameSvgItem { + imagePath: "widgets/slider" + prefix: "groove" + readonly property bool horizontal: control.orientation === Qt.Horizontal + implicitWidth: horizontal ? Kirigami.Units.gridUnit * 8 : margins.left + margins.right + implicitHeight: horizontal ? margins.top + margins.bottom : Kirigami.Units.gridUnit * 8 + width: horizontal ? control.availableWidth : implicitWidth + height: horizontal ? implicitHeight : control.availableHeight + anchors.centerIn: parent + scale: horizontal && control.mirrored ? -1 : 1 + opacity: control.enabled ? 1 : 0.6 + + KSvg.FrameSvgItem { + imagePath: "widgets/slider" + prefix: "groove-highlight" + x: parent.horizontal ? control.first.position * parent.width : 0 + y: parent.horizontal ? 0 : control.second.visualPosition * parent.height + width: parent.horizontal ? control.second.position * parent.width - control.first.position * parent.width : parent.width + height: parent.horizontal ? parent.height : control.second.position * parent.height - control.first.position * parent.height + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/RoundButton.qml b/src/declarativeimports/plasmacomponents3/RoundButton.qml new file mode 100644 index 0000000..bf54358 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/RoundButton.qml @@ -0,0 +1,152 @@ +/* + SPDX-FileCopyrightText: 2018 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami +import "private" as Private + +T.RoundButton { + id: control + + Accessible.role: Accessible.Button + + implicitWidth: Math.max(Kirigami.Units.gridUnit, contentItem.implicitWidth) + + leftPadding + rightPadding + implicitHeight: Math.max(Kirigami.Units.gridUnit, contentItem.implicitHeight) + + topPadding + bottomPadding + + leftPadding: text.length > 0 ? surfaceNormal.margins.left : contentItem.extraSpace + topPadding: text.length > 0 ? surfaceNormal.margins.top : contentItem.extraSpace + rightPadding: text.length > 0 ? surfaceNormal.margins.right : contentItem.extraSpace + bottomPadding: text.length > 0 ? surfaceNormal.margins.bottom : contentItem.extraSpace + + hoverEnabled: !Kirigami.Settings.tabletMode + + Kirigami.Theme.colorSet: Kirigami.Theme.Button + Kirigami.Theme.inherit: false + + contentItem: RowLayout { + // This is the spacing which will make the icon a square inscribed in the circle with an extra smallspacing of margins + readonly property int extraSpace: implicitWidth / 2 - implicitWidth / 2 * Math.sqrt(2) / 2 + Kirigami.Units.smallSpacing + Kirigami.Icon { + Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium + Layout.preferredHeight: Kirigami.Units.iconSizes.smallMedium + Layout.fillWidth: true + Layout.fillHeight: true + visible: source.length > 0 + source: control.icon ? (control.icon.name || control.icon.source) : "" + } + Label { + visible: text.length > 0 + text: control.text + font: control.font + opacity: enabled || control.highlighted || control.checked ? 1 : 0.4 + color: Kirigami.Theme.textColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + } + + background: Item { + id: backgroundItem + + opacity: control.enabled ? 1 : 0.6 + + // Round Button + + KSvg.Svg { + id: buttonSvg + imagePath: "widgets/actionbutton" + colorSet: KSvg.Svg.Button + } + + Private.RoundShadow { + id: roundShadow + visible: !control.flat || control.activeFocus || control.highlighted + anchors.fill: parent + state: { + if (control.down) { + return "hidden" + } else if (control.hovered) { + return "hover" + } else if (control.activeFocus || control.highlighted) { + return "focus" + } else { + return "shadow" + } + } + } + + KSvg.SvgItem { + id: buttonItem + svg: buttonSvg + elementId: (control.down || control.checked) ? "pressed" : "normal" + anchors.fill: parent + //internal: if there is no hover status, don't paint on mouse over in touchscreens + opacity: (control.down || control.checked || !control.flat || (roundShadow.hasOverState && control.hovered)) ? 1 : 0 + Behavior on opacity { + enabled: Kirigami.Units.longDuration > 0 + PropertyAnimation { duration: Kirigami.Units.longDuration } + } + } + + // Normal Button + // TODO: Make round button always round? + + readonly property bool useNormalButton: control.text.length > 0 + + Private.ButtonShadow { + anchors.fill: parent + showShadow: backgroundItem.useNormalButton && !control.flat && (!control.down || !control.checked) + } + + KSvg.FrameSvgItem { + id: surfaceNormal + anchors.fill: parent + imagePath: "widgets/button" + prefix: "normal" + opacity: backgroundItem.useNormalButton && (!control.flat || control.hovered) && (!control.down || !control.checked) ? 1 : 0 + Behavior on opacity { + enabled: Kirigami.Units.longDuration > 0 + OpacityAnimator { + duration: Kirigami.Units.longDuration + easing.type: Easing.InOutQuad + } + } + } + + Private.ButtonFocus { + anchors.fill: parent + showFocus: backgroundItem.useNormalButton && control.activeFocus && !control.down + } + + Private.ButtonHover { + anchors.fill: parent + showHover: backgroundItem.useNormalButton && control.hovered && !control.down + } + + KSvg.FrameSvgItem { + anchors.fill: parent + imagePath: "widgets/button" + prefix: "pressed" + visible: backgroundItem.useNormalButton + opacity: control.checked || control.down ? 1 : 0 + Behavior on opacity { + enabled: Kirigami.Units.longDuration > 0 + OpacityAnimator { + duration: Kirigami.Units.longDuration + easing.type: Easing.InOutQuad + } + } + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/ScrollBar.qml b/src/declarativeimports/plasmacomponents3/ScrollBar.qml new file mode 100644 index 0000000..c13d78a --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/ScrollBar.qml @@ -0,0 +1,113 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami + +T.ScrollBar { + id: controlRoot + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + hoverEnabled: interactive + + visible: (size > 0 && size < 1 && policy === T.ScrollBar.AsNeeded) || policy === T.ScrollBar.AlwaysOn + minimumSize: horizontal ? height / width : width / height + + // Working around weird default values for `margins` (== `fixedMargins`) and `inset` (== -1) + // TODO KF6: Use 0 as the default value for inset and margins + leftPadding: scrollbarSvg.hasElement(`${handle.usedPrefix}-hint-left-inset`) ? handle.inset.left : horizontalPadding + rightPadding: scrollbarSvg.hasElement(`${handle.usedPrefix}-hint-right-inset`) ? handle.inset.right : horizontalPadding + topPadding: scrollbarSvg.hasElement(`${handle.usedPrefix}-hint-top-inset`) ? handle.inset.top : verticalPadding + bottomPadding: scrollbarSvg.hasElement(`${handle.usedPrefix}-hint-bottom-inset`) ? handle.inset.bottom : verticalPadding + leftInset: scrollbarSvg.hasElement(`${bgFrame.usedPrefix}-hint-left-inset`) ? bgFrame.inset.left : 0 + rightInset: scrollbarSvg.hasElement(`${bgFrame.usedPrefix}-hint-right-inset`) ? bgFrame.inset.right : 0 + topInset: scrollbarSvg.hasElement(`${bgFrame.usedPrefix}-hint-top-inset`) ? bgFrame.inset.top : 0 + bottomInset: scrollbarSvg.hasElement(`${bgFrame.usedPrefix}-hint-bottom-inset`) ? bgFrame.inset.bottom : 0 + + Rectangle { + id: separator + anchors.left: parent.left + width: controlRoot.horizontal ? parent.width : undefined + height: controlRoot.vertical ? parent.height : undefined + // I'm wary of adding things that could be considered official features + // of the theming system willy-nilly, so this hint is marked private. + // Technically, there's nothing stopping theme authors from using this + // anyway, but I don't want to have to support it long term until we're + // sure we want this. + visible: scrollbarSvg.hasElement("private-hint-show-separator") + && controlRoot.interactive + && (controlRoot.mirrored ? controlRoot.rightInset > 0 : controlRoot.leftInset > 0) + implicitWidth: 1 + implicitHeight: implicitWidth + color: Kirigami.Theme.textColor + opacity: 0.1 + } + + background: KSvg.FrameSvgItem { + id: bgFrame + implicitWidth: Math.max(scrollbarSvg.elementSize("hint-scrollbar-size").width, fixedMargins.left + fixedMargins.right) + implicitHeight: Math.max(scrollbarSvg.elementSize("hint-scrollbar-size").height, fixedMargins.top + fixedMargins.bottom) + imagePath:"widgets/scrollbar" + prefix: controlRoot.horizontal ? "background-horizontal" : "background-vertical" + opacity: controlRoot.hovered && controlRoot.interactive + visible: opacity > 0 + Behavior on opacity { + enabled: Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.OutCubic + } + } + + TapHandler { + id: tapHandler + acceptedButtons: Qt.MiddleButton + acceptedDevices: PointerDevice.Stylus + gesturePolicy: TapHandler.ReleaseWithinBounds // Exclusive Grab + grabPermissions: PointerHandler.ApprovesTakeOverByAnything // But not that exclusive in case any pointer handler outside wants the exclusive grab + target: null + } + + Connections { // Whenever the position changes, tapHandler.pressed only needs checking once using Connections.enabled + enabled: tapHandler.pressed + target: tapHandler + function onPointChanged() { + controlRoot.position = Math.min(1 - controlRoot.size, Math.max(0, + (controlRoot.horizontal + ? tapHandler.point.position.x / bgFrame.width + : tapHandler.point.position.y / bgFrame.height + ) - controlRoot.size / 2 + )); + } + } + } + + contentItem: KSvg.FrameSvgItem { + id: handle + imagePath:"widgets/scrollbar" + implicitWidth: Math.max(scrollbarSvg.elementSize("hint-scrollbar-size").width, fixedMargins.left + fixedMargins.right) + implicitHeight: Math.max(scrollbarSvg.elementSize("hint-scrollbar-size").height, fixedMargins.top + fixedMargins.bottom) + prefix: controlRoot.interactive && (controlRoot.pressed || controlRoot.hovered) && controlRoot.enabled ? "mouseover-slider" : "slider" + opacity: enabled ? 1 : 0.5 + } + + KSvg.Svg { + id: scrollbarSvg + imagePath: "widgets/scrollbar" + //TODO: support arrows? + property bool arrowPresent: scrollbarSvg.hasElement("arrow-up") + //new theme may be different + onRepaintNeeded: arrowPresent = scrollbarSvg.hasElement("arrow-up") + } +} diff --git a/src/declarativeimports/plasmacomponents3/ScrollView.qml b/src/declarativeimports/plasmacomponents3/ScrollView.qml new file mode 100644 index 0000000..d1948f5 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/ScrollView.qml @@ -0,0 +1,60 @@ +/* + SPDX-FileCopyrightText: 2017 Marco Martin + SPDX-FileCopyrightText: 2017 The Qt Company Ltd. + + SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-or-later +*/ + + +import QtQuick +import QtQuick.Templates as T +import QtQml + +import org.kde.kirigami as Kirigami +import org.kde.plasma.components as PlasmaComponents3 + +T.ScrollView { + id: controlRoot + + clip: true + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + leftPadding: mirrored && T.ScrollBar.vertical.visible && !Kirigami.Settings.isMobile ? T.ScrollBar.vertical.width : 0 + rightPadding: !mirrored && T.ScrollBar.vertical.visible && !Kirigami.Settings.isMobile ? T.ScrollBar.vertical.width : 0 + bottomPadding: T.ScrollBar.horizontal.visible && !Kirigami.Settings.isMobile ? T.ScrollBar.horizontal.height : 0 + + data: [ + Kirigami.WheelHandler { + target: controlRoot.contentItem + // `Qt.styleHints.wheelScrollLines * 20` is the default scroll speed. + horizontalStepSize: Qt.styleHints.wheelScrollLines * 20 + verticalStepSize: Qt.styleHints.wheelScrollLines * 20 + }, + Binding { // TODO KF6: remove, Qt6 has this behavior by default + target: controlRoot.contentItem // always instanceof Flickable + property: 'clip' + value: true + restoreMode: Binding.RestoreBindingOrValue + } + ] + + T.ScrollBar.vertical: PlasmaComponents3.ScrollBar { + parent: controlRoot + x: controlRoot.mirrored ? 0 : controlRoot.width - width + y: controlRoot.topPadding + height: controlRoot.availableHeight + active: controlRoot.T.ScrollBar.horizontal.active + } + + T.ScrollBar.horizontal: PlasmaComponents3.ScrollBar { + parent: controlRoot + x: controlRoot.leftPadding + y: controlRoot.height - height + width: controlRoot.availableWidth + active: controlRoot.T.ScrollBar.vertical.active + } +} diff --git a/src/declarativeimports/plasmacomponents3/Slider.qml b/src/declarativeimports/plasmacomponents3/Slider.qml new file mode 100644 index 0000000..05dc461 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/Slider.qml @@ -0,0 +1,190 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + SPDX-FileCopyrightText: 2022 ivan (@ratijas) tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami +import "private" as P + +T.Slider { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitHandleWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitHandleHeight + topPadding + bottomPadding) + + snapMode: T.Slider.SnapOnRelease + hoverEnabled: true + + layer.enabled: opacity < 1 + opacity: control.enabled ? 1 : 0.5 + + KSvg.Svg { + id: sliderSvg + imagePath: "widgets/slider" + // FIXME + colorSet: control.Kirigami.Theme.colorSet + } + + // `wheelEnabled: true` doesn't work since it doesn't snap to tickmarks, + // so we have to implement the scroll handling ourselves. See + // https://bugreports.qt.io/browse/QTBUG-93081 + MouseArea { + property int wheelDelta: 0 + + anchors { + fill: parent + leftMargin: control.leftPadding + rightMargin: control.rightPadding + } + LayoutMirroring.enabled: false + + acceptedButtons: Qt.NoButton + + onWheel: wheel => { + const lastValue = control.value + // We want a positive delta to increase the slider for up/right scrolling, + // independently of the scrolling inversion setting + // The x-axis is also inverted (scrolling right produce negative values) + const delta = (wheel.angleDelta.y || -wheel.angleDelta.x) * (wheel.inverted ? -1 : 1) + wheelDelta += delta; + // magic number 120 for common "one click" + // See: https://doc.qt.io/qt-5/qml-qtquick-wheelevent.html#angleDelta-prop + while (wheelDelta >= 120) { + wheelDelta -= 120; + control.increase(); + } + while (wheelDelta <= -120) { + wheelDelta += 120; + control.decrease(); + } + if (lastValue !== control.value) { + control.moved(); + } + } + } + + handle: Item { + x: Math.round(control.leftPadding + (horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2)) + y: Math.round(control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height))) + + implicitWidth: sliderSvg.hasElement("hint-handle-size") ? sliderSvg.elementSize("hint-handle-size").width : firstHandle.implicitWidth + implicitHeight: sliderSvg.hasElement("hint-handle-size") ? sliderSvg.elementSize("hint-handle-size").height : firstHandle.implicitHeight + + KSvg.SvgItem { + id: shadow + z: -1 + anchors.centerIn: parent + implicitWidth: naturalSize.width + implicitHeight: naturalSize.height + svg: sliderSvg + elementId: control.horizontal ? "horizontal-slider-shadow" : "vertical-slider-shadow" + visible: enabled && !control.pressed + } + KSvg.SvgItem { + id: firstHandle + anchors.centerIn: parent + implicitWidth: naturalSize.width + implicitHeight: naturalSize.height + svg: sliderSvg + elementId: control.horizontal ? "horizontal-slider-handle" : "vertical-slider-handle" + } + KSvg.SvgItem { + anchors.centerIn: parent + implicitWidth: naturalSize.width + implicitHeight: naturalSize.height + svg: sliderSvg + elementId: control.horizontal ? "horizontal-slider-focus" : "vertical-slider-focus" + visible: opacity > 0 + opacity: control.visualFocus + Behavior on opacity { + enabled: Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.OutCubic + } + } + } + KSvg.SvgItem { + anchors.centerIn: parent + implicitWidth: naturalSize.width + implicitHeight: naturalSize.height + svg: sliderSvg + elementId: control.horizontal ? "horizontal-slider-hover" : "vertical-slider-hover" + visible: opacity > 0 + opacity: control.hovered + Behavior on opacity { + enabled: control.hovered && Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.OutCubic + } + } + } + } + + background: KSvg.FrameSvgItem { + imagePath: "widgets/slider" + prefix: "groove" + implicitWidth: control.horizontal ? Kirigami.Units.gridUnit * 12 : fixedMargins.left + fixedMargins.right + implicitHeight: control.vertical ? Kirigami.Units.gridUnit * 12 : fixedMargins.top + fixedMargins.bottom + + width: control.horizontal ? Math.max(fixedMargins.left + fixedMargins.right, control.availableWidth) : implicitWidth + height: control.vertical ? Math.max(fixedMargins.top + fixedMargins.bottom, control.availableHeight) : implicitHeight + x: control.leftPadding + (control.horizontal ? 0 : Math.round((control.availableWidth - width) / 2)) + y: control.topPadding + (control.vertical ? 0 : Math.round((control.availableHeight - height) / 2)) + + KSvg.FrameSvgItem { + id: grooveFill + imagePath: "widgets/slider" + prefix: "groove-highlight" + + LayoutMirroring.enabled: control.mirrored + anchors.left: parent.left + anchors.bottom: parent.bottom + // The general idea is to extend the groove at least up to the middle of a handle, but don't overextend it at the end. + width: control.horizontal ? Math.max(fixedMargins.left + fixedMargins.right, Math.round(control.position * (control.availableWidth - control.handle.width / 2) + (control.handle.width / 2))) : parent.width + height: control.vertical ? Math.max(fixedMargins.top + fixedMargins.bottom, Math.round(control.position * (control.availableHeight - control.handle.height / 2) + (control.handle.height / 2))) : parent.height + } + + Loader { + id: tickLoader + readonly property int stepCount: (control.to - control.from) / control.stepSize + visible: stepCount > 0 && stepCount <= 20 + active: visible + anchors { + left: control.horizontal ? parent.left : parent.right + top: control.vertical ? parent.top : parent.bottom + leftMargin: control.horizontal ? Math.round(control.handle.width / 2) : 1 + topMargin: control.vertical ? Math.round(control.handle.height / 2) : 1 + } + width: control.horizontal ? parent.width - control.handle.width : control.background.x + height: control.vertical ? parent.height - control.handle.height : control.background.y + sourceComponent: Grid { + anchors.fill: parent + rows: control.vertical ? tickLoader.stepCount + 1 : 1 + columns: control.horizontal ? tickLoader.stepCount + 1 : 1 + spacing: (control.vertical ? height : width - (tickLoader.stepCount + 1)) / tickLoader.stepCount + LayoutMirroring.enabled: control.mirrored + Repeater { + model: tickLoader.stepCount + 1 + delegate: Rectangle { + property bool withinFill: (control.horizontal ? index : stepCount - index) <= control.position * tickLoader.stepCount + width: control.vertical ? parent.width : 1 + height: control.horizontal ? parent.height : 1 + opacity: withinFill ? 1 : 0.3 + color: withinFill ? Kirigami.Theme.highlightColor : Kirigami.Theme.textColor + } + } + } + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/SpinBox.qml b/src/declarativeimports/plasmacomponents3/SpinBox.qml new file mode 100644 index 0000000..e4f827d --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/SpinBox.qml @@ -0,0 +1,229 @@ +/* + * SPDX-FileCopyrightText: 2017 Marco Martin + * SPDX-FileCopyrightText: 2020 Nate Graham + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ + +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.plasma.components as PlasmaComponents3 +import org.kde.kirigami as Kirigami +import "private" as P + +T.SpinBox { + id: control + + implicitWidth: Math.max( + implicitBackgroundWidth + leftInset + rightInset, + Math.max(implicitContentWidth, Kirigami.Units.gridUnit) + + spacing * 2 + leftPadding + rightPadding, + up.implicitIndicatorWidth + down.implicitIndicatorWidth + ) + implicitHeight: Math.max( + implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + up.implicitIndicatorHeight, + down.implicitIndicatorHeight + ) + + leftPadding: !mirrored ? down.implicitIndicatorWidth : up.implicitIndicatorWidth + rightPadding: mirrored ? down.implicitIndicatorWidth : up.implicitIndicatorWidth + topPadding: bgLoader.topMargin + bottomPadding: bgLoader.bottomMargin + spacing: bgLoader.leftMargin + editable: true + inputMethodHints: Qt.ImhFormattedNumbersOnly + validator: IntValidator { + locale: control.locale.name + bottom: Math.min(control.from, control.to) + top: Math.max(control.from, control.to) + } + wheelEnabled: true + hoverEnabled: Qt.styleHints.useHoverEffects + + KSvg.Svg { + id: lineSvg + imagePath: "widgets/line" + } + + up.indicator: P.FlatButtonBackground { + x: control.mirrored ? 0 : parent.width - width + implicitHeight: Kirigami.Units.gridUnit + bgLoader.topMargin + bgLoader.bottomMargin + implicitWidth: Kirigami.Units.gridUnit + bgLoader.leftMargin + bgLoader.rightMargin + height: parent.height + hovered: control.up.hovered + pressed: control.up.pressed + focused: false + checked: false + Kirigami.Icon { + anchors.centerIn: parent + implicitWidth: Kirigami.Units.iconSizes.sizeForLabels + implicitHeight: Kirigami.Units.iconSizes.sizeForLabels + source: "spinbox-increase" + fallback: "list-add" + } + KSvg.SvgItem { + x: control.mirrored ? parent.width - width : 0 + z: -1 + anchors { + top: parent.top + bottom: parent.bottom + topMargin: bgLoader.topMargin + bottomMargin: bgLoader.bottomMargin + } + implicitWidth: naturalSize.width + implicitHeight: implicitWidth + elementId: "vertical-line" + svg: lineSvg + } + } + + down.indicator: P.FlatButtonBackground { + x: control.mirrored ? parent.width - width : 0 + implicitHeight: Kirigami.Units.gridUnit + bgLoader.topMargin + bgLoader.bottomMargin + implicitWidth: Kirigami.Units.gridUnit + bgLoader.leftMargin + bgLoader.rightMargin + height: parent.height + hovered: control.down.hovered + pressed: control.down.pressed + focused: false + checked: false + Kirigami.Icon { + anchors.centerIn: parent + implicitWidth: Kirigami.Units.iconSizes.sizeForLabels + implicitHeight: Kirigami.Units.iconSizes.sizeForLabels + source: "spinbox-decrease" + fallback: "list-remove" + } + KSvg.SvgItem { + x: control.mirrored ? 0 : parent.width - width + z: -1 + anchors { + top: parent.top + bottom: parent.bottom + topMargin: bgLoader.topMargin + bottomMargin: bgLoader.bottomMargin + } + implicitWidth: naturalSize.width + implicitHeight: implicitWidth + elementId: "vertical-line" + svg: lineSvg + } + } + + contentItem: T.TextField { + id: textField + opacity: enabled ? 1 : 0.5 + implicitWidth: Math.ceil(contentWidth) + leftPadding + rightPadding + implicitHeight: Math.ceil(contentHeight) + topPadding + bottomPadding + text: control.displayText + font: control.font + Kirigami.Theme.colorSet: Kirigami.Theme.View + Kirigami.Theme.inherit: false + color: Kirigami.Theme.textColor + selectionColor: Kirigami.Theme.highlightColor + selectedTextColor: Kirigami.Theme.highlightedTextColor + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + readOnly: !control.editable + validator: control.validator + inputMethodHints: control.inputMethodHints + selectByMouse: true + hoverEnabled: false + } + + background: Loader { + id: bgLoader + // Anchors are needed because the Loader tries to resize itself on load + anchors { + fill: parent + topMargin: control.topInset + // Anchors will automirrot, inset won't, so we wnt the left stays left regardless of the layout + leftMargin: LayoutMirroring.enabled ? control.rightInset : control.leftInset + rightMargin: LayoutMirroring.enabled ? control.leftInset : control.rightInset + bottomMargin: control.bottomInset + } + readonly property real leftMargin: item.leftMargin + readonly property real rightMargin: item.rightMargin + readonly property real topMargin: item.topMargin + readonly property real bottomMargin: item.bottomMargin + sourceComponent: control.editable ? editableBg : noneditableBg + Component { + id: noneditableBg + P.RaisedButtonBackground { + hovered: control.hovered + focused: control.visualFocus || (control.contentItem.activeFocus && ( + control.contentItem.focusReason == Qt.TabFocusReason || + control.contentItem.focusReason == Qt.BacktabFocusReason || + control.contentItem.focusReason == Qt.ShortcutFocusReason + )) + checked: false + pressed: false + } + } + Component { + id: editableBg + KSvg.FrameSvgItem { + readonly property real leftMargin: margins.left + readonly property real rightMargin: margins.right + readonly property real topMargin: margins.top + readonly property real bottomMargin: margins.bottom + imagePath: "widgets/lineedit" + prefix: "base" + KSvg.FrameSvgItem { + anchors { + fill: parent + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + imagePath: "widgets/lineedit" + prefix: "hover" + visible: opacity > 0 + opacity: control.hovered + Behavior on opacity { + enabled: control.hovered && Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.OutCubic + } + } + } + KSvg.FrameSvgItem { + property bool visualFocus: control.visualFocus || (control.contentItem.activeFocus + && (control.contentItem.focusReason == Qt.TabFocusReason || + control.contentItem.focusReason == Qt.BacktabFocusReason || + control.contentItem.focusReason == Qt.ShortcutFocusReason) + ) + z: lineEditSvg.hasElement("hint-focus-over-base") ? 0 : -1 + anchors { + fill: parent + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + imagePath: "widgets/lineedit" + prefix: visualFocus && lineEditSvg.hasElement("focusframe-center") ? "focusframe" : "focus" + visible: opacity > 0 + opacity: visualFocus || control.activeFocus || control.contentItem.activeFocus + Behavior on opacity { + enabled: Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.OutCubic + } + } + } + KSvg.Svg { + id: lineEditSvg + imagePath: "widgets/lineedit" + } + } + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/SwipeView.qml b/src/declarativeimports/plasmacomponents3/SwipeView.qml new file mode 100644 index 0000000..c67bb5d --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/SwipeView.qml @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: 2016 Marco Martin +// SPDX-License-Identifier: LGPL-2.0-or-later + +import QtQuick +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami + +T.SwipeView { + id: control + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + + contentItem: ListView { + model: control.contentModel + interactive: control.interactive + currentIndex: control.currentIndex + focus: control.focus + + spacing: control.spacing + orientation: control.orientation + snapMode: ListView.SnapOneItem + boundsBehavior: Flickable.StopAtBounds + + highlightRangeMode: ListView.StrictlyEnforceRange + preferredHighlightBegin: 0 + preferredHighlightEnd: 0 + highlightMoveDuration: Kirigami.Units.longDuration + maximumFlickVelocity: 4 * (control.orientation === Qt.Horizontal ? width : height) + } +} diff --git a/src/declarativeimports/plasmacomponents3/Switch.qml b/src/declarativeimports/plasmacomponents3/Switch.qml new file mode 100644 index 0000000..3a37d36 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/Switch.qml @@ -0,0 +1,57 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + SPDX-FileCopyrightText: 2022 ivan (@ratijas) tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami +import "private" as Private + +T.Switch { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding, + implicitIndicatorWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + baselineOffset: contentItem.y + contentItem.baselineOffset + hoverEnabled: true + + spacing: Kirigami.Units.smallSpacing + + icon.width: Kirigami.Units.iconSizes.sizeForLabels + icon.height: Kirigami.Units.iconSizes.sizeForLabels + + indicator: SwitchIndicator { + x: (control.text || control.icon.name || control.icon.source) + ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) + : control.leftPadding + Math.round((control.availableWidth - width) / 2) + y: control.topPadding + Math.round((control.availableHeight - height) / 2) + + control: control + } + + contentItem: Private.IconLabel { + readonly property int effectiveIndicatorWidth: control.indicator && control.indicator.visible && control.indicator.width > 0 + ? control.indicator.width + control.spacing : 0 + + mirrored: control.mirrored + leftPadding: !control.mirrored ? effectiveIndicatorWidth : 0 + rightPadding: control.mirrored ? effectiveIndicatorWidth : 0 + + font: control.font + alignment: Qt.AlignLeft | Qt.AlignVCenter + display: control.display + spacing: control.spacing + iconItem.implicitWidth: control.icon.width + iconItem.implicitHeight: control.icon.height + iconItem.source: control.icon.name || control.icon.source + label.text: control.text + } +} diff --git a/src/declarativeimports/plasmacomponents3/SwitchDelegate.qml b/src/declarativeimports/plasmacomponents3/SwitchDelegate.qml new file mode 100644 index 0000000..ca77f59 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/SwitchDelegate.qml @@ -0,0 +1,65 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + SPDX-FileCopyrightText: 2022 ivan (@ratijas) tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami +import org.kde.ksvg as KSvg +import "private" as Private + +T.SwitchDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding, + implicitIndicatorWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + baselineOffset: contentItem.y + contentItem.baselineOffset + hoverEnabled: true + + topPadding: (background as KSvg.FrameSvgItem)?.margins.top ?? undefined + leftPadding: (background as KSvg.FrameSvgItem)?.margins.left ?? undefined + rightPadding: (background as KSvg.FrameSvgItem)?.margins.right ?? undefined + bottomPadding: (background as KSvg.FrameSvgItem)?.margins.bottom ?? undefined + + spacing: Kirigami.Units.smallSpacing + + icon.width: Kirigami.Units.iconSizes.sizeForLabels + icon.height: Kirigami.Units.iconSizes.sizeForLabels + + contentItem: Private.IconLabel { + readonly property int effectiveIndicatorWidth: control.indicator && control.indicator.visible && control.indicator.width > 0 + ? control.indicator.width + control.spacing : 0 + + mirrored: control.mirrored + leftPadding: !control.mirrored ? 0 : effectiveIndicatorWidth + rightPadding: control.mirrored ? 0 : effectiveIndicatorWidth + + font: control.font + alignment: Qt.AlignLeft + display: control.display + spacing: control.spacing + iconItem.implicitWidth: control.icon.width + iconItem.implicitHeight: control.icon.height + iconItem.source: control.icon.name || control.icon.source + label.text: control.text + } + + indicator: SwitchIndicator { + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + Math.round((control.availableHeight - height) / 2) + + control: control + } + + background: Private.DefaultListItemBackground { + control: control + } +} diff --git a/src/declarativeimports/plasmacomponents3/SwitchIndicator.qml b/src/declarativeimports/plasmacomponents3/SwitchIndicator.qml new file mode 100644 index 0000000..4014ca5 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/SwitchIndicator.qml @@ -0,0 +1,108 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + SPDX-FileCopyrightText: 2022 ivan (@ratijas) tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +import org.kde.kirigami as Kirigami +import "private" as Private + +Item { + id: root + + required property T.AbstractButton control + + implicitWidth: inactive.implicitWidth + implicitHeight: Math.max(inactive.implicitHeight, button.implicitHeight) + + layer.enabled: opacity < 1 + opacity: control.enabled ? 1 : 0.6 + + KSvg.Svg { + id: switchSvg + imagePath: "widgets/switch" + // FIXME + colorSet: root.control.Kirigami.Theme.colorSet + } + + KSvg.FrameSvgItem { + id: inactive + anchors { + left: parent.left + right: parent.right + leftMargin: 1 + rightMargin: 1 + verticalCenter: parent.verticalCenter + } + implicitHeight: switchSvg.hasElement("hint-bar-size") + ? switchSvg.elementSize("hint-bar-size").height + : button.implicitHeight + implicitWidth: switchSvg.hasElement("hint-bar-size") + ? switchSvg.elementSize("hint-bar-size").width + : root.implicitHeight * 2 + imagePath: "widgets/switch" + prefix: "inactive" + } + KSvg.FrameSvgItem { + anchors { + left: inactive.left + top: inactive.top + bottom: inactive.bottom + right: button.right + } + imagePath: "widgets/switch" + prefix: "active" + } + KSvg.SvgItem { + id: button + + x: Math.max(0, Math.min(parent.width - width, root.control.visualPosition * parent.width - (width / 2))) + + anchors.verticalCenter: parent.verticalCenter + + svg: switchSvg + elementId: root.control.down ? "handle-pressed" : (root.control.hovered || root.control.focus ? "handle-hover" : "handle") + + implicitWidth: naturalSize.width + implicitHeight: naturalSize.height + + Behavior on x { + enabled: !root.control.down && Kirigami.Units.shortDuration > 0 + // Can't use XAnimator, since it doesn't update x during the animation, so the active + // background is not animated. + NumberAnimation { + duration: Kirigami.Units.shortDuration + easing.type: Easing.InOutQuad + } + } + KSvg.SvgItem { + svg: switchSvg + z: -1 + anchors.centerIn: parent + implicitWidth: naturalSize.width + implicitHeight: naturalSize.height + elementId: "handle-shadow" + visible: enabled && !root.control.down + } + KSvg.SvgItem { + anchors.centerIn: parent + implicitWidth: naturalSize.width + implicitHeight: naturalSize.height + svg: switchSvg + elementId: "handle-focus" + visible: opacity > 0 + opacity: root.control.visualFocus + Behavior on opacity { + enabled: Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.OutCubic + } + } + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/TabBar.qml b/src/declarativeimports/plasmacomponents3/TabBar.qml new file mode 100644 index 0000000..aed9835 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/TabBar.qml @@ -0,0 +1,47 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami + +T.TabBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + spacing: 0 + + contentItem: ListView { + implicitWidth: contentWidth + implicitHeight: contentHeight + + model: control.contentModel + currentIndex: control.currentIndex + + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + flickableDirection: Flickable.AutoFlickIfNeeded + snapMode: ListView.SnapToItem + + highlightMoveDuration: Kirigami.Units.longDuration + highlightRangeMode: ListView.ApplyRange + preferredHighlightBegin: 40 + preferredHighlightEnd: width - 40 + highlightResizeDuration: 0 + highlight: KSvg.FrameSvgItem { + imagePath: "widgets/tabbar" + prefix: control.position == T.TabBar.Header ? "north-active-tab" : "south-active-tab" + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/TabButton.qml b/src/declarativeimports/plasmacomponents3/TabButton.qml new file mode 100644 index 0000000..e3e5c82 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/TabButton.qml @@ -0,0 +1,99 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + SPDX-FileCopyrightText: 2022 ivan (@ratijas) tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQml.Models +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami +import "private" as Private + +T.TabButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding, + implicitIndicatorWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + baselineOffset: contentItem.y + contentItem.baselineOffset + hoverEnabled: true + + topPadding: (background as KSvg.FrameSvgItem)?.margins.top ?? undefined + leftPadding: (background as KSvg.FrameSvgItem)?.margins.left ?? undefined + rightPadding: (background as KSvg.FrameSvgItem)?.margins.right ?? undefined + bottomPadding: (background as KSvg.FrameSvgItem)?.margins.bottom ?? undefined + + spacing: Kirigami.Units.smallSpacing + + icon.width: Kirigami.Units.iconSizes.smallMedium + icon.height: Kirigami.Units.iconSizes.smallMedium + + Kirigami.MnemonicData.enabled: control.enabled && control.visible + Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.SecondaryControl + Kirigami.MnemonicData.label: control.text + + Shortcut { + //in case of explicit & the button manages it by itself + enabled: !(RegExp(/\&[^\&]/).test(control.text)) + sequence: control.Kirigami.MnemonicData.sequence + onActivated: if (control.action) { + control.action.trigger() + } else if (control.checkable && !control.checked) { + // A checkable AbstractButton clicked by a user would normally + // change the checked state first before emitting clicked(). + control.toggle() + // Manually emit clicked() because action.trigger() is the only + // button related function that automatically emits clicked() + control.clicked() + } + } + + contentItem: Private.IconLabel { + mirrored: control.mirrored + font: control.font + display: control.display + spacing: control.spacing + iconItem.implicitWidth: control.icon.width + iconItem.implicitHeight: control.icon.height + iconItem.source: control.icon.name || control.icon.source + iconItem.active: control.visualFocus + label.text: control.Kirigami.MnemonicData.richTextLabel + label.color: control.visualFocus ? Kirigami.Theme.highlightColor : Kirigami.Theme.textColor + Rectangle { // As long as we don't enable antialiasing, not rounding should be fine + parent: control.contentItem.label + width: Math.min(parent.width, parent.contentWidth) + height: 1 + anchors.left: parent.left + anchors.top: parent.bottom + color: Kirigami.Theme.highlightColor + visible: control.visualFocus + } + } + + background: KSvg.FrameSvgItem { + visible: !control.ListView.view || !control.ListView.view.highlightItem + imagePath: "widgets/tabbar" + prefix: control.T.TabBar.position === T.TabBar.Footer ? "south-active-tab" : "north-active-tab" + enabledBorders: { + const borders = KSvg.FrameSvgItem.LeftBorder | KSvg.FrameSvgItem.RightBorder + if (!visible || control.checked) { + return borders | KSvg.FrameSvgItem.TopBorder | KSvg.FrameSvgItem.BottomBorder + } else if (control.T.TabBar.position === T.TabBar.Footer) { + return borders | KSvg.FrameSvgItem.BottomBorder + } else { + return borders | KSvg.FrameSvgItem.TopBorder + } + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/TextArea.qml b/src/declarativeimports/plasmacomponents3/TextArea.qml new file mode 100644 index 0000000..2311e92 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/TextArea.qml @@ -0,0 +1,104 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import "private" as Private +import org.kde.kirigami as Kirigami +import "mobiletextselection" as MobileTextSelection + +T.TextArea { + id: control + + implicitWidth: Math.max(contentWidth + leftPadding + rightPadding, + background ? background.implicitWidth : 0, + placeholder.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(contentHeight + topPadding + bottomPadding, + background ? background.implicitHeight : 0, + placeholder.implicitHeight + topPadding + bottomPadding) + + padding: 6 + + Kirigami.Theme.colorSet: Kirigami.Theme.View + Kirigami.Theme.inherit: false + color: Kirigami.Theme.textColor + selectionColor: Kirigami.Theme.highlightColor + selectedTextColor: Kirigami.Theme.highlightedTextColor + opacity: control.enabled ? 1 : 0.6 + verticalAlignment: TextEdit.AlignTop + hoverEnabled: !Kirigami.Settings.tabletMode || !Kirigami.Settings.hasTransientTouchInput + + selectByMouse: hoverEnabled + + cursorDelegate: !hoverEnabled ? mobileCursor : null + Component { + id: mobileCursor + MobileTextSelection.MobileCursor { + target: control + } + } + + onTextChanged: MobileTextSelection.MobileTextActionsToolBar.shouldBeVisible = false; + onPressed: event => MobileTextSelection.MobileTextActionsToolBar.shouldBeVisible = true; + + onPressAndHold: event => { + if (hoverEnabled) { + return; + } + forceActiveFocus(); + cursorPosition = positionAt(event.x, event.y); + selectWord(); + } + + MobileTextSelection.MobileCursor { + target: control + selectionStartHandle: true + property var rect: target.positionToRectangle(target.selectionStart) + x: rect.x + y: rect.y + } + + onFocusChanged: { + if (focus) { + MobileTextSelection.MobileTextActionsToolBar.controlRoot = control; + } + } + + Label { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + + text: control.placeholderText + font: control.font + color: Kirigami.Theme.textColor + opacity: 0.5 + enabled: false + horizontalAlignment: control.horizontalAlignment + verticalAlignment: control.verticalAlignment + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + elide: Text.ElideRight + } + + background: Item { + Private.TextFieldFocus { + state: control.activeFocus ? "focus" : (control.hovered ? "hover" : "hidden") + anchors.fill: parent + } + KSvg.FrameSvgItem { + id: base + anchors.fill: parent + imagePath: "widgets/lineedit" + prefix: "base" + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/TextField.qml b/src/declarativeimports/plasmacomponents3/TextField.qml new file mode 100644 index 0000000..1118ff2 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/TextField.qml @@ -0,0 +1,230 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami +import "mobiletextselection" as MobileTextSelection +import "private" as Private + +T.TextField { + id: control + + /** + * Whether the button to clear the text from TextField is visible. + * @since 5.73 + * @deprecated since 5.93 Use SearchField instead + */ + property bool clearButtonShown: false + + // Can't guarantee that background will always be present or have the margins property + readonly property bool __hasBackgroundAndMargins: background && background.hasOwnProperty("margins") + + // store information that echoMode was set to Password, regardless of its current value + property bool __isPassword: false + onEchoModeChanged: echoMode => { + __isPassword |= (echoMode === TextInput.Password); + } + + // TextField doesn't have this property by default for whatever reason + property bool visualFocus: activeFocus && [ + Qt.TabFocusReason, + Qt.BacktabFocusReason, + Qt.ShortcutFocusReason, + ].includes(focusReason) + + /* It might be preferable to do background width OR content width if we + * want content to stay within the background rather than expanding the + * control, but this is maintaining compatibility with the pre-existing + * behavior. Use the following 2 lines if you want text to stay within the + * background: + implicitBackgroundWidth + leftInset + rightInset + || Math.ceil(Math.max(contentWidth + leftPadding + rightPadding, placeholder.implicitWidth)) + */ + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + Math.ceil(Math.max(contentWidth + leftPadding + rightPadding, placeholder.implicitWidth))) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + Math.max(contentHeight + topPadding + bottomPadding, placeholder.implicitHeight, __isPassword ? passwordsizeholder.implicitHeight : 0)) + + topPadding: __hasBackgroundAndMargins ? background.margins.top : 0 + leftPadding: (__hasBackgroundAndMargins ? background.margins.left : 0) + (control.effectiveHorizontalAlignment === TextInput.AlignRight ? inlineButtonRow.width : 0) + rightPadding: (__hasBackgroundAndMargins ? background.margins.right : 0) + (control.effectiveHorizontalAlignment === TextInput.AlignRight ? 0 : inlineButtonRow.width) + bottomPadding: __hasBackgroundAndMargins ? background.margins.bottom : 0 + + Kirigami.Theme.inherit: !background || !background.visible + Kirigami.Theme.colorSet: Kirigami.Theme.View + + color: Kirigami.Theme.textColor + selectionColor: Kirigami.Theme.highlightColor + selectedTextColor: Kirigami.Theme.highlightedTextColor + placeholderTextColor: Kirigami.Theme.disabledTextColor + + verticalAlignment: TextInput.AlignVCenter + // Manually setting this fixes alignment in RTL layouts + horizontalAlignment: TextInput.AlignLeft + opacity: control.enabled ? 1 : 0.6 + hoverEnabled: !Kirigami.Settings.tabletMode + + selectByMouse: !Kirigami.Settings.tabletMode + + cursorDelegate: Kirigami.Settings.tabletMode ? mobileCursor : null + Component { + id: mobileCursor + MobileTextSelection.MobileCursor { + target: control + } + } + onFocusChanged: { + if (focus) { + MobileTextSelection.MobileTextActionsToolBar.controlRoot = control; + } + } + + onTextChanged: MobileTextSelection.MobileTextActionsToolBar.shouldBeVisible = false; + onPressed: event => MobileTextSelection.MobileTextActionsToolBar.shouldBeVisible = true; + + onPressAndHold: event => { + if (!Kirigami.Settings.tabletMode) { + return; + } + forceActiveFocus(); + cursorPosition = positionAt(event.x, event.y); + selectWord(); + } + MobileTextSelection.MobileCursor { + target: control + selectionStartHandle: true + property var rect: target.positionToRectangle(target.selectionStart) + //FIXME: this magic values seem to be always valid, for every font,every dpi, every scaling + x: rect.x + 5 + y: rect.y + 6 + } + + Label { + id: placeholder + enabled: false + x: 0 + y: 0 + topPadding: control.topPadding + bottomPadding: control.bottomPadding + leftPadding: control.leftPadding + rightPadding: control.rightPadding + height: control.height + width: control.width + font: control.font + LayoutMirroring.enabled: false + horizontalAlignment: control.effectiveHorizontalAlignment + verticalAlignment: control.verticalAlignment + elide: Text.ElideRight + renderType: control.renderType + text: control.placeholderText + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + color: control.placeholderTextColor + } + + // Object holding the size (implicitHeight) of the password dot character, + // so that a password TextField never gets shorter than required to display it + Label { + id: passwordsizeholder + enabled: false + visible: false + topPadding: control.topPadding + bottomPadding: control.bottomPadding + leftPadding: control.leftPadding + rightPadding: control.rightPadding + font: control.font + horizontalAlignment: control.horizontalAlignment + verticalAlignment: control.verticalAlignment + elide: Text.ElideRight + renderType: control.renderType + text: control.passwordCharacter + } + + Row { + id: inlineButtonRow + anchors.right: control.right + anchors.rightMargin: control.__hasBackgroundAndMargins ? background.margins.right : 0 + anchors.verticalCenter: control.verticalCenter + LayoutMirroring.enabled: control.effectiveHorizontalAlignment === TextInput.AlignRight + + Kirigami.Icon { + id: clearButton + //ltr confusingly refers to the direction of the arrow in the icon, not the text direction which it should be used in + source: clearButtonShown ? (control.effectiveHorizontalAlignment === TextInput.AlignRight ? "edit-clear-locationbar-ltr" : "edit-clear-locationbar-rtl") : "" + height: Kirigami.Units.iconSizes.small + width: height + opacity: (control.length > 0 && clearButtonShown && control.enabled) ? 1 : 0 + visible: opacity > 0 + Behavior on opacity { + enabled: Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.InOutQuad + } + } + MouseArea { + anchors.fill: parent + onClicked: mouse => { + control.clear() + control.forceActiveFocus() + } + } + } + } + + background: KSvg.FrameSvgItem { + implicitWidth: Kirigami.Units.gridUnit * 8 + margins.left + margins.right + implicitHeight: Kirigami.Units.gridUnit + margins.top + margins.bottom + imagePath: "widgets/lineedit" + prefix: "base" + + KSvg.FrameSvgItem { + anchors { + fill: parent + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + imagePath: "widgets/lineedit" + prefix: "hover" + visible: opacity > 0 + opacity: control.hovered + Behavior on opacity { + enabled: control.hovered && Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.OutCubic + } + } + } + KSvg.FrameSvgItem { + z: hasElement("hint-focus-over-base") ? 0 : -1 + anchors { + fill: parent + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + imagePath: "widgets/lineedit" + prefix: control.visualFocus && hasElement("focusframe-center") ? "focusframe" : "focus" + visible: opacity > 0 + opacity: control.visualFocus || control.activeFocus + Behavior on opacity { + enabled: Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.OutCubic + } + } + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/ToolBar.qml b/src/declarativeimports/plasmacomponents3/ToolBar.qml new file mode 100644 index 0000000..43c00de --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/ToolBar.qml @@ -0,0 +1,43 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami + +T.ToolBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: (background as KSvg.FrameSvgItem)?.margins.top ?? undefined + leftPadding: (background as KSvg.FrameSvgItem)?.margins.left ?? undefined + rightPadding: (background as KSvg.FrameSvgItem)?.margins.right ?? undefined + bottomPadding: (background as KSvg.FrameSvgItem)?.margins.bottom ?? undefined + + spacing: Kirigami.Units.smallSpacing + + background: KSvg.FrameSvgItem { + implicitHeight: 40 // TODO: Find a good way to sync this with the size of (Button or ToolButton) + padding + imagePath: "widgets/toolbar" + KSvg.SvgItem { + imagePath: "widgets/listitem" + elementId: "separator" + anchors { + left: parent.left + right: parent.right + top: control.position == T.ToolBar.Footer || (control.parent.footer && control.parent.footer == control) ? parent.top : undefined + bottom: control.position == T.ToolBar.Footer || (control.parent.footer && control.parent.footer == control) ? undefined : parent.bottom + } + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/ToolButton.qml b/src/declarativeimports/plasmacomponents3/ToolButton.qml new file mode 100644 index 0000000..84f8774 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/ToolButton.qml @@ -0,0 +1,59 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami +import "private" as Private + +T.ToolButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + topPadding: (background as Private.ButtonBackground)?.topMargin ?? undefined + leftPadding: (background as Private.ButtonBackground)?.leftMargin ?? undefined + rightPadding: (background as Private.ButtonBackground)?.rightMargin ?? undefined + bottomPadding: (background as Private.ButtonBackground)?.bottomMargin ?? undefined + + spacing: Kirigami.Units.smallSpacing + + hoverEnabled: !Kirigami.Settings.tabletMode + + Accessible.onPressAction: clicked() + + Kirigami.MnemonicData.enabled: control.enabled && control.visible + Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.SecondaryControl + Kirigami.MnemonicData.label: control.text + + // KF6 TODO: investigate setting this by default + // focusPolicy: Qt.TabFocus + + Shortcut { + //in case of explicit & the button manages it by itself + enabled: !(RegExp(/\&[^\&]/).test(control.text)) + sequence: control.Kirigami.MnemonicData.sequence + onActivated: control.clicked() + } + + flat: true + + Kirigami.Theme.inherit: flat + Kirigami.Theme.colorSet: Kirigami.Theme.Button + + contentItem: Private.ButtonContent { + labelText: control.Kirigami.MnemonicData.richTextLabel + button: control + } + + background: Private.ButtonBackground { + button: control + } +} diff --git a/src/declarativeimports/plasmacomponents3/ToolTip.qml b/src/declarativeimports/plasmacomponents3/ToolTip.qml new file mode 100644 index 0000000..c295e1c --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/ToolTip.qml @@ -0,0 +1,120 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + SPDX-FileCopyrightText: 2016 The Qt Company Ltd. + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +//NOTE: importing PlasmaCore is necessary in order to make KSvg load the current Plasma Theme +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami + +T.ToolTip { + id: control + + x: parent ? Math.round((parent.width - implicitWidth) / 2) : 0 + y: -implicitHeight - 3 + + Binding { + target: control + property: "visible" + delayed: true + value: parent.hovered, parent.pressed, parent instanceof T.AbstractButton && (Kirigami.Settings.tabletMode ? parent.pressed : parent.hovered) && text.length > 0 + } + + delay: Kirigami.Settings.tabletMode ? Qt.styleHints.mousePressAndHoldInterval : Kirigami.Units.toolTipDelay + // Never time out while being hovered; it's annoying + timeout: -1 + + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, contentHeight + topPadding + bottomPadding) + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, contentWidth + leftPadding + rightPadding) + + margins: Kirigami.Units.smallSpacing + + topPadding: backgroundItem.margins.top + leftPadding: backgroundItem.margins.left + rightPadding: backgroundItem.margins.right + bottomPadding: backgroundItem.margins.bottom + + enter: Transition { + NumberAnimation { + property: "opacity" + from: 0.0 + to: 1.0 + duration: Kirigami.Units.longDuration + easing.type: Easing.OutCubic + } + } + + exit: Transition { + NumberAnimation { + property: "opacity" + from: 1.0 + to: 0.0 + duration: Kirigami.Units.longDuration + easing.type: Easing.OutCubic + } + } + + closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent | T.Popup.CloseOnReleaseOutsideParent + + contentItem: Item { + implicitWidth: Math.min(label.maxTextLength, label.contentWidth) + implicitHeight: label.implicitHeight + + Label { + id: label + + // This value is basically arbitrary. It just looks nice. + readonly property double maxTextLength: Kirigami.Units.gridUnit * 14 + + // Strip out ampersands right before non-whitespace characters, i.e. + // those used to determine the alt key shortcut + text: control.text.replace(/&(?=\S)/g, "") + wrapMode: Text.WordWrap + font: control.font + + Kirigami.Theme.colorGroup: Kirigami.Theme.Tooltip + Kirigami.Theme.inherit: false + + // ensure that long text actually gets wrapped + onLineLaidOut: (line) => { + if (line.implicitWidth > maxTextLength) { + line.width = maxTextLength + } + } + } + } + + background: Item { + implicitHeight: Kirigami.Units.gridUnit + backgroundItem.margins.top + backgroundItem.margins.bottom + implicitWidth: Kirigami.Units.gridUnit + backgroundItem.margins.left + backgroundItem.margins.right + + KSvg.FrameSvgItem { + anchors { + fill: parent + topMargin: -margins.top + leftMargin: -margins.left + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + imagePath: "solid/widgets/tooltip" + prefix: "shadow" + Kirigami.Theme.colorGroup: Kirigami.Theme.Tooltip + Kirigami.Theme.inherit: false + } + + KSvg.FrameSvgItem { + id: backgroundItem + anchors.fill: parent + // Because the transparent one doesn't match the appearance of all + // other ones + imagePath: "solid/widgets/tooltip" + Kirigami.Theme.colorGroup: Kirigami.Theme.Tooltip + Kirigami.Theme.inherit: false + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/mobiletextselection/MobileCursor.qml b/src/declarativeimports/plasmacomponents3/mobiletextselection/MobileCursor.qml new file mode 100644 index 0000000..d6840ff --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/mobiletextselection/MobileCursor.qml @@ -0,0 +1,63 @@ +/* + SPDX-FileCopyrightText: 2018 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.kirigami as Kirigami + +Item { + id: root + width: 1 //<-important that this is actually a single device pixel + height: Kirigami.Units.gridUnit + + property Item target + + property bool selectionStartHandle: false + + visible: Kirigami.Settings.tabletMode && ((target.activeFocus && !selectionStartHandle) || target.selectedText.length > 0) + + Rectangle { + width: 3 + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top + bottom: parent.bottom + } + color: Qt.tint(Kirigami.Theme.highlightColor, Qt.rgba(1,1,1,0.4)) + radius: width + Rectangle { + width: Math.round(Kirigami.Units.gridUnit / 1.5) + height: width + visible: MobileTextActionsToolBar.shouldBeVisible + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.bottom + } + radius: width + color: Qt.tint(Kirigami.Theme.highlightColor, Qt.rgba(1,1,1,0.4)) + } + MouseArea { + anchors { + fill: parent + margins: -Kirigami.Units.gridUnit + } + preventStealing: true + onPositionChanged: mouse => { + var pos = mapToItem(target, mouse.x, mouse.y); + pos = target.positionAt(pos.x, pos.y); + + if (target.selectedText.length > 0) { + if (selectionStartHandle) { + target.select(Math.min(pos, target.selectionEnd - 1), target.selectionEnd); + } else { + target.select(target.selectionStart, Math.max(pos, target.selectionStart + 1)); + } + } else { + target.cursorPosition = pos; + } + } + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/mobiletextselection/MobileTextActionsToolBar.qml b/src/declarativeimports/plasmacomponents3/mobiletextselection/MobileTextActionsToolBar.qml new file mode 100644 index 0000000..28fffc9 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/mobiletextselection/MobileTextActionsToolBar.qml @@ -0,0 +1,18 @@ +/* + SPDX-FileCopyrightText: 2023 Fushan Wen + + SPDX-License-Identifier: LGPL-2.1-or-later +*/ + +pragma Singleton + +import QtQuick +import org.kde.kirigami as Kirigami + +Loader { + property Item controlRoot: null + property bool shouldBeVisible: false + + active: controlRoot ? shouldBeVisible && Kirigami.Settings.tabletMode && (controlRoot.selectedText.length > 0 || controlRoot.canPaste) : false + source: "MobileTextActionsToolBarImpl.qml" +} diff --git a/src/declarativeimports/plasmacomponents3/mobiletextselection/MobileTextActionsToolBarImpl.qml b/src/declarativeimports/plasmacomponents3/mobiletextselection/MobileTextActionsToolBarImpl.qml new file mode 100644 index 0000000..b9200a7 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/mobiletextselection/MobileTextActionsToolBarImpl.qml @@ -0,0 +1,64 @@ +/* + SPDX-FileCopyrightText: 2018 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import org.kde.kirigami as Kirigami + +Popup { + id: root + + parent: controlRoot.Window.window.contentItem + modal: false + focus: false + closePolicy: Popup.NoAutoClose + + x: parent ? Math.min(Math.max(0, controlRoot.mapToItem(root.parent, controlRoot.positionToRectangle(controlRoot.selectionStart).x, 0).x - root.width/2), parent.width - root.width) : 0 + + y: { + if (!parent) { + return false; + } + var desiredY = controlRoot.mapToItem(root.parent, 0, controlRoot.positionToRectangle(controlRoot.selectionStart).y).y - root.height; + + if (desiredY >= 0) { + return Math.min(desiredY, parent.height - root.height); + } else { + return Math.min(Math.max(0, controlRoot.mapToItem(root.parent, 0, controlRoot.positionToRectangle(controlRoot.selectionEnd).y + Math.round(Kirigami.Units.gridUnit * 1.5)).y), parent.height - root.height); + } + } + + width: contentItem.implicitWidth + leftPadding + rightPadding + visible: true + + contentItem: RowLayout { + ToolButton { + focusPolicy: Qt.NoFocus + icon.name: "edit-cut" + visible: controlRoot.selectedText.length > 0 && (!controlRoot.hasOwnProperty("echoMode") || controlRoot.echoMode === TextInput.Normal) + onClicked: { + controlRoot.cut(); + } + } + ToolButton { + focusPolicy: Qt.NoFocus + icon.name: "edit-copy" + visible: controlRoot.selectedText.length > 0 && (!controlRoot.hasOwnProperty("echoMode") || controlRoot.echoMode === TextInput.Normal) + onClicked: { + controlRoot.copy(); + } + } + ToolButton { + focusPolicy: Qt.NoFocus + icon.name: "edit-paste" + visible: controlRoot.canPaste + onClicked: { + controlRoot.paste(); + } + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/mobiletextselection/qmldir b/src/declarativeimports/plasmacomponents3/mobiletextselection/qmldir new file mode 100644 index 0000000..f87968d --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/mobiletextselection/qmldir @@ -0,0 +1,2 @@ +singleton MobileTextActionsToolBar 1.0 MobileTextActionsToolBar.qml +MobileCursor 1.0 MobileCursor.qml diff --git a/src/declarativeimports/plasmacomponents3/private/ButtonBackground.qml b/src/declarativeimports/plasmacomponents3/private/ButtonBackground.qml new file mode 100644 index 0000000..2389cc3 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/private/ButtonBackground.qml @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.0-or-later + */ + +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami + +Item { + id: root + + required property T.Button button + + // These should be used as the padding for the parent control + property real topMargin: loader.item.topMargin + property real leftMargin: loader.item.leftMargin + property real rightMargin: loader.item.rightMargin + property real bottomMargin: loader.item.bottomMargin + + implicitWidth: Kirigami.Units.gridUnit + root.leftMargin + root.rightMargin + implicitHeight: Kirigami.Units.gridUnit + root.topMargin + root.bottomMargin + + opacity: enabled ? 1 : 0.5 + layer.enabled: opacity < 1 + + Loader { + id: loader + anchors.fill: parent + sourceComponent: root.button.flat ? flatButtonBackground : raisedButtonBackground + } + + Component { + id: flatButtonBackground + FlatButtonBackground { + anchors.fill: parent + hovered: root.button.hovered + pressed: root.button.down + checked: root.button.checked + focused: root.button.visualFocus + } + } + + Component { + id: raisedButtonBackground + RaisedButtonBackground { + anchors.fill: parent + hovered: root.button.hovered + pressed: root.button.down + checked: root.button.checked + focused: root.button.visualFocus + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/private/ButtonContent.qml b/src/declarativeimports/plasmacomponents3/private/ButtonContent.qml new file mode 100644 index 0000000..97eeb73 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/private/ButtonContent.qml @@ -0,0 +1,82 @@ +/* + * SPDX-FileCopyrightText: 2016 Marco Martin + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.0-or-later + */ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +import org.kde.kirigami as Kirigami +import "../" as PlasmaComponents + +RowLayout { + id: root + + required property string labelText + required property T.Button button + + readonly property bool usingFocusBackground: !button.flat && buttonSvg.hasElement("hint-focus-highlighted-background") && button.visualFocus && !(button.pressed || button.checked) + readonly property int defaultIconSize: button.flat ? Kirigami.Units.iconSizes.smallMedium : Kirigami.Units.iconSizes.small + + // Can't rely on the transient Item::visible property + readonly property bool iconVisible: icon.source.toString() !== "" && button.display !== T.Button.TextOnly + readonly property bool labelVisible: labelText !== "" && root.button.display !== T.Button.IconOnly + + spacing: button.spacing + + GridLayout { + Layout.fillWidth: true + Layout.fillHeight: true + columns: root.button.display == T.Button.TextBesideIcon ? 2 : 1 + rowSpacing: root.button.spacing + columnSpacing: rowSpacing + + Kirigami.Icon { + id: icon + + Layout.alignment: Qt.AlignCenter + + Layout.fillWidth: root.button.display !== T.Button.TextBesideIcon || root.labelText === "" + Layout.fillHeight: true + + Layout.minimumWidth: Math.min(root.width, root.height, implicitWidth) + Layout.minimumHeight: Math.min(root.width, root.height, implicitHeight) + + Layout.maximumWidth: root.button.icon.width > 0 ? root.button.icon.width : Number.POSITIVE_INFINITY + Layout.maximumHeight: root.button.icon.height > 0 ? root.button.icon.height : Number.POSITIVE_INFINITY + + implicitWidth: root.button.icon.width > 0 ? root.button.icon.width : root.defaultIconSize + implicitHeight: root.button.icon.height > 0 ? root.button.icon.height : root.defaultIconSize + visible: root.iconVisible + source: root.button.icon.name !== "" ? root.button.icon.name : root.button.icon.source + color: root.button.icon.color + selected: root.usingFocusBackground + } + PlasmaComponents.Label { + id: label + Layout.fillWidth: true + Layout.fillHeight: true + visible: root.labelVisible + text: root.labelText + font: root.button.font + color: root.usingFocusBackground ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor + horizontalAlignment: root.button.display !== T.Button.TextUnderIcon && root.iconVisible ? Text.AlignLeft : Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + } + KSvg.SvgItem { + visible: root.button.Accessible.role === Accessible.ButtonMenu && root.labelVisible + Layout.preferredWidth: Kirigami.Units.iconSizes.small + Layout.preferredHeight: Layout.preferredWidth + Layout.alignment: Qt.AlignCenter + imagePath: "widgets/arrows" + elementId: "down-arrow" + } + KSvg.Svg { + id: buttonSvg + imagePath: "widgets/button" + } +} diff --git a/src/declarativeimports/plasmacomponents3/private/ButtonFocus.qml b/src/declarativeimports/plasmacomponents3/private/ButtonFocus.qml new file mode 100644 index 0000000..3f47ee1 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/private/ButtonFocus.qml @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.0-or-later + */ + +import QtQuick +import org.kde.ksvg as KSvg +import org.kde.kirigami as Kirigami + +KSvg.FrameSvgItem { + anchors { + fill: parent + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + + property bool showFocus: false + property bool flat: false + + imagePath: "widgets/button" + prefix: flat ? ["toolbutton-focus", "focus"] : "focus" + + opacity: showFocus ? 1 : 0 + Behavior on opacity { + enabled: Kirigami.Units.shortDuration > 0 + OpacityAnimator { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutQuad } + } +} diff --git a/src/declarativeimports/plasmacomponents3/private/ButtonHover.qml b/src/declarativeimports/plasmacomponents3/private/ButtonHover.qml new file mode 100644 index 0000000..0e0c7e0 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/private/ButtonHover.qml @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.0-or-later + */ + +import QtQuick +import org.kde.ksvg as KSvg + +KSvg.FrameSvgItem { + property bool showHover: false + + anchors { + fill: parent + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + imagePath: "widgets/button" + prefix: "hover" + + visible: showHover ? 1 : 0 +} diff --git a/src/declarativeimports/plasmacomponents3/private/ButtonShadow.qml b/src/declarativeimports/plasmacomponents3/private/ButtonShadow.qml new file mode 100644 index 0000000..e853972 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/private/ButtonShadow.qml @@ -0,0 +1,33 @@ +/* + SPDX-FileCopyrightText: 2011 Daker Fernandes Pinheiro + SPDX-FileCopyrightText: 2011 Marco Martin + SPDX-FileCopyrightText: 2020 Noah Davis + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.ksvg as KSvg +import org.kde.kirigami as Kirigami + +KSvg.FrameSvgItem { + id: shadowEffect + + property bool showShadow + + anchors { + fill: parent + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + imagePath: "widgets/button" + prefix: "shadow" + + opacity: showShadow ? 1 : 0 + Behavior on opacity { + enabled: Kirigami.Units.shortDuration > 0 + OpacityAnimator { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutQuad } + } +} diff --git a/src/declarativeimports/plasmacomponents3/private/DefaultListItemBackground.qml b/src/declarativeimports/plasmacomponents3/private/DefaultListItemBackground.qml new file mode 100644 index 0000000..0d5cf76 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/private/DefaultListItemBackground.qml @@ -0,0 +1,30 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +//for Settings +import QtQuick.Templates as T +import org.kde.ksvg as KSvg +import org.kde.kirigami as Kirigami + +KSvg.FrameSvgItem { + id: background + + required property T.ItemDelegate control + + imagePath: "widgets/listitem" + prefix: control.highlighted || control.down ? "pressed" : "normal" + + visible: control.ListView.view ? control.ListView.view.highlight === null : true + + KSvg.FrameSvgItem { + imagePath: "widgets/listitem" + visible: !Kirigami.Settings.isMobile + prefix: "hover" + anchors.fill: parent + opacity: background.control.hovered && !background.control.down ? 1 : 0 + } +} diff --git a/src/declarativeimports/plasmacomponents3/private/FlatButtonBackground.qml b/src/declarativeimports/plasmacomponents3/private/FlatButtonBackground.qml new file mode 100644 index 0000000..17688e9 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/private/FlatButtonBackground.qml @@ -0,0 +1,61 @@ +/* + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.0-or-later + */ + +import QtQuick +import org.kde.ksvg as KSvg +import org.kde.kirigami as Kirigami + +Item { + id: root + required property bool hovered + required property bool pressed + required property bool checked + required property bool focused + + property real leftMargin: surfaceHover.margins.left + property real topMargin: surfaceHover.margins.top + property real rightMargin: surfaceHover.margins.right + property real bottomMargin: surfaceHover.margins.bottom + property string usedPrefix: surfaceHover.usedPrefix + + ButtonShadow { + anchors.fill: parent + showShadow: !(root.checked || root.pressed) && root.usedPrefix === "normal" + } + + ButtonFocus { + anchors.fill: parent + showFocus: root.focused && !root.pressed + flat: true + } + + // TODO: Maybe add a way to customize the look of normal state flat buttons with "toolbutton-normal"? + // TODO: Maybe add a way to customize the background of focused flat buttons with "toolbutton-focus-background"? + // TODO KF6: "flat" would be a more logical name than "toolbutton" since toolbuttons can be non-flat. + KSvg.FrameSvgItem { + id: surfaceHover + anchors.fill: parent + imagePath: "widgets/button" + /* TODO KF6: making "toolbutton-hover" margins work like "hover" + * and using "hover" as a fallback would make more sense. + * If that is done, make ButtonHover handle flat button hover effects. + */ + // The fallback is "normal" to match PC2 behavior. Some 3rd party themes depend on this. + prefix: ["toolbutton-hover", "normal"] + visible: root.hovered + } + + KSvg.FrameSvgItem { + id: surfacePressed + anchors.fill: parent + imagePath: "widgets/button" + prefix: ["toolbutton-pressed", "pressed"] + opacity: root.checked || root.pressed ? 1 : 0 + Behavior on opacity { + enabled: Kirigami.Units.shortDuration > 0 + NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutQuad } + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/private/IconLabel.qml b/src/declarativeimports/plasmacomponents3/private/IconLabel.qml new file mode 100644 index 0000000..0b8cd67 --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/private/IconLabel.qml @@ -0,0 +1,100 @@ +/* + SPDX-FileCopyrightText: 2021 Noah Davis + SPDX-FileCopyrightText: 2022 ivan (@ratijas) tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Templates as T +import org.kde.kirigami as Kirigami + +Item { + id: root + + // alignment is subject to mirroring + property int alignment: 0 // Null alignment + property int effectiveHorizontalAlignment: !LayoutMirroring.enabled ? alignment + : (alignment & Qt.AlignLeft) ? Qt.AlignRight + : (alignment & Qt.AlignRight) ? Qt.AlignLeft + : Qt.AlignHCenter + property int display: T.AbstractButton.TextBesideIcon + + property alias iconItem: iconItem + property alias label: label + + property real topPadding: 0 + property real leftPadding: 0 + property real rightPadding: 0 + property real bottomPadding: 0 + + readonly property real availableWidth: width - leftPadding - rightPadding + readonly property real availableHeight: height - topPadding - bottomPadding + + property real spacing: 0 + + property font font + // TODO KF6: This is not a correct formula for mirrored property. + // Explicitly setting `LayoutMirroring.enabled` to `false` should undone + // any mirroring imposed by LayoutMirroring inheritance or RTL locale. + // Fixed in Qt 6.2, see QTBUG-91227 + property bool mirrored: false + + implicitWidth: gridLayout.implicitWidth + leftPadding + rightPadding + implicitHeight: gridLayout.implicitHeight + topPadding + bottomPadding + + GridLayout { + id: gridLayout + + rowSpacing: root.spacing + columnSpacing: root.spacing + flow: root.display === T.AbstractButton.TextUnderIcon ? GridLayout.TopToBottom : GridLayout.LeftToRight + // Avoid manipulating layoutDirection directly, and we still need to + // set LayoutMirroring.enabled to some deterministic value which + // would not be affected by a random LayoutMirroring.childrenInherit + // up the parents chain. + LayoutMirroring.enabled: root.mirrored + x: { + if (root.effectiveHorizontalAlignment & Qt.AlignLeft) { + return root.leftPadding; + } + if (root.effectiveHorizontalAlignment & Qt.AlignRight) { + return root.width - width - root.rightPadding; + } + return Math.round((root.availableWidth - width) / 2); + } + y: { + if (root.alignment & Qt.AlignTop) { + return root.topPadding; + } + if (root.alignment & Qt.AlignBottom) { + return root.height - height - root.bottomPadding; + } + return Math.round((root.availableHeight - height) / 2); + } + width: Math.min(root.availableWidth, implicitWidth) + height: Math.min(root.availableHeight, implicitHeight) + + Kirigami.Icon { + id: iconItem + visible: valid && width > 0 && height > 0 && root.display !== T.AbstractButton.TextOnly + implicitWidth: Kirigami.Units.iconSizes.sizeForLabels + implicitHeight: Kirigami.Units.iconSizes.sizeForLabels + Layout.alignment: Qt.AlignCenter + Layout.maximumWidth: implicitWidth > 0 ? implicitWidth : Number.POSITIVE_INFINITY + Layout.maximumHeight: implicitHeight > 0 ? implicitHeight : Number.POSITIVE_INFINITY + } + + Text { + id: label + visible: text.length > 0 && root.display !== T.AbstractButton.IconOnly + font: root.font + color: Kirigami.Theme.textColor + linkColor: Kirigami.Theme.linkColor + elide: Text.ElideRight + Layout.alignment: Qt.AlignCenter + Layout.fillWidth: true + } + } +} diff --git a/src/declarativeimports/plasmacomponents3/private/RaisedButtonBackground.qml b/src/declarativeimports/plasmacomponents3/private/RaisedButtonBackground.qml new file mode 100644 index 0000000..6ba82af --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/private/RaisedButtonBackground.qml @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.0-or-later + */ + +import QtQuick +import org.kde.ksvg as KSvg +import org.kde.kirigami as Kirigami + +Item { + id: root + required property bool hovered + required property bool pressed + required property bool checked + required property bool focused + + readonly property bool showPressed: checked || pressed + readonly property bool showFocused: focused && surfaceFocused.usedPrefix != "normal" + + property var margins: showPressed ? surfacePressed.margins : (showFocused ? surfaceFocused.margins : surfaceNormal.margins) + property real leftMargin: margins.left + property real topMargin: margins.top + property real rightMargin: margins.right + property real bottomMargin: margins.bottom + property string usedPrefix: showPressed ? surfacePressed.usedPrefix : (showFocused ? surfaceFocused.usedPrefix : surfaceNormal.usedPrefix) + + ButtonShadow { + anchors.fill: parent + showShadow: enabled && !root.checked && !root.pressed + } + + KSvg.FrameSvgItem { + id: surfaceNormal + anchors.fill: parent + imagePath: "widgets/button" + prefix: "normal" + } + + // Intentionally lower than surfacePressed, surfaceFocused + ButtonFocus { + anchors.fill: parent + showFocus: root.focused && !root.pressed + } + + // Intentionally lower than surfacePressed and surfaceFocused + ButtonHover { + anchors.fill: parent + showHover: root.hovered && !root.pressed + } + + KSvg.FrameSvgItem { + id: surfacePressed + anchors.fill: parent + imagePath: "widgets/button" + prefix: "pressed" + opacity: root.showPressed ? 1 : 0 + Behavior on opacity { + enabled: Kirigami.Units.shortDuration > 0 + OpacityAnimator { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutQuad } + } + } + + KSvg.FrameSvgItem { + id: surfaceFocused + anchors.fill: parent + imagePath: "widgets/button" + prefix: ["focus-background", "normal"] + opacity: root.showFocused ? 1 : 0 + Behavior on opacity { + enabled: Kirigami.Units.shortDuration > 0 + OpacityAnimator { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutQuad } + } + } + +} diff --git a/src/declarativeimports/plasmacomponents3/private/RoundShadow.qml b/src/declarativeimports/plasmacomponents3/private/RoundShadow.qml new file mode 100644 index 0000000..462dcfa --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/private/RoundShadow.qml @@ -0,0 +1,122 @@ +/* + SPDX-FileCopyrightText: 2011 Daker Fernandes Pinheiro + SPDX-FileCopyrightText: 2011 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +/**Documented API +Inherits: + Item + +Imports: + QtQuick 2.1 + org.kde.plasma.core + +Description: + It is a simple Radio button which is using the plasma theme. + TODO Do we need more info? + +Properties: + TODO needs more info?? +**/ + +import QtQuick +import org.kde.ksvg as KSvg +import org.kde.kirigami as Kirigami + +Item { + id: main + state: parent.state + property alias imagePath: shadowSvg.imagePath + property string hoverElement: "hover" + property string focusElement: "focus" + property alias shadowElement: shadow.elementId + + //used to tell apart this implementation with the touch components one + property bool hasOverState: true + + KSvg.Svg { + id: shadowSvg + imagePath: "widgets/actionbutton" + } + + KSvg.SvgItem { + id: hover + svg: shadowSvg + elementId: "hover" + + anchors.fill: parent + + opacity: 0 + } + + KSvg.SvgItem { + id: shadow + svg: shadowSvg + elementId: "shadow" + + anchors.fill: parent + } + + states: [ + State { + name: "shadow" + PropertyChanges { + target: shadow + opacity: 1 + } + PropertyChanges { + target: hover + opacity: 0 + elementId: hoverElement + } + }, + State { + name: "hover" + PropertyChanges { + target: shadow + opacity: 0 + } + PropertyChanges { + target: hover + opacity: 1 + elementId: hoverElement + } + }, + State { + name: "focus" + PropertyChanges { + target: shadow + opacity: 0 + } + PropertyChanges { + target: hover + opacity: 1 + elementId: focusElement + } + }, + State { + name: "hidden" + PropertyChanges { + target: shadow + opacity: 0 + } + PropertyChanges { + target: hover + opacity: 0 + elementId: hoverElement + } + } + ] + + transitions: [ + Transition { + PropertyAnimation { + properties: "opacity" + duration: Kirigami.Units.longDuration + easing.type: Easing.OutQuad + } + } + ] +} diff --git a/src/declarativeimports/plasmacomponents3/private/TextFieldFocus.qml b/src/declarativeimports/plasmacomponents3/private/TextFieldFocus.qml new file mode 100644 index 0000000..48630de --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/private/TextFieldFocus.qml @@ -0,0 +1,97 @@ +/* + SPDX-FileCopyrightText: 2011 Daker Fernandes Pinheiro + SPDX-FileCopyrightText: 2011 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.ksvg as KSvg +import org.kde.kirigami as Kirigami + +Item { + id: main + state: parent.state + + KSvg.Svg { + id: lineEditSvg + property bool hasFocusFrame: lineEditSvg.hasElement("focusframe-center") + property bool hasFocusOverBase: lineEditSvg.hasElement("hint-focus-over-base") + imagePath: "widgets/lineedit" + onRepaintNeeded: { + if (hasFocusOverBase) { + main.z = 800 + } else { + main.z = 0 + } + } + Component.onCompleted: { + if (hasFocusOverBase) { + main.z = 800 + } else { + main.z = 0 + } + } + } + + KSvg.FrameSvgItem { + id: hover + + anchors { + fill: parent + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + opacity: 0 + visible: opacity > 0 + imagePath: "widgets/lineedit" + prefix: "hover" + } + + states: [ + State { + name: "hover" + PropertyChanges { + target: hover + opacity: 1 + prefix: "hover" + } + }, + State { + name: "focus" + PropertyChanges { + target: hover + opacity: 1 + prefix: "focus" + } + }, + State { + name: "focusframe" + PropertyChanges { + target: hover + opacity: 1 + prefix: lineEditSvg.hasFocusFrame ? "focusframe" : "focus" + } + }, + State { + name: "hidden" + PropertyChanges { + target: hover + opacity: 0 + prefix: "hover" + } + } + ] + + transitions: [ + Transition { + PropertyAnimation { + properties: "opacity" + duration: Kirigami.Units.longDuration + easing.type: Easing.OutQuad + } + } + ] +} diff --git a/src/declarativeimports/plasmacomponents3/qmldir b/src/declarativeimports/plasmacomponents3/qmldir new file mode 100644 index 0000000..bbe96fb --- /dev/null +++ b/src/declarativeimports/plasmacomponents3/qmldir @@ -0,0 +1,42 @@ +module org.kde.plasma.components + +AbstractButton 3.0 AbstractButton.qml +BusyIndicator 3.0 BusyIndicator.qml +Button 3.0 Button.qml +CheckBox 3.0 CheckBox.qml +CheckDelegate 3.0 CheckDelegate.qml +ComboBox 3.0 ComboBox.qml +Container 3.0 Container.qml +Control 3.0 Control.qml +Dial 3.0 Dial.qml +Drawer 3.0 Drawer.qml +Frame 3.0 Frame.qml +GroupBox 3.0 GroupBox.qml +ItemDelegate 3.0 ItemDelegate.qml +Label 3.0 Label.qml +MenuItem 3.0 MenuItem.qml +Menu 3.0 Menu.qml +MenuSeparator 3.0 MenuSeparator.qml +Pane 3.0 Pane.qml +Popup 3.0 Popup.qml +ProgressBar 3.0 ProgressBar.qml +RadioButton 3.0 RadioButton.qml +RadioDelegate 3.0 RadioDelegate.qml +RangeSlider 3.0 RangeSlider.qml +ScrollBar 3.0 ScrollBar.qml +ScrollView 3.0 ScrollView.qml +Slider 3.0 Slider.qml +SpinBox 3.0 SpinBox.qml +SwipeView 3.0 SwipeView.qml +SwitchDelegate 3.0 SwitchDelegate.qml +Switch 3.0 Switch.qml +TabBar 3.0 TabBar.qml +TabButton 3.0 TabButton.qml +TextArea 3.0 TextArea.qml +TextField 3.0 TextField.qml +ToolBar 3.0 ToolBar.qml +ToolButton 3.0 ToolButton.qml +ToolTip 3.0 ToolTip.qml +RoundButton 3.0 RoundButton.qml +Page 3.0 Page.qml +PageIndicator 3.0 PageIndicator.qml diff --git a/src/declarativeimports/plasmaextracomponents/CMakeLists.txt b/src/declarativeimports/plasmaextracomponents/CMakeLists.txt new file mode 100644 index 0000000..acb950a --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/CMakeLists.txt @@ -0,0 +1,45 @@ +ecm_add_qml_module(plasmaextracomponentsplugin VERSION 2.0 URI "org.kde.plasma.extras" GENERATE_PLUGIN_SOURCE) + +target_sources(plasmaextracomponentsplugin PRIVATE + qmenu.cpp + qmenuitem.cpp +) + +ecm_target_qml_sources(plasmaextracomponentsplugin SOURCES + qml/ActionTextField.qml + qml/BasicPlasmoidHeading.qml + qml/DescriptiveLabel.qml + qml/ExpandableListItem.qml + qml/Heading.qml + qml/Highlight.qml + qml/ListItem.qml + qml/ListSectionHeader.qml + qml/ModelContextMenu.qml + qml/PasswordField.qml + qml/PlaceholderMessage.qml + qml/PlasmoidHeading.qml + qml/Representation.qml + qml/SearchField.qml + qml/ShadowedLabel.qml +) + +ecm_target_qml_sources(plasmaextracomponentsplugin PATH animations SOURCES + qml/animations/ActivateAnimation.qml + qml/animations/AppearAnimation.qml + qml/animations/DisappearAnimation.qml + qml/animations/PressedAnimation.qml + qml/animations/ReleasedAnimation.qml +) + +ecm_target_qml_sources(plasmaextracomponentsplugin PRIVATE PATH private SOURCES + qml/private/BackgroundMetrics.qml +) + +target_link_libraries(plasmaextracomponentsplugin PRIVATE + Qt6::Quick + Qt6::Qml + Qt6::Widgets + KF6::ConfigWidgets + Plasma::Plasma) + +ecm_finalize_qml_module(plasmaextracomponentsplugin DESTINATION ${KDE_INSTALL_QMLDIR}) diff --git a/src/declarativeimports/plasmaextracomponents/Mainpage.dox b/src/declarativeimports/plasmaextracomponents/Mainpage.dox new file mode 100644 index 0000000..c7eaf92 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/Mainpage.dox @@ -0,0 +1,34 @@ +/** @page plasmaextracomponents Plasma Extra Components + +

import org.kde.plasma.extras

+ +Heading +- \link org::kde::plasma::extras::BasicPlasmoidHeading BasicPlasmoidHeading \endlink +- \link org::kde::plasma::extras::PlasmoidHeading PlasmoidHeading \endlink + +List views +- \link org::kde::plasma::extras::ExpandableListItem ExpandableListItem \endlink +- \link org::kde::plasma::extras::ListItem ListItem \endlink +- \link org::kde::plasma::extras::Highlight Highlight \endlink +- \link org::kde::plasma::extras::PlaceholderMessage PlaceholderMessage \endlink + +Text formatting +- \link org::kde::plasma::extras::Heading Heading \endlink +- \link org::kde::plasma::extras::Title Title \endlink + +Animations +- \link org::kde::plasma::extras::ActivateAnimation ActivateAnimation \endlink +- \link org::kde::plasma::extras::AppearAnimation AppearAnimation \endlink +- \link org::kde::plasma::extras::PressedAnimation PressedAnimation \endlink +- \link org::kde::plasma::extras::ReleasedAnimation ReleasedAnimation \endlink + +Obsolete components +- \link org::kde::plasma::extras::App App \endlink +- \link org::kde::plasma::extras::PageRow PageRow \endlink +- \link org::kde::plasma::extras::ScrollArea ScrollArea \endlink +- \link FallbackComponent FallbackComponent \endlink + +*/ + +// DOXYGEN_SET_PROJECT_NAME = PlasmaExtraComponents +// vim:ts=4:sw=4:expandtab:filetype=doxygen diff --git a/src/declarativeimports/plasmaextracomponents/qmenu.cpp b/src/declarativeimports/plasmaextracomponents/qmenu.cpp new file mode 100644 index 0000000..fe8f8e5 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qmenu.cpp @@ -0,0 +1,571 @@ +/* + SPDX-FileCopyrightText: 2011 Viranch Mehta + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "qmenu.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "plasma.h" + +QMenuProxy::QMenuProxy(QObject *parent) + : QObject(parent) + , m_menu(nullptr) + , m_status(Closed) + , m_placement(LeftPosedTopAlignedPopup) + , m_preferSeamlessEdges(false) +{ + if (qobject_cast(QCoreApplication::instance())) { + m_menu = new QMenu(nullptr); + // Breeze and Oxygen have rounded corners on menus. They set this attribute in polish() + // but at that time the underlying surface has already been created where setting this + // flag makes no difference anymore (Bug 385311) + m_menu->setAttribute(Qt::WA_TranslucentBackground); + + KAcceleratorManager::manage(m_menu); + connect(m_menu, &QMenu::triggered, this, &QMenuProxy::itemTriggered); + connect(m_menu, &QMenu::aboutToHide, this, [this]() { + m_status = Closed; + Q_EMIT statusChanged(); + }); + } +} + +QMenuProxy::~QMenuProxy() +{ + delete m_menu; +} + +QQmlListProperty QMenuProxy::content() +{ + return QQmlListProperty(this, &m_items); +} + +int QMenuProxy::actionCount() const +{ + return m_items.count(); +} + +QMenuItem *QMenuProxy::action(int index) const +{ + return m_items.at(index); +} + +QMenuProxy::Status QMenuProxy::status() const +{ + return m_status; +} + +QObject *QMenuProxy::visualParent() const +{ + return m_visualParent.data(); +} + +void QMenuProxy::setVisualParent(QObject *parent) +{ + if (m_visualParent.data() == parent) { + return; + } + + // if the old parent was a QAction, disconnect the menu from it + QAction *action = qobject_cast(m_visualParent.data()); + if (action) { + action->setMenu(nullptr); + m_menu->clear(); + } + // if parent is a QAction, become a submenu + action = qobject_cast(parent); + if (action) { + action->setMenu(m_menu); + m_menu->clear(); + for (QMenuItem *item : std::as_const(m_items)) { + if (item->section()) { + if (!item->isVisible()) { + continue; + } + + m_menu->addSection(item->text()); + } else { + m_menu->addAction(item->action()); + } + } + m_menu->updateGeometry(); + } + + m_visualParent = parent; + Q_EMIT visualParentChanged(); +} + +QWindow *QMenuProxy::transientParent() +{ + if (!m_menu || !m_menu->windowHandle()) { + return nullptr; + } + return m_menu->windowHandle()->transientParent(); +} + +void QMenuProxy::setTransientParent(QWindow *parent) +{ + if (!m_menu || !m_menu->windowHandle() || parent == m_menu->windowHandle()->transientParent()) { + return; + } + + m_menu->windowHandle()->setTransientParent(parent); + Q_EMIT transientParentChanged(); +} + +QMenuProxy::PopupPlacement QMenuProxy::placement() const +{ + return m_placement; +} + +void QMenuProxy::setPlacement(QMenuProxy::PopupPlacement placement) +{ + if (m_placement != placement) { + m_placement = placement; + + Q_EMIT placementChanged(); + } +} + +bool QMenuProxy::preferSeamlessEdges() const +{ + return m_preferSeamlessEdges; +} + +void QMenuProxy::setPreferSeamlessEdges(bool request) +{ + if (m_preferSeamlessEdges != request) { + m_preferSeamlessEdges = request; + + Q_EMIT preferSeamlessEdgesChanged(); + } +} + +int QMenuProxy::minimumWidth() const +{ + return m_menu->minimumWidth(); +} + +void QMenuProxy::setMinimumWidth(int width) +{ + if (m_menu->minimumWidth() != width) { + m_menu->setMinimumWidth(width); + + Q_EMIT minimumWidthChanged(); + } +} + +int QMenuProxy::maximumWidth() const +{ + return m_menu->maximumWidth(); +} + +void QMenuProxy::setMaximumWidth(int width) +{ + if (m_menu->maximumWidth() != width) { + m_menu->setMaximumWidth(width); + + Q_EMIT maximumWidthChanged(); + } +} + +void QMenuProxy::resetMaximumWidth() +{ + setMaximumWidth(QWIDGETSIZE_MAX); +} + +bool QMenuProxy::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::ChildAdded: { + QChildEvent *ce = static_cast(event); + QMenuItem *mi = qobject_cast(ce->child()); + // FIXME: linear complexity here + if (mi && !m_items.contains(mi)) { + if (mi->separator()) { + m_menu->addSection(mi->text()); + } else { + m_menu->addAction(mi->action()); + } + m_items << mi; + } + break; + } + + case QEvent::ChildRemoved: { + QChildEvent *ce = static_cast(event); + QMenuItem *mi = qobject_cast(ce->child()); + + // FIXME: linear complexity here + if (mi) { + m_menu->removeAction(mi->action()); + m_items.removeAll(mi); + } + break; + } + + default: + break; + } + + return QObject::event(event); +} + +void QMenuProxy::clearMenuItems() +{ + qDeleteAll(m_items); + m_items.clear(); +} + +void QMenuProxy::addMenuItem(const QString &text) +{ + QMenuItem *item = new QMenuItem(); + item->setText(text); + m_menu->addAction(item->action()); + m_items << item; +} + +void QMenuProxy::addMenuItem(QMenuItem *item, QMenuItem *before) +{ + if (before) { + if (m_items.contains(item)) { + m_menu->removeAction(item->action()); + m_items.removeAll(item); + } + + m_menu->insertAction(before->action(), item->action()); + + const int index = m_items.indexOf(before); + + if (index != -1) { + m_items.insert(index, item); + } else { + m_items << item; + } + + } else if (!m_items.contains(item)) { + m_menu->addAction(item->action()); + m_items << item; + } + connect(item, &QMenuItem::destroyed, this, [this, item]() { + removeMenuItem(item); + }); +} + +void QMenuProxy::addSection(const QString &text) +{ + m_menu->addSection(text); +} + +void QMenuProxy::removeMenuItem(QMenuItem *item) +{ + if (!item) { + return; + } + + m_menu->removeAction(item->action()); + m_items.removeOne(item); +} + +void QMenuProxy::itemTriggered(QAction *action) +{ + for (int i = 0; i < m_items.count(); ++i) { + QMenuItem *item = m_items.at(i); + if (item->action() == action) { + Q_EMIT triggered(item); + Q_EMIT triggeredIndex(i); + break; + } + } +} + +void QMenuProxy::rebuildMenu() +{ + m_menu->clear(); + + for (QMenuItem *item : std::as_const(m_items)) { + if (item->section()) { + if (!item->isVisible()) { + continue; + } + + m_menu->addSection(item->text()); + } else { + m_menu->addAction(item->action()); + if (item->action()->menu()) { + // This ensures existence of the QWindow + m_menu->winId(); + item->action()->menu()->winId(); + item->action()->menu()->windowHandle()->setTransientParent(m_menu->windowHandle()); + } + } + } + + m_menu->adjustSize(); +} + +// Map to global coordinate space, accounting for embedded offscreen windows, e.g. QQuickWidget. +static QPoint mapToGlobalUsingRenderWindowOfItem(const QQuickItem *parentItem, QPointF posF) +{ + QPoint pos = posF.toPoint(); // XXX: Drop rounding if mapToGlobal ever supports floating points + if (QQuickWindow *quickWindow = parentItem->window()) { + QPoint offset; + if (auto renderWindow = QQuickRenderControl::renderWindowFor(quickWindow, &offset)) { + QPoint relativePos = pos + offset; + return renderWindow->mapToGlobal(relativePos); + } else { + return quickWindow->mapToGlobal(pos); + } + } else { + return pos; + } +} + +void QMenuProxy::open(int x, int y) +{ + QQuickItem *parentItem = nullptr; + + if (m_visualParent) { + parentItem = qobject_cast(m_visualParent.data()); + } else { + parentItem = qobject_cast(parent()); + } + + if (!parentItem) { + return; + } + + rebuildMenu(); + + QPointF posLocal = parentItem->mapToScene(QPointF(x, y)); + + QPoint posGlobal = mapToGlobalUsingRenderWindowOfItem(parentItem, posLocal); + + setupSeamlessEdges(std::nullopt); + + openInternal(posGlobal); +} + +void QMenuProxy::openRelative() +{ + QQuickItem *parentItem = nullptr; + + if (m_visualParent) { + parentItem = qobject_cast(m_visualParent.data()); + } else { + parentItem = qobject_cast(parent()); + } + + if (!parentItem) { + return; + } + + rebuildMenu(); + + QPointF posLocal; + QPoint posGlobal; + + auto boundaryCorrection = [this, &posLocal, &posGlobal, parentItem](int hDelta, int vDelta) { + if (auto window = parentItem->window(); // + QScreen *screen = window->screen()) { + QRect geo = screen->geometry(); + + QPoint pos = mapToGlobalUsingRenderWindowOfItem(parentItem, posLocal); + + if (pos.x() < geo.x()) { + pos.setX(pos.x() + hDelta); + } + if (pos.y() < geo.y()) { + pos.setY(pos.y() + vDelta); + } + + if (geo.x() + geo.width() < pos.x() + this->m_menu->width()) { + pos.setX(pos.x() + hDelta); + } + if (geo.y() + geo.height() < pos.y() + this->m_menu->height()) { + pos.setY(pos.y() + vDelta); + } + posGlobal = pos; + } else { + posGlobal = posLocal.toPoint(); + } + }; + + const QQmlProperty enabledProp(parentItem, QStringLiteral("LayoutMirroring.enabled"), qmlContext(parentItem)); + const bool mirrored(enabledProp.read().toBool()); + const auto placement = visualPopupPlacement(m_placement, mirrored ? Qt::RightToLeft : Qt::LeftToRight); + + using namespace Plasma; + + switch (placement) { + case TopPosedLeftAlignedPopup: { + posLocal = parentItem->mapToScene(QPointF(0, -m_menu->height())); + boundaryCorrection(-m_menu->width() + parentItem->width(), m_menu->height() + parentItem->height()); + break; + } + case LeftPosedTopAlignedPopup: { + posLocal = parentItem->mapToScene(QPointF(-m_menu->width(), 0)); + boundaryCorrection(m_menu->width() + parentItem->width(), -m_menu->height() + parentItem->height()); + break; + } + case TopPosedRightAlignedPopup: + posLocal = parentItem->mapToScene(QPointF(parentItem->width() - m_menu->width(), -m_menu->height())); + boundaryCorrection(m_menu->width() - parentItem->width(), m_menu->height() + parentItem->height()); + break; + case RightPosedTopAlignedPopup: { + posLocal = parentItem->mapToScene(QPointF(parentItem->width(), 0)); + boundaryCorrection(-m_menu->width() - parentItem->width(), -m_menu->height() + parentItem->height()); + break; + } + case LeftPosedBottomAlignedPopup: + posLocal = parentItem->mapToScene(QPointF(-m_menu->width(), -m_menu->height() + parentItem->height())); + boundaryCorrection(m_menu->width() + parentItem->width(), m_menu->height() - parentItem->height()); + break; + case BottomPosedLeftAlignedPopup: { + posLocal = parentItem->mapToScene(QPointF(0, parentItem->height())); + boundaryCorrection(-m_menu->width() + parentItem->width(), -m_menu->height() - parentItem->height()); + break; + } + case BottomPosedRightAlignedPopup: { + posLocal = parentItem->mapToScene(QPointF(parentItem->width() - m_menu->width(), parentItem->height())); + boundaryCorrection(m_menu->width() - parentItem->width(), -m_menu->height() - parentItem->height()); + break; + } + case RightPosedBottomAlignedPopup: { + posLocal = parentItem->mapToScene(QPointF(parentItem->width(), -m_menu->height() + parentItem->height())); + boundaryCorrection(-m_menu->width() - parentItem->width(), m_menu->height() - parentItem->height()); + break; + } + default: + open(); + return; + } + + setupSeamlessEdges(std::optional(placement)); + + openInternal(posGlobal); +} + +void QMenuProxy::openInternal(QPoint pos) +{ + QQuickItem *parentItem = this->parentItem(); + + if (parentItem && parentItem->window()) { + // create the QWindow + m_menu->winId(); + m_menu->windowHandle()->setTransientParent(parentItem->window()); + + // Workaround for QTBUG-59044 + // pre 5.8.0 QQuickWindow code is "item->grabMouse(); sendEvent(item, mouseEvent)" + // post 5.8.0 QQuickWindow code is sendEvent(item, mouseEvent); item->grabMouse() + QMetaObject::invokeMethod( + this, + [this]() { + QQuickItem *parentItem = this->parentItem(); + if (parentItem && parentItem->window() && parentItem->window()->mouseGrabberItem()) { + parentItem->window()->mouseGrabberItem()->ungrabMouse(); + } + }, + Qt::QueuedConnection); + // end workaround + } + + m_menu->popup(pos); + m_status = Open; + Q_EMIT statusChanged(); +} + +QQuickItem *QMenuProxy::parentItem() const +{ + if (m_visualParent) { + return qobject_cast(m_visualParent.data()); + } + + return qobject_cast(parent()); +} + +void QMenuProxy::close() +{ + m_menu->hide(); +} + +QMenuProxy::PopupPlacement QMenuProxy::visualPopupPlacement(PopupPlacement placement, Qt::LayoutDirection layoutDirection) +{ + const bool mirrored = (layoutDirection == Qt::LayoutDirectionAuto) ? qApp->isRightToLeft() : (layoutDirection == Qt::RightToLeft); + + if (!mirrored) { + return placement; + } + + switch (placement) { + case TopPosedLeftAlignedPopup: + return TopPosedRightAlignedPopup; + case TopPosedRightAlignedPopup: + return TopPosedLeftAlignedPopup; + case LeftPosedTopAlignedPopup: + return RightPosedTopAlignedPopup; + case LeftPosedBottomAlignedPopup: + return RightPosedBottomAlignedPopup; + case BottomPosedLeftAlignedPopup: + return BottomPosedRightAlignedPopup; + case BottomPosedRightAlignedPopup: + return BottomPosedLeftAlignedPopup; + case RightPosedTopAlignedPopup: + return LeftPosedTopAlignedPopup; + case RightPosedBottomAlignedPopup: + return LeftPosedBottomAlignedPopup; + case FloatingPopup: + default: + return placement; + } +} + +Qt::Edges QMenuProxy::seamlessEdgesForPlacement(std::optional placement) +{ + if (m_preferSeamlessEdges && placement.has_value()) { + switch (placement.value()) { + case TopPosedLeftAlignedPopup: + case TopPosedRightAlignedPopup: + return Qt::BottomEdge; + + case LeftPosedTopAlignedPopup: + case LeftPosedBottomAlignedPopup: + return Qt::RightEdge; + + case BottomPosedLeftAlignedPopup: + case BottomPosedRightAlignedPopup: + return Qt::TopEdge; + + case RightPosedTopAlignedPopup: + case RightPosedBottomAlignedPopup: + return Qt::LeftEdge; + + case FloatingPopup: + default: + break; + } + } + + return Qt::Edges(); +} + +void QMenuProxy::setupSeamlessEdges(std::optional placement) +{ + // Note: Assume that seamless edges don't affect size of the menu. + auto edges = seamlessEdgesForPlacement(placement); + m_menu->setProperty("_breeze_menu_seamless_edges", QVariant::fromValue(edges)); +} + +#include "moc_qmenu.cpp" diff --git a/src/declarativeimports/plasmaextracomponents/qmenu.h b/src/declarativeimports/plasmaextracomponents/qmenu.h new file mode 100644 index 0000000..a0afcfe --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qmenu.h @@ -0,0 +1,251 @@ +/* + SPDX-FileCopyrightText: 2011 Viranch Mehta + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#ifndef QMENU_PROXY_H +#define QMENU_PROXY_H + +#include "plasma.h" +#include "qmenuitem.h" +#include +#include +#include +#include +#include + +#include + +class QDeclarativeItem; +class QQuickItem; + +/** + * @class Menu + * + * An Item provides a menu for use in context specific situations. + * You can specify the position for the menu to open by setting its visualParent. + * MenuItems should be used to draw entries in the menu. + * The open() function opens up the menu at the given visualParent. + * + * + * Example usage: + * @code + * import org.kde.plasma.extras 2.0 as PlasmaExtras + * + * [...] + * PlasmaExtras.Menu { + * id: menu + * ... + * PlasmaExtras.MenuItem { + * text: "Delete" + * onClicked: { + * myListItem.remove(); + * } + * } + * } + * PlasmaExtras.Button { + * id: btn + * onClicked: { + * menu.visualParent = btn + * menu.open() + * } + * } + * [...] + * @endcode + * + */ + +class QMenuProxy : public QObject +{ + Q_OBJECT + QML_ELEMENT + QML_NAMED_ELEMENT(Menu) + + Q_PROPERTY(QQmlListProperty content READ content CONSTANT) + Q_CLASSINFO("DefaultProperty", "content") + + /** + * This is a hint to the window manager that this window is a dialog or pop-up on + * behalf of the given window. + */ + Q_PROPERTY(QWindow *transientParent READ transientParent WRITE setTransientParent NOTIFY transientParentChanged) + + /** + * The visualParent is used to position the menu. it can be an item on the + * scene, like a button (that will open the menu on clicked) or another menuitem + * (in this case this will be a submenu). + */ + Q_PROPERTY(QObject *visualParent READ visualParent WRITE setVisualParent NOTIFY visualParentChanged()) + Q_PROPERTY(Status status READ status NOTIFY statusChanged) + + /** + * This property holds the requested placement for the menu. It will be + * automatically flipped horizontally in Right-to-left User Interfaces. + * Additionally it may be flipped to the other side in any direction if + * there is not enough space on a screen to fit the menu. + */ + Q_PROPERTY(PopupPlacement placement READ placement WRITE setPlacement NOTIFY placementChanged) + + /** + * This property allows to request a seamless appearance in the direction + * adjacent to the visualParent item, as determined by the menu's placement + * policy. + */ + Q_PROPERTY(bool preferSeamlessEdges READ preferSeamlessEdges WRITE setPreferSeamlessEdges NOTIFY preferSeamlessEdgesChanged) + + /** + * A minimum width for the menu. + */ + Q_PROPERTY(int minimumWidth READ minimumWidth WRITE setMinimumWidth NOTIFY minimumWidthChanged) + + /** + * A maximum width for the menu. + * + * @since 5.31 + */ + Q_PROPERTY(int maximumWidth READ maximumWidth WRITE setMaximumWidth RESET resetMaximumWidth NOTIFY maximumWidthChanged) + +public: + /** + * The popup position enumeration relatively to his attached widget + * + **/ + enum PopupPlacement { + FloatingPopup = 0, /**< Free floating, non attached popup */ + TopPosedLeftAlignedPopup, /**< Popup positioned on the top, aligned + to the left of the widget */ + TopPosedRightAlignedPopup, /**< Popup positioned on the top, aligned + to the right of the widget */ + LeftPosedTopAlignedPopup, /**< Popup positioned on the left, aligned + to the top of the widget */ + LeftPosedBottomAlignedPopup, /**< Popup positioned on the left, aligned + to the bottom of the widget */ + BottomPosedLeftAlignedPopup, /**< Popup positioned on the bottom, aligned + to the left of the widget */ + BottomPosedRightAlignedPopup, /**< Popup positioned on the bottom, aligned + to the right of the widget */ + RightPosedTopAlignedPopup, /**< Popup positioned on the right, aligned + to the top of the widget */ + RightPosedBottomAlignedPopup, /**< Popup positioned on the right, aligned + to the bottom of the widget */ + }; + Q_ENUM(PopupPlacement) + + enum Status { + Opening, + Open, + Closing, + Closed, + }; + Q_ENUM(Status) + + explicit QMenuProxy(QObject *parent = nullptr); + ~QMenuProxy() override; + + QQmlListProperty content(); + int actionCount() const; + QMenuItem *action(int) const; + Status status() const; + + QObject *visualParent() const; + void setVisualParent(QObject *parent); + + QWindow *transientParent(); + void setTransientParent(QWindow *parent); + + PopupPlacement placement() const; + void setPlacement(PopupPlacement placement); + + bool preferSeamlessEdges() const; + void setPreferSeamlessEdges(bool request); + + int minimumWidth() const; + void setMinimumWidth(int width); + + int maximumWidth() const; + void setMaximumWidth(int maximumWidth); + void resetMaximumWidth(); + + /** + * This opens the menu at position x,y on the given visualParent. By default x and y are set to 0 + */ + Q_INVOKABLE void open(int x = 0, int y = 0); + /** + * This opens the menu at the specified placement relative to the visualParent. + */ + Q_INVOKABLE void openRelative(); + /** + * This closes the menu + */ + Q_INVOKABLE void close(); + /** + * This removes all menuItems inside the menu + */ + Q_INVOKABLE void clearMenuItems(); + /** + * This adds a menu item from a String + */ + Q_INVOKABLE void addMenuItem(const QString &text); + /** + * This adds MenuItem 'item' to the menu before MenuItem 'before'. + * If MenuItem 'before' is 0 or does not exist in the menu, 'item' + * is appended to the menu instead. + * If MenuItem 'item' already exists in the menu, it is removed and + * inserted at the new position. + */ + Q_INVOKABLE void addMenuItem(QMenuItem *item, QMenuItem *before = nullptr); + /** + * This adds a section header with a string used as name for the section + */ + Q_INVOKABLE void addSection(const QString &text); + + /** + * This removes MenuItem 'item' + * + * @since 5.27 + */ + Q_INVOKABLE void removeMenuItem(QMenuItem *item); + +protected: + bool event(QEvent *event) override; + +Q_SIGNALS: + void statusChanged(); + void visualParentChanged(); + void transientParentChanged(); + void placementChanged(); + void preferSeamlessEdgesChanged(); + void minimumWidthChanged(); + void maximumWidthChanged(); + void triggered(QMenuItem *item); + void triggeredIndex(int index); + +private Q_SLOTS: + void itemTriggered(QAction *item); + +private: + void rebuildMenu(); + void openInternal(QPoint pos); + QQuickItem *parentItem() const; + /* + * Mirrors popup placement horizontally in Right-To-Left environments. + * + * Mirroring behavior can be explicitly overridden by passing a specific + * direction with layoutDirection parameter, or left at default value of + * Qt::LayoutDirectionAuto, in which case it will be deduced from shared + * QGuiApplication instance. + **/ + static PopupPlacement visualPopupPlacement(PopupPlacement placement, Qt::LayoutDirection layoutDirection = Qt::LayoutDirectionAuto); + Qt::Edges seamlessEdgesForPlacement(std::optional placement); + void setupSeamlessEdges(std::optional placement); + + QList m_items; + QMenu *m_menu; + Status m_status; + QPointer m_visualParent; + PopupPlacement m_placement; + bool m_preferSeamlessEdges; +}; + +#endif // QMENU_PROXY_H diff --git a/src/declarativeimports/plasmaextracomponents/qmenuitem.cpp b/src/declarativeimports/plasmaextracomponents/qmenuitem.cpp new file mode 100644 index 0000000..068f171 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qmenuitem.cpp @@ -0,0 +1,159 @@ +/* + SPDX-FileCopyrightText: 2011 Viranch Mehta + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "qmenuitem.h" + +QMenuItem::QMenuItem(QObject *parent) + : QObject(parent) + , m_action(nullptr) + , m_section(false) +{ + setAction(new QAction(this)); +} + +QAction *QMenuItem::action() const +{ + return m_action; +} + +void QMenuItem::setAction(QAction *a) +{ + if (m_action != a) { + if (m_action) { + disconnect(m_action, nullptr, this, nullptr); + + if (m_action->parent() == this) { + delete m_action; + m_action = nullptr; + } + } + + if (a) { + m_action = a; + } else { + // don't end up with no action, create an invisible one instead + m_action = new QAction(this); + m_action->setVisible(false); + } + + setVisible(m_action->isVisible()); + setEnabled(m_action->isEnabled()); + + connect(m_action, &QAction::changed, this, &QMenuItem::textChanged); + connect(m_action, &QAction::checkableChanged, this, &QMenuItem::checkableChanged); + connect(m_action, &QAction::enabledChanged, this, &QMenuItem::enabledChanged); + connect(m_action, &QAction::visibleChanged, this, &QMenuItem::visibleChanged); + connect(m_action, &QAction::toggled, this, &QMenuItem::toggled); + connect(m_action, &QAction::triggered, this, &QMenuItem::clicked); + // HACK QMenuItem doesn't delete other people's QAction (see m_action->parent() check above) + // but it does not take kindly to the QAction being deleted under it + // as a workaround for crashing when this happens, replace it by a dummy action again + // TODO this entire ownership handling in QMenu(Item) needs to be refactored... + connect(m_action, &QObject::destroyed, this, [this] { + if (m_action->parent() != this) { + m_action = new QAction(this); + m_action->setVisible(false); + Q_EMIT actionChanged(); + } + }); + + connect(this, &QObject::destroyed, this, &QMenuItem::deleteLater); + + Q_EMIT actionChanged(); + } +} + +QVariant QMenuItem::icon() const +{ + return m_icon; +} + +void QMenuItem::setIcon(const QVariant &i) +{ + m_icon = i; + if (i.canConvert()) { + m_action->setIcon(i.value()); + } else if (i.canConvert()) { + m_action->setIcon(QIcon::fromTheme(i.toString())); + } + Q_EMIT iconChanged(); +} + +bool QMenuItem::separator() const +{ + return m_action->isSeparator(); +} + +void QMenuItem::setSeparator(bool s) +{ + m_action->setSeparator(s); +} + +bool QMenuItem::section() const +{ + return m_section; +} + +void QMenuItem::setSection(bool s) +{ + m_section = s; +} + +QString QMenuItem::text() const +{ + return m_action->text(); +} + +void QMenuItem::setText(const QString &t) +{ + if (m_action->text() != t) { + m_action->setText(t); + // signal comes from m_action + } +} + +bool QMenuItem::checkable() const +{ + return m_action->isCheckable(); +} + +void QMenuItem::setCheckable(bool checkable) +{ + m_action->setCheckable(checkable); +} + +bool QMenuItem::checked() const +{ + return m_action->isChecked(); +} + +void QMenuItem::setChecked(bool checked) +{ + m_action->setChecked(checked); +} + +bool QMenuItem::isEnabled() const +{ + return m_action->isEnabled(); +} + +void QMenuItem::setEnabled(bool enabled) +{ + m_action->setEnabled(enabled); +} + +bool QMenuItem::isVisible() const +{ + return m_action->isVisible(); +} + +void QMenuItem::setVisible(bool visible) +{ + m_action->setVisible(visible); +} + +#include "moc_qmenuitem.cpp" diff --git a/src/declarativeimports/plasmaextracomponents/qmenuitem.h b/src/declarativeimports/plasmaextracomponents/qmenuitem.h new file mode 100644 index 0000000..cf58893 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qmenuitem.h @@ -0,0 +1,88 @@ +/* + SPDX-FileCopyrightText: 2011 Viranch Mehta + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#ifndef QMENUITEM_H +#define QMENUITEM_H + +#include +#include + +#include + +class QMenuItem : public QObject +{ + Q_OBJECT + QML_ELEMENT + QML_NAMED_ELEMENT(MenuItem) + + /** + * The parent object + */ + Q_PROPERTY(QObject *parent READ parent WRITE setParent) + + /** + * If true, the menu item will behave like a separator + */ + Q_PROPERTY(bool separator READ separator WRITE setSeparator NOTIFY separatorChanged) + /** + * If true, the menu item will behave like a section + */ + Q_PROPERTY(bool section READ section WRITE setSection NOTIFY sectionChanged) + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) + Q_PROPERTY(QVariant icon READ icon WRITE setIcon NOTIFY iconChanged) + Q_PROPERTY(QAction *action READ action WRITE setAction NOTIFY actionChanged) + Q_PROPERTY(bool checkable READ checkable WRITE setCheckable NOTIFY checkableChanged) + Q_PROPERTY(bool checked READ checked WRITE setChecked NOTIFY toggled) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged) + +public: + explicit QMenuItem(QObject *parent = nullptr); + + QAction *action() const; + void setAction(QAction *a); + QVariant icon() const; + void setIcon(const QVariant &i); + bool separator() const; + void setSeparator(bool s); + bool section() const; + void setSection(bool s); + QString text() const; + void setText(const QString &t); + + bool checkable() const; + void setCheckable(bool checkable); + + bool checked() const; + void setChecked(bool checked); + + bool isEnabled() const; + void setEnabled(bool enabled); + + bool isVisible() const; + void setVisible(bool visible); + +Q_SIGNALS: + void clicked(); + + void actionChanged(); + void iconChanged(); + void separatorChanged(); + void sectionChanged(); + void textChanged(); + void toggled(bool checked); + void checkableChanged(); + void enabledChanged(); + void visibleChanged(); + +private: + QAction *m_action; + QVariant m_icon; + bool m_section; +}; + +#endif // QMENUITEM_H diff --git a/src/declarativeimports/plasmaextracomponents/qml/ActionTextField.qml b/src/declarativeimports/plasmaextracomponents/qml/ActionTextField.qml new file mode 100644 index 0000000..7b5ac2d --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/ActionTextField.qml @@ -0,0 +1,175 @@ +// SPDX-FileCopyrightText: 2019 Carl Schwan +// SPDX-License-Identifier: LGPL-2.0-or-later + +import QtQuick +import QtQuick.Controls as QQC2 +import QtQuick.Templates as T +import org.kde.plasma.components as PlasmaComponents3 +import org.kde.kirigami as Kirigami + +/** + * This is advanced textfield. It is recommended to use this class when there + * is a need to create a create a textfield with action buttons (e.g a clear + * action). + * + * For common pattern like, a search field or a password field, prefer using the + * more specifig org::kde::extras::SearchField or org::kde::extras::PasswordField. + * + * Example usage for a search field: + * @code + * import QtQuick.Controls as QQC2 + * import org.kde.plasma.extras as PlasmaExtras + * + * PlasmaExtras.ActionTextField { + * id: searchField + * + * placeholderText: "Search…" + * + * focusSequence: StandardKey.Find + * + * rightActions: [ + * QQC2.Action { + * icon.name: "edit-clear" + * enabled: searchField.text !== "" + * onTriggered: { + * searchField.clear() + * searchField.accepted() + * } + * } + * ] + * + * onAccepted: console.log("Search text is " + searchField.text) + * } + * @endcode + * + * @inherit QtQuick.Controls.TextField + * @since 5.93 + * @author Carl Schwan + */ +PlasmaComponents3.TextField { + id: root + + /** + * This property holds a shortcut sequence that will focus the text field. + * + * @property QtQuick.Shortcut.sequence focusSequence + * @since 5.93 + */ + property alias focusSequence: focusShortcut.sequence + + /** + * This property holds a list of actions that will be displayed on the left side of the text field. + * + * By default this list is empty. + * + * @since 5.93 + */ + property list leftActions + + /** + * This property holds a list of actions that will be displayed on the right side of the text field. + * + * By default this list is empty. + * + * @since 5.93 + */ + property list rightActions + + property alias _leftActionsRow: leftActionsRow + property alias _rightActionsRow: rightActionsRow + + hoverEnabled: true + + topPadding: __hasBackgroundAndMargins ? background.margins.top : 0 + bottomPadding: __hasBackgroundAndMargins ? background.margins.bottom : 0 + + leftPadding: if (root.effectiveHorizontalAlignment === TextInput.AlignRight) { + return _rightActionsRow.width + (__hasBackgroundAndMargins ? background.margins.left : 0); + } else { + return _leftActionsRow.width + (__hasBackgroundAndMargins ? background.margins.left : 0); + } + rightPadding: if (root.effectiveHorizontalAlignment === TextInput.AlignRight) { + return _leftActionsRow.width + (__hasBackgroundAndMargins ? background.margins.right : 0); + } else { + return _rightActionsRow.width + (__hasBackgroundAndMargins ? background.margins.right : 0); + } + + Behavior on leftPadding { + enabled: Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.InOutQuad + } + } + + Behavior on rightPadding { + enabled: Kirigami.Units.longDuration > 0 + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.InOutQuad + } + } + + Shortcut { + id: focusShortcut + onActivated: { + root.forceActiveFocus(Qt.ShortcutFocusReason) + root.selectAll() + } + + // here to make it private + component ActionIcon: Kirigami.Icon { + id: button + + required property T.Action modelData + + implicitWidth: Kirigami.Units.iconSizes.small + implicitHeight: Kirigami.Units.iconSizes.small + + anchors.verticalCenter: parent.verticalCenter + + source: modelData.icon.name.length > 0 ? modelData.icon.name : modelData.icon.source + visible: !(modelData instanceof Kirigami.Action) || modelData.visible + MouseArea { + onClicked: button.modelData.trigger() + cursorShape: Qt.ArrowCursor + anchors.fill: parent + } + } + } + + PlasmaComponents3.ToolTip.visible: focusShortcut.nativeText.length > 0 && root.text.length === 0 && !rightActionsRow.hovered && !leftActionsRow.hovered && hovered + PlasmaComponents3.ToolTip.text: focusShortcut.nativeText + PlasmaComponents3.ToolTip.delay: Kirigami.Settings.tabletMode ? Qt.styleHints.mousePressAndHoldInterval : Kirigami.Units.toolTipDelay + + Row { + id: leftActionsRow + padding: visible ? Kirigami.Units.smallSpacing : 0 + LayoutMirroring.enabled: root.effectiveHorizontalAlignment === TextInput.AlignRight + anchors.left: parent.left + anchors.leftMargin: Kirigami.Units.smallSpacing + anchors.verticalCenter: parent.verticalCenter + height: root.implicitHeight - 2 * Kirigami.Units.smallSpacing + visible: root.leftActions.length > 0 + Repeater { + model: root.leftActions + ActionIcon { } + } + } + + Row { + id: rightActionsRow + padding: visible ? Kirigami.Units.smallSpacing : 0 + layoutDirection: Qt.RightToLeft + LayoutMirroring.enabled: root.effectiveHorizontalAlignment === TextInput.AlignRight + anchors.right: parent.right + anchors.rightMargin: Kirigami.Units.smallSpacing + anchors.verticalCenter: parent.verticalCenter + height: root.implicitHeight - 2 * Kirigami.Units.smallSpacing + visible: root.rightActions.length > 0 + Repeater { + model: root.rightActions + ActionIcon { } + } + } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml b/src/declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml new file mode 100644 index 0000000..ea8b046 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/BasicPlasmoidHeading.qml @@ -0,0 +1,135 @@ +/* + SPDX-FileCopyrightText: 2020 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Templates as T + +import org.kde.plasma.plasmoid +import org.kde.plasma.core as PlasmaCore +import org.kde.plasma.extras as PlasmaExtras +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + + /** + * A standard basic header for plasmoids which has title, a config button and + * a popup menu with all extra plasmoid actions. + * + * By default, it will be invisible when the plasmoid is in the system tray, + * as it provides a replacement header with the same features + * + * @inherit PlasmoidHeading + */ +PlasmoidHeading { + /** + * extraControls: list + * + * Any extra control and button that may be inserted in the heading + */ + default property alias extraControls: extraControlsLayout.data + + visible: !(Plasmoid.containmentDisplayHints & PlasmaCore.Types.ContainmentDrawsPlasmoidHeading) + + contentItem: RowLayout { + Heading { + elide: Text.ElideRight + wrapMode: Text.NoWrap + Layout.fillWidth: true + level: 1 + text: Plasmoid.title + } + RowLayout { + id: extraControlsLayout + visible: children.length > 0 + Layout.fillHeight: true + } + PlasmaComponents.ToolButton { + id: actionsButton + visible: visibleActions > 0 + checked: configMenu.status !== PlasmaExtras.Menu.Closed + property int visibleActions: menuItemFactory.count + property QtObject singleAction: visibleActions === 1 ? menuItemFactory.object.action : null + icon.name: "open-menu-symbolic" + checkable: visibleActions > 1 + contentItem.opacity: visibleActions > 1 + // NOTE: it needs an Icon because QtQuickControls2 buttons cannot load QIcons as their icon + Kirigami.Icon { + parent: actionsButton + anchors.centerIn: parent + active: actionsButton.hovered + implicitWidth: Kirigami.Units.iconSizes.smallMedium + implicitHeight: implicitWidth + source: actionsButton.singleAction !== null ? actionsButton.singleAction.icon : "" + visible: actionsButton.singleAction + } + onToggled: { + if (checked) { + configMenu.openRelative(); + } else { + configMenu.close(); + } + } + onClicked: { + if (singleAction) { + singleAction.trigger(); + } + } + PlasmaComponents.ToolTip { + text: actionsButton.singleAction ? actionsButton.singleAction.text : i18nd("libplasma6", "More actions") + } + PlasmaExtras.Menu { + id: configMenu + visualParent: actionsButton + placement: PlasmaExtras.Menu.BottomPosedLeftAlignedPopup + } + + Instantiator { + id: menuItemFactory + model: { + configMenu.clearMenuItems(); + const configureAction = Plasmoid.internalAction("configure"); + const actions = Plasmoid.contextualActions + .filter(action => action !== configureAction); + return actions; + } + delegate: PlasmaExtras.MenuItem { + required property QtObject modelData // type: QAction + action: modelData + } + onObjectAdded: { + configMenu.addMenuItem(object); + } + } + } + PlasmaComponents.ToolButton { + id: configureButton + + property PlasmaCore.Action internalAction + + function fetchInternalAction() { + internalAction = Plasmoid.internalAction("configure"); + } + + Connections { + target: Plasmoid + function onInternalActionsChanged(actions) { + configureButton.fetchInternalAction(); + } + } + + Component.onCompleted: fetchInternalAction() + + icon.name: "configure" + visible: internalAction !== null + text: internalAction?.text ?? "" + display: T.AbstractButton.IconOnly + PlasmaComponents.ToolTip { + text: configureButton.text + } + onClicked: internalAction?.trigger(); + } + } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/DescriptiveLabel.qml b/src/declarativeimports/plasmaextracomponents/qml/DescriptiveLabel.qml new file mode 100644 index 0000000..5ff4b1e --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/DescriptiveLabel.qml @@ -0,0 +1,42 @@ +/* + SPDX-FileCopyrightText: 2012 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.components + +/** + * This is a descriptive label which uses the plasma theme. The characteristics of + * the text will be automatically set according to the plasma theme. Use this + * components for less important additional data to show in a user interface. + * + * Example usage: + * @code + * import org.kde.plasma.extras as PlasmaExtras + * [...] + * Column { + * PlasmaComponents.Label { text: "Firefox" } + * PlasmaExtras.DescriptiveLabel { text: "Web Browser"} + * [...] + * } + * @endcode + * + * See PlasmaComponents Label and primitive QML Text element API for additional + * properties, methods and signals. + * + * @inherits org::kde::plasma::components::Label + */ +Label { + id: root + + /* + * If a user can interact with this item, for example in a ListView delegate, this + * property should be set to true when the label is being interacted with. + * The default is false. + */ + property bool active: false + + opacity: active ? 0.8 : 0.6 +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml b/src/declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml new file mode 100644 index 0000000..f418d62 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/ExpandableListItem.qml @@ -0,0 +1,647 @@ +/* + SPDX-FileCopyrightText: 2020 Nate Graham + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import QtQuick.Templates as T +import org.kde.plasma.core as PlasmaCore +import org.kde.ksvg as KSvg +import org.kde.plasma.components as PlasmaComponents3 +import org.kde.plasma.extras as PlasmaExtras +import org.kde.kirigami as Kirigami + +/** + * A list item that expands when clicked to show additional actions and/or a + * custom view. + * The list item has a standardized appearance, with an icon on the left badged + * with an optional emblem, a title and optional subtitle to the right, an + * optional default action button, and a button to expand and collapse the list + * item. + * + * When expanded, the list item shows a list of contextually-appropriate actions + * if contextualActions has been defined. + * If customExpandedViewContent has been defined, it will show a custom view. + * If both have been defined, it shows both, with the actions above the custom + * view. + * + * It is not valid to define neither; define one or both. + * + * Note: this component should only be used for lists where the maximum number + * of items is very low, ideally less than 10. For longer lists, consider using + * a different paradigm. + * + * + * Example usage: + * + * @code + * import QtQuick + * import QtQuick.Controls as QQC2 + * import org.kde.kirigami as Kirigami + * import org.kde.plasma.extras as PlasmaExtras + * import org.kde.plasma.components as PlasmaComponents + * + * PlasmaComponents.ScrollView { + * ListView { + * anchors.fill: parent + * focus: true + * currentIndex: -1 + * clip: true + * model: myModel + * highlight: PlasmaExtras.Highlight {} + * highlightMoveDuration: Kirigami.Units.shortDuration + * highlightResizeDuration: Kirigami.Units.shortDuration + * delegate: PlasmaExtras.ExpandableListItem { + * icon: model.iconName + * iconEmblem: model.isPaused ? "emblem-pause" : "" + * title: model.name + * subtitle: model.subtitle + * isDefault: model.isDefault + * defaultActionButtonAction: QQC2.Action { + * icon.name: model.isPaused ? "media-playback-start" : "media-playback-pause" + * text: model.isPaused ? "Resume" : "Pause" + * onTriggered: { + * if (model.isPaused) { + * model.resume(model.name); + * } else { + * model.pause(model.name); + * } + * } + * } + * contextualActions: [ + * QQC2.Action { + * icon.name: "configure" + * text: "Configure…" + * onTriggered: model.configure(model.name); + * } + * ] + * } + * } + * } + * @endcode + */ +Item { + id: listItem + + /** + * icon: var + * The name of the icon used in the list item. + * @sa Kirigami.Icon::source + * + * Required. + */ + property alias icon: listItemIcon.source + + /** + * iconEmblem: var + * The name of the emblem to badge the icon with. + * @sa Kirigami.Icon::source + * + * Optional, defaults to nothing, in which case there is no emblem. + */ + property alias iconEmblem: iconEmblem.source + + /* + * title: string + * The name or title for this list item. + * + * Optional; if not defined, there will be no title and the subtitle will be + * vertically centered in the list item. + */ + property alias title: listItemTitle.text + + /* + * subtitle: string + * The subtitle for this list item, displayed under the title. + * + * Optional; if not defined, there will be no subtitle and the title will be + * vertically centered in the list item. + */ + property alias subtitle: listItemSubtitle.text + + /* + * subtitleCanWrap: bool + * Whether to allow the subtitle to become a multi-line string instead of + * eliding when the text is very long. + * + * Optional, defaults to false. + */ + property bool subtitleCanWrap: false + + /* + * subtitleColor: color + * The color of the subtitle text + * + * Optional; if not defined, the subtitle will use the default text color + */ + property alias subtitleColor: listItemSubtitle.color + + /* + * allowStyledText: bool + * Whether to allow the title, subtitle, and tooltip to contain styled text. + * For performance and security reasons, keep this off unless needed. + * + * Optional, defaults to false. + */ + property bool allowStyledText: false + + /* + * defaultActionButtonAction: T.Action + * The Action to execute when the default button is clicked. + * + * Optional; if not defined, no default action button will be displayed. + */ + property alias defaultActionButtonAction: defaultActionButton.action + + /* + * defaultActionButtonVisible: bool + * When/whether to show to default action button. Useful for making it + * conditionally appear or disappear. + * + * Optional; defaults to true + */ + property bool defaultActionButtonVisible: true + + /* + * showDefaultActionButtonWhenBusy : bool + * Whether to continue showing the default action button while the busy + * indicator is visible. Useful for cancelable actions that could take a few + * seconds and show a busy indicator while processing. + * + * Optional; defaults to false + */ + property bool showDefaultActionButtonWhenBusy: false + + /* + * contextualActions: list + * A list of standard QQC2.Action objects that describes additional actions + * that can be performed on this list item. For example: + * + * @code + * contextualActions: [ + * Action { + * text: "Do something" + * icon.name: "document-edit" + * onTriggered: doSomething() + * }, + * Action { + * text: "Do something else" + * icon.name: "draw-polygon" + * onTriggered: doSomethingElse() + * }, + * Action { + * text: "Do something completely different" + * icon.name: "games-highscores" + * onTriggered: doSomethingCompletelyDifferent() + * } + * ] + * @endcode + * + * Optional; if not defined, no contextual actions will be displayed and + * you should instead assign a custom view to customExpandedViewContent, + * which will be shown when the user expands the list item. + */ + property list contextualActions + + readonly property list __enabledContextualActions: contextualActions.filter(action => action?.enabled ?? false) + + /* + * A custom view to display when the user expands the list item. + * + * This component must define width and height properties. Width should be + * equal to the width of the list item itself, while height: will depend + * on the component itself. + * + * Optional; if not defined, no custom view actions will be displayed and + * you should instead define contextualActions, and then actions will + * be shown when the user expands the list item. + */ + property Component customExpandedViewContent + + /* + * The actual instance of the custom view content, if loaded. + * @since 5.72 + */ + property alias customExpandedViewContentItem: customContentLoader.item + + /* + * isBusy: bool + * Whether or not to display a busy indicator on the list item. Set to true + * while the item should be non-interactive because things are processing. + * + * Optional; defaults to false. + */ + property bool isBusy: false + + /* + * isDefault: bool + * Whether or not this list item should be considered the "default" or + * "Current" item in the list. When set to true, and the list itself has + * more than one item in it, the list item's title and subtitle will be + * drawn in a bold style. + * + * Optional; defaults to false. + */ + property bool isDefault: false + + /** + * expanded: bool + * Whether the expanded view is visible. + * + * @since 5.98 + */ + readonly property alias expanded: expandedView.expanded + + /* + * hasExpandableContent: bool (read-only) + * Whether or not this expandable list item is actually expandable. True if + * this item has either a custom view or else at least one enabled action. + * Otherwise false. + */ + readonly property bool hasExpandableContent: customExpandedViewContent !== null || __enabledContextualActions.length > 0 + + /* + * expand() + * Show the expanded view, growing the list item to its taller size. + */ + function expand() { + if (!listItem.hasExpandableContent) { + return; + } + expandedView.expanded = true + listItem.itemExpanded() + } + + /* + * collapse() + * Hide the expanded view and collapse the list item to its shorter size. + */ + function collapse() { + if (!listItem.hasExpandableContent) { + return; + } + expandedView.expanded = false + listItem.itemCollapsed() + } + + /* + * toggleExpanded() + * Expand or collapse the list item depending on its current state. + */ + function toggleExpanded() { + if (!listItem.hasExpandableContent) { + return; + } + expandedView.expanded ? listItem.collapse() : listItem.expand() + } + + signal itemExpanded() + signal itemCollapsed() + + width: parent ? parent.width : undefined // Assume that we will be used as a delegate, not placed in a layout + height: mainLayout.height + + Behavior on height { + enabled: listItem.ListView.view.highlightResizeDuration > 0 + SmoothedAnimation { // to match the highlight + id: heightAnimation + duration: listItem.ListView.view.highlightResizeDuration || -1 + velocity: listItem.ListView.view.highlightResizeVelocity + easing.type: Easing.InOutCubic + } + } + clip: heightAnimation.running || expandedItemOpacityFade.running + + onEnabledChanged: if (!listItem.enabled) { collapse() } + + Keys.onPressed: event => { + if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { + if (defaultActionButtonAction) { + defaultActionButtonAction.trigger() + } else { + toggleExpanded(); + } + event.accepted = true; + } else if (event.key === Qt.Key_Escape) { + if (expandedView.expanded) { + collapse(); + event.accepted = true; + } + // if not active, we'll let the Escape event pass through, so it can close the applet, etc. + } else if (event.key === Qt.Key_Space) { + toggleExpanded(); + event.accepted = true; + } + } + + KeyNavigation.tab: defaultActionButtonVisible ? defaultActionButton : expandToggleButton + KeyNavigation.right: defaultActionButtonVisible ? defaultActionButton : expandToggleButton + KeyNavigation.down: expandToggleButton.KeyNavigation.down + Keys.onDownPressed: event => { + if (!actionsListLoader.item || ListView.view.currentIndex < 0) { + ListView.view.incrementCurrentIndex(); + const item = ListView.view.currentItem; + if (item) { + item.forceActiveFocus(Qt.TabFocusReason); + } + event.accepted = true; + return; + } + event.accepted = false; // Forward to KeyNavigation.down + } + Keys.onUpPressed: event => { + if (ListView.view.currentIndex === 0) { + event.accepted = false; + } else { + ListView.view.decrementCurrentIndex(); + const item = ListView.view.currentItem; + if (item) { + item.forceActiveFocus(Qt.BacktabFocusReason); + } + event.accepted = true; + } + } + + Accessible.role: Accessible.Button + Accessible.name: title + Accessible.description: subtitle + + // Handle left clicks and taps; don't accept stylus input or else it steals + // events from the buttons on the list item + TapHandler { + enabled: listItem.hasExpandableContent + + acceptedPointerTypes: PointerDevice.Generic | PointerDevice.Finger + + onSingleTapped: { + listItem.ListView.view.currentIndex = index + listItem.toggleExpanded() + } + } + + MouseArea { + anchors.fill: parent + + // This MouseArea used to intercept RightButton to open a context + // menu, but that has been removed, and now it's only used for hover + acceptedButtons: Qt.NoButton + hoverEnabled: true + + // using onPositionChanged instead of onContainsMouseChanged so this doesn't trigger when the list reflows + onPositionChanged: { + // don't change currentIndex if it would make listview scroll + // see https://bugs.kde.org/show_bug.cgi?id=387797 + // this is a workaround till https://bugreports.qt.io/browse/QTBUG-114574 gets fixed + // which would allow a proper solution + if (parent.y - listItem.ListView.view.contentY >= 0 && parent.y - listItem.ListView.view.contentY + parent.height + 1 /* border */ < listItem.ListView.view.height) { + listItem.ListView.view.currentIndex = (containsMouse ? index : -1) + } + } + onExited: if (listItem.ListView.view.currentIndex === index) { + listItem.ListView.view.currentIndex = -1; + } + + ColumnLayout { + id: mainLayout + + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + + spacing: 0 + + RowLayout { + id: mainRowLayout + + Layout.fillWidth: true + Layout.margins: Kirigami.Units.smallSpacing + // Otherwise it becomes taller when the button appears + Layout.minimumHeight: defaultActionButton.height + + // Icon and optional emblem + Kirigami.Icon { + id: listItemIcon + + implicitWidth: Kirigami.Units.iconSizes.medium + implicitHeight: Kirigami.Units.iconSizes.medium + + Kirigami.Icon { + id: iconEmblem + + visible: valid + + anchors.right: parent.right + anchors.bottom: parent.bottom + + implicitWidth: Kirigami.Units.iconSizes.small + implicitHeight: Kirigami.Units.iconSizes.small + } + } + + // Title and subtitle + ColumnLayout { + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter + + spacing: 0 + + Kirigami.Heading { + id: listItemTitle + + visible: text.length > 0 + + Layout.fillWidth: true + + level: 5 + + textFormat: listItem.allowStyledText ? Text.StyledText : Text.PlainText + elide: Text.ElideRight + maximumLineCount: 1 + + // Even if it's the default item, only make it bold when + // there's more than one item in the list, or else there's + // only one item and it's bold, which is a little bit weird + font.weight: listItem.isDefault && listItem.ListView.view.count > 1 + ? Font.Bold + : Font.Normal + } + + PlasmaComponents3.Label { + id: listItemSubtitle + + visible: text.length > 0 + font: Kirigami.Theme.smallFont + + // Otherwise colored text can be hard to see + opacity: color === Kirigami.Theme.textColor ? 0.7 : 1.0 + + Layout.fillWidth: true + + textFormat: listItem.allowStyledText ? Text.StyledText : Text.PlainText + elide: Text.ElideRight + maximumLineCount: subtitleCanWrap ? 9999 : 1 + wrapMode: subtitleCanWrap ? Text.WordWrap : Text.NoWrap + } + } + + // Busy indicator + PlasmaComponents3.BusyIndicator { + id: busyIndicator + + visible: listItem.isBusy + + // Otherwise it makes the list item taller when it appears + Layout.maximumHeight: defaultActionButton.implicitHeight + Layout.maximumWidth: Layout.maximumHeight + } + + // Default action button + PlasmaComponents3.ToolButton { + id: defaultActionButton + + visible: defaultActionButtonAction + && listItem.defaultActionButtonVisible + && (!busyIndicator.visible || listItem.showDefaultActionButtonWhenBusy) + + KeyNavigation.tab: expandToggleButton + KeyNavigation.right: expandToggleButton + KeyNavigation.down: expandToggleButton.KeyNavigation.down + Keys.onUpPressed: event => listItem.Keys.upPressed(event) + + Accessible.name: action !== null ? action.text : "" + } + + // Expand/collapse button + PlasmaComponents3.ToolButton { + id: expandToggleButton + visible: listItem.hasExpandableContent + + display: PlasmaComponents3.AbstractButton.IconOnly + text: expandedView.expanded ? i18ndc("libplasma6", "@action:button", "Collapse") : i18ndc("libplasma6", "@action:button", "Expand") + icon.name: expandedView.expanded ? "collapse" : "expand" + + Keys.onUpPressed: event => listItem.Keys.upPressed(event) + + onClicked: listItem.toggleExpanded() + + PlasmaComponents3.ToolTip { + text: parent.text + } + } + } + + + // Expanded view with actions and/or custom content in it + Item { + id: expandedView + property bool expanded: false + + Layout.preferredHeight: expanded ? + expandedViewLayout.implicitHeight + expandedViewLayout.anchors.topMargin + expandedViewLayout.anchors.bottomMargin : 0 + Layout.fillWidth: true + + opacity: expanded ? 1 : 0 + Behavior on opacity { + enabled: listItem.ListView.view.highlightResizeDuration > 0 + SmoothedAnimation { // to match the highlight + id: expandedItemOpacityFade + duration: listItem.ListView.view.highlightResizeDuration || -1 + // velocity is divided by the default speed, as we're in the range 0-1 + velocity: listItem.ListView.view.highlightResizeVelocity / 200 + easing.type: Easing.InOutCubic + } + } + visible: opacity > 0 + + ColumnLayout { + id: expandedViewLayout + anchors.fill: parent + anchors.margins: Kirigami.Units.smallSpacing + + spacing: Kirigami.Units.smallSpacing + + // Actions list + Loader { + id: actionsListLoader + + visible: status === Loader.Ready + active: expandedView.visible && listItem.__enabledContextualActions.length > 0 + + Layout.fillWidth: true + + sourceComponent: Item { + height: childrenRect.height + width: actionsListLoader.width // basically, parent.width but null-proof + + ColumnLayout { + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: Kirigami.Units.gridUnit + anchors.rightMargin: Kirigami.Units.gridUnit + + spacing: 0 + + Repeater { + id: actionRepeater + + model: listItem.__enabledContextualActions + + delegate: PlasmaComponents3.ToolButton { + required property int index + required property T.Action modelData + + Layout.fillWidth: true + + text: modelData.text + icon.name: modelData.icon.name + + KeyNavigation.up: index > 0 ? actionRepeater.itemAt(index - 1) : expandToggleButton + Keys.onDownPressed: event => { + if (index === actionRepeater.count - 1) { + event.accepted = true; + listItem.ListView.view.incrementCurrentIndex(); + listItem.ListView.view.currentItem.forceActiveFocus(Qt.TabFocusReason); + } else { + event.accepted = false; // Forward to KeyNavigation.down + } + } + + onClicked: { + modelData.trigger() + collapse() + } + } + } + } + } + } + + // Separator between the two items when both are shown + KSvg.SvgItem { + Layout.fillWidth: true + imagePath: "widgets/line" + elementId: "horizontal-line" + visible: actionsListLoader.visible && customContentLoader.visible + } + + // Custom content item, if any + Loader { + id: customContentLoader + visible: status === Loader.Ready + + Layout.fillWidth: true + + active: expandedView.visible + asynchronous: true + sourceComponent: listItem.customExpandedViewContent + } + } + } + } + } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/Heading.qml b/src/declarativeimports/plasmaextracomponents/qml/Heading.qml new file mode 100644 index 0000000..5238a10 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/Heading.qml @@ -0,0 +1,97 @@ +/* + SPDX-FileCopyrightText: 2012 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.components +import org.kde.kirigami as Kirigami + +/** + * A heading label used for subsections of texts. + * + * The characteristics of the text will be automatically set according to the + * plasma theme. Use this components for section titles or headings in your UI, + * for example page or section titles. + * + * Example usage: + * + * @code + * import org.kde.plasma.components as PlasmaComponents3 + * import org.kde.plasma.extras as PlasmaExtras + * [...] + * Column { + * PlasmaExtras.Heading { text: "Fruit sweetness on the rise"; level: 1 } + * PlasmaExtras.Heading { text: "Apples in the sunlight"; level: 2 } + * PlasmaComponents3.Label { text: "Long text about fruit and apples [...]" } + * [...] + * } + * @endcode + * + * The most important property is "text", which applies to the text property of + * Label. See PlasmaComponents Label and primitive QML Text element API for + * additional properties, methods and signals. + */ +Label { + id: heading + + /** + * The level determines how big the section header is display, values + * between 1 (big) and 5 (small) are accepted. (default: 1) + */ + property int level: 1 + + enum Type { + Normal, + Primary, + Secondary + } + + /** + * The type of the heading. This can be: + * + * * PlasmaExtras.Heading.Type.Normal: Create a normal heading (default) + * * PlasmaExtras.Heading.Type.Primary: Makes the heading more prominent. Useful + * when making the heading bigger is not enough. + * * PlasmaExtras.Heading.Type.Secondary: Makes the heading less prominent. + * Useful when an heading is for a less important section in an application. + * + * @since 5.88 + */ + property int type: Heading.Type.Normal + + font.pointSize: __headerPointSize(level) + font.weight: type === Heading.Type.Primary ? Font.DemiBold : Font.Normal + wrapMode: Text.WordWrap + + opacity: type === Heading.Type.Secondary ? 0.7 : 1 + + Accessible.role: Accessible.Heading + + // + // W A R N I N G + // ------------- + // + // This method is not part of the PlasmaExtras API. It exists purely as an + // implementation detail. It may change from version to + // version without notice, or even be removed. + // + // We mean it. + // + function __headerPointSize(level) { + const n = Kirigami.Theme.defaultFont.pointSize; + switch (level) { + case 1: + return n * 1.35; + case 2: + return n * 1.20; + case 3: + return n * 1.15; + case 4: + return n * 1.10; + default: + return n; + } + } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/Highlight.qml b/src/declarativeimports/plasmaextracomponents/qml/Highlight.qml new file mode 100644 index 0000000..fbd6af9 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/Highlight.qml @@ -0,0 +1,98 @@ +/* + SPDX-FileCopyrightText: 2011 Daker Fernandes Pinheiro + SPDX-FileCopyrightText: 2022 Carl Schwan + SPDX-FileCopyrightText: 2023 ivan tkachenko + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.ksvg as KSvg +import org.kde.kirigami as Kirigami + +/** + * @brief Highlight for a list or grid item. + * + * Highlight provides the highlight used to indicate the active + * item in a model view. It is typically used in conjunction with + * the @sa QtQuick.ListView::highlight or the + * @sa QtQuick.GridView::highlight properties. + * + * Provides built-in animation of Behavior on opacity Easing.OutQuad for a + * duration of 50ms (defined in Kirigami.Units.veryShortDuration). + * + * @code{.qml} + * import QtQuick + * import org.kde.plasma.extras as PlasmaExtras + * + * ListView { + * highlightFollowsCurrentItem: true + * highlight: PlasmaExtras.Highlight { } + * highlightMoveDuration: 0 + * highlightResizeDuration: 0 + * currentIndex: -1 + * } + * + * @endcode + * + * @inherit QtQuick.Item + */ +Item { + id: highlight + + /** + * This property holds whether the control is hovered. + * + * This is set automatically when used in a ListView and GridView. + */ + property bool hovered: ListView.view !== null || GridView.view !== null + + /** + * This property holds whether the highlight has a pressed appearance. + */ + property bool pressed: false + + /** + * This property holds the margin hints used by the background. + * + * @property int marginHints + */ + property alias marginHints: background.margins + + /** + * This property holds whether the item is active. True by default. Set it to + * false to visually mark an item that's in the "current item" or "selected" + * state but is not currently being hovered. + */ + property bool active: true + + width: { + const view = ListView.view; + return view ? view.width - view.leftMargin - view.rightMargin : undefined; + } + + KSvg.FrameSvgItem { + id: background + + anchors.fill: parent + + opacity: highlight.active ? 1 : 0.6 + + imagePath: "widgets/viewitem" + prefix: { + if (highlight.pressed) { + return highlight.hovered ? 'selected+hover' : 'selected'; + } + + return highlight.hovered ? 'hover' : 'normal'; + } + + Behavior on opacity { + enabled: Kirigami.Units.veryShortDuration > 0 + NumberAnimation { + duration: Kirigami.Units.veryShortDuration + easing.type: Easing.OutQuad + } + } + } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/ListItem.qml b/src/declarativeimports/plasmaextracomponents/qml/ListItem.qml new file mode 100644 index 0000000..418bc94 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/ListItem.qml @@ -0,0 +1,82 @@ +/* + SPDX-FileCopyrightText: 2020 Carson Black + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.components as PC3 +import org.kde.kirigami as Kirigami +import org.kde.ksvg as KSvg + +PC3.ItemDelegate { + id: __listItem + + /** + * content: list + * + * The content of this ListItem. + */ + default property alias content: __innerItem.data + + /** + * separatorVisible: bool + * + * Whether this ListItem displays a separator. + */ + property bool separatorVisible: true + + /** + * sectionDelegate: bool + * + * Whether this ListItem renders as a section header. + */ + property bool sectionDelegate: false + + /** + * containsMouse: bool + * + * Whether this ListItem contains the mouse. + * + * Alias of Control.hovered. + */ + readonly property bool containsMouse: hovered + + leftPadding: __background.margins.left + rightPadding: __background.margins.right + topPadding: __background.margins.top + bottomPadding: __background.margins.bottom + + // TODO KF6: `implicitContentWidth, implicitBackgroundWidth, leftInset and rightInset are not available in Controls 2.2 which this component is based on. + implicitWidth: (contentItem ? contentItem.implicitWidth : 0) + leftPadding + rightPadding + + // TODO KF6: Make this behave more like the normal Control default. + // Behaving this way for backwards compatibility reasons. + contentItem: Item { + id: __innerItem + } + + background: KSvg.FrameSvgItem { + id: __background + imagePath: "widgets/listitem" + prefix: (__listItem.sectionDelegate ? "section" : + (__listItem.pressed || __listItem.checked) ? "pressed" : "normal") + + anchors.fill: parent + visible: __listItem.ListView.view ? __listItem.ListView.view.highlight === null : true + + KSvg.SvgItem { + svg: KSvg.Svg { + imagePath: "widgets/listitem" + } + elementId: "separator" + anchors { + left: parent.left + right: parent.right + top: parent.top + } + height: naturalSize.height + visible: __listItem.separatorVisible && (__listItem.sectionDelegate || (typeof(index) != "undefined" && index > 0 && !__listItem.checked && !__listItem.pressed)) + } + } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/ListSectionHeader.qml b/src/declarativeimports/plasmaextracomponents/qml/ListSectionHeader.qml new file mode 100644 index 0000000..35824a3 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/ListSectionHeader.qml @@ -0,0 +1,94 @@ +/* + * SPDX-FileCopyrightText: 2019 Björn Feber + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ + +import QtQuick +import QtQuick.Layouts +import org.kde.kirigami as Kirigami +import org.kde.ksvg as KSvg +import org.kde.plasma.components as PlasmaComponents + +/** + * @brief A section delegate for the primitive ListView component. + * + * It's intended to make all listviews look coherent, mirroring the style + * of the Kirigami version, but with the separator line being an SVG from the + * Plasma theme rather than a simple line. + * + * Any additional content items will be positioned in a row at the trailing side + * of this component. + * + * + * Example usage: + * @code + * import QtQuick + * import org.kde.plasma.components as PlasmaComponents + * import org.kde.plasma.extras as PlasmaExtras + * + * ListView { + * section.delegate: PlasmaExtras.ListSectionHeader { + * label: section + * + * PlasmaComponents.Button { + * text: "Button 1" + * } + * PlasmaComponents.Button { + * text: "Button 2" + * } + * } + * } + * @endcode + */ +PlasmaComponents.ItemDelegate { + id: listSection + + /** + * @brief This property sets the text of the ListView's section header. + * @property string label + */ + property alias label: listSection.text + + default property alias _contents: rowLayout.data + + hoverEnabled: false + + activeFocusOnTab: false + + // we do not need a background + background: null + + topPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing + + contentItem: RowLayout { + id: rowLayout + spacing: Kirigami.Units.largeSpacing + + Kirigami.Heading { + Layout.maximumWidth: rowLayout.width + Layout.alignment: Qt.AlignVCenter + + opacity: 0.7 + level: 5 + type: Kirigami.Heading.Primary + text: listSection.text + elide: Text.ElideRight + + // we override the Primary type's font weight (DemiBold) for Bold for contrast with small text + font.weight: Font.Bold + + Accessible.ignored: true + } + + KSvg.SvgItem { + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter + + imagePath: "widgets/line" + elementId: "horizontal-line" + + Accessible.ignored: true + } + } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/ModelContextMenu.qml b/src/declarativeimports/plasmaextracomponents/qml/ModelContextMenu.qml new file mode 100644 index 0000000..afd78f6 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/ModelContextMenu.qml @@ -0,0 +1,71 @@ +/* + SPDX-FileCopyrightText: 2014 David Edmundson + SPDX-FileCopyrightText: 2017 Kai Uwe Broulik + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import org.kde.plasma.extras as PlasmaExtras + +import QtQuick +import QtQml + +/** + * A ModelContextMenu creates a context menu with items populated from a model or a QList. + * For standard item models, actions are created using the following model role names or properties: + * @li @c display - a string contains the action name + * @li @c decoration - an icon to display + * @li @c separator - boolean that will add a separator in the list + * + * + * + * Example code: + * + * @code + * ModelContextMenu { + * id: menu + * visualParent: someButton + * model: myModel + * } + * + * Button { + * id: someButton + * onClicked: menu.popup() + * } + * @endcode + */ + +PlasmaExtras.Menu { + id: menu + + /** + * The model containing menu items + */ + property alias model: instantiator.model + + /** + * This signal is emitted when a menu item is clicked. + * The attached model properties for that menu item are passed as an argument + */ + signal clicked(var model) + + //ContextMenu cannot have child items, so in order to have ContextMenu as the root object of this item + //we create a new property which contains an item which can then load the child items + property Instantiator _children: Instantiator { + id: instantiator + delegate: PlasmaExtras.MenuItem { + //for QList Repeater adds an attached property modelData + //for QAbstractItemModel* it doesn't. Not checking causes errors + text: (typeof(modelData) != "undefined" ? modelData.text : model.display) || "" + icon: typeof(modelData) != "undefined" ? modelData.icon : model.decoration + separator: (typeof(modelData) != "undefined" ? modelData.separator : model.separator === true) || false + section: (typeof(modelData) != "undefined" ? modelData.section : model.section === true) || false + onClicked: { + menu.clicked(typeof(modelData) != "undefined" ? modelData : model) + } + } + + onObjectAdded: (index, object) => menu.addMenuItem(object, null) + onObjectRemoved: (index, object) => menu.removeMenuItem(object) + } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/PasswordField.qml b/src/declarativeimports/plasmaextracomponents/qml/PasswordField.qml new file mode 100644 index 0000000..521cffa --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/PasswordField.qml @@ -0,0 +1,66 @@ +// SPDX-FileCopyrightText: 2019 Carl-Lucien Schwan +// SPDX-License-Identifier: LGPL-2.0-or-later + +import QtQuick +import QtQuick.Controls as QQC2 +import org.kde.plasma.extras as PlasmaExtras +import org.kde.config as KConfig +import org.kde.kirigami as Kirigami + +/** + * This is a standard password text field. + * + * Example usage for the password field component: + * + * @code{.qml} + * import org.kde.plasma.extras as PlasmaExtras + * + * PlasmaExtras.PasswordField { + * id: passwordField + * onAccepted: { + * // check if passwordField.text is valid + * } + * } + * @endcode + * + * @since 5.93 + * @inherit org::kde::plasma::extras::ActionTextField + * @author Carl Schwan + */ +PlasmaExtras.ActionTextField { + id: root + + /** + * This property holds whether we show the clear text password. + * + * By default, it's false. + * @since 5.93 + */ + property bool showPassword: false + + Shortcut { + // Let's consider this shortcut a standard, it's also supported at least by su and sudo + sequence: "Ctrl+Shift+U" + enabled: root.activeFocus + onActivated: root.clear(); + } + + echoMode: root.showPassword ? TextInput.Normal : TextInput.Password + placeholderText: i18nd("libplasma6", "Password") + inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText | Qt.ImhSensitiveData + + rightActions: Kirigami.Action { + enabled: KConfig.KAuthorized.authorize("lineedit_reveal_password") + visible: enabled + icon.name: root.showPassword ? "password-show-off" : "password-show-on" + onTriggered: root.showPassword = !root.showPassword + } + + Keys.onPressed: event => { + if (event.matches(StandardKey.Undo)) { + // Disable undo action for security reasons + // See QTBUG-103934 + event.accepted = true + } + } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/PlaceholderMessage.qml b/src/declarativeimports/plasmaextracomponents/qml/PlaceholderMessage.qml new file mode 100644 index 0000000..3635a6b --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/PlaceholderMessage.qml @@ -0,0 +1,265 @@ +/* + * SPDX-FileCopyrightText: 2020 Nate Graham + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Templates as T + +import org.kde.plasma.components as PlasmaComponents3 +import org.kde.kirigami as Kirigami + +/** + * A placeholder message indicating that a list view is empty. The message + * comprises a label with lightened text, an optional icon above the text, and + * an optional button below the text which can be used to easily show the user + * what to do next to add content to the view. + * + * The top-level component is a ColumnLayout, so additional components items can + * simply be added as child items and they will be positioned sanely. + * + * Example usage: + * + * @code{.qml} + ** Shows how to use PlaceholderMessage to implement a "this view is empty" message + * import QtQuick + * import org.kde.plasma.extras as PlasmaExtras + * + * ListView { + * id: listView + * model: [...] + * delegate: [...] + * + * PlasmaExtras.PlaceholderMessage { + * anchors.centerIn: parent + * width: parent.width - (Kirigami.Units.gridUnit * 4) + * + * visible: listView.count == 0 + * + * text: "There are no items in this list" + * } + * } + * @endcode + * @code{.qml} + ** Shows how to use PlaceholderMessage to implement a "here's how to proceed" message + * import QtQuick + * import QtQuick.Controls as QQC2 + * import org.kde.plasma.extras as PlasmaExtras + * + * ListView { + * id: listView + * model: [...] + * delegate: [...] + * + * PlasmaExtras.PlaceholderMessage { + * anchors.centerIn: parent + * width: parent.width - (Kirigami.Units.gridUnit * 4) + * + * visible: listView.count == 0 + * + * text: "Add an item to proceed" + * + * helpfulAction: QQC2.Action { + * icon.name: "list-add" + * text: "Add item..." + * onTriggered: { + * [...] + * } + * } + * } + * [...] + * } + * @endcode + * @code{.qml} + ** Shows how to use PlaceholderMessage to implement a "there was a problem here" message + * import org.kde.plasma.components as PlasmaComponents3 + * import org.kde.plasma.extras as PlasmaExtras + * + * PlasmaComponents3.Page { + * id: root + * readonly property bool networkConnected: [...] + * + * PlasmaExtras.PlaceholderMessage { + * anchors.centerIn: parent + * width: parent.width - (Kirigami.Units.gridUnit * 4) + * + * visible: root.networkConnected + * + * iconName: "network-disconnect" + * text: "Unable to load content + * explanation: "Please try again later" + * } + * } + * @endcode + * @code{.qml} + * import org.kde.plasma.components as PlasmaComponents3 + * import org.kde.plasma.extras as PlasmaExtras + * + ** Shows how to use PlaceholderMessage to implement a loading indicator + * PlasmaComponents3.Page { + * id: root + * readonly property bool loading: [...] + * readonly property int completionStatus: [...] + * + * PlasmaExtras.PlaceholderMessage { + * anchors.centerIn: parent + * width: parent.width - (Kirigami.Units.gridUnit * 4) + * + * visible: root.loading + * + * iconName: "my-awesome-app-icon" + * text: "Loading this awesome app" + * + * PlasmaComponents3.ProgressBar { + * Layout.preferredWidth: Kirigami.Units.gridUnit * 20 + * value: root.completionStatus + * from: 0 + * to: 100 + * } + * } + * } + * @endcode + * @code{.qml} + * import QtQuick.Controls as QQC2 + * import org.kde.plasma.components as PlasmaComponents3 + * import org.kde.plasma.extras as PlasmaExtras + * + ** Shows how to use PlaceholderMessage to implement a "Here's what you do next" button + * PlasmaComponents3.Page { + * id: root + * + * PlasmaExtras.PlaceholderMessage { + * anchors.centerIn: parent + * width: parent.width - (Kirigami.Units.largeSpacing * 4) + * + * visible: root.loading + * + * helpfulAction: QQC2.Action { + * icon.name: "list-add" + * text: "Add item..." + * onTriggered: { + * [...] + * } + * } + * } + * } + * @endcode + * @since 5.72 + */ +ColumnLayout { + id: root + + enum Type { + Actionable, + Informational + } + + /** + * The type of the message. This can be: + * + * * PlasmaExtras.PlaceholderMessage.Type.Actionable: Makes it more attention-getting. Useful when the user is expected to interact with the message. + * * PlasmaExtras.PlaceholderMessage.Type.Informational: Makes it less prominent. Useful when the message in only informational. + * + * By default if an helpfulAction is provided this will be of type Actionable otherwise of type Informational. + * @since 5.94 + */ + property int type: helpfulAction && helpfulAction.enabled ? PlaceholderMessage.Type.Actionable : PlaceholderMessage.Type.Informational + + /** + * text: string + * The text to show as a placeholder label + * + * Optional; if not defined, the message will have no large text label + * text. If both text: and explanation: are omitted, the message will have + * no text and only an icon, action button, and/or other custom content. + * + * @since 5.72 + */ + property string text + + /** + * explanation: string + * Smaller explanatory text to show below the larger title-style text + * + * Useful for providing a user-friendly explanation for how to proceed. + * + * Optional; if not defined, the message will have no supplementary + * explanatory text. + * + * @since 5.80 + */ + property string explanation + + /** + * iconName: string + * The icon to show above the text label. + * + * Optional + * Falls back to `undefined` if the specified icon is not valid or cannot + * be loaded. + * + * @since 5.72 + * @see Icon::source + */ + property string iconName + + /** + * helpfulAction: QtQuickControls2 Action + * An action that helps the user proceed. Typically used to guide the user + * to the next step for adding content or items to an empty view. + * + * Optional + * + * @since 5.72 + */ + property T.Action helpfulAction + + spacing: Kirigami.Units.gridUnit + + Kirigami.Icon { + visible: source !== undefined + opacity: root.type === PlaceholderMessage.Type.Actionable ? 1 : 0.5 + + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: Math.round(Kirigami.Units.iconSizes.huge * 1.5) + Layout.preferredHeight: Math.round(Kirigami.Units.iconSizes.huge * 1.5) + + source: root.iconName || null + } + + Kirigami.Heading { + text: root.text + visible: text.length > 0 + opacity: root.type === PlaceholderMessage.Type.Actionable ? 1 : 0.65 + + type: Kirigami.Heading.Primary + + Layout.fillWidth: true + horizontalAlignment: Qt.AlignHCenter + + wrapMode: Text.WordWrap + } + + PlasmaComponents3.Label { + text: root.explanation + visible: root.explanation !== "" + opacity: root.type === PlaceholderMessage.Type.Actionable ? 1 : 0.65 + + horizontalAlignment: Qt.AlignHCenter + wrapMode: Text.WordWrap + + Layout.fillWidth: true + } + + Loader { + active: root.helpfulAction && root.helpfulAction.enabled + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: Kirigami.Units.gridUnit + + sourceComponent: PlasmaComponents3.Button { + action: root.helpfulAction + } + } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/PlasmoidHeading.qml b/src/declarativeimports/plasmaextracomponents/qml/PlasmoidHeading.qml new file mode 100644 index 0000000..6853e1b --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/PlasmoidHeading.qml @@ -0,0 +1,120 @@ +/* + SPDX-FileCopyrightText: 2020 Niccolò Venerandi + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Templates as T + +import org.kde.plasma.core as PlasmaCore +import org.kde.ksvg as KSvg +import org.kde.plasma.plasmoid +import org.kde.kirigami as Kirigami + +/** + * Item to be used as a header or footer in plasmoids + * + * @inherit QtQuick.Templates.ToolBar + */ +T.ToolBar { + id: control + + Layout.fillWidth: true + bottomPadding: position === T.ToolBar.Footer ? 0 : -backgroundMetrics.getMargin("bottom") + topPadding: position === T.ToolBar.Footer ? -backgroundMetrics.getMargin("top") : 0 + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + leftInset: backgroundMetrics.getMargin("left") + rightInset: backgroundMetrics.getMargin("right") + topInset: position === T.ToolBar.Footer ? 0 : backgroundMetrics.getMargin("top") + bottomInset: position === T.ToolBar.Footer ? backgroundMetrics.getMargin("bottom") : 0 + + Kirigami.Theme.colorSet: position === T.ToolBar.Header ? Kirigami.Theme.Header : Kirigami.Theme.Window + Kirigami.Theme.inherit: false + + property /*Qt.Edges*/ int enabledBorders: { + const w = Window.window; + const popup = w as PlasmaCore.PopupPlasmaWindow; + if (!popup) { + return Qt.LeftEdge | Qt.TopEdge | Qt.RightEdge | Qt.BottomEdge; + } + + const windowBorders = popup.borders; + let borders = Qt.TopEdge | Qt.BottomEdge; + + if (windowBorders & Qt.LeftEdge && Math.floor(background.Kirigami.ScenePosition.x) <= 0) { + borders |= Qt.LeftEdge; + } + if (windowBorders & Qt.RightEdge && Math.ceil(background.Kirigami.ScenePosition.x + background.width) >= w.width) { + borders |= Qt.RightEdge; + } + + return borders; + } + background: KSvg.FrameSvgItem { + id: headingSvg + // This graphics has to back with the dialog background, so it can be used if: + // * both this and the dialog background are from the current theme + // * both this and the dialog background are from fallback + visible: fromCurrentImageSet === backgroundSvg.fromCurrentImageSet + imagePath: "widgets/plasmoidheading" + prefix: control.position === T.ToolBar.Header ? "header" : "footer" + KSvg.Svg { + id: backgroundSvg + imagePath: "dialogs/background" + } + + enabledBorders: { + let borders = KSvg.FrameSvg.NoBorder; + if (control.enabledBorders & Qt.LeftEdge) { + borders |= KSvg.FrameSvg.LeftBorder; + } + if (control.enabledBorders & Qt.RightEdge) { + borders |= KSvg.FrameSvg.RightBorder; + } + if (control.enabledBorders & Qt.TopEdge) { + borders |= KSvg.FrameSvg.TopBorder; + } + if (control.enabledBorders & Qt.BottomEdge) { + borders |= KSvg.FrameSvg.BottomBorder; + } + return borders; + } + + BackgroundMetrics { + id: backgroundMetrics + + function getMargin(margin: string): real { + const w = Window.window; + + // TODO: This shouldn't be duck-typed + if (w && w.hasOwnProperty("leftPadding") + && w.hasOwnProperty("topPadding") + && w.hasOwnProperty("rightPadding") + && w.hasOwnProperty("bottomPadding")) { + switch (margin) { + case "left": + return -w.leftPadding; + case "top": + return -w.topPadding; + case "right": + return -w.rightPadding; + case "bottom": + default: + return -w.bottomPadding; + } + } else if (!hasInset) { + return -headingSvg.fixedMargins[margin]; + } else { + return -fixedMargins[margin] + inset[margin]; + } + } + } + } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/Representation.qml b/src/declarativeimports/plasmaextracomponents/qml/Representation.qml new file mode 100644 index 0000000..75f344f --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/Representation.qml @@ -0,0 +1,60 @@ +/* + SPDX-FileCopyrightText: 2020 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts + +import org.kde.plasma.components as PlasmaComponents + +/** + * Item to be used as root item for representations (full and compact) of plasmoids. + * It's a QtQuickControls2 Page, and like that one, has an header, a contentItem and a Footer + * It may go over the plasmoid edges (both on desktop and popups) with the properties applyHorizontalPadding and applyVerticalPadding. + * When the contentItem is a ScrollView or a Scrollarea, the plasmoid margins will be automatically removed. + * + * This code will create a full representation with a listview that will automatically + * fill the whole area without margins from the plasmoid popup borders + * @code{.qml} + * Plasmoid.Representation: PlasmaExtras.Representation { + * header: PlasmaExtras.BasicPlasmoidHeading {} + * contentItem: PlasmaComponent.ScrollView { + * ListView { + * // ... + * } + * } + * } + * @endcode + * + * @since 5.77 + * @inherit QtQuick.Templates.Page + */ +PlasmaComponents.Page { + id: control + + // TODO KF6: should become possible to set the paddings directly (which won't be negative anymore) + /** + * collapseMarginsHint: bool + * if true, the representation will remove any borders its container may have put and will be collapsed above its borders + */ + property bool collapseMarginsHint: contentItem instanceof PlasmaComponents.ScrollView + + leftPadding: backgroundMetrics.getMargin("left") + rightPadding: backgroundMetrics.getMargin("right") + topPadding: header?.visible ? 0 : backgroundMetrics.getMargin("top") + bottomPadding: footer?.visible ? 0 : backgroundMetrics.getMargin("bottom") + + BackgroundMetrics { + id: backgroundMetrics + + function getMargin(margin: string): real { + if (hasInset && control.collapseMarginsHint) { + return -fixedMargins[margin] + inset[margin]; + } else { + return 0; + } + } + } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/SearchField.qml b/src/declarativeimports/plasmaextracomponents/qml/SearchField.qml new file mode 100644 index 0000000..33c285d --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/SearchField.qml @@ -0,0 +1,80 @@ +// SPDX-FileCopyrightText: 2019 Carl-Lucien Schwan +// SPDX-FileCopyrightText: 2022 Felipe Kinoshita +// SPDX-License-Identifier: LGPL-2.0-or-later + +import QtQuick +import QtQuick.Controls as QQC2 + +import org.kde.plasma.components as PlasmaComponents3 +import org.kde.plasma.extras as PlasmaExtras +import org.kde.ksvg as KSvg +import org.kde.kirigami as Kirigami + +/** + * This is a standard textfield following KDE HIG. Using Ctrl+F as focus + * sequence and "Search…" as placeholder text. + * + * Example usage for the search field component: + * @code + * import org.kde.plasma.extras as PlasmaExtras + * + * PlasmaExtras.SearchField { + * id: searchField + * onAccepted: console.log("Search text is " + searchField.text) + * } + * @endcode + * + * @inherit org::plasmas::extras::ActionTextField + * @since 5.93 + */ +PlasmaExtras.ActionTextField { + id: root + + property int _iconWidth: searchIcon.width + searchIcon.anchors.leftMargin + + // padding to accommodate search icon nicely + leftPadding: if (root.effectiveHorizontalAlignment === TextInput.AlignRight) { + return (_rightActionsRow.visible ? _rightActionsRow.width : 0) + (__hasBackgroundAndMargins ? background.margins.left : 0); + } else { + return _iconWidth + (_leftActionsRow.visible ? _leftActionsRow.width : 0) + (__hasBackgroundAndMargins ? background.margins.left : 0); + } + rightPadding: if (root.effectiveHorizontalAlignment === TextInput.AlignRight) { + return _iconWidth + (_leftActionsRow.visible ? _leftActionsRow.width : 0) + (__hasBackgroundAndMargins ? background.margins.right : 0); + } else { + return (_rightActionsRow.visible ? _rightActionsRow.width : 0) + (__hasBackgroundAndMargins ? background.margins.right : 0); + } + + Kirigami.Icon { + id: searchIcon + LayoutMirroring.enabled: root.effectiveHorizontalAlignment === TextInput.AlignRight + anchors.left: root.left + anchors.leftMargin: Kirigami.Units.smallSpacing * 2 + anchors.verticalCenter: root.verticalCenter + anchors.verticalCenterOffset: Math.round((root.topPadding - root.bottomPadding) / 2) + implicitHeight: Kirigami.Units.iconSizes.sizeForLabels + implicitWidth: Kirigami.Units.iconSizes.sizeForLabels + + source: "search" + } + + placeholderText: i18nd("libplasma6", "Search…") + + Accessible.name: i18nd("libplasma6", "Search") + Accessible.searchEdit: true + + focusSequence: StandardKey.Find + inputMethodHints: Qt.ImhNoPredictiveText + + rightActions: [ + Kirigami.Action { + //ltr confusingly refers to the direction of the arrow in the icon, not the text direction which it should be used in + icon.name: root.effectiveHorizontalAlignment === TextInput.AlignRight ? "edit-clear-locationbar-ltr" : "edit-clear-locationbar-rtl" + visible: root.text.length > 0 + text: i18nd("libplasma6", "Clear search") + onTriggered: { + root.clear(); + root.accepted(); + } + } + ] +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/ShadowedLabel.qml b/src/declarativeimports/plasmaextracomponents/qml/ShadowedLabel.qml new file mode 100644 index 0000000..d6d5668 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/ShadowedLabel.qml @@ -0,0 +1,74 @@ +/* + * SPDX-FileCopyrightText: 2013 Bhushan Shah + * SPDX-FileCopyrightText: 2016 Kai Uwe Broulik + * SPDX-FileCopyrightText: 2022 ivan tkachenko + * SPDX-FileCopyrightText: 2023 Mike Noe + * SPDX-FileCopyrightText: 2023 Nate Graham + * + * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + */ + +import QtQuick +import Qt5Compat.GraphicalEffects + +import org.kde.plasma.components as PlasmaComponents3 +import org.kde.kirigami as Kirigami + +/** + * @brief White text label with a black shadow behind it + * + * A standardized label with white text and a black shadow behind it. When using + * software rendering such that the shadow is not available, a black rounded + * rectangle is used in its stead. + * + * By default it elides text on the right, wraps in a way that prefers word + * boundaries, and uses plain text formatting. + * + * The most important property is "text", which applies to the text property of + * the underlying Label component. See the Label component from QtQuick.Controls + * 2 and primitive QML Text element API for additional properties, methods, and + * signals. + * + * @inherit org.kde.plasma.components.Label + */ +PlasmaComponents3.Label { + /** + * This property can be used to conditionally *not* render the shadow, even + * when it's technically possible to render it. + * + * default: ``true`` + */ + property bool renderShadow: true + + elide: Text.ElideRight + wrapMode: Text.Wrap + textFormat: Text.PlainText + + color: "white" + + layer.enabled: renderShadow && GraphicsInfo.api !== GraphicsInfo.Software + layer.effect: DropShadow { + horizontalOffset: 1 + verticalOffset: 1 + + radius: 4.0 + samples: radius * 2 + 1 + spread: 0.35 + color: "black" + } + + // Fallback background when we can't draw the text shadow because hardware + // rendering isn't available + Rectangle { + anchors { + fill: parent + margins: -Kirigami.Units.smallSpacing + } + + color: "black" + radius: Kirigami.Units.smallSpacing + opacity: 0.45 + + visible: GraphicsInfo.api === GraphicsInfo.Software + } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/animations/ActivateAnimation.qml b/src/declarativeimports/plasmaextracomponents/qml/animations/ActivateAnimation.qml new file mode 100644 index 0000000..d23ba74 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/animations/ActivateAnimation.qml @@ -0,0 +1,24 @@ +/* + SPDX-FileCopyrightText: 2011 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.kirigami as Kirigami + +SequentialAnimation { + id: activateAnimation + objectName: "activateAnimation" + + property Item targetItem + property int duration: Kirigami.Units.shortDuration + + // Fast scaling while we're animation == more FPS + ScriptAction { script: targetItem.smooth = false } + + PressedAnimation { targetItem: activateAnimation.targetItem } + ReleasedAnimation { targetItem: activateAnimation.targetItem } + + ScriptAction { script: targetItem.smooth = true } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/animations/AppearAnimation.qml b/src/declarativeimports/plasmaextracomponents/qml/animations/AppearAnimation.qml new file mode 100644 index 0000000..c780a85 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/animations/AppearAnimation.qml @@ -0,0 +1,41 @@ +/* + SPDX-FileCopyrightText: 2011 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.kirigami as Kirigami + +SequentialAnimation { + id: appearAnimation + objectName: "appearAnimation" + + property Item targetItem + property int duration: Kirigami.Units.longDuration + + // Animators run on the render thread so they kick in slightly delayed + // so explicitly set the item's opacity to 0 before starting the animation + ScriptAction { + script: { + targetItem.opacity = 0 + } + } + + ParallelAnimation { + OpacityAnimator { + target: targetItem + from: 0 + to: 1.0 + duration: appearAnimation.duration + easing.type: Easing.InExpo + } + ScaleAnimator { + target: targetItem + from: 0.8 + to: 1.0 + duration: appearAnimation.duration + easing.type: Easing.InExpo + } + } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/animations/DisappearAnimation.qml b/src/declarativeimports/plasmaextracomponents/qml/animations/DisappearAnimation.qml new file mode 100644 index 0000000..feaa5bd --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/animations/DisappearAnimation.qml @@ -0,0 +1,39 @@ +/* + SPDX-FileCopyrightText: 2011 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.kirigami as Kirigami + +SequentialAnimation { + id: disappearAnimation + objectName: "disappearAnimation" + + property Item targetItem + property int duration: Kirigami.Units.longDuration + + ParallelAnimation { + OpacityAnimator { + duration: disappearAnimation.duration + from: 1.0 + to: 0 + target: disappearAnimation.targetItem + easing.type: Easing.OutExpo + } + ScaleAnimator { + target: disappearAnimation.targetItem + from: 1.0 + to: 0.8 + duration: disappearAnimation.duration * 0.6 + easing.type: Easing.OutExpo + } + } + + ScriptAction { + script: { + targetItem.visible = false; + } + } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/animations/PressedAnimation.qml b/src/declarativeimports/plasmaextracomponents/qml/animations/PressedAnimation.qml new file mode 100644 index 0000000..542ab23 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/animations/PressedAnimation.qml @@ -0,0 +1,37 @@ +/* + SPDX-FileCopyrightText: 2011 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.kirigami as Kirigami + +SequentialAnimation { + id: pressedAnimation + objectName: "pressedAnimation" + + property Item targetItem + property int duration: Kirigami.Units.shortDuration + + // Fast scaling while we're animation == more FPS + ScriptAction { script: targetItem.smooth = false } + + ParallelAnimation { + PropertyAnimation { + target: targetItem + properties: "opacity" + from: 1.0; to: 0.8 + duration: pressedAnimation.duration; + easing.type: Easing.OutExpo; + } + PropertyAnimation { + target: targetItem + properties: "scale" + from: 1.0; to: 0.95 + duration: pressedAnimation.duration; + easing.type: Easing.OutExpo; + } + } + ScriptAction { script: targetItem.smooth = true } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/animations/ReleasedAnimation.qml b/src/declarativeimports/plasmaextracomponents/qml/animations/ReleasedAnimation.qml new file mode 100644 index 0000000..59bea2c --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/animations/ReleasedAnimation.qml @@ -0,0 +1,38 @@ +/* + SPDX-FileCopyrightText: 2011 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import org.kde.kirigami as Kirigami + +SequentialAnimation { + id: releasedAnimation + objectName: "releasedAnimation" + + property Item targetItem + property int duration: Kirigami.Units.shortDuration + + // Fast scaling while we're animation == more FPS + ScriptAction { script: targetItem.smooth = false } + + ParallelAnimation { + PropertyAnimation { + target: targetItem + properties: "opacity" + from: 0.8; to: 1.0 + duration: releasedAnimation.duration; + easing.type: Easing.InExpo; + } + PropertyAnimation { + target: targetItem + properties: "scale" + from: 0.95; to: 1.0 + duration: releasedAnimation.duration; + easing.type: Easing.InExpo; + } + } + + ScriptAction { script: targetItem.smooth = true } +} diff --git a/src/declarativeimports/plasmaextracomponents/qml/private/BackgroundMetrics.qml b/src/declarativeimports/plasmaextracomponents/qml/private/BackgroundMetrics.qml new file mode 100644 index 0000000..02c1497 --- /dev/null +++ b/src/declarativeimports/plasmaextracomponents/qml/private/BackgroundMetrics.qml @@ -0,0 +1,25 @@ +/* + SPDX-FileCopyrightText: 2020 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ +import QtQuick + +import org.kde.plasma.plasmoid +import org.kde.plasma.core as PlasmaCore +import org.kde.ksvg as KSvg + +KSvg.FrameSvgItem { + visible: false + imagePath: { + if (Window.window instanceof PlasmaCore.AppletPopup || Window.window instanceof PlasmaCore.Dialog) { + return "dialogs/background"; + } else if (Plasmoid.formFactor === PlasmaCore.Types.Planar) { + return "widgets/background"; + // panels and other formfactors are explicitly not supported + } else { + return ""; + } + } + readonly property bool hasInset: inset.left >= 0 && inset.right >= 0 && inset.top >= 0 && inset.bottom >= 0 +} diff --git a/src/desktoptheme/CMakeLists.txt b/src/desktoptheme/CMakeLists.txt new file mode 100644 index 0000000..8814950 --- /dev/null +++ b/src/desktoptheme/CMakeLists.txt @@ -0,0 +1,104 @@ + +option(GZIP_DESKTOPTHEME_SVG "Install Desktop Theme SVG files as .svgz." ON) + +if (GZIP_DESKTOPTHEME_SVG) + if(WIN32) + find_package(7z) + set_package_properties(7z PROPERTIES + TYPE REQUIRED + ) + else() + find_package(gzip) + set_package_properties(gzip PROPERTIES + TYPE REQUIRED + ) + endif() +endif() + +# Helper function, private for now +# Once it has matured and proven, add to public macros +function(PLASMA_INSTALL_DESKTOPTHEME_SVGS theme_name) + set(options + ) + set(oneValueArgs + SUBPATH + ) + set(multiValueArgs + FILES + ) + + cmake_parse_arguments(PIDS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT DEFINED PIDS_SUBPATH) + message(FATAL_ERROR "SUBPATH needs to be defined when calling plasma_install_desktoptheme_svgs.") + endif() + + if(NOT PIDS_FILES) + message(FATAL_ERROR "No files passed when calling plasma_install_desktoptheme_svgs.") + endif() + + set(_target_name "${theme_name}_desktoptheme_graphics_${PIDS_SUBPATH}") + string(REPLACE "/" "_" _target_name "${_target_name}") + + set(desktoptheme_COMPONENTDIR "${theme_name}/${PIDS_SUBPATH}") + set(desktoptheme_INSTALLDIR ${PLASMA_DATA_INSTALL_DIR}/desktoptheme/${desktoptheme_COMPONENTDIR}) + + if (GZIP_DESKTOPTHEME_SVG) + set(desktoptheme_GZIPDIR "${theme_name}.gzipped/${PIDS_SUBPATH}") + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${desktoptheme_GZIPDIR}") + endif() + + set(_install_files) + + foreach(_src_file ${PIDS_FILES}) + if (NOT IS_ABSOLUTE ${_src_file}) + set(_src_file "${CMAKE_CURRENT_SOURCE_DIR}/${_src_file}") + endif() + if (NOT EXISTS ${_src_file}) + message(FATAL_ERROR "No such file found: ${_src_file}") + endif() + get_filename_component(_fileName "${_src_file}" NAME) + + if (GZIP_DESKTOPTHEME_SVG) + set(_gzipped_file_displayname "${desktoptheme_COMPONENTDIR}/${_fileName}z") + set(_gzipped_file "${CMAKE_CURRENT_BINARY_DIR}/${desktoptheme_GZIPDIR}/${_fileName}z") + if(WIN32) + add_custom_command( + OUTPUT ${_gzipped_file} + COMMAND 7z::7z + ARGS + a + -tgzip + ${_gzipped_file} ${_src_file} + DEPENDS ${_src_file} + COMMENT "Gzipping ${_gzipped_file_displayname}" + ) + else() + add_custom_command( + OUTPUT ${_gzipped_file} + COMMAND gzip::gzip + ARGS + -9 # compress best + -n # no original name and timestamp stored, for reproducibility + -c # write to stdout + ${_src_file} > ${_gzipped_file} + DEPENDS ${_src_file} + COMMENT "Gzipping ${_gzipped_file_displayname}" + ) + endif() + else() + set(_gzipped_file "${_src_file}") + endif() + + list(APPEND _install_files "${_gzipped_file}") + endforeach() + + add_custom_target(${_target_name} ALL DEPENDS ${_install_files}) + + install(FILES ${_install_files} DESTINATION "${desktoptheme_INSTALLDIR}" ) +endfunction() + + +add_subdirectory( breeze ) +add_subdirectory( breeze-dark ) +add_subdirectory( breeze-light ) diff --git a/src/desktoptheme/breeze-dark/CMakeLists.txt b/src/desktoptheme/breeze-dark/CMakeLists.txt new file mode 100644 index 0000000..c103c31 --- /dev/null +++ b/src/desktoptheme/breeze-dark/CMakeLists.txt @@ -0,0 +1,12 @@ +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/metadata.json.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/metadata.json" + @ONLY +) + +install( + FILES colors "${CMAKE_CURRENT_BINARY_DIR}/metadata.json" + plasmarc + DESTINATION ${PLASMA_DATA_INSTALL_DIR}/desktoptheme/breeze-dark +) + diff --git a/src/desktoptheme/breeze-dark/colors b/src/desktoptheme/breeze-dark/colors new file mode 100644 index 0000000..0694752 --- /dev/null +++ b/src/desktoptheme/breeze-dark/colors @@ -0,0 +1,123 @@ +[ColorEffects:Disabled] +Color=56,56,56 +ColorAmount=0 +ColorEffect=0 +ContrastAmount=0.65 +ContrastEffect=1 +IntensityAmount=0.1 +IntensityEffect=2 + +[ColorEffects:Inactive] +ChangeSelectionColor=true +Color=112,111,110 +ColorAmount=0.025 +ColorEffect=2 +ContrastAmount=0.1 +ContrastEffect=2 +Enable=false +IntensityAmount=0 +IntensityEffect=0 + +[Colors:Button] +BackgroundAlternate=30,87,116 +BackgroundNormal=49,54,59 +ForegroundInactive=161,169,177 +ForegroundLink=29,153,243 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=252,252,252 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[Colors:Complementary] +BackgroundAlternate=30,87,116 +BackgroundNormal=42,46,50 +ForegroundInactive=161,169,177 +ForegroundLink=29,153,243 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=252,252,252 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[Colors:Header] +BackgroundAlternate=42,46,50 +BackgroundNormal=49,54,59 +ForegroundInactive=161,169,177 +ForegroundLink=29,153,243 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=252,252,252 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[Colors:Header][Inactive] +BackgroundAlternate=49,54,59 +BackgroundNormal=42,46,50 +ForegroundInactive=161,169,177 +ForegroundLink=29,153,243 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=252,252,252 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[Colors:Selection] +BackgroundAlternate=30,87,116 +ForegroundActive=252,252,252 +ForegroundInactive=161,169,177 +ForegroundLink=253,188,75 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=252,252,252 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[Colors:Tooltip] +BackgroundAlternate=42,46,50 +BackgroundNormal=49,54,59 +ForegroundInactive=161,169,177 +ForegroundLink=29,153,243 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=252,252,252 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[Colors:View] +BackgroundAlternate=35,38,41 +BackgroundNormal=27,30,32 +ForegroundInactive=161,169,177 +ForegroundLink=29,153,243 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=252,252,252 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[Colors:Window] +BackgroundAlternate=49,54,59 +BackgroundNormal=42,46,50 +ForegroundInactive=161,169,177 +ForegroundLink=29,153,243 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=252,252,252 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[General] +ColorScheme=Breeze Dark +Name=Breeze Dark +shadeSortColumn=true + +[KDE] +contrast=4 + +[WM] +activeBackground=49,54,59 +activeBlend=252,252,252 +activeForeground=252,252,252 +inactiveBackground=42,46,50 +inactiveBlend=161,169,177 +inactiveForeground=161,169,177 diff --git a/src/desktoptheme/breeze-dark/metadata.json.cmake b/src/desktoptheme/breeze-dark/metadata.json.cmake new file mode 100644 index 0000000..7272b05 --- /dev/null +++ b/src/desktoptheme/breeze-dark/metadata.json.cmake @@ -0,0 +1,154 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "kde-artists@kde.org", + "Name": "KDE Visual Design Group", + "Name[ar]": "مجموعة التصميم المرئي لكِيدِي", + "Name[az]": "KDE Vizual Dizayn Qrupu", + "Name[be]": "Суполка візуальнага дызайну KDE", + "Name[bg]": "KDE Visual Design Group", + "Name[ca@valencia]": "Grup de disseny visual de KDE", + "Name[ca]": "Grup de disseny visual de KDE", + "Name[cs]": "Skupina vizuálního návrhu KDE", + "Name[da]": "KDE visuelle designgruppe", + "Name[de]": "KDE Visual Design Group", + "Name[el]": "Ομάδα οπτικού σχεδιασμού KDE", + "Name[en_GB]": "KDE Visual Design Group", + "Name[eo]": "KDE Vida Dezajna Grupo", + "Name[es]": "El grupo de diseño visual de KDE", + "Name[eu]": "KDE Diseinu bisualeko taldea", + "Name[fi]": "KDE:n visuaalinen suunnitteluryhmä", + "Name[fr]": "Groupe de conception graphique de KDE « VDG » (Visual Design Group)", + "Name[gl]": "Grupo de deseño visual de KDE", + "Name[he]": "קבוצת העיצוב החזותי של KDE", + "Name[hu]": "KDE Visual Design Group", + "Name[ia]": "KDE Visual Design Group (Gruppo de Designo Visual de KDE)", + "Name[id]": "Grup Desain Visual KDE", + "Name[is]": "Myndrænn hönnunarhópur KDE", + "Name[it]": "KDE Visual Design Group", + "Name[ka]": "KDE Visual Design Group", + "Name[ko]": "KDE 시각 디자인 그룹", + "Name[lt]": "KDE vaizdinio dizaino grupė", + "Name[lv]": "KDE Vizuālā dizaina grupa", + "Name[nl]": "KDE Visuele ontwerpgroep", + "Name[nn]": "KDE Visual Design Group", + "Name[pl]": "Grupa oprawy graficznej KDE", + "Name[pt]": "Grupo de Desenho Visual do KDE", + "Name[pt_BR]": "Grupo de design visual do KDE (KDE VDG)", + "Name[ro]": "KDE Visual Design Group", + "Name[ru]": "Группа KDE Visual Design", + "Name[sa]": "KDE Visual Design Group", + "Name[sk]": "KDE Visual Design Group", + "Name[sl]": "Skupina vizualnega designa KDE", + "Name[sv]": "KDE:s visuella designgrupp", + "Name[ta]": "கே.டீ.யீ. வரைகலை வடிவமைப்புக் குழு", + "Name[tr]": "KDE Görsel Tasarım Grubu", + "Name[uk]": "Група з візуального дизайну KDE", + "Name[vi]": "Đội Thiết kế Trực quan KDE", + "Name[x-test]": "xxKDE Visual Design Groupxx", + "Name[zh_CN]": "KDE 视觉设计团队", + "Name[zh_TW]": "KDE VDG 視覺設計組" + } + ], + "Category": "", + "Description": "Breeze Dark by the KDE VDG", + "Description[ar]": "نسيم داكن من من مجموعة تصميم كِيدِي", + "Description[az]": "KDE VDG tərəfindən Breeze Qara", + "Description[be]": "Breeze Dark ад KDE VDG", + "Description[bg]": "Breeze Тъмен от KDE VDG", + "Description[ca@valencia]": "Brisa fosca, creat pel VDG de KDE", + "Description[ca]": "Brisa fosca, creat pel VDG del KDE", + "Description[cs]": "Breeze Dark od KDE VDG", + "Description[da]": "Breeze Mørk af KDE's visuelle designgruppe", + "Description[de]": "Breeze Dunkel von der KDE VDG", + "Description[el]": "Breeze σκοτεινό από το KDE VDG", + "Description[en_GB]": "Breeze Dark by the KDE VDG", + "Description[eo]": "Breeze Dark de la KDE VDG", + "Description[es]": "Brisa oscuro, por KDE VDG", + "Description[eu]": "Brisa iluna KDEren VDGk egina", + "Description[fi]": "Tumma Breeze KDE VDG:ltä", + "Description[fr]": "Breeze sombre par l'équipe « KDE VDG »", + "Description[gl]": "Brisa escura do KDE VDG.", + "Description[he]": "בריזה כהה מאת קבוצת העיצוב החזותי של KDE", + "Description[hu]": "Breeze Dark a KDE VDG-től", + "Description[ia]": "Breeze Dark (Brisa Obscure) per le KDE VDG", + "Description[id]": "Breeze Gelap oleh KDE VDG", + "Description[is]": "Breeze Dark frá KDE VDG", + "Description[it]": "Brezza scuro a cura del KDE VDG", + "Description[ka]": "Breeze Dark \"KDE VDG\"-სგან", + "Description[ko]": "KDE 시각 디자인 그룹에서 제작한 어두운 Breeze", + "Description[lt]": "Breeze tamsus pagal KDE VDG", + "Description[lv]": "KDE VDG veidotā „Breeze Dark“", + "Description[nl]": "Breeze Dark door de KDE VDG", + "Description[nn]": "Breeze mørk frå KDE VDG", + "Description[pl]": "Ciemna Bryza autorstwa KDE VDG", + "Description[pt]": "Brisa Escuro da VDG do KDE", + "Description[pt_BR]": "Breeze pelo KDE VDG", + "Description[ro]": "Briză, întunecat, de KDE VDG", + "Description[ru]": "Тёмный вариант Breeze от KDE VDG", + "Description[sa]": "KDE VDG द्वारा Breeze Dark", + "Description[sk]": "Vánok Tmavý od KDE VDG", + "Description[sl]": "Temna sapica od KDE VDG", + "Description[sv]": "Breeze mörk av KDE:s visuella designgrupp", + "Description[ta]": "கே.டீ.யீ. VDG வழங்கும் கரும் பிரீஸ்", + "Description[tr]": "KDE VDG’den Esinti Koyu", + "Description[uk]": "Темна Breeze, автори — KDE VDG", + "Description[vi]": "Breeze Tối, do KDE VDG", + "Description[x-test]": "xxBreeze Dark by the KDE VDGxx", + "Description[zh_CN]": "Breeze 微风深色主题,由 KDE VDG (视觉设计团队) 设计制作", + "Description[zh_TW]": "由 KDE VDG 設計的 Breeze Dark", + "EnabledByDefault": true, + "Id": "breeze-dark", + "License": "LGPL", + "Name": "Breeze Dark", + "Name[ar]": "نسيم داكن", + "Name[az]": "Breeze Qara", + "Name[be]": "Breeze Dark", + "Name[bg]": "Breeze Тъмен", + "Name[ca@valencia]": "Brisa fosca", + "Name[ca]": "Brisa fosca", + "Name[cs]": "Breeze Tmavé", + "Name[da]": "Breeze Mørk", + "Name[de]": "Breeze Dunkel", + "Name[el]": "Breeze σκοτεινό", + "Name[en_GB]": "Breeze Dark", + "Name[eo]": "Vento Malhela", + "Name[es]": "Brisa oscuro", + "Name[eu]": "Brisa iluna", + "Name[fi]": "Tumma Breeze", + "Name[fr]": "Breeze Sombre", + "Name[gl]": "Brisa escura", + "Name[he]": "בריזה כהה", + "Name[hu]": "Breeze Dark", + "Name[ia]": "Brisa obscure", + "Name[id]": "Breeze Gelap", + "Name[is]": "Breeze Dark", + "Name[it]": "Brezza scuro", + "Name[ka]": "Breeze Dark", + "Name[ko]": "어두운 Breeze", + "Name[lt]": "Breeze tamsus", + "Name[lv]": "Breeze Dark", + "Name[nl]": "Breeze Dark", + "Name[nn]": "Breeze mørk", + "Name[pl]": "Ciemna Bryza", + "Name[pt]": "Brisa Escura", + "Name[pt_BR]": "Breeze Dark", + "Name[ro]": "Briză, întunecat", + "Name[ru]": "Breeze, тёмный вариант", + "Name[sa]": "Breeze Dark", + "Name[sk]": "Vánok Tmavý", + "Name[sl]": "Temna sapica", + "Name[sv]": "Breeze mörk", + "Name[ta]": "கரும் பிரீஸ்", + "Name[tr]": "Esinti Koyu", + "Name[uk]": "Темна Breeze", + "Name[vi]": "Breeze Tối", + "Name[x-test]": "xxBreeze Darkxx", + "Name[zh_CN]": "Breeze 微风深色", + "Name[zh_TW]": "Breeze Dark", + "Version": "@KF6_MIN_VERSION@", + "Website": "https://www.kde.org/" + }, + "X-Plasma-API": "5.0" +} diff --git a/src/desktoptheme/breeze-dark/plasmarc b/src/desktoptheme/breeze-dark/plasmarc new file mode 100644 index 0000000..f81eccc --- /dev/null +++ b/src/desktoptheme/breeze-dark/plasmarc @@ -0,0 +1,14 @@ +[Wallpaper] +defaultWallpaperTheme=Next +defaultFileSuffix=.png +defaultWidth=1920 +defaultHeight=1080 + +[ContrastEffect] +enabled=true +contrast=0.2 +intensity=0.6 +saturation=10 + +[AdaptiveTransparency] +enabled=true diff --git a/src/desktoptheme/breeze-light/CMakeLists.txt b/src/desktoptheme/breeze-light/CMakeLists.txt new file mode 100644 index 0000000..a461502 --- /dev/null +++ b/src/desktoptheme/breeze-light/CMakeLists.txt @@ -0,0 +1,11 @@ +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/metadata.json.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/metadata.json" + @ONLY +) + +install( + FILES colors "${CMAKE_CURRENT_BINARY_DIR}/metadata.json" + plasmarc + DESTINATION ${PLASMA_DATA_INSTALL_DIR}/desktoptheme/breeze-light +) diff --git a/src/desktoptheme/breeze-light/colors b/src/desktoptheme/breeze-light/colors new file mode 100644 index 0000000..b6f24e3 --- /dev/null +++ b/src/desktoptheme/breeze-light/colors @@ -0,0 +1,122 @@ +[ColorEffects:Disabled] +Color=56,56,56 +ColorAmount=0 +ColorEffect=0 +ContrastAmount=0.65 +ContrastEffect=1 +IntensityAmount=0.1 +IntensityEffect=2 + +[ColorEffects:Inactive] +ChangeSelectionColor=true +Color=112,111,110 +ColorAmount=0.025 +ColorEffect=2 +ContrastAmount=0.1 +ContrastEffect=2 +Enable=false +IntensityAmount=0 +IntensityEffect=0 + +[Colors:Button] +BackgroundAlternate=163,212,250 +BackgroundNormal=247,247,247 +ForegroundInactive=112,125,138 +ForegroundLink=41,128,185 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=35,38,41 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[Colors:Complementary] +BackgroundAlternate=27,30,32 +BackgroundNormal=42,46,50 +ForegroundInactive=161,169,177 +ForegroundLink=29,153,243 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=252,252,252 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[Colors:Header] +BackgroundAlternate=239,240,241 +BackgroundNormal=222,224,226 +ForegroundInactive=112,125,138 +ForegroundLink=41,128,185 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=35,38,41 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[Colors:Header][Inactive] +BackgroundAlternate=227,229,231 +BackgroundNormal=239,240,241 +ForegroundInactive=112,125,138 +ForegroundLink=41,128,185 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=35,38,41 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[Colors:Selection] +BackgroundAlternate=163,212,250 +ForegroundInactive=112,125,138 +ForegroundLink=41,128,185 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=255,255,255 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[Colors:Tooltip] +BackgroundAlternate=239,240,241 +BackgroundNormal=247,247,247 +ForegroundInactive=112,125,138 +ForegroundLink=41,128,185 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=35,38,41 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[Colors:View] +BackgroundAlternate=247,247,247 +BackgroundNormal=255,255,255 +ForegroundInactive=112,125,138 +ForegroundLink=41,128,185 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=35,38,41 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[Colors:Window] +BackgroundAlternate=227,229,231 +BackgroundNormal=239,240,241 +ForegroundInactive=112,125,138 +ForegroundLink=41,128,185 +ForegroundNegative=218,68,83 +ForegroundNeutral=246,116,0 +ForegroundNormal=35,38,41 +ForegroundPositive=39,174,96 +ForegroundVisited=155,89,182 + +[General] +ColorScheme=Breeze Light +Name=Breeze Light +shadeSortColumn=true + +[KDE] +contrast=4 + +[WM] +activeBackground=227,229,231 +activeBlend=227,229,231 +activeForeground=35,38,41 +inactiveBackground=239,240,241 +inactiveBlend=239,240,241 +inactiveForeground=112,125,138 diff --git a/src/desktoptheme/breeze-light/metadata.json.cmake b/src/desktoptheme/breeze-light/metadata.json.cmake new file mode 100644 index 0000000..b3a1260 --- /dev/null +++ b/src/desktoptheme/breeze-light/metadata.json.cmake @@ -0,0 +1,154 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "kde-artists@kde.org", + "Name": "KDE Visual Design Group", + "Name[ar]": "مجموعة التصميم المرئي لكِيدِي", + "Name[az]": "KDE Vizual Dizayn Qrupu", + "Name[be]": "Суполка візуальнага дызайну KDE", + "Name[bg]": "KDE Visual Design Group", + "Name[ca@valencia]": "Grup de disseny visual de KDE", + "Name[ca]": "Grup de disseny visual de KDE", + "Name[cs]": "Skupina vizuálního návrhu KDE", + "Name[da]": "KDE visuelle designgruppe", + "Name[de]": "KDE Visual Design Group", + "Name[el]": "Ομάδα οπτικού σχεδιασμού KDE", + "Name[en_GB]": "KDE Visual Design Group", + "Name[eo]": "KDE Vida Dezajna Grupo", + "Name[es]": "El grupo de diseño visual de KDE", + "Name[eu]": "KDE Diseinu bisualeko taldea", + "Name[fi]": "KDE:n visuaalinen suunnitteluryhmä", + "Name[fr]": "Groupe de conception graphique de KDE « VDG » (Visual Design Group)", + "Name[gl]": "Grupo de deseño visual de KDE", + "Name[he]": "קבוצת העיצוב החזותי של KDE", + "Name[hu]": "KDE Visual Design Group", + "Name[ia]": "KDE Visual Design Group (Gruppo de Designo Visual de KDE)", + "Name[id]": "Grup Desain Visual KDE", + "Name[is]": "Myndrænn hönnunarhópur KDE", + "Name[it]": "KDE Visual Design Group", + "Name[ka]": "KDE Visual Design Group", + "Name[ko]": "KDE 시각 디자인 그룹", + "Name[lt]": "KDE vaizdinio dizaino grupė", + "Name[lv]": "KDE Vizuālā dizaina grupa", + "Name[nl]": "KDE Visuele ontwerpgroep", + "Name[nn]": "KDE Visual Design Group", + "Name[pl]": "Grupa oprawy graficznej KDE", + "Name[pt]": "Grupo de Desenho Visual do KDE", + "Name[pt_BR]": "Grupo de design visual do KDE (KDE VDG)", + "Name[ro]": "KDE Visual Design Group", + "Name[ru]": "Группа KDE Visual Design", + "Name[sa]": "KDE Visual Design Group", + "Name[sk]": "KDE Visual Design Group", + "Name[sl]": "Skupina vizualnega designa KDE", + "Name[sv]": "KDE:s visuella designgrupp", + "Name[ta]": "கே.டீ.யீ. வரைகலை வடிவமைப்புக் குழு", + "Name[tr]": "KDE Görsel Tasarım Grubu", + "Name[uk]": "Група з візуального дизайну KDE", + "Name[vi]": "Đội Thiết kế Trực quan KDE", + "Name[x-test]": "xxKDE Visual Design Groupxx", + "Name[zh_CN]": "KDE 视觉设计团队", + "Name[zh_TW]": "KDE VDG 視覺設計組" + } + ], + "Category": "", + "Description": "Breeze Light by the KDE VDG", + "Description[ar]": "نسيم فاتح من مجموعة تصميم كِيدِي", + "Description[az]": "Breeze -İşıqlı - KDE VDG tərəfindən", + "Description[be]": "Breeze Light ад KDE VDG", + "Description[bg]": "Breeze Светъл от KDE VDG", + "Description[ca@valencia]": "Brisa clara, creat pel VDG de KDE", + "Description[ca]": "Brisa clara, creat pel VDG del KDE", + "Description[cs]": "Breeze Light od KDE VDG", + "Description[da]": "Breeze Lys af KDE's visuelle designgruppe", + "Description[de]": "Breeze Hell von der KDE VDG", + "Description[el]": "Breeze φωτεινό από το KDE VDG", + "Description[en_GB]": "Breeze Light by the KDE VDG", + "Description[eo]": "Breeze Light de la KDE VDG", + "Description[es]": "Brisa claro, por KDE VDG", + "Description[eu]": "Brisa argia, KDE VDGk egina", + "Description[fi]": "Vaalea Breeze KDE VDG:ltä", + "Description[fr]": "Breeze clair par l'équipe « KDE VDG »", + "Description[gl]": "Brisa clara do KDE VDG.", + "Description[he]": "בריזה בהירה מאת קבוצת העיצוב החזותי של KDE", + "Description[hu]": "Breeze Light a KDE VDG-től", + "Description[ia]": "Brisa Ligier per KDE VDG", + "Description[id]": "Breeze Terang oleh KDE VDG", + "Description[is]": "Breeze Light frá KDE VDG", + "Description[it]": "Brezza chiaro a cura del VDG di KDE", + "Description[ka]": "Breeze-ის ღია ვარიანტი, KDE VDG-სგან", + "Description[ko]": "KDE 시각 디자인 그룹에서 제작한 밝은 Breeze", + "Description[lt]": "Breeze šviesus pagal KDE VDG", + "Description[lv]": "KDE VDG veidotā „Breeze Light“", + "Description[nl]": "Breeze Light door de KDE VDG", + "Description[nn]": "Breeze skumring frå KDE VDG", + "Description[pl]": "Jasna Bryza autorstwa KDE VDG", + "Description[pt]": "Brisa Claro da VDG do KDE", + "Description[pt_BR]": "Breeze Light pelo KDE VDG", + "Description[ro]": "Briză, luminos, de KDE VDG", + "Description[ru]": "Светлый вариант Breeze от KDE VDG", + "Description[sa]": "KDE VDG द्वारा Breeze Light", + "Description[sk]": "Vánok Svetlý od KDE VDG", + "Description[sl]": "Svetla sapica od KDE VDG", + "Description[sv]": "Breeze ljus av KDE:s visuella designgrupp", + "Description[ta]": "கே.டீ.யீ. VDG வழங்கும் வெளிர் பிரீஸ்", + "Description[tr]": "KDE VDG’den Esinti Açık", + "Description[uk]": "Світла Breeze, автори — KDE VDG", + "Description[vi]": "Breeze Sáng, do KDE VDG", + "Description[x-test]": "xxBreeze Light by the KDE VDGxx", + "Description[zh_CN]": "Breeze 微风浅色主题,由 KDE VDG (视觉设计团队) 设计制作", + "Description[zh_TW]": "由 KDE VDG 製作的 Breeze Light", + "EnabledByDefault": true, + "Id": "default", + "License": "LGPL", + "Name": "Breeze Light", + "Name[ar]": "نسيم فاتح", + "Name[az]": "Breeze - İşıqlı", + "Name[be]": "Breeze Light", + "Name[bg]": "Breeze Светъл", + "Name[ca@valencia]": "Brisa clara", + "Name[ca]": "Brisa clara", + "Name[cs]": "Breeze Světlé", + "Name[da]": "Breeze Lys", + "Name[de]": "Breeze Hell", + "Name[el]": "Breeze φωτεινό", + "Name[en_GB]": "Breeze Light", + "Name[eo]": "Briza Lumo", + "Name[es]": "Brisa claro", + "Name[eu]": "Brisa argia", + "Name[fi]": "Vaalea Breeze", + "Name[fr]": "Breeze clair", + "Name[gl]": "Brisa clara", + "Name[he]": "בריזה בהירה", + "Name[hu]": "Breeze Light", + "Name[ia]": "Brisa Ligier", + "Name[id]": "Breeze Terang", + "Name[is]": "Breeze Light", + "Name[it]": "Brezza chiaro", + "Name[ka]": "ნიავი ღია", + "Name[ko]": "밝은 Breeze", + "Name[lt]": "Breeze šviesus", + "Name[lv]": "Breeze Light", + "Name[nl]": "Breeze Light", + "Name[nn]": "Breeze lys", + "Name[pl]": "Jasna Bryza", + "Name[pt]": "Brisa Clara", + "Name[pt_BR]": "Breeze Light", + "Name[ro]": "Briză, luminos", + "Name[ru]": "Breeze, светлый вариант", + "Name[sa]": "Breeze Light", + "Name[sk]": "Vánok Svetlý", + "Name[sl]": "Svetla sapica", + "Name[sv]": "Breeze ljus", + "Name[ta]": "வெளிர் பிரீஸ்", + "Name[tr]": "Esinti Açık", + "Name[uk]": "Світла Breeze", + "Name[vi]": "Breeze Sáng", + "Name[x-test]": "xxBreeze Lightxx", + "Name[zh_CN]": "Breeze 微风浅色", + "Name[zh_TW]": "Breeze Light", + "Version": "@KF6_MIN_VERSION@", + "Website": "https://www.kde.org/" + }, + "X-Plasma-API": "5.0" +} diff --git a/src/desktoptheme/breeze-light/plasmarc b/src/desktoptheme/breeze-light/plasmarc new file mode 100644 index 0000000..9e3a58f --- /dev/null +++ b/src/desktoptheme/breeze-light/plasmarc @@ -0,0 +1,14 @@ +[Wallpaper] +defaultWallpaperTheme=Next +defaultFileSuffix=.png +defaultWidth=1920 +defaultHeight=1080 + +[ContrastEffect] +enabled=true +contrast=0.17 +intensity=1.25 +saturation=9 + +[AdaptiveTransparency] +enabled=true diff --git a/src/desktoptheme/breeze/.gitignore b/src/desktoptheme/breeze/.gitignore new file mode 100644 index 0000000..f820cd3 --- /dev/null +++ b/src/desktoptheme/breeze/.gitignore @@ -0,0 +1,5 @@ +# Compiled source # +################### +*.directory +*.bak +*thumbs.db \ No newline at end of file diff --git a/src/desktoptheme/breeze/CMakeLists.txt b/src/desktoptheme/breeze/CMakeLists.txt new file mode 100644 index 0000000..9291c61 --- /dev/null +++ b/src/desktoptheme/breeze/CMakeLists.txt @@ -0,0 +1,40 @@ + +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/metadata.json.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/metadata.json" + @ONLY +) + +install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/metadata.json" + plasmarc + DESTINATION ${PLASMA_DATA_INSTALL_DIR}/desktoptheme/default +) + +FILE(GLOB widgets widgets/*.svg) +plasma_install_desktoptheme_svgs(default SUBPATH widgets FILES ${widgets}) + +FILE(GLOB dialogs dialogs/*.svg) +plasma_install_desktoptheme_svgs(default SUBPATH dialogs FILES ${dialogs}) + +FILE(GLOB opaque_dialogs opaque/dialogs/*.svg) +plasma_install_desktoptheme_svgs(default SUBPATH opaque/dialogs FILES ${opaque_dialogs}) + +FILE(GLOB opaque_widgets opaque/widgets/*.svg) +plasma_install_desktoptheme_svgs(default SUBPATH opaque/widgets FILES ${opaque_widgets}) + +FILE(GLOB translucent_widgets translucent/widgets/*.svg) +plasma_install_desktoptheme_svgs(default SUBPATH translucent/widgets FILES ${translucent_widgets}) + +FILE(GLOB translucent_dialogs translucent/dialogs/*.svg) +plasma_install_desktoptheme_svgs(default SUBPATH translucent/dialogs FILES ${translucent_dialogs}) + +FILE(GLOB solid_widgets solid/widgets/*.svg) +plasma_install_desktoptheme_svgs(default SUBPATH solid/widgets FILES ${solid_widgets}) + +FILE(GLOB solid_dialogs solid/dialogs/*.svg) +plasma_install_desktoptheme_svgs(default SUBPATH solid/dialogs FILES ${solid_dialogs}) + +FILE(GLOB icons icons/*.svg) +plasma_install_desktoptheme_svgs(default SUBPATH icons FILES ${icons}) + diff --git a/src/desktoptheme/breeze/dialogs/background.svg b/src/desktoptheme/breeze/dialogs/background.svg new file mode 100644 index 0000000..a422924 --- /dev/null +++ b/src/desktoptheme/breeze/dialogs/background.svg @@ -0,0 +1,665 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The corners of the mask are 1px smaller because theyare not antialiased, whereas the svg corners are; if themask is the same size of the svg, then, some of the cornerpixels of the mask will be visible even though they shouldbe covered by the svg. + diff --git a/src/desktoptheme/breeze/icons/akonadi.svg b/src/desktoptheme/breeze/icons/akonadi.svg new file mode 100644 index 0000000..9f1bb90 --- /dev/null +++ b/src/desktoptheme/breeze/icons/akonadi.svg @@ -0,0 +1,81 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/akregator.svg b/src/desktoptheme/breeze/icons/akregator.svg new file mode 100644 index 0000000..2e6d722 --- /dev/null +++ b/src/desktoptheme/breeze/icons/akregator.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/amarok.svg b/src/desktoptheme/breeze/icons/amarok.svg new file mode 100644 index 0000000..9bca0d5 --- /dev/null +++ b/src/desktoptheme/breeze/icons/amarok.svg @@ -0,0 +1,81 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/applications.svg b/src/desktoptheme/breeze/icons/applications.svg new file mode 100644 index 0000000..830796b --- /dev/null +++ b/src/desktoptheme/breeze/icons/applications.svg @@ -0,0 +1,95 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/apport.svg b/src/desktoptheme/breeze/icons/apport.svg new file mode 100644 index 0000000..8b73089 --- /dev/null +++ b/src/desktoptheme/breeze/icons/apport.svg @@ -0,0 +1,81 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/audio.svg b/src/desktoptheme/breeze/icons/audio.svg new file mode 100644 index 0000000..dfbf9a5 --- /dev/null +++ b/src/desktoptheme/breeze/icons/audio.svg @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/battery.svg b/src/desktoptheme/breeze/icons/battery.svg new file mode 100644 index 0000000..d771e84 --- /dev/null +++ b/src/desktoptheme/breeze/icons/battery.svg @@ -0,0 +1,956 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/bookmarks.svg b/src/desktoptheme/breeze/icons/bookmarks.svg new file mode 100644 index 0000000..179506d --- /dev/null +++ b/src/desktoptheme/breeze/icons/bookmarks.svg @@ -0,0 +1,95 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/cantata.svg b/src/desktoptheme/breeze/icons/cantata.svg new file mode 100644 index 0000000..d56e645 --- /dev/null +++ b/src/desktoptheme/breeze/icons/cantata.svg @@ -0,0 +1,92 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/computer.svg b/src/desktoptheme/breeze/icons/computer.svg new file mode 100644 index 0000000..931884a --- /dev/null +++ b/src/desktoptheme/breeze/icons/computer.svg @@ -0,0 +1,161 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/configure.svg b/src/desktoptheme/breeze/icons/configure.svg new file mode 100644 index 0000000..c14cf85 --- /dev/null +++ b/src/desktoptheme/breeze/icons/configure.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/device.svg b/src/desktoptheme/breeze/icons/device.svg new file mode 100644 index 0000000..5ddf466 --- /dev/null +++ b/src/desktoptheme/breeze/icons/device.svg @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/disk.svg b/src/desktoptheme/breeze/icons/disk.svg new file mode 100644 index 0000000..3b19ca2 --- /dev/null +++ b/src/desktoptheme/breeze/icons/disk.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/distribute.svg b/src/desktoptheme/breeze/icons/distribute.svg new file mode 100644 index 0000000..f85730f --- /dev/null +++ b/src/desktoptheme/breeze/icons/distribute.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/document.svg b/src/desktoptheme/breeze/icons/document.svg new file mode 100644 index 0000000..24cc666 --- /dev/null +++ b/src/desktoptheme/breeze/icons/document.svg @@ -0,0 +1,168 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/drive.svg b/src/desktoptheme/breeze/icons/drive.svg new file mode 100644 index 0000000..c019947 --- /dev/null +++ b/src/desktoptheme/breeze/icons/drive.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/edit.svg b/src/desktoptheme/breeze/icons/edit.svg new file mode 100644 index 0000000..106134e --- /dev/null +++ b/src/desktoptheme/breeze/icons/edit.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/fcitx.svg b/src/desktoptheme/breeze/icons/fcitx.svg new file mode 100644 index 0000000..39b6bb7 --- /dev/null +++ b/src/desktoptheme/breeze/icons/fcitx.svg @@ -0,0 +1,766 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/go.svg b/src/desktoptheme/breeze/icons/go.svg new file mode 100644 index 0000000..1c966c6 --- /dev/null +++ b/src/desktoptheme/breeze/icons/go.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/ime.svg b/src/desktoptheme/breeze/icons/ime.svg new file mode 100644 index 0000000..00a2099 --- /dev/null +++ b/src/desktoptheme/breeze/icons/ime.svg @@ -0,0 +1,697 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/input.svg b/src/desktoptheme/breeze/icons/input.svg new file mode 100644 index 0000000..e235621 --- /dev/null +++ b/src/desktoptheme/breeze/icons/input.svg @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/kalarm.svg b/src/desktoptheme/breeze/icons/kalarm.svg new file mode 100644 index 0000000..5ae5e5e --- /dev/null +++ b/src/desktoptheme/breeze/icons/kalarm.svg @@ -0,0 +1,126 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/kdeconnect.svg b/src/desktoptheme/breeze/icons/kdeconnect.svg new file mode 100644 index 0000000..8374825 --- /dev/null +++ b/src/desktoptheme/breeze/icons/kdeconnect.svg @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/keyboard.svg b/src/desktoptheme/breeze/icons/keyboard.svg new file mode 100644 index 0000000..225c8de --- /dev/null +++ b/src/desktoptheme/breeze/icons/keyboard.svg @@ -0,0 +1,99 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/kget.svg b/src/desktoptheme/breeze/icons/kget.svg new file mode 100644 index 0000000..dcc7e1d --- /dev/null +++ b/src/desktoptheme/breeze/icons/kget.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/kgpg.svg b/src/desktoptheme/breeze/icons/kgpg.svg new file mode 100644 index 0000000..7a669d9 --- /dev/null +++ b/src/desktoptheme/breeze/icons/kgpg.svg @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/kleopatra.svg b/src/desktoptheme/breeze/icons/kleopatra.svg new file mode 100644 index 0000000..7c67f41 --- /dev/null +++ b/src/desktoptheme/breeze/icons/kleopatra.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/klipper.svg b/src/desktoptheme/breeze/icons/klipper.svg new file mode 100644 index 0000000..5f0eea6 --- /dev/null +++ b/src/desktoptheme/breeze/icons/klipper.svg @@ -0,0 +1,70 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/kmail.svg b/src/desktoptheme/breeze/icons/kmail.svg new file mode 100644 index 0000000..8046e9e --- /dev/null +++ b/src/desktoptheme/breeze/icons/kmail.svg @@ -0,0 +1,66 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/konv_message.svg b/src/desktoptheme/breeze/icons/konv_message.svg new file mode 100644 index 0000000..8edaa4f --- /dev/null +++ b/src/desktoptheme/breeze/icons/konv_message.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/konversation.svg b/src/desktoptheme/breeze/icons/konversation.svg new file mode 100644 index 0000000..83b3101 --- /dev/null +++ b/src/desktoptheme/breeze/icons/konversation.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/kopete.svg b/src/desktoptheme/breeze/icons/kopete.svg new file mode 100644 index 0000000..07c4bb0 --- /dev/null +++ b/src/desktoptheme/breeze/icons/kopete.svg @@ -0,0 +1,66 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/korgac.svg b/src/desktoptheme/breeze/icons/korgac.svg new file mode 100644 index 0000000..0717abb --- /dev/null +++ b/src/desktoptheme/breeze/icons/korgac.svg @@ -0,0 +1,66 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/kpackagekit.svg b/src/desktoptheme/breeze/icons/kpackagekit.svg new file mode 100644 index 0000000..f120f3e --- /dev/null +++ b/src/desktoptheme/breeze/icons/kpackagekit.svg @@ -0,0 +1,88 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/kruler.svg b/src/desktoptheme/breeze/icons/kruler.svg new file mode 100644 index 0000000..7ed3255 --- /dev/null +++ b/src/desktoptheme/breeze/icons/kruler.svg @@ -0,0 +1,74 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/kteatime.svg b/src/desktoptheme/breeze/icons/kteatime.svg new file mode 100644 index 0000000..632b96b --- /dev/null +++ b/src/desktoptheme/breeze/icons/kteatime.svg @@ -0,0 +1,66 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/ktorrent.svg b/src/desktoptheme/breeze/icons/ktorrent.svg new file mode 100644 index 0000000..58f301e --- /dev/null +++ b/src/desktoptheme/breeze/icons/ktorrent.svg @@ -0,0 +1,80 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/kup.svg b/src/desktoptheme/breeze/icons/kup.svg new file mode 100644 index 0000000..35b330e --- /dev/null +++ b/src/desktoptheme/breeze/icons/kup.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/list.svg b/src/desktoptheme/breeze/icons/list.svg new file mode 100644 index 0000000..5d2f47c --- /dev/null +++ b/src/desktoptheme/breeze/icons/list.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/mail.svg b/src/desktoptheme/breeze/icons/mail.svg new file mode 100644 index 0000000..32d6cdf --- /dev/null +++ b/src/desktoptheme/breeze/icons/mail.svg @@ -0,0 +1,95 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/media.svg b/src/desktoptheme/breeze/icons/media.svg new file mode 100644 index 0000000..63d6b48 --- /dev/null +++ b/src/desktoptheme/breeze/icons/media.svg @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/mobile.svg b/src/desktoptheme/breeze/icons/mobile.svg new file mode 100644 index 0000000..0e3fac3 --- /dev/null +++ b/src/desktoptheme/breeze/icons/mobile.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/network.svg b/src/desktoptheme/breeze/icons/network.svg new file mode 100644 index 0000000..c0f6cf1 --- /dev/null +++ b/src/desktoptheme/breeze/icons/network.svg @@ -0,0 +1,4327 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/notification.svg b/src/desktoptheme/breeze/icons/notification.svg new file mode 100644 index 0000000..eed21e8 --- /dev/null +++ b/src/desktoptheme/breeze/icons/notification.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/osd.svg b/src/desktoptheme/breeze/icons/osd.svg new file mode 100644 index 0000000..ff2221c --- /dev/null +++ b/src/desktoptheme/breeze/icons/osd.svg @@ -0,0 +1,1048 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/phone.svg b/src/desktoptheme/breeze/icons/phone.svg new file mode 100644 index 0000000..25cf809 --- /dev/null +++ b/src/desktoptheme/breeze/icons/phone.svg @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/plasmavault.svg b/src/desktoptheme/breeze/icons/plasmavault.svg new file mode 100644 index 0000000..e67751c --- /dev/null +++ b/src/desktoptheme/breeze/icons/plasmavault.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/plasmavault_error.svg b/src/desktoptheme/breeze/icons/plasmavault_error.svg new file mode 100644 index 0000000..fc3607a --- /dev/null +++ b/src/desktoptheme/breeze/icons/plasmavault_error.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/preferences.svg b/src/desktoptheme/breeze/icons/preferences.svg new file mode 100644 index 0000000..7ff0f89 --- /dev/null +++ b/src/desktoptheme/breeze/icons/preferences.svg @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/printer.svg b/src/desktoptheme/breeze/icons/printer.svg new file mode 100644 index 0000000..3469c3d --- /dev/null +++ b/src/desktoptheme/breeze/icons/printer.svg @@ -0,0 +1,103 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/quassel.svg b/src/desktoptheme/breeze/icons/quassel.svg new file mode 100644 index 0000000..a9cc910 --- /dev/null +++ b/src/desktoptheme/breeze/icons/quassel.svg @@ -0,0 +1,175 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/search.svg b/src/desktoptheme/breeze/icons/search.svg new file mode 100644 index 0000000..79e9a1c --- /dev/null +++ b/src/desktoptheme/breeze/icons/search.svg @@ -0,0 +1,111 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/slc.svg b/src/desktoptheme/breeze/icons/slc.svg new file mode 100644 index 0000000..da3b4be --- /dev/null +++ b/src/desktoptheme/breeze/icons/slc.svg @@ -0,0 +1,174 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/software.svg b/src/desktoptheme/breeze/icons/software.svg new file mode 100644 index 0000000..e1f2cdc --- /dev/null +++ b/src/desktoptheme/breeze/icons/software.svg @@ -0,0 +1,94 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/start.svg b/src/desktoptheme/breeze/icons/start.svg new file mode 100644 index 0000000..bf37e52 --- /dev/null +++ b/src/desktoptheme/breeze/icons/start.svg @@ -0,0 +1,89 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/system.svg b/src/desktoptheme/breeze/icons/system.svg new file mode 100644 index 0000000..1f9012f --- /dev/null +++ b/src/desktoptheme/breeze/icons/system.svg @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/touchpad.svg b/src/desktoptheme/breeze/icons/touchpad.svg new file mode 100644 index 0000000..694bb14 --- /dev/null +++ b/src/desktoptheme/breeze/icons/touchpad.svg @@ -0,0 +1,153 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/user.svg b/src/desktoptheme/breeze/icons/user.svg new file mode 100644 index 0000000..19fe292 --- /dev/null +++ b/src/desktoptheme/breeze/icons/user.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/video-card.svg b/src/desktoptheme/breeze/icons/video-card.svg new file mode 100644 index 0000000..732f0ad --- /dev/null +++ b/src/desktoptheme/breeze/icons/video-card.svg @@ -0,0 +1,50 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/video.svg b/src/desktoptheme/breeze/icons/video.svg new file mode 100644 index 0000000..feb8527 --- /dev/null +++ b/src/desktoptheme/breeze/icons/video.svg @@ -0,0 +1,263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/view.svg b/src/desktoptheme/breeze/icons/view.svg new file mode 100644 index 0000000..71271ca --- /dev/null +++ b/src/desktoptheme/breeze/icons/view.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/vlc.svg b/src/desktoptheme/breeze/icons/vlc.svg new file mode 100644 index 0000000..c9d3b98 --- /dev/null +++ b/src/desktoptheme/breeze/icons/vlc.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/wallet.svg b/src/desktoptheme/breeze/icons/wallet.svg new file mode 100644 index 0000000..3343a8d --- /dev/null +++ b/src/desktoptheme/breeze/icons/wallet.svg @@ -0,0 +1,103 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/window.svg b/src/desktoptheme/breeze/icons/window.svg new file mode 100644 index 0000000..d99def2 --- /dev/null +++ b/src/desktoptheme/breeze/icons/window.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/yakuake.svg b/src/desktoptheme/breeze/icons/yakuake.svg new file mode 100644 index 0000000..1a5f799 --- /dev/null +++ b/src/desktoptheme/breeze/icons/yakuake.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/icons/zoom.svg b/src/desktoptheme/breeze/icons/zoom.svg new file mode 100644 index 0000000..70b0d80 --- /dev/null +++ b/src/desktoptheme/breeze/icons/zoom.svg @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/metadata.json.cmake b/src/desktoptheme/breeze/metadata.json.cmake new file mode 100644 index 0000000..e8ef8e4 --- /dev/null +++ b/src/desktoptheme/breeze/metadata.json.cmake @@ -0,0 +1,154 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "kde-artists@kde.org", + "Name": "KDE Visual Design Group", + "Name[ar]": "مجموعة التصميم المرئي لكِيدِي", + "Name[az]": "KDE Vizual Dizayn Qrupu", + "Name[be]": "Суполка візуальнага дызайну KDE", + "Name[bg]": "KDE Visual Design Group", + "Name[ca@valencia]": "Grup de disseny visual de KDE", + "Name[ca]": "Grup de disseny visual de KDE", + "Name[cs]": "Skupina vizuálního návrhu KDE", + "Name[da]": "KDE visuelle designgruppe", + "Name[de]": "KDE Visual Design Group", + "Name[el]": "Ομάδα οπτικού σχεδιασμού KDE", + "Name[en_GB]": "KDE Visual Design Group", + "Name[eo]": "KDE Vida Dezajna Grupo", + "Name[es]": "El grupo de diseño visual de KDE", + "Name[eu]": "KDE Diseinu bisualeko taldea", + "Name[fi]": "KDE:n visuaalinen suunnitteluryhmä", + "Name[fr]": "Groupe de conception graphique de KDE « VDG » (Visual Design Group)", + "Name[gl]": "Grupo de deseño visual de KDE", + "Name[he]": "קבוצת העיצוב החזותי של KDE", + "Name[hu]": "KDE Visual Design Group", + "Name[ia]": "KDE Visual Design Group (Gruppo de Designo Visual de KDE)", + "Name[id]": "Grup Desain Visual KDE", + "Name[is]": "Myndrænn hönnunarhópur KDE", + "Name[it]": "KDE Visual Design Group", + "Name[ka]": "KDE Visual Design Group", + "Name[ko]": "KDE 시각 디자인 그룹", + "Name[lt]": "KDE vaizdinio dizaino grupė", + "Name[lv]": "KDE Vizuālā dizaina grupa", + "Name[nl]": "KDE Visuele ontwerpgroep", + "Name[nn]": "KDE Visual Design Group", + "Name[pl]": "Grupa oprawy graficznej KDE", + "Name[pt]": "Grupo de Desenho Visual do KDE", + "Name[pt_BR]": "Grupo de design visual do KDE (KDE VDG)", + "Name[ro]": "KDE Visual Design Group", + "Name[ru]": "Группа KDE Visual Design", + "Name[sa]": "KDE Visual Design Group", + "Name[sk]": "KDE Visual Design Group", + "Name[sl]": "Skupina vizualnega designa KDE", + "Name[sv]": "KDE:s visuella designgrupp", + "Name[ta]": "கே.டீ.யீ. வரைகலை வடிவமைப்புக் குழு", + "Name[tr]": "KDE Görsel Tasarım Grubu", + "Name[uk]": "Група з візуального дизайну KDE", + "Name[vi]": "Đội Thiết kế Trực quan KDE", + "Name[x-test]": "xxKDE Visual Design Groupxx", + "Name[zh_CN]": "KDE 视觉设计团队", + "Name[zh_TW]": "KDE VDG 視覺設計組" + } + ], + "Category": "", + "Description": "Breeze by the KDE VDG", + "Description[ar]": "نسيم من مجموعة تصميم كِيدِي", + "Description[az]": "KDE VDG tərəfindən Breeze İş mühiti görünüşü", + "Description[be]": "Breeze ад KDE VDG", + "Description[bg]": "Breeze от KDE VDG", + "Description[ca@valencia]": "Brisa, creat pel VDG de KDE", + "Description[ca]": "Brisa, creat pel VDG del KDE", + "Description[cs]": "Breeze od KDE VDG", + "Description[da]": "Breeze af KDE's visuelle designgruppe", + "Description[de]": "Breeze von der KDE VDG", + "Description[el]": "Breeze από το KDE VDG", + "Description[en_GB]": "Breeze by the KDE VDG", + "Description[eo]": "Brizo de la KDE VDG", + "Description[es]": "Brisa, por KDE VDG", + "Description[eu]": "Brisa KDEren VDGk egina", + "Description[fi]": "Breeze KDE VDG:ltä", + "Description[fr]": "Breeze par l'équipe « KDE VDG »", + "Description[gl]": "Brisa do KDE VDG.", + "Description[he]": "בריזה מאת קבוצת העיצוב החזותי של KDE", + "Description[hu]": "Breeze a KDE VDG-től", + "Description[ia]": "Breeze (Brisa) per le KDE VDG", + "Description[id]": "Breeze oleh KDE VDG", + "Description[is]": "Breeze frá KDE VDG", + "Description[it]": "Brezza a cura del KDE VDG", + "Description[ka]": "Breeze KDE VDG-სგან", + "Description[ko]": "KDE 시각 디자인 그룹에서 제작한 Breeze", + "Description[lt]": "Breeze pagal KDE VDG", + "Description[lv]": "KDE VDG veidotā „Breeze“", + "Description[nl]": "Breeze door de KDE VDG", + "Description[nn]": "Breeze frå KDE VDG", + "Description[pl]": "Bryza autorstwa KDE VDG", + "Description[pt]": "Brisa da VDG do KDE", + "Description[pt_BR]": "Breeze pelo KDE VDG", + "Description[ro]": "Briză, de KDE VDG", + "Description[ru]": "Оформление рабочей среды Breeze от KDE VDG", + "Description[sa]": "KDE VDG द्वारा Breeze", + "Description[sk]": "Vánok od KDE VDG", + "Description[sl]": "Sapica od KDE VDG", + "Description[sv]": "Breeze av KDE:s visuella designgrupp", + "Description[ta]": "கே.டீ.யீ. VDG வழங்கும் பிரீஸ்", + "Description[tr]": "KDE VDG’den Esinti", + "Description[uk]": "Breeze, автори — KDE VDG", + "Description[vi]": "Breeze, do KDE VDG", + "Description[x-test]": "xxBreeze by the KDE VDGxx", + "Description[zh_CN]": "Breeze 微风主题,由 KDE VDG (视觉设计团队) 设计制作", + "Description[zh_TW]": "由 KDE VDG 設計的 Breeze", + "EnabledByDefault": true, + "Id": "default", + "License": "LGPL", + "Name": "Breeze", + "Name[ar]": "نسيم", + "Name[az]": "Breeze", + "Name[be]": "Breeze", + "Name[bg]": "Breeze", + "Name[ca@valencia]": "Brisa", + "Name[ca]": "Brisa", + "Name[cs]": "Breeze", + "Name[da]": "Breeze", + "Name[de]": "Breeze", + "Name[el]": "Breeze", + "Name[en_GB]": "Breeze", + "Name[eo]": "Vento", + "Name[es]": "Brisa", + "Name[eu]": "Brisa", + "Name[fi]": "Breeze", + "Name[fr]": "Breeze", + "Name[gl]": "Brisa", + "Name[he]": "בריזה", + "Name[hu]": "Breeze", + "Name[ia]": "Brisa", + "Name[id]": "Breeze", + "Name[is]": "Breeze", + "Name[it]": "Brezza", + "Name[ka]": "ნიავი", + "Name[ko]": "Breeze", + "Name[lt]": "Breeze", + "Name[lv]": "Breeze", + "Name[nl]": "Breeze", + "Name[nn]": "Breeze", + "Name[pl]": "Bryza", + "Name[pt]": "Brisa", + "Name[pt_BR]": "Breeze", + "Name[ro]": "Briză", + "Name[ru]": "Breeze", + "Name[sa]": "Breeze", + "Name[sk]": "Vánok", + "Name[sl]": "Sapica", + "Name[sv]": "Breeze", + "Name[ta]": "பிரீஸ்", + "Name[tr]": "Esinti", + "Name[uk]": "Breeze", + "Name[vi]": "Breeze", + "Name[x-test]": "xxBreezexx", + "Name[zh_CN]": "Breeze 微风", + "Name[zh_TW]": "Breeze", + "Version": "@KF6_MIN_VERSION@", + "Website": "https://www.kde.org/" + }, + "X-Plasma-API": "5.0" +} diff --git a/src/desktoptheme/breeze/opaque/dialogs/background.svg b/src/desktoptheme/breeze/opaque/dialogs/background.svg new file mode 100644 index 0000000..0c5c17d --- /dev/null +++ b/src/desktoptheme/breeze/opaque/dialogs/background.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/opaque/widgets/panel-background.svg b/src/desktoptheme/breeze/opaque/widgets/panel-background.svg new file mode 100644 index 0000000..64a2b38 --- /dev/null +++ b/src/desktoptheme/breeze/opaque/widgets/panel-background.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/opaque/widgets/tooltip.svg b/src/desktoptheme/breeze/opaque/widgets/tooltip.svg new file mode 100644 index 0000000..5220abd --- /dev/null +++ b/src/desktoptheme/breeze/opaque/widgets/tooltip.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/plasmarc b/src/desktoptheme/breeze/plasmarc new file mode 100644 index 0000000..dbff0aa --- /dev/null +++ b/src/desktoptheme/breeze/plasmarc @@ -0,0 +1,13 @@ +[Wallpaper] +defaultWallpaperTheme=Next +defaultFileSuffix=.png +defaultWidth=1920 +defaultHeight=1080 + +[ContrastEffect] +enabled=true +contrast=0.2 +saturation=10 + +[AdaptiveTransparency] +enabled=true diff --git a/src/desktoptheme/breeze/solid/dialogs/background.svg b/src/desktoptheme/breeze/solid/dialogs/background.svg new file mode 100644 index 0000000..63de59d --- /dev/null +++ b/src/desktoptheme/breeze/solid/dialogs/background.svg @@ -0,0 +1,635 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The corners of the mask are 1px smaller because theyare not antialiased, whereas the svg corners are; if themask is the same size of the svg, then, some of the cornerpixels of the mask will be visible even though they shouldbe covered by the svg. + diff --git a/src/desktoptheme/breeze/solid/widgets/background.svg b/src/desktoptheme/breeze/solid/widgets/background.svg new file mode 100644 index 0000000..5749766 --- /dev/null +++ b/src/desktoptheme/breeze/solid/widgets/background.svg @@ -0,0 +1,669 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The corners of the mask are 1px smaller because theyare not antialiased, whereas the svg corners are; if themask is the same size of the svg, then, some of the cornerpixels of the mask will be visible even though they shouldbe covered by the svg. + diff --git a/src/desktoptheme/breeze/solid/widgets/panel-background.svg b/src/desktoptheme/breeze/solid/widgets/panel-background.svg new file mode 100644 index 0000000..bacfbf2 --- /dev/null +++ b/src/desktoptheme/breeze/solid/widgets/panel-background.svg @@ -0,0 +1,676 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The corners of the mask are 1px smaller because theyare not antialiased, whereas the svg corners are; if themask is the same size of the svg, then, some of the cornerpixels of the mask will be visible even though they shouldbe covered by the svg. + diff --git a/src/desktoptheme/breeze/solid/widgets/tooltip.svg b/src/desktoptheme/breeze/solid/widgets/tooltip.svg new file mode 100644 index 0000000..49f65ec --- /dev/null +++ b/src/desktoptheme/breeze/solid/widgets/tooltip.svg @@ -0,0 +1,638 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The corners of the mask are 1px smaller because theyare not antialiased, whereas the svg corners are; if themask is the same size of the svg, then, some of the cornerpixels of the mask will be visible even though they shouldbe covered by the svg. + diff --git a/src/desktoptheme/breeze/translucent/dialogs/background.svg b/src/desktoptheme/breeze/translucent/dialogs/background.svg new file mode 100644 index 0000000..af7c6a3 --- /dev/null +++ b/src/desktoptheme/breeze/translucent/dialogs/background.svg @@ -0,0 +1,662 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The corners of the mask are 1px smaller because theyare not antialiased, whereas the svg corners are; if themask is the same size of the svg, then, some of the cornerpixels of the mask will be visible even though they shouldbe covered by the svg. + diff --git a/src/desktoptheme/breeze/translucent/widgets/background.svg b/src/desktoptheme/breeze/translucent/widgets/background.svg new file mode 100644 index 0000000..187c0c6 --- /dev/null +++ b/src/desktoptheme/breeze/translucent/widgets/background.svg @@ -0,0 +1,1422 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + image/svg+xml + + + + image/svg+xml + + + + + + +   + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/translucent/widgets/panel-background.svg b/src/desktoptheme/breeze/translucent/widgets/panel-background.svg new file mode 100644 index 0000000..bb8d544 --- /dev/null +++ b/src/desktoptheme/breeze/translucent/widgets/panel-background.svg @@ -0,0 +1,700 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The corners of the mask are 1px smaller because theyare not antialiased, whereas the svg corners are; if themask is the same size of the svg, then, some of the cornerpixels of the mask will be visible even though they shouldbe covered by the svg. + diff --git a/src/desktoptheme/breeze/translucent/widgets/tooltip.svg b/src/desktoptheme/breeze/translucent/widgets/tooltip.svg new file mode 100644 index 0000000..b19c630 --- /dev/null +++ b/src/desktoptheme/breeze/translucent/widgets/tooltip.svg @@ -0,0 +1,662 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The corners of the mask are 1px smaller because theyare not antialiased, whereas the svg corners are; if themask is the same size of the svg, then, some of the cornerpixels of the mask will be visible even though they shouldbe covered by the svg. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/.png b/src/desktoptheme/breeze/widgets/.png new file mode 100644 index 0000000000000000000000000000000000000000..eedda0f71d400629008e50f2b1f53e0764750869 GIT binary patch literal 283 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4u@pObhHwBu4M$1`kk47*5n0T@ zAiW-h8RMiT$^Zo=OI#yLg7ec#$`gxH8OqDc^)mCai<1)zQuXqS(r3T3kpe23;pyTS zA~Ch~ykVA8pg`-x{B=^I%9@*)v%RlBx^|~udc)QYTfAqv2#P+9ve2(=Qe>}tC-Q&p zVVAX{E=QQMb2c1RFSB?Q^=H|F$t9n4Jxih=nOD7dtomF|Z$)llw>gi2&$%6DrM_Vj ziFY2EO8(7RvsF(yX;w6UWaOrQB4@8w{*)-*^O!mQ#^WCf+w9I5oV@jE`463^^-t$X Yv*@cmy>_X<3+P4$Pgg&ebxsLQ0JHgN=>Px# literal 0 HcmV?d00001 diff --git a/src/desktoptheme/breeze/widgets/action-overlays.svg b/src/desktoptheme/breeze/widgets/action-overlays.svg new file mode 100644 index 0000000..1eda611 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/action-overlays.svg @@ -0,0 +1,420 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/actionbutton.svg b/src/desktoptheme/breeze/widgets/actionbutton.svg new file mode 100644 index 0000000..4a385f4 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/actionbutton.svg @@ -0,0 +1,491 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/analog_meter.svg b/src/desktoptheme/breeze/widgets/analog_meter.svg new file mode 100644 index 0000000..af67d15 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/analog_meter.svg @@ -0,0 +1,697 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/arrows.svg b/src/desktoptheme/breeze/widgets/arrows.svg new file mode 100644 index 0000000..d88465b --- /dev/null +++ b/src/desktoptheme/breeze/widgets/arrows.svg @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/background.svg b/src/desktoptheme/breeze/widgets/background.svg new file mode 100644 index 0000000..47ab2ff --- /dev/null +++ b/src/desktoptheme/breeze/widgets/background.svg @@ -0,0 +1,922 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + image/svg+xml + + + + image/svg+xml + + + + + + +   + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/bar_meter_horizontal.svg b/src/desktoptheme/breeze/widgets/bar_meter_horizontal.svg new file mode 100644 index 0000000..5d64a08 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/bar_meter_horizontal.svg @@ -0,0 +1,457 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/bar_meter_vertical.svg b/src/desktoptheme/breeze/widgets/bar_meter_vertical.svg new file mode 100644 index 0000000..927dec2 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/bar_meter_vertical.svg @@ -0,0 +1,457 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/branding.svg b/src/desktoptheme/breeze/widgets/branding.svg new file mode 100644 index 0000000..30f5945 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/branding.svg @@ -0,0 +1,69 @@ + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/busywidget.svg b/src/desktoptheme/breeze/widgets/busywidget.svg new file mode 100644 index 0000000..0eaf137 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/busywidget.svg @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/button.svg b/src/desktoptheme/breeze/widgets/button.svg new file mode 100644 index 0000000..ff52c5f --- /dev/null +++ b/src/desktoptheme/breeze/widgets/button.svg @@ -0,0 +1,1819 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + buttonarea + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + normal + hover + focus + pressed + (default) + toolbutton + shadow + mask + background + + margin hint + NOTE: Some margin hints have 0.001 width or height because you can't use exactly 0! NOTE: shadow, hover and focus (not focus-background) use negative margins! This behavior is implemented in at least the following files (please keep this up to date, fix the problem or find a better place to put this info): plasma-framework/src/declarativeimports/plasmacomponents3/private/ButtonShadow.qml plasma-framework/src/declarativeimports/plasmacomponents3/private/ButtonHover.qml plasma-framework/src/declarativeimports/plasmacomponents3/private/ButtonFocus.qml We should add support for a negative margins hint to FrameSvg and document it instead of requiring people to read source code in order to know these things. Unfortunately, not sure if we can change the code of ButtonShadow since it would break themes that rely on this undocumented behaviour. Maybe in KF6. + + + + other hints + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/calendar.svg b/src/desktoptheme/breeze/widgets/calendar.svg new file mode 100644 index 0000000..0b8f88c --- /dev/null +++ b/src/desktoptheme/breeze/widgets/calendar.svg @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/checkmarks.svg b/src/desktoptheme/breeze/widgets/checkmarks.svg new file mode 100644 index 0000000..e13150c --- /dev/null +++ b/src/desktoptheme/breeze/widgets/checkmarks.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/clock.svg b/src/desktoptheme/breeze/widgets/clock.svg new file mode 100644 index 0000000..330dcd2 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/clock.svg @@ -0,0 +1,856 @@ + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/configuration-icons.svg b/src/desktoptheme/breeze/widgets/configuration-icons.svg new file mode 100644 index 0000000..bdbaa7a --- /dev/null +++ b/src/desktoptheme/breeze/widgets/configuration-icons.svg @@ -0,0 +1,715 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/containment-controls.svg b/src/desktoptheme/breeze/widgets/containment-controls.svg new file mode 100644 index 0000000..96b7eae --- /dev/null +++ b/src/desktoptheme/breeze/widgets/containment-controls.svg @@ -0,0 +1,672 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/dragger.svg b/src/desktoptheme/breeze/widgets/dragger.svg new file mode 100644 index 0000000..4650a7a --- /dev/null +++ b/src/desktoptheme/breeze/widgets/dragger.svg @@ -0,0 +1,301 @@ + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/frame.svg b/src/desktoptheme/breeze/widgets/frame.svg new file mode 100644 index 0000000..9586c0b --- /dev/null +++ b/src/desktoptheme/breeze/widgets/frame.svg @@ -0,0 +1,879 @@ + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/glowbar.svg b/src/desktoptheme/breeze/widgets/glowbar.svg new file mode 100644 index 0000000..713bd7c --- /dev/null +++ b/src/desktoptheme/breeze/widgets/glowbar.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/line.svg b/src/desktoptheme/breeze/widgets/line.svg new file mode 100644 index 0000000..f57eccb --- /dev/null +++ b/src/desktoptheme/breeze/widgets/line.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/lineedit.svg b/src/desktoptheme/breeze/widgets/lineedit.svg new file mode 100644 index 0000000..30077ee --- /dev/null +++ b/src/desktoptheme/breeze/widgets/lineedit.svg @@ -0,0 +1,835 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/listitem.svg b/src/desktoptheme/breeze/widgets/listitem.svg new file mode 100644 index 0000000..153eabc --- /dev/null +++ b/src/desktoptheme/breeze/widgets/listitem.svg @@ -0,0 +1,870 @@ + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/margins-highlight.svg b/src/desktoptheme/breeze/widgets/margins-highlight.svg new file mode 100644 index 0000000..d82adbf --- /dev/null +++ b/src/desktoptheme/breeze/widgets/margins-highlight.svg @@ -0,0 +1,315 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/media-delegate.svg b/src/desktoptheme/breeze/widgets/media-delegate.svg new file mode 100644 index 0000000..596df55 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/media-delegate.svg @@ -0,0 +1,531 @@ + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/menubaritem.svg b/src/desktoptheme/breeze/widgets/menubaritem.svg new file mode 100644 index 0000000..349a1a6 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/menubaritem.svg @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/monitor.svg b/src/desktoptheme/breeze/widgets/monitor.svg new file mode 100644 index 0000000..7a75622 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/monitor.svg @@ -0,0 +1,2910 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/notes.svg b/src/desktoptheme/breeze/widgets/notes.svg new file mode 100644 index 0000000..1f66b2c --- /dev/null +++ b/src/desktoptheme/breeze/widgets/notes.svg @@ -0,0 +1,3095 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/pager.svg b/src/desktoptheme/breeze/widgets/pager.svg new file mode 100644 index 0000000..c9c69f7 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/pager.svg @@ -0,0 +1,727 @@ + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/panel-background.svg b/src/desktoptheme/breeze/widgets/panel-background.svg new file mode 100644 index 0000000..300d5a0 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/panel-background.svg @@ -0,0 +1,700 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The corners of the mask are 1px smaller because theyare not antialiased, whereas the svg corners are; if themask is the same size of the svg, then, some of the cornerpixels of the mask will be visible even though they shouldbe covered by the svg. + diff --git a/src/desktoptheme/breeze/widgets/picker.svg b/src/desktoptheme/breeze/widgets/picker.svg new file mode 100644 index 0000000..db75f8c --- /dev/null +++ b/src/desktoptheme/breeze/widgets/picker.svg @@ -0,0 +1,548 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/plasmoidheading.svg b/src/desktoptheme/breeze/widgets/plasmoidheading.svg new file mode 100644 index 0000000..362ee14 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/plasmoidheading.svg @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/plot-background.svg b/src/desktoptheme/breeze/widgets/plot-background.svg new file mode 100644 index 0000000..e48f135 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/plot-background.svg @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/radiobutton.svg b/src/desktoptheme/breeze/widgets/radiobutton.svg new file mode 100644 index 0000000..d0687cc --- /dev/null +++ b/src/desktoptheme/breeze/widgets/radiobutton.svg @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/scrollbar.svg b/src/desktoptheme/breeze/widgets/scrollbar.svg new file mode 100644 index 0000000..065ec6d --- /dev/null +++ b/src/desktoptheme/breeze/widgets/scrollbar.svg @@ -0,0 +1,996 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/scrollwidget.svg b/src/desktoptheme/breeze/widgets/scrollwidget.svg new file mode 100644 index 0000000..9dcf5c8 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/scrollwidget.svg @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/slider.svg b/src/desktoptheme/breeze/widgets/slider.svg new file mode 100644 index 0000000..bb965df --- /dev/null +++ b/src/desktoptheme/breeze/widgets/slider.svg @@ -0,0 +1,662 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/switch.svg b/src/desktoptheme/breeze/widgets/switch.svg new file mode 100644 index 0000000..5cd5e0b --- /dev/null +++ b/src/desktoptheme/breeze/widgets/switch.svg @@ -0,0 +1,487 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/tabbar.svg b/src/desktoptheme/breeze/widgets/tabbar.svg new file mode 100644 index 0000000..c4c2e07 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/tabbar.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/tasks.svg b/src/desktoptheme/breeze/widgets/tasks.svg new file mode 100644 index 0000000..b76d1a3 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/tasks.svg @@ -0,0 +1,981 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/toolbar.svg b/src/desktoptheme/breeze/widgets/toolbar.svg new file mode 100644 index 0000000..e8169c5 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/toolbar.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/tooltip.svg b/src/desktoptheme/breeze/widgets/tooltip.svg new file mode 100644 index 0000000..969e943 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/tooltip.svg @@ -0,0 +1,662 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The corners of the mask are 1px smaller because theyare not antialiased, whereas the svg corners are; if themask is the same size of the svg, then, some of the cornerpixels of the mask will be visible even though they shouldbe covered by the svg. + diff --git a/src/desktoptheme/breeze/widgets/translucentbackground.svg b/src/desktoptheme/breeze/widgets/translucentbackground.svg new file mode 100644 index 0000000..d0f4b84 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/translucentbackground.svg @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/breeze/widgets/viewitem.svg b/src/desktoptheme/breeze/widgets/viewitem.svg new file mode 100644 index 0000000..1b231b4 --- /dev/null +++ b/src/desktoptheme/breeze/widgets/viewitem.svg @@ -0,0 +1,706 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktoptheme/oxygen/metadata.json.cmake b/src/desktoptheme/oxygen/metadata.json.cmake new file mode 100644 index 0000000..95a64f5 --- /dev/null +++ b/src/desktoptheme/oxygen/metadata.json.cmake @@ -0,0 +1,152 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "kde-artists@kde.org", + "Name": "The Oxygen Project", + "Name[az]": "Oxygen layihəsi", + "Name[be]": "Праект \"Oxygen\"", + "Name[bg]": "Проектът Oxygen", + "Name[ca@valencia]": "El projecte Oxygen", + "Name[ca]": "The Oxygen Project", + "Name[cs]": "Projekt Oxygen", + "Name[da]": "Oxygen-projektet", + "Name[de]": "Das Oxygen-Projekt", + "Name[el]": "Το έργο Oxygen", + "Name[en_GB]": "The Oxygen Project", + "Name[eo]": "La Oksigeno-Projekto", + "Name[es]": "El proyecto Oxígeno", + "Name[eu]": "«Oxygen» proiektua", + "Name[fi]": "Oxygen-projekti", + "Name[fr]": "Le projet « Oxygen »", + "Name[gl]": "O proxecto Osíxeno", + "Name[he]": "מיזם חמצן (Oxygen)", + "Name[hu]": "Az Oxygen projekt", + "Name[ia]": "Le projecto Oxigen", + "Name[id]": "The Oxygen Project", + "Name[is]": "Oxygen-verkefnið", + "Name[it]": "Il progetto Oxygen", + "Name[ka]": "The Oxygen Project", + "Name[ko]": "The Oxygen Project", + "Name[lt]": "Oxygen projektas", + "Name[lv]": "„Oxygen“ projekts", + "Name[nl]": "Het project Oxygen", + "Name[nn]": "Oxygen-prosjektet", + "Name[pl]": "Projekt Tlenu", + "Name[pt]": "O Projecto Oxygen", + "Name[pt_BR]": "O projeto Oxygen", + "Name[ro]": "Proiectul Oxygen", + "Name[ru]": "Проект Oxygen", + "Name[sa]": "The Oxygen Project", + "Name[sk]": "Projekt Oxygen", + "Name[sl]": "Projekt kisik", + "Name[sv]": "Oxygen-projektet", + "Name[ta]": "ஆக்‌ஸிஜன் திட்டப்பணி", + "Name[tr]": "Oksijen Projesi", + "Name[uk]": "Проєкт Oxygen", + "Name[vi]": "Dự án Oxygen", + "Name[x-test]": "xxThe Oxygen Projectxx", + "Name[zh_CN]": "Oxygen 轻氧项目", + "Name[zh_TW]": "Oxygen 專案" + } + ], + "Category": "", + "Description": "Theme done in the Oxygen style", + "Description[az]": "Mövzu Oxygen stilində hazırlanıb", + "Description[be]": "Тэма створаная ў стылі Oxygen", + "Description[bg]": "Тема в стил Oxygen", + "Description[ca@valencia]": "Tema fet en l'estil Oxygen", + "Description[ca]": "Tema fet en l'estil Oxygen", + "Description[cs]": "Motiv ve stylu Oxygen", + "Description[da]": "Teame gjort i Oxygen-stilen", + "Description[de]": "Ein Design im Oxygen-Stil", + "Description[el]": "Θέμα στο στυλ Oxygen", + "Description[en_GB]": "Theme done in the Oxygen style", + "Description[eo]": "Etoso farita en la stilo de Oksigeno", + "Description[es]": "Tema realizado al estilo de Oxígeno", + "Description[eu]": "Oxygen-en estilora egindako gaia", + "Description[fi]": "Oxygen-tyylillä tehty teema", + "Description[fr]": "Thème réalisé selon un thème « Oxygen »", + "Description[gl]": "Tema feito no estilo Oxygen.", + "Description[he]": "ערכת העיצוב עוצבה בסגנון חמצן (Oxygen)", + "Description[hu]": "Az Oxygen stílusában készült téma", + "Description[ia]": "Thema facite in le stilo de Oxygen", + "Description[id]": "Tema dilakukan dalam gaya Oksigen", + "Description[is]": "Þema gert í stíl við Oxygen", + "Description[it]": "Tema realizzato nello stile di Oxygen", + "Description[ka]": "Oxygen-ის სტილში შესრულებული თემა", + "Description[ko]": "Oxygen 스타일의 기본 테마", + "Description[lt]": "Apipavidalinimas atliktas Oxygen stiliuje", + "Description[lv]": "„Oxygen“ stilā veidots motīvs", + "Description[nl]": "Thema in Oxygen-stijl", + "Description[nn]": "Tema laga i Oxygen-stilen", + "Description[pl]": "Wystrój wzorowany na stylu Tlen", + "Description[pt]": "Tema criado no estilo do Oxygen", + "Description[pt_BR]": "Tema feito no estilo Oxygen", + "Description[ro]": "Tematică executată în stilul Oxygen", + "Description[ru]": "Тема, выполненная в стиле Oxygen", + "Description[sa]": "आक्सीजनशैल्या कृता विषयः", + "Description[sk]": "Téma vytvorená v štýle Oxygen", + "Description[sl]": "Teme izdelana v slogu Kisika", + "Description[sv]": "Tema skapat med Oxygen-stilen", + "Description[ta]": "ஆக்ஸிஜன் பாணியிலுள்ள தோற்றத்திட்டம்", + "Description[tr]": "Oksijen tarzında yapılmış tema", + "Description[uk]": "Тема в стилі Oxygen", + "Description[vi]": "Chủ đề được tạo với kiểu cách Oxygen", + "Description[x-test]": "xxTheme done in the Oxygen stylexx", + "Description[zh_CN]": "Oxygen 轻氧风格的主题", + "Description[zh_TW]": "以 Oxygen 風格所做的主題", + "EnabledByDefault": true, + "Id": "oxygen", + "License": "GPL", + "Name": "Oxygen", + "Name[ar]": "أكسجين", + "Name[az]": "Oxygen ayarları", + "Name[be]": "Oxygen", + "Name[bg]": "Oxygen", + "Name[ca@valencia]": "Oxygen", + "Name[ca]": "Oxygen", + "Name[cs]": "Oxygen", + "Name[da]": "Oxygen", + "Name[de]": "Oxygen", + "Name[el]": "Oxygen", + "Name[en_GB]": "Oxygen", + "Name[eo]": "Oksigeno", + "Name[es]": "Oxígeno", + "Name[eu]": "Oxigenoa", + "Name[fi]": "Oxygen", + "Name[fr]": "Oxygen", + "Name[gl]": "Osíxeno", + "Name[he]": "חמצן", + "Name[hu]": "Oxygen", + "Name[ia]": "Oxygen", + "Name[id]": "Oxygen", + "Name[is]": "Oxygen", + "Name[it]": "Oxygen", + "Name[ka]": "ჟანგბადი", + "Name[ko]": "Oxygen", + "Name[lt]": "Oxygen", + "Name[lv]": "Oxygen", + "Name[nl]": "Oxygen", + "Name[nn]": "Oxygen", + "Name[pl]": "Tlen", + "Name[pt]": "Oxygen", + "Name[pt_BR]": "Oxygen", + "Name[ro]": "Oxygen", + "Name[ru]": "Oxygen", + "Name[sa]": "आक्सीजन (Oxygen)", + "Name[sk]": "Oxygen", + "Name[sl]": "Kisik", + "Name[sv]": "Oxygen", + "Name[ta]": "ஆக்ஸிஜன்", + "Name[tr]": "Oksijen", + "Name[uk]": "Oxygen", + "Name[vi]": "Oxygen", + "Name[x-test]": "xxOxygenxx", + "Name[zh_CN]": "Oxygen 轻氧", + "Name[zh_TW]": "Oxygen", + "Version": "@KF6_MIN_VERSION@", + "Website": "https://www.kde.org/" + }, + "X-Plasma-API": "5.0" +} diff --git a/src/plasma/.krazy b/src/plasma/.krazy new file mode 100644 index 0000000..587e2fc --- /dev/null +++ b/src/plasma/.krazy @@ -0,0 +1,2 @@ +EXTRA defines,kdebug,qenums,tipsandthis +SKIP /widgets/template\.h diff --git a/src/plasma/CMakeLists.txt b/src/plasma/CMakeLists.txt new file mode 100644 index 0000000..d353a35 --- /dev/null +++ b/src/plasma/CMakeLists.txt @@ -0,0 +1,161 @@ +add_subdirectory(packagestructure) + +# Consumer's include dir which has to be explicitly used to make headers of this lib visible to documented includes +# Results in duplicate of prefix-dir & C++ namespace below, but part of different things, so by design: +# //class header files +set(PLASMA_INSTALL_INCLUDEDIR "${KDE_INSTALL_INCLUDEDIR}/Plasma") + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-plasma.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-plasma.h) + +add_library(Plasma) +add_library(Plasma::Plasma ALIAS Plasma) + +qt_extract_metatypes(Plasma) + +set_target_properties(Plasma PROPERTIES + VERSION ${PLASMA_VERSION} + SOVERSION ${PLASMA_SOVERSION} + EXPORT_NAME Plasma +) + +target_sources(Plasma PRIVATE +#global + plasma.cpp + pluginloader.cpp + +#applets,containments,corona + applet.cpp + containment.cpp + containmentactions.cpp + corona.cpp + private/applet_p.cpp + private/containment_p.cpp + +#graphics + theme.cpp + private/theme_p.cpp +) + +if(HAVE_X11) + target_sources(Plasma PRIVATE private/effectwatcher.cpp) +endif() + +kconfig_add_kcfg_files(Plasma data/kconfigxt/libplasma-theme-global.kcfgc) + +ecm_qt_declare_logging_category(Plasma + HEADER debug_p.h + IDENTIFIER LOG_PLASMA + CATEGORY_NAME kf.plasma.core + OLD_CATEGORY_NAMES org.kde.plasma + DESCRIPTION "Plasma Core lib" + EXPORT PLASMA +) + +ecm_generate_export_header(Plasma + EXPORT_FILE_NAME plasma/plasma_export.h + BASE_NAME Plasma + GROUP_BASE_NAME KF + VERSION ${KF6_MIN_VERSION} + USE_VERSION_HEADER + DEPRECATED_BASE_VERSION 0 + EXCLUDE_DEPRECATED_BEFORE_AND_AT ${EXCLUDE_DEPRECATED_BEFORE_AND_AT} + DEPRECATION_VERSIONS +) + +if(HAVE_X11) + set(PLASMA_EXTRA_LIBS ${PLASMA_EXTRA_LIBS} XCB::XCB) +endif() + +target_link_libraries(Plasma +PUBLIC + Qt6::Gui + KF6::ConfigCore + KF6::CoreAddons + Qt6::Qml +PRIVATE + Qt6::Quick + KF6::ConfigGui + KF6::ColorScheme + KF6::ConfigQml + KF6::Archive + KF6::GuiAddons #kimagecache + KF6::I18n + KF6::WindowSystem #compositingActive + KF6::GlobalAccel #Applet::setGlobalShortcut + KF6::Notifications + KF6::IconThemes + Plasma::Activities + KF6::Svg + ${PLASMA_EXTRA_LIBS} +) + +target_link_libraries(Plasma PRIVATE KF6::Package) + +set(Plasma_BUILD_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/Plasma +) +target_include_directories(Plasma + PUBLIC + "$" + INTERFACE + "$" +) + +########### install files ############### +ecm_generate_headers(Plasma_CamelCase_HEADERS + HEADER_NAMES + Applet + Containment + ContainmentActions + Corona + PluginLoader + Theme + Plasma + REQUIRED_HEADERS Plasma_HEADERS + PREFIX Plasma +) + +install(FILES + ${Plasma_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/plasma/plasma_export.h + DESTINATION ${PLASMA_INSTALL_INCLUDEDIR}/plasma # C++ namespace + COMPONENT Devel +) + +install( + FILES ${Plasma_CamelCase_HEADERS} + DESTINATION ${PLASMA_INSTALL_INCLUDEDIR}/Plasma # C++ namespace + COMPONENT Devel +) + +install(TARGETS Plasma EXPORT PlasmaTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) + +if(BUILD_QCH) + ecm_add_qch( + Plasma_QCH + NAME Plasma + BASE_NAME Plasma + VERSION ${PLASMA_VERSION} + ORG_DOMAIN org.kde + SOURCES # using only public headers, to cover only public API + ${Plasma_HEADERS} + Mainpage.dox + MD_MAINPAGE "${CMAKE_SOURCE_DIR}/README.md" + LINK_QCHS + Qt6Gui_QCH + KF6Service_QCH + KF6Package_QCH + INCLUDE_DIRS + ${Plasma_BUILD_INCLUDE_DIRS} + BLANK_MACROS + PLASMA_EXPORT + PLASMA_DEPRECATED + PLASMA_DEPRECATED_EXPORT + "PLASMA_DEPRECATED_VERSION(x, y, t)" + TAGFILE_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR} + QCH_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR} + COMPONENT Devel + ) +endif() diff --git a/src/plasma/Mainpage.dox b/src/plasma/Mainpage.dox new file mode 100644 index 0000000..1248931 --- /dev/null +++ b/src/plasma/Mainpage.dox @@ -0,0 +1,81 @@ +/** @page libplasma Plasma framework + +Plasma framework is the core of the Plasma desktop. It provides a framework of graphical +widgets (Plasma::Applet) that can be organised into managed groupings +(Plasma::Containment), such as a desktop or panel.) and a corresponding service interaction +layer (Plasma::Service) to make implementing widgets easier. + +The Qt Quick +framework and set of KDE Frameworks +provide the underpinning for Plasma framework. As a result, it should +work anywhere that Qt does. + +Although Plasma framework is developed for the use of the Plasma desktop shell, +currently known as Plasma 5, it is general enough to be useful in other applications. +Amarok is using it for its context +view, allowing for pluggable widgets to display and interact with the music +collection, such as "current track" and "tag cloud" widgets. + +Plasma framework itself only provides a framework, and the widgets, containments, +data engines are all implemented as plugins (using C++, for widgets QML is prefferd). +However, the framework is designed to make implementing these plugins as easy +as possible, including providing scripting support. + +Other important classes are: + + - Plasma::Corona: the canvas that containments are placed on + - Plasma::View: a QWidget for displaying a containment + - Plasma::Theme: provides theming support + - Plasma::Package: provides descriptions of packages containing plugins + for libplasma + - Plasma::Svg and Plasma::FrameSvg: provides themable, cached SVGs + + +The +Plasma tutorials +on TechBase provide a good introduction to writing plugins, such as widgets and +data engines, for libplasma-based applications. + +@authors +Aaron Seigo \
+Alessandro Diaferia \
+Alex Merry \
+Alexander Wiedenbruch \
+Alexis Ménard \
+André Duffeck \
+Andrew Lake \
+Artur de Souza \
+Bertjan Broeksema \
+Chani Armitage \
+Davide Bettio \
+Dan Meltzer \
+Fredrik Höglund \
+Ivan Cukic \
+John Tapsell \
+Jordi Polo \
+Kevin Ottens \
+Montel Laurent \
+Marco Martin \
+Matt Broadstone \
+Petri Damsten \
+Rafael Fernández López \
+Riccardo Iaconelli \
+Richard J. Moore \
+Rob Scheepmaker \
+Robert Knight \
+Sebastian Kuegler \
+Siraj Razick \
+Zack Rusin \ + +@maintainers +Marco Martin \ + +@licenses +@lgpl + +*/ + +// DOXYGEN_SET_PROJECT_NAME = Plasma +// DOXYGEN_SET_RECURSIVE = YES +// DOXYGEN_EXCLUDE_PATTERNS = *_p.h */private/* */tests/* +// vim:ts=4:sw=4:expandtab:filetype=doxygen diff --git a/src/plasma/README b/src/plasma/README new file mode 100644 index 0000000..7f92812 --- /dev/null +++ b/src/plasma/README @@ -0,0 +1,29 @@ +libplasma + +This directory contains the classes making up libplasma, which provides the +core framework used by Plasma applications, such as the Plasma desktop shell +and its components. This includes applet and extension definitions and loading, +common GUI elements, data and service interaction, search system, etc. + +Domain specific sets of functionality, e.g. for network awareness or sensors, +are not found here but as Applet, Wallpaper, +ContainmentActions, Containment and other plugins. + +Commit Guidelines: +* If your patch is not an obvious or trivial bug fix, have it peer reviewed + by another Plasma developer; https://phabricator.kde.org is your friend :) + +* All code MUST follow the KDE Frameworks coding style, as found at: + https://techbase.kde.org/Policies/Frameworks_Coding_Style + +* All new public API MUST have apidox written before committing and must go + through an API review with another Plasma developer. We have to maintain + binary compatibility, remember! + +Unit tests are next to godliness. (Though as you can see, right now libplasma +is hellbound.) + +Please refer to the Plasma website (https://plasma.kde.org) and Plasma wiki +(https://community.kde.org/Plasma) for API documentation and design +documents regarding this library. + diff --git a/src/plasma/applet.cpp b/src/plasma/applet.cpp new file mode 100644 index 0000000..9cb9dde --- /dev/null +++ b/src/plasma/applet.cpp @@ -0,0 +1,890 @@ +/* + SPDX-FileCopyrightText: 2005 Aaron Seigo + SPDX-FileCopyrightText: 2007 Riccardo Iaconelli + SPDX-FileCopyrightText: 2008 Ménard Alexis + SPDX-FileCopyrightText: 2009 Chani Armitage + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "applet.h" +#include "private/applet_p.h" + +#include "config-plasma.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "containment.h" +#include "corona.h" +#include "plasma.h" +#include "pluginloader.h" + +#include "debug_p.h" +#include "private/containment_p.h" + +#include +#include + +namespace Plasma +{ +Applet::Applet(QObject *parentObject, const KPluginMetaData &data, const QVariantList &args) + : QObject(parentObject) + , d(new AppletPrivate(data, args.count() > 1 ? args[1].toInt() : 0, this)) +{ + if (!args.isEmpty()) { + const QVariant first = args.first(); + if (first.canConvert()) { + d->package = first.value(); + } + } + d->icon = d->appletDescription.iconName(); + + if (args.contains(QVariant::fromValue(QStringLiteral("org.kde.plasma:force-create")))) { + setProperty("org.kde.plasma:force-create", true); + } + + // WARNING: do not access config() OR globalConfig() in this method! + // that requires a scene, which is not available at this point + d->init(args.mid(2)); +} + +Applet::~Applet() +{ + for (QAction *a : d->actions.values()) { + disconnect(a, nullptr, this, nullptr); + } + for (QAction *a : d->contextualActions) { + disconnect(a, nullptr, this, nullptr); + } + + // let people know that i will die + Q_EMIT appletDeleted(this); + + if (d->transient) { + d->resetConfigurationObject(); + } + + // ConfigLoader is deleted when AppletPrivate closes not Applet + // It saves on closure and emits a signal. + // disconnect early to avoid a crash. See 411221 + if (d->configLoader) { + disconnect(d->configLoader, SIGNAL(configChanged()), this, SLOT(propagateConfigChanged())); + } + delete d; +} + +void Applet::init() +{ + // Don't implement anything here, it will be overridden by subclasses +} + +uint Applet::id() const +{ + return d->appletId; +} + +QVariantList Applet::startupArguments() const +{ + return d->startupArguments; +} + +void Applet::save(KConfigGroup &g) const +{ + if (d->transient || !d->appletDescription.isValid()) { + return; + } + + KConfigGroup group = g; + if (!group.isValid()) { + group = *d->mainConfigGroup(); + } + + // qCDebug(LOG_PLASMA) << "saving" << pluginName() << "to" << group.name(); + // we call the dptr member directly for locked since isImmutable() + // also checks kiosk and parent containers + group.writeEntry("immutability", (int)d->immutability); + group.writeEntry("plugin", d->appletDescription.pluginId()); + + if (!d->started) { + return; + } + + KConfigGroup appletConfigGroup(&group, QStringLiteral("Configuration")); + saveState(appletConfigGroup); + + if (d->configLoader) { + // we're saving so we know its changed, we don't need or want the configChanged + // signal bubbling up at this point due to that + disconnect(d->configLoader, SIGNAL(configChanged()), this, SLOT(propagateConfigChanged())); + d->configLoader->save(); + connect(d->configLoader, SIGNAL(configChanged()), this, SLOT(propagateConfigChanged())); + } +} + +void Applet::restore(KConfigGroup &group) +{ + setImmutability((Types::ImmutabilityType)group.readEntry("immutability", (int)Types::Mutable)); + + KConfigGroup shortcutConfig(&group, QStringLiteral("Shortcuts")); + QString shortcutText = shortcutConfig.readEntryUntranslated("global", QString()); + if (!shortcutText.isEmpty()) { + setGlobalShortcut(QKeySequence(shortcutText)); + /* + #ifndef NDEBUG + // qCDebug(LOG_PLASMA) << "got global shortcut for" << name() << "of" << QKeySequence(shortcutText); + #endif + #ifndef NDEBUG + // qCDebug(LOG_PLASMA) << "set to" << d->activationAction->objectName() + #endif + << d->activationAction->globalShortcut().primary(); + */ + } + + // User background hints + // TODO support flags in the config + QByteArray hintsString = config().readEntry("UserBackgroundHints", QString()).toUtf8(); + QMetaEnum hintEnum = QMetaEnum::fromType(); + bool ok; + int value = hintEnum.keyToValue(hintsString.constData(), &ok); + if (ok) { + d->userBackgroundHints = Plasma::Types::BackgroundHints(value); + d->userBackgroundHintsInitialized = true; + Q_EMIT userBackgroundHintsChanged(); + if (d->backgroundHints & Plasma::Types::ConfigurableBackground) { + Q_EMIT effectiveBackgroundHintsChanged(); + } + } +} + +void Applet::setLaunchErrorMessage(const QString &message) +{ + if (message == d->launchErrorMessage) { + return; + } + + d->failed = true; + d->launchErrorMessage = message; +} + +void Applet::saveState(KConfigGroup &group) const +{ + if (group.config()->name() != config().config()->name()) { + // we're being saved to a different file! + // let's just copy the current values in our configuration over + KConfigGroup c = config(); + c.copyTo(&group); + } +} + +KConfigGroup Applet::config() const +{ + if (d->transient) { + return KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("PlasmaTransientsConfig")); + } + + if (isContainment()) { + return *(d->mainConfigGroup()); + } + + return KConfigGroup(d->mainConfigGroup(), QStringLiteral("Configuration")); +} + +KConfigGroup Applet::globalConfig() const +{ + KConfigGroup globalAppletConfig; + QString group = isContainment() ? QStringLiteral("ContainmentGlobals") : QStringLiteral("AppletGlobals"); + + Containment *cont = containment(); + Corona *corona = nullptr; + if (cont) { + corona = cont->corona(); + } + if (corona) { + KSharedConfig::Ptr coronaConfig = corona->config(); + globalAppletConfig = KConfigGroup(coronaConfig, group); + } else { + globalAppletConfig = KConfigGroup(KSharedConfig::openConfig(), group); + } + + return KConfigGroup(&globalAppletConfig, d->globalName()); +} + +void Applet::destroy() +{ + if (immutability() != Types::Mutable || d->transient || !d->started) { + return; // don't double delete + } + + d->setDestroyed(true); + // FIXME: an animation on leave if !isContainment() would be good again .. which should be handled by the containment class + d->cleanUpAndDelete(); +} + +bool Applet::destroyed() const +{ + return d->transient; +} + +KConfigLoader *Applet::configScheme() const +{ + if (!d->configLoader) { + const QString xmlPath = d->package.isValid() ? d->package.filePath("mainconfigxml") : QString(); + KConfigGroup cfg = config(); + if (xmlPath.isEmpty()) { + d->configLoader = new KConfigLoader(cfg, nullptr); + } else { + QFile file(xmlPath); + d->configLoader = new KConfigLoader(cfg, &file); + QObject::connect(d->configLoader, SIGNAL(configChanged()), this, SLOT(propagateConfigChanged())); + } + } + + return d->configLoader; +} + +KConfigPropertyMap *Applet::configuration() +{ + if (!d->configPropertyMap) { + d->configPropertyMap = new KConfigPropertyMap(configScheme(), this); + connect(d->configPropertyMap, &KConfigPropertyMap::valueChanged, this, [this]() { + d->scheduleModificationNotification(); + }); + } + return d->configPropertyMap; +} + +void Applet::updateConstraints(Constraints constraints) +{ + d->scheduleConstraintsUpdate(constraints); +} + +void Applet::constraintsEvent(Constraints constraints) +{ + // NOTE: do NOT put any code in here that reacts to constraints updates + // as it will not get called for any applet that reimplements constraintsEvent + // without calling the Applet:: version as well, which it shouldn't need to. + // INSTEAD put such code into flushPendingConstraintsEvents + Q_UNUSED(constraints) + // qCDebug(LOG_PLASMA) << constraints << "constraints are FormFactor: " << formFactor() + // << ", Location: " << location(); +} + +QString Applet::title() const +{ + if (!d->customTitle.isEmpty()) { + return d->customTitle; + } + + if (d->appletDescription.isValid()) { + return d->appletDescription.name(); + } + + return i18n("Unknown"); +} + +void Applet::setTitle(const QString &title) +{ + if (title == d->customTitle) { + return; + } + + d->customTitle = title; + Q_EMIT titleChanged(title); +} + +QString Applet::icon() const +{ + return d->icon; +} + +void Applet::setIcon(const QString &icon) +{ + if (icon == d->icon) { + return; + } + + d->icon = icon; + Q_EMIT iconChanged(icon); +} + +bool Applet::isBusy() const +{ + return d->busy; +} + +void Applet::setBusy(bool busy) +{ + if (busy == d->busy) { + return; + } + + d->busy = busy; + Q_EMIT busyChanged(busy); +} + +Plasma::Types::BackgroundHints Applet::backgroundHints() const +{ + return d->backgroundHints; +} + +void Applet::setBackgroundHints(Plasma::Types::BackgroundHints hint) +{ + if (d->backgroundHints == hint) { + return; + } + + Plasma::Types::BackgroundHints oldeffectiveHints = effectiveBackgroundHints(); + + d->backgroundHints = hint; + Q_EMIT backgroundHintsChanged(); + + if (oldeffectiveHints != effectiveBackgroundHints()) { + Q_EMIT effectiveBackgroundHintsChanged(); + } +} + +Plasma::Types::BackgroundHints Applet::effectiveBackgroundHints() const +{ + if (d->userBackgroundHintsInitialized && (d->backgroundHints & Plasma::Types::ConfigurableBackground)) { + return d->userBackgroundHints; + } else { + return d->backgroundHints; + } +} + +Plasma::Types::BackgroundHints Applet::userBackgroundHints() const +{ + return d->userBackgroundHints; +} + +void Applet::setUserBackgroundHints(Plasma::Types::BackgroundHints hint) +{ + if (d->userBackgroundHints == hint && d->userBackgroundHintsInitialized) { + return; + } + + d->userBackgroundHints = hint; + d->userBackgroundHintsInitialized = true; + QMetaEnum hintEnum = QMetaEnum::fromType(); + config().writeEntry("UserBackgroundHints", hintEnum.valueToKey(d->userBackgroundHints)); + if (containment() && containment()->corona()) { + containment()->corona()->requestConfigSync(); + } + + Q_EMIT userBackgroundHintsChanged(); + + if (d->backgroundHints & Plasma::Types::ConfigurableBackground) { + Q_EMIT effectiveBackgroundHintsChanged(); + } +} + +KPluginMetaData Applet::pluginMetaData() const +{ + return d->appletDescription; +} + +QString Applet::pluginName() const +{ + return d->appletDescription.isValid() ? d->appletDescription.pluginId() : QString(); +} + +Types::ImmutabilityType Applet::immutability() const +{ + // if this object is itself system immutable, then just return that; it's the most + // restrictive setting possible and will override anything that might be happening above it + // in the Corona->Containment->Applet hierarchy + if (d->transient || (d->mainConfig && d->mainConfig->isImmutable())) { + return Types::SystemImmutable; + } + + // Returning the more strict immutability between the applet immutability, Containment and Corona + Types::ImmutabilityType upperImmutability = Types::Mutable; + + if (isContainment()) { + Corona *cor = static_cast(const_cast(this))->corona(); + if (cor) { + upperImmutability = cor->immutability(); + } + } else { + const Containment *cont = containment(); + if (cont) { + if (cont->corona()) { + upperImmutability = cont->corona()->immutability(); + } else { + upperImmutability = cont->immutability(); + } + } + } + + if (upperImmutability != Types::Mutable) { + // it's either system or user immutable, and we already check for local system immutability, + // so upperImmutability is guaranteed to be as or more severe as this object's immutability + return upperImmutability; + } else { + return d->immutability; + } +} + +void Applet::setImmutability(const Types::ImmutabilityType immutable) +{ + if (d->immutability == immutable || immutable == Types::SystemImmutable) { + // we do not store system immutability in d->immutability since that gets saved + // out to the config file; instead, we check with + // the config group itself for this information at all times. this differs from + // corona, where SystemImmutability is stored in d->immutability. + return; + } + + d->immutability = immutable; + updateConstraints(ImmutableConstraint); +} + +bool Applet::immutable() const +{ + return immutability() != Types::Mutable; +} + +QString Applet::launchErrorMessage() const +{ + return d->launchErrorMessage; +} + +bool Applet::failedToLaunch() const +{ + return d->failed; +} + +bool Applet::configurationRequired() const +{ + return d->needsConfig; +} + +QString Applet::configurationRequiredReason() const +{ + return d->configurationRequiredReason; +} + +void Applet::setConfigurationRequired(bool needsConfig, const QString &reason) +{ + if (d->needsConfig == needsConfig && reason == d->configurationRequiredReason) { + return; + } + + d->needsConfig = needsConfig; + d->configurationRequiredReason = reason; + + Q_EMIT configurationRequiredChanged(needsConfig, reason); +} + +void Applet::setConstraintHints(ConstraintHints constraintHints) +{ + if (d->constraintHints == constraintHints) { + return; + } + + d->constraintHints = constraintHints; + Q_EMIT constraintHintsChanged(constraintHints); +} + +Applet::ConstraintHints Applet::constraintHints() const +{ + return d->constraintHints; +} + +bool Applet::isUserConfiguring() const +{ + return d->userConfiguring; +} + +void Applet::setUserConfiguring(bool configuring) +{ + if (configuring == d->userConfiguring) { + return; + } + + d->userConfiguring = configuring; + Q_EMIT userConfiguringChanged(configuring); +} + +Types::ItemStatus Applet::status() const +{ + return d->itemStatus; +} + +void Applet::setStatus(const Types::ItemStatus status) +{ + if (status == d->itemStatus) { + return; + } + d->itemStatus = status; + Q_EMIT statusChanged(status); +} + +void Applet::flushPendingConstraintsEvents() +{ + if (d->pendingConstraints == NoConstraint) { + return; + } + + if (d->constraintsTimer.isActive()) { + d->constraintsTimer.stop(); + } + + // qCDebug(LOG_PLASMA) << "flushing constraints: " << d->pendingConstraints << "!!!!!!!!!!!!!!!!!!!!!!!!!!!"; + Constraints c = d->pendingConstraints; + d->pendingConstraints = NoConstraint; + + if (c & UiReadyConstraint) { + d->setUiReady(); + } + + if (c & StartupCompletedConstraint) { + // common actions + bool unlocked = immutability() == Types::Mutable; + QAction *closeApplet = d->actions.value(QStringLiteral("remove")); + if (closeApplet) { + closeApplet->setEnabled(unlocked); + closeApplet->setVisible(unlocked); + connect(closeApplet, SIGNAL(triggered(bool)), this, SLOT(askDestroy()), Qt::UniqueConnection); + } + + QAction *configAction = d->actions.value(QStringLiteral("configure")); + if (configAction) { + if (d->hasConfigurationInterface) { + bool canConfig = unlocked || KAuthorized::authorize(QStringLiteral("plasma/allow_configure_when_locked")); + configAction->setVisible(canConfig); + configAction->setEnabled(canConfig); + } + } + } + + if (c & ImmutableConstraint) { + bool unlocked = immutability() == Types::Mutable; + QAction *action = d->actions.value(QStringLiteral("remove")); + if (action) { + action->setVisible(unlocked); + action->setEnabled(unlocked); + } + + action = d->actions.value(QStringLiteral("configure")); + if (action && d->hasConfigurationInterface) { + bool canConfig = unlocked || KAuthorized::authorize(QStringLiteral("plasma/allow_configure_when_locked")); + action->setVisible(canConfig); + action->setEnabled(canConfig); + } + + // an immutable constraint will always happen at startup + // make sure don't emit a change signal for nothing + if (d->oldImmutability != immutability()) { + Q_EMIT immutabilityChanged(immutability()); + } + d->oldImmutability = immutability(); + } + + // now take care of constraints in special subclass: Containment + Containment *containment = qobject_cast(this); + if (containment) { + containment->d->containmentConstraintsEvent(c); + } + + // pass the constraint on to the actual subclass + constraintsEvent(c); + + if (c & StartupCompletedConstraint) { + // start up is done, we can now go do a mod timer + if (d->modificationsTimer) { + if (d->modificationsTimer->isActive()) { + d->modificationsTimer->stop(); + } + } else { + d->modificationsTimer = new QBasicTimer; + } + } + + if (c & FormFactorConstraint) { + Q_EMIT formFactorChanged(formFactor()); + } + + if (c & LocationConstraint) { + Q_EMIT locationChanged(location()); + } +} + +QList Applet::contextualActions() +{ + return d->contextualActions; +} + +QQmlListProperty Applet::qmlContextualActions() +{ + return QQmlListProperty(this, + nullptr, + AppletPrivate::contextualActions_append, + AppletPrivate::contextualActions_count, + AppletPrivate::contextualActions_at, + AppletPrivate::contextualActions_clear, + AppletPrivate::contextualActions_replace, + AppletPrivate::contextualActions_removeLast); +} + +void Applet::setInternalAction(const QString &name, QAction *action) +{ + if (name.isEmpty()) { + return; + } + + action->setObjectName(name); + QAction *oldAction = d->actions.value(name); + if (oldAction && QJSEngine::objectOwnership(oldAction) == QJSEngine::CppOwnership) { + delete oldAction; + } + + d->actions[name] = action; + + QObject::connect(action, &QObject::destroyed, this, [this, name]() { + d->actions.remove(name); + Q_EMIT internalActionsChanged(d->actions.values()); + }); + + Q_EMIT internalActionsChanged(d->actions.values()); +} + +QAction *Applet::internalAction(const QString &name) const +{ + return d->actions.value(name); +} + +void Applet::removeInternalAction(const QString &name) +{ + QAction *action = d->actions.value(name); + + if (action && QJSEngine::objectOwnership(action) == QJSEngine::CppOwnership) { + disconnect(action, &QObject::destroyed, this, nullptr); // Avoid emitting signal again + delete action; + } + + d->actions.remove(name); + + Q_EMIT internalActionsChanged(d->actions.values()); +} + +QList Applet::internalActions() const +{ + return d->actions.values(); +} + +Types::FormFactor Applet::formFactor() const +{ + Containment *c = containment(); + QObject *pw = qobject_cast(parent()); + Plasma::Applet *parentApplet = qobject_cast(pw); + // assumption: this loop is usually is -really- short or doesn't run at all + while (!parentApplet && pw && pw->parent()) { + pw = pw->parent(); + parentApplet = qobject_cast(pw); + } + + return c ? c->d->formFactor : Plasma::Types::Planar; +} + +Types::ContainmentDisplayHints Applet::containmentDisplayHints() const +{ + Containment *c = containment(); + + return c ? c->d->containmentDisplayHints : Plasma::Types::NoContainmentDisplayHint; +} + +Containment *Applet::containment() const +{ + Containment *c = qobject_cast(const_cast(this)); + if (c && c->isContainment()) { + return c; + } else { + c = nullptr; + } + + QObject *parent = this->parent(); + + while (parent) { + Containment *possibleC = qobject_cast(parent); + + if (possibleC && possibleC->isContainment()) { + c = possibleC; + break; + } + parent = parent->parent(); + } + + return c; +} + +void Applet::setGlobalShortcut(const QKeySequence &shortcut) +{ + if (!d->activationAction) { + d->activationAction = new QAction(this); + d->activationAction->setText(i18n("Activate %1 Widget", title())); + d->activationAction->setObjectName(QStringLiteral("activate widget %1").arg(id())); // NO I18N + connect(d->activationAction, &QAction::triggered, this, &Applet::activated); + connect(KGlobalAccel::self(), &KGlobalAccel::globalShortcutChanged, this, [this](QAction *action, const QKeySequence &shortcut) { + if (action == d->activationAction) { + d->activationAction->setShortcut(shortcut); + d->globalShortcutChanged(); + } + }); + } else if (d->activationAction->shortcut() == shortcut) { + return; + } + + d->activationAction->setShortcut(shortcut); + d->globalShortcutEnabled = true; + QList seqs{shortcut}; + KGlobalAccel::self()->setShortcut(d->activationAction, seqs, KGlobalAccel::NoAutoloading); + d->globalShortcutChanged(); + + Q_EMIT globalShortcutChanged(shortcut); +} + +QKeySequence Applet::globalShortcut() const +{ + if (d->activationAction) { + QList shortcuts = KGlobalAccel::self()->shortcut(d->activationAction); + if (!shortcuts.isEmpty()) { + return shortcuts.first(); + } + } + + return QKeySequence(); +} + +Types::Location Applet::location() const +{ + Containment *c = containment(); + return c ? c->d->location : Plasma::Types::Desktop; +} + +bool Applet::hasConfigurationInterface() const +{ + return d->hasConfigurationInterface; +} + +void Applet::setHasConfigurationInterface(bool hasInterface) +{ + if (hasInterface == d->hasConfigurationInterface) { + return; + } + + QAction *configAction = d->actions.value(QStringLiteral("configure")); + if (configAction) { + bool enable = hasInterface; + if (enable) { + const bool unlocked = immutability() == Types::Mutable; + enable = unlocked || KAuthorized::authorize(QStringLiteral("plasma/allow_configure_when_locked")); + } + configAction->setEnabled(enable); + } + + d->hasConfigurationInterface = hasInterface; + Q_EMIT hasConfigurationInterfaceChanged(hasInterface); +} + +void Applet::configChanged() +{ + if (d->configLoader) { + d->configLoader->load(); + } +} + +QUrl Applet::fileUrl(const QByteArray &key, const QString &filename) const +{ + if (d->package.isValid()) { + return d->package.fileUrl(key, filename); + } + return QUrl(); +} + +QUrl Applet::mainScript() const +{ + if (d->package.isValid()) { + return d->package.fileUrl("mainscript"); + } + return QUrl(); +} + +QUrl Applet::configModel() const +{ + if (d->package.isValid()) { + return d->package.fileUrl("configmodel"); + } + + return QUrl(); +} + +bool Applet::sourceValid() const +{ + return d->package.isValid(); +} + +void Applet::timerEvent(QTimerEvent *event) +{ + if (d->transient) { + d->constraintsTimer.stop(); + if (d->modificationsTimer) { + d->modificationsTimer->stop(); + } + return; + } + + if (event->timerId() == d->constraintsTimer.timerId()) { + d->constraintsTimer.stop(); + + // Don't flushPendingConstraints if we're just starting up + // flushPendingConstraints will be called by Corona + if (!(d->pendingConstraints & StartupCompletedConstraint)) { + flushPendingConstraintsEvents(); + } + } else if (d->modificationsTimer && event->timerId() == d->modificationsTimer->timerId()) { + d->modificationsTimer->stop(); + // invalid group, will result in save using the default group + KConfigGroup cg; + + save(cg); + Q_EMIT configNeedsSaving(); + } +} + +bool Applet::isContainment() const +{ + // HACK: this is a special case for the systray + // containment in an applet that is not a containment + Applet *pa = qobject_cast(parent()); + if (pa && !pa->isContainment()) { + return true; + } + // normal "acting as a containment" condition + return qobject_cast(this) && qobject_cast(parent()); +} + +QString Applet::translationDomain() const +{ + const QString rootPath = d->appletDescription.value(QStringLiteral("X-Plasma-RootPath")); + if (!rootPath.isEmpty()) { + return QLatin1String("plasma_applet_") + rootPath; + } else { + return QLatin1String("plasma_applet_") + d->appletDescription.pluginId(); + } +} + +} // Plasma namespace + +#include "moc_applet.cpp" diff --git a/src/plasma/applet.h b/src/plasma/applet.h new file mode 100644 index 0000000..a604c21 --- /dev/null +++ b/src/plasma/applet.h @@ -0,0 +1,925 @@ +/* + SPDX-FileCopyrightText: 2006-2007 Aaron Seigo <:wqaseigo@kde.org> + SPDX-FileCopyrightText: 2007 Riccardo Iaconelli + SPDX-FileCopyrightText: 2008 Ménard Alexis + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMA_APPLET_H +#define PLASMA_APPLET_H + +#include +#include +#include +#include +#include + +#include +#include + +#include + +namespace KPackage +{ +class Package; +} +namespace PlasmaQuick +{ +class AppletQuickItem; +class ConfigViewPrivate; +class ConfigModelPrivate; +class ConfigModel; +class ConfigView; +}; +class DeclarativeAppletScript; +#include + +class KConfigLoader; +class KConfigPropertyMap; + +namespace Plasma +{ +class AppletPrivate; +class Containment; +class Package; + +/** + * @class Applet plasma/applet.h + * + * @short The base Applet class + * + * Applet provides several important roles for add-ons widgets in Plasma. + * + * First, it is the base class for the plugin system and therefore is the + * interface to applets for host applications. + * Background painting (allowing for consistent and complex + * look and feel in just one line of code for applets), loading and starting + * of scripting support for each applet, providing access to the associated + * plasmoid package (if any) and access to configuration data. + * + * See techbase.kde.org for tutorials on writing Applets using this class. + */ +class PLASMA_EXPORT Applet : public QObject +{ + Q_OBJECT + /** + * Applet id: is unique in the whole Plasma session and will never change across restarts + */ + Q_PROPERTY(uint id READ id CONSTANT FINAL) + + /** + * User friendly title for the plasmoid: it's the localized applet name by default + */ + Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged FINAL) + + /** + * Icon to represent the plasmoid + */ + Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged FINAL) + + // TODO KF6 toolTipMainText toolTipSubText toolTipTextFormat toolTipItem: need to either be here or some other kind of attached property + + /** + * The current form factor the applet is being displayed in. + * + * @see Plasma::FormFactor + */ + Q_PROPERTY(Plasma::Types::FormFactor formFactor READ formFactor NOTIFY formFactorChanged) + + /** + * The location of the scene which is displaying applet. + * + * @see Plasma::Types::Location + */ + Q_PROPERTY(Plasma::Types::Location location READ location NOTIFY locationChanged) + + /** + * Status of the plasmoid: useful to instruct the shell if this plasmoid is requesting attention, if is accepting input, or if is in an idle, inactive state + */ + Q_PROPERTY(Plasma::Types::ItemStatus status READ status WRITE setStatus NOTIFY statusChanged) + + /** + * The immutability of the Corona. + * Tells the applet whether it should allow for any modification by the user. + */ + Q_PROPERTY(Plasma::Types::ImmutabilityType immutability READ immutability WRITE setImmutability NOTIFY immutabilityChanged) + + /** + * Whether the Corona is immutable. The plasmoid implementation should avoid allowing "dangerous" modifications from the user when in an immutable mode + * + * This is true when immutability is not Mutable + */ + Q_PROPERTY(bool immutable READ immutable NOTIFY immutabilityChanged) + + /** + * Display hints that come from the containment that suggest the applet how to look and behave. + * TODO: only in containment? + */ + Q_PROPERTY(Plasma::Types::ContainmentDisplayHints containmentDisplayHints READ containmentDisplayHints NOTIFY containmentDisplayHintsChanged) + + /** + * True if the applet should show a busy status, for instance doing + * some network operation + */ + Q_PROPERTY(bool busy READ isBusy WRITE setBusy NOTIFY busyChanged FINAL) + + /** + * True when the user is configuring, for instance when the configuration dialog is open. + */ + Q_PROPERTY(bool userConfiguring READ isUserConfiguring NOTIFY userConfiguringChanged) + + /** + * How the applet wants its background to be drawn. The containment may chose to ignore this hint. + */ + Q_PROPERTY(Plasma::Types::BackgroundHints backgroundHints WRITE setBackgroundHints READ backgroundHints NOTIFY backgroundHintsChanged FINAL) + + /** + * The containment (and/or the user) may decide to use another kind of background instead (if supported by the applet) + */ + Q_PROPERTY(Plasma::Types::BackgroundHints userBackgroundHints WRITE setUserBackgroundHints READ userBackgroundHints NOTIFY userBackgroundHintsChanged FINAL) + + /** + * The effective background hints the applet has, internally decided how to mix with userBackgroundHints + */ + Q_PROPERTY(Plasma::Types::BackgroundHints effectiveBackgroundHints READ effectiveBackgroundHints NOTIFY effectiveBackgroundHintsChanged FINAL) + + // TODO KF6: activity, screen, screenGeometry, availableScreenRect, availableScreenRegion: should we instead make the containment accessible from qml + // plasmoids and ask from there? + + /** + * A KConfigPropertyMap instance that represents the configuration + * which is usable from QML to read and write settings like any JavaScript Object + */ + Q_PROPERTY(KConfigPropertyMap *configuration READ configuration CONSTANT FINAL) + + /** + * The global shortcut to activate the plasmoid + * + * This is typically only used by the default configuration module + * + */ + Q_PROPERTY(QKeySequence globalShortcut READ globalShortcut WRITE setGlobalShortcut RESET setGlobalShortcut NOTIFY globalShortcutChanged) + + /** + * If true the applet requires manual configuration from the user + * TODO KF6: having just a reson property and required would be string not empty? Uglier from c++ pov but more straight forward from qml pov + */ + Q_PROPERTY(bool configurationRequired READ configurationRequired WRITE setConfigurationRequired NOTIFY configurationRequiredChanged) + + /** + * True if this applet will provide a UI for its configuration + */ + Q_PROPERTY(bool hasConfigurationInterface READ hasConfigurationInterface WRITE setHasConfigurationInterface NOTIFY hasConfigurationInterfaceChanged) + + /** + * The hints that the applet gives to its constraint, + * such as asking to fill all the available space ignoring margins. + */ + Q_PROPERTY(Applet::ConstraintHints constraintHints READ constraintHints WRITE setConstraintHints NOTIFY constraintHintsChanged FINAL) + + /** + * The metadata of the applet. + */ + Q_PROPERTY(KPluginMetaData metaData READ pluginMetaData CONSTANT) + + /** + * The Containment managing this applet + */ + Q_PROPERTY(Plasma::Containment *containment READ containment NOTIFY containmentChanged) + + /** + * Actions to be added in the plasmoid context menu. To instantiate QActions in a declarative way, + * PlasmaCore.Action {} can be used + */ + Q_PROPERTY(QQmlListProperty contextualActions READ qmlContextualActions NOTIFY contextualActionsChanged) + + /** + * True if this applet is a Containment and is acting as one, such as a desktop or a panel + */ + Q_PROPERTY(bool isContainment READ isContainment CONSTANT) + + /** + * Plugin name for the applet + */ + Q_PROPERTY(QString pluginName READ pluginName CONSTANT FINAL) + +public: + /** + * The Constraint enumeration lists the various constraints that Plasma + * objects have managed for them and which they may wish to react to, + * for instance in Applet::constraintsUpdated + */ + enum Constraint { + NoConstraint = 0, /**< No constraint; never passed in to Applet::constraintsEvent on its own */ + FormFactorConstraint = 1, /**< The FormFactor for an object */ + LocationConstraint = 2, /**< The Location of an object */ + ScreenConstraint = 4, /**< Which screen an object is on */ + ImmutableConstraint = 8, /**< the immutability (locked) nature of the applet changed */ + StartupCompletedConstraint = 16, /**< application startup has completed */ + UiReadyConstraint = 32, + /**< The ui has been completely loaded */ // (FIXME: merged with StartupCompletedConstraint?) + AllConstraints = FormFactorConstraint | LocationConstraint | ScreenConstraint | ImmutableConstraint, + }; + Q_ENUM(Constraint) + Q_DECLARE_FLAGS(Constraints, Constraint) + + /** + * This enumeration lists the various hints that an applet can pass to its + * constraint regarding the way that it is represented + */ + enum ConstraintHint { + NoHint = 0, + CanFillArea = 1, + /**< The CompactRepresentation can fill the area and ignore constraint margins*/ // (TODO: KF6 CanFillArea -> CompactRepresentationFillArea) + MarginAreasSeparator = CanFillArea | 2, /**< The applet acts as a separator between the standard and slim panel margin areas*/ + }; + Q_DECLARE_FLAGS(ConstraintHints, ConstraintHint) + Q_FLAG(ConstraintHints) + + // CONSTRUCTORS + + /** + * This constructor can be used with the KCoreAddons plugin loading system. + * The argument list is expected to have contain the KPackage of the applet, + * the meta data file path (for compatibility) and an applet ID which must be a base 10 number. + * + * @param parent a QObject parent; you probably want to pass in 0 + * @param data, KPluginMetaData used to create this plugin + * @param args a list of strings containing the applet id + * @Since 5.86 + */ + Applet(QObject *parentObject, const KPluginMetaData &data, const QVariantList &args); + + ~Applet() override; + + // BOOKKEEPING + /** + * @return the id of this applet + */ + uint id() const; + + /** + * @return the arguments this applet was started with. + * Some applets support arguments, for instance the notes applet supports to be + * instantiated with a given text already passed as paramenter + */ + QVariantList startupArguments() const; + + /** + * @return The type of immutability of this applet + */ + Types::ImmutabilityType immutability() const; + + /** + * @return true if immutability() is not Types::Mutable + */ + bool immutable() const; + + /** + * If for some reason, the applet fails to get up on its feet (the + * library couldn't be loaded, necessary hardware support wasn't found, + * etc..) this method returns the reason why, in an user-readable way. + * @since 5.0 + **/ + QString launchErrorMessage() const; + + /** + * If for some reason, the applet fails to get up on its feet (the + * library couldn't be loaded, necessary hardware support wasn't found, + * etc..) this method returns true. + **/ + bool failedToLaunch() const; + + /** + * @return true if destroy() was called; useful for Applets which should avoid + * certain tasks if they are about to be deleted permanently + */ + bool destroyed() const; + + /** + * @return the Containment, if any, this applet belongs to + **/ + Containment *containment() const; + + /** + * @return true if this Applet is currently being used as a Containment, false otherwise + */ + bool isContainment() const; + + /** + * @return the status of the applet + * @since 4.4 + */ + Types::ItemStatus status() const; + + /** + * Returns the current form factor the applet is being displayed in. + * + * @see Plasma::FormFactor + */ + Types::FormFactor formFactor() const; + + /** + * Returns the location of the scene which is displaying applet. + * + * @see Plasma::Types::Location + */ + Types::Location location() const; + + /** + * @return Display hints that come from the containment that suggest the applet how to look and behave. + * @since 5.77 + */ + Types::ContainmentDisplayHints containmentDisplayHints() const; + + // CONFIGURATION + /** + * Returns the KConfigGroup to access the applets configuration. + * + * This config object will write to an instance + * specific config file named \\rc + * in the Plasma appdata directory. + **/ + KConfigGroup config() const; + + /** + * Returns a KConfigGroup object to be shared by all applets of this + * type. + * + * This config object will write to an applet-specific config object + * named plasma_\rc in the local config directory. + */ + KConfigGroup globalConfig() const; + + /** + * Returns the config skeleton object from this applet's package, + * if any. + * + * @return config skeleton object, or 0 if none + **/ + KConfigLoader *configScheme() const; + + /** + * @return a KConfigPropertyMap instance that represents the configuration + * which is usable from QML to read and write settings like any JavaScript Object + */ + KConfigPropertyMap *configuration(); + + /** + * Saves state information about this applet that will + * be accessed when next instantiated in the restore(KConfigGroup&) method. + * + * This method does not need to be reimplemented by Applet + * subclasses, but can be useful for Applet specializations + * (such as Containment) to do so. + * + * Applet subclasses may instead want to reimplement saveState(). + **/ + virtual void save(KConfigGroup &group) const; + + /** + * Restores state information about this applet saved previously + * in save(KConfigGroup&). + * + * This method does not need to be reimplemented by Applet + * subclasses, but can be useful for Applet specializations + * (such as Containment) to do so. + **/ + virtual void restore(KConfigGroup &group); + + /** + * When the applet needs to be configured before being usable, this + * method can be called to show a standard interface prompting the user + * to configure the applet + * + * @param needsConfiguring true if the applet needs to be configured, + * or false if it doesn't + * @param reason a translated message for the user explaining that the + * applet needs configuring; this should note what needs + * to be configured + */ + void setConfigurationRequired(bool needsConfiguring, const QString &reason = QString()); + + /** + * @return true if the applet currently needs to be configured, + * otherwise, false + */ + bool configurationRequired() const; + + /** + * @return A translated message for the user explaining that the + * applet needs configuring; this should note what needs + * to be configured + * + * @see setConfigurationRequired + * @since 5.20 + */ + QString configurationRequiredReason() const; + + /** + * Sets the constraint hits which give a more granular control over sizing in + * constrained layouts such as panels + * + * @param constraintHints such as CanFillArea or MarginAreasSeparator, + * they can be in bitwise OR + */ + void setConstraintHints(ConstraintHints constraintHints); + + /** + * @return The constraint hints such as CanFillArea or MarginAreasSeparator, + * they can be in bitwise OR + */ + ConstraintHints constraintHints() const; + + /** + * @return true when the configuration interface is being shown + * @since 4.5 + */ + bool isUserConfiguring() const; + + /** + * Tells the applet the user is configuring + * @param configuring true if the configuration ui is showing + */ + void setUserConfiguring(bool configuring); + + // UTILS + /** + * Called when any of the geometry constraints have been updated. + * This method calls constraintsEvent, which may be reimplemented, + * once the Applet has been prepared for updating the constraints. + * + * @param constraints the type of constraints that were updated + */ + void updateConstraints(Constraints constraints = AllConstraints); + + // METADATA + + /** + * @return metadata information about this plugin + * + * @since 5.27 + */ + KPluginMetaData pluginMetaData() const; + + /** + * @return the plugin name form KPluginMetaData + */ + QString pluginName() const; + + /** + * Returns the user-visible title for the applet, as specified in the + * Name field of the .desktop file. Can be changed with @see setTitle + * + * @since 5.0 + * @return the user-visible title for the applet. + **/ + QString title() const; + + /** + * Sets a custom title for this instance of the applet. E.g. a clock might + * use the timezone as its name rather than the .desktop file + * + * @since 5.0 + * @param title the user-visible title for the applet. + */ + void setTitle(const QString &title); + + /** + * @returns The icon name related to this applet + * By default is the one in the plasmoid desktop file + **/ + QString icon() const; + + /** + * Sets an icon name for this applet + * @param icon Freedesktop compatible icon name + */ + void setIcon(const QString &icon); + + /** + * @returns true if the applet should show a busy status, for instance doing + * some network operation + * @since 5.21 + */ + bool isBusy() const; + + /** + * Sets the Applet to have a busy status hint, for instance the applet doing + * some network operation. + * The graphical representation of the busy status depends completely from + * the visualization. + * @param busy true if the applet is busy + * @since 5.21 + */ + void setBusy(bool busy); + + /** + * How the applet wants its background to be drawn. The containment may chose to ignore this hint. + * @since 5.65 + */ + Plasma::Types::BackgroundHints backgroundHints() const; + + /** + * Sets the applet background hints. Only Applet implementations should write this property + * @since 5.65 + */ + void setBackgroundHints(Plasma::Types::BackgroundHints hint); + + /** + * The containment (and/or the user) may decide to use another kind of background instead if supported by the applet. + * In order for an applet to support user configuration of the + * background, it needs to have the Plasma::Types::ConfigurableBackground flag set in its backgroundHints + * @since 5.65 + */ + Plasma::Types::BackgroundHints userBackgroundHints() const; + + /** + * Sets the hints the user wished the background style for the applet to be. + * @since 5.65 + */ + void setUserBackgroundHints(Plasma::Types::BackgroundHints hint); + + /** + * The effective background hints the applet will have: it will follow userBackgroundHints only if backgroundHints has the + * Plasma::Types::ConfigurableBackground flag set + * @since 5.65 + */ + Plasma::Types::BackgroundHints effectiveBackgroundHints() const; + + // ACTIONS + /** + * Returns a list of context-related QAction instances. + * + * This is used e.g. within the \a DesktopView to display a + * contextmenu. + * + * @return A list of actions. The default implementation returns an + * empty list. + **/ + virtual QList contextualActions(); + + QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE + QQmlListProperty qmlContextualActions(); + + /** + * Add a new internal action. if an internal action with the same name already exists, it + * will be replaced with this new one. + * Those are usually actions defined by the system, such as "configure" and "remove" + * + * @param name The unique name for the action + * @param action The new QAction to be added + */ + Q_INVOKABLE void setInternalAction(const QString &name, QAction *action); + + /** + * @returns the internal action with the given name if available + * @param name the unique name of the action we want + */ + Q_INVOKABLE QAction *internalAction(const QString &name) const; + + /** + * Removes an action from the internal actions + * @param name the action to be removed + */ + Q_INVOKABLE void removeInternalAction(const QString &name); + + /** + * @returns All the internal actions such as configure, remove, alternatives etc + */ + QList internalActions() const; + + /** + * Sets the global shortcut to associate with this widget. + */ + void setGlobalShortcut(const QKeySequence &shortcut = QKeySequence()); + + /** + * @return the global shortcut associated with this widget, or + * an empty shortcut if no global shortcut is associated. + */ + QKeySequence globalShortcut() const; + + /** + * Sets whether or not this applet provides a user interface for + * configuring the applet. + * + * It defaults to false, and if true is passed in you should + * also reimplement createConfigurationInterface() + * + * @param hasInterface whether or not there is a user interface available + **/ + void setHasConfigurationInterface(bool hasInterface); + + // Completely UI-specific, remove or move to scriptengine + /** + * @return true if this plasmoid provides a GUI configuration + **/ + bool hasConfigurationInterface() const; + + /** + * The translation domain for this applet + * + * @since 6.1 + */ + QString translationDomain() const; + +Q_SIGNALS: + // BOOKKEEPING + /** + * Emitted when the immutability changes + * @since 4.4 + */ + void immutabilityChanged(Plasma::Types::ImmutabilityType immutable); + + /** + * Emitted when the applet status changes + * @since 4.4 + */ + void statusChanged(Plasma::Types::ItemStatus status); + + /** + * Emitted when the applet has been scheduled for destruction + * or the destruction has been undone + * @since 5.4 + */ + void destroyedChanged(bool destroyed); + + /** + * Emitted when the title has changed + * @since 5.20 + */ + void titleChanged(const QString &title); + + /** + * Emitted when the icon name for the applet has changed + * @since 5.20 + */ + void iconChanged(const QString &icon); + + /** + * Emitted when the busy status has changed + * @since 5.21 + */ + void busyChanged(bool busy); + + /** + * Emitted when the background hints have changed + * @since 5.65 + */ + void backgroundHintsChanged(); + + /** + * Emitted when the user background hints have changed + * @since 5.65 + */ + void userBackgroundHintsChanged(); + + /** + * Emitted when the effective background hints have changed + * @since 5.65 + */ + void effectiveBackgroundHintsChanged(); + + /** + * Emitted when the global shortcut to activate this applet has chanaged + */ + void globalShortcutChanged(const QKeySequence &sequence); + + // CONFIGURATION + /** + * Emitted when an applet has changed values in its configuration + * and wishes for them to be saved at the next save point. As this implies + * disk activity, this signal should be used with care. + * + * @note This does not need to be emitted from saveState by individual + * applets. + */ + void configNeedsSaving(); + + /** + * emitted when the config ui appears or disappears + */ + void userConfiguringChanged(bool configuring); + + // ACTIONS + /** + * Emitted just before the contextual actions are about to show + * For instance just before the context menu containing the actions + * added with setAction() is shown + */ + void contextualActionsAboutToShow(); + + /** + * Emitted when activation is requested due to, for example, a global + * keyboard shortcut. By default the widget is given focus. + */ + void activated(); + + // TODO: fix usage in containment, port to QObject::destroyed + /** + * Emitted when the applet is deleted + */ + void appletDeleted(Plasma::Applet *applet); + + /** + * Emitted when the formfactor changes + */ + void formFactorChanged(Plasma::Types::FormFactor formFactor); + + /** + * Emitted when the location changes + */ + void locationChanged(Plasma::Types::Location location); + + void containmentDisplayHintsChanged(Plasma::Types::ContainmentDisplayHints hints); + + /** + * Emitted when setConfigurationRequired was called + * @see setConfigurationRequired + * @since 5.20 + */ + void configurationRequiredChanged(bool needsConfig, const QString &reason); + + /** + * Emitted when the applet gains or loses the ability to show a configuration interface + * @see hasConfigurationInterface + * @since 6.0 + */ + void hasConfigurationInterfaceChanged(bool hasConfiguration); + + /** + * Emitted when the constraint hints changed + * @see setConstraintHints + */ + void constraintHintsChanged(ConstraintHints constraintHints); + + /** + * Emitted when the containment changes + */ + void containmentChanged(Plasma::Containment *containment); + + /** + * Emitted when the list of contextual actions has changed + */ + void contextualActionsChanged(const QList &actions); + + /** + * Emitted when the list of internal actions has changed + */ + void internalActionsChanged(const QList &actions); + + // TODO KF6 keep as Q_SLOT only stuff that needsto be manually invokable from qml +public Q_SLOTS: + // BOOKKEEPING + /** + * Call this method when the applet fails to launch properly. An + * optional reason can be provided. + * + * Not that all children items will be deleted when this method is + * called. If you have pointers to these items, you will need to + * reset them after calling this method. + * + * @param failed true when the applet failed, false when it succeeded + * @param reason an optional reason to show the user why the applet + * failed to launch + * @since 5.0 + **/ + void setLaunchErrorMessage(const QString &reason = QString()); + + /** + * Sets the immutability type for this applet (not immutable, + * user immutable or system immutable) + * @param immutable the new immutability type of this applet + */ + void setImmutability(const Types::ImmutabilityType immutable); + + /** + * Destroys the applet; it will be removed nicely and deleted. + * Its configuration will also be deleted. + * If you want to remove the Applet configuration, use this, don't just delete the Applet * + */ + void destroy(); + + /** + * sets the status for this applet + * @since 4.4 + */ + void setStatus(const Types::ItemStatus stat); + + // CONFIGURATION + /** + * Called when applet configuration values have changed. + */ + // TODO KF6: make it not a slot anymore and protected + virtual void configChanged(); + + // UTILS + /** + * Sends all pending constraints updates to the applet. Will usually + * be called automatically, but can also be called manually if needed. + */ + void flushPendingConstraintsEvents(); + + /** + * This method is called once the applet is loaded and added to a Corona. + * If the applet requires a Scene or has an particularly intensive + * set of initialization routines to go through, consider implementing it + * in this method instead of the constructor. + * + * Note: paintInterface may get called before init() depending on initialization + * order. Painting is managed by the canvas (QGraphisScene), and may schedule a + * paint event prior to init() being called. + **/ + virtual void init(); + +protected: + // CONFIGURATION + /** + * When called, the Applet should write any information needed as part + * of the Applet's running state to the configuration object in config() + * and/or globalConfig(). + * + * Applets that always sync their settings/state with the config + * objects when these settings/states change do not need to reimplement + * this method. + **/ + virtual void saveState(KConfigGroup &config) const; + + // UTILS + /** + * Called when any of the constraints for the applet have been updated. These constraints + * range from notifying when the applet has officially "started up" to when geometry changes + * to when the form factor changes. + * + * Each constraint that has been changed is passed in the constraints flag. + * All of the constraints and how they work is documented in the @see Plasma::Constraints + * enumeration. + * + * On applet creation, this is always called prior to painting and can be used as an + * opportunity to layout the widget, calculate sizings, etc. + * + * Do not call update() from this method; an update() will be triggered + * at the appropriate time for the applet. + * + * @param constraints the type of constraints that were updated + * @property constraint + */ + virtual void constraintsEvent(Constraints constraints); + + // TODO: timerEvent should go into AppletPrivate + /** + * Reimplemented from QObject + */ + void timerEvent(QTimerEvent *event) override; + +private: + QUrl fileUrl(const QByteArray &key, const QString &filename) const; + QUrl mainScript() const; + QUrl configModel() const; + bool sourceValid() const; + /** + * @internal This constructor is to be used with the Package loading system. + * + * @param parent a QObject parent; you probably want to pass in 0 + * @param args a list of strings containing two entries: the service id + * and the applet id + * @since 4.3 + */ + Applet(const QString &packagePath, uint appletId); + + // TODO KF6: drop Q_PRIVATE_SLOT + Q_PRIVATE_SLOT(d, void cleanUpAndDelete()) + Q_PRIVATE_SLOT(d, void askDestroy()) + Q_PRIVATE_SLOT(d, void globalShortcutChanged()) + Q_PRIVATE_SLOT(d, void propagateConfigChanged()) + Q_PRIVATE_SLOT(d, void requestConfiguration()) + + AppletPrivate *const d; + + // Corona needs to access setLaunchErrorMessage and init + friend class Corona; + friend class CoronaPrivate; + friend class Containment; + friend class ContainmentPrivate; + friend class AppletScript; + friend class AppletPrivate; + friend class AccessAppletJobPrivate; + friend class GraphicsViewAppletPrivate; + friend class PluginLoader; + friend class SvgPrivate; + friend class PlasmaQuick::AppletQuickItem; + friend class PlasmaQuick::ConfigModel; + friend class PlasmaQuick::ConfigModelPrivate; + friend class PlasmaQuick::ConfigViewPrivate; + friend class PlasmaQuick::ConfigView; + friend DeclarativeAppletScript; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(Applet::Constraints) +Q_DECLARE_OPERATORS_FOR_FLAGS(Applet::ConstraintHints) + +} // Plasma namespace + +#endif // multiple inclusion guard diff --git a/src/plasma/config-plasma.h.cmake b/src/plasma/config-plasma.h.cmake new file mode 100644 index 0000000..e3c9b61 --- /dev/null +++ b/src/plasma/config-plasma.h.cmake @@ -0,0 +1,5 @@ +#cmakedefine01 HAVE_X11 +#cmakedefine01 HAVE_GLX +#cmakedefine01 HAVE_EGL + +#define PLASMA_RELATIVE_DATA_INSTALL_DIR "@PLASMA_RELATIVE_DATA_INSTALL_DIR@" diff --git a/src/plasma/containment.cpp b/src/plasma/containment.cpp new file mode 100644 index 0000000..a5093b4 --- /dev/null +++ b/src/plasma/containment.cpp @@ -0,0 +1,685 @@ +/* + SPDX-FileCopyrightText: 2007 Aaron Seigo + SPDX-FileCopyrightText: 2008 Ménard Alexis + SPDX-FileCopyrightText: 2009 Chani Armitage + SPDX-FileCopyrightText: 2012 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "containment.h" +#include "private/containment_p.h" + +#include "config-plasma.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "containmentactions.h" +#include "corona.h" +#include "debug_p.h" +#include "pluginloader.h" + +#include "private/applet_p.h" + +#include "plasma/plasma.h" + +namespace Plasma +{ +Containment::Containment(QObject *parentObject, const KPluginMetaData &data, const QVariantList &args) + : Applet(parentObject, data, args) + , d(new ContainmentPrivate(this)) +{ + // WARNING: do not access config() OR globalConfig() in this method! + // that requires a scene, which is not available at this point + setHasConfigurationInterface(true); + + // Try to determine the containment type. It must be done as soon as possible + const QString type = pluginMetaData().value(QStringLiteral("X-Plasma-ContainmentType")); + QMetaEnum metaEnum = QMetaEnum::fromType(); + d->type = (Plasma::Containment::Type)metaEnum.keyToValue(type.toLocal8Bit().constData()); + if (d->type == Plasma::Containment::Type::NoContainment) { + qCWarning(LOG_PLASMA) << "Unknown containment type requested:" << type << pluginMetaData().fileName() + << "check Plasma::Containment::Type for supported values"; + } +} + +Containment::~Containment() +{ + disconnect(corona(), nullptr, this, nullptr); + qDeleteAll(d->localActionPlugins); + delete d; +} + +void Containment::init() +{ + Applet::init(); + + connect(corona(), &Plasma::Corona::availableScreenRectChanged, this, [this](int screenId) { + if (screenId == screen()) { + Q_EMIT availableRelativeScreenRectChanged(availableRelativeScreenRect()); + } + }); + connect(corona(), &Plasma::Corona::availableScreenRegionChanged, this, [this](int screenId) { + if (screenId == screen()) { + Q_EMIT availableRelativeScreenRegionChanged(availableRelativeScreenRegion()); + } + }); + connect(corona(), &Plasma::Corona::screenGeometryChanged, this, [this](int screenId) { + if (screenId == screen()) { + Q_EMIT screenGeometryChanged(screenGeometry()); + } + }); + + QMap actions = static_cast(this)->d->actions; + // connect actions + ContainmentPrivate::addDefaultActions(actions, this); + bool unlocked = immutability() == Types::Mutable; + + // fix the text of the actions that need title() + // btw, do we really want to use title() when it's a desktopcontainment? + QAction *closeApplet = internalAction(QStringLiteral("remove")); + if (closeApplet) { + closeApplet->setText(i18nc("%1 is the name of the applet", "Remove %1", title())); + } + + QAction *configAction = internalAction(QStringLiteral("configure")); + if (configAction) { + if (d->type == Containment::Type::Panel || d->type == Containment::Type::CustomPanel) { + configAction->setText(i18n("Enter Edit Mode")); + configAction->setIcon(QIcon::fromTheme(QStringLiteral("document-edit"))); + } else { + configAction->setText(i18nc("%1 is the name of the applet", "Configure %1...", title())); + } + } + + QAction *appletBrowserAction = internalAction(QStringLiteral("add widgets")); + if (appletBrowserAction) { + appletBrowserAction->setVisible(unlocked); + appletBrowserAction->setEnabled(unlocked); + connect(appletBrowserAction, SIGNAL(triggered()), this, SLOT(triggerShowAddWidgets())); + } + + if (immutability() != Types::SystemImmutable && corona()) { + QAction *lockDesktopAction = corona()->action(QStringLiteral("lock widgets")); + // keep a pointer so nobody notices it moved to corona + if (lockDesktopAction) { + setInternalAction(QStringLiteral("lock widgets"), lockDesktopAction); + } + } + + // HACK: this is valid only in the systray case + connect(this, &Containment::configureRequested, this, [this](Plasma::Applet *a) { + if (Plasma::Applet *p = qobject_cast(parent())) { + Q_EMIT p->containment()->configureRequested(a); + } + }); +} + +// helper function for sorting the list of applets +bool appletConfigLessThan(const KConfigGroup &c1, const KConfigGroup &c2) +{ + int i1 = c1.readEntry("id", 0); + int i2 = c2.readEntry("id", 0); + + return (i1 < i2); +} + +void Containment::restore(KConfigGroup &group) +{ + /* + #ifndef NDEBUG + // qCDebug(LOG_PLASMA) << "!!!!!!!!!!!!initConstraints" << group.name() << d->type; + // qCDebug(LOG_PLASMA) << " location:" << group.readEntry("location", (int)d->location); + // qCDebug(LOG_PLASMA) << " geom:" << group.readEntry("geometry", geometry()); + // qCDebug(LOG_PLASMA) << " formfactor:" << group.readEntry("formfactor", (int)d->formFactor); + // qCDebug(LOG_PLASMA) << " screen:" << group.readEntry("screen", d->screen); + #endif + */ + setLocation((Plasma::Types::Location)group.readEntry("location", (int)d->location)); + setFormFactor((Plasma::Types::FormFactor)group.readEntry("formfactor", (int)d->formFactor)); + d->lastScreen = group.readEntry("lastScreen", d->lastScreen); + + setWallpaperPlugin(group.readEntry("wallpaperplugin", ContainmentPrivate::defaultWallpaperPlugin)); + + d->activityId = group.readEntry("activityId", QString()); + + flushPendingConstraintsEvents(); + restoreContents(group); + setImmutability((Types::ImmutabilityType)group.readEntry("immutability", (int)Types::Mutable)); + + if (isContainment() && KAuthorized::authorize(QStringLiteral("plasma/containment_actions"))) { + KConfigGroup cfg = KConfigGroup(corona()->config(), QStringLiteral("ActionPlugins")); + cfg = KConfigGroup(&cfg, QString::number((int)containmentType())); + + // qCDebug(LOG_PLASMA) << cfg.keyList(); + if (cfg.exists()) { + const auto keyList = cfg.keyList(); + for (const QString &key : keyList) { + // qCDebug(LOG_PLASMA) << "loading" << key; + setContainmentActions(key, cfg.readEntry(key, QString())); + } + } else { // shell defaults + KConfigGroup defaultActionsCfg; + + switch (d->type) { + case Plasma::Containment::Type::Panel: + /* fall through*/ + case Plasma::Containment::Type::CustomPanel: + defaultActionsCfg = KConfigGroup(KSharedConfig::openConfig(corona()->kPackage().filePath("defaults")), QStringLiteral("Panel")); + break; + case Plasma::Containment::Type::Desktop: + defaultActionsCfg = KConfigGroup(KSharedConfig::openConfig(corona()->kPackage().filePath("defaults")), QStringLiteral("Desktop")); + break; + default: + // for any other type of containment, there are no defaults + break; + } + if (defaultActionsCfg.isValid()) { + defaultActionsCfg = KConfigGroup(&defaultActionsCfg, QStringLiteral("ContainmentActions")); + const auto keyList = defaultActionsCfg.keyList(); + for (const QString &key : keyList) { + setContainmentActions(key, defaultActionsCfg.readEntry(key, QString())); + } + } + } + } + Applet::restore(group); +} + +void Containment::save(KConfigGroup &g) const +{ + if (Applet::d->transient) { + return; + } + + KConfigGroup group = g; + if (!group.isValid()) { + group = config(); + } + + // locking is saved in Applet::save + Applet::save(group); + + // group.writeEntry("screen", d->screen); + group.writeEntry("lastScreen", d->lastScreen); + group.writeEntry("formfactor", (int)d->formFactor); + group.writeEntry("location", (int)d->location); + group.writeEntry("activityId", d->activityId); + + group.writeEntry("wallpaperplugin", d->wallpaperPlugin); + + saveContents(group); +} + +void Containment::saveContents(KConfigGroup &group) const +{ + KConfigGroup applets(&group, QStringLiteral("Applets")); + for (const Applet *applet : std::as_const(d->applets)) { + KConfigGroup appletConfig(&applets, QString::number(applet->id())); + applet->save(appletConfig); + } +} + +void Containment::restoreContents(KConfigGroup &group) +{ + KConfigGroup applets(&group, QStringLiteral("Applets")); + + // restore the applets ordered by id + QStringList groups = applets.groupList(); + std::sort(groups.begin(), groups.end()); + + // Sort the applet configs in order of geometry to ensure that applets + // are added from left to right or top to bottom for a panel containment + QList appletConfigs; + for (const QString &appletGroup : std::as_const(groups)) { + // qCDebug(LOG_PLASMA) << "reading from applet group" << appletGroup; + KConfigGroup appletConfig(&applets, appletGroup); + appletConfigs.append(appletConfig); + } + std::stable_sort(appletConfigs.begin(), appletConfigs.end(), appletConfigLessThan); + + QMutableListIterator it(appletConfigs); + while (it.hasNext()) { + KConfigGroup &appletConfig = it.next(); + if (appletConfig.readEntry(QStringLiteral("transient"), false)) { + appletConfig.deleteGroup(); + continue; + } + int appId = appletConfig.name().toUInt(); + QString plugin = appletConfig.readEntry("plugin", QString()); + + if (plugin.isEmpty()) { + continue; + } + + d->createApplet(plugin, QVariantList(), appId); + } + + // if there are no applets, none of them is "loading" + if (Containment::applets().isEmpty()) { + d->appletsUiReady = true; + } + const auto lstApplets = Containment::applets(); + for (Applet *applet : lstApplets) { + if (!applet->pluginMetaData().isValid()) { + applet->updateConstraints(UiReadyConstraint); + } + } +} + +Plasma::Containment::Type Containment::containmentType() const +{ + return d->type; +} + +Corona *Containment::corona() const +{ + // We are not sure where the corona parent is in the hyerarchy, because of... the systray. + // We are iterating over the parent tree here rather than casting the parent + // to applet then asking ofr its containment and corona, as this might break during + // teardown, as this can be invoked during dtor of one of the ancestors, + // see https://bugs.kde.org/show_bug.cgi?id=477067 where it happens during destruction + // of the panel (containment of the applet that contains the systray containment) + for (auto candidate = parent(); candidate; candidate = candidate->parent()) { + if (auto c = qobject_cast(candidate)) { + return c; + } + } + + return nullptr; +} + +void Containment::setFormFactor(Types::FormFactor formFactor) +{ + if (d->formFactor == formFactor) { + return; + } + + // qCDebug(LOG_PLASMA) << "switching FF to " << formFactor; + d->formFactor = formFactor; + + updateConstraints(FormFactorConstraint); + + KConfigGroup c = config(); + c.writeEntry("formfactor", (int)formFactor); + Q_EMIT configNeedsSaving(); + Q_EMIT formFactorChanged(formFactor); +} + +void Containment::setContainmentDisplayHints(Types::ContainmentDisplayHints hints) +{ + if (d->containmentDisplayHints == hints) { + return; + } + + d->containmentDisplayHints = hints; + Q_EMIT containmentDisplayHintsChanged(hints); +} + +void Containment::setLocation(Types::Location location) +{ + if (d->location == location) { + return; + } + + d->location = location; + + for (Applet *applet : std::as_const(d->applets)) { + applet->updateConstraints(LocationConstraint); + } + + updateConstraints(LocationConstraint); + + KConfigGroup c = config(); + c.writeEntry("location", (int)location); + Q_EMIT configNeedsSaving(); + Q_EMIT locationChanged(location); +} + +Applet *Containment::createApplet(const QString &name, const QVariantList &args, const QRectF &geometryHint) +{ + Plasma::Applet *applet = d->createApplet(name, args, 0, geometryHint); + if (applet) { + Q_EMIT appletCreated(applet, geometryHint); + } + return applet; +} + +void Containment::addApplet(Applet *applet, const QRectF &geometryHint) +{ + if (!applet) { +#ifndef NDEBUG + // qCDebug(LOG_PLASMA) << "adding null applet!?!"; +#endif + return; + } + + if (immutability() != Types::Mutable && !applet->property("org.kde.plasma:force-create").toBool()) { + return; + } + +#ifndef NDEBUG + if (d->applets.contains(applet)) { + // qCDebug(LOG_PLASMA) << "already have this applet!"; + } +#endif + + Containment *currentContainment = applet->containment(); + + if (currentContainment && currentContainment != this) { + Q_EMIT currentContainment->appletAboutToBeRemoved(applet); + Q_EMIT currentContainment->appletRemoved(applet); + Q_EMIT appletsChanged(); + + disconnect(applet, nullptr, currentContainment, nullptr); + connect(currentContainment, nullptr, applet, nullptr); + KConfigGroup oldConfig = applet->config(); + currentContainment->d->applets.removeAll(applet); + applet->setParent(this); + + // now move the old config to the new location + // FIXME: this doesn't seem to get the actual main config group containing plugin=, etc + KConfigGroup c = config().group(QStringLiteral("Applets")).group(QString::number(applet->id())); + oldConfig.reparent(&c); + applet->d->resetConfigurationObject(); + + disconnect(applet, &Applet::activated, currentContainment, &Applet::activated); + // change the group to its configloader, if any + // FIXME: this is very, very brutal + if (applet->configScheme()) { + const QString oldGroupPrefix = QStringLiteral("Containments") + QString::number(currentContainment->id()) + QStringLiteral("Applets"); + const QString newGroupPrefix = QStringLiteral("Containments") + QString::number(id()) + QStringLiteral("Applets"); + + applet->configScheme()->setCurrentGroup(applet->configScheme()->currentGroup().replace(0, oldGroupPrefix.length(), newGroupPrefix)); + + const auto items = applet->configScheme()->items(); + for (KConfigSkeletonItem *item : items) { + item->setGroup(item->group().replace(0, oldGroupPrefix.length(), newGroupPrefix)); + } + } + } else { + applet->setParent(this); + } + + // make sure the applets are sorted by id + auto position = std::lower_bound(d->applets.begin(), d->applets.end(), applet, [](Plasma::Applet *a1, Plasma::Applet *a2) { + return a1->id() < a2->id(); + }); + Q_EMIT appletAboutToBeAdded(applet, geometryHint); + d->applets.insert(position, applet); + + if (!d->uiReady) { + d->loadingApplets << applet; + } + + connect(applet, &Applet::configNeedsSaving, this, &Applet::configNeedsSaving); + connect(applet, SIGNAL(appletDeleted(Plasma::Applet *)), this, SLOT(appletDeleted(Plasma::Applet *))); + connect(applet, SIGNAL(statusChanged(Plasma::Types::ItemStatus)), this, SLOT(checkStatus(Plasma::Types::ItemStatus))); + connect(this, &Containment::containmentDisplayHintsChanged, applet, &Applet::containmentDisplayHintsChanged); + + if (!currentContainment) { + const bool isNew = applet->d->mainConfigGroup()->entryMap().isEmpty(); + + if (!isNew) { + applet->restore(*applet->d->mainConfigGroup()); + } + + applet->init(); + + if (isNew) { + applet->save(*applet->d->mainConfigGroup()); + Q_EMIT configNeedsSaving(); + } + // FIXME: an on-appear animation would be nice to have again + } + + applet->updateConstraints(AllConstraints); + applet->flushPendingConstraintsEvents(); + + Q_EMIT appletAdded(applet, geometryHint); + Q_EMIT appletsChanged(); + Q_EMIT applet->containmentChanged(this); + + if (!currentContainment) { + applet->updateConstraints(StartupCompletedConstraint); + applet->flushPendingConstraintsEvents(); + } + + applet->d->scheduleModificationNotification(); +} + +QList Containment::applets() const +{ + return d->applets; +} + +int Containment::screen() const +{ + Q_ASSERT(corona()); + if (Corona *c = corona()) { + return c->screenForContainment(this); + } else { + return -1; + } +} + +int Containment::lastScreen() const +{ + return d->lastScreen; +} + +QRectF Containment::availableRelativeScreenRect() const +{ + if (!corona()) { + return {}; + } + + int screenId = screen(); + + // If corona returned an invalid screenId, try to use lastScreen value if it is valid + if (screenId == -1 && lastScreen() > -1) { + screenId = lastScreen(); + // Is this a screen not actually valid? + if (screenId >= corona()->numScreens()) { + screenId = -1; + } + } + + if (screenId > -1) { + QRectF rect = corona()->availableScreenRect(screenId); + // make it relative + QRectF geometry = corona()->screenGeometry(screenId); + rect.moveTo(rect.topLeft() - geometry.topLeft()); + return rect; + } + + return {}; +} + +QList Containment::availableRelativeScreenRegion() const +{ + QList regVal; + + if (!containment() || !containment()->corona()) { + return regVal; + } + + QRegion reg = QRect(QPoint(0, 0), screenGeometry().size().toSize()); + int screenId = screen(); + if (screenId < 0) { + return {}; + } + reg = containment()->corona()->availableScreenRegion(screenId); + + auto it = reg.begin(); + const auto itEnd = reg.end(); + QRect geometry = containment()->corona()->screenGeometry(screenId); + for (; it != itEnd; ++it) { + QRect rect = *it; + // make it relative + rect.moveTo(rect.topLeft() - geometry.topLeft()); + regVal << QRectF(rect); + } + return regVal; +} + +QRectF Containment::screenGeometry() const +{ + if (!corona() || screen() < 0) { + return {}; + } + + return corona()->screenGeometry(screen()); +} + +void Containment::setWallpaperPlugin(const QString &pluginName) +{ + if (pluginName != d->wallpaperPlugin) { + d->wallpaperPlugin = pluginName; + + KConfigGroup cfg = config(); + cfg.writeEntry("wallpaperplugin", d->wallpaperPlugin); + Q_EMIT configNeedsSaving(); + Q_EMIT wallpaperPluginChanged(); + } +} + +QString Containment::wallpaperPlugin() const +{ + return d->wallpaperPlugin; +} + +QObject *Containment::wallpaperGraphicsObject() const +{ + return d->wallpaperGraphicsObject; +} + +void Containment::setWallpaperGraphicsObject(QObject *object) +{ + if (d->wallpaperGraphicsObject == object) { + return; + } + d->wallpaperGraphicsObject = object; + Q_EMIT wallpaperGraphicsObjectChanged(); +} + +QUrl Containment::compactApplet() const +{ + if (Applet::d->package.isValid()) { + return Applet::d->package.fileUrl("compactapplet"); + } + return QUrl(); +} + +void Containment::setContainmentActions(const QString &trigger, const QString &pluginName) +{ + KConfigGroup cfg = d->containmentActionsConfig(); + ContainmentActions *plugin = nullptr; + + plugin = containmentActions().value(trigger); + if (plugin && plugin->metadata().pluginId() != pluginName) { + containmentActions().remove(trigger); + delete plugin; + plugin = nullptr; + } + + if (pluginName.isEmpty()) { + cfg.deleteEntry(trigger); + } else if (plugin) { + // it already existed, just reload config + plugin->setContainment(this); // to be safe + // FIXME make a truly unique config group + KConfigGroup pluginConfig = KConfigGroup(&cfg, trigger); + plugin->restore(pluginConfig); + + } else { + plugin = PluginLoader::self()->loadContainmentActions(this, pluginName); + + if (plugin) { + cfg.writeEntry(trigger, pluginName); + containmentActions().insert(trigger, plugin); + plugin->setContainment(this); + KConfigGroup pluginConfig = KConfigGroup(&cfg, trigger); + plugin->restore(pluginConfig); + } else { + // bad plugin... gets removed. is this a feature or a bug? + cfg.deleteEntry(trigger); + } + } + + Q_EMIT configNeedsSaving(); +} + +QHash &Containment::containmentActions() +{ + return d->localActionPlugins; +} + +bool Containment::isUiReady() const +{ + return d->uiReady && d->appletsUiReady && Applet::d->started; +} + +void Containment::setActivity(const QString &activityId) +{ + if (activityId.isEmpty() || d->activityId == activityId) { + return; + } + + d->activityId = activityId; + KConfigGroup c = config(); + c.writeEntry("activityId", activityId); + + Q_EMIT configNeedsSaving(); + Q_EMIT activityChanged(activityId); +} + +QString Containment::activity() const +{ + return d->activityId; +} + +QString Containment::activityName() const +{ + if (!d->activityInfo) { + return QString(); + } + return d->activityInfo->name(); +} + +void Containment::reactToScreenChange() +{ + int newScreen = screen(); + + Q_EMIT screenChanged(newScreen); + + if (newScreen >= 0) { + d->lastScreen = newScreen; + KConfigGroup c = config(); + c.writeEntry("lastScreen", d->lastScreen); + Q_EMIT configNeedsSaving(); + + Q_EMIT availableRelativeScreenRectChanged(availableRelativeScreenRect()); + Q_EMIT screenGeometryChanged(screenGeometry()); + Q_EMIT availableRelativeScreenRegionChanged(availableRelativeScreenRegion()); + } +} + +} // Plasma namespace + +#include "moc_containment.cpp" diff --git a/src/plasma/containment.h b/src/plasma/containment.h new file mode 100644 index 0000000..c512e98 --- /dev/null +++ b/src/plasma/containment.h @@ -0,0 +1,496 @@ +/* + SPDX-FileCopyrightText: 2007 Aaron Seigo + SPDX-FileCopyrightText: 2008 Ménard Alexis + SPDX-FileCopyrightText: 2009 Chani Armitage + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMA_CONTAINMENT_H +#define PLASMA_CONTAINMENT_H + +#include +#include +#include +#include + +class QQuickItem; + +namespace Plasma +{ +class Corona; +class ContainmentActions; +class ContainmentPrivate; + +/** + * @class Containment plasma/containment.h + * + * @short The base class for plugins that provide backgrounds and applet grouping containers + * + * Containment objects provide the means to group applets into functional sets. + * They also provide the following: + * + * creation of focusing event + * - drawing of the background image (which can be interactive) + * - form factors (e.g. panel, desktop, full screen, etc) + * - applet layout management + * + * Since containment is actually just a Plasma::Applet, all the techniques used + * for writing the visual presentation of Applets is applicable to Containtments. + * Containments are differentiated from Applets by being marked with the ServiceType + * of Plasma/Containment. Plugins registered with both the Applet and the Containment + * ServiceTypes can be loaded for us in either situation. + * + * See techbase.kde.org for a tutorial on writing Containments using this class. + */ +class PLASMA_EXPORT Containment : public Applet +{ + Q_OBJECT + + /** + * List of applets this containment has: the containments + * KF6: this should be AppletQuickItem * + */ + Q_PROPERTY(QList applets READ applets NOTIFY appletsChanged) + + /** + * The corona for this contaiment + */ + Q_PROPERTY(Plasma::Corona *corona READ corona CONSTANT) + + /** + * Type of this containment + */ + Q_PROPERTY(Plasma::Containment::Type containmentType READ containmentType NOTIFY containmentTypeChanged) + + /** + * Activity UID of this containment + */ + Q_PROPERTY(QString activity READ activity NOTIFY activityChanged) + + /** + * Activity name of this containment + */ + Q_PROPERTY(QString activityName READ activityName NOTIFY activityNameChanged) + + Q_PROPERTY(Plasma::Types::ContainmentDisplayHints containmentDisplayHints READ containmentDisplayHints WRITE setContainmentDisplayHints NOTIFY + containmentDisplayHintsChanged) + + Q_PROPERTY(QString wallpaperPlugin READ wallpaperPlugin WRITE setWallpaperPlugin NOTIFY wallpaperPluginChanged) + Q_PROPERTY(QObject *wallpaperGraphicsObject READ wallpaperGraphicsObject WRITE setWallpaperGraphicsObject NOTIFY wallpaperGraphicsObjectChanged) + + Q_PROPERTY(bool isUiReady READ isUiReady NOTIFY uiReadyChanged) + + /** + * The screen number this containment is serving as the desktop for, or -1 if none + */ + Q_PROPERTY(int screen READ screen NOTIFY screenChanged) + + /** + * screen area free of panels: the coordinates are relative to the containment, + * it's independent from the screen position + * For more precise available geometry use availableScreenRegion() + */ + Q_PROPERTY(QRectF availableScreenRect READ availableRelativeScreenRect NOTIFY availableRelativeScreenRectChanged) + + /** + * The available region of this screen, panels excluded. It's a list of rectangles + */ + Q_PROPERTY(QList availableScreenRegion READ availableRelativeScreenRegion NOTIFY availableRelativeScreenRegionChanged) + + /** + * Provides access to the geometry of the applet is in. + * Can be useful to figure out what's the absolute position of the applet. + */ + Q_PROPERTY(QRectF screenGeometry READ screenGeometry NOTIFY screenGeometryChanged) + +public: + /** + * This constructor can be used with the KCoreAddons plugin loading system. + * The argument list is expected to have contain the KPackage of the applet, + * the meta data file path (for compatibility) and an applet ID which must be a base 10 number. + * + * @param parent a QObject parent; you probably want to pass in 0 + * @param data, KPluginMetaData used to create this plugin + * @param args a list of strings containing the applet id + * @since 5.86 + */ + explicit Containment(QObject *parentObject, const KPluginMetaData &data, const QVariantList &args); + + ~Containment() override; + + /** + * Reimplemented from Applet + */ + void init() override; + + /** + * This enumeration describes the type of the Containment. + * DesktopContainments represent main containments that will own a screen in a mutually exclusive fashion, + * while PanelContainments are accessories which can be present multiple per screen. + * + * This value is specified in the "X-Plasma-ContainmentType" JSON-metadata value of containments. + */ + enum Type { + NoContainment = -1, /**< @internal */ + Desktop = 0, /**< A desktop containment */ + Panel, /**< A desktop panel */ + Custom = 127, /**< A containment that is neither a desktop nor a panel but something application specific */ + CustomPanel = 128, /**< A customized desktop panel. "CustomPanel" in metadata */ + CustomEmbedded = 129, /**< A customized containment embedded in another applet */ + }; + Q_ENUM(Type) + + /** + * Returns the type of containment + */ + Type containmentType() const; + + /** + * Returns the Corona (if any) that this Containment is hosted by + */ + Corona *corona() const; + + /** + * Adds an applet to this Containment + * + * @param name the plugin name for the applet, as given by + * KPluginInfo::pluginName() + * @param args argument list to pass to the plasmoid + * @param geometryHint an hint to pass to the GUI on the location + * and size we prefer for the newly created applet; + * the gui might choose whether to respect or not this hint. + * The default position is (-1, -1) and the default size + * is (0, 0). + * + * @return a pointer to the applet on success, or 0 on failure + */ + Applet *createApplet(const QString &name, const QVariantList &args = QVariantList(), const QRectF &geometryHint = QRectF(-1, -1, 0, 0)); + + /** + * Add an existing applet to this Containment + * + * @param applet the applet that should be added + * @param geometryHint an hint to pass to the GUI on the location + * and size we prefer for the newly created applet; + * the gui might choose whether to respect or not this hint + */ + Q_INVOKABLE void addApplet(Applet *applet, const QRectF &geometryHint = QRectF()); + + /** + * @return the applets currently in this Containment + */ + QList applets() const; + + /** + * @return the screen number this containment is serving as the desktop for + * or -1 if none + * TODO KF6 virtual? this shouldbe available to applet as well + */ + int screen() const; + + /** + * @return the last screen number this containment had + * only returns -1 if it's never ever been on a screen + * @since 4.5 + */ + int lastScreen() const; + + /** + * @reimp + * @sa Applet::save(KConfigGroup &) + */ + void save(KConfigGroup &group) const override; + + /** + * @reimp + * @sa Applet::restore(KConfigGroup &) + */ + void restore(KConfigGroup &group) override; + + /** + * Sets wallpaper plugin. + * + * @param pluginName the name of the wallpaper to attempt to load + */ + void setWallpaperPlugin(const QString &pluginName); + + /** + * Return wallpaper plugin. + */ + QString wallpaperPlugin() const; + + /** + * Sets the current activity by id + * + * @param activity the id of the activity + */ + void setActivity(const QString &activityId); + + /** + * @return the current activity id associated with this containment + * TODO KF6: this should be available to Appelt as well as a property... virtual? + */ + QString activity() const; + + /** + * @return Activity name corresponding to the activity UID + * @see activity + */ + QString activityName() const; + + /** + * Sets a containmentactions plugin. + * + * @param trigger the mouse button (and optional modifier) to associate the plugin with + * @param pluginName the name of the plugin to attempt to load. blank = set no plugin. + * @since 4.4 + */ + void setContainmentActions(const QString &trigger, const QString &pluginName); + + /** + * @return All the loaded containment action plugins, indexed by trigger name + * @since 5.0 + */ + QHash &containmentActions(); + + /** + * @returns true when the ui of this containment is fully loaded, as well the ui of every applet in it + */ + bool isUiReady() const; + + /** + * @returns The available screen rect (excluding panels) for the screen this containment is associated to, + * empty rectangle if the containment is not active in a screen + */ + QRectF availableRelativeScreenRect() const; + + /** + * @returns The available region of this screen, panels excluded. It's a list of rectangles + */ + QList availableRelativeScreenRegion() const; + + /** + * @returns The geometry of the screen this containment is associated to + */ + QRectF screenGeometry() const; + +Q_SIGNALS: + /** + * This signal is emitted when a new applet is added in the containment + * It may happen in the following situations: + * * The user created the applet + * * The applet was moved in from another containment + * * The applet got restored at startup + * @param applet the applet that has been added + * @param geometryHint an hint to pass to the GUI on the location + * and size we prefer for the newly created applet; + * the gui might choose whether to respect or not this hint + */ + void appletAdded(Plasma::Applet *applet, const QRectF &geometryHint); + + /** + * This signal is emitted right before appletAdded, it can be used + * to do a preliminary setup on the applet before the handlers of appletAdded are executed. + * Useful for instance to prepare the GUI for the applet + * @param applet the applet that is about to be added + * @param geometryHint an hint to pass to the GUI on the location + * and size we prefer for the newly created applet; + * the gui might choose whether to respect or not this hint + */ + void appletAboutToBeAdded(Plasma::Applet *applet, const QRectF &geometryHint); + + /** + * This signal is emitted when an applet is destroyed + */ + void appletRemoved(Plasma::Applet *applet); + + /** + * This signal is emitted right before appletRemoved, it can be used + * to do a preliminary setup on the applet before the handlers of appletRemoved are executed. + * Useful for instance to prepare or teardown the GUI for the applet + */ + void appletAboutToBeRemoved(Plasma::Applet *applet); + + /** + * This signal is emitted when a new applet is created by the containment. + * Compared to appletAdded, this gets emitted only when the user explicitly + * creates a new applet, either via the widget explorer or the scripting + * environment. + * @see appletAdded + * @since 5.16 + */ + void appletCreated(Plasma::Applet *applet, const QRectF &geometryHint); + + /** + * Emitted when the list of applets has changed, either added or removed + */ + void appletsChanged(); + + /** + * Emitted when the activity id has changed + */ + void activityChanged(const QString &activity); + + /** + * Emitted when the activity name has changed + */ + void activityNameChanged(const QString &name); + + /** + * Emitted when the containment requests an add widgets dialog is shown. + * Usually only used for desktop containments. + * + * @param pos where in the containment this request was made from, or + * an invalid position (QPointF()) is not location specific + */ + void showAddWidgetsInterface(const QPointF &pos); + + /** + * This signal indicates that a containment has been + * associated (or dissociated) with a physical screen. + * + * @param newScreen the screen it is now associated with + */ + void screenChanged(int newScreen); + + /** + * Emitted when the user wants to configure/change the containment, or an applet inside it. + */ + void configureRequested(Plasma::Applet *applet); + + /** + * Emitted when the user wants to chose an alternative for this applet or containment. + */ + void appletAlternativesRequested(Plasma::Applet *applet); + + /** + * Emitted when the wallpaper plugin is changed + */ + void wallpaperPluginChanged(); + + /** + * Emitted when the location has changed + * @since 5.0 + */ + void locationChanged(Plasma::Types::Location location); + + /** + * Emitted when the formFactor has changed + * @since 5.0 + */ + void formFactorChanged(Plasma::Types::FormFactor formFactor); + + /** + * Emitted when the containment disaplay hints change + */ + void containmentDisplayHintsChanged(Plasma::Types::ContainmentDisplayHints hints); + + /** + * Emitted when the ui has been fully loaded and is fully working + * @param uiReady true when the ui of the containment is ready, as well the ui of each applet in it + */ + void uiReadyChanged(bool uiReady); + + /** + * emitted when the containment type changed + */ + void containmentTypeChanged(); + + /** + * Emitted when the available screen rectangle has changed + */ + void availableRelativeScreenRectChanged(const QRectF &rect); + + /** + * Emitted when the available screen rectangle has changed + */ + void availableRelativeScreenRegionChanged(const QList ®ion); + + /** + * Emitted when the screen geometry has changed + */ + void screenGeometryChanged(const QRectF &rect); + + /** + * Emitted when the root wallpaper item has changed + */ + void wallpaperGraphicsObjectChanged(); + +public Q_SLOTS: + /** + * Informs the Corona as to what position it is in. This is informational + * only, as the Corona doesn't change its actual location. This is, + * however, passed on to Applets that may be managed by this Corona. + * + * @param location the new location of this Corona + */ + void setLocation(Plasma::Types::Location location); + + /** + * Sets the form factor for this Containment. This may cause changes in both + * the arrangement of Applets as well as the display choices of individual + * Applets. + */ + void setFormFactor(Plasma::Types::FormFactor formFactor); + + /** + * Set Display hints that come from the containment that suggest the applet how to look and behave. + * + * @param hints the new hints, as bitwise OR + * @since 5.77 + */ + void setContainmentDisplayHints(Plasma::Types::ContainmentDisplayHints hints); + + void reactToScreenChange(); + +protected: + /** + * Called when the contents of the containment should be saved. By default this saves + * all loaded Applets + * + * @param group the KConfigGroup to save settings under + */ + virtual void saveContents(KConfigGroup &group) const; + + /** + * Called when the contents of the containment should be loaded. By default this loads + * all previously saved Applets + * + * @param group the KConfigGroup to save settings under + */ + virtual void restoreContents(KConfigGroup &group); + +private: + /** + * @internal This constructor is to be used with the Package loading system. + * + * @param parent a QObject parent; you probably want to pass in 0 + * @since 4.3 + */ + Containment(const KPluginMetaData &md, uint appletId); + + /** + * @internal Return root wallpaper item + */ + QObject *wallpaperGraphicsObject() const; + void setWallpaperGraphicsObject(QObject *object); + + QUrl compactApplet() const; + + Q_PRIVATE_SLOT(d, void appletDeleted(Plasma::Applet *)) + Q_PRIVATE_SLOT(d, void triggerShowAddWidgets()) + Q_PRIVATE_SLOT(d, void checkStatus(Plasma::Types::ItemStatus)) + + friend class Applet; + friend class AppletPrivate; + friend class CoronaPrivate; + friend class ContainmentPrivate; + friend class ContainmentActions; + friend class PlasmaQuick::AppletQuickItem; + ContainmentPrivate *const d; +}; + +} // Plasma namespace + +#endif // multiple inclusion guard diff --git a/src/plasma/containmentactions.cpp b/src/plasma/containmentactions.cpp new file mode 100644 index 0000000..7c55985 --- /dev/null +++ b/src/plasma/containmentactions.cpp @@ -0,0 +1,147 @@ +/* + SPDX-FileCopyrightText: 2009 Chani Armitage + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "containmentactions.h" +#include "containment.h" + +#include "private/containment_p.h" +#include "private/containmentactions_p.h" + +#include +#include +#include +#include +#include + +#include + +namespace Plasma +{ +ContainmentActions::ContainmentActions(QObject *parentObject) + : d(new ContainmentActionsPrivate({}, this)) +{ + setParent(parentObject); +} + +ContainmentActions::ContainmentActions(QObject *parentObject, const QVariantList &args) + : d(new ContainmentActionsPrivate(args.value(0), this)) +{ + setParent(parentObject); + + // now remove first item since those are managed by Wallpaper and subclasses shouldn't + // need to worry about them. yes, it violates the constness of this var, but it lets us add + // or remove items later while applets can just pretend that their args always start at 0 + QVariantList &mutableArgs = const_cast(args); + if (!mutableArgs.isEmpty()) { + mutableArgs.removeFirst(); + } +} + +ContainmentActions::~ContainmentActions() +{ + delete d; +} + +KPluginMetaData ContainmentActions::metadata() const +{ + return d->containmentActionsDescription; +} + +Containment *ContainmentActions::containment() +{ + if (d->containment) { + return d->containment; + } + return qobject_cast(parent()); +} + +void ContainmentActions::restore(const KConfigGroup &config) +{ + Q_UNUSED(config); +} + +void ContainmentActions::save(KConfigGroup &config) +{ + Q_UNUSED(config); +} + +QWidget *ContainmentActions::createConfigurationInterface(QWidget *parent) +{ + Q_UNUSED(parent); + return nullptr; +} + +void ContainmentActions::configurationAccepted() +{ + // do nothing by default +} + +void ContainmentActions::performNextAction() +{ + // do nothing by default, implement in subclasses +} + +void ContainmentActions::performPreviousAction() +{ + // do nothing by default, implement in subclasses +} + +QList ContainmentActions::contextualActions() +{ + return QList(); +} + +QString ContainmentActions::eventToString(QEvent *event) +{ + QString trigger; + Qt::KeyboardModifiers modifiers; + + const auto &mo = Qt::staticMetaObject; + + switch (event->type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: { + QMouseEvent *e = static_cast(event); + int m = mo.indexOfEnumerator("MouseButtons"); + QMetaEnum mouse = mo.enumerator(m); + trigger += QString::fromLatin1(mouse.valueToKey(e->button())); + modifiers = e->modifiers(); + break; + } + case QEvent::Wheel: { + QWheelEvent *e = static_cast(event); + trigger = QStringLiteral("wheel:%1") + .arg(std::abs(e->angleDelta().x()) > std::abs(e->angleDelta().y()) ? QStringLiteral("Horizontal") : QStringLiteral("Vertical")); + modifiers = e->modifiers(); + break; + } + case QEvent::ContextMenu: { + int m = mo.indexOfEnumerator("MouseButtons"); + QMetaEnum mouse = mo.enumerator(m); + trigger = QString::fromLatin1(mouse.valueToKey(Qt::RightButton)); + modifiers = Qt::NoModifier; + break; + } + default: + return QString(); + } + + int k = mo.indexOfEnumerator("KeyboardModifiers"); + QMetaEnum kbd = mo.enumerator(k); + trigger += QLatin1Char(';') + QString::fromLatin1(kbd.valueToKeys(modifiers)); + + return trigger; +} + +void ContainmentActions::setContainment(Containment *newContainment) +{ + d->containment = newContainment; +} + +} // Plasma namespace + +#include "moc_containmentactions.cpp" diff --git a/src/plasma/containmentactions.h b/src/plasma/containmentactions.h new file mode 100644 index 0000000..a2d1ed5 --- /dev/null +++ b/src/plasma/containmentactions.h @@ -0,0 +1,140 @@ +/* + SPDX-FileCopyrightText: 2009 Chani Armitage + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMA_CONTAINMENTACTIONS_H +#define PLASMA_CONTAINMENTACTIONS_H + +#include + +#include + +#include + +class QAction; +class KPluginMetaData; +class KConfigGroup; + +namespace Plasma +{ +class Containment; +class ContainmentActionsPrivate; + +/** + * @class ContainmentActions plasma/containmentactions.h + * + * @short The base ContainmentActions class + * + * "ContainmentActions" are components that provide actions (usually displaying a contextmenu) in + * response to an event with a position (usually a mouse event). + * + * ContainmentActions plugins are registered using .desktop files. These files should be + * named using the following naming scheme: + * + * plasma-containmentactions-\.desktop + * + */ + +class PLASMA_EXPORT ContainmentActions : public QObject +{ + Q_OBJECT + +public: + /** + * Default constructor for an empty or null containmentactions + */ + explicit ContainmentActions(QObject *parent = nullptr); + + ~ContainmentActions() override; + + /** + * @return metadata for this ContainmentActions instance + * including name, pluginName and icon + * @since 5.67 + */ + KPluginMetaData metadata() const; + + /** + * This method should be called once the plugin is loaded or settings are changed. + * @param config Config group to load settings + * @see init + **/ + virtual void restore(const KConfigGroup &config); + + /** + * This method is called when settings need to be saved. + * @param config Config group to save settings + **/ + virtual void save(KConfigGroup &config); + + /** + * Returns the widget used in the configuration dialog. + * Add the configuration interface of the containmentactions to this widget. + */ + virtual QWidget *createConfigurationInterface(QWidget *parent); + + /** + * This method is called when the user's configuration changes are accepted + */ + virtual void configurationAccepted(); + + /** + * Called when a "next" action is triggered (e.g. by mouse wheel scroll). This + * can be used to scroll through a list of items this plugin manages such as + * windows, virtual desktops, activities, etc. + * @see performPrevious + */ + virtual void performNextAction(); + + /** + * Called when a "previous" action is triggered (e.g. by mouse wheel scroll). This + * can be used to scroll through a list of items this plugin manages such as + * windows, virtual desktops, activities, etc. + * @see performNext + */ + virtual void performPreviousAction(); + + /** + * Implement this to provide a list of actions that can be added to another menu + * for example, when right-clicking an applet, the "Activity Options" submenu is populated + * with this. + */ + virtual QList contextualActions(); + + /** + * Turns a mouse or wheel event into a string suitable for a ContainmentActions + * @return the string representation of the event + */ + static QString eventToString(QEvent *event); + + /** + * @p newContainment the containment the plugin should be associated with. + * @since 4.6 + */ + void setContainment(Containment *newContainment); + + /** + * @return the containment the plugin is associated with. + */ + Containment *containment(); + +protected: + /** + * This constructor is to be used with the plugin loading systems + * found in KPluginInfo and KService. The argument list is expected + * to have one element: the KService service ID for the desktop entry. + * + * @param parent a QObject parent; you probably want to pass in 0 + * @param args a list of strings containing one entry: the service id + */ + ContainmentActions(QObject *parent, const QVariantList &args); + +private: + ContainmentActionsPrivate *const d; +}; + +} // Plasma namespace + +#endif // PLASMA_CONTAINMENTACTIONS_H diff --git a/src/plasma/corona.cpp b/src/plasma/corona.cpp new file mode 100644 index 0000000..6831d21 --- /dev/null +++ b/src/plasma/corona.cpp @@ -0,0 +1,716 @@ +/* + SPDX-FileCopyrightText: 2007 Matt Broadstone + SPDX-FileCopyrightText: 2007-2011 Aaron Seigo + SPDX-FileCopyrightText: 2007 Riccardo Iaconelli + SPDX-FileCopyrightText: 2009 Chani Armitage + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "corona.h" +#include "private/corona_p.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "containment.h" +#include "debug_p.h" +#include "pluginloader.h" +#include "private/applet_p.h" +#include "private/containment_p.h" + +using namespace Plasma; + +namespace Plasma +{ +Corona::Corona(QObject *parent) + : QObject(parent) + , d(new CoronaPrivate(this)) +{ + d->init(); +} + +Corona::~Corona() +{ + KConfigGroup trans(KSharedConfig::openConfig(), QStringLiteral("PlasmaTransientsConfig")); + trans.deleteGroup(); + + delete d; +} + +KPackage::Package Corona::kPackage() const +{ + return d->package; +} + +void Corona::setKPackage(const KPackage::Package &package) +{ + d->package = package; + Q_EMIT kPackageChanged(package); +} + +void Corona::saveLayout(const QString &configName) const +{ + KSharedConfigPtr c; + + if (configName.isEmpty() || configName == d->configName) { + c = config(); + } else { + c = KSharedConfig::openConfig(configName, KConfig::SimpleConfig); + } + + d->saveLayout(c); +} + +void Corona::exportLayout(KConfigGroup &config, QList containments) +{ + const auto groupList = config.groupList(); + for (const QString &group : groupList) { + KConfigGroup cg(&config, group); + cg.deleteGroup(); + } + + // temporarily unlock so that removal works + Types::ImmutabilityType oldImm = immutability(); + d->immutability = Types::Mutable; + + KConfigGroup dest(&config, QStringLiteral("Containments")); + KConfigGroup dummy; + for (Plasma::Containment *c : std::as_const(containments)) { + c->save(dummy); + c->config().reparent(&dest); + + // ensure the containment is unlocked + // this is done directly because we have to bypass any Types::SystemImmutable checks + c->Applet::d->immutability = Types::Mutable; + const auto lstApplet = c->applets(); + for (Applet *a : lstApplet) { + a->d->immutability = Types::Mutable; + } + + c->destroy(); + } + + // restore immutability + d->immutability = oldImm; + + config.sync(); +} + +void Corona::requestConfigSync() +{ + // constant controlling how long between requesting a configuration sync + // and one happening should occur. currently 10 seconds + static const int CONFIG_SYNC_TIMEOUT = 10000; + + // TODO: should we check into our immutability before doing this? + + // NOTE: this is a pretty simplistic model: we simply save no more than CONFIG_SYNC_TIMEOUT + // after the first time this is called. not much of a heuristic for save points, but + // it should at least compress these activities a bit and provide a way for applet + // authors to ween themselves from the sync() disease. A more interesting/dynamic + // algorithm for determining when to actually sync() to disk might be better, though. + if (!d->configSyncTimer->isActive()) { + d->configSyncTimer->start(CONFIG_SYNC_TIMEOUT); + } +} + +void Corona::requireConfigSync() +{ + d->syncConfig(); +} + +void Corona::loadLayout(const QString &configName) +{ + if (!configName.isEmpty() && configName != d->configName) { + // if we have a new config name passed in, then use that as the config file for this Corona + d->config = nullptr; + d->configName = configName; + } + + KConfigGroup conf(config(), QString()); + if (!config()->groupList().isEmpty()) { + d->importLayout(conf, false); + } else { + loadDefaultLayout(); + d->notifyContainmentsReady(); + } + + KConfigGroup cg(config(), QStringLiteral("General")); + setImmutability((Plasma::Types::ImmutabilityType)cg.readEntry("immutability", (int)Plasma::Types::Mutable)); +} + +QList Corona::importLayout(const KConfigGroup &conf) +{ + return d->importLayout(conf, true); +} + +Containment *Corona::containmentForScreen(int screen, const QString &activity, const QString &defaultPluginIfNonExistent, const QVariantList &defaultArgs) +{ + Containment *containment = nullptr; + + for (Containment *cont : std::as_const(d->containments)) { + if (cont->lastScreen() == screen // + && ((cont->activity().isEmpty() || activity.isEmpty()) || cont->activity() == activity) + && (cont->containmentType() == Plasma::Containment::Type::Desktop // + || cont->containmentType() == Plasma::Containment::Type::Custom || cont->containmentType() == Plasma::Containment::Type::NoContainment)) { + containment = cont; + } + } + + if (!containment && !defaultPluginIfNonExistent.isEmpty()) { + // screen requests are allowed to bypass immutability + if (screen >= 0) { + Plasma::Types::ImmutabilityType imm = d->immutability; + d->immutability = Types::Mutable; + containment = d->addContainment(defaultPluginIfNonExistent, defaultArgs, 0, screen, false); + + d->immutability = imm; + } + } + + if (containment) { + containment->setActivity(activity); + } + return containment; +} + +QList Corona::containmentsForActivity(const QString &activity) +{ + QList conts; + + if (activity.isEmpty()) { + return conts; + } + + std::copy_if(d->containments.begin(), d->containments.end(), std::back_inserter(conts), [activity](Containment *cont) { + return cont->activity() == activity + && (cont->containmentType() == Plasma::Containment::Type::Desktop || cont->containmentType() == Plasma::Containment::Type::Custom); + }); + + return conts; +} + +QList Corona::containmentsForScreen(int screen) +{ + QList conts; + + if (screen < 0) { + return conts; + } + + std::copy_if(d->containments.begin(), d->containments.end(), std::back_inserter(conts), [screen](Containment *cont) { + return cont->lastScreen() == screen + && (cont->containmentType() == Plasma::Containment::Type::Desktop // + || cont->containmentType() == Plasma::Containment::Type::Custom); + }); + + return conts; +} + +QList Corona::containments() const +{ + return d->containments; +} + +bool Corona::isStartupCompleted() const +{ + return d->containmentsStarting <= 0; +} + +KSharedConfigPtr Corona::config() const +{ + if (!d->config) { + d->config = KSharedConfig::openConfig(d->configName, KConfig::SimpleConfig); + } + + return d->config; +} + +Containment *Corona::createContainment(const QString &name, const QVariantList &args) +{ + if (d->immutability == Types::Mutable || args.contains(QVariant::fromValue(QStringLiteral("org.kde.plasma:force-create")))) { + return d->addContainment(name, args, 0, -1, false); + } + + return nullptr; +} + +Containment *Corona::createContainmentDelayed(const QString &name, const QVariantList &args) +{ + if (d->immutability == Types::Mutable) { + return d->addContainment(name, args, 0, -1, true); + } + + return nullptr; +} + +int Corona::screenForContainment(const Containment *) const +{ + return -1; +} + +int Corona::numScreens() const +{ + return 1; +} + +QRegion Corona::availableScreenRegion(int id) const +{ + return QRegion(screenGeometry(id)); +} + +QRect Corona::availableScreenRect(int id) const +{ + return screenGeometry(id); +} + +void Corona::loadDefaultLayout() +{ + // Default implementation does nothing +} + +Types::ImmutabilityType Corona::immutability() const +{ + return d->immutability; +} + +void Corona::setImmutability(const Types::ImmutabilityType immutable) +{ + if (d->immutability == immutable || d->immutability == Types::SystemImmutable) { + return; + } + +#ifndef NDEBUG + // qCDebug(LOG_PLASMA) << "setting immutability to" << immutable; +#endif + d->immutability = immutable; + d->updateContainmentImmutability(); + // tell non-containments that might care (like plasmaapp or a custom corona) + Q_EMIT immutabilityChanged(immutable); + + // update our actions + QAction *action = d->actions.value(QStringLiteral("lock widgets")); + if (action) { + if (d->immutability == Types::SystemImmutable) { + action->setEnabled(false); + action->setVisible(false); + } else { + bool unlocked = d->immutability == Types::Mutable; + action->setText(unlocked ? i18n("Lock Widgets") : i18n("Unlock Widgets")); + action->setIcon(QIcon::fromTheme(unlocked ? QStringLiteral("object-locked") : QStringLiteral("object-unlocked"))); + action->setEnabled(true); + action->setVisible(true); + } + } + + action = d->actions.value(QStringLiteral("edit mode")); + if (action) { + switch (d->immutability) { + case Types::UserImmutable: + action->setEnabled(false); + action->setVisible(true); + break; + case Types::SystemImmutable: + action->setEnabled(false); + action->setVisible(false); + break; + case Types::Mutable: + default: + action->setEnabled(true); + action->setVisible(true); + break; + } + } + + if (d->immutability != Types::SystemImmutable) { + KConfigGroup cg(config(), QStringLiteral("General")); + + // we call the dptr member directly for locked since isImmutable() + // also checks kiosk and parent containers + cg.writeEntry("immutability", (int)d->immutability); + requestConfigSync(); + } + + if (d->immutability != Types::Mutable) { + setEditMode(false); + } +} + +void Corona::setEditMode(bool edit) +{ + if (edit == d->editMode || (edit && d->immutability != Plasma::Types::Mutable)) { + return; + } + + QAction *editAction = d->actions.value(QStringLiteral("edit mode")); + if (editAction) { + if (edit) { + editAction->setText(i18n("Exit Edit Mode")); + } else { + editAction->setText(i18n("Enter Edit Mode")); + } + } + + if (!edit) { + requireConfigSync(); + } + + d->editMode = edit; + Q_EMIT editModeChanged(edit); +} + +bool Corona::isEditMode() const +{ + return d->editMode; +} + +QList Corona::freeEdges(int screen) const +{ + QList freeEdges; + /* clang-format off */ + freeEdges << Plasma::Types::TopEdge + << Plasma::Types::BottomEdge + << Plasma::Types::LeftEdge + << Plasma::Types::RightEdge; + /* clang-format on */ + + const auto containments = this->containments(); + for (Containment *containment : containments) { + if (containment->lastScreen() == screen && freeEdges.contains(containment->location())) { + freeEdges.removeAll(containment->location()); + } + } + + return freeEdges; +} + +QAction *Corona::action(const QString &name) const +{ + return d->actions.value(name); +} + +void Corona::setAction(const QString &name, QAction *action) +{ + if (name.isEmpty()) { + return; + } + action->setObjectName(name); + QAction *oldAction = d->actions.value(name); + if (oldAction && QJSEngine::objectOwnership(oldAction) == QJSEngine::CppOwnership) { + delete oldAction; + } + connect(action, &QObject::destroyed, this, [this, name]() { + d->actions.remove(name); + }); + d->actions[name] = action; +} + +void Corona::removeAction(const QString &name) +{ + QAction *action = d->actions.value(name); + if (action && QJSEngine::objectOwnership(action) == QJSEngine::CppOwnership) { + delete action; + } + d->actions.remove(name); +} + +QList Corona::actions() const +{ + return d->actions.values(); +} + +CoronaPrivate::CoronaPrivate(Corona *corona) + : q(corona) + , immutability(Types::Mutable) + , config(nullptr) + , configSyncTimer(new QTimer(corona)) + , containmentsStarting(0) +{ + // TODO: make Package path configurable + + if (QCoreApplication::instance()) { + configName = QCoreApplication::instance()->applicationName() + QStringLiteral("-appletsrc"); + } else { + configName = QStringLiteral("plasma-appletsrc"); + } +} + +CoronaPrivate::~CoronaPrivate() +{ + // Do not qDeleteAll. The list gets mutated as objects are destroyed because we are connected to the destroyed signal! + while (!containments.isEmpty()) { + delete containments.takeAt(0); + } +} + +void CoronaPrivate::init() +{ + desktopDefaultsConfig = KConfigGroup(KSharedConfig::openConfig(package.filePath("defaults")), QStringLiteral("Desktop")); + + configSyncTimer->setSingleShot(true); + QObject::connect(configSyncTimer, SIGNAL(timeout()), q, SLOT(syncConfig())); + + QAction *lockAction = new QAction(q); + q->setAction(QStringLiteral("lock widgets"), lockAction); + QObject::connect(lockAction, SIGNAL(triggered(bool)), q, SLOT(toggleImmutability())); + lockAction->setText(i18n("Lock Widgets")); + lockAction->setAutoRepeat(true); + lockAction->setIcon(QIcon::fromTheme(QStringLiteral("object-locked"))); + lockAction->setShortcutContext(Qt::ApplicationShortcut); + + // fake containment/applet actions + auto containmentActions = AppletPrivate::defaultActions(q); // containment has to start with applet stuff + ContainmentPrivate::addDefaultActions(containmentActions, nullptr, q); // now it's really containment + actions.insert(containmentActions); + + QAction *editAction = new QAction(q); + q->setAction(QStringLiteral("edit mode"), editAction); + QObject::connect(editAction, &QAction::triggered, q, [this]() { + q->setEditMode(!q->isEditMode()); + }); + editAction->setText(i18n("Enter Edit Mode")); + editAction->setAutoRepeat(true); + editAction->setIcon(QIcon::fromTheme(QStringLiteral("document-edit"))); + editAction->setShortcut(QKeySequence(QStringLiteral("alt+d, e"))); + editAction->setShortcutContext(Qt::ApplicationShortcut); +} + +void CoronaPrivate::toggleImmutability() +{ + if (immutability == Types::Mutable) { + q->setImmutability(Types::UserImmutable); + } else { + q->setImmutability(Types::Mutable); + } +} + +void CoronaPrivate::saveLayout(KSharedConfigPtr cg) const +{ + KConfigGroup containmentsGroup(cg, QStringLiteral("Containments")); + for (const Containment *containment : containments) { + QString cid = QString::number(containment->id()); + KConfigGroup containmentConfig(&containmentsGroup, cid); + containment->save(containmentConfig); + } +} + +void CoronaPrivate::updateContainmentImmutability() +{ + for (Containment *c : std::as_const(containments)) { + // we need to tell each containment that immutability has been altered + c->updateConstraints(Applet::ImmutableConstraint); + } +} + +void CoronaPrivate::containmentDestroyed(QObject *obj) +{ + // we do a static_cast here since it really isn't an Containment by this + // point anymore since we are in the qobject dtor. we don't actually + // try and do anything with it, we just need the value of the pointer + // so this unsafe looking code is actually just fine. + Containment *containment = static_cast(obj); + int index = containments.indexOf(containment); + + if (index > -1) { + containments.removeAt(index); + q->requestConfigSync(); + } +} + +void CoronaPrivate::syncConfig() +{ + q->config()->sync(); + Q_EMIT q->configSynced(); +} + +Containment *CoronaPrivate::addContainment(const QString &name, const QVariantList &args, uint id, int lastScreen, bool delayedInit) +{ + QString pluginName = name; + Containment *containment = nullptr; + Applet *applet = nullptr; + + // qCDebug(LOG_PLASMA) << "Loading" << name << args << id; + + if (pluginName.isEmpty() || pluginName == QLatin1String("default")) { + // default to the desktop containment + pluginName = desktopDefaultsConfig.readEntry("Containment", "org.kde.desktopcontainment"); + } + + bool loadingNull = pluginName == QLatin1String("null"); + if (!loadingNull) { + applet = PluginLoader::self()->loadApplet(pluginName, id, args); + containment = dynamic_cast(applet); + if (containment) { + containment->setParent(q); + } + } + + if (!containment) { + if (!loadingNull) { +#ifndef NDEBUG + // qCDebug(LOG_PLASMA) << "loading of containment" << name << "failed."; +#endif + } + // in case we got a non-Containment from Applet::loadApplet or + // a null containment was requested + if (applet) { + // the applet probably doesn't know what's hit it, so let's pretend it can be + // initialized to make assumptions in the applet's dtor safer + applet->init(); + delete applet; + } + applet = containment = new Containment(q, KPluginMetaData(), QVariantList{QVariant(), id}); + if (lastScreen >= 0) { + containment->d->lastScreen = lastScreen; + } + // if it's a dummy containment, just say its ui is ready, not blocking the corona + applet->updateConstraints(Applet::UiReadyConstraint); + + // we want to provide something and don't care about the failure to launch + containment->setFormFactor(Plasma::Types::Planar); + } + + // if this is a new containment, we need to ensure that there are no stale + // configuration data around + if (id == 0) { + KConfigGroup conf(q->config(), QStringLiteral("Containments")); + conf = KConfigGroup(&conf, QString::number(containment->id())); + conf.deleteGroup(); + } + + // make sure the containments are sorted by id + auto position = std::lower_bound(containments.begin(), containments.end(), containment, [](Plasma::Containment *c1, Plasma::Containment *c2) { + return c1->id() < c2->id(); + }); + containments.insert(position, containment); + + QObject::connect(containment, SIGNAL(destroyed(QObject *)), q, SLOT(containmentDestroyed(QObject *))); + QObject::connect(containment, &Applet::configNeedsSaving, q, &Corona::requestConfigSync); + QObject::connect(containment, &Containment::screenChanged, q, &Corona::screenOwnerChanged); + + if (!delayedInit) { + containment->init(); + KConfigGroup cg = containment->config(); + containment->restore(cg); + containment->updateConstraints(Applet::StartupCompletedConstraint); + containment->save(cg); + q->requestConfigSync(); + containment->flushPendingConstraintsEvents(); + Q_EMIT q->containmentAdded(containment); + // if id = 0 a new containment has been created, not restored + if (id == 0) { + Q_EMIT q->containmentCreated(containment); + } + } + + return containment; +} + +QList CoronaPrivate::importLayout(const KConfigGroup &conf, bool mergeConfig) +{ + if (!conf.isValid()) { + return QList(); + } + + QList newContainments; + QSet containmentsIds; + + for (Containment *containment : std::as_const(containments)) { + containmentsIds.insert(containment->id()); + } + + KConfigGroup containmentsGroup(&conf, QStringLiteral("Containments")); + QStringList groups = containmentsGroup.groupList(); + std::sort(groups.begin(), groups.end()); + + for (const QString &group : std::as_const(groups)) { + KConfigGroup containmentConfig(&containmentsGroup, group); + + if (containmentConfig.entryMap().isEmpty()) { + continue; + } else if (containmentConfig.readEntry(QStringLiteral("transient"), false)) { + containmentConfig.deleteGroup(); + continue; + } + + uint cid = group.toUInt(); + if (containmentsIds.contains(cid)) { + cid = ++AppletPrivate::s_maxAppletId; + } else if (cid > AppletPrivate::s_maxAppletId) { + AppletPrivate::s_maxAppletId = cid; + } + + if (mergeConfig) { + KConfigGroup realConf(q->config(), QStringLiteral("Containments")); + realConf = KConfigGroup(&realConf, QString::number(cid)); + // in case something was there before us + realConf.deleteGroup(); + containmentConfig.copyTo(&realConf); + } + + // qCDebug(LOG_PLASMA) << "got a containment in the config, trying to make a" << containmentConfig.readEntry("plugin", QString()) << "from" << group; +#ifndef NDEBUG + // qCDebug(LOG_PLASMA) << "!!{} STARTUP TIME" << QTime().msecsTo(QTime::currentTime()) << "Adding Containment" << containmentConfig.readEntry("plugin", + // QString()); +#endif + Containment *c = addContainment(containmentConfig.readEntry("plugin", QString()), QVariantList(), cid, -1); + if (!c) { + continue; + } + + newContainments.append(c); + containmentsIds.insert(c->id()); + +#ifndef NDEBUG +// qCDebug(LOG_PLASMA) << "!!{} STARTUP TIME" << QTime().msecsTo(QTime::currentTime()) << "Restored Containment" << c->pluginName(); +#endif + } + + if (!mergeConfig) { + notifyContainmentsReady(); + } + + return newContainments; +} + +void CoronaPrivate::notifyContainmentsReady() +{ + containmentsStarting = 0; + for (Containment *containment : std::as_const(containments)) { + if (!containment->isUiReady() && containment->screen() >= 0) { + ++containmentsStarting; + QObject::connect(containment, &Plasma::Containment::uiReadyChanged, q, [this](bool ready) { + containmentReady(ready); + }); + } + } + + if (containmentsStarting <= 0) { + Q_EMIT q->startupCompleted(); + } +} + +void CoronaPrivate::containmentReady(bool ready) +{ + if (!ready) { + return; + } + --containmentsStarting; + if (containmentsStarting <= 0) { + Q_EMIT q->startupCompleted(); + } +} + +} // namespace Plasma + +#include "moc_corona.cpp" diff --git a/src/plasma/corona.h b/src/plasma/corona.h new file mode 100644 index 0000000..95e3ef7 --- /dev/null +++ b/src/plasma/corona.h @@ -0,0 +1,394 @@ +/* + SPDX-FileCopyrightText: 2007 Aaron Seigo + SPDX-FileCopyrightText: 2007 Matt Broadstone + SPDX-FileCopyrightText: 2012 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMA_CORONA_H +#define PLASMA_CORONA_H + +#include +#include +#include + +class QAction; + +namespace Plasma +{ +class CoronaPrivate; + +/** + * @class Corona plasma/Corona.h + * + * @short A bookkeeping Scene for Plasma::Applets + */ +class PLASMA_EXPORT Corona : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool isStartupCompleted READ isStartupCompleted NOTIFY startupCompleted) + Q_PROPERTY(bool editMode READ isEditMode WRITE setEditMode NOTIFY editModeChanged) + Q_PROPERTY(KPackage::Package kPackage READ kPackage NOTIFY kPackageChanged) + +public: + explicit Corona(QObject *parent = nullptr); + ~Corona() override; + + /** + * Accessor for the associated Package object if any. + * A Corona package defines how Containments are laid out in a View, + * ToolBoxes, default layout, error messages + * and in general all the furniture specific of a particular + * device form factor. + * + * @return the Package object, or an invalid one if none + * @since 5.5 + **/ + KPackage::Package kPackage() const; + + /** + * Setting the package for the corona + * @since 5.5 + */ + void setKPackage(const KPackage::Package &package); + + /** + * @return all containments on this Corona + */ + QList containments() const; + + /** + * @returns true when the startup is over, and + * all the ui graphics has been instantiated + */ + bool isStartupCompleted() const; + + /** + * Returns the config file used to store the configuration for this Corona + */ + KSharedConfig::Ptr config() const; + + /** + * Adds a Containment to the Corona + * + * @param name the plugin name for the containment, as given by + * KPluginInfo::pluginName(). If an empty string is passed in, the default + * containment plugin will be used (usually DesktopContainment). If the + * string literal "null" is passed in, then no plugin will be loaded and + * a simple Containment object will be created instead. + * @param args argument list to pass to the containment + * + * @return a pointer to the containment on success, or 0 on failure. Failure can be + * caused by too restrictive of an Immutability type, as containments cannot be added + * when widgets are locked. + * If the requested containment plugin can not be located or successfully loaded, the Containment will have an invalid pluginInfo(). + */ + Containment *createContainment(const QString &name, const QVariantList &args = QVariantList()); + + /** + * Returns the Containment for a given physical screen and desktop, creating one + * if none exists + * + * @param screen number of the physical screen to locate + * @param activity the activity id of the containment we want, + * and empty string if the activity is not important + * @param defaultPluginIfNonExistent the plugin to load by default; "null" won't + * create it and "default" creates the default plugin + * @param defaultArgs optional arguments to pass in when creating a Containment if needed + * @since 5.45 + */ + Containment * + containmentForScreen(int screen, const QString &activity, const QString &defaultPluginIfNonExistent, const QVariantList &defaultArgs = QVariantList()); + + /** + * Returns all containments which match a particular activity, for any screen + * @param activity the activity id we want + * @returns the list of matching containments if any, empty if activity is an empty string + * @since 5.45 + */ + QList containmentsForActivity(const QString &activity); + + /** + * Returns all containments which match a particular screen, for any activity + * @param screen the screen number we want + * @returns the list of matching containments if any, empty if screen is < 0 + * @since 5.45 + */ + QList containmentsForScreen(int screen); + + /** + * Returns the number of screens available to plasma. + * Subclasses should override this method as the default + * implementation returns a meaningless value. + */ + virtual int numScreens() const; + + /** + * Returns the geometry of a given screen. + * Valid screen ids are 0 to numScreen()-1, or -1 for the full desktop geometry. + * Subclasses should override this method as the default + * implementation returns a meaningless value. + */ + virtual QRect screenGeometry(int id) const = 0; + + /** + * Returns the available region for a given screen. + * The available region excludes panels and similar windows. + * Valid screen ids are 0 to numScreens()-1. + * By default this method returns a rectangular region + * equal to screenGeometry(id); subclasses that need another + * behavior should override this method. + */ + virtual QRegion availableScreenRegion(int id) const; + + /** + * Returns the available rect for a given screen. + * The difference between this and availableScreenRegion() + * is that this method returns only a rectangular + * available space (it doesn't care if your panel is not 100% width). + * The available rect excludes panels and similar windows. + * Valid screen ids are 0 to numScreens()-1. + * By default this method returns a rectangular region + * equal to screenGeometry(id); subclasses that need another + * behavior should override this method. + */ + virtual QRect availableScreenRect(int id) const; + + /** + * This method is useful in order to retrieve the list of available + * screen edges for panel type containments. + * @param screen the id of the screen to look for free edges. + * @returns a list of free edges not filled with panel type containments. + */ + QList freeEdges(int screen) const; + + /** + * @returns The action with the given name, if any + */ + Q_INVOKABLE QAction *action(const QString &name) const; + + /** + * Defines a new action with the given name in the internal collection + */ + void setAction(const QString &name, QAction *action); + + /** + * Remove the action with the given name, if exists + */ + void removeAction(const QString &name); + + /** + * @returns all the actions supported by the corona + */ + QList actions() const; + + /** + * Imports an applet layout from a config file. The results will be added to the + * current set of Containments. + * + * @param config the name of the config file to load from, + * or the default config file if QString() + * @return the list of containments that were loaded + * @since 4.6 + */ + QList importLayout(const KConfigGroup &config); + + /** + * Exports a set of containments to a config file. + * + * @param config the config group to save to + * @param containments the list of containments to save + * @since 4.6 + */ + void exportLayout(KConfigGroup &config, QList containments); + + /** + * @returns the id of the screen which is showing @p containment + * -1 is returned if the containment is not associated with a screen. + */ + virtual int screenForContainment(const Containment *containment) const; + + /** + * @return The type of immutability of this Corona + */ + Types::ImmutabilityType immutability() const; + + /** + * Set the Corona globally into "edit mode" + * Only when the corona is of mutable type can be set of edit mode. + * This indicates the UI to make easy for the user to manipulate applets. + * @param edit + * @since 5.63 + */ + void setEditMode(bool edit); + + /** + * @returns true if the corona is in edit mode + * @since 5.63 + */ + bool isEditMode() const; + + // TODO: make them not slots anymore +public Q_SLOTS: + /** + * Load applet layout from a config file. The results will be added to the + * current set of Containments. + * + * @param config the name of the config file to load from, + * or the default config file if QString() + */ + void loadLayout(const QString &config = QString()); + + /** + * Save applets layout to file + * @param config the file to save to, or the default config file if QString() + */ + void saveLayout(const QString &config = QString()) const; + + /** + * Sets the immutability type for this Corona (not immutable, + * user immutable or system immutable) + * @param immutable the new immutability type of this applet + */ + void setImmutability(const Types::ImmutabilityType immutable); + + /** + * Schedules a flush-to-disk synchronization of the configuration state + * at the next convenient moment. + */ + void requestConfigSync(); + + /** + * Schedules a time sensitive flush-to-disk synchronization of the + * configuration state. Since this method does not provide any sort of + * event compression, it should only be used when an *immediate* disk + * sync is *absolutely* required. Otherwise, use @see requestConfigSync() + * which does do event compression. + */ + void requireConfigSync(); + +Q_SIGNALS: + /** + * This signal indicates a new containment has been added to + * the Corona: it may occur after creation or restore from config + */ + void containmentAdded(Plasma::Containment *containment); + + /** + * This signal indicates a new containment has been created + * in the Corona. Compared to containmentAdded it can only happen + * after the creation of a new containment. + * + * @see containmentAdded + * @since 5.16 + */ + void containmentCreated(Plasma::Containment *containment); + + /** + * This signal indicates that a containment has been newly + * associated (or dissociated) with a physical screen. + * + * @param isScreen the screen it is now associated with + */ + void screenOwnerChanged(int isScreen); + + /** + * This signal indicates that the configuration file was flushed to disk. + */ + void configSynced(); + + /** + * This signal indicates that a change in available screen geometry occurred. + */ + void availableScreenRegionChanged(int id); + + /** + * This signal indicates that a change in available screen geometry occurred. + */ + void availableScreenRectChanged(int id); + + /** + * This signal indicates that a change in geometry for the screen occurred. + */ + void screenGeometryChanged(int id); + + /** + * emitted when immutability changes. + * this is for use by things that don't get constraints events, like plasmaapp. + * it's NOT for containments or applets or any of the other stuff on the scene. + * if your code's not in shells/ it probably shouldn't be using it. + */ + void immutabilityChanged(Plasma::Types::ImmutabilityType immutability); + + /** This signal indicates the screen with the specified id was removed. + * @since 5.40 + */ + void screenRemoved(int id); + + /** This signal indicates a new screen with the specified id was added. + * @since 5.40 + */ + void screenAdded(int id); + + /** + * emitted when the editMode state changes + * @see isEditMode() + * @since 5.63 + */ + void editModeChanged(bool edit); + + /** + * Emitted when the package for this corona has been changed. + * Shells must support changing the shell package on the fly (for instance due to device form factor changing) + * + * @param package the new package that defines the Corona furniture and behavior + */ + void kPackageChanged(const KPackage::Package &package); + + /** + * Emitted when the startup phase has been completed + */ + void startupCompleted(); + +protected: + /** + * Loads the default (system wide) layout for this user + **/ + virtual void loadDefaultLayout(); + + /** + * Loads a containment with delayed initialization, primarily useful + * for implementations of loadDefaultLayout. The caller is responsible + * for all initialization, saving and notification of a new containment. + * + * @param name the plugin name for the containment, as given by + * KPluginInfo::pluginName(). If an empty string is passed in, the default + * containment plugin will be used (usually DesktopContainment). If the + * string literal "null" is passed in, then no plugin will be loaded and + * a simple Containment object will be created instead. + * @param args argument list to pass to the containment + * + * @return a pointer to the containment on success, or 0 on failure. Failure can + * be caused by the Immutability type being too restrictive, as containments can't be added + * when widgets are locked, or if the requested containment plugin can not be located + * or successfully loaded. + * @see addContainment + **/ + Containment *createContainmentDelayed(const QString &name, const QVariantList &args = QVariantList()); + +private: + CoronaPrivate *const d; + + Q_PRIVATE_SLOT(d, void containmentDestroyed(QObject *)) + Q_PRIVATE_SLOT(d, void syncConfig()) + Q_PRIVATE_SLOT(d, void toggleImmutability()) + Q_PRIVATE_SLOT(d, void containmentReady(bool)) + + friend class CoronaPrivate; + friend class View; +}; + +} // namespace Plasma + +#endif diff --git a/src/plasma/data/kconfigxt/libplasma-theme-global.kcfg b/src/plasma/data/kconfigxt/libplasma-theme-global.kcfg new file mode 100644 index 0000000..a813fe8 --- /dev/null +++ b/src/plasma/data/kconfigxt/libplasma-theme-global.kcfg @@ -0,0 +1,19 @@ + + + + + + + true + + + + + 16384 + + + + diff --git a/src/plasma/data/kconfigxt/libplasma-theme-global.kcfgc b/src/plasma/data/kconfigxt/libplasma-theme-global.kcfgc new file mode 100644 index 0000000..bdbc8ab --- /dev/null +++ b/src/plasma/data/kconfigxt/libplasma-theme-global.kcfgc @@ -0,0 +1,4 @@ +File=libplasma-theme-global.kcfg +ClassName=ThemeConfig +Singleton=false +Mutators=false diff --git a/src/plasma/packagestructure/CMakeLists.txt b/src/plasma/packagestructure/CMakeLists.txt new file mode 100644 index 0000000..65656b6 --- /dev/null +++ b/src/plasma/packagestructure/CMakeLists.txt @@ -0,0 +1,21 @@ +function(install_package_structure name) + kcoreaddons_add_plugin(${name} SOURCES ${name}_packagestructure.cpp INSTALL_NAMESPACE "kf6/packagestructure") + target_link_libraries(${name} plasma_packagestructure_static) +endfunction() + +function(install_package_structure_source name source) + kcoreaddons_add_plugin(${name} SOURCES ${source} INSTALL_NAMESPACE "kf6/packagestructure") + target_link_libraries(${name} KF6::Package) +endfunction() + +add_library(plasma_packagestructure_static STATIC packages.cpp) +target_link_libraries(plasma_packagestructure_static KF6::Package Plasma::Plasma) +set_property(TARGET plasma_packagestructure_static PROPERTY POSITION_INDEPENDENT_CODE ON) + +install_package_structure(plasma_generic) +install_package_structure(plasma_applet) +install_package_structure(plasma_theme) +install_package_structure(plasma_containmentactions) + +install_package_structure_source(plasma_wallpaper qmlWallpaper/wallpaper.cpp) +install_package_structure_source(plasma_shell shell/shellpackage.cpp) diff --git a/src/plasma/packagestructure/packages.cpp b/src/plasma/packagestructure/packages.cpp new file mode 100644 index 0000000..2328907 --- /dev/null +++ b/src/plasma/packagestructure/packages.cpp @@ -0,0 +1,59 @@ +/* + SPDX-FileCopyrightText: 2007-2009 Aaron Seigo + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include +#include +#include + +#include +#include +#include +#include + +#include "config-plasma.h" +#include "packages_p.h" + +namespace Plasma +{ +void GenericPackage::initPackage(KPackage::Package *package) +{ + package->addFileDefinition("mainscript", QStringLiteral("ui/main.qml")); + package->setRequired("mainscript", true); + package->addFileDefinition("test", QStringLiteral("tests/test.qml")); + + if (QStringList platform = KRuntimePlatform::runtimePlatform(); !platform.isEmpty()) { + for (QString &platformEntry : platform) { + platformEntry.prepend(QLatin1String("platformcontents/")); + } + platform.append(QStringLiteral("contents")); + package->setContentsPrefixPaths(platform); + } + + package->setDefaultPackageRoot(QStringLiteral(PLASMA_RELATIVE_DATA_INSTALL_DIR "/packages/")); + + package->addDirectoryDefinition("images", QStringLiteral("images")); + package->addDirectoryDefinition("theme", QStringLiteral("theme")); + const QStringList imageMimeTypes{QStringLiteral("image/svg+xml"), QStringLiteral("image/png"), QStringLiteral("image/jpeg")}; + package->setMimeTypes("images", imageMimeTypes); + package->setMimeTypes("theme", imageMimeTypes); + + package->addDirectoryDefinition("config", QStringLiteral("config")); + package->setMimeTypes("config", QStringList{QStringLiteral("text/xml")}); + + package->addDirectoryDefinition("ui", QStringLiteral("ui")); + + package->addDirectoryDefinition("data", QStringLiteral("data")); + + package->addDirectoryDefinition("scripts", QStringLiteral("code")); + package->setMimeTypes("scripts", QStringList{QStringLiteral("text/plain")}); + package->addFileDefinition("screenshot", QStringLiteral("screenshot.png")); + + package->addDirectoryDefinition("translations", QStringLiteral("locale")); +} + +} // namespace Plasma + +#include "moc_packages_p.cpp" diff --git a/src/plasma/packagestructure/packages_p.h b/src/plasma/packagestructure/packages_p.h new file mode 100644 index 0000000..f0c1af2 --- /dev/null +++ b/src/plasma/packagestructure/packages_p.h @@ -0,0 +1,25 @@ +/* + SPDX-FileCopyrightText: 2007 Aaron Seigo + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef LIBS_PLASMA_PACKAGES_P_H +#define LIBS_PLASMA_PACKAGES_P_H + +#include +#include + +namespace Plasma +{ +class GenericPackage : public KPackage::PackageStructure +{ + Q_OBJECT +public: + using KPackage::PackageStructure::PackageStructure; + void initPackage(KPackage::Package *package) override; +}; + +} // namespace Plasma + +#endif // LIBS_PLASMA_PACKAGES_P_H diff --git a/src/plasma/packagestructure/plasma_applet_packagestructure.cpp b/src/plasma/packagestructure/plasma_applet_packagestructure.cpp new file mode 100644 index 0000000..d91a776 --- /dev/null +++ b/src/plasma/packagestructure/plasma_applet_packagestructure.cpp @@ -0,0 +1,50 @@ +/* + SPDX-FileCopyrightText: 2007-2009 Aaron Seigo + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "config-plasma.h" +#include "packages_p.h" +#include +#include +#include +#include +#include + +class PlasmoidPackage : public Plasma::GenericPackage +{ + Q_OBJECT +public: + using Plasma::GenericPackage::GenericPackage; + + void initPackage(KPackage::Package *package) override + { + GenericPackage::initPackage(package); + package->setDefaultPackageRoot(QStringLiteral(PLASMA_RELATIVE_DATA_INSTALL_DIR "/plasmoids/")); + + package->addFileDefinition("configmodel", QStringLiteral("config/config.qml")); + package->addFileDefinition("mainconfigxml", QStringLiteral("config/main.xml")); + package->setRequired("metadata", true); + package->addFileDefinition("metadata", QStringLiteral("metadata.desktop")); + package->setRequired("metadata", true); + } + + void pathChanged(KPackage::Package *package) override + { + GenericPackage::pathChanged(package); + if (const KPluginMetaData md = package->metadata(); md.isValid()) { + if (md.rawData().contains(QStringLiteral("X-Plasma-ContainmentType"))) { + package->addFileDefinition("compactapplet", QStringLiteral("applet/CompactApplet.qml")); + } else { + package->removeDefinition("compactapplet"); + } + } + // The widge explorer uses it to display old incompatible plasmoids + KPackagePrivate::convertCompatMetaDataDesktopFile(package); + } +}; + +K_PLUGIN_CLASS_WITH_JSON(PlasmoidPackage, "plasma_applet_packagestructure.json") + +#include "plasma_applet_packagestructure.moc" diff --git a/src/plasma/packagestructure/plasma_applet_packagestructure.json b/src/plasma/packagestructure/plasma_applet_packagestructure.json new file mode 100644 index 0000000..fdae726 --- /dev/null +++ b/src/plasma/packagestructure/plasma_applet_packagestructure.json @@ -0,0 +1,4 @@ +{ + "KPackageStructure": "Plasma/Applet", + "X-KDE-ParentApp": "org.kde.plasmashell" +} diff --git a/src/plasma/packagestructure/plasma_containmentactions_packagestructure.cpp b/src/plasma/packagestructure/plasma_containmentactions_packagestructure.cpp new file mode 100644 index 0000000..24a63d5 --- /dev/null +++ b/src/plasma/packagestructure/plasma_containmentactions_packagestructure.cpp @@ -0,0 +1,27 @@ +/* + SPDX-FileCopyrightText: 2007-2009 Aaron Seigo + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "config-plasma.h" +#include "packages_p.h" +#include +#include + +class ContainmentActionsPackage : public Plasma::GenericPackage +{ + Q_OBJECT +public: + using Plasma::GenericPackage::GenericPackage; + + void initPackage(KPackage::Package *package) override + { + GenericPackage::initPackage(package); + package->setDefaultPackageRoot(QStringLiteral(PLASMA_RELATIVE_DATA_INSTALL_DIR "/containmentactions/")); + } +}; + +K_PLUGIN_CLASS_WITH_JSON(ContainmentActionsPackage, "plasma_containmentactions_packagestructure.json") + +#include "plasma_containmentactions_packagestructure.moc" diff --git a/src/plasma/packagestructure/plasma_containmentactions_packagestructure.json b/src/plasma/packagestructure/plasma_containmentactions_packagestructure.json new file mode 100644 index 0000000..3fb45c0 --- /dev/null +++ b/src/plasma/packagestructure/plasma_containmentactions_packagestructure.json @@ -0,0 +1,4 @@ +{ + "KPackageStructure": "Plasma/ContainmentActions", + "X-KDE-ParentApp": "org.kde.plasmashell" +} diff --git a/src/plasma/packagestructure/plasma_generic_packagestructure.cpp b/src/plasma/packagestructure/plasma_generic_packagestructure.cpp new file mode 100644 index 0000000..f2c66e6 --- /dev/null +++ b/src/plasma/packagestructure/plasma_generic_packagestructure.cpp @@ -0,0 +1,11 @@ +/* + SPDX-FileCopyrightText: 2007-2009 Aaron Seigo + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "packages_p.h" + +K_PLUGIN_CLASS_WITH_JSON(Plasma::GenericPackage, "plasma_generic_packagestructure.json") + +#include "plasma_generic_packagestructure.moc" diff --git a/src/plasma/packagestructure/plasma_generic_packagestructure.json b/src/plasma/packagestructure/plasma_generic_packagestructure.json new file mode 100644 index 0000000..3f3780d --- /dev/null +++ b/src/plasma/packagestructure/plasma_generic_packagestructure.json @@ -0,0 +1,4 @@ +{ + "KPackageStructure": "Plasma/Generic", + "X-KDE-ParentApp": "org.kde.plasmashell" +} diff --git a/src/plasma/packagestructure/plasma_theme_packagestructure.cpp b/src/plasma/packagestructure/plasma_theme_packagestructure.cpp new file mode 100644 index 0000000..2665364 --- /dev/null +++ b/src/plasma/packagestructure/plasma_theme_packagestructure.cpp @@ -0,0 +1,75 @@ +/* + SPDX-FileCopyrightText: 2007-2009 Aaron Seigo + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "config-plasma.h" +#include +#include +#include +#include +#include + +class ThemePackage : public KPackage::PackageStructure +{ + Q_OBJECT +public: + using KPackage::PackageStructure::PackageStructure; + + void initPackage(KPackage::Package *package) override + { + // by default the packages have "contents/" as contentsPrefixPaths + // but for the themes we don't want that, so unset it. + package->setContentsPrefixPaths(QStringList()); + package->setDefaultPackageRoot(QStringLiteral(PLASMA_RELATIVE_DATA_INSTALL_DIR "/desktoptheme/")); + + package->addDirectoryDefinition("dialogs", QStringLiteral("dialogs/")); + package->addFileDefinition("dialogs/background", QStringLiteral("dialogs/background.svg")); + package->addFileDefinition("dialogs/background", QStringLiteral("dialogs/background.svgz")); + package->addFileDefinition("dialogs/shutdowndialog", QStringLiteral("dialogs/shutdowndialog.svg")); + package->addFileDefinition("dialogs/shutdowndialog", QStringLiteral("dialogs/shutdowndialog.svgz")); + + package->addDirectoryDefinition("wallpapers", QStringLiteral("wallpapers/")); + + package->addDirectoryDefinition("widgets", QStringLiteral("widgets/")); + package->addFileDefinition("widgets/background", QStringLiteral("widgets/background.svg")); + package->addFileDefinition("widgets/background", QStringLiteral("widgets/background.svgz")); + package->addFileDefinition("widgets/clock", QStringLiteral("widgets/clock.svg")); + package->addFileDefinition("widgets/clock", QStringLiteral("widgets/clock.svgz")); + package->addFileDefinition("widgets/panel-background", QStringLiteral("widgets/panel-background.svg")); + package->addFileDefinition("widgets/panel-background", QStringLiteral("widgets/panel-background.svgz")); + package->addFileDefinition("widgets/plot-background", QStringLiteral("widgets/plot-background.svg")); + package->addFileDefinition("widgets/plot-background", QStringLiteral("widgets/plot-background.svgz")); + package->addFileDefinition("widgets/tooltip", QStringLiteral("widgets/tooltip.svg")); + package->addFileDefinition("widgets/tooltip", QStringLiteral("widgets/tooltip.svgz")); + + package->addDirectoryDefinition("opaque/dialogs", QStringLiteral("opaque/dialogs/")); + package->addFileDefinition("opaque/dialogs/background", QStringLiteral("opaque/dialogs/background.svg")); + package->addFileDefinition("opaque/dialogs/background", QStringLiteral("opaque/dialogs/background.svgz")); + package->addFileDefinition("opaque/dialogs/shutdowndialog", QStringLiteral("opaque/dialogs/shutdowndialog.svg")); + package->addFileDefinition("opaque/dialogs/shutdowndialog", QStringLiteral("opaque/dialogs/shutdowndialog.svgz")); + + package->addDirectoryDefinition("opaque/widgets", QStringLiteral("opaque/widgets/")); + package->addFileDefinition("opaque/widgets/panel-background", QStringLiteral("opaque/widgets/panel-background.svg")); + package->addFileDefinition("opaque/widgets/panel-background", QStringLiteral("opaque/widgets/panel-background.svgz")); + package->addFileDefinition("opaque/widgets/tooltip", QStringLiteral("opaque/widgets/tooltip.svg")); + package->addFileDefinition("opaque/widgets/tooltip", QStringLiteral("opaque/widgets/tooltip.svgz")); + + package->addFileDefinition("colors", QStringLiteral("colors")); + + package->setDefaultMimeTypes({QStringLiteral("image/svg+xml")}); + + package->addFileDefinition("metadata", QStringLiteral("metadata.desktop")); + package->setRequired("metadata", true); + } + void pathChanged(KPackage::Package *package) override + { + // The KCM uses KPackage to list available themes + KPackagePrivate::convertCompatMetaDataDesktopFile(package); + } +}; + +K_PLUGIN_CLASS_WITH_JSON(ThemePackage, "plasma_theme_packagestructure.json") + +#include "plasma_theme_packagestructure.moc" diff --git a/src/plasma/packagestructure/plasma_theme_packagestructure.json b/src/plasma/packagestructure/plasma_theme_packagestructure.json new file mode 100644 index 0000000..e90a71a --- /dev/null +++ b/src/plasma/packagestructure/plasma_theme_packagestructure.json @@ -0,0 +1,4 @@ +{ + "KPackageStructure": "Plasma/Theme", + "X-KDE-ParentApp": "org.kde.plasmashell" +} diff --git a/src/plasma/packagestructure/qmlWallpaper/plasma-packagestructure-wallpaper.json b/src/plasma/packagestructure/qmlWallpaper/plasma-packagestructure-wallpaper.json new file mode 100644 index 0000000..77368cf --- /dev/null +++ b/src/plasma/packagestructure/qmlWallpaper/plasma-packagestructure-wallpaper.json @@ -0,0 +1,4 @@ +{ + "KPackageStructure": "Plasma/Wallpaper", + "X-KDE-ParentApp": "org.kde.plasmashell" +} diff --git a/src/plasma/packagestructure/qmlWallpaper/wallpaper.cpp b/src/plasma/packagestructure/qmlWallpaper/wallpaper.cpp new file mode 100644 index 0000000..b5fa9b3 --- /dev/null +++ b/src/plasma/packagestructure/qmlWallpaper/wallpaper.cpp @@ -0,0 +1,58 @@ +/* + SPDX-FileCopyrightText: 2007-2009 Aaron Seigo + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include +#include + +class QmlWallpaperPackage : public KPackage::PackageStructure +{ + Q_OBJECT +public: + using KPackage::PackageStructure::PackageStructure; + + void initPackage(KPackage::Package *package) override + { + package->addFileDefinition("mainscript", QStringLiteral("ui/main.qml")); + package->setRequired("mainscript", true); + + QStringList platform = KRuntimePlatform::runtimePlatform(); + if (!platform.isEmpty()) { + QMutableStringListIterator it(platform); + while (it.hasNext()) { + it.next(); + it.setValue(QStringLiteral("platformcontents/") + it.value()); + } + + platform.append(QStringLiteral("contents")); + package->setContentsPrefixPaths(platform); + } + + package->setDefaultPackageRoot(QStringLiteral("plasma/wallpapers/")); + + package->addDirectoryDefinition("images", QStringLiteral("images")); + package->addDirectoryDefinition("theme", QStringLiteral("theme")); + const QStringList mimetypes{QStringLiteral("image/svg+xml"), QStringLiteral("image/png"), QStringLiteral("image/jpeg")}; + package->setMimeTypes("images", mimetypes); + package->setMimeTypes("theme", mimetypes); + + package->addDirectoryDefinition("config", QStringLiteral("config")); + package->setMimeTypes("config", QStringList{QStringLiteral("text/xml")}); + + package->addDirectoryDefinition("ui", QStringLiteral("ui")); + + package->addDirectoryDefinition("data", QStringLiteral("data")); + + package->addDirectoryDefinition("scripts", QStringLiteral("code")); + package->setMimeTypes("scripts", QStringList{QStringLiteral("text/plain")}); + + package->addDirectoryDefinition("translations", QStringLiteral("locale")); + } +}; + +K_PLUGIN_CLASS_WITH_JSON(QmlWallpaperPackage, "plasma-packagestructure-wallpaper.json") + +#include "wallpaper.moc" diff --git a/src/plasma/packagestructure/shell/plasma-packagestructure-plasma-shell.json b/src/plasma/packagestructure/shell/plasma-packagestructure-plasma-shell.json new file mode 100644 index 0000000..0587eab --- /dev/null +++ b/src/plasma/packagestructure/shell/plasma-packagestructure-plasma-shell.json @@ -0,0 +1,4 @@ +{ + "KPackageStructure": "Plasma/Shell", + "X-KDE-ParentApp": "org.kde.plasmashell" +} diff --git a/src/plasma/packagestructure/shell/shellpackage.cpp b/src/plasma/packagestructure/shell/shellpackage.cpp new file mode 100644 index 0000000..7cb7f38 --- /dev/null +++ b/src/plasma/packagestructure/shell/shellpackage.cpp @@ -0,0 +1,89 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include +#include + +#include +#include +#include + +#define DEFAULT_SHELL "org.kde.plasma.desktop" + +class ShellPackage : public KPackage::PackageStructure +{ + Q_OBJECT +public: + using KPackage::PackageStructure::PackageStructure; + + void initPackage(KPackage::Package *package) override + { + package->setDefaultPackageRoot(QStringLiteral("plasma/shells/")); + + // Directories + package->addDirectoryDefinition("applet", QStringLiteral("applet")); + package->addDirectoryDefinition("configuration", QStringLiteral("configuration")); + package->addDirectoryDefinition("explorer", QStringLiteral("explorer")); + package->addDirectoryDefinition("views", QStringLiteral("views")); + + package->setMimeTypes("applet", QStringList{QStringLiteral("text/x-qml")}); + package->setMimeTypes("configuration", QStringList{QStringLiteral("text/x-qml")}); + package->setMimeTypes("views", QStringList{QStringLiteral("text/x-qml")}); + + // Files + // Default layout + package->addFileDefinition("defaultlayout", QStringLiteral("layout.js")); + package->addFileDefinition("defaults", QStringLiteral("defaults")); + package->setMimeTypes("defaultlayout", QStringList{QStringLiteral("application/javascript"), QStringLiteral("text/javascript")}); + package->setMimeTypes("defaults", QStringList{QStringLiteral("text/plain")}); + + // OSD + package->addDirectoryDefinition("osd", QStringLiteral("osd")); + package->addFileDefinition("osdmainscript", QStringLiteral("osd/Osd.qml")); + + // Applet furniture + package->addFileDefinition("appleterror", QStringLiteral("applet/AppletError.qml")); + package->addFileDefinition("compactapplet", QStringLiteral("applet/CompactApplet.qml")); + package->addFileDefinition("defaultcompactrepresentation", QStringLiteral("applet/DefaultCompactRepresentation.qml")); + + // Configuration + package->addFileDefinition("appletconfigurationui", QStringLiteral("configuration/AppletConfiguration.qml")); + package->addFileDefinition("containmentconfigurationui", QStringLiteral("configuration/ContainmentConfiguration.qml")); + package->addFileDefinition("panelconfigurationui", QStringLiteral("configuration/PanelConfiguration.qml")); + package->addFileDefinition("appletalternativesui", QStringLiteral("explorer/AppletAlternatives.qml")); + package->addFileDefinition("containmentmanagementui", QStringLiteral("configuration/ShellContainmentConfiguration.qml")); + + // Widget explorer + package->addFileDefinition("widgetexplorer", QStringLiteral("explorer/WidgetExplorer.qml")); + + // Lock screen + package->addDirectoryDefinition("lockscreen", QStringLiteral("lockscreen")); + package->addFileDefinition("lockscreenmainscript", QStringLiteral("lockscreen/LockScreen.qml")); + + package->addFileDefinition("interactiveconsole", QStringLiteral("InteractiveConsole.qml")); + } + + void pathChanged(KPackage::Package *package) override + { + if (!package->metadata().isValid()) { + return; + } + + const QString pluginName = package->metadata().pluginId(); + if (!pluginName.isEmpty() && pluginName != QStringLiteral(DEFAULT_SHELL)) { + const QString fallback = package->metadata().value(QStringLiteral("X-Plasma-FallbackPackage"), QStringLiteral(DEFAULT_SHELL)); + + KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Shell"), fallback); + package->setFallbackPackage(pkg); + } else if (package->fallbackPackage().isValid() && pluginName == QStringLiteral(DEFAULT_SHELL)) { + package->setFallbackPackage(KPackage::Package()); + } + } +}; + +K_PLUGIN_CLASS_WITH_JSON(ShellPackage, "plasma-packagestructure-plasma-shell.json") + +#include "shellpackage.moc" diff --git a/src/plasma/plasma.cpp b/src/plasma/plasma.cpp new file mode 100644 index 0000000..2d70601 --- /dev/null +++ b/src/plasma/plasma.cpp @@ -0,0 +1,28 @@ +/* + SPDX-FileCopyrightText: 2005 Aaron Seigo + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include + +#include +#include +#include + +#include "containment.h" + +namespace Plasma +{ +Types::Types(QObject *parent) + : QObject(parent) +{ +} + +Types::~Types() +{ +} + +} // Plasma namespace + +#include "moc_plasma.cpp" diff --git a/src/plasma/plasma.h b/src/plasma/plasma.h new file mode 100644 index 0000000..994588c --- /dev/null +++ b/src/plasma/plasma.h @@ -0,0 +1,148 @@ +/* + SPDX-FileCopyrightText: 2005 Aaron Seigo + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMA_DEFS_H +#define PLASMA_DEFS_H + +/** @header plasma/plasma.h */ + +#include + +#include + +class QAction; + +/** + * Namespace for everything in libplasma + */ +namespace Plasma +{ +/** + * @class Types plasma/plasma.h + * @short Enums and constants used in Plasma + * + */ +class PLASMA_EXPORT Types : public QObject +{ + Q_OBJECT + +public: + ~Types() override; + + /** + * The FormFactor enumeration describes how a Plasma::Applet should arrange + * itself. The value is derived from the container managing the Applet + * (e.g. in Plasma, a Corona on the desktop or on a panel). + **/ + enum FormFactor { + Planar = 0, /**< The applet lives in a plane and has two + degrees of freedom to grow. Optimize for + desktop, laptop or tablet usage: a high + resolution screen 1-3 feet distant from the + viewer. */ + MediaCenter, /**< As with Planar, the applet lives in a plane + but the interface should be optimized for + medium-to-high resolution screens that are + 5-15 feet distant from the viewer. Sometimes + referred to as a "ten foot interface".*/ + Horizontal, /**< The applet is constrained vertically, but + can expand horizontally. */ + Vertical, /**< The applet is constrained horizontally, but + can expand vertically. */ + Application, /**< The Applet lives in a plane and should be optimized to look as a full application, + for the desktop or the particular device. */ + }; + Q_ENUM(FormFactor) + + /** + * Display hints that come from the containment that suggest the applet how to look and behave. + * @since 5.77 + */ + enum ContainmentDisplayHint { + NoContainmentDisplayHint = 0, + ContainmentDrawsPlasmoidHeading = + 1, /**< The containment will draw an titlebar-looking header for the applets, so the applets shouldn't attempt to paint a similar thing **/ + ContainmentForcesSquarePlasmoids = + 2, /**< The containment will force every plasmoid to be constrained in a square icon (An example is the System Tray)**/ + ContainmentPrefersOpaqueBackground = 4, /**< The containment prefers the style of the applets to be opaque, where applicable */ + ContainmentPrefersFloatingApplets = 8 /**< The containment prefers applet's dialogs to be floating, where applicable */ + }; + Q_ENUM(ContainmentDisplayHint) + Q_DECLARE_FLAGS(ContainmentDisplayHints, ContainmentDisplayHint) + Q_FLAG(ContainmentDisplayHints) + + /** + * The Location enumeration describes where on screen an element, such as an + * Applet or its managing container, is positioned on the screen. + **/ + enum Location { + Floating = 0, /**< Free floating. Neither geometry or z-ordering + is described precisely by this value. */ + Desktop, /**< On the planar desktop layer, extending across + the full screen from edge to edge */ + FullScreen, /**< Full screen */ + TopEdge, /**< Along the top of the screen*/ + BottomEdge, /**< Along the bottom of the screen*/ + LeftEdge, /**< Along the left side of the screen */ + RightEdge, /**< Along the right side of the screen */ + }; + Q_ENUM(Location) + + /** + * Defines the immutability of items like applets, corona and containments + * they can be free to modify, locked down by the user or locked down by the + * system (e.g. kiosk setups). + */ + enum ImmutabilityType { + Mutable = 1, /**< The item can be modified in any way **/ + UserImmutable = 2, /**< The user has requested a lock down, and can undo + the lock down at any time **/ + SystemImmutable = 4, /**< the item is locked down by the system, the user + can't unlock it **/ + }; + Q_ENUM(ImmutabilityType) + + /** + * Status of an applet + * @since 4.3 + */ + enum ItemStatus { + UnknownStatus = 0, /**< The status is unknown **/ + PassiveStatus = 1, /**< The Item is passive **/ + ActiveStatus = 2, /**< The Item is active **/ + NeedsAttentionStatus = 3, /**< The Item needs attention **/ + RequiresAttentionStatus = 4, /**< The Item needs persistent attention **/ + AcceptingInputStatus = 5, /**< The Item is accepting input **/ + // FIXME KF6: this should be the smallest status + HiddenStatus = 6, /**< The Item will be hidden totally **/ + }; + Q_ENUM(ItemStatus) + + /** + * Description on how draw a background for the applet + */ + enum BackgroundHints { + NoBackground = 0, /**< Not drawing a background under the applet, the applet has its own implementation */ + StandardBackground = 1, /**< The standard background from the theme is drawn */ + TranslucentBackground = 2, /**< An alternate version of the background is drawn, usually more translucent */ + ShadowBackground = 4, /**< The applet won't have a svg background but a drop shadow of its content done via a shader */ + ConfigurableBackground = 8, /** If the hint has this flag, the user is able to configure this background */ + DefaultBackground = StandardBackground, /**< Default settings: both standard background */ + }; + Q_ENUM(BackgroundHints) + // TODO KF6: BackgroundHint and BackgroundHints + Q_DECLARE_FLAGS(BackgroundFlags, BackgroundHints) + +private: + Types(QObject *parent = nullptr); +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(Types::ContainmentDisplayHints) +Q_DECLARE_OPERATORS_FOR_FLAGS(Types::BackgroundFlags) + +} // Plasma namespace + +#endif // multiple inclusion guard diff --git a/src/plasma/pluginloader.cpp b/src/plasma/pluginloader.cpp new file mode 100644 index 0000000..b982cd4 --- /dev/null +++ b/src/plasma/pluginloader.cpp @@ -0,0 +1,249 @@ +/* + SPDX-FileCopyrightText: 2010 Ryan Rix + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "pluginloader.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "config-plasma.h" + +#include "applet.h" +#include "containment.h" +#include "containmentactions.h" +#include "debug_p.h" +#include "private/applet_p.h" + +namespace Plasma +{ +inline bool isContainmentMetaData(const KPluginMetaData &md) +{ + return md.rawData().contains(QStringLiteral("X-Plasma-ContainmentType")); +} + +PluginLoader *PluginLoader::self() +{ + static PluginLoader self; + return &self; +} + +Applet *PluginLoader::loadApplet(const QString &name, uint appletId, const QVariantList &args) +{ + if (name.isEmpty()) { + return nullptr; + } + + Applet *applet = nullptr; + + if (appletId == 0) { + appletId = ++AppletPrivate::s_maxAppletId; + } + + // name can be either an actual applet name or an absolute path, in the + // latter case, ensure we only use the name part of the path. + const QString pluginName = name.section(QLatin1Char('/'), -1); + + KPluginMetaData plugin(QStringLiteral("plasma/applets/") + pluginName, KPluginMetaData::AllowEmptyMetaData); + const KPackage::Package p = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Applet"), name); + + if (!p.isValid()) { + qWarning(LOG_PLASMA) << "Applet invalid: Cannot find a package for" << name; + } + + // If the applet is using another applet package, search for the plugin of the other applet + if (!plugin.isValid()) { + const QString parentPlugin = p.metadata().value(QStringLiteral("X-Plasma-RootPath")); + if (!parentPlugin.isEmpty()) { + plugin = KPluginMetaData(QStringLiteral("plasma/applets/") + parentPlugin, KPluginMetaData::AllowEmptyMetaData); + } + } + + if (plugin.isValid()) { + QVariantList allArgs = QVariantList{QVariant::fromValue(p), appletId} << args; + if (KPluginFactory *factory = KPluginFactory::loadFactory(plugin).plugin) { + if (factory->metaData().rawData().isEmpty()) { + factory->setMetaData(p.metadata()); + } + applet = factory->create(nullptr, allArgs); + } + } + if (applet) { + return applet; + } + + QVariantList allArgs; + allArgs << QVariant::fromValue(p) << appletId << args; + + if (isContainmentMetaData(p.metadata())) { + applet = new Containment(nullptr, p.metadata(), allArgs); + } else { + KPluginMetaData metadata = p.metadata(); + if (metadata.pluginId().isEmpty()) { + // Add fake extension to parse completeBaseName() as pluginId + // without having to construct a fake JSON metadata object. + // This would help with better error messages which would + // at least show the missing applet's ID. + const auto fakeFileName = name + u'.'; + metadata = KPluginMetaData(QJsonObject(), fakeFileName); + } + applet = new Applet(nullptr, metadata, allArgs); + } + + const QString localePath = p.filePath("translations"); + if (!localePath.isEmpty()) { + KLocalizedString::addDomainLocaleDir(QByteArray("plasma_applet_") + name.toLatin1(), localePath); + } + return applet; +} + +ContainmentActions *PluginLoader::loadContainmentActions(Containment *parent, const QString &name, const QVariantList &args) +{ + if (name.isEmpty()) { + return nullptr; + } + + KPluginMetaData plugin(QStringLiteral("plasma/containmentactions/") + name, KPluginMetaData::AllowEmptyMetaData); + + if (plugin.isValid()) { + if (auto res = KPluginFactory::instantiatePlugin(plugin, nullptr, {QVariant::fromValue(plugin)})) { + return res.plugin; + } + } + + return nullptr; +} + +QList PluginLoader::listAppletMetaData(const QString &category) +{ + auto platforms = KRuntimePlatform::runtimePlatform(); + // For now desktop always lists everything + if (platforms.contains(QStringLiteral("desktop"))) { + platforms.clear(); + } + + // FIXME: this assumes we are always use packages.. no pure c++ + std::function filter; + if (category.isEmpty()) { // use all but the excluded categories + KConfigGroup group(KSharedConfig::openConfig(), QStringLiteral("General")); + QStringList excluded = group.readEntry("ExcludeCategories", QStringList()); + + filter = [excluded, platforms](const KPluginMetaData &md) -> bool { + if (!platforms.isEmpty() && !md.formFactors().isEmpty()) { + bool found = false; + for (const auto &plat : platforms) { + if (md.formFactors().contains(plat)) { + found = true; + break; + } + } + + if (!found) { + return false; + } + } + + return !excluded.contains(md.category()); + }; + } else { // specific category (this could be an excluded one - is that bad?) + + filter = [category, platforms](const KPluginMetaData &md) -> bool { + if (!platforms.isEmpty() && !md.formFactors().isEmpty()) { + bool found = false; + for (const auto &plat : platforms) { + if (md.formFactors().contains(plat)) { + found = true; + break; + } + } + + if (!found) { + return false; + } + } + + if (category == QLatin1String("Miscellaneous")) { + return md.category() == category || md.category().isEmpty(); + } else { + return md.category() == category; + } + }; + } + + return KPackage::PackageLoader::self()->findPackages(QStringLiteral("Plasma/Applet"), QString(), filter); +} + +QList PluginLoader::listAppletMetaDataForMimeType(const QString &mimeType) +{ + auto filter = [&mimeType](const KPluginMetaData &md) -> bool { + return md.value(QStringLiteral("X-Plasma-DropMimeTypes"), QStringList()).contains(mimeType); + }; + return KPackage::PackageLoader::self()->findPackages(QStringLiteral("Plasma/Applet"), QString(), filter); +} + +QList PluginLoader::listAppletMetaDataForUrl(const QUrl &url) +{ + auto filter = [](const KPluginMetaData &md) -> bool { + return !md.value(QStringLiteral("X-Plasma-DropUrlPatterns"), QStringList()).isEmpty(); + }; + const QList allApplets = KPackage::PackageLoader::self()->findPackages(QStringLiteral("Plasma/Applet"), QString(), filter); + + QList filtered; + for (const KPluginMetaData &md : allApplets) { + const QStringList urlPatterns = md.value(QStringLiteral("X-Plasma-DropUrlPatterns"), QStringList()); + for (const QString &glob : urlPatterns) { + QRegularExpression rx(QRegularExpression::anchoredPattern(QRegularExpression::wildcardToRegularExpression(glob))); + if (rx.match(url.toString()).hasMatch()) { + filtered << md; + } + } + } + + return filtered; +} + +QList PluginLoader::listContainmentsMetaData(std::function filter) +{ + auto ownFilter = [filter](const KPluginMetaData &md) -> bool { + return isContainmentMetaData(md) && filter(md); + }; + + return KPackage::PackageLoader::self()->findPackages(QStringLiteral("Plasma/Applet"), QString(), ownFilter); +} + +QList PluginLoader::listContainmentsMetaDataOfType(const QString &type) +{ + auto filter = [type](const KPluginMetaData &md) -> bool { + return md.value(QStringLiteral("X-Plasma-ContainmentType")) == type; + }; + + return listContainmentsMetaData(filter); +} + +QList PluginLoader::listContainmentActionsMetaData(const QString &parentApp) +{ + auto filter = [&parentApp](const KPluginMetaData &md) -> bool { + return md.value(QStringLiteral("X-KDE-ParentApp")) == parentApp; + }; + + QList plugins; + if (parentApp.isEmpty()) { + plugins = KPluginMetaData::findPlugins(QStringLiteral("plasma/containmentactions")); + } else { + plugins = KPluginMetaData::findPlugins(QStringLiteral("plasma/containmentactions"), filter); + } + + return plugins; +} + +} // Plasma Namespace diff --git a/src/plasma/pluginloader.h b/src/plasma/pluginloader.h new file mode 100644 index 0000000..30b57ae --- /dev/null +++ b/src/plasma/pluginloader.h @@ -0,0 +1,146 @@ +/* + SPDX-FileCopyrightText: 2010 Ryan Rix + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLUGIN_LOADER_H +#define PLUGIN_LOADER_H + +#include + +#include + +#include + +class KPluginMetaData; +namespace Plasma +{ +class Applet; +class Containment; +class ContainmentActions; + +// TODO: +// * add loadWallpaper +// * add KPluginInfo listing support for Containments (already loaded via the applet loading code) + +/** + * @class PluginLoader plasma/pluginloader.h + * + * This is an abstract base class which defines an interface to which Plasma's + * Applet Loading logic can communicate with a parent application. The plugin loader + * must be set before any plugins are loaded, otherwise (for safety reasons), the + * default PluginLoader implementation will be used. The reimplemented version should + * not do more than simply returning a loaded plugin. It should not init() it, and it should not + * hang on to it. The associated methods will be called only when a component of Plasma + * needs to load a _new_ plugin. + * + * @author Ryan Rix + * @since 4.6 + **/ +class PLASMA_EXPORT PluginLoader +{ +public: + /** + * Load an Applet plugin. + * + * @param name the plugin name, as returned by KPluginInfo::pluginName() + * @param appletId unique ID to assign the applet, or zero to have one + * assigned automatically. + * @param args to send the applet extra arguments + * @return a pointer to the loaded applet, or 0 on load failure + **/ + Applet *loadApplet(const QString &name, uint appletId = 0, const QVariantList &args = QVariantList()); + + /** + * Load a ContainmentActions plugin. + * + * Returns a pointer to the containmentactions if successful. + * The caller takes responsibility for the containmentactions, including + * deleting it when no longer needed. + * + * @param parent the parent containment. @since 4.6 null is allowed. + * @param name the plugin name, as returned by KPluginInfo::pluginName() + * @param args to send the containmentactions extra arguments + * @return a ContainmentActions object + **/ + ContainmentActions *loadContainmentActions(Containment *parent, const QString &containmentActionsName, const QVariantList &args = QVariantList()); + + /** + * Returns a list of all known applets. + * This may skip applets based on security settings and ExcludeCategories in the application's config. + * + * @param category Only applets matching this category will be returned. + * If "Misc" is passed in, then applets without a + * Categories= entry are also returned. + * If an empty string is passed in, all applets are + * returned. + * @return list of applets + * + * @since 5.28 + **/ + QList listAppletMetaData(const QString &category); + + /** + * Returns a list of all known applets associated with a certain mimetype. + * + * @return list of applets + * @since 5.36 + **/ + QList listAppletMetaDataForMimeType(const QString &mimetype); + + /** + * Returns a list of all known applets associated with a certain URL. + * + * @return list of applets + * @since 5.36 + **/ + QList listAppletMetaDataForUrl(const QUrl &url); + + /** + * Returns a list of all known containments. + * + * @param filter An optional predicate that can be used for filtering. + * + * @return list of containments + */ + static QList listContainmentsMetaData(std::function filter = {}); + + /** + * Returns a list of containments of the specified type. + * + * @param type The target containment type + * + * @return list of containments + */ + static QList listContainmentsMetaDataOfType(const QString &type); + + /** + * Returns a list of all known ContainmentActions. + * + * @param parentApp the application to filter ContainmentActions on. Uses the + * X-KDE-ParentApp entry (if any) in the plugin metadata. + * The default value of QString() will result in a + * list of all ContainmentActions. + * @return list of ContainmentActions + * @since 5.77 + **/ + QList listContainmentActionsMetaData(const QString &parentApp); + + /** + * Return the active plugin loader + **/ + static PluginLoader *self(); + + PluginLoader() = default; + virtual ~PluginLoader() = default; + +private: + void *d; +}; + +} + +Q_DECLARE_METATYPE(Plasma::PluginLoader *) + +#endif diff --git a/src/plasma/private/applet_p.cpp b/src/plasma/private/applet_p.cpp new file mode 100644 index 0000000..ab10645 --- /dev/null +++ b/src/plasma/private/applet_p.cpp @@ -0,0 +1,544 @@ +/* + SPDX-FileCopyrightText: 2005 Aaron Seigo + SPDX-FileCopyrightText: 2007 Riccardo Iaconelli + SPDX-FileCopyrightText: 2008 Ménard Alexis + SPDX-FileCopyrightText: 2009 Chani Armitage + SPDX-FileCopyrightText: 2012 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "private/applet_p.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "containment.h" +#include "corona.h" +#include "debug_p.h" +#include "pluginloader.h" +#include "private/containment_p.h" + +namespace Plasma +{ +AppletPrivate::AppletPrivate(const KPluginMetaData &info, int uniqueID, Applet *applet) + : appletId(uniqueID) + , q(applet) + , immutability(Types::Mutable) + , oldImmutability(Types::Mutable) + , appletDescription(info) + , icon(appletDescription.iconName()) + , mainConfig(nullptr) + , pendingConstraints(Applet::NoConstraint) + , package(nullptr) + , configLoader(nullptr) + , actions(AppletPrivate::defaultActions(applet)) + , activationAction(nullptr) + , itemStatus(Types::UnknownStatus) + , modificationsTimer(nullptr) + , deleteNotificationTimer(nullptr) + , hasConfigurationInterface(false) + , failed(false) + , transient(false) + , needsConfig(false) + , started(false) + , globalShortcutEnabled(false) + , userConfiguring(false) + , busy(false) +{ + if (appletId == 0) { + appletId = ++s_maxAppletId; + } else if (appletId > s_maxAppletId) { + s_maxAppletId = appletId; + } + QObject::connect(actions.value(QStringLiteral("configure")), SIGNAL(triggered()), q, SLOT(requestConfiguration())); + + for (auto it = actions.constBegin(); it != actions.constEnd(); ++it) { + QAction *action = it.value(); + const QString name = it.key(); + QObject::connect(action, &QObject::destroyed, q, [this, name]() { + actions.remove(name); + }); + } +} + +AppletPrivate::~AppletPrivate() +{ + if (deleteNotification) { + deleteNotification->close(); + } + + delete configLoader; + configLoader = nullptr; + delete mainConfig; + mainConfig = nullptr; + delete modificationsTimer; +} + +void AppletPrivate::init(const QVariantList &args) +{ + startupArguments = args; + + // WARNING: do not access config() OR globalConfig() in this method! + // that requires a Corona, which is not available at this point + q->setHasConfigurationInterface(true); + + QAction *closeApplet = actions.value(QStringLiteral("remove")); + if (closeApplet) { + closeApplet->setText(i18nc("%1 is the name of the applet", "Remove %1", q->title())); + } + + QAction *configAction = actions.value(QStringLiteral("configure")); + if (configAction) { + configAction->setText(i18nc("%1 is the name of the applet", "Configure %1...", q->title().replace(QLatin1Char('&'), QStringLiteral("&&")))); + } + + if (!appletDescription.isValid()) { +#ifndef NDEBUG + // qCDebug(LOG_PLASMA) << "Check your constructor! " + // << "You probably want to be passing in a Service::Ptr " + // << "or a QVariantList with a valid storageid as arg[0]."; +#endif + return; + } + + if (!q->isContainment()) { + QAction *a = new QAction(QIcon::fromTheme(QStringLiteral("widget-alternatives")), i18n("Show Alternatives..."), q); + a->setVisible(false); + q->setInternalAction(QStringLiteral("alternatives"), a); + QObject::connect(a, &QAction::triggered, q, [this] { + if (q->containment()) { + Q_EMIT q->containment()->appletAlternativesRequested(q); + } + }); + + QObject::connect(q, &Applet::contextualActionsAboutToShow, a, [=, this]() { + bool hasAlternatives = false; + + const QStringList provides = q->pluginMetaData().value(QStringLiteral("X-Plasma-Provides"), QStringList()); + if (!provides.isEmpty() && q->immutability() == Types::Mutable) { + const auto applets = Plasma::PluginLoader::self()->listAppletMetaData(QString()); + + auto filter = [this, &provides](const KPluginMetaData &md) -> bool { + // Ignore ourselves + if (q->pluginMetaData().pluginId() == md.pluginId()) { + return false; + } + + const QStringList provided = md.value(QStringLiteral("X-Plasma-Provides"), QStringList()); + for (const QString &p : provides) { + if (provided.contains(p)) { + return true; + } + } + return false; + }; + + hasAlternatives = std::any_of(applets.cbegin(), applets.cend(), filter); + } + a->setVisible(hasAlternatives); + }); + } +} + +void AppletPrivate::cleanUpAndDelete() +{ + // reimplemented in the UI specific library + if (configLoader) { + configLoader->clearItems(); + } + + resetConfigurationObject(); + + if (activationAction && globalShortcutEnabled) { + // qCDebug(LOG_PLASMA) << "resetting global action for" << q->title() << activationAction->objectName(); + KGlobalAccel::self()->removeAllShortcuts(activationAction); + } + + if (q->isContainment()) { + // prematurely emit our destruction if we are a Containment, + // giving Corona a chance to remove this Containment from its collection + Q_EMIT q->QObject::destroyed(q); + } + + if (qApp->closingDown()) { + // If we are closing down, the actual delete will be executed when the corona will be destroyed + // which crashes + delete q; + } else { + q->deleteLater(); + } +} + +void AppletPrivate::setDestroyed(bool destroyed) +{ + transient = destroyed; + if (destroyed) { + // If the user was configuring, "destroying" it will also remove access to all configuration ui + q->setUserConfiguring(false); + mainConfig->writeEntry(QStringLiteral("transient"), true); + } else { + mainConfig->deleteEntry(QStringLiteral("transient")); + } + Q_EMIT q->destroyedChanged(destroyed); + // when an applet gets transient, it's "systemimmutable" + Q_EMIT q->immutabilityChanged(q->immutability()); + + Plasma::Containment *asContainment = qobject_cast(q); + if (asContainment) { + const auto lstApplets = asContainment->applets(); + for (Applet *a : lstApplets) { + a->d->setDestroyed(destroyed); + } + } + Q_EMIT q->configNeedsSaving(); +} + +void AppletPrivate::askDestroy() +{ + if (q->immutability() != Types::Mutable || !started) { + return; // don't double delete + } + + if (transient) { + cleanUpAndDelete(); + } else { + // There is no confirmation anymore for panels removal: + // this needs users feedback + setDestroyed(true); + // no parent, but it won't leak, since it will be closed both in case of timeout + // or direct action + deleteNotification = new KNotification(QStringLiteral("plasmoidDeleted")); + deleteNotification->setFlags(KNotification::Persistent | KNotification::SkipGrouping); + + deleteNotification->setComponentName(QStringLiteral("plasma_workspace")); + deleteNotification->setIconName(q->icon()); + Plasma::Containment *asContainment = qobject_cast(q); + + if (!q->isContainment()) { + deleteNotification->setTitle(i18n("Widget Removed")); + deleteNotification->setText(i18n("The widget \"%1\" has been removed.", q->title().toHtmlEscaped())); + } else if (asContainment + && (asContainment->containmentType() == Containment::Type::Panel // + || asContainment->containmentType() == Containment::Type::CustomPanel)) { + deleteNotification->setTitle(i18n("Panel Removed")); + deleteNotification->setText(i18n("A panel has been removed.")); + // This will never happen with our current shell, but could with a custom one + } else { + deleteNotification->setTitle(i18n("Desktop Removed")); + deleteNotification->setText(i18n("A desktop has been removed.")); + } + + KNotificationAction *undoAction = deleteNotification->addAction(i18n("Undo")); + QObject::connect(undoAction, &KNotificationAction::activated, q, [=, this]() { + setDestroyed(false); + if (!q->isContainment() && q->containment()) { + Plasma::Applet *containmentApplet = static_cast(q->containment()); + if (containmentApplet && containmentApplet->d->deleteNotificationTimer) { + Q_EMIT containmentApplet->destroyedChanged(false); + // when an applet gets transient, it's "systemimmutable" + Q_EMIT q->immutabilityChanged(q->immutability()); + delete containmentApplet->d->deleteNotificationTimer; + containmentApplet->d->deleteNotificationTimer = nullptr; + } + + // make sure the applets are sorted by id + auto position = + std::lower_bound(q->containment()->d->applets.begin(), q->containment()->d->applets.end(), q, [](Plasma::Applet *a1, Plasma::Applet *a2) { + return a1->id() < a2->id(); + }); + Q_EMIT q->containment()->appletAboutToBeAdded(q, QRectF()); + q->containment()->d->applets.insert(position, q); + Q_EMIT q->containment()->appletAdded(q, QRectF()); + Q_EMIT q->containment()->appletsChanged(); + } + if (deleteNotification) { + deleteNotification->close(); + } else if (deleteNotificationTimer) { + deleteNotificationTimer->stop(); + deleteNotificationTimer->deleteLater(); + deleteNotificationTimer = nullptr; + } + }); + QObject::connect(deleteNotification.data(), &KNotification::closed, q, [this]() { + // If the timer still exists, it means the undo action was NOT triggered + if (transient) { + cleanUpAndDelete(); + } + if (deleteNotificationTimer) { + deleteNotificationTimer->stop(); + deleteNotificationTimer->deleteLater(); + deleteNotificationTimer = nullptr; + } + }); + + deleteNotification->sendEvent(); + if (!deleteNotificationTimer) { + deleteNotificationTimer = new QTimer(q); + // really delete after a minute + deleteNotificationTimer->setInterval(60 * 1000); + deleteNotificationTimer->setSingleShot(true); + QObject::connect(deleteNotificationTimer, &QTimer::timeout, q, [=, this]() { + transient = true; + if (deleteNotification) { + deleteNotification->close(); + } else { + Q_EMIT q->destroyedChanged(true); + cleanUpAndDelete(); + } + }); + deleteNotificationTimer->start(); + } + if (!q->isContainment() && q->containment()) { + Q_EMIT q->containment()->appletAboutToBeRemoved(q); + q->containment()->d->applets.removeAll(q); + Q_EMIT q->containment()->appletRemoved(q); + Q_EMIT q->containment()->appletsChanged(); + } + } +} + +void AppletPrivate::globalShortcutChanged() +{ + if (!activationAction) { + return; + } + KConfigGroup shortcutConfig(mainConfigGroup(), QStringLiteral("Shortcuts")); + QString newShortCut = activationAction->shortcut().toString(); + QString oldShortCut = shortcutConfig.readEntry("global", QString()); + if (newShortCut != oldShortCut) { + shortcutConfig.writeEntry("global", newShortCut); + scheduleModificationNotification(); + } + // qCDebug(LOG_PLASMA) << "after" << shortcut.primary() << d->activationAction->globalShortcut().primary(); +} + +QMap AppletPrivate::defaultActions(QObject *parent) +{ + QMap actions; + + QAction *configAction = new QAction(parent); + actions[QStringLiteral("configure")] = configAction; + configAction->setAutoRepeat(false); + configAction->setText(i18n("Widget Settings")); + configAction->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); + configAction->setShortcut(QKeySequence(QStringLiteral("alt+d, s"))); + + QAction *closeApplet = new QAction(parent); + actions[QStringLiteral("remove")] = closeApplet; + closeApplet->setAutoRepeat(false); + closeApplet->setText(i18n("Remove this Widget")); + closeApplet->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete"))); + closeApplet->setShortcut(QKeySequence(QStringLiteral("alt+d, r"))); + + return actions; +} + +void AppletPrivate::contextualActions_append(QQmlListProperty *prop, QAction *action) +{ + Applet *a = static_cast(prop->object); + a->d->contextualActions.append(action); + QObject::connect(action, &QObject::destroyed, a, [a, action]() { + if (a->destroyed()) + return; + a->d->contextualActions.removeAll(action); + Q_EMIT a->contextualActionsChanged(a->d->contextualActions); + }); + Q_EMIT a->contextualActionsChanged(a->d->contextualActions); +}; + +qsizetype AppletPrivate::contextualActions_count(QQmlListProperty *prop) +{ + Applet *a = static_cast(prop->object); + return a->d->contextualActions.count(); +} + +QAction *AppletPrivate::contextualActions_at(QQmlListProperty *prop, qsizetype idx) +{ + Applet *a = static_cast(prop->object); + return a->d->contextualActions.value(idx); +} + +void AppletPrivate::contextualActions_clear(QQmlListProperty *prop) +{ + Applet *a = static_cast(prop->object); + a->d->contextualActions.clear(); + Q_EMIT a->contextualActionsChanged(a->d->contextualActions); +} + +void AppletPrivate::contextualActions_replace(QQmlListProperty *prop, qsizetype idx, QAction *action) +{ + Applet *a = static_cast(prop->object); + a->d->contextualActions.replace(idx, action); + QObject::connect(action, &QObject::destroyed, a, [a, action]() { + a->d->contextualActions.removeAll(action); + Q_EMIT a->contextualActionsChanged(a->d->contextualActions); + }); + Q_EMIT a->contextualActionsChanged(a->d->contextualActions); +} + +void AppletPrivate::contextualActions_removeLast(QQmlListProperty *prop) +{ + Applet *a = static_cast(prop->object); + a->d->contextualActions.pop_back(); + Q_EMIT a->contextualActionsChanged(a->d->contextualActions); +} + +void AppletPrivate::requestConfiguration() +{ + if (q->containment()) { + Q_EMIT q->containment()->configureRequested(q); + } +} + +void AppletPrivate::propagateConfigChanged() +{ + Containment *c = qobject_cast(q); + if (c) { + c->d->configChanged(); + } + q->configChanged(); +} + +void AppletPrivate::setUiReady() +{ + // am i the containment? + Containment *c = qobject_cast(q); + if (c && c->isContainment()) { + c->d->setUiReady(); + } else if (Containment *cc = q->containment()) { + cc->d->appletLoaded(q); + } +} + +QString AppletPrivate::globalName() const +{ + if (!appletDescription.isValid()) { + return QString(); + } + + return appletDescription.pluginId(); +} + +void AppletPrivate::scheduleConstraintsUpdate(Applet::Constraints c) +{ + // Don't start up a timer if we're just starting up + // flushPendingConstraints will be called by Corona + if (started && !constraintsTimer.isActive() && !(c & Applet::StartupCompletedConstraint)) { + constraintsTimer.start(0, q); + } + + if (c & Applet::StartupCompletedConstraint) { + started = true; + if (q->isContainment()) { + qobject_cast(q)->d->setStarted(); + } + } + + pendingConstraints |= c; +} + +void AppletPrivate::scheduleModificationNotification() +{ + // modificationsTimer is not allocated until we get our notice of being started + if (modificationsTimer) { + // schedule a save + modificationsTimer->start(1000, q); + } +} + +KConfigGroup *AppletPrivate::mainConfigGroup() +{ + if (mainConfig) { + return mainConfig; + } + + Containment *c = q->containment(); + Plasma::Applet *parentApplet = nullptr; + if (c) { + parentApplet = qobject_cast(c->parent()); + } + + if (q->isContainment()) { + Corona *corona = static_cast(q)->corona(); + KConfigGroup containmentConfig; + // qCDebug(LOG_PLASMA) << "got a corona, baby?" << (QObject*)corona << (QObject*)q; + + if (parentApplet) { + containmentConfig = parentApplet->config(); + containmentConfig = KConfigGroup(&containmentConfig, QStringLiteral("Containments")); + } else if (corona) { + containmentConfig = KConfigGroup(corona->config(), QStringLiteral("Containments")); + } else { + containmentConfig = KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("Containments")); + } + + mainConfig = new KConfigGroup(&containmentConfig, QString::number(appletId)); + } else { + KConfigGroup appletConfig; + + if (c) { + // applet directly in a Containment, as usual + appletConfig = c->config(); + appletConfig = KConfigGroup(&appletConfig, QStringLiteral("Applets")); + } else { + qCDebug(LOG_PLASMA) << "requesting config for" << q->title() << "without a containment!"; + appletConfig = KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("Applets")); + } + + mainConfig = new KConfigGroup(&appletConfig, QString::number(appletId)); + } + + if (configLoader) { + configLoader->setSharedConfig(KSharedConfig::openConfig(mainConfig->config()->name())); + configLoader->load(); + } + + return mainConfig; +} + +void AppletPrivate::resetConfigurationObject() +{ + // make sure mainConfigGroup exists in all cases + mainConfigGroup(); + mainConfig->deleteEntry("plugin"); + mainConfig->deleteEntry("formfactor"); + mainConfig->deleteEntry("immutability"); + mainConfig->deleteEntry("location"); + // if it's not a containment, deleting the non existing activityId entry does nothing + mainConfig->deleteEntry("activityId"); + mainConfig->deleteGroup(); + delete mainConfig; + mainConfig = nullptr; + + Containment *cont = qobject_cast(q); + + if (cont && cont->corona()) { + cont->corona()->requireConfigSync(); + } else { + if (!q->containment()) { + return; + } + Corona *corona = q->containment()->corona(); + if (corona) { + corona->requireConfigSync(); + } + } +} + +uint AppletPrivate::s_maxAppletId = 0; + +} // namespace Plasma diff --git a/src/plasma/private/applet_p.h b/src/plasma/private/applet_p.h new file mode 100644 index 0000000..ec1b073 --- /dev/null +++ b/src/plasma/private/applet_p.h @@ -0,0 +1,125 @@ +/* + SPDX-FileCopyrightText: 2005 Aaron Seigo + SPDX-FileCopyrightText: 2007 Riccardo Iaconelli + SPDX-FileCopyrightText: 2008 Ménard Alexis + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMA_APPLET_P_H +#define PLASMA_APPLET_P_H + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "plasma/applet.h" + +class KKeySequenceWidget; + +namespace Plasma +{ +class Service; + +class AppletPrivate +{ +public: + AppletPrivate(const KPluginMetaData &info, int uniqueID, Applet *applet); + virtual ~AppletPrivate(); + + void init(const QVariantList &args); + + void setDestroyed(bool destroyed); + void askDestroy(); + virtual void cleanUpAndDelete(); + + QString globalName() const; + void scheduleConstraintsUpdate(Applet::Constraints c); + void scheduleModificationNotification(); + KConfigGroup *mainConfigGroup(); + void resetConfigurationObject(); + void globalShortcutChanged(); + void propagateConfigChanged(); + void setUiReady(); + + static QMap defaultActions(QObject *parent); + + static void contextualActions_append(QQmlListProperty *prop, QAction *action); + static qsizetype contextualActions_count(QQmlListProperty *prop); + static QAction *contextualActions_at(QQmlListProperty *prop, qsizetype idx); + static void contextualActions_clear(QQmlListProperty *prop); + static void contextualActions_replace(QQmlListProperty *prop, qsizetype idx, QAction *action); + static void contextualActions_removeLast(QQmlListProperty *prop); + + void requestConfiguration(); + + static uint s_maxAppletId; + + uint appletId; + Applet *q; + + // applet attributes + Types::ImmutabilityType immutability; + Types::ImmutabilityType oldImmutability; + QString launchErrorMessage; + + // applet info we keep around in case its needed + KPluginMetaData appletDescription; + QString customTitle; + QString icon; + + QVariantList startupArguments; + + // bookkeeping + KConfigGroup *mainConfig; + Applet::Constraints pendingConstraints; + + // config and package stuff + KPackage::Package package; + KConfigLoader *configLoader = nullptr; + KConfigPropertyMap *configPropertyMap = nullptr; + + // It's a map to have values() as a stable list + QMap actions; + QList contextualActions; + QAction *activationAction; + QHash actionGroups; + + Types::ItemStatus itemStatus; + + // timerEvent bookkeeping + QBasicTimer constraintsTimer; + QBasicTimer *modificationsTimer; + + QPointer deleteNotification; + QTimer *deleteNotificationTimer; + + QString configurationRequiredReason; + + Types::BackgroundHints backgroundHints = Types::DefaultBackground; + Types::BackgroundHints userBackgroundHints = Types::DefaultBackground; + Applet::ConstraintHints constraintHints = Applet::NoHint; + + // a great green field of booleans :) + bool userBackgroundHintsInitialized = false; + bool hasConfigurationInterface : 1; + bool failed : 1; + bool transient : 1; + bool needsConfig : 1; + bool started : 1; + bool globalShortcutEnabled : 1; + bool userConfiguring : 1; + bool busy : 1; +}; + +} // Plasma namespace + +#endif diff --git a/src/plasma/private/containment_p.cpp b/src/plasma/private/containment_p.cpp new file mode 100644 index 0000000..3b2721b --- /dev/null +++ b/src/plasma/private/containment_p.cpp @@ -0,0 +1,257 @@ +/* + SPDX-FileCopyrightText: 2007 Aaron Seigo + SPDX-FileCopyrightText: 2008 Ménard Alexis + SPDX-FileCopyrightText: 2009 Chani Armitage + SPDX-FileCopyrightText: 2012 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "private/containment_p.h" + +#include +#include + +#include "config-plasma.h" + +#include "pluginloader.h" + +#include + +#include "debug_p.h" +#include "private/applet_p.h" + +namespace Plasma +{ +const char ContainmentPrivate::defaultWallpaperPlugin[] = "org.kde.image"; + +ContainmentPrivate::ContainmentPrivate(Containment *c) + : q(c) + , formFactor(Types::Planar) + , location(Types::Floating) + , lastScreen(-1) + , type(Plasma::Containment::Type::NoContainment) // never had a screen + , uiReady(false) + , appletsUiReady(false) +{ + // if the parent is an applet (i.e we are the systray) + // we want to follow screen changed signals from the parent's containment + auto appletParent = qobject_cast(c->parent()); + if (appletParent) { + QObject::connect(appletParent->containment(), &Containment::screenChanged, c, &Containment::screenChanged); + } + activityInfo = new KActivities::Info(activityId, q); + QObject::connect(activityInfo, &KActivities::Info::nameChanged, q, &Containment::activityNameChanged); +} + +Plasma::ContainmentPrivate::~ContainmentPrivate() +{ + applets.clear(); +} + +void ContainmentPrivate::addDefaultActions(QMap &actions, Containment *c, Corona *cor) +{ + // adjust applet actions + QAction *appAction = actions.value(QStringLiteral("remove")); + appAction->setShortcut(QKeySequence(Qt::ALT | Qt::Key_D, Qt::ALT | Qt::Key_R)); + if (c && c->d->isPanelContainment()) { + appAction->setText(i18n("Remove this Panel")); + } else { + appAction->setText(i18n("Remove this Activity")); + } + + appAction = actions.value(QStringLiteral("configure")); + if (appAction) { + appAction->setShortcut(QKeySequence(Qt::ALT | Qt::Key_D, Qt::ALT | Qt::Key_S)); + appAction->setText(i18n("Activity Settings")); + } + + // add our own actions + QAction *appletBrowserAction; + if (c) { + appletBrowserAction = new QAction(c); + } else { + appletBrowserAction = new QAction(cor); + } + actions[QStringLiteral("add widgets")] = appletBrowserAction; + appletBrowserAction->setAutoRepeat(false); + appletBrowserAction->setText(i18n("Add or Manage Widgets…")); + appletBrowserAction->setIcon(QIcon::fromTheme(QStringLiteral("view-group-symbolic"))); + appletBrowserAction->setShortcut(QKeySequence(Qt::ALT | Qt::Key_D, Qt::Key_A)); + + if (c) { + static_cast(c)->d->actions.insert(actions); + } +} + +KConfigGroup ContainmentPrivate::containmentActionsConfig() const +{ + KConfigGroup cfg = KConfigGroup(q->corona()->config(), QStringLiteral("ActionPlugins")); + return KConfigGroup(&cfg, QString::number((int)type)); +} + +void ContainmentPrivate::configChanged() +{ + KConfigGroup group = q->config(); + q->setWallpaperPlugin(group.readEntry("wallpaperplugin", defaultWallpaperPlugin)); +} + +void ContainmentPrivate::checkStatus(Plasma::Types::ItemStatus appletStatus) +{ + // qCDebug(LOG_PLASMA) << "================== "<< appletStatus << q->status(); + if (appletStatus == q->status()) { + return; + } + + if (appletStatus < q->status() || appletStatus == Plasma::Types::HiddenStatus) { + // check to see if any other applet has a higher status, and stick with that if we do + // we'll treat HiddenStatus as lowest as we cannot change the enum value which is highest anymore + for (Applet *applet : std::as_const(applets)) { + if (applet->status() > appletStatus && applet->status() != Plasma::Types::HiddenStatus) { + appletStatus = applet->status(); + } + } + } + + if (appletStatus != Plasma::Types::HiddenStatus) { + q->setStatus(appletStatus); + } +} + +void ContainmentPrivate::triggerShowAddWidgets() +{ + Q_EMIT q->showAddWidgetsInterface(QPointF()); +} + +void ContainmentPrivate::containmentConstraintsEvent(Applet::Constraints constraints) +{ + if (!q->isContainment()) { + return; + } + + // qCDebug(LOG_PLASMA) << "got containmentConstraintsEvent" << constraints; + if (constraints & Applet::ImmutableConstraint) { + // update actions + const bool unlocked = q->immutability() == Types::Mutable; + + QAction *action = q->internalAction(QStringLiteral("remove")); + if (action) { + action->setEnabled(unlocked); + action->setVisible(unlocked); + } + + action = q->internalAction(QStringLiteral("add widgets")); + if (action) { + action->setEnabled(unlocked); + action->setVisible(unlocked); + } + + // tell the applets too + for (Applet *a : std::as_const(applets)) { + /*Why qMin? + * the applets immutability() is the maximum between internal applet immutability + * and the immutability of its containment. + * so not set higher immutability in the internal member of Applet + * or the applet will not be able to be unlocked properly + */ + a->setImmutability(qMin(q->immutability(), a->d->immutability)); + a->updateConstraints(Applet::ImmutableConstraint); + } + } + + // pass on the constraints that are relevant here + Applet::Constraints appletConstraints = Applet::NoConstraint; + if (constraints & Applet::FormFactorConstraint) { + appletConstraints |= Applet::FormFactorConstraint; + } + + if (constraints & Applet::ScreenConstraint) { + appletConstraints |= Applet::ScreenConstraint; + } + + if (appletConstraints != Applet::NoConstraint) { + for (Applet *applet : std::as_const(applets)) { + applet->updateConstraints(appletConstraints); + } + } +} + +Applet *ContainmentPrivate::createApplet(const QString &name, const QVariantList &args, uint id, const QRectF &geometryHint) +{ + if (!q->isContainment()) { + return nullptr; + } + + if (q->immutability() != Types::Mutable && !args.contains(QVariant::fromValue(QStringLiteral("org.kde.plasma:force-create")))) { +#ifndef NDEBUG + // qCDebug(LOG_PLASMA) << "addApplet for" << name << "requested, but we're currently immutable!"; +#endif + return nullptr; + } + + Applet *applet = PluginLoader::self()->loadApplet(name, id, args); + + if (!applet) { + qCWarning(LOG_PLASMA) << "Applet" << name << "could not be loaded."; + applet = new Applet(nullptr, KPluginMetaData(), QVariantList{QVariant(), id}); + applet->setLaunchErrorMessage(i18n("Could not find requested component: %1", name)); + } + + q->addApplet(applet, geometryHint); + // mirror behavior of resorecontents: if an applet is not valid, set it immediately to uiReady + if (!applet->pluginMetaData().isValid()) { + applet->updateConstraints(Applet::UiReadyConstraint); + } + return applet; +} + +void ContainmentPrivate::appletDeleted(Plasma::Applet *applet) +{ + Q_EMIT q->appletAboutToBeRemoved(applet); + applets.removeAll(applet); + + Q_EMIT q->appletRemoved(applet); + Q_EMIT q->appletsChanged(); + Q_EMIT q->configNeedsSaving(); +} + +bool ContainmentPrivate::isPanelContainment() const +{ + return type == Plasma::Containment::Type::Panel || type == Plasma::Containment::Type::CustomPanel; +} + +void ContainmentPrivate::setStarted() +{ + if (!q->Applet::d->started) { + q->Applet::d->started = true; + + if (uiReady) { + Q_EMIT q->uiReadyChanged(true); + } + } +} + +void ContainmentPrivate::setUiReady() +{ + // if we are the containment and there is still some incomplete applet, we're still incomplete + if (!uiReady) { + uiReady = true; + if (q->Applet::d->started && (appletsUiReady || applets.isEmpty()) && loadingApplets.isEmpty()) { + Q_EMIT q->uiReadyChanged(true); + } + } +} + +void ContainmentPrivate::appletLoaded(Applet *applet) +{ + loadingApplets.remove(applet); + + if (loadingApplets.isEmpty() && !appletsUiReady) { + appletsUiReady = true; + if (q->Applet::d->started && uiReady) { + Q_EMIT q->uiReadyChanged(true); + } + } +} + +} diff --git a/src/plasma/private/containment_p.h b/src/plasma/private/containment_p.h new file mode 100644 index 0000000..d8f1705 --- /dev/null +++ b/src/plasma/private/containment_p.h @@ -0,0 +1,95 @@ +/* + SPDX-FileCopyrightText: 2007 Aaron Seigo + SPDX-FileCopyrightText: 2008 Ménard Alexis + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef CONTAINMENT_P_H +#define CONTAINMENT_P_H + +#include + +#include "applet.h" +#include "containmentactions.h" +#include "corona.h" +#include "plasma.h" + +class KJob; + +namespace KIO +{ +class Job; +} + +namespace KActivities +{ +class Info; +} + +namespace Plasma +{ +class Containment; + +class ContainmentPrivate +{ +public: + ContainmentPrivate(Containment *c); + ~ContainmentPrivate(); + + void triggerShowAddWidgets(); + void checkStatus(Plasma::Types::ItemStatus status); + + /** + * Called when constraints have been updated on this containment to provide + * constraint services common to all containments. Containments should still + * implement their own constraintsEvent method + */ + void containmentConstraintsEvent(Applet::Constraints constraints); + + bool isPanelContainment() const; + void appletDeleted(Applet *); + void configChanged(); + + Applet *createApplet(const QString &name, const QVariantList &args = QVariantList(), uint id = 0, const QRectF &geometryHint = QRectF(-1, -1, 0, 0)); + + /** + * FIXME: this should completely go from here + * @return the config group that containmentactions plugins go in + * @since 4.6 + */ + KConfigGroup containmentActionsConfig() const; + + /** + * add the regular actions & keyboard shortcuts onto Applet's collection + */ + static void addDefaultActions(QMap &actions, Containment *c = nullptr, Corona *cor = nullptr); + + void setUiReady(); + void setStarted(); + void appletLoaded(Applet *applet); + + Containment *q; + Types::FormFactor formFactor; + Types::Location location; + Types::ContainmentDisplayHints containmentDisplayHints = Types::NoContainmentDisplayHint; + + KActivities::Info *activityInfo; + QList applets; + // Applets still considered not ready + QSet loadingApplets; + QString wallpaperPlugin; + QObject *wallpaperGraphicsObject = nullptr; + QHash localActionPlugins; + int lastScreen; + QString activityId; + Containment::Type type; + bool uiReady : 1; + bool appletsUiReady : 1; + + static const char defaultWallpaperPlugin[]; +}; + +} // Plasma namespace + +#endif diff --git a/src/plasma/private/containmentactions_p.h b/src/plasma/private/containmentactions_p.h new file mode 100644 index 0000000..5fcdbb1 --- /dev/null +++ b/src/plasma/private/containmentactions_p.h @@ -0,0 +1,28 @@ +/* + SPDX-FileCopyrightText: 2009 Chani Armitage + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMA_CONTAINMENTACTIONSPRIVATE_H +#define PLASMA_CONTAINMENTACTIONSPRIVATE_H + +#include + +namespace Plasma +{ + +class ContainmentActionsPrivate +{ +public: + ContainmentActionsPrivate(const QVariant &arg, ContainmentActions * /*containmentActions*/) + : containmentActionsDescription(arg.value()) + { + } + + const KPluginMetaData containmentActionsDescription; + Containment *containment = nullptr; +}; + +} // namespace Plasma +#endif // PLASMA_CONTAINMENTACTIONSPRIVATE_H diff --git a/src/plasma/private/corona_p.h b/src/plasma/private/corona_p.h new file mode 100644 index 0000000..6017131 --- /dev/null +++ b/src/plasma/private/corona_p.h @@ -0,0 +1,51 @@ +/* + SPDX-FileCopyrightText: 2007-2011 Aaron Seigo + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMA_CORONA_P_H +#define PLASMA_CORONA_P_H + +#include + +#include + +namespace Plasma +{ +class Containment; + +class CoronaPrivate +{ +public: + CoronaPrivate(Corona *corona); + ~CoronaPrivate(); + + void init(); + void toggleImmutability(); + void saveLayout(KSharedConfigPtr cg) const; + void updateContainmentImmutability(); + void containmentDestroyed(QObject *obj); + void syncConfig(); + void notifyContainmentsReady(); + void containmentReady(bool ready); + Containment *addContainment(const QString &name, const QVariantList &args, uint id, int lastScreen, bool delayedInit = false); + QList importLayout(const KConfigGroup &conf, bool mergeConfig); + + Corona *q; + KPackage::Package package; + KConfigGroup desktopDefaultsConfig; + Types::ImmutabilityType immutability; + QString configName; + KSharedConfigPtr config; + QTimer *configSyncTimer; + QList containments; + // It's a map to have values() as a stable list + QMap actions; + int containmentsStarting; + bool editMode = false; +}; + +} + +#endif diff --git a/src/plasma/private/effectwatcher.cpp b/src/plasma/private/effectwatcher.cpp new file mode 100644 index 0000000..896c883 --- /dev/null +++ b/src/plasma/private/effectwatcher.cpp @@ -0,0 +1,93 @@ +/* + SPDX-FileCopyrightText: 2011 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "effectwatcher_p.h" + +#include + +namespace Plasma +{ +EffectWatcher::EffectWatcher(const QString &property, QObject *parent) + : QObject(parent) + , m_property(XCB_ATOM_NONE) + , m_x11Interface(qGuiApp->nativeInterface()) +{ + init(property); +} + +void EffectWatcher::init(const QString &property) +{ + if (!m_x11Interface) { + return; + } + QCoreApplication::instance()->installNativeEventFilter(this); + + xcb_connection_t *c = m_x11Interface->connection(); + const QByteArray propertyName = property.toLatin1(); + xcb_intern_atom_cookie_t atomCookie = xcb_intern_atom_unchecked(c, false, propertyName.length(), propertyName.constData()); + xcb_get_window_attributes_cookie_t winAttrCookie = xcb_get_window_attributes_unchecked(c, DefaultRootWindow(m_x11Interface->display())); + + QScopedPointer atom(xcb_intern_atom_reply(c, atomCookie, nullptr)); + if (!atom.isNull()) { + m_property = atom->atom; + } + m_effectActive = isEffectActive(); + + QScopedPointer attrs(xcb_get_window_attributes_reply(c, winAttrCookie, nullptr)); + if (!attrs.isNull()) { + uint32_t events = attrs->your_event_mask | XCB_EVENT_MASK_PROPERTY_CHANGE; + xcb_change_window_attributes(c, DefaultRootWindow(m_x11Interface->display()), XCB_CW_EVENT_MASK, &events); + } +} + +bool EffectWatcher::nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) +{ + Q_UNUSED(result); + // A faster comparison than eventType != "xcb_generic_event_t" + // given that eventType can only have the following values: + // "xcb_generic_event_t", "windows_generic_MSG" and "mac_generic_NSEvent" + // According to https://doc.qt.io/qt-5/qabstractnativeeventfilter.html + if (eventType[0] != 'x') { + return false; + } + xcb_generic_event_t *event = reinterpret_cast(message); + uint response_type = event->response_type & ~0x80; + if (response_type != XCB_PROPERTY_NOTIFY || m_property == XCB_ATOM_NONE) { + return false; + } + + xcb_property_notify_event_t *prop_event = reinterpret_cast(event); + if (prop_event->atom == m_property) { + bool nowEffectActive = isEffectActive(); + if (m_effectActive != nowEffectActive) { + m_effectActive = nowEffectActive; + Q_EMIT effectChanged(m_effectActive); + } + } + return false; +} + +bool EffectWatcher::isEffectActive() const +{ + if (m_property == XCB_ATOM_NONE || !m_x11Interface) { + return false; + } + xcb_connection_t *c = m_x11Interface->connection(); + xcb_list_properties_cookie_t propsCookie = xcb_list_properties_unchecked(c, DefaultRootWindow(m_x11Interface->display())); + QScopedPointer props(xcb_list_properties_reply(c, propsCookie, nullptr)); + if (props.isNull()) { + return false; + } + xcb_atom_t *atoms = xcb_list_properties_atoms(props.data()); + for (int i = 0; i < props->atoms_len; ++i) { + if (atoms[i] == m_property) { + return true; + } + } + return false; +} + +} // namespace Plasma diff --git a/src/plasma/private/effectwatcher_p.h b/src/plasma/private/effectwatcher_p.h new file mode 100644 index 0000000..2253604 --- /dev/null +++ b/src/plasma/private/effectwatcher_p.h @@ -0,0 +1,42 @@ +/* + SPDX-FileCopyrightText: 2011 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef EFFECTWATCHER_P_H +#define EFFECTWATCHER_P_H + +#include +#include + +#include + +#include + +namespace Plasma +{ +class EffectWatcher : public QObject, public QAbstractNativeEventFilter +{ + Q_OBJECT + +public: + explicit EffectWatcher(const QString &property, QObject *parent = nullptr); + +protected: + bool isEffectActive() const; + bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *) override; + +Q_SIGNALS: + void effectChanged(bool on); + +private: + void init(const QString &property); + xcb_atom_t m_property; + bool m_effectActive; + QNativeInterface::QX11Application *m_x11Interface = nullptr; +}; + +} // namespace Plasma + +#endif diff --git a/src/plasma/private/theme_p.cpp b/src/plasma/private/theme_p.cpp new file mode 100644 index 0000000..7bc5998 --- /dev/null +++ b/src/plasma/private/theme_p.cpp @@ -0,0 +1,704 @@ +/* + SPDX-FileCopyrightText: 2006-2007 Aaron Seigo + SPDX-FileCopyrightText: 2013 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "theme_p.h" +#include "debug_p.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Plasma +{ +const char ThemePrivate::defaultTheme[] = "default"; +const char ThemePrivate::themeRcFile[] = "plasmarc"; +// the system colors theme is used to cache unthemed svgs with colorization needs +// these svgs do not follow the theme's colors, but rather the system colors +const char ThemePrivate::systemColorsTheme[] = "internal-system-colors"; +#if HAVE_X11 +EffectWatcher *ThemePrivate::s_backgroundContrastEffectWatcher = nullptr; +#endif + +ThemePrivate *ThemePrivate::globalTheme = nullptr; +QHash ThemePrivate::themes = QHash(); +using QSP = QStandardPaths; + +KSharedConfig::Ptr configForTheme(const QString &theme) +{ + const QString baseName = QLatin1String(PLASMA_RELATIVE_DATA_INSTALL_DIR "/desktoptheme/") % theme; + QString configPath = QSP::locate(QSP::GenericDataLocation, baseName + QLatin1String("/plasmarc")); + if (!configPath.isEmpty()) { + return KSharedConfig::openConfig(configPath, KConfig::SimpleConfig); + } + // Because we have dektop file compat code further below too, this is still needed in KF6 + QString metadataPath = QSP::locate(QSP::GenericDataLocation, baseName + QLatin1String("/metadata.desktop")); + return KSharedConfig::openConfig(metadataPath, KConfig::SimpleConfig); +} + +KPluginMetaData metaDataForTheme(const QString &theme) +{ + const QString packageBasePath = + QSP::locate(QSP::GenericDataLocation, QLatin1String(PLASMA_RELATIVE_DATA_INSTALL_DIR "/desktoptheme/") % theme, QSP::LocateDirectory); + if (packageBasePath.isEmpty()) { + qWarning(LOG_PLASMA) << "Could not locate plasma theme" << theme << "in" << PLASMA_RELATIVE_DATA_INSTALL_DIR "/desktoptheme/" + << "using search path" << QSP::standardLocations(QSP::GenericDataLocation); + return {}; + } + if (QFileInfo::exists(packageBasePath + QLatin1String("/metadata.json"))) { + return KPluginMetaData::fromJsonFile(packageBasePath + QLatin1String("/metadata.json")); + } else if (QFileInfo::exists(packageBasePath + QLatin1String("/metadata.desktop"))) { + QString metadataPath = packageBasePath + QLatin1String("/metadata.desktop"); + KConfigGroup cg(KSharedConfig::openConfig(packageBasePath + QLatin1String("/metadata.desktop"), KConfig::SimpleConfig), + QStringLiteral("Desktop Entry")); + QJsonObject obj = {}; + for (const QString &key : cg.keyList()) { + obj[key] = cg.readEntry(key); + } + qWarning(LOG_PLASMA) << "The theme" << theme + << "uses the legacy metadata.desktop. Consider contacting the author and asking them update it to use the newer JSON format."; + return KPluginMetaData(obj, packageBasePath + QLatin1String("/metadata.desktop")); + } else { + qCWarning(LOG_PLASMA) << "Could not locate metadata for theme" << theme; + return {}; + } +} + +ThemePrivate::ThemePrivate(QObject *parent) + : QObject(parent) + , colorScheme(QPalette::Active, KColorScheme::Window, KSharedConfigPtr(nullptr)) + , selectionColorScheme(QPalette::Active, KColorScheme::Selection, KSharedConfigPtr(nullptr)) + , buttonColorScheme(QPalette::Active, KColorScheme::Button, KSharedConfigPtr(nullptr)) + , viewColorScheme(QPalette::Active, KColorScheme::View, KSharedConfigPtr(nullptr)) + , complementaryColorScheme(QPalette::Active, KColorScheme::Complementary, KSharedConfigPtr(nullptr)) + , headerColorScheme(QPalette::Active, KColorScheme::Header, KSharedConfigPtr(nullptr)) + , tooltipColorScheme(QPalette::Active, KColorScheme::Tooltip, KSharedConfigPtr(nullptr)) + , defaultWallpaperTheme(QStringLiteral(DEFAULT_WALLPAPER_THEME)) + , defaultWallpaperSuffix(QStringLiteral(DEFAULT_WALLPAPER_SUFFIX)) + , defaultWallpaperWidth(DEFAULT_WALLPAPER_WIDTH) + , defaultWallpaperHeight(DEFAULT_WALLPAPER_HEIGHT) + , cacheSize(0) + , cachesToDiscard(NoCache) + , compositingActive(true) + , backgroundContrastActive(KWindowEffects::isEffectAvailable(KWindowEffects::BackgroundContrast)) + , isDefault(true) + , useGlobal(true) + , hasWallpapers(false) + , fixedName(false) + , backgroundContrast(qQNaN()) + , backgroundIntensity(qQNaN()) + , backgroundSaturation(qQNaN()) + , backgroundContrastEnabled(true) + , adaptiveTransparencyEnabled(false) + , blurBehindEnabled(true) + , apiMajor(1) + , apiMinor(0) + , apiRevision(0) +{ + if (KWindowSystem::isPlatformX11()) { + compositingActive = KX11Extras::self()->compositingActive(); + } + + ThemeConfig config; + cacheTheme = config.cacheTheme(); + kSvgImageSet = std::unique_ptr(new KSvg::ImageSet); + kSvgImageSet->setBasePath(QStringLiteral(PLASMA_RELATIVE_DATA_INSTALL_DIR "/desktoptheme/")); + + pixmapSaveTimer = new QTimer(this); + pixmapSaveTimer->setSingleShot(true); + pixmapSaveTimer->setInterval(600); + QObject::connect(pixmapSaveTimer, &QTimer::timeout, this, &ThemePrivate::scheduledCacheUpdate); + + updateNotificationTimer = new QTimer(this); + updateNotificationTimer->setSingleShot(true); + updateNotificationTimer->setInterval(100); + QObject::connect(updateNotificationTimer, &QTimer::timeout, this, &ThemePrivate::notifyOfChanged); + + if (QPixmap::defaultDepth() > 8) { +#if HAVE_X11 + // watch for background contrast effect property changes as well + if (!s_backgroundContrastEffectWatcher) { + s_backgroundContrastEffectWatcher = new EffectWatcher(QStringLiteral("_KDE_NET_WM_BACKGROUND_CONTRAST_REGION")); + } + + QObject::connect(s_backgroundContrastEffectWatcher, &EffectWatcher::effectChanged, this, [this](bool active) { + if (backgroundContrastActive != active) { + backgroundContrastActive = active; + scheduleThemeChangeNotification(PixmapCache | SvgElementsCache); + kSvgImageSet->setSelectors({QStringLiteral("translucent")}); + } + }); +#endif + } + QCoreApplication::instance()->installEventFilter(this); + + const QString configFile = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1Char('/') + QLatin1String(themeRcFile); + KDirWatch::self()->addFile(configFile); + + // Catch both, direct changes to the config file ... + connect(KDirWatch::self(), &KDirWatch::dirty, this, &ThemePrivate::settingsFileChanged); + // ... but also remove/recreate cycles, like KConfig does it + connect(KDirWatch::self(), &KDirWatch::created, this, &ThemePrivate::settingsFileChanged); + + QObject::connect(KIconLoader::global(), &KIconLoader::iconChanged, this, [this]() { + scheduleThemeChangeNotification(PixmapCache | SvgElementsCache); + }); + + if (KWindowSystem::isPlatformX11()) { + connect(KX11Extras::self(), &KX11Extras::compositingChanged, this, &ThemePrivate::compositingChanged); + compositingChanged(KX11Extras::compositingActive()); + } +} + +ThemePrivate::~ThemePrivate() +{ +} + +KConfigGroup &ThemePrivate::config() +{ + if (!cfg.isValid()) { + QString groupName = QStringLiteral("Theme"); + + if (!useGlobal) { + QString app = QCoreApplication::applicationName(); + + if (!app.isEmpty()) { +#ifndef NDEBUG + // qCDebug(LOG_PLASMA) << "using theme for app" << app; +#endif + groupName.append(QLatin1Char('-')).append(app); + } + } + cfg = KConfigGroup(KSharedConfig::openConfig(QFile::decodeName(themeRcFile)), groupName); + } + + return cfg; +} + +bool ThemePrivate::useCache() +{ + bool cachesTooOld = false; + + if (cacheTheme) { + if (cacheSize == 0) { + ThemeConfig config; + cacheSize = config.themeCacheKb(); + } + const bool isRegularTheme = themeName != QLatin1String(systemColorsTheme); + QString cacheFile = QLatin1String("plasma_theme_") + themeName; + + // clear any cached values from the previous theme cache + themeVersion.clear(); + + if (!themeMetadataPath.isEmpty()) { + KDirWatch::self()->removeFile(themeMetadataPath); + } + themeMetadataPath = configForTheme(themeName)->name(); + if (isRegularTheme) { + const auto *iconTheme = KIconLoader::global()->theme(); + if (iconTheme) { + iconThemeMetadataPath = iconTheme->dir() + QStringLiteral("index.theme"); + } + + const QString cacheFileBase = cacheFile + QLatin1String("*.kcache"); + + QString currentCacheFileName; + if (!themeMetadataPath.isEmpty()) { + // now we record the theme version, if we can + const KPluginMetaData data = metaDataForTheme(themeName); + if (data.isValid()) { + themeVersion = data.version(); + } + if (!themeVersion.isEmpty()) { + cacheFile += QLatin1String("_v") + themeVersion; + currentCacheFileName = cacheFile + QLatin1String(".kcache"); + } + + // watch the metadata file for changes at runtime + KDirWatch::self()->addFile(themeMetadataPath); + QObject::connect(KDirWatch::self(), &KDirWatch::created, this, &ThemePrivate::settingsFileChanged, Qt::UniqueConnection); + QObject::connect(KDirWatch::self(), &KDirWatch::dirty, this, &ThemePrivate::settingsFileChanged, Qt::UniqueConnection); + + if (!iconThemeMetadataPath.isEmpty()) { + KDirWatch::self()->addFile(iconThemeMetadataPath); + } + } + + // now we check for, and remove if necessary, old caches + QDir cacheDir(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation)); + cacheDir.setNameFilters(QStringList({cacheFileBase})); + + const auto files = cacheDir.entryInfoList(); + for (const QFileInfo &file : files) { + if (currentCacheFileName.isEmpty() // + || !file.absoluteFilePath().endsWith(currentCacheFileName)) { + QFile::remove(file.absoluteFilePath()); + } + } + } + + // now we do a sanity check: if the metadata.desktop file is newer than the cache, drop the cache + if (isRegularTheme && !themeMetadataPath.isEmpty()) { + // now we check to see if the theme metadata file itself is newer than the pixmap cache + // this is done before creating the pixmapCache object since that can change the mtime + // on the cache file + + // FIXME: when using the system colors, if they change while the application is not running + // the cache should be dropped; we need a way to detect system color change when the + // application is not running. + // check for expired cache + const QString cacheFilePath = + QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QLatin1Char('/') + cacheFile + QLatin1String(".kcache"); + if (!cacheFilePath.isEmpty()) { + const QFileInfo cacheFileInfo(cacheFilePath); + const QFileInfo metadataFileInfo(themeMetadataPath); + const QFileInfo iconThemeMetadataFileInfo(iconThemeMetadataPath); + + cachesTooOld = (cacheFileInfo.lastModified().toSecsSinceEpoch() < metadataFileInfo.lastModified().toSecsSinceEpoch()) + || (cacheFileInfo.lastModified().toSecsSinceEpoch() < iconThemeMetadataFileInfo.lastModified().toSecsSinceEpoch()); + } + } + + ThemeConfig config; + + if (cachesTooOld) { + discardCache(PixmapCache | SvgElementsCache); + } + } + + if (cacheTheme) { + QString currentIconThemePath; + const auto *iconTheme = KIconLoader::global()->theme(); + if (iconTheme) { + currentIconThemePath = iconTheme->dir(); + } + } + + return cacheTheme; +} + +void ThemePrivate::onAppExitCleanup() +{ + cacheTheme = false; +} + +QString ThemePrivate::imagePath(const QString &theme, const QString &type, const QString &image) +{ + QString subdir = QLatin1String(PLASMA_RELATIVE_DATA_INSTALL_DIR "/desktoptheme/") % theme % type % image; + return QStandardPaths::locate(QStandardPaths::GenericDataLocation, subdir); +} + +QString ThemePrivate::findInTheme(const QString &image, const QString &theme, bool cache) +{ + if (cache) { + auto it = discoveries.constFind(image); + if (it != discoveries.constEnd()) { + return it.value(); + } + } + + QString type = QStringLiteral("/"); + if (!compositingActive) { + type = QStringLiteral("/opaque/"); + } else if (backgroundContrastActive) { + type = QStringLiteral("/translucent/"); + } + + QString search = imagePath(theme, type, image); + + // not found or compositing enabled + if (search.isEmpty()) { + search = imagePath(theme, QStringLiteral("/"), image); + } + + if (cache && !search.isEmpty()) { + discoveries.insert(image, search); + } + + return search; +} + +void ThemePrivate::compositingChanged(bool active) +{ +#if HAVE_X11 + if (compositingActive != active) { + compositingActive = active; + // qCDebug(LOG_PLASMA) << QTime::currentTime(); + scheduleThemeChangeNotification(PixmapCache | SvgElementsCache); + if (active) { + kSvgImageSet->setSelectors({}); + } else { + kSvgImageSet->setSelectors({QStringLiteral("opaque")}); + } + } +#endif +} + +void ThemePrivate::discardCache(CacheTypes caches) +{ + if (caches & SvgElementsCache) { + discoveries.clear(); + } +} + +void ThemePrivate::scheduledCacheUpdate() +{ +} + +void ThemePrivate::colorsChanged() +{ + // in the case the theme follows the desktop settings, refetch the colorschemes + // and discard the svg pixmap cache + if (colors != nullptr) { + colors->reparseConfiguration(); + } else { + KSharedConfig::openConfig()->reparseConfiguration(); + } + colorScheme = KColorScheme(QPalette::Active, KColorScheme::Window, colors); + buttonColorScheme = KColorScheme(QPalette::Active, KColorScheme::Button, colors); + viewColorScheme = KColorScheme(QPalette::Active, KColorScheme::View, colors); + selectionColorScheme = KColorScheme(QPalette::Active, KColorScheme::Selection, colors); + complementaryColorScheme = KColorScheme(QPalette::Active, KColorScheme::Complementary, colors); + headerColorScheme = KColorScheme(QPalette::Active, KColorScheme::Header, colors); + tooltipColorScheme = KColorScheme(QPalette::Active, KColorScheme::Tooltip, colors); + palette = KColorScheme::createApplicationPalette(colors); + scheduleThemeChangeNotification(PixmapCache | SvgElementsCache); + Q_EMIT applicationPaletteChange(); +} + +void ThemePrivate::scheduleThemeChangeNotification(CacheTypes caches) +{ + cachesToDiscard |= caches; + updateNotificationTimer->start(); +} + +void ThemePrivate::notifyOfChanged() +{ + // qCDebug(LOG_PLASMA) << cachesToDiscard; + discardCache(cachesToDiscard); + cachesToDiscard = NoCache; + Q_EMIT themeChanged(); +} + +void ThemePrivate::settingsFileChanged(const QString &file) +{ + qCDebug(LOG_PLASMA) << "settingsFile: " << file; + if (file == themeMetadataPath) { + const KPluginMetaData data = metaDataForTheme(themeName); + if (!data.isValid() || themeVersion != data.version()) { + scheduleThemeChangeNotification(SvgElementsCache); + } + } else if (file.endsWith(QLatin1String(themeRcFile))) { + config().config()->reparseConfiguration(); + settingsChanged(true); + } +} + +void ThemePrivate::settingsChanged(bool emitChanges) +{ + if (fixedName) { + return; + } + // qCDebug(LOG_PLASMA) << "Settings Changed!"; + KConfigGroup cg = config(); + setThemeName(cg.readEntry("name", ThemePrivate::defaultTheme), false, emitChanges); +} + +QColor ThemePrivate::color(Theme::ColorRole role, Theme::ColorGroup group) const +{ + const KColorScheme *scheme = nullptr; + + // Before 5.0 Plasma theme really only used Normal and Button + // many old themes are built on this assumption and will break + // otherwise + if (apiMajor < 5 && group != Theme::NormalColorGroup) { + group = Theme::ButtonColorGroup; + } + + switch (group) { + case Theme::ButtonColorGroup: { + scheme = &buttonColorScheme; + break; + } + + case Theme::ViewColorGroup: { + scheme = &viewColorScheme; + break; + } + + // this doesn't have a real kcolorscheme + case Theme::ComplementaryColorGroup: { + scheme = &complementaryColorScheme; + break; + } + + case Theme::HeaderColorGroup: { + scheme = &headerColorScheme; + break; + } + + case Theme::ToolTipColorGroup: { + scheme = &tooltipColorScheme; + break; + } + + case Theme::NormalColorGroup: + default: { + scheme = &colorScheme; + break; + } + } + + switch (role) { + case Theme::TextColor: + return scheme->foreground(KColorScheme::NormalText).color(); + + case Theme::BackgroundColor: + return scheme->background(KColorScheme::NormalBackground).color(); + + case Theme::HoverColor: + return scheme->decoration(KColorScheme::HoverColor).color(); + + case Theme::HighlightColor: + return selectionColorScheme.background(KColorScheme::NormalBackground).color(); + + case Theme::FocusColor: + return scheme->decoration(KColorScheme::FocusColor).color(); + + case Theme::LinkColor: + return scheme->foreground(KColorScheme::LinkText).color(); + + case Theme::VisitedLinkColor: + return scheme->foreground(KColorScheme::VisitedText).color(); + + case Theme::HighlightedTextColor: + return selectionColorScheme.foreground(KColorScheme::NormalText).color(); + + case Theme::PositiveTextColor: + return scheme->foreground(KColorScheme::PositiveText).color(); + case Theme::NeutralTextColor: + return scheme->foreground(KColorScheme::NeutralText).color(); + case Theme::NegativeTextColor: + return scheme->foreground(KColorScheme::NegativeText).color(); + case Theme::DisabledTextColor: + return scheme->foreground(KColorScheme::InactiveText).color(); + } + + return QColor(); +} + +void ThemePrivate::processWallpaperSettings(const KSharedConfigPtr &metadata) +{ + if (!defaultWallpaperTheme.isEmpty() && defaultWallpaperTheme != QLatin1String(DEFAULT_WALLPAPER_THEME)) { + return; + } + + KConfigGroup cg; + if (metadata->hasGroup(QStringLiteral("Wallpaper"))) { + // we have a theme color config, so let's also check to see if + // there is a wallpaper defined in there. + cg = KConfigGroup(metadata, QStringLiteral("Wallpaper")); + } else { + // since we didn't find an entry in the theme, let's look in the main + // theme config + cg = config(); + } + + defaultWallpaperTheme = cg.readEntry("defaultWallpaperTheme", DEFAULT_WALLPAPER_THEME); + defaultWallpaperSuffix = cg.readEntry("defaultFileSuffix", DEFAULT_WALLPAPER_SUFFIX); + defaultWallpaperWidth = cg.readEntry("defaultWidth", DEFAULT_WALLPAPER_WIDTH); + defaultWallpaperHeight = cg.readEntry("defaultHeight", DEFAULT_WALLPAPER_HEIGHT); +} + +void ThemePrivate::processContrastSettings(const KSharedConfigPtr &metadata) +{ + KConfigGroup cg; + if (metadata->hasGroup(QStringLiteral("ContrastEffect"))) { + cg = KConfigGroup(metadata, QStringLiteral("ContrastEffect")); + backgroundContrastEnabled = cg.readEntry("enabled", false); + + backgroundContrast = cg.readEntry("contrast", qQNaN()); + backgroundIntensity = cg.readEntry("intensity", qQNaN()); + backgroundSaturation = cg.readEntry("saturation", qQNaN()); + } else { + backgroundContrastEnabled = false; + } +} + +void ThemePrivate::processAdaptiveTransparencySettings(const KSharedConfigPtr &metadata) +{ + KConfigGroup cg; + if (metadata->hasGroup(QStringLiteral("AdaptiveTransparency"))) { + cg = KConfigGroup(metadata, QStringLiteral("AdaptiveTransparency")); + adaptiveTransparencyEnabled = cg.readEntry("enabled", false); + } else { + adaptiveTransparencyEnabled = false; + } +} + +void ThemePrivate::processBlurBehindSettings(const KSharedConfigPtr &metadata) +{ + KConfigGroup cg; + if (metadata->hasGroup(QStringLiteral("BlurBehindEffect"))) { + cg = KConfigGroup(metadata, QStringLiteral("BlurBehindEffect")); + blurBehindEnabled = cg.readEntry("enabled", true); + } else { + blurBehindEnabled = true; + } +} + +void ThemePrivate::setThemeName(const QString &tempThemeName, bool writeSettings, bool emitChanged) +{ + kSvgImageSet->setImageSetName(tempThemeName); + QString theme = tempThemeName; + if (theme.isEmpty() || theme == themeName) { + // let's try and get the default theme at least + if (themeName.isEmpty()) { + theme = QLatin1String(ThemePrivate::defaultTheme); + } else { + return; + } + } + + // we have one special theme: essentially a dummy theme used to cache things with + // the system colors. + bool realTheme = theme != QLatin1String(systemColorsTheme); + if (realTheme) { + KPluginMetaData data = metaDataForTheme(theme); + if (!data.isValid()) { + data = metaDataForTheme(QStringLiteral("default")); + if (!data.isValid()) { + return; + } + + theme = QLatin1String(ThemePrivate::defaultTheme); + } + } + + // check again as ThemePrivate::defaultTheme might be empty + if (themeName == theme) { + return; + } + + themeName = theme; + + // load the color scheme config + const QString colorsFile = realTheme + ? QStandardPaths::locate(QStandardPaths::GenericDataLocation, + QLatin1String(PLASMA_RELATIVE_DATA_INSTALL_DIR "/desktoptheme/") % theme % QLatin1String("/colors")) + : QString(); + + // qCDebug(LOG_PLASMA) << "we're going for..." << colorsFile << "*******************"; + + if (colorsFile.isEmpty()) { + colors = nullptr; + } else { + colors = KSharedConfig::openConfig(colorsFile); + } + + colorScheme = KColorScheme(QPalette::Active, KColorScheme::Window, colors); + selectionColorScheme = KColorScheme(QPalette::Active, KColorScheme::Selection, colors); + buttonColorScheme = KColorScheme(QPalette::Active, KColorScheme::Button, colors); + viewColorScheme = KColorScheme(QPalette::Active, KColorScheme::View, colors); + complementaryColorScheme = KColorScheme(QPalette::Active, KColorScheme::Complementary, colors); + headerColorScheme = KColorScheme(QPalette::Active, KColorScheme::Header, colors); + tooltipColorScheme = KColorScheme(QPalette::Active, KColorScheme::Tooltip, colors); + palette = KColorScheme::createApplicationPalette(colors); + const QString wallpaperPath = QLatin1String(PLASMA_RELATIVE_DATA_INSTALL_DIR "/desktoptheme/") % theme % QLatin1String("/wallpapers/"); + hasWallpapers = !QStandardPaths::locate(QStandardPaths::GenericDataLocation, wallpaperPath, QStandardPaths::LocateDirectory).isEmpty(); + + // load the wallpaper settings, if any + if (realTheme) { + pluginMetaData = metaDataForTheme(theme); + KSharedConfigPtr metadata = configForTheme(theme); + + processContrastSettings(metadata); + processBlurBehindSettings(metadata); + processAdaptiveTransparencySettings(metadata); + + processWallpaperSettings(metadata); + + KConfigGroup cg(metadata, QStringLiteral("Settings")); + QString fallback = cg.readEntry("FallbackTheme", QString()); + + fallbackThemes.clear(); + while (!fallback.isEmpty() && !fallbackThemes.contains(fallback)) { + fallbackThemes.append(fallback); + + KSharedConfigPtr metadata = configForTheme(fallback); + KConfigGroup cg(metadata, QStringLiteral("Settings")); + fallback = cg.readEntry("FallbackTheme", QString()); + } + + if (!fallbackThemes.contains(QLatin1String(ThemePrivate::defaultTheme))) { + fallbackThemes.append(QLatin1String(ThemePrivate::defaultTheme)); + } + + for (const QString &theme : std::as_const(fallbackThemes)) { + KSharedConfigPtr metadata = configForTheme(theme); + processWallpaperSettings(metadata); + } + + // Check for what Plasma version the theme has been done + // There are some behavioral differences between KDE4 Plasma and Plasma 5 + const QString apiVersion = pluginMetaData.value(QStringLiteral("X-Plasma-API")); + apiMajor = 1; + apiMinor = 0; + apiRevision = 0; + if (!apiVersion.isEmpty()) { + const QList parts = QStringView(apiVersion).split(QLatin1Char('.')); + if (!parts.isEmpty()) { + apiMajor = parts.value(0).toInt(); + } + if (parts.count() > 1) { + apiMinor = parts.value(1).toInt(); + } + if (parts.count() > 2) { + apiRevision = parts.value(2).toInt(); + } + } + } + + if (realTheme && isDefault && writeSettings) { + // we're the default theme, let's save our status + KConfigGroup &cg = config(); + cg.writeEntry("name", themeName); + cg.sync(); + } + + if (emitChanged) { + scheduleThemeChangeNotification(PixmapCache | SvgElementsCache); + } +} + +bool ThemePrivate::eventFilter(QObject *watched, QEvent *event) +{ + if (watched == QCoreApplication::instance()) { + if (event->type() == QEvent::ApplicationPaletteChange) { + colorsChanged(); + } + if (event->type() == QEvent::ApplicationFontChange || event->type() == QEvent::FontChange) { + Q_EMIT defaultFontChanged(); + Q_EMIT smallestFontChanged(); + } + } + return QObject::eventFilter(watched, event); +} + +} + +#include "moc_theme_p.cpp" diff --git a/src/plasma/private/theme_p.h b/src/plasma/private/theme_p.h new file mode 100644 index 0000000..c7e9a10 --- /dev/null +++ b/src/plasma/private/theme_p.h @@ -0,0 +1,150 @@ +/* + SPDX-FileCopyrightText: 2006-2007 Aaron Seigo + SPDX-FileCopyrightText: 2013 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMA_THEME_P_H +#define PLASMA_THEME_P_H + +#include "theme.h" +#include + +#include +#include +#include +#include +#include +#include + +#include +#if HAVE_X11 +#include "private/effectwatcher_p.h" +#endif + +#include "libplasma-theme-global.h" + +#include + +namespace Plasma +{ +class Theme; + +// NOTE: Default wallpaper can be set from the theme configuration +#define DEFAULT_WALLPAPER_THEME "default" +#define DEFAULT_WALLPAPER_SUFFIX ".png" +static const int DEFAULT_WALLPAPER_WIDTH = 1920; +static const int DEFAULT_WALLPAPER_HEIGHT = 1200; + +enum CacheType { + NoCache = 0, + PixmapCache = 1, + SvgElementsCache = 2, +}; +Q_DECLARE_FLAGS(CacheTypes, CacheType) +Q_DECLARE_OPERATORS_FOR_FLAGS(CacheTypes) + +class ThemePrivate : public QObject, public QSharedData +{ + Q_OBJECT + +public: + explicit ThemePrivate(QObject *parent = nullptr); + ~ThemePrivate() override; + + KConfigGroup &config(); + + QString imagePath(const QString &theme, const QString &type, const QString &image); + QString findInTheme(const QString &image, const QString &theme, bool cache = true); + void discardCache(CacheTypes caches); + void scheduleThemeChangeNotification(CacheTypes caches); + bool useCache(); + void setThemeName(const QString &themeName, bool writeSettings, bool emitChanged); + void processWallpaperSettings(const KSharedConfigPtr &metadata); + void processContrastSettings(const KSharedConfigPtr &metadata); + void processAdaptiveTransparencySettings(const KSharedConfigPtr &metadata); + void processBlurBehindSettings(const KSharedConfigPtr &metadata); + + QColor color(Theme::ColorRole role, Theme::ColorGroup group = Theme::NormalColorGroup) const; + +public Q_SLOTS: + void compositingChanged(bool active); + void colorsChanged(); + void settingsFileChanged(const QString &settings); + void scheduledCacheUpdate(); + void onAppExitCleanup(); + void notifyOfChanged(); + void settingsChanged(bool emitChanges); + +Q_SIGNALS: + void themeChanged(); + void defaultFontChanged(); + void smallestFontChanged(); + void applicationPaletteChange(); + +public: + static const char defaultTheme[]; + static const char systemColorsTheme[]; + static const char themeRcFile[]; +#if HAVE_X11 + static EffectWatcher *s_backgroundContrastEffectWatcher; +#endif + // Ref counting of ThemePrivate instances + static ThemePrivate *globalTheme; + static QHash themes; + + std::unique_ptr kSvgImageSet; + QString themeName; + KPluginMetaData pluginMetaData; + QList fallbackThemes; + KSharedConfigPtr colors; + KColorScheme colorScheme; + KColorScheme selectionColorScheme; + KColorScheme buttonColorScheme; + KColorScheme viewColorScheme; + KColorScheme complementaryColorScheme; + KColorScheme headerColorScheme; + KColorScheme tooltipColorScheme; + QPalette palette; + bool eventFilter(QObject *watched, QEvent *event) override; + KConfigGroup cfg; + QString defaultWallpaperTheme; + QString defaultWallpaperSuffix; + int defaultWallpaperWidth; + int defaultWallpaperHeight; + QHash discoveries; + QTimer *pixmapSaveTimer; + QTimer *updateNotificationTimer; + unsigned cacheSize; + CacheTypes cachesToDiscard; + QString themeVersion; + QString themeMetadataPath; + QString iconThemeMetadataPath; + + bool compositingActive : 1; + bool backgroundContrastActive : 1; + bool isDefault : 1; + bool useGlobal : 1; + bool hasWallpapers : 1; + bool cacheTheme : 1; + bool fixedName : 1; + + qreal backgroundContrast; + qreal backgroundIntensity; + qreal backgroundSaturation; + bool backgroundContrastEnabled; + bool adaptiveTransparencyEnabled; + bool blurBehindEnabled; + + // Version number of Plasma the Theme has been designed for + int apiMajor; + int apiMinor; + int apiRevision; +}; + +} + +#endif + +extern const QString s; diff --git a/src/plasma/theme.cpp b/src/plasma/theme.cpp new file mode 100644 index 0000000..f367219 --- /dev/null +++ b/src/plasma/theme.cpp @@ -0,0 +1,349 @@ +/* + SPDX-FileCopyrightText: 2006-2007 Aaron Seigo + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "theme.h" +#include "private/theme_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config-plasma.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "debug_p.h" + +namespace Plasma +{ +Theme::Theme(QObject *parent) + : QObject(parent) +{ + if (!ThemePrivate::globalTheme) { + ThemePrivate::globalTheme = new ThemePrivate; + ThemePrivate::globalTheme->settingsChanged(false); + if (QCoreApplication::instance()) { + connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, ThemePrivate::globalTheme, &ThemePrivate::onAppExitCleanup); + } + } + ThemePrivate::globalTheme->ref.ref(); + d = ThemePrivate::globalTheme; + + connect(d, &ThemePrivate::themeChanged, this, &Theme::themeChanged); + connect(d, &ThemePrivate::defaultFontChanged, this, &Theme::defaultFontChanged); + connect(d, &ThemePrivate::smallestFontChanged, this, &Theme::smallestFontChanged); +} + +Theme::Theme(const QString &themeName, QObject *parent) + : QObject(parent) +{ + auto &priv = ThemePrivate::themes[themeName]; + if (!priv) { + priv = new ThemePrivate; + if (QCoreApplication::instance()) { + connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, priv, &ThemePrivate::onAppExitCleanup); + } + } + + priv->ref.ref(); + d = priv; + + // turn off caching so we don't accidentally trigger unnecessary disk activity at this point + bool useCache = d->cacheTheme; + d->cacheTheme = false; + d->setThemeName(themeName, false, false); + d->cacheTheme = useCache; + d->fixedName = true; + connect(d, &ThemePrivate::themeChanged, this, &Theme::themeChanged); +} + +Theme::~Theme() +{ + if (d == ThemePrivate::globalTheme) { + if (!d->ref.deref()) { + disconnect(ThemePrivate::globalTheme, nullptr, this, nullptr); + delete ThemePrivate::globalTheme; + ThemePrivate::globalTheme = nullptr; + d = nullptr; + } + } else { + if (!d->ref.deref()) { + delete ThemePrivate::themes.take(d->themeName); + } + } +} + +void Theme::setThemeName(const QString &themeName) +{ + if (d->themeName == themeName) { + return; + } + + if (d != ThemePrivate::globalTheme) { + disconnect(QCoreApplication::instance(), nullptr, d, nullptr); + if (!d->ref.deref()) { + delete ThemePrivate::themes.take(d->themeName); + } + + auto &priv = ThemePrivate::themes[themeName]; + if (!priv) { + priv = new ThemePrivate; + if (QCoreApplication::instance()) { + connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, priv, &ThemePrivate::onAppExitCleanup); + } + } + priv->ref.ref(); + d = priv; + connect(d, &ThemePrivate::themeChanged, this, &Theme::themeChanged); + } + + d->setThemeName(themeName, true, true); +} + +QString Theme::themeName() const +{ + return d->themeName; +} + +QString Theme::imagePath(const QString &name) const +{ + // look for a compressed svg file in the theme + if (name.contains(QLatin1String("../")) || name.isEmpty()) { + // we don't support relative paths + // qCDebug(LOG_PLASMA) << "Theme says: bad image path " << name; + return QString(); + } + + const QString svgzName = name % QLatin1String(".svgz"); + QString path = d->findInTheme(svgzName, d->themeName); + + if (path.isEmpty()) { + // try for an uncompressed svg file + const QString svgName = name % QLatin1String(".svg"); + path = d->findInTheme(svgName, d->themeName); + + // search in fallback themes if necessary + for (int i = 0; path.isEmpty() && i < d->fallbackThemes.count(); ++i) { + if (d->themeName == d->fallbackThemes[i]) { + continue; + } + + // try a compressed svg file in the fallback theme + path = d->findInTheme(svgzName, d->fallbackThemes[i]); + + if (path.isEmpty()) { + // try an uncompressed svg file in the fallback theme + path = d->findInTheme(svgName, d->fallbackThemes[i]); + } + } + } + + return path; +} + +QString Theme::backgroundPath(const QString &image) const +{ + return d->imagePath(themeName(), QStringLiteral("/appbackgrounds/"), image); +} + +QPalette Theme::palette() const +{ + return d->palette; +} + +QPalette Theme::globalPalette() +{ + if (!ThemePrivate::globalTheme) { + ThemePrivate::globalTheme = new ThemePrivate; + ThemePrivate::globalTheme->settingsChanged(false); + } + return ThemePrivate::globalTheme->palette; +} + +KSharedConfigPtr Theme::globalColorScheme() +{ + if (!ThemePrivate::globalTheme) { + ThemePrivate::globalTheme = new ThemePrivate; + ThemePrivate::globalTheme->settingsChanged(false); + } + return ThemePrivate::globalTheme->colors; +} + +QString Theme::wallpaperPath(const QSize &size) const +{ + QString fullPath; + QString image = d->defaultWallpaperTheme + QStringLiteral("/contents/images/%1x%2") + d->defaultWallpaperSuffix; + QString defaultImage = image.arg(d->defaultWallpaperWidth).arg(d->defaultWallpaperHeight); + + if (size.isValid()) { + // try to customize the paper to the size requested + // TODO: this should do better than just fallback to the default size. + // a "best fit" matching would be far better, so we don't end + // up returning a 1920x1200 wallpaper for a 640x480 request ;) + image = image.arg(size.width()).arg(size.height()); + } else { + image = defaultImage; + } + + // TODO: the theme's wallpaper overrides regularly installed wallpapers. + // should it be possible for user installed (e.g. locateLocal) wallpapers + // to override the theme? + if (d->hasWallpapers) { + // check in the theme first + fullPath = d->findInTheme(QLatin1String("wallpapers/") % image, d->themeName); + + if (fullPath.isEmpty()) { + fullPath = d->findInTheme(QLatin1String("wallpapers/") % defaultImage, d->themeName); + } + } + + if (fullPath.isEmpty()) { + // we failed to find it in the theme, so look in the standard directories + // qCDebug(LOG_PLASMA) << "looking for" << image; + fullPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("wallpapers/") + image); + } + + if (fullPath.isEmpty()) { + // we still failed to find it in the theme, so look for the default in + // the standard directories + // qCDebug(LOG_PLASMA) << "looking for" << defaultImage; + fullPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("wallpapers/") + defaultImage); + } + + return fullPath; +} + +QString Theme::wallpaperPathForSize(int width, int height) const +{ + return Plasma::Theme::wallpaperPath(QSize(width, height)); +} + +bool Theme::currentThemeHasImage(const QString &name) const +{ + if (name.contains(QLatin1String("../"))) { + // we don't support relative paths + return false; + } + + QString path = d->findInTheme(name % QLatin1String(".svgz"), d->themeName); + if (path.isEmpty()) { + path = d->findInTheme(name % QLatin1String(".svg"), d->themeName); + } + return path.contains(QLatin1String("/" PLASMA_RELATIVE_DATA_INSTALL_DIR "/desktoptheme/") % d->themeName); +} + +KSharedConfigPtr Theme::colorScheme() const +{ + return d->colors; +} + +QColor Theme::color(ColorRole role, ColorGroup group) const +{ + return d->color(role, group); +} + +void Theme::setUseGlobalSettings(bool useGlobal) +{ + if (d->useGlobal == useGlobal) { + return; + } + + d->useGlobal = useGlobal; + d->cfg = KConfigGroup(); + d->themeName.clear(); + d->settingsChanged(true); +} + +bool Theme::useGlobalSettings() const +{ + return d->useGlobal; +} + +KPluginMetaData Theme::metadata() const +{ + return d->pluginMetaData; +} + +QFont Theme::defaultFont() const +{ + return QGuiApplication::font(); +} + +QFont Theme::smallestFont() const +{ + return QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont); +} + +QSizeF Theme::mSize(const QFont &font) const +{ + return QFontMetrics(font).boundingRect(QStringLiteral("M")).size(); +} + +bool Theme::backgroundContrastEnabled() const +{ + return d->backgroundContrastEnabled; +} + +bool Theme::adaptiveTransparencyEnabled() const +{ + return d->adaptiveTransparencyEnabled; +} + +qreal Theme::backgroundContrast() const +{ + if (qIsNaN(d->backgroundContrast)) { + // Make up sensible default values, based on the background color + // If we're using a dark background color, darken the background + if (qGray(color(Plasma::Theme::BackgroundColor).rgb()) < 127) { + return 0.45; + // for a light theme lighten up the background + } else { + return 0.3; + } + } + return d->backgroundContrast; +} + +qreal Theme::backgroundIntensity() const +{ + if (qIsNaN(d->backgroundIntensity)) { + if (qGray(color(Plasma::Theme::BackgroundColor).rgb()) < 127) { + return 0.6; + } else { + return 1.4; + } + } + return d->backgroundIntensity; +} + +qreal Theme::backgroundSaturation() const +{ + if (qIsNaN(d->backgroundSaturation)) { + return 1.7; + } + return d->backgroundSaturation; +} + +bool Theme::blurBehindEnabled() const +{ + return d->blurBehindEnabled; +} + +} + +#include "moc_theme.cpp" diff --git a/src/plasma/theme.h b/src/plasma/theme.h new file mode 100644 index 0000000..2aec95f --- /dev/null +++ b/src/plasma/theme.h @@ -0,0 +1,320 @@ +/* + SPDX-FileCopyrightText: 2006-2007 Aaron Seigo + SPDX-FileCopyrightText: 2013 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMA_THEME_H +#define PLASMA_THEME_H + +#include +#include +#include + +#include +#include + +class KPluginMetaData; + +namespace Plasma +{ +class ThemePrivate; +class SvgPrivate; + +/** + * @class Theme plasma/theme.h + * + * @short Interface to the Plasma theme + * + * + * Plasma::Theme provides access to a common and standardized set of graphic + * elements stored in SVG format. This allows artists to create single packages + * of SVGs that will affect the look and feel of all workspace components. + * + * Plasma::Svg uses Plasma::Theme internally to locate and load the appropriate + * SVG data. Alternatively, Plasma::Theme can be used directly to retrieve + * file system paths to SVGs by name. + */ +class PLASMA_EXPORT Theme : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QString themeName READ themeName NOTIFY themeChanged) + Q_PROPERTY(bool useGlobalSettings READ useGlobalSettings NOTIFY themeChanged) + Q_PROPERTY(QString wallpaperPath READ wallpaperPath NOTIFY themeChanged) + + // fonts + Q_PROPERTY(QFont defaultFont READ defaultFont NOTIFY defaultFontChanged) + Q_PROPERTY(QFont smallestFont READ smallestFont NOTIFY smallestFontChanged) + + Q_PROPERTY(QPalette palette READ palette NOTIFY themeChanged) + +public: + enum ColorRole { + TextColor = 0, /**< the text color to be used by items resting on the background */ + BackgroundColor = 1, /**< the default background color */ + HighlightColor = 2, /**< the text highlight color to be used by items resting + on the background */ + HoverColor = 3, /**< color for hover effect on view */ + FocusColor = 4, /**< color for focus effect on view */ + LinkColor = 5, /**< color for clickable links */ + VisitedLinkColor = 6, /**< color visited clickable links */ + HighlightedTextColor = 7, /**< color contrasting with HighlightColor, to be used for instance with */ + PositiveTextColor = 8, /**< color of foreground objects with a "positive message" connotation (usually green) */ + NeutralTextColor = 9, /**< color of foreground objects with a "neutral message" connotation (usually yellow) */ + NegativeTextColor = 10, /**< color of foreground objects with a "negative message" connotation (usually red) */ + DisabledTextColor = 11, /**< color of disabled text @since 5.64 */ + }; + + enum ColorGroup { + NormalColorGroup = 0, + ButtonColorGroup = 1, + ViewColorGroup = 2, + ComplementaryColorGroup = 3, + HeaderColorGroup, + ToolTipColorGroup, + }; + Q_ENUM(ColorGroup) + + /** + * Default constructor. It will be the global theme configured in plasmarc + * @param parent the parent object + */ + explicit Theme(QObject *parent = nullptr); + + /** + * Construct a theme. It will be a custom theme instance of themeName. + * @param themeName the name of the theme to create + * @param parent the parent object + * @since 4.3 + */ + explicit Theme(const QString &themeName, QObject *parent = nullptr); + + ~Theme() override; + + /** + * Sets the current theme being used. + */ + void setThemeName(const QString &themeName); + + /** + * @return the name of the theme. + */ + QString themeName() const; + + /** + * Retrieve the path for an SVG image in the current theme. + * + * @param name the name of the file in the theme directory (without the + * ".svg" part or a leading slash) + * @return the full path to the requested file for the current theme + */ + QString imagePath(const QString &name) const; + + /** + * Retrieves the default wallpaper associated with this theme. + * + * @param size the target height and width of the wallpaper; if an invalid size + * is passed in, then a default size will be provided instead. + * @return the full path to the wallpaper image + */ + QString wallpaperPath(const QSize &size = QSize()) const; + + Q_INVOKABLE QString wallpaperPathForSize(int width = -1, int height = -1) const; + + /** + * Checks if this theme has an image named in a certain way + * + * @param name the name of the file in the theme directory (without the + * ".svg" part or a leading slash) + * @return true if the image exists for this theme + */ + bool currentThemeHasImage(const QString &name) const; + + /** + * Returns the color scheme configurationthat goes along this theme. + * This can be used with KStatefulBrush and KColorScheme to determine + * the proper colours to use along with the visual elements in this theme. + */ + KSharedConfigPtr colorScheme() const; + + /** + * Returns the text color to be used by items resting on the background + * + * @param role which role (usage pattern) to get the color for + * @param group which group we want a color of + */ + QColor color(ColorRole role, ColorGroup group = NormalColorGroup) const; + + /** + * Tells the theme whether to follow the global settings or use application + * specific settings + * + * @param useGlobal pass in true to follow the global settings + */ + void setUseGlobalSettings(bool useGlobal); + + /** + * @return true if the global settings are followed, false if application + * specific settings are used. + */ + bool useGlobalSettings() const; + + /** + * Returns a QPalette with the colors set as defined by the theme. + * @since 5.68 + */ + QPalette palette() const; + + /** + * @return plugin metadata for this theme, with information such as + * name, description, author, website etc + * @since 5.95 + */ + KPluginMetaData metadata() const; + + /** + * @return The default application font + * @since 5.0 + */ + QFont defaultFont() const; + + /** + * @return The smallest readable font + * @since 5.0 + */ + QFont smallestFont() const; + + /** This method allows Plasma to enable and disable the background + * contrast effect for a given theme, improving readability. The + * value is read from the "enabled" key in the "ContrastEffect" + * group in the Theme's metadata file. + * The configuration in the metadata.desktop file of the theme + * could look like this (for a lighter background): + * \code + * [ContrastEffect] + * enabled=true + * contrast=0.45 + * intensity=0.45 + * saturation=1.7 + * \endcode + * @return Whether or not to enable the contrasteffect + * @since 5.0 + */ + bool backgroundContrastEnabled() const; + + /** This method allows Plasma to enable and disable the adaptive + * transparency option of the panel, which allows user to decide + * whether the panel should be always transparent, always opaque + * or only opaque when a window is maximized. + * The configuration in the metadata.desktop file of the theme + * could look like this (for a lighter background): + * \code + * [AdaptiveTransparency] + * enabled=true + * \endcode + * @return Whether or not to enable the adaptive transparency + * @since 5.20 + */ + bool adaptiveTransparencyEnabled() const; + + /** This method allows Plasma to set a background contrast effect + * for a given theme, improving readability. The value is read + * from the "contrast" key in the "ContrastEffect" group in the + * Theme's metadata file. + * @return The contrast provided to the contrasteffect + * @since 5.0 + * @see backgroundContrastEnabled + */ + qreal backgroundContrast() const; + + /** This method allows Plasma to set a background contrast effect + * for a given theme, improving readability. The value is read + * from the "intensity" key in the "ContrastEffect" group in the + * Theme's metadata file. + * @return The intensity provided to the contrasteffect + * @since 5.0 + * @see backgroundContrastEnabled + */ + qreal backgroundIntensity() const; + + /** This method allows Plasma to set a background contrast effect + * for a given theme, improving readability. The value is read + * from the "saturation" key in the "ContrastEffect" group in the + * Theme's metadata file. + * @return The saturation provided to the contrasteffect + * @since 5.0 + * @see backgroundContrastEnabled + */ + qreal backgroundSaturation() const; + + /** This method allows Plasma to enable and disable the blurring + * of what is behind the background for a given theme. The + * value is read from the "enabled" key in the "BlurBehindEffect" + * group in the Theme's metadata file. Default is @c true. + * + * The configuration in the metadata.desktop file of the theme + * could look like this: + * \code + * [BlurBehindEffect] + * enabled=false + * \endcode + * @return Whether or not to enable blurring of what is behind + * @since 5.57 + */ + bool blurBehindEnabled() const; + + /** + * Returns the size of the letter "M" as rendered on the screen with the given font. + * This values gives you a base size that: + * * scales dependent on the DPI of the screen + * * Scales with the default font as set by the user + * You can use it like this in QML Items: + * \code + * Item { + * width: PlasmaCore.Theme.mSize(PlasmaCore.Theme.defaultFont).height + * height: width + * } + * \endcode + * This allows you to dynamically scale elements of your user interface with different font settings and + * different physical outputs (with different DPI). + * @param font The font to use for the metrics. + * @return The size of the letter "M" as rendered on the screen with the given font. + * @since 5.0 + */ + Q_INVOKABLE QSizeF mSize(const QFont &font = QGuiApplication::font()) const; + + QString backgroundPath(const QString &image) const; + + static QPalette globalPalette(); + + static KSharedConfigPtr globalColorScheme(); + +Q_SIGNALS: + /** + * Emitted when the user changes the theme. Stylesheet usage, colors, etc. should + * be updated at this point. However, SVGs should *not* be repainted in response + * to this signal; connect to Svg::repaintNeeded() instead for that, as Svg objects + * need repainting not only when themeChanged() is emitted; moreover Svg objects + * connect to and respond appropriately to themeChanged() internally, emitting + * Svg::repaintNeeded() at an appropriate time. + */ + void themeChanged(); + + /** Notifier for change of defaultFont property */ + void defaultFontChanged(); + /** Notifier for change of smallestFont property */ + void smallestFontChanged(); + +private: + friend class SvgPrivate; + friend class FrameSvg; + friend class FrameSvgPrivate; + friend class ThemePrivate; + ThemePrivate *d; +}; + +} // Plasma namespace + +#endif // multiple inclusion guard diff --git a/src/plasmaquick/CMakeLists.txt b/src/plasmaquick/CMakeLists.txt new file mode 100644 index 0000000..ffc1893 --- /dev/null +++ b/src/plasmaquick/CMakeLists.txt @@ -0,0 +1,179 @@ +# Consumer's include dir which has to be explicitly used to make headers of this lib visible to documented includes +# Results in duplicate of prefix-dir & C++ namespace below, but part of different things, so by design: +# //class header files +set(PLASMAQUICK_INSTALL_INCLUDEDIR "${KDE_INSTALL_INCLUDEDIR}/PlasmaQuick") + +add_library(PlasmaQuick SHARED) +add_library(Plasma::PlasmaQuick ALIAS PlasmaQuick) + +qt_extract_metatypes(PlasmaQuick) + +set_target_properties(PlasmaQuick PROPERTIES + VERSION ${PLASMA_VERSION} + SOVERSION ${PLASMA_SOVERSION} + EXPORT_NAME PlasmaQuick +) + +target_sources(PlasmaQuick PRIVATE + appletcontext.cpp + appletquickitem.cpp + appletpopup.cpp + debug_p.cpp + dialog.cpp + dialogshadows.cpp + containmentview.cpp + configmodel.cpp + configview.cpp + edgeeventforwarder.cpp + plasmashellwaylandintegration.cpp + sharedqmlengine.cpp + quickviewsharedengine.cpp + plasmawindow.cpp + popupplasmawindow.cpp + transientplacementhint.cpp + windowresizehandler.cpp + configcategory_p.cpp + plasmoidattached_p.cpp + dialogbackground_p.cpp + utils.cpp + plasmoid/plasmoiditem.cpp + plasmoid/containmentitem.cpp + plasmoid/dropmenu.cpp + plasmoid/wallpaperitem.cpp +) + +if (Qt6_VERSION VERSION_GREATER_EQUAL "6.8.0") + set(private_code_option "PRIVATE_CODE") +endif() +qt_generate_wayland_protocol_client_sources(PlasmaQuick + FILES + "${PLASMA_WAYLAND_PROTOCOLS_DIR}/plasma-shell.xml" + "${Wayland_DATADIR}/wayland.xml" + ${private_code_option} +) + +ecm_qt_declare_logging_category(PlasmaQuick + HEADER debug_p.h + IDENTIFIER LOG_PLASMAQUICK + CATEGORY_NAME kf.plasma.quick + OLD_CATEGORY_NAMES org.kde.plasmaquick + DESCRIPTION "Plasma Quick lib" + EXPORT PLASMA +) + +set_target_properties(PlasmaQuick PROPERTIES + VERSION ${PLASMA_VERSION} + SOVERSION ${PLASMA_SOVERSION} + EXPORT_NAME PlasmaQuick +) + +target_include_directories(PlasmaQuick + PUBLIC + "$" + INTERFACE + "$" + "$" # module version header +) + +target_link_libraries(PlasmaQuick + PUBLIC + Qt6::Gui + Qt6::Quick + Qt6::Qml + Plasma::Plasma + KF6::WindowSystem + PRIVATE + Qt6::Svg + Qt6::GuiPrivate + Qt6::WaylandClient + Wayland::Client + KF6::ConfigGui + KF6::ConfigQml + KF6::I18n + KF6::IconThemes + KF6::CoreAddons + KF6::Package + KF6::KIOCore + KF6::KIOWidgets + KF6::Notifications + KF6::KCMUtilsQuick + KF6::Svg + KF6::GuiAddons +) + +if(HAVE_X11) + target_link_libraries(PlasmaQuick + PRIVATE + ${X11_LIBRARIES} + XCB::XCB + Qt6::GuiPrivate + ) +endif() + +install(TARGETS PlasmaQuick EXPORT PlasmaQuickTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) + +ecm_generate_export_header(PlasmaQuick + BASE_NAME PlasmaQuick + GROUP_BASE_NAME KF + VERSION ${KF6_MIN_VERSION} + USE_VERSION_HEADER + VERSION_BASE_NAME Plasma + DEPRECATED_BASE_VERSION 0 + EXCLUDE_DEPRECATED_BEFORE_AND_AT ${EXCLUDE_DEPRECATED_BEFORE_AND_AT} + DEPRECATION_VERSIONS +) + +set(plasmaquick_LIB_INCLUDES + ${CMAKE_CURRENT_BINARY_DIR}/plasmaquick_export.h +) + +ecm_generate_headers(PlasmaQuick_CamelCase_HEADERS + HEADER_NAMES + AppletQuickItem + ContainmentView + ConfigView + ConfigModel + Dialog + PlasmaWindow + PlasmaShellWaylandIntegration + PopupPlasmaWindow + AppletPopup + SharedQmlEngine + QuickViewSharedEngine + REQUIRED_HEADERS plasmaquick_LIB_INCLUDES + PREFIX PlasmaQuick +) + +install( + FILES ${plasmaquick_LIB_INCLUDES} + DESTINATION ${PLASMAQUICK_INSTALL_INCLUDEDIR}/plasmaquick + COMPONENT Devel +) + +install( + FILES ${PlasmaQuick_CamelCase_HEADERS} + DESTINATION ${PLASMAQUICK_INSTALL_INCLUDEDIR}/PlasmaQuick + COMPONENT Devel +) + +set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/PlasmaQuick") + +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/PlasmaQuickConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/PlasmaQuickConfig.cmake" + INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} + PATH_VARS PLASMAQUICK_INSTALL_INCLUDEDIR CMAKE_INSTALL_PREFIX +) + +ecm_setup_version(${PLASMA_VERSION} + VARIABLE_PREFIX PLASMAQUICK + SOVERSION 6 + PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/PlasmaQuickConfigVersion.cmake" ) + +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/PlasmaQuickConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/PlasmaQuickConfigVersion.cmake" + DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel +) + +install(EXPORT PlasmaQuickTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE PlasmaQuickTargets.cmake NAMESPACE Plasma:: ) diff --git a/src/plasmaquick/Mainpage.dox b/src/plasmaquick/Mainpage.dox new file mode 100644 index 0000000..f604aab --- /dev/null +++ b/src/plasmaquick/Mainpage.dox @@ -0,0 +1,26 @@ +/** @page libplasmaquick Plasmoid Interfaces + +libplasmaquick is an internal part of lib plasma. + +It should not be used directly, however some classes are exposed to Plasma as attached properties. + +Namely: + - PlasmoidItem + - ContainmentItem +which are exposed as "Plasmoid" for applets and containments respectively. + +QML applets should import org.kde.plasma.plasmoid 2.0 in order to access this attached object + + + - WallpaperItem +which is exposed as to wallpapers as the attached property "wallpaper". +It does not require any special imports + + +*/ + +// DOXYGEN_SET_PROJECT_NAME = Plasma +// DOXYGEN_SET_RECURSIVE = YES +// DOXYGEN_EXCLUDE_PATTERNS = *_p.h */private/* */tests/* + +// vim:ts=4:sw=4:expandtab:filetype=doxygen diff --git a/src/plasmaquick/PlasmaQuickConfig.cmake.in b/src/plasmaquick/PlasmaQuickConfig.cmake.in new file mode 100644 index 0000000..cea75cf --- /dev/null +++ b/src/plasmaquick/PlasmaQuickConfig.cmake.in @@ -0,0 +1,16 @@ +@PACKAGE_INIT@ + +# Any changes in this ".cmake" file will be overwritten by CMake, the source is the ".cmake.in" file. + +# do not use PACKAGE_CMAKE_INSTALL_PREFIX after calls to find_dependency, its content can change! +set(PlasmaQuick_INSTALL_PREFIX "@PACKAGE_CMAKE_INSTALL_PREFIX@") +set_and_check(PlasmaQuick_INCLUDE_DIR "@PACKAGE_PLASMAQUICK_INSTALL_INCLUDEDIR@") + +include(CMakeFindDependencyMacro) +find_dependency(Qt6Quick "@REQUIRED_QT_VERSION@") +find_dependency(Plasma "@KF_DEP_VERSION@") + +include("${CMAKE_CURRENT_LIST_DIR}/PlasmaQuickTargets.cmake") + +set(PlasmaQuick_LIBRARIES Plasma::PlasmaQuick) + diff --git a/src/plasmaquick/appletcontext.cpp b/src/plasmaquick/appletcontext.cpp new file mode 100644 index 0000000..1a9b721 --- /dev/null +++ b/src/plasmaquick/appletcontext.cpp @@ -0,0 +1,53 @@ +/* + SPDX-FileCopyrightText: 2023 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "appletcontext_p.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include + +namespace PlasmaQuick +{ + +AppletContext::AppletContext(QQmlEngine *engine, Plasma::Applet *applet, SharedQmlEngine *parent) + : QQmlContext(engine, applet) + , m_applet(applet) + , m_sharedEngine(parent) +{ + setParent(parent); +} + +AppletContext::~AppletContext() +{ +} + +Plasma::Applet *AppletContext::applet() const +{ + return m_applet; +} + +SharedQmlEngine *AppletContext::sharedQmlEngine() const +{ + return m_sharedEngine; +} + +} + +#include "moc_appletcontext_p.cpp" diff --git a/src/plasmaquick/appletcontext_p.h b/src/plasmaquick/appletcontext_p.h new file mode 100644 index 0000000..9bbd6c2 --- /dev/null +++ b/src/plasmaquick/appletcontext_p.h @@ -0,0 +1,37 @@ +/* + SPDX-FileCopyrightText: 2023 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#pragma once + +#include "sharedqmlengine.h" + +#include +#include + +namespace Plasma +{ +class Applet; +} + +namespace PlasmaQuick +{ + +class AppletContext : public QQmlContext +{ + Q_OBJECT +public: + AppletContext(QQmlEngine *engine, Plasma::Applet *applet, SharedQmlEngine *parent); + ~AppletContext(); + + Plasma::Applet *applet() const; + SharedQmlEngine *sharedQmlEngine() const; + +private: + Plasma::Applet *m_applet; + SharedQmlEngine *m_sharedEngine; +}; + +} diff --git a/src/plasmaquick/appletpopup.cpp b/src/plasmaquick/appletpopup.cpp new file mode 100644 index 0000000..c67c2a9 --- /dev/null +++ b/src/plasmaquick/appletpopup.cpp @@ -0,0 +1,348 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "appletpopup.h" + +#include +#include +#include // for QWINDOWSIZE_MAX + +#include +#include +#include +#include + +#include "applet.h" +#include "appletquickitem.h" +#include "edgeeventforwarder.h" +#include "plasmashellwaylandintegration.h" +#include "windowresizehandler.h" + +// used in detecting if focus passes to config UI +#include "configview.h" +#include "sharedqmlengine.h" +#include "utils.h" + +// This is a proxy object that connects to the Layout attached property of an item +// it also handles turning properties to proper defaults +// we need a wrapper as QQmlProperty can't disconnect + +namespace PlasmaQuick +{ + +class LayoutChangedProxy : public QObject +{ + Q_OBJECT +public: + LayoutChangedProxy(QQuickItem *item); + QSize minimumSize() const; + QSize maximumSize() const; + QSize implicitSize() const; +Q_SIGNALS: + void implicitSizeChanged(); + void minimumSizeChanged(); + void maximumSizeChanged(); + +private: + QQmlProperty m_minimumWidth; + QQmlProperty m_maximumWidth; + QQmlProperty m_minimumHeight; + QQmlProperty m_maximumHeight; + QQmlProperty m_preferredWidth; + QQmlProperty m_preferredHeight; + QPointer m_item; +}; +} + +using namespace PlasmaQuick; + +AppletPopup::AppletPopup() + : PopupPlasmaWindow() +{ + setAnimated(true); + setFlags(flags() | Qt::Dialog); + + if (KWindowSystem::isPlatformX11()) { + KX11Extras::setType(winId(), NET::AppletPopup); + } else { + PlasmaShellWaylandIntegration::get(this)->setRole(QtWayland::org_kde_plasma_surface::role::role_appletpopup); + } + + auto edgeForwarder = new EdgeEventForwarder(this); + edgeForwarder->setMargins(padding()); + connect(this, &PlasmaWindow::paddingChanged, this, [edgeForwarder, this]() { + edgeForwarder->setMargins(padding()); + }); + // edges that have a border are not on a screen edge + // we want to forward on sides touching screen edges + edgeForwarder->setActiveEdges(~borders()); + connect(this, &PlasmaWindow::bordersChanged, this, [edgeForwarder, this]() { + edgeForwarder->setActiveEdges(~borders()); + }); + + auto windowResizer = new WindowResizeHandler(this); + windowResizer->setMargins(padding()); + connect(this, &PlasmaWindow::paddingChanged, this, [windowResizer, this]() { + windowResizer->setMargins(padding()); + }); + + auto updateWindowResizerEdges = [windowResizer, this]() { + Qt::Edges activeEdges = borders(); + activeEdges.setFlag(PlasmaQuickPrivate::oppositeEdge(effectivePopupDirection()), false); + windowResizer->setActiveEdges(activeEdges); + }; + updateWindowResizerEdges(); + connect(this, &PlasmaWindow::bordersChanged, this, updateWindowResizerEdges); + connect(this, &PopupPlasmaWindow::effectivePopupDirectionChanged, this, updateWindowResizerEdges); + + connect(this, &PlasmaWindow::mainItemChanged, this, &AppletPopup::onMainItemChanged); + connect(this, &PlasmaWindow::paddingChanged, this, &AppletPopup::updateMaxSize); + connect(this, &PlasmaWindow::paddingChanged, this, &AppletPopup::updateSize); + connect(this, &PlasmaWindow::paddingChanged, this, &AppletPopup::updateMinSize); + + connect(this, &PlasmaWindow::screenChanged, this, [this](QScreen *screen) { + if (m_oldScreen) { + disconnect(m_oldScreen, &QScreen::geometryChanged, this, &AppletPopup::updateMaxSize); + } + if (screen) { + connect(screen, &QScreen::geometryChanged, this, &AppletPopup::updateMaxSize); + } + m_oldScreen = screen; + updateMaxSize(); + }); +} + +AppletPopup::~AppletPopup() +{ +} + +QQuickItem *AppletPopup::appletInterface() const +{ + return m_appletInterface.data(); +} + +void AppletPopup::setAppletInterface(QQuickItem *appletInterface) +{ + if (appletInterface == m_appletInterface) { + return; + } + + m_appletInterface = qobject_cast(appletInterface); + m_sizeExplicitlySetFromConfig = false; + + if (m_appletInterface) { + KConfigGroup config = m_appletInterface->applet()->config(); + QSize size; + size.rwidth() = config.readEntry("popupWidth", 0); + size.rheight() = config.readEntry("popupHeight", 0); + if (!size.isEmpty()) { + m_sizeExplicitlySetFromConfig = true; + resize(size.grownBy(padding())); + return; + } + } + + Q_EMIT appletInterfaceChanged(); +} + +bool AppletPopup::hideOnWindowDeactivate() const +{ + return m_hideOnWindowDeactivate; +} + +void AppletPopup::setHideOnWindowDeactivate(bool hideOnWindowDeactivate) +{ + if (hideOnWindowDeactivate == m_hideOnWindowDeactivate) { + return; + } + m_hideOnWindowDeactivate = hideOnWindowDeactivate; + Q_EMIT hideOnWindowDeactivateChanged(); +} + +void AppletPopup::hideEvent(QHideEvent *event) +{ + // Persist the size if this contains an applet + if (m_appletInterface) { + KConfigGroup config = m_appletInterface->applet()->config(); + // save size without margins, so we're robust against theme changes + const QSize popupSize = size().shrunkBy(padding()); + config.writeEntry("popupWidth", popupSize.width()); + config.writeEntry("popupHeight", popupSize.height()); + config.sync(); + } + + PopupPlasmaWindow::hideEvent(event); +} + +void AppletPopup::focusOutEvent(QFocusEvent *ev) +{ + if (m_hideOnWindowDeactivate) { + bool parentHasFocus = false; + + QWindow *parentWindow = transientParent(); + + while (parentWindow) { + if (parentWindow->isActive() && !(parentWindow->flags() & Qt::WindowDoesNotAcceptFocus)) { + parentHasFocus = true; + break; + } + + parentWindow = parentWindow->transientParent(); + } + + const QWindow *focusWindow = QGuiApplication::focusWindow(); + bool childHasFocus = focusWindow && ((focusWindow->isActive() && isAncestorOf(focusWindow)) || (focusWindow->type() & Qt::Popup) == Qt::Popup); + + const bool viewClicked = qobject_cast(focusWindow) || qobject_cast(focusWindow); + + if (viewClicked || (!parentHasFocus && !childHasFocus)) { + setVisible(false); + } + } + + PopupPlasmaWindow::focusOutEvent(ev); +} + +void AppletPopup::onMainItemChanged() +{ + QQuickItem *mainItem = PlasmaWindow::mainItem(); + if (!mainItem) { + m_layoutChangedProxy.reset(); + return; + } + + // update window to mainItem size hints + m_layoutChangedProxy.reset(new LayoutChangedProxy(mainItem)); + connect(m_layoutChangedProxy.data(), &LayoutChangedProxy::maximumSizeChanged, this, &AppletPopup::updateMaxSize); + connect(m_layoutChangedProxy.data(), &LayoutChangedProxy::minimumSizeChanged, this, &AppletPopup::updateMinSize); + connect(m_layoutChangedProxy.data(), &LayoutChangedProxy::implicitSizeChanged, this, &AppletPopup::updateSize); + + updateMinSize(); + updateMaxSize(); + updateSize(); +} + +void AppletPopup::updateMinSize() +{ + if (!m_layoutChangedProxy) { + return; + } + setMinimumSize(m_layoutChangedProxy->minimumSize().grownBy(padding())); + // SetMinimumsize doesn't work since + // https://codereview.qt-project.org/c/qt/qtwayland/+/527831 + // which fixes and conforms to the wayland protocol specification. + // This workaround is needed as the bug is in the protocol itself + if (!size().isEmpty()) { + resize(std::max(size().width(), minimumSize().width()), std::max(size().height(), minimumSize().height())); + } +} + +void AppletPopup::updateMaxSize() +{ + if (!m_layoutChangedProxy) { + return; + } + QSize maxSize = m_layoutChangedProxy->maximumSize().grownBy(padding()); + if (screen()) { + maxSize.setWidth(std::min(maxSize.width(), int(std::round(screen()->geometry().width() * 0.95)))); + maxSize.setHeight(std::min(maxSize.height(), int(std::round(screen()->geometry().height() * 0.95)))); + } + setMaximumSize(maxSize); + if (!size().isEmpty() && !maxSize.isEmpty()) { + resize(std::min(size().width(), maxSize.width()), std::min(size().height(), maxSize.height())); + } +} + +void AppletPopup::updateSize() +{ + if (m_sizeExplicitlySetFromConfig) { + return; + } + if (!m_layoutChangedProxy) { + return; + } + const QSize wantedSize = m_layoutChangedProxy->implicitSize().grownBy(padding()); + + // NOTE: not using std::clamp as it might assert due to (possible) malformed values, sich as min > max + QSize size = { + std::min(std::max(minimumSize().width(), wantedSize.width()), maximumSize().width()), + std::min(std::max(minimumSize().height(), wantedSize.height()), maximumSize().height()) + }; + + resize(size); +} + +LayoutChangedProxy::LayoutChangedProxy(QQuickItem *item) + : m_item(item) +{ + m_minimumWidth = QQmlProperty(item, QStringLiteral("Layout.minimumWidth"), qmlContext(item)); + m_minimumHeight = QQmlProperty(item, QStringLiteral("Layout.minimumHeight"), qmlContext(item)); + m_maximumWidth = QQmlProperty(item, QStringLiteral("Layout.maximumWidth"), qmlContext(item)); + m_maximumHeight = QQmlProperty(item, QStringLiteral("Layout.maximumHeight"), qmlContext(item)); + m_preferredWidth = QQmlProperty(item, QStringLiteral("Layout.preferredWidth"), qmlContext(item)); + m_preferredHeight = QQmlProperty(item, QStringLiteral("Layout.preferredHeight"), qmlContext(item)); + + m_minimumWidth.connectNotifySignal(this, QMetaMethod::fromSignal(&LayoutChangedProxy::minimumSizeChanged).methodIndex()); + m_minimumHeight.connectNotifySignal(this, QMetaMethod::fromSignal(&LayoutChangedProxy::minimumSizeChanged).methodIndex()); + m_maximumWidth.connectNotifySignal(this, QMetaMethod::fromSignal(&LayoutChangedProxy::maximumSizeChanged).methodIndex()); + m_maximumHeight.connectNotifySignal(this, QMetaMethod::fromSignal(&LayoutChangedProxy::maximumSizeChanged).methodIndex()); + m_preferredWidth.connectNotifySignal(this, QMetaMethod::fromSignal(&LayoutChangedProxy::implicitSizeChanged).methodIndex()); + m_preferredHeight.connectNotifySignal(this, QMetaMethod::fromSignal(&LayoutChangedProxy::implicitSizeChanged).methodIndex()); + connect(item, &QQuickItem::implicitWidthChanged, this, &LayoutChangedProxy::implicitSizeChanged); + connect(item, &QQuickItem::implicitHeightChanged, this, &LayoutChangedProxy::implicitSizeChanged); +} + +QSize LayoutChangedProxy::maximumSize() const +{ + QSize size(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX); + qreal width = m_maximumWidth.read().toReal(); + if (qIsFinite(width) && int(width) > 0) { + size.setWidth(width); + } + qreal height = m_maximumHeight.read().toReal(); + if (qIsFinite(height) && int(height) > 0) { + size.setHeight(height); + } + + return size; +} + +QSize LayoutChangedProxy::implicitSize() const +{ + QSize size(200, 200); + + // Layout.preferredSize has precedent over implicit in layouts + // so mimic that behaviour here + if (m_item) { + size = QSize(m_item->implicitWidth(), m_item->implicitHeight()); + } + qreal width = m_preferredWidth.read().toReal(); + if (qIsFinite(width) && int(width) > 0) { + size.setWidth(width); + } + qreal height = m_preferredHeight.read().toReal(); + if (qIsFinite(height) && int(height) > 0) { + size.setHeight(height); + } + return size; +} + +QSize LayoutChangedProxy::minimumSize() const +{ + QSize size(0, 0); + qreal width = m_minimumWidth.read().toReal(); + if (qIsFinite(width) && int(width) > 0) { + size.setWidth(width); + } + qreal height = m_minimumHeight.read().toReal(); + if (qIsFinite(height) && int(height) > 0) { + size.setHeight(height); + } + + return size; +} + +#include "appletpopup.moc" diff --git a/src/plasmaquick/appletpopup.h b/src/plasmaquick/appletpopup.h new file mode 100644 index 0000000..e196966 --- /dev/null +++ b/src/plasmaquick/appletpopup.h @@ -0,0 +1,74 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#pragma once + +#include "popupplasmawindow.h" + +#include + +#include + +namespace PlasmaQuick +{ + +class AppletQuickItem; +class LayoutChangedProxy; + +/** + * @brief The AppletPopup class shows a popup for an applet either in the panel or on the desktop + * + * In addition to the new API this class is resizable and can forward any input events recieved + * on the margin to the main item + * + * Size hints are transferred from the mainItem's size hints. + */ +class PLASMAQUICK_EXPORT AppletPopup : public PopupPlasmaWindow +{ + Q_OBJECT + /** + * This property holds a pointer to the AppletInterface used by + */ + Q_PROPERTY(QQuickItem *appletInterface READ appletInterface WRITE setAppletInterface NOTIFY appletInterfaceChanged) + + /** + * Whether the dialog should be hidden when the dialog loses focus. + * + * The default value is @c false. + **/ + Q_PROPERTY(bool hideOnWindowDeactivate READ hideOnWindowDeactivate WRITE setHideOnWindowDeactivate NOTIFY hideOnWindowDeactivateChanged) + +public: + AppletPopup(); + ~AppletPopup() override; + QQuickItem *appletInterface() const; + void setAppletInterface(QQuickItem *appletInterface); + + bool hideOnWindowDeactivate() const; + void setHideOnWindowDeactivate(bool hideOnWindowDeactivate); + +Q_SIGNALS: + void appletInterfaceChanged(); + void hideOnWindowDeactivateChanged(); + +protected: + void hideEvent(QHideEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; + +private: + void onMainItemChanged(); + void updateMinSize(); + void updateMaxSize(); + void updateSize(); + + QPointer m_appletInterface; + QPointer m_oldScreen; + bool m_hideOnWindowDeactivate = false; + bool m_sizeExplicitlySetFromConfig = false; + QScopedPointer m_layoutChangedProxy; +}; + +} diff --git a/src/plasmaquick/appletquickitem.cpp b/src/plasmaquick/appletquickitem.cpp new file mode 100644 index 0000000..53eb26c --- /dev/null +++ b/src/plasmaquick/appletquickitem.cpp @@ -0,0 +1,961 @@ +/* + SPDX-FileCopyrightText: 2014 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "appletquickitem.h" +#include "applet.h" +#include "appletcontext_p.h" +#include "appletquickitem_p.h" +#include "configview.h" +#include "containment.h" +#include "debug_p.h" +#include "plasma_version.h" +#include "plasmoid/containmentitem.h" +#include "plasmoid/plasmoiditem.h" +#include "plasmoid/wallpaperitem.h" +#include "plasmoidattached_p.h" +#include "sharedqmlengine.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +namespace PlasmaQuick +{ + +QHash AppletQuickItemPrivate::s_itemsForApplet = QHash(); +AppletQuickItemPrivate::PreloadPolicy AppletQuickItemPrivate::s_preloadPolicy = AppletQuickItemPrivate::Uninitialized; + +AppletQuickItemPrivate::AppletQuickItemPrivate(AppletQuickItem *item) + : q(item) + , switchWidth(-1) + , switchHeight(-1) + , initComplete(false) + , compactRepresentationCheckGuard(false) +{ + if (s_preloadPolicy == Uninitialized) { + // default as Adaptive + s_preloadPolicy = Adaptive; + + if (qEnvironmentVariableIsSet("PLASMA_PRELOAD_POLICY")) { + const QString policy = QString::fromUtf8(qgetenv("PLASMA_PRELOAD_POLICY")).toLower(); + if (policy == QLatin1String("aggressive")) { + s_preloadPolicy = Aggressive; + } else if (policy == QLatin1String("none")) { + s_preloadPolicy = None; + } + } + + qCInfo(LOG_PLASMAQUICK) << "Applet preload policy set to" << s_preloadPolicy; + } +} + +int AppletQuickItemPrivate::preloadWeight() const +{ + int defaultWeight; + const QStringList provides = applet->pluginMetaData().value(QStringLiteral("X-Plasma-Provides"), QStringList()); + + // some applet types we want a bigger weight + if (provides.contains(QLatin1String("org.kde.plasma.launchermenu"))) { + defaultWeight = DefaultLauncherPreloadWeight; + } else { + defaultWeight = DefaultPreloadWeight; + } + // default widgets to be barely preloaded + return qBound(0, + applet->config().readEntry(QStringLiteral("PreloadWeight"), + qMax(defaultWeight, applet->pluginMetaData().value(QStringLiteral("X-Plasma-PreloadWeight"), 0))), + 100); +} + +QObject *AppletQuickItemPrivate::searchLayoutAttached(QObject *parent) const +{ + QObject *layout = nullptr; + // Search a child that has the needed Layout properties + // HACK: here we are not type safe, but is the only way to access to a pointer of Layout + const auto lstChildren = parent->children(); + for (QObject *child : lstChildren) { + // find for the needed property of Layout: minimum/maximum/preferred sizes and fillWidth/fillHeight + /* clang-format off */ + if (child->property("minimumWidth").isValid() + && child->property("minimumHeight").isValid() + && child->property("preferredWidth").isValid() + && child->property("preferredHeight").isValid() + && child->property("maximumWidth").isValid() + && child->property("maximumHeight").isValid() + && child->property("fillWidth").isValid() + && child->property("fillHeight").isValid()) { /* clang-format on */ + layout = child; + break; + } + } + return layout; +} + +void AppletQuickItemPrivate::connectLayoutAttached(QObject *item) +{ + // Extract the representation's Layout, if any + if (!item) { + return; + } + + QObject *layout = searchLayoutAttached(item); + + // if the compact repr doesn't export a Layout.* attached property, + // reset our own with default values + if (!layout) { + if (ownLayout) { + ownLayout->setProperty("minimumWidth", 0); + ownLayout->setProperty("minimumHeight", 0); + ownLayout->setProperty("preferredWidth", -1); + ownLayout->setProperty("preferredHeight", -1); + ownLayout->setProperty("maximumWidth", std::numeric_limits::infinity()); + ownLayout->setProperty("maximumHeight", std::numeric_limits::infinity()); + ownLayout->setProperty("fillWidth", false); + ownLayout->setProperty("fillHeight", false); + } + return; + } + + // propagate all the size hints + propagateSizeHint("minimumWidth"); + propagateSizeHint("minimumHeight"); + propagateSizeHint("preferredWidth"); + propagateSizeHint("preferredHeight"); + propagateSizeHint("maximumWidth"); + propagateSizeHint("maximumHeight"); + propagateSizeHint("fillWidth"); + propagateSizeHint("fillHeight"); + + QObject *newOwnLayout = searchLayoutAttached(q); + + // this should never happen, since we ask to create it if doesn't exists + if (!newOwnLayout) { + return; + } + + // if the representation didn't change, don't do anything + if (representationLayout == layout) { + return; + } + + if (representationLayout) { + QObject::disconnect(representationLayout, nullptr, q, nullptr); + } + + // Here we can't use the new connect syntax because we can't link against QtQuick layouts + QObject::connect(layout, SIGNAL(minimumWidthChanged()), q, SLOT(minimumWidthChanged())); + QObject::connect(layout, SIGNAL(minimumHeightChanged()), q, SLOT(minimumHeightChanged())); + + QObject::connect(layout, SIGNAL(preferredWidthChanged()), q, SLOT(preferredWidthChanged())); + QObject::connect(layout, SIGNAL(preferredHeightChanged()), q, SLOT(preferredHeightChanged())); + + QObject::connect(layout, SIGNAL(maximumWidthChanged()), q, SLOT(maximumWidthChanged())); + QObject::connect(layout, SIGNAL(maximumHeightChanged()), q, SLOT(maximumHeightChanged())); + + QObject::connect(layout, SIGNAL(fillWidthChanged()), q, SLOT(fillWidthChanged())); + QObject::connect(layout, SIGNAL(fillHeightChanged()), q, SLOT(fillHeightChanged())); + + representationLayout = layout; + ownLayout = newOwnLayout; + + propagateSizeHint("minimumWidth"); + propagateSizeHint("minimumHeight"); + propagateSizeHint("preferredWidth"); + propagateSizeHint("preferredHeight"); + propagateSizeHint("maximumWidth"); + propagateSizeHint("maximumHeight"); + propagateSizeHint("fillWidth"); + propagateSizeHint("fillHeight"); +} + +void AppletQuickItemPrivate::propagateSizeHint(const QByteArray &layoutProperty) +{ + if (ownLayout && representationLayout) { + ownLayout->setProperty(layoutProperty.constData(), representationLayout->property(layoutProperty.constData()).toReal()); + } +} + +QQuickItem *AppletQuickItemPrivate::createCompactRepresentationItem() +{ + if (!compactRepresentation) { + return nullptr; + } + + if (compactRepresentationItem) { + return compactRepresentationItem; + } + + QVariantHash initialProperties; + initialProperties[QStringLiteral("parent")] = QVariant::fromValue(q); + initialProperties[QStringLiteral("plasmoidItem")] = QVariant::fromValue(q); + + compactRepresentationItem = qobject_cast(qmlObject->createObjectFromComponent(compactRepresentation, qmlContext(q), initialProperties)); + + Q_EMIT q->compactRepresentationItemChanged(compactRepresentationItem); + + return compactRepresentationItem; +} + +QQuickItem *AppletQuickItemPrivate::createFullRepresentationItem() +{ + if (fullRepresentationItem) { + return fullRepresentationItem; + } + + if (fullRepresentation && fullRepresentation != qmlObject->mainComponent()) { + QVariantHash initialProperties; + initialProperties[QStringLiteral("parent")] = QVariant(); + fullRepresentationItem = qobject_cast(qmlObject->createObjectFromComponent(fullRepresentation, qmlContext(q), initialProperties)); + } + + if (!fullRepresentationItem) { + return nullptr; + } + + Q_EMIT q->fullRepresentationItemChanged(fullRepresentationItem); + + return fullRepresentationItem; +} + +QQuickItem *AppletQuickItemPrivate::createCompactRepresentationExpanderItem() +{ + if (!compactRepresentationExpander) { + return nullptr; + } + + if (compactRepresentationExpanderItem) { + return compactRepresentationExpanderItem; + } + + compactRepresentationExpanderItem = qobject_cast(qmlObject->createObjectFromComponent(compactRepresentationExpander, qmlContext(q))); + + if (!compactRepresentationExpanderItem) { + return nullptr; + } + + compactRepresentationExpanderItem->setProperty("compactRepresentation", QVariant::fromValue(createCompactRepresentationItem())); + compactRepresentationExpanderItem->setProperty("plasmoidItem", QVariant::fromValue(q)); + + return compactRepresentationExpanderItem; +} + +bool AppletQuickItemPrivate::appletShouldBeExpanded() const +{ + if (applet->isContainment()) { + return true; + + } else { + if (!fullRepresentation) { + // If a full representation wasn't specified, the onle and only representation of the plasmoid are our + // direct contents, so we consider it always expanded + return true; + } + if (switchWidth > 0 && switchHeight > 0) { + // This code checks against the following edge case: + // The compact representation preferred size is bigger than both the switch + // size, and the full representation preferred size. + // this can cause in the panel (when is quite big) an infinite resize loop, because + // the applet size is bigger than the switch size, then it switches to full + // representaiton that has a smaller hint. this causes a resize that will make it + // switch to compact representation, making it grow again and switch again + if (compactRepresentationItem && fullRepresentationItem) { + QObject *compactLayout = searchLayoutAttached(compactRepresentationItem); + QObject *fullLayout = searchLayoutAttached(fullRepresentationItem); + if (compactLayout && fullLayout) { + QSizeF compactPreferred = {compactLayout->property("preferredWidth").toReal(), compactLayout->property("preferredHeight").toReal()}; + QSizeF fullPreferred = {fullLayout->property("preferredWidth").toReal(), fullLayout->property("preferredHeight").toReal()}; + + if ((compactPreferred.width() > fullPreferred.width() && compactPreferred.width() > switchWidth) || + (compactPreferred.height() > fullPreferred.height() && compactPreferred.height() > switchHeight)) { + return false; + } + } + } + return q->width() > switchWidth && q->height() > switchHeight; + + // if a size to switch wasn't set, determine what representation to always chose + } else { + // preferred representation set? + if (preferredRepresentation) { + return preferredRepresentation == fullRepresentation; + // Otherwise, base on FormFactor + } else { + return (applet->formFactor() != Plasma::Types::Horizontal && applet->formFactor() != Plasma::Types::Vertical); + } + } + } +} + +void AppletQuickItemPrivate::preloadForExpansion() +{ + qint64 time = 0; + if (QLoggingCategory::defaultCategory()->isInfoEnabled()) { + time = QDateTime::currentMSecsSinceEpoch(); + } + + if (!createFullRepresentationItem()) { + return; + } + + // When not already expanded, also preload the expander + if (!appletShouldBeExpanded() && !applet->isContainment() && (!preferredRepresentation || preferredRepresentation != fullRepresentation)) { + createCompactRepresentationExpanderItem(); + } + + if (!appletShouldBeExpanded() && compactRepresentationExpanderItem) { + compactRepresentationExpanderItem->setProperty("fullRepresentation", QVariant::fromValue(createFullRepresentationItem())); + } else if (fullRepresentationItem) { + fullRepresentationItem->setProperty("parent", QVariant::fromValue(q)); + } + + // preallocate nodes + if (fullRepresentationItem && fullRepresentationItem->window()) { + fullRepresentationItem->window()->create(); + } + + qCDebug(LOG_PLASMAQUICK) << "Applet" << applet->title() << "loaded after" << (QDateTime::currentMSecsSinceEpoch() - time) << "msec"; +} + +void AppletQuickItemPrivate::anchorsFillParent(QQuickItem *item, QQuickItem *parent) +{ + if (item->parentItem() != parent) { + return; + } + // just set once, don't bind + QQmlProperty::write(item, QStringLiteral("anchors.fill"), QVariant::fromValue(parent)); +} + +void AppletQuickItemPrivate::compactRepresentationCheck() +{ + if (!initComplete) { + return; + } + + // ignore 0 sizes; + if (q->width() <= 0 || q->height() <= 0) { + return; + } + + // ignore if this widget is being checked somewhere above + if (compactRepresentationCheckGuard) { + return; + } + + bool full = appletShouldBeExpanded(); + + if ((full && fullRepresentationItem && fullRepresentationItem == currentRepresentationItem) + || (!full && compactRepresentationItem && compactRepresentationItem == currentRepresentationItem)) { + return; + } + + compactRepresentationCheckGuard = true; + + // Expanded + if (full) { + QQuickItem *item = createFullRepresentationItem(); + + if (item) { + // unwire with the expander + if (compactRepresentationExpanderItem) { + compactRepresentationExpanderItem->setProperty("fullRepresentation", QVariant()); + compactRepresentationExpanderItem->setProperty("compactRepresentation", QVariant()); + compactRepresentationExpanderItem->setVisible(false); + } + + const bool fullRepresentationWasVisible = fullRepresentationItem->parentItem() == q; + + // the fullrepresentation being the complete AppletItem is actually allowed when the main ui + // is child of the root item (like many panel applets) + if (item != q) { + item->setParentItem(q); + anchorsFillParent(item, q); + } + + if (compactRepresentationItem) { + compactRepresentationItem->setVisible(false); + } + + currentRepresentationItem = item; + connectLayoutAttached(item); + + if (!expanded && !fullRepresentationWasVisible) { + expanded = true; + Q_EMIT q->expandedChanged(true); + } + } + + } else { + // Icon + QQuickItem *compactItem = createCompactRepresentationItem(); + QQuickItem *compactExpanderItem = createCompactRepresentationExpanderItem(); + + if (compactItem && compactExpanderItem) { + // set the root item as the main visible item + compactItem->setVisible(true); + compactExpanderItem->setParentItem(q); + compactExpanderItem->setVisible(true); + anchorsFillParent(compactExpanderItem, q); + + // only reparent full representation to null if it was parented to the applet + // if it was already in the expander, leave it where it is + const bool fullRepresentationWasVisible = fullRepresentationItem && fullRepresentationItem->parentItem() == q; + if (fullRepresentationItem && fullRepresentationWasVisible) { + fullRepresentationItem->setProperty("parent", QVariant()); + } + + compactExpanderItem->setProperty("compactRepresentation", QVariant::fromValue(compactItem)); + // The actual full representation will be connected when created + compactExpanderItem->setProperty("fullRepresentation", QVariant()); + + currentRepresentationItem = compactItem; + connectLayoutAttached(compactItem); + + // set Expanded to false only if the expanded cause was the full representation + // in the applet item, not if the full representation was in the popup and the popup was open + if (expanded && fullRepresentationWasVisible) { + expanded = false; + Q_EMIT q->expandedChanged(false); + } + } + } + + compactRepresentationCheckGuard = false; +} + +void AppletQuickItemPrivate::minimumWidthChanged() +{ + propagateSizeHint("minimumWidth"); +} + +void AppletQuickItemPrivate::minimumHeightChanged() +{ + propagateSizeHint("minimumHeight"); +} + +void AppletQuickItemPrivate::preferredWidthChanged() +{ + propagateSizeHint("preferredWidth"); +} + +void AppletQuickItemPrivate::preferredHeightChanged() +{ + propagateSizeHint("preferredHeight"); +} + +void AppletQuickItemPrivate::maximumWidthChanged() +{ + propagateSizeHint("maximumWidth"); +} + +void AppletQuickItemPrivate::maximumHeightChanged() +{ + propagateSizeHint("maximumHeight"); +} + +void AppletQuickItemPrivate::fillWidthChanged() +{ + propagateSizeHint("fillWidth"); +} + +void AppletQuickItemPrivate::fillHeightChanged() +{ + propagateSizeHint("fillHeight"); +} + +AppletQuickItem::AppletQuickItem(QQuickItem *parent) + : QQuickItem(parent) + , d(new AppletQuickItemPrivate(this)) +{ +} + +AppletQuickItem::~AppletQuickItem() +{ + AppletQuickItemPrivate::s_itemsForApplet.remove(d->applet); + // decrease weight + if (d->s_preloadPolicy >= AppletQuickItemPrivate::Adaptive) { + d->applet->config().writeEntry(QStringLiteral("PreloadWeight"), qMax(0, d->preloadWeight() - AppletQuickItemPrivate::PreloadWeightDecrement)); + } + + // Here the order is important + delete d->compactRepresentationItem; + delete d->fullRepresentationItem; + delete d->compactRepresentationExpanderItem; + delete d; +} + +bool AppletQuickItem::hasItemForApplet(Plasma::Applet *applet) +{ + return AppletQuickItemPrivate::s_itemsForApplet.contains(applet); +} + +AppletQuickItem *AppletQuickItem::itemForApplet(Plasma::Applet *applet) +{ + if (!applet) { + return nullptr; + } + + // TODO: move somewhere else? in plasmacore import? + if (AppletQuickItemPrivate::s_itemsForApplet.isEmpty()) { + const char *uri = "org.kde.plasma.plasmoid"; + qmlRegisterExtendedType(uri, 2, 0, "Plasmoid"); + qmlRegisterExtendedType(uri, 2, 0, "Containment"); + + qmlRegisterType(uri, 2, 0, "PlasmoidItem"); + qmlRegisterType(uri, 2, 0, "ContainmentItem"); + qmlRegisterType(uri, 2, 0, "WallpaperItem"); + qmlRegisterAnonymousType("org.kde.plasma.plasmoid", 1); + } + auto it = AppletQuickItemPrivate::s_itemsForApplet.constFind(applet); + if (it != AppletQuickItemPrivate::s_itemsForApplet.constEnd()) { + return it.value(); + } + + // Don't try to create applet items when the app is closing + if (qApp->closingDown() || applet->destroyed()) { + return nullptr; + } + + Plasma::Containment *pc = qobject_cast(applet); + auto *qmlObject = new PlasmaQuick::SharedQmlEngine(applet, applet); + qmlObject->engine()->setProperty("_kirigamiTheme", QStringLiteral("KirigamiPlasmaStyle")); + qmlObject->setInitializationDelayed(true); + qmlObject->setTranslationDomain(applet->translationDomain()); + + AppletQuickItem *item = nullptr; + qmlObject->setSource(applet->mainScript()); + if (pc && pc->isContainment()) { + item = qobject_cast(qmlObject->rootObject()); + if (!item && qmlObject->mainComponent() && !qmlObject->mainComponent()->isError()) { + applet->setLaunchErrorMessage(i18n("The root item of %1 must be of type ContainmentItem", applet->mainScript().toString())); + } + } else { + item = qobject_cast(qmlObject->rootObject()); + if (!item && qmlObject->mainComponent() && !qmlObject->mainComponent()->isError()) { + applet->setLaunchErrorMessage(i18n("The root item of %1 must be of type PlasmoidItem", applet->mainScript().toString())); + } + } + + if (!item || !qmlObject->mainComponent() || qmlObject->mainComponent()->isError() || applet->failedToLaunch()) { + QString reason; + QString compactReason; + QJsonObject errorData; + errorData[QStringLiteral("appletName")] = i18n("Unknown Applet"); + errorData[QStringLiteral("isDebugMode")] = qEnvironmentVariableIntValue("PLASMA_ENABLE_QML_DEBUG") != 0; + + if (applet->sourceValid()) { + const QString versionString = applet->pluginMetaData().value(QStringLiteral("X-Plasma-API-Minimum-Version")); + QVersionNumber version; + if (!versionString.isEmpty()) { + version = QVersionNumber::fromString(versionString); + } + + bool versionMismatch = false; + const int plasma_version_major = 6; // TODO: as soon PLASMA_VERSION_MAJOR is actually 6, use directly that + if (version.isNull()) { + reason = i18n( + "This Widget was written for an unknown older version of Plasma and is not compatible with Plasma %1. Please contact the widget's author for " + "an updated version.", + plasma_version_major); + compactReason = i18n("%1 is not compatible with Plasma %2", applet->pluginMetaData().name(), plasma_version_major); + versionMismatch = true; + } else if (version.majorVersion() < plasma_version_major) { + reason = + i18n("This Widget was written for Plasma %1 and is not compatible with Plasma %2. Please contact the widget's author for an updated version.", + version.majorVersion(), + plasma_version_major); + compactReason = i18n("%1 is not compatible with Plasma %2", applet->pluginMetaData().name(), plasma_version_major); + versionMismatch = true; + } else if (version.majorVersion() > plasma_version_major || version.minorVersion() > PLASMA_VERSION_MINOR) { + reason = i18n("This Widget was written for Plasma %1 and is not compatible with Plasma %2. Please update Plasma in order to use the widget.", + versionString, + plasma_version_major); + compactReason = i18n("%1 is not compatible with Plasma %2", applet->pluginMetaData().name(), plasma_version_major); + versionMismatch = true; + } else if (applet->failedToLaunch()) { + reason = applet->launchErrorMessage(); + compactReason = reason; + } else { + compactReason = i18n("Sorry! There was an error loading %1.", applet->pluginMetaData().name()); + } + errorData[QStringLiteral("errors")] = QJsonArray::fromStringList({reason}); + if (compactReason != QString()) { + errorData[QStringLiteral("compactError")] = compactReason; + } + + if (!versionMismatch) { + const auto errors = qmlObject->mainComponent()->errors(); + QStringList errorList; + for (const QQmlError &error : errors) { + reason += error.toString() + QLatin1Char('\n'); + errorList << error.toString(); + } + errorData[QStringLiteral("errors")] = QJsonArray::fromStringList(errorList); + } + errorData[QStringLiteral("appletName")] = applet->pluginMetaData().name(); + reason += i18n("Error loading QML file: %1 %2", qmlObject->mainComponent()->url().toString(), reason); + } else { + const auto pluginId = applet->pluginMetaData().pluginId(); + reason = i18n("Error loading Applet: package %1 does not exist.", pluginId); + errorData[QStringLiteral("errors")] = QJsonArray::fromStringList({reason}); + compactReason = i18n("Sorry! There was an error loading %1.", pluginId); + errorData[QStringLiteral("compactError")] = compactReason; + } + + qCWarning(LOG_PLASMAQUICK) << "error when loading applet" << applet->pluginMetaData().pluginId() + << errorData[QStringLiteral("errors")].toVariant().toStringList(); + + qmlObject->setSource(applet->containment()->corona()->kPackage().fileUrl("appleterror")); + + applet->setHasConfigurationInterface(false); + // even the error message QML may fail + if (qmlObject->mainComponent()->isError()) { + return nullptr; + } + + item = qobject_cast(qmlObject->rootObject()); + + applet->setLaunchErrorMessage(reason); + if (item) { + item->setProperty("errorInformation", errorData); + } else { + // In this case the error message loaded correctly, but was not a PlasmoidItem, bail out + qCWarning(LOG_PLASMAQUICK) << "Applet Error message is not of type PlasmoidItem" + << applet->containment()->corona()->kPackage().fileUrl("appleterror"); + return nullptr; + } + } + + AppletQuickItemPrivate::s_itemsForApplet[applet] = item; + qmlObject->setInitializationDelayed(false); + qmlObject->completeInitialization(); + + // A normal applet has UI ready as soon as is loaded, a containment, only when also the wallpaper is loaded + if (!pc || !pc->isContainment()) { + applet->updateConstraints(Plasma::Applet::UiReadyConstraint); + applet->flushPendingConstraintsEvents(); + } + + item->setProperty("_plasma_applet", QVariant::fromValue(applet)); + item->d->applet = applet; + item->d->qmlObject = qmlObject; + + if (!qEnvironmentVariableIntValue("PLASMA_NO_CONTEXTPROPERTIES")) { + qmlObject->rootContext()->setContextProperty(QStringLiteral("plasmoid"), applet); + } + + QObject::connect(applet, &Plasma::Applet::appletDeleted, item, [qmlObject](Plasma::Applet *applet) { + // Deleting qmlObject will also delete the instantiated plasmoidItem + // deleteing just the plasmoiditem will cause a double deletion when qmlObject + // gets deleted by applet deletion + if (qmlObject->parent() == applet) { + // appletDelete can also be emitted by a containment for one of its children + delete qmlObject; + AppletQuickItemPrivate::s_itemsForApplet.remove(applet); + } + }); + + applet->setProperty("_plasmoid", QVariant::fromValue(item)); + return item; +} + +Plasma::Applet *AppletQuickItem::applet() const +{ + return d->applet; +} + +void AppletQuickItem::init() +{ + if (!d->applet) { + // This can happen only if the client QML code declares a PlasmoidItem somewhere else than the root object + return; + } + if (d->initComplete) { + return; + } + + if (d->applet->containment()) { + if (d->applet->containment()->corona()) { + d->coronaPackage = d->applet->containment()->corona()->kPackage(); + } + } + + // Initialize the main QML file + QQmlEngine *engine = d->qmlObject->engine().get(); + + // If no fullRepresentation was defined, we won't create compact and expander either. + // The only representation available are whatever items defined directly inside PlasmoidItem {} + // default compactRepresentation is a simple icon provided by the shell package + if (!d->compactRepresentation && d->fullRepresentation) { + d->compactRepresentation = new QQmlComponent(engine, this); + d->compactRepresentation->loadUrl(d->coronaPackage.fileUrl("defaultcompactrepresentation")); + Q_EMIT compactRepresentationChanged(d->compactRepresentation); + } + + // default compactRepresentationExpander is the popup in which fullRepresentation goes + if (!d->compactRepresentationExpander && d->fullRepresentation) { + d->compactRepresentationExpander = new QQmlComponent(engine, this); + QUrl compactExpanderUrl = d->applet->containment()->compactApplet(); + if (compactExpanderUrl.isEmpty()) { + compactExpanderUrl = d->coronaPackage.fileUrl("compactapplet"); + } + + d->compactRepresentationExpander->loadUrl(compactExpanderUrl); + } + + d->initComplete = true; + d->compactRepresentationCheck(); + qmlObject()->engine()->rootContext()->setBaseUrl(qmlObject()->source()); + + // if we're expanded we don't care about preloading because it will already be the case + // as well as for containments + if (d->applet->isContainment() || d->expanded || d->preferredRepresentation == d->fullRepresentation) { + return; + } + + if (!d->applet->isContainment() && d->applet->containment()) { + connect(d->applet->containment(), &Plasma::Containment::uiReadyChanged, this, [this](bool uiReady) { + if (uiReady && d->s_preloadPolicy >= AppletQuickItemPrivate::Adaptive) { + const int preloadWeight = d->preloadWeight(); + qCDebug(LOG_PLASMAQUICK) << "New Applet " << d->applet->title() << "with a weight of" << preloadWeight; + + // don't preload applets less then a certain weight + if (d->s_preloadPolicy >= AppletQuickItemPrivate::Aggressive || preloadWeight >= AppletQuickItemPrivate::DelayedPreloadWeight) { + // spread the creation over a random delay to make it look + // plasma started already, and load the popup in the background + // without big noticeable freezes, the bigger the weight the smaller is likely + // to be the delay, smaller minimum walue, smaller spread + const int min = (100 - preloadWeight) * 20; + const int max = (100 - preloadWeight) * 100; + const int delay = QRandomGenerator::global()->bounded((max + 1) - min) + min; + QTimer::singleShot(delay, this, [this, delay]() { + qCDebug(LOG_PLASMAQUICK) << "Delayed preload of " << d->applet->title() << "after" << (qreal)delay / 1000 << "seconds"; + d->preloadForExpansion(); + }); + } + } + }); + } +} + +void AppletQuickItem::classBegin() +{ + QQuickItem::classBegin(); + AppletContext *ac = qobject_cast(QQmlEngine::contextForObject(this)->parentContext()); + if (!ac) { + qCWarning(LOG_PLASMAQUICK) << "Detected a PlasmoidItem which is not the root QML item: this is not supported."; + return; + } + d->applet = ac->applet(); + d->qmlObject = ac->sharedQmlEngine(); +} + +void AppletQuickItem::componentComplete() +{ + QQuickItem::componentComplete(); + init(); +} + +int AppletQuickItem::switchWidth() const +{ + return d->switchWidth; +} + +void AppletQuickItem::setSwitchWidth(int width) +{ + if (d->switchWidth == width) { + return; + } + + d->switchWidth = width; + d->compactRepresentationCheck(); + Q_EMIT switchWidthChanged(width); +} + +int AppletQuickItem::switchHeight() const +{ + return d->switchHeight; +} + +void AppletQuickItem::setSwitchHeight(int height) +{ + if (d->switchHeight == height) { + return; + } + + d->switchHeight = height; + d->compactRepresentationCheck(); + Q_EMIT switchHeightChanged(height); +} + +QQmlComponent *AppletQuickItem::compactRepresentation() +{ + return d->compactRepresentation; +} + +void AppletQuickItem::setCompactRepresentation(QQmlComponent *component) +{ + if (d->compactRepresentation == component) { + return; + } + + d->compactRepresentation = component; + Q_EMIT compactRepresentationChanged(component); +} + +QQmlComponent *AppletQuickItem::fullRepresentation() +{ + return d->fullRepresentation; +} + +void AppletQuickItem::setFullRepresentation(QQmlComponent *component) +{ + if (d->fullRepresentation == component) { + return; + } + + d->fullRepresentation = component; + Q_EMIT fullRepresentationChanged(component); +} + +QQmlComponent *AppletQuickItem::preferredRepresentation() +{ + return d->preferredRepresentation; +} + +void AppletQuickItem::setPreferredRepresentation(QQmlComponent *component) +{ + if (d->preferredRepresentation == component) { + return; + } + + d->preferredRepresentation = component; + Q_EMIT preferredRepresentationChanged(component); + d->compactRepresentationCheck(); +} + +bool AppletQuickItem::isExpanded() const +{ + return d->applet->isContainment() || !d->fullRepresentation || d->expanded; +} + +void AppletQuickItem::setExpanded(bool expanded) +{ + if (d->expanded == expanded) { + return; + } + + if (expanded) { + d->preloadForExpansion(); + // increase on open, ignore containments + if (d->s_preloadPolicy >= AppletQuickItemPrivate::Adaptive && !d->applet->isContainment()) { + const int newWeight = qMin(d->preloadWeight() + AppletQuickItemPrivate::PreloadWeightIncrement, 100); + d->applet->config().writeEntry(QStringLiteral("PreloadWeight"), newWeight); + qCDebug(LOG_PLASMAQUICK) << "Increasing score for" << d->applet->title() << "to" << newWeight; + } + } + + d->expanded = expanded; + + Q_EMIT expandedChanged(expanded); +} + +bool AppletQuickItem::isActivationTogglesExpanded() const +{ + return d->activationTogglesExpanded; +} + +void AppletQuickItem::setActivationTogglesExpanded(bool activationTogglesExpanded) +{ + if (d->activationTogglesExpanded == activationTogglesExpanded) { + return; + } + d->activationTogglesExpanded = activationTogglesExpanded; + Q_EMIT activationTogglesExpandedChanged(activationTogglesExpanded); +} + +bool AppletQuickItem::hideOnWindowDeactivate() const +{ + return d->hideOnWindowDeactivate; +} + +void AppletQuickItem::setHideOnWindowDeactivate(bool hide) +{ + if (d->hideOnWindowDeactivate == hide) { + return; + } + d->hideOnWindowDeactivate = hide; + Q_EMIT hideOnWindowDeactivateChanged(hide); +} + +bool AppletQuickItem::preloadFullRepresentation() const +{ + return d->preloadFullRepresentation; +} + +void AppletQuickItem::setPreloadFullRepresentation(bool preload) +{ + if (d->preloadFullRepresentation == preload) { + return; + } + + d->preloadFullRepresentation = preload; + d->createFullRepresentationItem(); + + Q_EMIT preloadFullRepresentationChanged(preload); +} + +////////////Internals + +PlasmaQuick::SharedQmlEngine *AppletQuickItem::qmlObject() +{ + return d->qmlObject; +} + +QQuickItem *AppletQuickItem::compactRepresentationItem() +{ + return d->compactRepresentationItem; +} + +QQuickItem *AppletQuickItem::fullRepresentationItem() +{ + return d->fullRepresentationItem; +} + +void AppletQuickItem::childEvent(QChildEvent *event) +{ + // Added child may be QQuickLayoutAttached + if (event->added() && !d->ownLayout && d->currentRepresentationItem) { + // Child has not yet finished initialization at this point + QTimer::singleShot(0, this, [this]() { + if (!d->ownLayout) { + d->connectLayoutAttached(d->currentRepresentationItem); + } + }); + } + + QQuickItem::childEvent(event); +} + +void AppletQuickItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + QQuickItem::geometryChange(newGeometry, oldGeometry); + d->compactRepresentationCheck(); +} +} + +#include "moc_appletquickitem.cpp" diff --git a/src/plasmaquick/appletquickitem.h b/src/plasmaquick/appletquickitem.h new file mode 100644 index 0000000..b031ad8 --- /dev/null +++ b/src/plasmaquick/appletquickitem.h @@ -0,0 +1,176 @@ +/* + SPDX-FileCopyrightText: 2014 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef APPLETQUICKITEM_H +#define APPLETQUICKITEM_H + +#include +#include +#include +#include +#include + +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the public Plasma API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +namespace Plasma +{ +class Applet; +} + +namespace PlasmaQuick +{ +class AppletQuickItemPrivate; +class SharedQmlEngine; + +class PLASMAQUICK_EXPORT AppletQuickItem : public QQuickItem +{ + Q_OBJECT + + Q_PROPERTY(int switchWidth READ switchWidth WRITE setSwitchWidth NOTIFY switchWidthChanged) + Q_PROPERTY(int switchHeight READ switchHeight WRITE setSwitchHeight NOTIFY switchHeightChanged) + + Q_PROPERTY(QQmlComponent *compactRepresentation READ compactRepresentation WRITE setCompactRepresentation NOTIFY compactRepresentationChanged) + Q_PROPERTY(QQuickItem *compactRepresentationItem READ compactRepresentationItem NOTIFY compactRepresentationItemChanged) + + Q_PROPERTY(QQmlComponent *fullRepresentation READ fullRepresentation WRITE setFullRepresentation NOTIFY fullRepresentationChanged) + Q_PROPERTY(QQuickItem *fullRepresentationItem READ fullRepresentationItem NOTIFY fullRepresentationItemChanged) + + /** + * When true the full representation will be loaded immediately together with the main plasmoid. + * Note that this will have a negative impact on plasmoid loading times + * This is needed only when some important logic has to live inside the full representation and + * needs to be accessed from the outside. Use with care + * TODO: remove? we whould find a better way to fix folderview and Notes + */ + Q_PROPERTY(bool preloadFullRepresentation READ preloadFullRepresentation WRITE setPreloadFullRepresentation NOTIFY preloadFullRepresentationChanged) + + /** + * this is supposed to be either one between compactRepresentation or fullRepresentation + */ + Q_PROPERTY(QQmlComponent *preferredRepresentation READ preferredRepresentation WRITE setPreferredRepresentation NOTIFY preferredRepresentationChanged) + + /** + * Hint set to true if the applet should be displayed as expanded, such as the main popup open + */ + Q_PROPERTY(bool expanded READ isExpanded WRITE setExpanded NOTIFY expandedChanged) + + /** + * True when the applet wants the activation signal act in toggle mode, i.e. while being expanded + * the signal shrinks the applet to its not expanded state instead of reexpanding it. + */ + Q_PROPERTY(bool activationTogglesExpanded WRITE setActivationTogglesExpanded READ isActivationTogglesExpanded NOTIFY activationTogglesExpandedChanged) + + /** + * Whether the dialog should be hidden when the dialog loses focus. + * + * The default value is @c false. + **/ + Q_PROPERTY(bool hideOnWindowDeactivate READ hideOnWindowDeactivate WRITE setHideOnWindowDeactivate NOTIFY hideOnWindowDeactivateChanged) + + /** + * Gives compatibility to the old plasmoid.* api + */ + Q_PROPERTY(QObject *plasmoid READ applet CONSTANT) + +public: + AppletQuickItem(QQuickItem *parent = nullptr); + ~AppletQuickItem() override; + + ////API NOT SUPPOSED TO BE USED BY QML + Plasma::Applet *applet() const; + + void classBegin() override; + void componentComplete() override; + + QQuickItem *compactRepresentationItem(); + QQuickItem *fullRepresentationItem(); + + ////PROPERTY ACCESSORS + int switchWidth() const; + void setSwitchWidth(int width); + + int switchHeight() const; + void setSwitchHeight(int width); + + QQmlComponent *compactRepresentation(); + void setCompactRepresentation(QQmlComponent *component); + + QQmlComponent *fullRepresentation(); + void setFullRepresentation(QQmlComponent *component); + + QQmlComponent *preferredRepresentation(); + void setPreferredRepresentation(QQmlComponent *component); + + bool isExpanded() const; + void setExpanded(bool expanded); + + bool isActivationTogglesExpanded() const; + void setActivationTogglesExpanded(bool activationTogglesExpanded); + + bool hideOnWindowDeactivate() const; + void setHideOnWindowDeactivate(bool hide); + + bool preloadFullRepresentation() const; + void setPreloadFullRepresentation(bool preload); + + static bool hasItemForApplet(Plasma::Applet *applet); + static AppletQuickItem *itemForApplet(Plasma::Applet *applet); + +Q_SIGNALS: + // Property signals + void switchWidthChanged(int width); + void switchHeightChanged(int height); + + void expandedChanged(bool expanded); + + void activationTogglesExpandedChanged(bool activationTogglesExpanded); + void hideOnWindowDeactivateChanged(bool hide); + + void compactRepresentationChanged(QQmlComponent *compactRepresentation); + void fullRepresentationChanged(QQmlComponent *fullRepresentation); + void preferredRepresentationChanged(QQmlComponent *preferredRepresentation); + + void compactRepresentationItemChanged(QObject *compactRepresentationItem); + void fullRepresentationItemChanged(QObject *fullRepresentationItem); + + void preloadFullRepresentationChanged(bool preload); + +protected: + // Initializations that need to be executed after classBegin() + virtual void init(); + PlasmaQuick::SharedQmlEngine *qmlObject(); + + // Reimplementation + void childEvent(QChildEvent *event) override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + +private: + AppletQuickItemPrivate *const d; + + Q_PRIVATE_SLOT(d, void minimumWidthChanged()) + Q_PRIVATE_SLOT(d, void minimumHeightChanged()) + Q_PRIVATE_SLOT(d, void preferredWidthChanged()) + Q_PRIVATE_SLOT(d, void preferredHeightChanged()) + Q_PRIVATE_SLOT(d, void maximumWidthChanged()) + Q_PRIVATE_SLOT(d, void maximumHeightChanged()) + Q_PRIVATE_SLOT(d, void fillWidthChanged()) + Q_PRIVATE_SLOT(d, void fillHeightChanged()) +}; + +} + +#endif diff --git a/src/plasmaquick/appletquickitem_p.h b/src/plasmaquick/appletquickitem_p.h new file mode 100644 index 0000000..9d42d0b --- /dev/null +++ b/src/plasmaquick/appletquickitem_p.h @@ -0,0 +1,125 @@ +/* + SPDX-FileCopyrightText: 2014 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef APPLETQUICKITEM_P_H +#define APPLETQUICKITEM_P_H + +#include +#include +#include +#include + +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the public Plasma API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +namespace Plasma +{ +class Applet; +} + +namespace PlasmaQuick +{ +class AppletQuickItem; +class SharedQmlEngine; +class AppletContext; + +class AppletQuickItemPrivate +{ +public: + // weight values for the logic for when or if to preload + enum PreloadWeights { + DefaultPreloadWeight = 50, + DefaultLauncherPreloadWeight = 100, + DelayedPreloadWeight = 25, + PreloadWeightIncrement = 5, + PreloadWeightDecrement = 8, + }; + + enum PreloadPolicy { + Uninitialized = -1, + None = 0, + Adaptive = 1, + Aggressive = 2, + }; + + AppletQuickItemPrivate(AppletQuickItem *item); + + int preloadWeight() const; + + QQuickItem *createCompactRepresentationItem(); + QQuickItem *createFullRepresentationItem(); + QQuickItem *createCompactRepresentationExpanderItem(); + + // true if the applet is at a size in which it should be expanded, + // false if is too small and should be an icon + bool appletShouldBeExpanded() const; + // ensures the popup is preloaded, don't expand yet + void preloadForExpansion(); + + // look into item, and return the Layout attached property, if found + QObject *searchLayoutAttached(QObject *parent) const; + void connectLayoutAttached(QObject *item); + void propagateSizeHint(const QByteArray &layoutProperty); + + // handlers of Layout signals, private slots + static void anchorsFillParent(QQuickItem *item, QQuickItem *parent); + void compactRepresentationCheck(); + void minimumWidthChanged(); + void minimumHeightChanged(); + void preferredWidthChanged(); + void preferredHeightChanged(); + void maximumWidthChanged(); + void maximumHeightChanged(); + void fillWidthChanged(); + void fillHeightChanged(); + + AppletQuickItem *q; + + static QHash s_itemsForApplet; + static PreloadPolicy s_preloadPolicy; + int switchWidth; + int switchHeight; + + QPointer compactRepresentation; + QPointer fullRepresentation; + QPointer preferredRepresentation; + QPointer compactRepresentationExpander; + + QPointer compactRepresentationItem; + QPointer fullRepresentationItem; + QPointer compactRepresentationExpanderItem; + QPointer currentRepresentationItem; + + // Attached layout objects: own and the representation's one + QPointer representationLayout; + QPointer ownLayout; + + Plasma::Applet *applet = nullptr; + PlasmaQuick::SharedQmlEngine *qmlObject; + + KPackage::Package coronaPackage; + + bool expanded = false; + bool hideOnWindowDeactivate = false; + bool preloadFullRepresentation = false; + bool activationTogglesExpanded = true; + bool initComplete : 1; + bool compactRepresentationCheckGuard : 1; +}; + +} + +#endif diff --git a/src/plasmaquick/configcategory_p.cpp b/src/plasmaquick/configcategory_p.cpp new file mode 100644 index 0000000..14f9f10 --- /dev/null +++ b/src/plasmaquick/configcategory_p.cpp @@ -0,0 +1,117 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + SPDX-FileCopyrightText: 2015 Eike Hein + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "configcategory_p.h" + +namespace PlasmaQuick +{ +///////////////////////ConfigCategory + +ConfigCategory::ConfigCategory(QObject *parent) + : QObject(parent) + , m_includeMargins(true) + , m_visible(true) +{ +} + +ConfigCategory::~ConfigCategory() +{ +} + +QString ConfigCategory::name() const +{ + return m_name; +} + +void ConfigCategory::setName(const QString &name) +{ + if (m_name == name) { + return; + } + + m_name = name; + Q_EMIT nameChanged(); +} + +QString ConfigCategory::icon() const +{ + return m_icon; +} + +void ConfigCategory::setIcon(const QString &icon) +{ + if (m_icon == icon) { + return; + } + + m_icon = icon; + Q_EMIT iconChanged(); +} + +QString ConfigCategory::source() const +{ + return m_source; +} + +void ConfigCategory::setSource(const QString &source) +{ + if (m_source == source) { + return; + } + + m_source = source; + Q_EMIT sourceChanged(); +} + +QString ConfigCategory::pluginName() const +{ + return m_pluginName; +} + +void ConfigCategory::setPluginName(const QString &name) +{ + if (m_pluginName == name) { + return; + } + + m_pluginName = name; + Q_EMIT pluginNameChanged(); +} + +bool ConfigCategory::includeMargins() const +{ + return m_includeMargins; +} + +void ConfigCategory::setIncludeMargins(bool includeMargins) +{ + if (m_includeMargins == includeMargins) { + return; + } + + m_includeMargins = includeMargins; + Q_EMIT includeMarginsChanged(); +} + +bool ConfigCategory::visible() const +{ + return m_visible; +} + +void ConfigCategory::setVisible(bool visible) +{ + if (m_visible == visible) { + return; + } + + m_visible = visible; + Q_EMIT visibleChanged(); +} + +} + +#include "moc_configcategory_p.cpp" diff --git a/src/plasmaquick/configcategory_p.h b/src/plasmaquick/configcategory_p.h new file mode 100644 index 0000000..72ece2a --- /dev/null +++ b/src/plasmaquick/configcategory_p.h @@ -0,0 +1,79 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + SPDX-FileCopyrightText: 2015 Eike Hein + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef CONFIGCATEGORY_P_H +#define CONFIGCATEGORY_P_H + +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the public Plasma API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +namespace PlasmaQuick +{ +// This class represents a single row item of the ConfigModel model in a QML friendly manner. +// the properties contains all the data needed to represent an icon in the sidebar of a configuration dialog, of applets or containments +class ConfigCategory : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged) + Q_PROPERTY(QString source READ source WRITE setSource NOTIFY sourceChanged) + Q_PROPERTY(QString pluginName READ pluginName WRITE setPluginName NOTIFY pluginNameChanged) + Q_PROPERTY(bool includeMargins READ includeMargins WRITE setIncludeMargins NOTIFY includeMarginsChanged) + Q_PROPERTY(bool visible READ visible WRITE setVisible NOTIFY visibleChanged) + +public: + ConfigCategory(QObject *parent = nullptr); + ~ConfigCategory() override; + + QString name() const; + void setName(const QString &name); + + QString icon() const; + void setIcon(const QString &icon); + + QString source() const; + void setSource(const QString &source); + + QString pluginName() const; + void setPluginName(const QString &pluginName); + + bool includeMargins() const; + void setIncludeMargins(bool includeMargins); + + bool visible() const; + void setVisible(bool visible); + +Q_SIGNALS: + void nameChanged(); + void iconChanged(); + void sourceChanged(); + void pluginNameChanged(); + void includeMarginsChanged(); + void visibleChanged(); + +private: + QString m_name; + QString m_icon; + QString m_source; + QString m_pluginName; + bool m_includeMargins; + bool m_visible; +}; + +} + +#endif // multiple inclusion guard diff --git a/src/plasmaquick/configmodel.cpp b/src/plasmaquick/configmodel.cpp new file mode 100644 index 0000000..33015c8 --- /dev/null +++ b/src/plasmaquick/configmodel.cpp @@ -0,0 +1,349 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + SPDX-FileCopyrightText: 2015 Eike Hein + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "configmodel.h" +#include "Plasma/Applet" +#include "Plasma/Containment" +#include "configcategory_p.h" +#include "configview.h" +#include "debug_p.h" +#include "sharedqmlengine.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +namespace PlasmaQuick +{ +//////////////////////////////ConfigModel + +class ConfigModelPrivate +{ +public: + ConfigModelPrivate(ConfigModel *model); + ~ConfigModelPrivate(); + + ConfigModel *q; + QList categories; + QPointer appletInterface; + QHash kcms; + + void appendCategory(ConfigCategory *c); + void removeCategory(ConfigCategory *c); + void removeCategoryAt(int index); + void clear(); + QVariant get(int row) const; + + static ConfigCategory *categories_at(QQmlListProperty *prop, qsizetype index); + static qsizetype categories_count(QQmlListProperty *prop); + static void categories_append(QQmlListProperty *prop, ConfigCategory *o); + static void categories_clear(QQmlListProperty *prop); +}; + +ConfigModelPrivate::ConfigModelPrivate(ConfigModel *model) + : q(model) +{ +} + +ConfigModelPrivate::~ConfigModelPrivate() +{ +} + +ConfigCategory *ConfigModelPrivate::categories_at(QQmlListProperty *prop, qsizetype index) +{ + ConfigModel *model = qobject_cast(prop->object); + if (!model || index >= model->d->categories.count() || index < 0) { + return nullptr; + } else { + return model->d->categories.at(index); + } +} + +void ConfigModelPrivate::categories_append(QQmlListProperty *prop, ConfigCategory *o) +{ + ConfigModel *model = qobject_cast(prop->object); + if (!o || !model) { + return; + } + + if (o->parent() == prop->object) { + o->setParent(nullptr); + } + + o->setParent(prop->object); + model->d->appendCategory(o); +} + +qsizetype ConfigModelPrivate::categories_count(QQmlListProperty *prop) +{ + ConfigModel *model = qobject_cast(prop->object); + if (model) { + return model->d->categories.count(); + } else { + return 0; + } +} + +void ConfigModelPrivate::categories_clear(QQmlListProperty *prop) +{ + ConfigModel *model = qobject_cast(prop->object); + if (!model) { + return; + } + + model->clear(); +} + +void ConfigModelPrivate::clear() +{ + q->beginResetModel(); + while (!categories.isEmpty()) { + categories.first()->setParent(nullptr); + categories.pop_front(); + } + q->endResetModel(); + Q_EMIT q->countChanged(); +} + +void ConfigModelPrivate::appendCategory(ConfigCategory *c) +{ + if (!c) { + return; + } + + q->beginInsertRows(QModelIndex(), categories.size(), categories.size()); + categories.append(c); + + auto emitChange = [this, c] { + const int row = categories.indexOf(c); + if (row > -1) { + QModelIndex modelIndex = q->index(row); + Q_EMIT q->dataChanged(modelIndex, modelIndex); + } + }; + + QObject::connect(c, &ConfigCategory::nameChanged, q, emitChange); + QObject::connect(c, &ConfigCategory::iconChanged, q, emitChange); + QObject::connect(c, &ConfigCategory::sourceChanged, q, emitChange); + QObject::connect(c, &ConfigCategory::pluginNameChanged, q, emitChange); + QObject::connect(c, &ConfigCategory::visibleChanged, q, emitChange); + + q->endInsertRows(); + Q_EMIT q->countChanged(); +} + +void ConfigModelPrivate::removeCategory(ConfigCategory *c) +{ + const int index = categories.indexOf(c); + if (index > -1) { + removeCategoryAt(index); + } +} + +void ConfigModelPrivate::removeCategoryAt(int index) +{ + if (index < 0 || index >= categories.count()) { + return; + } + + q->beginRemoveRows(QModelIndex(), index, index); + + ConfigCategory *c = categories.takeAt(index); + if (c->parent() == q) { + c->deleteLater(); + } + + q->endRemoveRows(); + Q_EMIT q->countChanged(); +} + +QVariant ConfigModelPrivate::get(int row) const +{ + QVariantMap value; + if (row < 0 || row >= categories.count()) { + return value; + } + + value[QStringLiteral("name")] = categories.at(row)->name(); + value[QStringLiteral("icon")] = categories.at(row)->icon(); + value[QStringLiteral("pluginName")] = categories.at(row)->pluginName(); + value[QStringLiteral("source")] = q->data(q->index(row, 0), ConfigModel::SourceRole); + value[QStringLiteral("includeMargins")] = categories.at(row)->includeMargins(); + value[QStringLiteral("visible")] = categories.at(row)->visible(); + value[QStringLiteral("kcm")] = q->data(q->index(row, 0), ConfigModel::KCMRole); + + return value; +} + +ConfigModel::ConfigModel(QObject *parent) + : QAbstractListModel(parent) + , d(new ConfigModelPrivate(this)) +{ +} + +ConfigModel::~ConfigModel() +{ + delete d; +} + +int ConfigModel::rowCount(const QModelIndex &index) const +{ + if (index.column() > 0) { + return 0; + } + return d->categories.count(); +} + +QVariant ConfigModel::data(const QModelIndex &index, int role) const +{ + if (index.row() < 0 || index.row() >= d->categories.count()) { + return QVariant(); + } + switch (role) { + case NameRole: + return d->categories.at(index.row())->name(); + case IconRole: + return d->categories.at(index.row())->icon(); + case SourceRole: { + const QString source = d->categories.at(index.row())->source(); + // Quick check if source is an absolute path or not + if (d->appletInterface && !source.isEmpty() && !(source.startsWith(QLatin1Char('/')) && source.endsWith(QLatin1String("qml")))) { + return d->appletInterface.data()->fileUrl("ui", source); + } else { + return source; + } + } + case PluginNameRole: + return d->categories.at(index.row())->pluginName(); + case IncludeMarginsRole: + return d->categories.at(index.row())->includeMargins(); + case VisibleRole: + return d->categories.at(index.row())->visible(); + case KCMRole: { + const QString pluginName = d->categories.at(index.row())->pluginName(); + // no kcm is registered for this row, it's a normal qml-only entry + if (pluginName.isEmpty()) { + return QVariant(); + } + + if (d->kcms.contains(pluginName)) { + return QVariant::fromValue(d->kcms.value(pluginName)); + } + auto parent = const_cast(this); + auto engine = new PlasmaQuick::SharedQmlEngine(parent); + auto cmResult = KQuickConfigModuleLoader::loadModule(KPluginMetaData(pluginName), parent, QVariantList(), engine->engine()); + if (KQuickConfigModule *cm = cmResult.plugin) { + if (QQmlContext *ctx = QQmlEngine::contextForObject(this)) { + // assign the ConfigModule the same QML context as we have so it can use the same QML engine as we do + QQmlEngine::setContextForObject(cmResult.plugin, ctx); + } + + d->kcms[pluginName] = cm; + return QVariant::fromValue(cm); + } else { + qCDebug(LOG_PLASMAQUICK) << "Error loading KCM:" << cmResult.errorText; + return QVariant(); + } + } + default: + return QVariant(); + } +} + +QHash ConfigModel::roleNames() const +{ + return { + {NameRole, "name"}, + {IconRole, "icon"}, + {SourceRole, "source"}, + {PluginNameRole, "pluginName"}, + {IncludeMarginsRole, "includeMargins"}, + {VisibleRole, "visible"}, + {KCMRole, "kcm"}, + }; +} + +QVariant ConfigModel::get(int row) const +{ + return d->get(row); +} + +void ConfigModel::appendCategory(const QString &iconName, const QString &name, const QString &path, const QString &pluginName) +{ + ConfigCategory *cat = new ConfigCategory(this); + cat->setIcon(iconName); + cat->setName(name); + cat->setSource(path); + cat->setPluginName(pluginName); + d->appendCategory(cat); +} + +void ConfigModel::appendCategory(const QString &iconName, const QString &name, const QString &path, const QString &pluginName, bool visible) +{ + ConfigCategory *cat = new ConfigCategory(this); + cat->setIcon(iconName); + cat->setName(name); + cat->setSource(path); + cat->setPluginName(pluginName); + cat->setVisible(visible); + d->appendCategory(cat); +} + +void ConfigModel::appendCategory(ConfigCategory *category) +{ + d->appendCategory(category); +} + +void ConfigModel::removeCategory(ConfigCategory *category) +{ + d->removeCategory(category); +} + +void ConfigModel::removeCategoryAt(int index) +{ + d->removeCategoryAt(index); +} + +void ConfigModel::clear() +{ + d->clear(); +} + +void ConfigModel::setApplet(Plasma::Applet *interface) +{ + d->appletInterface = interface; +} + +Plasma::Applet *ConfigModel::applet() const +{ + return d->appletInterface.data(); +} + +QQmlListProperty ConfigModel::categories() +{ + return QQmlListProperty(this, + nullptr, + ConfigModelPrivate::categories_append, + ConfigModelPrivate::categories_count, + ConfigModelPrivate::categories_at, + ConfigModelPrivate::categories_clear); +} + +} + +#include "moc_configmodel.cpp" diff --git a/src/plasmaquick/configmodel.h b/src/plasmaquick/configmodel.h new file mode 100644 index 0000000..17e98f0 --- /dev/null +++ b/src/plasmaquick/configmodel.h @@ -0,0 +1,125 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + SPDX-FileCopyrightText: 2015 Eike Hein + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef CONFIGMODEL_H +#define CONFIGMODEL_H + +#include +#include + +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the public Plasma API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +namespace Plasma +{ +class Applet; +} + +namespace PlasmaQuick +{ +class ConfigPropertyMap; + +class ConfigCategoryPrivate; + +class ConfigModelPrivate; +class ConfigCategory; + +/** + * This model contains all the possible config categories for a dialog, + * such as categories of the config dialog for an Applet + * TODO: it should probably become an import instead of a library? + * + * Import Statement + * @code import org.kde.plasma.configuration @endcode + * @version 2.0 + */ +class PLASMAQUICK_EXPORT ConfigModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty categories READ categories CONSTANT) + Q_CLASSINFO("DefaultProperty", "categories") + Q_PROPERTY(int count READ count NOTIFY countChanged) + +public: + enum Roles { + NameRole = Qt::UserRole + 1, + IconRole, + SourceRole, + PluginNameRole, + IncludeMarginsRole, + VisibleRole, + KCMRole, + }; + Q_ENUM(Roles) + + explicit ConfigModel(QObject *parent = nullptr); + ~ConfigModel() override; + + /** + * add a new category in the model + * @param ConfigCategory the new category + **/ + void appendCategory(const QString &iconName, const QString &name, const QString &path, const QString &pluginName); + + Q_INVOKABLE void appendCategory(const QString &iconName, const QString &name, const QString &path, const QString &pluginName, bool visible); + // QML Engine isn't particularly smart resolving namespaces, hence fully qualified signature + Q_INVOKABLE void appendCategory(PlasmaQuick::ConfigCategory *category); + + Q_INVOKABLE void removeCategory(PlasmaQuick::ConfigCategory *category); + Q_INVOKABLE void removeCategoryAt(int index); + + /** + * clears the model + **/ + void clear(); + + void setApplet(Plasma::Applet *interface); + Plasma::Applet *applet() const; + + int count() + { + return rowCount(); + } + int rowCount(const QModelIndex &index = QModelIndex()) const override; + QVariant data(const QModelIndex &, int) const override; + QHash roleNames() const override; + + /** + * @param row the row for which the data will be returned + * @return the data of the specified row + **/ + Q_INVOKABLE QVariant get(int row) const; + + /** + * @return the categories of the model + **/ + QQmlListProperty categories(); + +Q_SIGNALS: + /** + * emitted when the count is changed + **/ + void countChanged(); + +private: + friend class ConfigModelPrivate; + ConfigModelPrivate *const d; +}; + +} + +#endif // multiple inclusion guard diff --git a/src/plasmaquick/configview.cpp b/src/plasmaquick/configview.cpp new file mode 100644 index 0000000..7ad9ccf --- /dev/null +++ b/src/plasmaquick/configview.cpp @@ -0,0 +1,407 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "configview.h" +#include "Plasma/Applet" +#include "Plasma/Containment" +#include "appletcontext_p.h" +#include "appletquickitem.h" +#include "configcategory_p.h" +#include "configmodel.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +// Unfortunately QWINDOWSIZE_MAX is not exported +#define DIALOGSIZE_MAX ((1 << 24) - 1) + +namespace PlasmaQuick +{ +//////////////////////////////ConfigView + +class ConfigViewPrivate +{ +public: + ConfigViewPrivate(Plasma::Applet *appl, ConfigView *view); + ~ConfigViewPrivate() = default; + + void init(); + + void updateMinimumWidth(); + void updateMinimumHeight(); + void updateMaximumWidth(); + void updateMaximumHeight(); + void updateTitle(); + void mainItemLoaded(); + + ConfigView *q; + QPointer applet; + ConfigModel *configModel; + ConfigModel *kcmConfigModel; + Plasma::Corona *corona; + AppletContext *rootContext; + QQmlEngine *engine = nullptr; + QQuickItem *rootItem = nullptr; + + // Attached Layout property of mainItem, if any + QPointer mainItemLayout; +}; + +ConfigViewPrivate::ConfigViewPrivate(Plasma::Applet *appl, ConfigView *view) + : q(view) + , applet(appl) + , corona(nullptr) +{ + engine = new QQmlEngine(q); +} + +void ConfigViewPrivate::init() +{ + if (!applet) { + qWarning() << "Null applet passed to constructor"; + return; + } + if (!applet.data()->pluginMetaData().isValid()) { + qWarning() << "Invalid applet passed to constructor"; + if (applet->containment()) { + corona = applet->containment()->corona(); + } + return; + } + + rootContext = new AppletContext(q->engine(), applet, nullptr); + rootContext->setParent(q->engine()); + + applet.data()->setUserConfiguring(true); + + KLocalizedContext *localizedContextObject = new KLocalizedContext(q->engine()); + localizedContextObject->setTranslationDomain(applet->translationDomain()); + rootContext->setContextObject(localizedContextObject); + + // FIXME: problem on nvidia, all windows should be transparent or won't show + q->setColor(Qt::transparent); + updateTitle(); + + // systray case + if (!applet.data()->containment()->corona()) { + Plasma::Applet *a = qobject_cast(applet.data()->containment()->parent()); + if (a) { + corona = a->containment()->corona(); + } + } else { + if (!applet.data()->containment()->corona()->kPackage().isValid()) { + qWarning() << "Invalid home screen package"; + } + corona = applet.data()->containment()->corona(); + } + if (!corona) { + qWarning() << "Cannot find a Corona, this should never happen!"; + return; + } + + const auto pkg = corona->kPackage(); + if (pkg.isValid()) { + new QQmlFileSelector(q->engine(), q->engine()); + } + + if (!qEnvironmentVariableIntValue("PLASMA_NO_CONTEXTPROPERTIES")) { + rootContext->setContextProperties({QQmlContext::PropertyPair{QStringLiteral("plasmoid"), QVariant::fromValue(applet.data())}, + QQmlContext::PropertyPair{QStringLiteral("configDialog"), QVariant::fromValue(q)}}); + } + + // config model local of the applet + QQmlComponent component(q->engine(), applet.data()->configModel()); + QObject *object = component.create(rootContext); + configModel = qobject_cast(object); + + if (configModel) { + configModel->setApplet(applet.data()); + configModel->setParent(q); + } else { + delete object; + } + + QStringList kcms = applet.data()->pluginMetaData().value(QStringLiteral("X-Plasma-ConfigPlugins"), QStringList()); + + // filter out non-authorized KCMs + // KAuthorized expects KCMs with .desktop suffix, so we can't just pass everything + // to KAuthorized::authorizeControlModules verbatim + kcms.erase(std::remove_if(kcms.begin(), + kcms.end(), + [](const QString &kcm) { + return !KAuthorized::authorizeControlModule(kcm + QLatin1String(".desktop")); + }), + kcms.end()); + + if (!kcms.isEmpty()) { + if (!configModel) { + configModel = new ConfigModel(q); + } + + for (const QString &kcm : std::as_const(kcms)) { + // Only look for KCMs in the "kcms_" folder where new QML KCMs live + // because we don't support loading QWidgets KCMs + KPluginMetaData md(QLatin1String("kcms/") + kcm); + + if (!md.isValid()) { + qWarning() << "Could not find" << kcm + << "requested by X-Plasma-ConfigPlugins. Ensure that it exists, is a QML KCM, and lives in the 'kcms/' subdirectory."; + continue; + } + + configModel->appendCategory(md.iconName(), md.name(), QString(), QLatin1String("kcms/") + kcm); + } + } +} + +void ConfigViewPrivate::updateMinimumWidth() +{ + if (mainItemLayout) { + q->setMinimumWidth(mainItemLayout.data()->property("minimumWidth").toInt()); + // Sometimes setMinimumWidth doesn't actually resize: Qt bug? + + q->setWidth(qMax(q->width(), q->minimumWidth())); + } else { + q->setMinimumWidth(-1); + } +} + +void ConfigViewPrivate::updateMinimumHeight() +{ + if (mainItemLayout) { + q->setMinimumHeight(mainItemLayout.data()->property("minimumHeight").toInt()); + // Sometimes setMinimumHeight doesn't actually resize: Qt bug? + + q->setHeight(qMax(q->height(), q->minimumHeight())); + } else { + q->setMinimumHeight(-1); + } +} + +void ConfigViewPrivate::updateMaximumWidth() +{ + if (mainItemLayout) { + const int hint = mainItemLayout.data()->property("maximumWidth").toInt(); + + if (hint > 0) { + q->setMaximumWidth(hint); + } else { + q->setMaximumWidth(DIALOGSIZE_MAX); + } + } else { + q->setMaximumWidth(DIALOGSIZE_MAX); + } +} + +void ConfigViewPrivate::updateMaximumHeight() +{ + if (mainItemLayout) { + const int hint = mainItemLayout.data()->property("maximumHeight").toInt(); + + if (hint > 0) { + q->setMaximumHeight(hint); + } else { + q->setMaximumHeight(DIALOGSIZE_MAX); + } + } else { + q->setMaximumHeight(DIALOGSIZE_MAX); + } +} + +void ConfigViewPrivate::updateTitle() +{ + QVariant itemTitle = rootItem ? rootItem->property("title") : QVariant(); + q->setTitle(itemTitle.canConvert() ? i18n("%1 — %2 Settings", itemTitle.toString(), applet.data()->title()) + : i18n("%1 Settings", applet.data()->title())); +} + +void ConfigViewPrivate::mainItemLoaded() +{ + if (applet) { + KConfigGroup cg = applet.data()->config(); + cg = KConfigGroup(&cg, QStringLiteral("ConfigDialog")); + q->resize(cg.readEntry("DialogWidth", q->width()), cg.readEntry("DialogHeight", q->height())); + + if (rootItem->property("title").isValid()) { + QObject::connect(rootItem, SIGNAL(titleChanged()), q, SLOT(updateTitle())); + updateTitle(); + } + } + + // Extract the representation's Layout, if any + QObject *layout = nullptr; + + // Search a child that has the needed Layout properties + // HACK: here we are not type safe, but is the only way to access to a pointer of Layout + const auto children = rootItem->children(); + for (QObject *child : children) { + // find for the needed property of Layout: minimum/maximum/preferred sizes and fillWidth/fillHeight + if (child->property("minimumWidth").isValid() && child->property("minimumHeight").isValid() && child->property("preferredWidth").isValid() + && child->property("preferredHeight").isValid() && child->property("maximumWidth").isValid() && child->property("maximumHeight").isValid() + && child->property("fillWidth").isValid() && child->property("fillHeight").isValid()) { + layout = child; + break; + } + } + mainItemLayout = layout; + + if (layout) { + QObject::connect(layout, SIGNAL(minimumWidthChanged()), q, SLOT(updateMinimumWidth())); + QObject::connect(layout, SIGNAL(minimumHeightChanged()), q, SLOT(updateMinimumHeight())); + QObject::connect(layout, SIGNAL(maximumWidthChanged()), q, SLOT(updateMaximumWidth())); + QObject::connect(layout, SIGNAL(maximumHeightChanged()), q, SLOT(updateMaximumHeight())); + + updateMinimumWidth(); + updateMinimumHeight(); + updateMaximumWidth(); + updateMaximumHeight(); + } +} + +ConfigView::ConfigView(Plasma::Applet *applet, QWindow *parent) + : QQuickWindow(parent) + , d(new ConfigViewPrivate(applet, this)) +{ + setIcon(QIcon::fromTheme(QStringLiteral("configure"))); + // Only register types once + [[maybe_unused]] static int configModelRegisterResult = qmlRegisterType("org.kde.plasma.configuration", 2, 0, "ConfigModel"); + [[maybe_unused]] static int configCategoryRegisterResult = qmlRegisterType("org.kde.plasma.configuration", 2, 0, "ConfigCategory"); + d->init(); + connect(applet, &QObject::destroyed, this, &ConfigView::close); +} + +ConfigView::~ConfigView() +{ + if (d->applet) { + d->applet.data()->setUserConfiguring(false); + if (d->applet.data()->containment() && d->applet.data()->containment()->corona()) { + d->applet.data()->containment()->corona()->requestConfigSync(); + } + } + delete d->rootItem; +} + +QQmlEngine *ConfigView::engine() +{ + return d->engine; +} + +QQmlContext *ConfigView::rootContext() +{ + return d->rootContext; +} + +void ConfigView::setSource(const QUrl &src) +{ + QQmlComponent uiComponent(engine(), src); + if (uiComponent.isError()) { + for (const auto &error : uiComponent.errors()) { + qWarning() << error; + } + } + + std::unique_ptr object(uiComponent.createWithInitialProperties({{QStringLiteral("parent"), QVariant::fromValue(contentItem())}}, d->rootContext)); + d->rootItem = qobject_cast(object.get()); + if (!d->rootItem) { + return; + } + Q_UNUSED(object.release()); + d->mainItemLoaded(); + + if (d->rootItem->implicitHeight() > 0 || d->rootItem->implicitWidth() > 0) { + resize(QSize(d->rootItem->implicitWidth(), d->rootItem->implicitHeight())); + } + d->rootItem->setSize(QSizeF(width(), height())); + + connect(d->rootItem, &QQuickItem::implicitWidthChanged, this, [this]() { + setWidth(d->rootItem->implicitWidth()); + }); + connect(d->rootItem, &QQuickItem::implicitHeightChanged, this, [this]() { + setWidth(d->rootItem->implicitHeight()); + }); +} + +QQuickItem *ConfigView::rootObject() +{ + return d->rootItem; +} + +void ConfigView::init() +{ + setSource(d->corona->kPackage().fileUrl("appletconfigurationui")); +} + +Plasma::Applet *ConfigView::applet() +{ + return d->applet.data(); +} + +ConfigModel *ConfigView::configModel() const +{ + return d->configModel; +} + +QString ConfigView::appletGlobalShortcut() const +{ + if (!d->applet) { + return QString(); + } + + return d->applet.data()->globalShortcut().toString(); +} + +void ConfigView::setAppletGlobalShortcut(const QString &shortcut) +{ + if (!d->applet || d->applet.data()->globalShortcut().toString().toLower() == shortcut.toLower()) { + return; + } + + d->applet.data()->setGlobalShortcut(shortcut); + Q_EMIT appletGlobalShortcutChanged(); +} + +// To emulate Qt::WA_DeleteOnClose that QWindow doesn't have +void ConfigView::hideEvent(QHideEvent *ev) +{ + QQuickWindow::hideEvent(ev); + deleteLater(); +} + +void ConfigView::resizeEvent(QResizeEvent *re) +{ + if (!d->rootItem) { + return; + } + + d->rootItem->setSize(re->size()); + + if (d->applet) { + KConfigGroup cg = d->applet.data()->config(); + cg = KConfigGroup(&cg, QStringLiteral("ConfigDialog")); + cg.writeEntry("DialogWidth", re->size().width()); + cg.writeEntry("DialogHeight", re->size().height()); + } + + QQuickWindow::resizeEvent(re); +} + +} + +#include "moc_configview.cpp" diff --git a/src/plasmaquick/configview.h b/src/plasmaquick/configview.h new file mode 100644 index 0000000..d9246a4 --- /dev/null +++ b/src/plasmaquick/configview.h @@ -0,0 +1,88 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef CONFIGVIEW_H +#define CONFIGVIEW_H + +#include +#include + +#include +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the public Plasma API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +namespace Plasma +{ +class Applet; +} + +namespace PlasmaQuick +{ +class ConfigViewPrivate; + +class ConfigModel; + +class PLASMAQUICK_EXPORT ConfigView : public QQuickWindow +{ + Q_OBJECT + Q_PROPERTY(PlasmaQuick::ConfigModel *configModel READ configModel CONSTANT) + Q_PROPERTY(QString appletGlobalShortcut READ appletGlobalShortcut WRITE setAppletGlobalShortcut NOTIFY appletGlobalShortcutChanged) + +public: + /** + * @param applet the applet of this ConfigView + * @param parent the QWindow in which this ConfigView is parented to + **/ + ConfigView(Plasma::Applet *applet, QWindow *parent = nullptr); + ~ConfigView() override; + + QQmlEngine *engine(); + QQmlContext *rootContext(); + void setSource(const QUrl &src); + QQuickItem *rootObject(); + + virtual void init(); + + Plasma::Applet *applet(); + + QString appletGlobalShortcut() const; + void setAppletGlobalShortcut(const QString &shortcut); + + /** + * @return the ConfigModel of the ConfigView + **/ + PlasmaQuick::ConfigModel *configModel() const; + +Q_SIGNALS: + void appletGlobalShortcutChanged(); + +protected: + void hideEvent(QHideEvent *ev) override; + void resizeEvent(QResizeEvent *re) override; + +private: + QScopedPointer const d; + + Q_PRIVATE_SLOT(d, void updateMinimumWidth()) + Q_PRIVATE_SLOT(d, void updateMinimumHeight()) + Q_PRIVATE_SLOT(d, void updateMaximumWidth()) + Q_PRIVATE_SLOT(d, void updateMaximumHeight()) + Q_PRIVATE_SLOT(d, void updateTitle()) +}; + +} + +#endif // multiple inclusion guard diff --git a/src/plasmaquick/containmentview.cpp b/src/plasmaquick/containmentview.cpp new file mode 100644 index 0000000..a0d63b5 --- /dev/null +++ b/src/plasmaquick/containmentview.cpp @@ -0,0 +1,295 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "containmentview.h" +#include "configview.h" +#include "plasmoid/containmentitem.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace PlasmaQuick +{ +class ContainmentViewPrivate +{ +public: + ContainmentViewPrivate(Plasma::Corona *corona, ContainmentView *view); + ~ContainmentViewPrivate(); + + void setContainment(Plasma::Containment *cont); + Plasma::Types::FormFactor formFactor() const; + Plasma::Types::Location location() const; + void showConfigurationInterface(Plasma::Applet *applet); + void updateDestroyed(bool destroyed); + /** + * Reconnects the relevant signals after a screen change + **/ + void reactToScreenChange(); + + ContainmentView *q; + friend class ContainmentView; + Plasma::Corona *corona; + QScreen *lastScreen; + QPointer containment; + QPointer configContainmentView; +}; + +ContainmentViewPrivate::ContainmentViewPrivate(Plasma::Corona *cor, ContainmentView *view) + : q(view) + , corona(cor) +{ +} + +ContainmentViewPrivate::~ContainmentViewPrivate() +{ +} + +void ContainmentViewPrivate::setContainment(Plasma::Containment *cont) +{ + if (containment == cont) { + return; + } + + Plasma::Types::Location oldLoc = location(); + Plasma::Types::FormFactor oldForm = formFactor(); + + if (containment) { + QObject::disconnect(containment, nullptr, q, nullptr); + QObject *oldGraphicObject = AppletQuickItem::itemForApplet(containment); + if (auto item = qobject_cast(oldGraphicObject)) { + // TODO: delete the item when needed instead of just hiding, but there are quite a lot of cornercases to manage beforehand + item->setVisible(false); + } + containment->reactToScreenChange(); + } + + containment = cont; + + if (oldLoc != location()) { + Q_EMIT q->locationChanged(location()); + } + if (oldForm != formFactor()) { + Q_EMIT q->formFactorChanged(formFactor()); + } + + Q_EMIT q->containmentChanged(); + + // we are QuickViewSharedEngine::SizeRootObjectToView, but that's not enough, as + // the root object isn't immediately resized (done at the resizeEvent handler). + // by resizing it just before restoring the containment, it removes a chain of resizes at startup + if (q->rootObject()) { + q->rootObject()->setSize(q->size()); + } + if (cont) { + cont->reactToScreenChange(); + QObject::connect(cont, &Plasma::Containment::locationChanged, q, &ContainmentView::locationChanged); + QObject::connect(cont, &Plasma::Containment::formFactorChanged, q, &ContainmentView::formFactorChanged); + QObject::connect(cont, &Plasma::Containment::configureRequested, q, &ContainmentView::showConfigurationInterface); + QObject::connect(cont, SIGNAL(destroyedChanged(bool)), q, SLOT(updateDestroyed(bool))); + + // Panels are created invisible and the code below ensures they are only + // shown once their contents have settled to avoid visual glitches on startup + if (cont->containmentType() == Plasma::Containment::Type::Panel || cont->containmentType() == Plasma::Containment::Type::CustomPanel) { + QObject::connect(cont, &Plasma::Containment::uiReadyChanged, q, [this, cont](bool ready) { + if (ready && !cont->destroyed()) { + q->setVisible(true); + } + }); + + q->setVisible(!cont->destroyed() && cont->isUiReady()); + } + } else { + return; + } + + QQuickItem *graphicObject = AppletQuickItem::itemForApplet(containment); + + if (graphicObject) { + // qDebug() << "using as graphic containment" << graphicObject << containment.data(); + + graphicObject->setFocus(true); + // by resizing before adding, it will avoid some resizes in most cases + graphicObject->setSize(q->size()); + graphicObject->setParentItem(q->rootObject()); + if (q->rootObject()) { + q->rootObject()->setProperty("containment", QVariant::fromValue(graphicObject)); + QObject *wpGraphicObject = containment->property("wallpaperGraphicsObject").value(); + if (wpGraphicObject) { + q->rootObject()->setProperty("wallpaper", QVariant::fromValue(wpGraphicObject)); + } + } else { + qWarning() << "Could not set containment property on rootObject"; + } + } else { + qWarning() << "Containment graphic object not valid"; + } +} + +Plasma::Types::Location ContainmentViewPrivate::location() const +{ + if (!containment) { + return Plasma::Types::Desktop; + } + return containment->location(); +} + +Plasma::Types::FormFactor ContainmentViewPrivate::formFactor() const +{ + if (!containment) { + return Plasma::Types::Planar; + } + return containment->formFactor(); +} + +void ContainmentViewPrivate::showConfigurationInterface(Plasma::Applet *applet) +{ + if (configContainmentView) { + if (configContainmentView->applet() != applet) { + configContainmentView->hide(); + configContainmentView->deleteLater(); + } else { + configContainmentView->raise(); + configContainmentView->requestActivate(); + return; + } + } + + if (!applet || !applet->containment()) { + return; + } + + configContainmentView = new ConfigView(applet); + + configContainmentView->init(); + configContainmentView->show(); +} + +void ContainmentViewPrivate::updateDestroyed(bool destroyed) +{ + q->setVisible(!destroyed); +} + +void ContainmentViewPrivate::reactToScreenChange() +{ + QScreen *newScreen = q->screen(); + + if (newScreen == lastScreen) { + return; + } + + QObject::disconnect(lastScreen, nullptr, q, nullptr); + lastScreen = newScreen; + QObject::connect(newScreen, &QScreen::geometryChanged, q, + &ContainmentView::screenGeometryChanged); + Q_EMIT q->screenGeometryChanged(); +} + +ContainmentView::ContainmentView(Plasma::Corona *corona, QWindow *parent) + : PlasmaQuick::QuickViewSharedEngine(parent) + , d(new ContainmentViewPrivate(corona, this)) +{ + setColor(Qt::transparent); + + d->lastScreen = screen(); + QObject::connect(d->lastScreen, &QScreen::geometryChanged, this, + &ContainmentView::screenGeometryChanged); + QObject::connect(this, &ContainmentView::screenChanged, this, + [this]() { + d->reactToScreenChange(); + }); + + if (corona->kPackage().isValid()) { + const auto info = corona->kPackage().metadata(); + if (info.isValid()) { + setTranslationDomain(QStringLiteral("plasma_shell_") + info.pluginId()); + } else { + qWarning() << "Invalid corona package metadata"; + } + } else { + qWarning() << "Invalid home screen package"; + } + + setResizeMode(ContainmentView::SizeRootObjectToView); +} + +ContainmentView::~ContainmentView() +{ + delete d; +} + +void ContainmentView::destroy() +{ + // it will hide and deallocate the window so that no visibility or geometry + // changes will be emitted during the destructor, avoiding potential crash + // situations + QWindow::destroy(); + + // TODO: do we need a version which does not create? + QQuickItem *graphicObject = AppletQuickItem::itemForApplet(d->containment); + if (auto item = qobject_cast(graphicObject)) { + item->setVisible(false); + item->setParentItem(nullptr); // First, remove the item from the view + } + deleteLater(); // delete the view +} + +Plasma::Corona *ContainmentView::corona() const +{ + return d->corona; +} + +KConfigGroup ContainmentView::config() const +{ + if (!containment()) { + return KConfigGroup(); + } + KConfigGroup views(KSharedConfig::openConfig(), QStringLiteral("PlasmaContainmentViews")); + return KConfigGroup(&views, QString::number(containment()->lastScreen())); +} + +void ContainmentView::setContainment(Plasma::Containment *cont) +{ + d->setContainment(cont); +} + +Plasma::Containment *ContainmentView::containment() const +{ + return d->containment; +} + +void ContainmentView::setLocation(Plasma::Types::Location location) +{ + d->containment->setLocation(location); +} + +Plasma::Types::Location ContainmentView::location() const +{ + return d->location(); +} + +Plasma::Types::FormFactor ContainmentView::formFactor() const +{ + return d->formFactor(); +} + +QRectF ContainmentView::screenGeometry() +{ + return screen()->geometry(); +} + +void ContainmentView::showConfigurationInterface(Plasma::Applet *applet) +{ + d->showConfigurationInterface(applet); +} + +} + +#include "moc_containmentview.cpp" diff --git a/src/plasmaquick/containmentview.h b/src/plasmaquick/containmentview.h new file mode 100644 index 0000000..bf72820 --- /dev/null +++ b/src/plasmaquick/containmentview.h @@ -0,0 +1,127 @@ +/* + SPDX-FileCopyrightText: 2012 Marco Martin + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#ifndef PLASMAQUICKCONTAINMENTVIEW_H +#define PLASMAQUICKCONTAINMENTVIEW_H + +#include "plasma/containment.h" +#include "plasma/corona.h" +#include +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the public Plasma API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +namespace PlasmaQuick +{ +class ContainmentViewPrivate; + +class PLASMAQUICK_EXPORT ContainmentView : public PlasmaQuick::QuickViewSharedEngine +{ + Q_OBJECT + Q_PROPERTY(Plasma::Types::Location location READ location WRITE setLocation NOTIFY locationChanged) + Q_PROPERTY(Plasma::Types::FormFactor formFactor READ formFactor NOTIFY formFactorChanged) + Q_PROPERTY(QRectF screenGeometry READ screenGeometry NOTIFY screenGeometryChanged) + +public: + /** + * @param corona the corona of this view + * @param parent the QWindow this ContainmentView is parented to + **/ + explicit ContainmentView(Plasma::Corona *corona, QWindow *parent = nullptr); + ~ContainmentView() override; + + /** + * Unassign any containment UI from this view, then delete it + */ + void destroy(); + + /** + * @return the corona of this view + **/ + Plasma::Corona *corona() const; + + /** + * @return the KConfigGroup of this view + **/ + virtual KConfigGroup config() const; + + /** + * sets the containment for this view + * @param cont the containment of this view + **/ + void setContainment(Plasma::Containment *cont); + + /** + * @return the containment of this ContainmentView + **/ + Plasma::Containment *containment() const; + + /** + * @return the location of this ContainmentView + **/ + Plasma::Types::Location location() const; + + /** + * Sets the location of the ContainmentView + * @param location the location of the ContainmentView + **/ + void setLocation(Plasma::Types::Location location); + + /** + * @return the formfactor of the ContainmentView + **/ + Plasma::Types::FormFactor formFactor() const; + + /** + * @return the screenGeometry of the ContainmentView + **/ + QRectF screenGeometry(); + +protected Q_SLOTS: + /** + * It will be called when the configuration is requested + */ + virtual void showConfigurationInterface(Plasma::Applet *applet); + +Q_SIGNALS: + /** + * emitted when the location is changed + **/ + void locationChanged(Plasma::Types::Location location); + + /** + * emitted when the formfactor is changed + **/ + void formFactorChanged(Plasma::Types::FormFactor formFactor); + + /** + * emitted when the containment is changed + **/ + void containmentChanged(); + + /** + * emitted when the screenGeometry is changed + **/ + void screenGeometryChanged(); + +private: + ContainmentViewPrivate *const d; + Q_PRIVATE_SLOT(d, void updateDestroyed(bool)) + friend class ContainmentViewPrivate; +}; + +} + +#endif // CONTAINMENTVIEW_H diff --git a/src/plasmaquick/dialog.cpp b/src/plasmaquick/dialog.cpp new file mode 100644 index 0000000..c505721 --- /dev/null +++ b/src/plasmaquick/dialog.cpp @@ -0,0 +1,1651 @@ +/* + SPDX-FileCopyrightText: 2011 Marco Martin + SPDX-FileCopyrightText: 2013 Sebastian Kügler + SPDX-FileCopyrightText: 2014 Martin Gräßlin + SPDX-FileCopyrightText: 2014 Vishesh Handa + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "dialog.h" +#include "../declarativeimports/core/config-x11.h" +#include "appletquickitem.h" +#include "config-plasma.h" +#include "configview.h" +#include "dialogbackground_p.h" +#include "dialogshadows_p.h" +#include "sharedqmlengine.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#if HAVE_X11 +#include +#endif + +#include "plasmashellwaylandintegration.h" + +// Unfortunately QWINDOWSIZE_MAX is not exported +#define DIALOGSIZE_MAX ((1 << 24) - 1) + +namespace PlasmaQuick +{ +class DialogPrivate +{ +public: + DialogPrivate(Dialog *dialog) + : q(dialog) + , location(Plasma::Types::BottomEdge) + , dialogBackground(new DialogBackground(q->contentItem())) + , hasMask(false) + , type(Dialog::Normal) + , hideOnWindowDeactivate(false) + , outputOnly(false) + , visible(false) + , resizableEdges({}) + , floating(0) + , overridingCursor(false) + , appletInterface(nullptr) + , componentComplete(dialog->parent() == nullptr) + , needsSetupNextExpose(true) + , backgroundHints(Dialog::StandardBackground) + { + } + + // SLOTS + /** + * Sync Borders updates the enabled borders of the dialogBackground depending + * on the geometry of the window. + * + * \param windowGeometry The window geometry which should be taken into + * consideration when activating/deactivating certain borders + */ + void syncBorders(const QRect &windowGeometry); + + /** + * This function sets the blurBehind, background contrast and shadows. It + * does so wrt the dialogBackground. So make sure the dialogBackground is the + * correct size before calling this function. + */ + void updateTheme(); + void updateVisibility(bool visible); + + void updateMinimumWidth(); + void updateMinimumHeight(); + void updateMaximumWidth(); + void updateMaximumHeight(); + void updateResizableEdges(); + void updateSizeFromAppletInterface(); + + /** + * Gets the maximum and minimum size hints for the window based on the contents. it doesn't actually resize anything + */ + void getSizeHints(QSize &min, QSize &max) const; + + /** + * This function is an optimized version of updateMaximumHeight, + * updateMaximumWidth,updateMinimumWidth and updateMinimumHeight. + * It should be called when you need to call all 4 of these functions + * AND you have called syncToMainItemSize before. + */ + void updateLayoutParameters(); + + QRect availableScreenGeometryForPosition(const QPoint &pos) const; + + /** + * This function checks the current position of the dialog and repositions + * it so that no part of it is not on the screen + */ + void repositionIfOffScreen(); + + void slotMainItemSizeChanged(); + void slotWindowPositionChanged(); + + void syncToMainItemSize(); + + bool mainItemContainsPosition(const QPointF &point) const; + QPointF positionAdjustedForMainItem(const QPointF &point) const; + + void applyType(); + + bool updateMouseCursor(const QPointF &globalMousePos); + Qt::Edges hitTest(const QPointF &pos); + bool hitTestLeft(const QPointF &pos); + bool hitTestRight(const QPointF &pos); + bool hitTestTop(const QPointF &pos); + bool hitTestBottom(const QPointF &pos); + + Dialog *q; + Plasma::Types::Location location; + DialogBackground *dialogBackground; + QPointer mainItem; + QPointer visualParent; + + QRect cachedGeometry; + bool hasMask; + Dialog::WindowType type; + bool hideOnWindowDeactivate; + bool outputOnly; + bool visible; + Qt::Edges resizableEdges; + int floating; + bool overridingCursor; + AppletQuickItem *appletInterface; + Plasma::Theme theme; + bool componentComplete; + bool needsSetupNextExpose; + Dialog::BackgroundHints backgroundHints; + + // Attached Layout property of mainItem, if any + QPointer mainItemLayout; +}; + +static bool isRunningInKWin() +{ + static bool check = QGuiApplication::platformName() == QLatin1String("wayland-org.kde.kwin.qpa"); + return check; +} + +QRect DialogPrivate::availableScreenGeometryForPosition(const QPoint &pos) const +{ + // FIXME: QWindow::screen() never ever changes if the window is moved across + // virtual screens (normal two screens with X), this seems to be intentional + // as it's explicitly mentioned in the docs. Until that's changed or some + // more proper way of howto get the current QScreen for given QWindow is found, + // we simply iterate over the virtual screens and pick the one our QWindow + // says it's at. + QRect avail; + const auto screens = QGuiApplication::screens(); + for (QScreen *screen : screens) { + // we check geometry() but then take availableGeometry() + // to reliably check in which screen a position is, we need the full + // geometry, including areas for panels + if (screen->geometry().contains(pos)) { + avail = screen->availableGeometry(); + break; + } + } + + /* + * if the heuristic fails (because the topleft of the dialog is offscreen) + * use at least our screen() + * the screen should be correctly updated now on Qt 5.3+ so should be + * more reliable anyways (could be tried to remove the whole for loop + * above at this point) + * + * important: screen can be a nullptr... see bug 345173 + */ + if (avail.isEmpty() && q->screen()) { + avail = q->screen()->availableGeometry(); + } + + return avail; +} + +void DialogPrivate::syncBorders(const QRect &geom) +{ + QRect avail = availableScreenGeometryForPosition(geom.topLeft()); + int borders = KSvg::FrameSvg::AllBorders; + + // Tooltips always have all the borders + // floating windows have all borders + if (!q->flags().testFlag(Qt::ToolTip) && location != Plasma::Types::Floating && floating == 0) { + if (geom.x() <= avail.x() || location == Plasma::Types::LeftEdge) { + borders = borders & ~KSvg::FrameSvg::LeftBorder; + } + if (geom.y() <= avail.y() || location == Plasma::Types::TopEdge) { + borders = borders & ~KSvg::FrameSvg::TopBorder; + } + if (avail.right() <= geom.x() + geom.width() || location == Plasma::Types::RightEdge) { + borders = borders & ~KSvg::FrameSvg::RightBorder; + } + if (avail.bottom() <= geom.y() + geom.height() || location == Plasma::Types::BottomEdge) { + borders = borders & ~KSvg::FrameSvg::BottomBorder; + } + } + + if (dialogBackground->enabledBorders() != (KSvg::FrameSvg::EnabledBorder)borders) { + dialogBackground->setEnabledBorders((KSvg::FrameSvg::EnabledBorder)borders); + } +} + +void DialogPrivate::updateTheme() +{ + if (backgroundHints == Dialog::NoBackground) { + dialogBackground->setImagePath(QString()); + KWindowEffects::enableBlurBehind(q, false); + KWindowEffects::enableBackgroundContrast(q, false); + q->setMask(QRegion()); + DialogShadows::instance()->removeWindow(q); + } else { + auto prefix = QStringLiteral(""); + if ((backgroundHints & Dialog::SolidBackground) == Dialog::SolidBackground) { + prefix = QStringLiteral("solid/"); + } + if (type == Dialog::Tooltip) { + dialogBackground->setImagePath(prefix + QStringLiteral("widgets/tooltip")); + } else { + dialogBackground->setImagePath(prefix + QStringLiteral("dialogs/background")); + } + + const QRegion mask = dialogBackground->mask(); + KWindowEffects::enableBlurBehind(q, theme.blurBehindEnabled(), mask); + + KWindowEffects::enableBackgroundContrast(q, + theme.backgroundContrastEnabled(), + theme.backgroundContrast(), + theme.backgroundIntensity(), + theme.backgroundSaturation(), + mask); + + if (!KWindowSystem::isPlatformX11() || KX11Extras::compositingActive()) { + if (hasMask) { + hasMask = false; + q->setMask(QRegion()); + } + } else { + hasMask = true; + q->setMask(dialogBackground->mask()); + } + if (q->isVisible()) { + DialogShadows::instance()->addWindow(q, dialogBackground->enabledBorders()); + } + } +} + +void DialogPrivate::updateVisibility(bool visible) +{ + if (visible) { + if (visualParent && visualParent->window()) { + q->setTransientParent(visualParent->window()); + } + + if (q->location() == Plasma::Types::FullScreen) { + dialogBackground->setEnabledBorders(KSvg::FrameSvg::NoBorder); + + // We cache the original size of the item, to retrieve it + // when the dialog is switched back from fullscreen. + if (q->geometry() != q->screen()->availableGeometry()) { + cachedGeometry = q->geometry(); + } + q->setGeometry(q->screen()->availableGeometry()); + } else { + if (!cachedGeometry.isNull()) { + q->resize(cachedGeometry.size()); + slotWindowPositionChanged(); + if (visualParent) { + q->setPosition(q->popupPosition(visualParent, q->size())); + } + cachedGeometry = QRect(); + } + + if (mainItem) { + syncToMainItemSize(); + } + if (mainItemLayout) { + updateLayoutParameters(); + } + + // if is a wayland window that was hidden, we need + // to set its position again as there won't be any move event to sync QWindow::position and shellsurface::position + if (type != Dialog::OnScreenDisplay) { + PlasmaShellWaylandIntegration::get(q)->setPosition(q->position()); + } + } + } + + if (!q->flags().testFlag(Qt::ToolTip) && type != Dialog::Notification && type != Dialog::CriticalNotification) { + KWindowEffects::SlideFromLocation slideLocation = KWindowEffects::NoEdge; + + switch (location) { + case Plasma::Types::TopEdge: + slideLocation = KWindowEffects::TopEdge; + break; + case Plasma::Types::LeftEdge: + slideLocation = KWindowEffects::LeftEdge; + break; + case Plasma::Types::RightEdge: + slideLocation = KWindowEffects::RightEdge; + break; + case Plasma::Types::BottomEdge: + slideLocation = KWindowEffects::BottomEdge; + break; + // no edge, no slide + default: + break; + } + + KWindowEffects::slideWindow(q, slideLocation, -1); + } + + if (visible) { + q->raise(); + + applyType(); + } +} + +void DialogPrivate::updateMinimumWidth() +{ + Q_ASSERT(mainItem); + Q_ASSERT(mainItemLayout); + + if (!componentComplete) { + return; + } + + q->setMinimumWidth(0); + + // this is to try to get the internal item resized a tad before, but + // the flicker almost always happen anyways, so is *probably* useless + // this other kind of flicker is the view not being always focused exactly + // on the scene + int minimumWidth = mainItemLayout->property("minimumWidth").toInt() + dialogBackground->leftMargin() + dialogBackground->rightMargin(); + if (q->screen()) { + minimumWidth = qMin(q->screen()->availableGeometry().width(), minimumWidth); + } + q->contentItem()->setWidth(qMax(q->width(), minimumWidth)); + q->setWidth(qMax(q->width(), minimumWidth)); + + updateLayoutParameters(); +} + +void DialogPrivate::updateMinimumHeight() +{ + Q_ASSERT(mainItem); + Q_ASSERT(mainItemLayout); + + if (!componentComplete) { + return; + } + + q->setMinimumHeight(0); + + // this is to try to get the internal item resized a tad before, but + // the flicker almost always happen anyways, so is *probably* useless + // this other kind of flicker is the view not being always focused exactly + // on the scene + int minimumHeight = mainItemLayout->property("minimumHeight").toInt() + dialogBackground->topMargin() + dialogBackground->bottomMargin(); + if (q->screen()) { + minimumHeight = qMin(q->screen()->availableGeometry().height(), minimumHeight); + } + q->contentItem()->setHeight(qMax(q->height(), minimumHeight)); + q->setHeight(qMax(q->height(), minimumHeight)); + + updateLayoutParameters(); +} + +void DialogPrivate::updateMaximumWidth() +{ + Q_ASSERT(mainItem); + Q_ASSERT(mainItemLayout); + + if (!componentComplete) { + return; + } + + q->setMaximumWidth(DIALOGSIZE_MAX); + + int maximumWidth = mainItemLayout->property("maximumWidth").toInt() + dialogBackground->leftMargin() + dialogBackground->rightMargin(); + if (q->screen()) { + maximumWidth = qMin(q->screen()->availableGeometry().width(), maximumWidth); + } + q->contentItem()->setWidth(qMin(q->width(), maximumWidth)); + q->setWidth(qMin(q->width(), maximumWidth)); + + updateLayoutParameters(); +} + +void DialogPrivate::updateMaximumHeight() +{ + Q_ASSERT(mainItem); + Q_ASSERT(mainItemLayout); + + if (!componentComplete) { + return; + } + + q->setMaximumHeight(DIALOGSIZE_MAX); + + int maximumHeight = mainItemLayout->property("maximumHeight").toInt() + dialogBackground->topMargin() + dialogBackground->bottomMargin(); + if (q->screen()) { + maximumHeight = qMin(q->screen()->availableGeometry().height(), maximumHeight); + } + q->contentItem()->setHeight(qMin(q->height(), maximumHeight)); + q->setHeight(qMin(q->height(), maximumHeight)); + + updateLayoutParameters(); +} + +void DialogPrivate::updateResizableEdges() +{ + if (!appletInterface) { + resizableEdges = {}; + return; + } + + QSize min; + QSize max(DIALOGSIZE_MAX, DIALOGSIZE_MAX); + getSizeHints(min, max); + if (min == max) { + resizableEdges = {}; + return; + } + + switch (q->location()) { + case Plasma::Types::BottomEdge: + resizableEdges = Qt::LeftEdge | Qt::TopEdge | Qt::RightEdge; + break; + case Plasma::Types::TopEdge: + resizableEdges = Qt::LeftEdge | Qt::BottomEdge | Qt::RightEdge; + break; + case Plasma::Types::LeftEdge: + resizableEdges = Qt::TopEdge | Qt::BottomEdge | Qt::RightEdge; + break; + case Plasma::Types::RightEdge: + resizableEdges = Qt::LeftEdge | Qt::TopEdge | Qt::BottomEdge; + break; + case Plasma::Types::Floating: + case Plasma::Types::Desktop: + case Plasma::Types::FullScreen: + resizableEdges = {}; + break; + } +} + +void DialogPrivate::updateSizeFromAppletInterface() +{ + if (!appletInterface) { + return; + } + if (!mainItem) { + return; + } + if (!mainItemLayout) { + return; + } + + QSize min; + QSize max(DIALOGSIZE_MAX, DIALOGSIZE_MAX); + getSizeHints(min, max); + if (min == max) { + return; + } + + QVariant prefHeight = mainItemLayout->property("preferredHeight"); + QVariant prefWidth = mainItemLayout->property("preferredWidth"); + int defHeight = prefHeight.isNull() ? min.height() : prefHeight.toInt(); + int defWidth = prefWidth.isNull() ? min.width() : prefWidth.toInt(); + + KConfigGroup config = appletInterface->applet()->config(); + qreal popupWidth = config.readEntry("popupWidth", static_cast(defWidth)); + qreal popupHeight = config.readEntry("popupHeight", static_cast(defHeight)); + mainItemLayout->setProperty("preferredWidth", popupWidth); + mainItemLayout->setProperty("preferredHeight", popupHeight); + mainItem->setWidth(popupWidth); + mainItem->setHeight(popupHeight); + updateLayoutParameters(); +} + +void DialogPrivate::getSizeHints(QSize &min, QSize &max) const +{ + if (!componentComplete || !mainItem || !mainItemLayout) { + return; + } + Q_ASSERT(mainItem); + Q_ASSERT(mainItemLayout); + + int minimumHeight = mainItemLayout->property("minimumHeight").toInt(); + int maximumHeight = mainItemLayout->property("maximumHeight").toInt(); + maximumHeight = maximumHeight > 0 ? qMax(minimumHeight, maximumHeight) : DIALOGSIZE_MAX; + + int minimumWidth = mainItemLayout->property("minimumWidth").toInt(); + int maximumWidth = mainItemLayout->property("maximumWidth").toInt(); + maximumWidth = maximumWidth > 0 ? qMax(minimumWidth, maximumWidth) : DIALOGSIZE_MAX; + + minimumHeight += dialogBackground->topMargin() + dialogBackground->bottomMargin(); + maximumHeight += dialogBackground->topMargin() + dialogBackground->bottomMargin(); + minimumWidth += dialogBackground->leftMargin() + dialogBackground->rightMargin(); + maximumWidth += dialogBackground->leftMargin() + dialogBackground->rightMargin(); + + if (q->screen()) { + minimumWidth = qMin(q->screen()->availableGeometry().width(), minimumWidth); + minimumHeight = qMin(q->screen()->availableGeometry().height(), minimumHeight); + maximumWidth = qMin(q->screen()->availableGeometry().width(), maximumWidth); + maximumHeight = qMin(q->screen()->availableGeometry().height(), maximumHeight); + } + + // Make sure that we never return min that would be larger than max + min = QSize(qMin(minimumWidth, maximumWidth), qMin(minimumHeight, maximumHeight)); + max = QSize(maximumWidth, maximumHeight); +} + +void DialogPrivate::updateLayoutParameters() +{ + if (!componentComplete || !mainItem || !mainItemLayout || q->visibility() == QWindow::Hidden) { + return; + } + + mainItem->disconnect(q); + + QSize min; + QSize max(DIALOGSIZE_MAX, DIALOGSIZE_MAX); + getSizeHints(min, max); + + const QSize finalSize(qBound(min.width(), q->width(), std::max(max.width(), min.width())), + qBound(min.height(), q->height(), std::max(max.height(), min.height()))); + + if (visualParent) { + // it's important here that we're using re->size() as size, we don't want to do recursive resizeEvents + const QRect geom(q->popupPosition(visualParent, finalSize), finalSize); + q->adjustGeometry(geom); + } else { + q->resize(finalSize); + } + + mainItem->setPosition(QPointF(dialogBackground->leftMargin(), dialogBackground->topMargin())); + mainItem->setSize(QSizeF(q->width() - dialogBackground->leftMargin() - dialogBackground->rightMargin(), + q->height() - dialogBackground->topMargin() - dialogBackground->bottomMargin())); + + dialogBackground->setSize(QSizeF(q->width(), q->height())); + + if (!needsSetupNextExpose && visible) { + // Only reposition after successful setup; otherwise repositionIfOffScreen will override the default position set by kwin under wayland + repositionIfOffScreen(); + } + updateTheme(); + + // setting the minimum or maximum size will resize the window instantly and min <= max is enforced + // so we have to set maximum first in that case, but also care about the new maximum being smaller + // than the current minimum + // QTBUG-113233 + q->setMaximumSize(max.expandedTo(q->maximumSize())); + q->setMinimumSize(min); + q->setMaximumSize(max); + + QObject::connect(mainItem, SIGNAL(widthChanged()), q, SLOT(slotMainItemSizeChanged())); + QObject::connect(mainItem, SIGNAL(heightChanged()), q, SLOT(slotMainItemSizeChanged())); +} + +void DialogPrivate::repositionIfOffScreen() +{ + if (!componentComplete) { + return; + } + const QRect avail = availableScreenGeometryForPosition(q->position()); + + int x = q->x(); + int y = q->y(); + + if (x < avail.left()) { + x = avail.left(); + } else if (x + q->width() > avail.right()) { + x = avail.right() - q->width() + 1; + } + + if (y < avail.top()) { + y = avail.top(); + } else if (y + q->height() > avail.bottom()) { + y = avail.bottom() - q->height() + 1; + } + + q->setX(x); + q->setY(y); +} + +void DialogPrivate::syncToMainItemSize() +{ + Q_ASSERT(mainItem); + + if (!componentComplete || q->visibility() == QWindow::Hidden) { + return; + } + if (mainItem->width() <= 0 || mainItem->height() <= 0) { + qWarning() << "trying to show an empty dialog"; + } + + updateTheme(); + if (visualParent) { + const QSize fullSize = QSize(mainItem->width(), mainItem->height()) + + QSize(dialogBackground->leftMargin() + dialogBackground->rightMargin(), dialogBackground->topMargin() + dialogBackground->bottomMargin()); + + // We get the popup position with the fullsize as we need the popup + // position in order to determine our actual size, as the position + // determines which borders will be shown. + const QRect geom(q->popupPosition(visualParent, fullSize), fullSize); + + // We're then moving the window to where we think we would be with all + // the borders. This way when syncBorders is called, it has a geometry + // to work with. + syncBorders(geom); + } else { + syncBorders(q->geometry()); + } + + QSize s = QSize(mainItem->width(), mainItem->height()) + + QSize(dialogBackground->leftMargin() + dialogBackground->rightMargin(), dialogBackground->topMargin() + dialogBackground->bottomMargin()); + + QSize min; + QSize max(DIALOGSIZE_MAX, DIALOGSIZE_MAX); + getSizeHints(min, max); + s = QSize(qBound(min.width(), s.width(), max.width()), qBound(min.height(), s.height(), max.height())); + + q->contentItem()->setSize(s); + + dialogBackground->setSize(s); + + if (visualParent) { + const QRect geom(q->popupPosition(visualParent, s), s); + + if (geom == q->geometry()) { + return; + } + + q->adjustGeometry(geom); + // The borders will instantly be updated but the geometry might take a + // while as sub-classes can reimplement adjustGeometry and animate it. + syncBorders(geom); + + } else { + q->resize(s); + } + + mainItem->setPosition(QPointF(dialogBackground->leftMargin(), dialogBackground->topMargin())); + + updateTheme(); +} + +void DialogPrivate::slotWindowPositionChanged() +{ + // Tooltips always have all the borders + // floating windows have all borders + if (!q->isVisible() || q->flags().testFlag(Qt::ToolTip) || location == Plasma::Types::Floating || floating > 0) { + return; + } + + syncBorders(q->geometry()); + updateTheme(); + + if (mainItem) { + mainItem->setPosition(QPoint(dialogBackground->leftMargin(), dialogBackground->topMargin())); + mainItem->setSize(QSize(q->width() - dialogBackground->leftMargin() - dialogBackground->rightMargin(), + q->height() - dialogBackground->topMargin() - dialogBackground->bottomMargin())); + } +} + +bool DialogPrivate::mainItemContainsPosition(const QPointF &point) const +{ + if (!mainItem) { + return false; + } + + return QRectF(mainItem->mapToScene(QPoint(0, 0)), QSizeF(mainItem->width(), mainItem->height())).contains(point); +} + +QPointF DialogPrivate::positionAdjustedForMainItem(const QPointF &point) const +{ + if (!mainItem) { + return point; + } + + QRectF itemRect(mainItem->mapToScene(QPoint(0, 0)), QSizeF(mainItem->width(), mainItem->height())); + + return QPointF(qBound(itemRect.left(), point.x(), itemRect.right()), qBound(itemRect.top(), point.y(), itemRect.bottom())); +} + +void DialogPrivate::applyType() +{ + /*QXcbWindowFunctions::WmWindowType*/ int wmType = 0; + +#if HAVE_X11 + if (KWindowSystem::isPlatformX11()) { + switch (type) { + case Dialog::Normal: + q->setFlags(Qt::FramelessWindowHint | q->flags()); + break; + case Dialog::Dock: + wmType = QNativeInterface::Private::QXcbWindow::Dock; + break; + case Dialog::DialogWindow: + wmType = QNativeInterface::Private::QXcbWindow::Dialog; + break; + case Dialog::PopupMenu: + wmType = QNativeInterface::Private::QXcbWindow::PopupMenu; + break; + case Dialog::Tooltip: + wmType = QNativeInterface::Private::QXcbWindow::Tooltip; + break; + case Dialog::Notification: + wmType = QNativeInterface::Private::QXcbWindow::Notification; + break; + case Dialog::OnScreenDisplay: + case Dialog::CriticalNotification: + case Dialog::AppletPopup: + // Not supported by Qt + break; + } + + if (wmType) { + // QXcbWindow isn't installed and thus inaccessible to us, but it does read this magic property from the window... + q->setProperty("_q_xcb_wm_window_type", wmType); + } + } +#endif + + if (!wmType && type != Dialog::Normal && KWindowSystem::isPlatformX11()) { + KX11Extras::setType(q->winId(), static_cast(type)); + } + if (q->flags() & Qt::WindowStaysOnTopHint) { + // If the AppletPopup type is not explicitly requested, then use the Dock type in this case + // to avoid bug #454635. + if (type != Dialog::AppletPopup && type != Dialog::Tooltip) { + type = Dialog::Dock; + PlasmaShellWaylandIntegration::get(q)->setPanelBehavior(QtWayland::org_kde_plasma_surface::panel_behavior_windows_go_below); + } else { + PlasmaShellWaylandIntegration::get(q)->setPanelBehavior(QtWayland::org_kde_plasma_surface::panel_behavior_always_visible); + } + } + switch (type) { + case Dialog::Dock: + PlasmaShellWaylandIntegration::get(q)->setRole(QtWayland::org_kde_plasma_surface::role_panel); + break; + case Dialog::Tooltip: + PlasmaShellWaylandIntegration::get(q)->setRole(QtWayland::org_kde_plasma_surface::role_tooltip); + break; + case Dialog::Notification: + PlasmaShellWaylandIntegration::get(q)->setRole(QtWayland::org_kde_plasma_surface::role_notification); + break; + case Dialog::OnScreenDisplay: + PlasmaShellWaylandIntegration::get(q)->setRole(QtWayland::org_kde_plasma_surface::role_onscreendisplay); + break; + case Dialog::CriticalNotification: + PlasmaShellWaylandIntegration::get(q)->setRole(QtWayland::org_kde_plasma_surface::role_criticalnotification); + break; + case Dialog::Normal: + PlasmaShellWaylandIntegration::get(q)->setRole(QtWayland::org_kde_plasma_surface::role_normal); + break; + case Dialog::AppletPopup: + PlasmaShellWaylandIntegration::get(q)->setRole(QtWayland::org_kde_plasma_surface::role_appletpopup); + break; + default: + break; + } + + // an OSD can't be a Dialog, as qt xcb would attempt to set a transient parent for it + // see bug 370433 + if (type == Dialog::OnScreenDisplay) { + Qt::WindowFlags flags = (q->flags() & ~Qt::Dialog) | Qt::Window; + if (outputOnly) { + flags |= Qt::WindowTransparentForInput; + } else { + flags &= ~Qt::WindowTransparentForInput; + } + q->setFlags(flags); + } + + if (backgroundHints == Dialog::NoBackground) { + dialogBackground->setImagePath(QString()); + } else { + auto prefix = QStringLiteral(""); + if ((backgroundHints & Dialog::SolidBackground) == Dialog::SolidBackground) { + prefix = QStringLiteral("solid/"); + } + if (type == Dialog::Tooltip) { + dialogBackground->setImagePath(prefix + QStringLiteral("widgets/tooltip")); + } else { + dialogBackground->setImagePath(prefix + QStringLiteral("dialogs/background")); + } + } + + if (KWindowSystem::isPlatformX11()) { + if (type == Dialog::Dock || type == Dialog::Notification || type == Dialog::OnScreenDisplay || type == Dialog::CriticalNotification) { + KX11Extras::setOnAllDesktops(q->winId(), true); + } else { + KX11Extras::setOnAllDesktops(q->winId(), false); + } + } + + PlasmaShellWaylandIntegration::get(q)->setTakesFocus(!q->flags().testFlag(Qt::WindowDoesNotAcceptFocus)); +} + +bool DialogPrivate::updateMouseCursor(const QPointF &globalMousePos) +{ + Qt::Edges sides = hitTest(globalMousePos) & resizableEdges; + if (!sides) { + if (overridingCursor) { + q->unsetCursor(); + overridingCursor = false; + } + return false; + } + + if (sides == Qt::Edges(Qt::LeftEdge | Qt::TopEdge)) { + q->setCursor(Qt::SizeFDiagCursor); + } else if (sides == Qt::Edges(Qt::RightEdge | Qt::TopEdge)) { + q->setCursor(Qt::SizeBDiagCursor); + } else if (sides == Qt::Edges(Qt::LeftEdge | Qt::BottomEdge)) { + q->setCursor(Qt::SizeBDiagCursor); + } else if (sides == Qt::Edges(Qt::RightEdge | Qt::BottomEdge)) { + q->setCursor(Qt::SizeFDiagCursor); + } else if (sides.testFlag(Qt::TopEdge)) { + q->setCursor(Qt::SizeVerCursor); + } else if (sides.testFlag(Qt::LeftEdge)) { + q->setCursor(Qt::SizeHorCursor); + } else if (sides.testFlag(Qt::RightEdge)) { + q->setCursor(Qt::SizeHorCursor); + } else { + q->setCursor(Qt::SizeVerCursor); + } + + overridingCursor = true; + return true; +} + +Qt::Edges DialogPrivate::hitTest(const QPointF &pos) +{ + bool left = hitTestLeft(pos); + bool right = hitTestRight(pos); + bool top = hitTestTop(pos); + bool bottom = hitTestBottom(pos); + Qt::Edges edges; + if (left) { + edges.setFlag(Qt::LeftEdge); + } + if (right) { + edges.setFlag(Qt::RightEdge); + } + if (bottom) { + edges.setFlag(Qt::BottomEdge); + } + if (top) { + edges.setFlag(Qt::TopEdge); + } + + return edges; +} + +bool DialogPrivate::hitTestLeft(const QPointF &pos) +{ + const QRect geometry = q->geometry(); + const QRectF rect(geometry.x(), geometry.y(), dialogBackground->leftMargin(), geometry.height()); + return rect.contains(pos); +} + +bool DialogPrivate::hitTestRight(const QPointF &pos) +{ + const QRect geometry = q->geometry(); + const QRectF rect(geometry.x() + geometry.width() - dialogBackground->rightMargin(), geometry.y(), dialogBackground->rightMargin(), geometry.height()); + return rect.contains(pos); +} + +bool DialogPrivate::hitTestTop(const QPointF &pos) +{ + const QRect geometry = q->geometry(); + const QRectF rect(geometry.x(), geometry.y(), geometry.width(), dialogBackground->topMargin()); + return rect.contains(pos); +} + +bool DialogPrivate::hitTestBottom(const QPointF &pos) +{ + const QRect geometry = q->geometry(); + const QRectF rect(geometry.x(), geometry.y() + geometry.height() - dialogBackground->bottomMargin(), geometry.width(), dialogBackground->bottomMargin()); + return rect.contains(pos); +} + +Dialog::Dialog(QQuickItem *parent) + : QQuickWindow(parent ? parent->window() : nullptr) + , d(new DialogPrivate(this)) +{ + setColor(QColor(Qt::transparent)); + setFlags(Qt::FramelessWindowHint | Qt::Dialog); + + connect(this, &QWindow::xChanged, [this]() { + d->slotWindowPositionChanged(); + }); + connect(this, &QWindow::yChanged, [this]() { + d->slotWindowPositionChanged(); + }); + connect(this, &Dialog::locationChanged, this, [&] { + d->updateResizableEdges(); + }); + + // Given dialogs are skip task bar and don't have a decoration + // minimizing them using e.g. "minimize all" should just close them + connect(this, &QWindow::windowStateChanged, this, [this](Qt::WindowState newState) { + if (newState == Qt::WindowMinimized) { + setVisible(false); + } + }); + + connect(this, &QWindow::visibleChanged, this, &Dialog::visibleChangedProxy); + + // HACK: this property is invoked due to the initialization that gets done to contentItem() in the getter + property("data"); + + // This is needed as a transition thing for KWayland + // FIXME: is this valid anymore? + // setProperty("__plasma_frameSvg", QVariant::fromValue(d->dialogBackground->frameSvg())); + + connect(&d->theme, SIGNAL(themeChanged()), this, SLOT(updateTheme())); +} + +Dialog::~Dialog() +{ + // Prevent signals from super-class destructor invoking our now-destroyed slots + disconnect(this, nullptr, this, nullptr); +} + +QQuickItem *Dialog::mainItem() const +{ + return d->mainItem; +} + +void Dialog::setMainItem(QQuickItem *mainItem) +{ + if (d->mainItem != mainItem) { + if (d->mainItem) { + disconnect(d->mainItem, nullptr, this, nullptr); + d->mainItem->setParentItem(nullptr); + } + + if (d->mainItemLayout) { + disconnect(d->mainItemLayout, nullptr, this, nullptr); + } + + d->mainItem = mainItem; + + if (mainItem) { + mainItem->setParentItem(contentItem()); + + connect(mainItem, SIGNAL(widthChanged()), this, SLOT(slotMainItemSizeChanged())); + connect(mainItem, SIGNAL(heightChanged()), this, SLOT(slotMainItemSizeChanged())); + d->slotMainItemSizeChanged(); + + // Extract the representation's Layout, if any + QObject *layout = nullptr; + setMinimumSize(QSize(0, 0)); + setMaximumSize(QSize(DIALOGSIZE_MAX, DIALOGSIZE_MAX)); + + // Search a child that has the needed Layout properties + // HACK: here we are not type safe, but is the only way to access to a pointer of Layout + const auto lstChild = mainItem->children(); + for (QObject *child : lstChild) { + // find for the needed property of Layout: minimum/maximum/preferred sizes and fillWidth/fillHeight + if (child->property("minimumWidth").isValid() && child->property("minimumHeight").isValid() && child->property("preferredWidth").isValid() + && child->property("preferredHeight").isValid() && child->property("maximumWidth").isValid() && child->property("maximumHeight").isValid() + && child->property("fillWidth").isValid() && child->property("fillHeight").isValid()) { + layout = child; + break; + } + } + + d->mainItemLayout = layout; + + if (layout) { + // These connections are direct. They run on the GUI thread. + // If the underlying QQuickItem is sane, these properties should be updated atomically in one cycle + // of the GUI thread event loop, denying the chance for the event loop to run a QQuickItem::update() call in between. + // So we avoid rendering a frame in between with inconsistent geometry properties which would cause flickering issues. + connect(layout, SIGNAL(minimumWidthChanged()), this, SLOT(updateMinimumWidth())); + connect(layout, SIGNAL(minimumHeightChanged()), this, SLOT(updateMinimumHeight())); + connect(layout, SIGNAL(maximumWidthChanged()), this, SLOT(updateMaximumWidth())); + connect(layout, SIGNAL(maximumHeightChanged()), this, SLOT(updateMaximumHeight())); + + d->updateLayoutParameters(); + } + } + + // if this is called in Component.onCompleted we have to wait a loop the item is added to a scene + Q_EMIT mainItemChanged(); + } +} + +void DialogPrivate::slotMainItemSizeChanged() +{ + syncToMainItemSize(); +} + +QQuickItem *Dialog::visualParent() const +{ + return d->visualParent; +} + +void Dialog::setVisualParent(QQuickItem *visualParent) +{ + if (d->visualParent == visualParent) { + return; + } + + d->visualParent = visualParent; + Q_EMIT visualParentChanged(); + if (visualParent) { + if (visualParent->window()) { + setTransientParent(visualParent->window()); + } + if (d->mainItem) { + d->syncToMainItemSize(); + } + } +} + +QPoint Dialog::popupPosition(QQuickItem *item, const QSize &size) +{ + if (!item) { + // If no item was specified try to align at the center of the parent view + QQuickItem *parentItem = qobject_cast(parent()); + if (parentItem) { + QScreen *screen = parentItem->window()->screen(); + + switch (d->location) { + case Plasma::Types::TopEdge: + return QPoint(screen->availableGeometry().center().x() - size.width() / 2, screen->availableGeometry().y()); + case Plasma::Types::LeftEdge: + return QPoint(screen->availableGeometry().x(), screen->availableGeometry().center().y() - size.height() / 2); + case Plasma::Types::RightEdge: + return QPoint(screen->availableGeometry().right() - size.width(), screen->availableGeometry().center().y() - size.height() / 2); + case Plasma::Types::BottomEdge: + return QPoint(screen->availableGeometry().center().x() - size.width() / 2, screen->availableGeometry().bottom() - size.height()); + // Default center in the screen + default: + return screen->geometry().center() - QPoint(size.width() / 2, size.height() / 2); + } + } else { + return QPoint(); + } + } + + QPointF pos = item->mapToScene(QPointF(0, 0)); + + if (item->window()) { + pos = item->window()->mapToGlobal(pos.toPoint()); + } else { + return QPoint(); + } + + // if the item is in a dock or in a window that ignores WM we want to position the popups outside of the dock + const KWindowInfo winInfo(item->window()->winId(), NET::WMWindowType); + const bool outsideParentWindow = + ((winInfo.windowType(NET::AllTypesMask) == NET::Dock) || (item->window()->flags() & Qt::X11BypassWindowManagerHint)) && item->window()->mask().isNull(); + + QRect parentGeometryBounds; + if (outsideParentWindow) { + parentGeometryBounds = item->window()->geometry(); + } else { + parentGeometryBounds = item->mapRectToScene(item->boundingRect()).toRect(); + if (item->window()) { + parentGeometryBounds.moveTopLeft(item->window()->mapToGlobal(parentGeometryBounds.topLeft())); + pos = parentGeometryBounds.topLeft(); + } + } + + const QRectF itemSceneBoundingRect = item->mapRectToScene(item->boundingRect()); + const QPoint centerPoint(pos.x() + (itemSceneBoundingRect.width() - size.width()) / 2, // + pos.y() + (itemSceneBoundingRect.height() - size.height()) / 2); + + const QPoint topPoint(centerPoint.x(), parentGeometryBounds.top() - size.height()); + const QPoint bottomPoint(centerPoint.x(), parentGeometryBounds.bottom()); + + const QPoint leftPoint(parentGeometryBounds.left() - size.width(), centerPoint.y()); + const QPoint rightPoint(parentGeometryBounds.right(), centerPoint.y()); + + QPoint dialogPos; + if (d->location == Plasma::Types::TopEdge) { + dialogPos = bottomPoint; + } else if (d->location == Plasma::Types::LeftEdge) { + dialogPos = rightPoint; + } else if (d->location == Plasma::Types::RightEdge) { + dialogPos = leftPoint; + } else { // Types::BottomEdge + dialogPos = topPoint; + } + + // find the correct screen for the item + // we do not rely on item->window()->screen() because + // QWindow::screen() is always only the screen where the window gets first created + // not actually the current window. See QWindow::screen() documentation + QRect avail = item->window()->screen()->availableGeometry(); + avail.adjust(d->floating, d->floating, -d->floating, -d->floating); + + if (outsideParentWindow && d->dialogBackground->enabledBorders() != KSvg::FrameSvg::AllBorders) { + // make the panel look it's inside the panel, in order to not make it look cut + switch (d->location) { + case Plasma::Types::LeftEdge: + case Plasma::Types::RightEdge: + avail.setTop(qMax(avail.top(), parentGeometryBounds.top())); + avail.setBottom(qMin(avail.bottom(), parentGeometryBounds.bottom())); + break; + default: + avail.setLeft(qMax(avail.left(), parentGeometryBounds.left())); + avail.setRight(qMin(avail.right(), parentGeometryBounds.right())); + break; + } + } + + // If the dialog is from opening an applet in the panel and it's close enough to the center that + // it would still cover the original applet in the panel if it was centered, then we manually center it. + if (d->type == Dialog::AppletPopup) { + QRectF parentRect = item->mapRectToScene(item->boundingRect()); + switch (d->location) { + case Plasma::Types::TopEdge: + case Plasma::Types::BottomEdge: + if (qAbs(dialogPos.x() + size.width() / 2 - avail.center().x()) < size.width() / 2 - parentRect.width() / 3) { + dialogPos.setX(avail.center().x() - size.width() / 2); + } + break; + case Plasma::Types::LeftEdge: + case Plasma::Types::RightEdge: + if (qAbs(dialogPos.y() + size.height() / 2 - avail.center().y()) < size.height() / 2 - parentRect.height() / 3) { + dialogPos.setY(avail.center().y() - size.height() / 2); + } + break; + default: + break; + } + } + + // For top & bottom the inner conditions are intentionally different from thouse for left & right, + // because we want floating popups to flip vertically, but only push them in bounds horizontally. + + // If popup goes out of bounds... + // ...at the left edge + if (dialogPos.x() < avail.left()) { + if (d->location != Plasma::Types::LeftEdge) { + // move it in bounds + // Note: floating popup goes here. + dialogPos.setX(avail.left()); + } else { + // flip it around + dialogPos.setX(rightPoint.x()); + } + } + // ...at the right edge + if (dialogPos.x() + size.width() > avail.right()) { + if (d->location != Plasma::Types::RightEdge) { + // move it in bounds + // Note: floating popup goes here. + dialogPos.setX(qMax(avail.left(), (avail.right() - size.width() + 1))); + } else { + // flip it around + dialogPos.setX(leftPoint.x()); + } + } + // ...at the top edge + if (dialogPos.y() < avail.top()) { + if (d->location == Plasma::Types::LeftEdge || d->location == Plasma::Types::RightEdge) { + // move it in bounds + dialogPos.setY(avail.top()); + } else { + // flip it around + // Note: floating popup goes here. + dialogPos.setY(bottomPoint.y()); + } + } + // ...at the bottom edge + if (dialogPos.y() + size.height() > avail.bottom()) { + if (d->location == Plasma::Types::LeftEdge || d->location == Plasma::Types::RightEdge) { + // move it in bounds + dialogPos.setY(qMax(avail.top(), (avail.bottom() - size.height() + 1))); + } else { + // flip it around + // Note: floating popup goes here. + dialogPos.setY(topPoint.y()); + } + } + + return dialogPos; +} + +Plasma::Types::Location Dialog::location() const +{ + return d->location; +} + +void Dialog::setLocation(Plasma::Types::Location location) +{ + if (d->location == location) { + return; + } + d->location = location; + Q_EMIT locationChanged(); + + if (d->mainItem) { + d->syncToMainItemSize(); + } +} + +QObject *Dialog::margins() const +{ + return d->dialogBackground->fixedMargins(); +} + +QObject *Dialog::inset() const +{ + return d->dialogBackground->inset(); +} + +void Dialog::setFramelessFlags(Qt::WindowFlags flags) +{ + if (d->type == Dialog::Normal) { + flags |= Qt::Dialog; + } + setFlags(Qt::FramelessWindowHint | flags); + d->applyType(); + Q_EMIT flagsChanged(); +} + +void Dialog::adjustGeometry(const QRect &geom) +{ + setGeometry(geom); +} + +void Dialog::resizeEvent(QResizeEvent *re) +{ + QQuickWindow::resizeEvent(re); + + if (d->resizableEdges) { + d->updateMouseCursor(QCursor::pos()); + } + + // it's a spontaneous event generated in qguiapplication.cpp QGuiApplicationPrivate::processWindowScreenChangedEvent + // QWindowSystemInterfacePrivate::GeometryChangeEvent gce(window, QHighDpi::fromNativePixels(window->handle()->geometry(), window), QRect()); + // This happens before the first show event when there is more than one screen, + // right after the window has been created, the window is still 0x0, + // but the resize event gets delivered with 0x0 again and executed with all the bad side effects + // this seems to happen for every window when there are multiple screens, so something we have probably to watch out for in the future + if (re->size().isEmpty() || re->size() == re->oldSize()) { + return; + } + + // A dialog can be resized even if no mainItem has ever been set + if (!d->mainItem || !isExposed()) { + return; + } + + d->mainItem->disconnect(this); + + d->dialogBackground->setSize(QSizeF(re->size().width(), re->size().height())); + d->mainItem->setPosition(QPointF(d->dialogBackground->leftMargin(), d->dialogBackground->topMargin())); + + d->mainItem->setSize(QSize(re->size().width() - d->dialogBackground->leftMargin() - d->dialogBackground->rightMargin(), + re->size().height() - d->dialogBackground->topMargin() - d->dialogBackground->bottomMargin())); + + d->updateTheme(); + + QObject::connect(d->mainItem, SIGNAL(widthChanged()), this, SLOT(slotMainItemSizeChanged())); + QObject::connect(d->mainItem, SIGNAL(heightChanged()), this, SLOT(slotMainItemSizeChanged())); +} + +void Dialog::setType(WindowType type) +{ + if (type == d->type) { + return; + } + + d->type = type; + d->applyType(); + Q_EMIT typeChanged(); +} + +Dialog::WindowType Dialog::type() const +{ + return d->type; +} + +void Dialog::focusInEvent(QFocusEvent *ev) +{ + QQuickWindow::focusInEvent(ev); +} + +void Dialog::focusOutEvent(QFocusEvent *ev) +{ + if (d->hideOnWindowDeactivate) { + bool parentHasFocus = false; + + QWindow *parentWindow = transientParent(); + + while (parentWindow) { + if (parentWindow->isActive() && !(parentWindow->flags() & Qt::WindowDoesNotAcceptFocus)) { + parentHasFocus = true; + + break; + } + + parentWindow = parentWindow->transientParent(); + } + + const QWindow *focusWindow = QGuiApplication::focusWindow(); + bool childHasFocus = focusWindow && ((focusWindow->isActive() && isAncestorOf(focusWindow)) || (focusWindow->type() & Qt::Popup) == Qt::Popup); + + const bool viewClicked = qobject_cast(focusWindow) || qobject_cast(focusWindow); + + if (viewClicked || (!parentHasFocus && !childHasFocus)) { + setVisible(false); + Q_EMIT windowDeactivated(); + } + } + + QQuickWindow::focusOutEvent(ev); +} + +void Dialog::showEvent(QShowEvent *event) +{ + d->updateResizableEdges(); + d->updateSizeFromAppletInterface(); + + if (d->backgroundHints != Dialog::NoBackground) { + DialogShadows::instance()->addWindow(this, d->dialogBackground->enabledBorders()); + } + + if (KWindowSystem::isPlatformX11()) { + KX11Extras::setState(winId(), NET::SkipTaskbar | NET::SkipPager | NET::SkipSwitcher); + } + QQuickWindow::showEvent(event); +} + +bool Dialog::event(QEvent *event) +{ + if (event->type() == QEvent::Expose) { + if (!KWindowSystem::isPlatformWayland() || isRunningInKWin() || !isExposed()) { + return QQuickWindow::event(event); + } + + /* + * expose event is the only place where to correctly + * register our wayland extensions, as showevent is a bit too + * soon and the platform window isn't shown yet + * (only the first expose event, guarded by needsSetupNextExpose bool) + * and tear it down when the window gets hidden + * see https://phabricator.kde.org/T6064 + */ + // sometimes non null regions arrive even for non visible windows + // for which surface creation would fail + if (d->needsSetupNextExpose && isVisible()) { + d->updateVisibility(true); + const bool ret = QQuickWindow::event(event); + d->updateTheme(); + d->needsSetupNextExpose = false; + return ret; + } + } else if (event->type() == QEvent::Show) { + d->updateVisibility(true); + } else if (event->type() == QEvent::Hide) { + d->updateVisibility(false); + d->needsSetupNextExpose = true; + } else if (event->type() == QEvent::Move) { + QMoveEvent *me = static_cast(event); + PlasmaShellWaylandIntegration::get(this)->setPosition(me->pos()); + } + + /*Fitt's law: if the containment has margins, and the mouse cursor clicked + * on the mouse edge, forward the click in the containment boundaries + */ + if (d->mainItem && !d->mainItem->size().isEmpty()) { + switch (event->type()) { + case QEvent::MouseMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: { + QMouseEvent *me = static_cast(event); + if (d->resizableEdges) { + if (event->type() == QEvent::MouseMove && d->updateMouseCursor(me->globalPosition())) { + return QQuickWindow::event(event); + } + if (event->type() == QEvent::MouseButtonPress) { + const QPointF globalMousePos = me->globalPosition(); + const Qt::Edges sides = d->hitTest(globalMousePos) & d->resizableEdges; + if (sides) { + startSystemResize(sides); + return true; + } + } + } + + // don't mess with position if the cursor is actually outside the view: + // somebody is doing a click and drag that must not break when the cursor is outside + if (geometry().contains(me->globalPosition().toPoint()) && !d->mainItemContainsPosition(me->scenePosition())) { + QMouseEvent me2(me->type(), + d->positionAdjustedForMainItem(me->scenePosition()), + d->positionAdjustedForMainItem(me->scenePosition()), + d->positionAdjustedForMainItem(me->scenePosition()) + position(), + me->button(), + me->buttons(), + me->modifiers()); + me2.setTimestamp(me->timestamp()); + + if (isVisible()) { + QCoreApplication::sendEvent(this, &me2); + } + return true; + } + break; + } + + case QEvent::Wheel: { + QWheelEvent *we = static_cast(event); + + const QPoint pos = we->position().toPoint(); + + if (!d->mainItemContainsPosition(pos)) { + QWheelEvent we2(d->positionAdjustedForMainItem(pos), + d->positionAdjustedForMainItem(pos) + position(), + we->pixelDelta(), + we->angleDelta(), + we->buttons(), + we->modifiers(), + we->phase(), + false /*inverted*/); + we2.setTimestamp(we->timestamp()); + + if (isVisible()) { + QCoreApplication::sendEvent(this, &we2); + } + return true; + } + break; + } + + case QEvent::DragEnter: { + QDragEnterEvent *de = static_cast(event); + if (!d->mainItemContainsPosition(de->position())) { + QDragEnterEvent de2(d->positionAdjustedForMainItem(de->position()).toPoint(), + de->possibleActions(), + de->mimeData(), + de->buttons(), + de->modifiers()); + + if (isVisible()) { + QCoreApplication::sendEvent(this, &de2); + } + return true; + } + break; + } + // DragLeave just works + case QEvent::DragLeave: + break; + case QEvent::DragMove: { + QDragMoveEvent *de = static_cast(event); + if (!d->mainItemContainsPosition(de->position())) { + QDragMoveEvent de2(d->positionAdjustedForMainItem(de->position()).toPoint(), + de->possibleActions(), + de->mimeData(), + de->buttons(), + de->modifiers()); + + if (isVisible()) { + QCoreApplication::sendEvent(this, &de2); + } + return true; + } + break; + } + case QEvent::Drop: { + QDropEvent *de = static_cast(event); + if (!d->mainItemContainsPosition(de->position())) { + QDropEvent de2(d->positionAdjustedForMainItem(de->position()).toPoint(), de->possibleActions(), de->mimeData(), de->buttons(), de->modifiers()); + + if (isVisible()) { + QCoreApplication::sendEvent(this, &de2); + } + return true; + } + break; + } + + default: + break; + } + } + + return QQuickWindow::event(event); +} + +void Dialog::hideEvent(QHideEvent *event) +{ + // Persist the size if this contains an applet + if (d->appletInterface && d->mainItem) { + KConfigGroup config = d->appletInterface->applet()->config(); + qreal w = d->mainItem->width(); + qreal h = d->mainItem->height(); + config.writeEntry("popupWidth", w); + config.writeEntry("popupHeight", h); + config.sync(); + } + + QQuickWindow::hideEvent(event); +} + +void Dialog::moveEvent(QMoveEvent *e) +{ + QQuickWindow::moveEvent(e); + if (d->resizableEdges) { + d->updateMouseCursor(QCursor::pos()); + } +} + +void Dialog::classBegin() +{ + d->componentComplete = false; +} + +void Dialog::componentComplete() +{ + d->componentComplete = true; + QQuickWindow::setVisible(d->visible); + d->updateTheme(); +} + +bool Dialog::hideOnWindowDeactivate() const +{ + return d->hideOnWindowDeactivate; +} + +void Dialog::setHideOnWindowDeactivate(bool hide) +{ + if (d->hideOnWindowDeactivate == hide) { + return; + } + d->hideOnWindowDeactivate = hide; + Q_EMIT hideOnWindowDeactivateChanged(); +} + +bool Dialog::isOutputOnly() const +{ + return d->outputOnly; +} + +void Dialog::setOutputOnly(bool outputOnly) +{ + if (d->outputOnly == outputOnly) { + return; + } + d->outputOnly = outputOnly; + d->applyType(); + Q_EMIT outputOnlyChanged(); +} + +void Dialog::setFloating(int floating) +{ + d->floating = floating; + Q_EMIT floatingChanged(); +} + +int Dialog::floating() const +{ + return d->floating; +} + +void Dialog::setVisible(bool visible) +{ + // only update real visibility when we have finished component completion + // and all flags have been set + + d->visible = visible; + if (d->componentComplete) { + if (visible && d->visualParent) { + setPosition(popupPosition(d->visualParent, size())); + } + + // Bug 381242: Qt remembers minimize state and re-applies it when showing + setWindowStates(windowStates() & ~Qt::WindowMinimized); + QQuickWindow::setVisible(visible); + // signal will be emitted and proxied from the QQuickWindow code + } else { + Q_EMIT visibleChangedProxy(); + } +} + +bool Dialog::isVisible() const +{ + if (d->componentComplete) { + return QQuickWindow::isVisible(); + } + return d->visible; +} + +void Dialog::setAppletInterface(QQuickItem *appletInterface) +{ + if (d->appletInterface == appletInterface) { + return; + } + d->appletInterface = qobject_cast(appletInterface); + Q_EMIT appletInterfaceChanged(); +} + +QQuickItem *Dialog::appletInterface() const +{ + return d->appletInterface; +} + +Dialog::BackgroundHints Dialog::backgroundHints() const +{ + return d->backgroundHints; +} + +void Dialog::setBackgroundHints(Dialog::BackgroundHints hints) +{ + if (d->backgroundHints == hints) { + return; + } + + d->backgroundHints = hints; + d->updateTheme(); + Q_EMIT backgroundHintsChanged(); +} + +} + +#include "moc_dialog.cpp" diff --git a/src/plasmaquick/dialog.h b/src/plasmaquick/dialog.h new file mode 100644 index 0000000..5b1767d --- /dev/null +++ b/src/plasmaquick/dialog.h @@ -0,0 +1,281 @@ +/* + SPDX-FileCopyrightText: 2011 Marco Martin + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ +#ifndef DIALOG_PROXY_P +#define DIALOG_PROXY_P + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the public Plasma API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +class QQuickItem; +class QScreen; + +namespace PlasmaQuick +{ +class DialogPrivate; + +/** + * Dialog creates a Plasma themed top level window that can contain any QML component. + * + * It can be automatically positioned relative to a visual parent + * The dialog will resize to the size of the main item + * + * @code{.qml} + * import QtQuick 2.0 + * import org.kde.plasma.core as PlasmaCore + * Item { + * PlasmaCore.Dialog { + * visible: true + * mainItem: Item { + * width: 500 + * height: 500 + * + * Text { + * anchors.centerIn: parent + * color: "red" + * text: "text" + * } + * } + * } + * } + * @endcode + * + * Import Statement + * @code import org.kde.plasma.core @endcode + * @version 2.0 + */ +class PLASMAQUICK_EXPORT Dialog : public QQuickWindow, public QQmlParserStatus +{ + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + + /** + * The main QML item that will be displayed in the Dialog + */ + Q_PROPERTY(QQuickItem *mainItem READ mainItem WRITE setMainItem NOTIFY mainItemChanged) + + /** + * The main QML item that will be displayed in the Dialog + */ + Q_PROPERTY(QQuickItem *visualParent READ visualParent WRITE setVisualParent NOTIFY visualParentChanged) + + /** + * Margins of the dialog around the mainItem. + * @see DialogMargins + */ + Q_PROPERTY(QObject *margins READ margins CONSTANT) + + /** + * Margins where the dialog background actually starts, excluiding things like shadows or borders + * @see DialogMargins + * @since 5.77 + */ + Q_PROPERTY(QObject *inset READ inset CONSTANT) + + /** + * Plasma Location of the dialog window. Useful if this dialog is a popup for a panel + */ + Q_PROPERTY(Plasma::Types::Location location READ location WRITE setLocation NOTIFY locationChanged) + + /** + * Type of the window + */ + Q_PROPERTY(WindowType type READ type WRITE setType NOTIFY typeChanged) + + /** + * Whether the dialog should be hidden when the dialog loses focus. + * + * The default value is @c false. + **/ + Q_PROPERTY(bool hideOnWindowDeactivate READ hideOnWindowDeactivate WRITE setHideOnWindowDeactivate NOTIFY hideOnWindowDeactivateChanged) + + /** + * Whether the dialog is output only. Default value is @c false. If it is @c true + * the dialog does not accept input and all pointer events are not accepted, thus the dialog + * is click through. + * + * This property is currently only supported on the X11 platform. On any other platform the + * property has no effect. + **/ + Q_PROPERTY(bool outputOnly READ isOutputOnly WRITE setOutputOnly NOTIFY outputOnlyChanged) + + /** + * This property holds the window flags of the window. + * The window flags control the window's appearance in the windowing system, + * whether it's a dialog, popup, or a regular window, and whether it should + * have a title bar, etc. + * Regardless to what the user sets, the flags will always have the + * FramelessWindowHint flag set + */ + Q_PROPERTY(Qt::WindowFlags flags READ flags WRITE setFramelessFlags NOTIFY flagsChanged) + + /** + * This property holds how (and if at all) the dialog should draw its own background + * or if it is complete responsibility of the content item to render a background. + * Note that in case of NoBackground it loses kwin side shadows and blur + */ + Q_PROPERTY(BackgroundHints backgroundHints READ backgroundHints WRITE setBackgroundHints NOTIFY backgroundHintsChanged) + + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChangedProxy) + + /** + * This property holds by how much the applet should be floating even if the location + * is set to a certain screen side; if this value is positive, the dialog will draw + * all four sides and maintain the required distance from the screen borders. + */ + Q_PROPERTY(int floating READ floating WRITE setFloating NOTIFY floatingChanged) + + /** + * This property holds a pointer to the AppletInterface used by an applet. It is + * null when the dialog is not used for an applet. + */ + // TODO: plasmoidItem? + Q_PROPERTY(QQuickItem *appletInterface READ appletInterface WRITE setAppletInterface NOTIFY appletInterfaceChanged) + + Q_CLASSINFO("DefaultProperty", "mainItem") + +public: + enum WindowType { + Normal = NET::Normal, + Dock = NET::Dock, + DialogWindow = NET::Dialog, + PopupMenu = NET::PopupMenu, + Tooltip = NET::Tooltip, + Notification = NET::Notification, + OnScreenDisplay = NET::OnScreenDisplay, + CriticalNotification = NET::CriticalNotification, + AppletPopup = NET::AppletPopup, + }; + Q_ENUM(WindowType) + + enum BackgroundHints { + NoBackground = 0, /**< Not drawing a background under the applet, the dialog has its own implementation */ + StandardBackground = 1, /**< The standard background from the theme is drawn */ + SolidBackground = 2, /**< The solid version of the background is preferred */ + }; + Q_ENUM(BackgroundHints) + + explicit Dialog(QQuickItem *parent = nullptr); + ~Dialog() override; + + // PROPERTIES ACCESSORS + QQuickItem *mainItem() const; + void setMainItem(QQuickItem *mainItem); + + QQuickItem *visualParent() const; + void setVisualParent(QQuickItem *visualParent); + + Plasma::Types::Location location() const; + void setLocation(Plasma::Types::Location location); + + QObject *margins() const; + QObject *inset() const; + + void setFramelessFlags(Qt::WindowFlags flags); + + void setType(WindowType type); + WindowType type() const; + + bool hideOnWindowDeactivate() const; + void setHideOnWindowDeactivate(bool hide); + + void setOutputOnly(bool outputOnly); + bool isOutputOnly() const; + + BackgroundHints backgroundHints() const; + void setBackgroundHints(BackgroundHints hints); + + bool isVisible() const; + void setVisible(bool visible); + + int floating() const; + void setFloating(int floating); + + QQuickItem *appletInterface() const; + void setAppletInterface(QQuickItem *appletInterface); + + /** + * @returns The suggested screen position for the popup + * @param item the item the popup has to be positioned relatively to. if null, the popup will be positioned in the center of the window + * @param size the size that the popup will have, which influences the final position + */ + virtual QPoint popupPosition(QQuickItem *item, const QSize &size); + +Q_SIGNALS: + void mainItemChanged(); + void locationChanged(); + void visualParentChanged(); + void typeChanged(); + void hideOnWindowDeactivateChanged(); + void outputOnlyChanged(); + void flagsChanged(); + void floatingChanged(); + void backgroundHintsChanged(); + void visibleChangedProxy(); // redeclaration of QQuickWindow::visibleChanged + void appletInterfaceChanged(); + /** + * Emitted when the @see hideOnWindowDeactivate property is @c true and this dialog lost focus to a + * window that is neither a parent dialog to nor a child dialog of this dialog. + */ + void windowDeactivated(); + +protected: + /** + * set the dialog position. subclasses may change it. ToolTipDialog adjusts the position in an animated way + */ + virtual void adjustGeometry(const QRect &geom); + + // Reimplementations + void classBegin() override; + void componentComplete() override; + void resizeEvent(QResizeEvent *re) override; + void focusInEvent(QFocusEvent *ev) override; + void focusOutEvent(QFocusEvent *ev) override; + void showEvent(QShowEvent *event) override; + void hideEvent(QHideEvent *event) override; + void moveEvent(QMoveEvent *) override; + bool event(QEvent *event) override; + +private: + friend class DialogPrivate; + const QScopedPointer d; + + Q_PRIVATE_SLOT(d, void updateTheme()) + Q_PRIVATE_SLOT(d, void updateVisibility(bool visible)) + + Q_PRIVATE_SLOT(d, void updateMinimumWidth()) + Q_PRIVATE_SLOT(d, void updateMinimumHeight()) + Q_PRIVATE_SLOT(d, void updateMaximumWidth()) + Q_PRIVATE_SLOT(d, void updateMaximumHeight()) + Q_PRIVATE_SLOT(d, void updateLayoutParameters()) + + Q_PRIVATE_SLOT(d, void slotMainItemSizeChanged()) +}; + +} + +#endif diff --git a/src/plasmaquick/dialogbackground_p.cpp b/src/plasmaquick/dialogbackground_p.cpp new file mode 100644 index 0000000..ed4c23b --- /dev/null +++ b/src/plasmaquick/dialogbackground_p.cpp @@ -0,0 +1,99 @@ +/* + SPDX-FileCopyrightText: 2023 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "dialogbackground_p.h" + +#include +#include + +#include "sharedqmlengine.h" + +namespace PlasmaQuick +{ + +DialogBackground::DialogBackground(QQuickItem *parent) + : QQuickItem(parent) + , m_sharedEngine(new SharedQmlEngine(this)) +{ + QQmlComponent component(m_sharedEngine->engine().get(), "org.kde.plasma.core", "DialogBackground"); + + QVariantHash props({{QStringLiteral("parent"), QVariant::fromValue(this)}}); + QObject *object = m_sharedEngine->createObjectFromComponent(&component, m_sharedEngine->rootContext(), props); + + m_frameSvgItem = qobject_cast(object); + Q_ASSERT(m_frameSvgItem); + + connect(m_frameSvgItem, SIGNAL(maskChanged()), this, SIGNAL(maskChanged())); + connect(m_frameSvgItem->property("fixedMargins").value(), SIGNAL(marginsChanged()), this, SIGNAL(fixedMarginsChanged())); +} + +DialogBackground::~DialogBackground() +{ + delete m_frameSvgItem; +} + +QString DialogBackground::imagePath() const +{ + return m_frameSvgItem->property("imagePath").toString(); +} + +void DialogBackground::setImagePath(const QString &path) +{ + m_frameSvgItem->setProperty("imagePath", path); +} + +void DialogBackground::setEnabledBorders(const KSvg::FrameSvg::EnabledBorders borders) +{ + m_frameSvgItem->setProperty("enabledBorders", QVariant::fromValue(borders)); +} + +KSvg::FrameSvg::EnabledBorders DialogBackground::enabledBorders() const +{ + return m_frameSvgItem->property("enabledBorders").value(); +} + +QRegion DialogBackground::mask() const +{ + return m_frameSvgItem->property("mask").value(); +} + +qreal DialogBackground::leftMargin() const +{ + // assume margins is valid, as we asserted it's a valid FrameSvgItem + QObject *margins = m_frameSvgItem->property("fixedMargins").value(); + return margins->property("left").value(); +} + +qreal DialogBackground::topMargin() const +{ + QObject *margins = m_frameSvgItem->property("fixedMargins").value(); + return margins->property("top").value(); +} + +qreal DialogBackground::rightMargin() const +{ + QObject *margins = m_frameSvgItem->property("fixedMargins").value(); + return margins->property("right").value(); +} + +qreal DialogBackground::bottomMargin() const +{ + QObject *margins = m_frameSvgItem->property("fixedMargins").value(); + return margins->property("bottom").value(); +} + +QObject *DialogBackground::fixedMargins() const +{ + return m_frameSvgItem->property("fixedMargins").value(); +} + +QObject *DialogBackground::inset() const +{ + return m_frameSvgItem->property("inset").value(); +} +} + +#include "moc_dialogbackground_p.cpp" diff --git a/src/plasmaquick/dialogbackground_p.h b/src/plasmaquick/dialogbackground_p.h new file mode 100644 index 0000000..b40c289 --- /dev/null +++ b/src/plasmaquick/dialogbackground_p.h @@ -0,0 +1,67 @@ +/* + SPDX-FileCopyrightText: 2023 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef DIALOGBACKGROUND_P_H +#define DIALOGBACKGROUND_P_H + +#include "sharedqmlengine.h" +#include + +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the public Plasma API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +namespace PlasmaQuick +{ +class SharedQmlEngine; + +// This class wraps a FrameSvgITem created from QML, so is not necessary to statically link to it to be used in Dialog +class DialogBackground : public QQuickItem +{ + Q_OBJECT + +public: + DialogBackground(QQuickItem *parent = nullptr); + ~DialogBackground() override; + + QString imagePath() const; + void setImagePath(const QString &name); + + void setEnabledBorders(const KSvg::FrameSvg::EnabledBorders borders); + KSvg::FrameSvg::EnabledBorders enabledBorders() const; + + QRegion mask() const; + + qreal leftMargin() const; + qreal topMargin() const; + qreal rightMargin() const; + qreal bottomMargin() const; + + // Needed for the QML api of Dialog + QObject *fixedMargins() const; + QObject *inset() const; + +Q_SIGNALS: + void fixedMarginsChanged(); + void maskChanged(); + +private: + QQuickItem *m_frameSvgItem; + SharedQmlEngine *m_sharedEngine; +}; + +} + +#endif // multiple inclusion guard diff --git a/src/plasmaquick/dialogshadows.cpp b/src/plasmaquick/dialogshadows.cpp new file mode 100644 index 0000000..d5474c9 --- /dev/null +++ b/src/plasmaquick/dialogshadows.cpp @@ -0,0 +1,271 @@ +/* + SPDX-FileCopyrightText: 2011 Aaron Seigo + SPDX-FileCopyrightText: 2020 Vlad Zahorodnii + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "debug_p.h" +#include "dialogshadows_p.h" + +#include + +class DialogShadows::Private +{ +public: + Private(DialogShadows *shadows) + : q(shadows) + { + } + + ~Private() + { + } + + void clearTiles(); + void setupTiles(); + void initTile(const QString &element); + void updateShadow(QWindow *window, KSvg::FrameSvg::EnabledBorders); + void clearShadow(QWindow *window); + void updateShadows(); + void windowDestroyed(QObject *deletedObject); + + DialogShadows *q; + + QHash m_windows; + QHash m_shadows; + QList m_tiles; +}; + +typedef QHash DialogShadowHash; +Q_GLOBAL_STATIC(DialogShadowHash, s_privateDialogShadowsInstances) + +DialogShadows *DialogShadows::instance(const QString &prefix) +{ + DialogShadows *&shadow = (*s_privateDialogShadowsInstances)[prefix]; + if (!shadow) { + shadow = new DialogShadows(qApp, prefix); + } + return shadow; +} + +DialogShadows::DialogShadows(QObject *parent, const QString &prefix) + : KSvg::Svg(parent) + , d(new Private(this)) +{ + setImagePath(prefix); + connect(this, SIGNAL(repaintNeeded()), this, SLOT(updateShadows())); +} + +DialogShadows::~DialogShadows() +{ + delete d; +} + +void DialogShadows::addWindow(QWindow *window, KSvg::FrameSvg::EnabledBorders enabledBorders) +{ + if (!window) { + return; + } + + d->m_windows[window] = enabledBorders; + d->updateShadow(window, enabledBorders); + connect(window, SIGNAL(destroyed(QObject *)), this, SLOT(windowDestroyed(QObject *)), Qt::UniqueConnection); +} + +void DialogShadows::removeWindow(QWindow *window) +{ + if (!d->m_windows.contains(window)) { + return; + } + + d->m_windows.remove(window); + disconnect(window, nullptr, this, nullptr); + d->clearShadow(window); + + if (d->m_windows.isEmpty()) { + d->clearTiles(); + } +} + +void DialogShadows::setEnabledBorders(QWindow *window, KSvg::FrameSvg::EnabledBorders enabledBorders) +{ + Q_ASSERT(d->m_windows.contains(window)); + if (!window || !d->m_windows.contains(window)) { + return; + } + + d->updateShadow(window, enabledBorders); +} + +void DialogShadows::Private::windowDestroyed(QObject *deletedObject) +{ + QWindow *window = static_cast(deletedObject); + + m_windows.remove(window); + clearShadow(window); + + if (m_windows.isEmpty()) { + clearTiles(); + } +} + +void DialogShadows::Private::updateShadows() +{ + setupTiles(); + QHash::const_iterator i; + for (i = m_windows.constBegin(); i != m_windows.constEnd(); ++i) { + updateShadow(i.key(), i.value()); + } +} + +void DialogShadows::Private::initTile(const QString &element) +{ + const QImage image = q->pixmap(element).toImage(); + + KWindowShadowTile::Ptr tile = KWindowShadowTile::Ptr::create(); + tile->setImage(image); + + m_tiles << tile; +} + +void DialogShadows::Private::setupTiles() +{ + clearTiles(); + + initTile(QStringLiteral("shadow-top")); + initTile(QStringLiteral("shadow-topright")); + initTile(QStringLiteral("shadow-right")); + initTile(QStringLiteral("shadow-bottomright")); + initTile(QStringLiteral("shadow-bottom")); + initTile(QStringLiteral("shadow-bottomleft")); + initTile(QStringLiteral("shadow-left")); + initTile(QStringLiteral("shadow-topleft")); +} + +void DialogShadows::Private::clearTiles() +{ + m_tiles.clear(); +} + +void DialogShadows::Private::updateShadow(QWindow *window, KSvg::FrameSvg::EnabledBorders enabledBorders) +{ + if (m_tiles.isEmpty()) { + setupTiles(); + } + + KWindowShadow *&shadow = m_shadows[window]; + + if (!shadow) { + shadow = new KWindowShadow(q); + } + + if (shadow->isCreated()) { + shadow->destroy(); + } + + if (enabledBorders & KSvg::FrameSvg::TopBorder) { + shadow->setTopTile(m_tiles.at(0)); + } else { + shadow->setTopTile(nullptr); + } + + if (enabledBorders & KSvg::FrameSvg::TopBorder && enabledBorders & KSvg::FrameSvg::RightBorder) { + shadow->setTopRightTile(m_tiles.at(1)); + } else { + shadow->setTopRightTile(nullptr); + } + + if (enabledBorders & KSvg::FrameSvg::RightBorder) { + shadow->setRightTile(m_tiles.at(2)); + } else { + shadow->setRightTile(nullptr); + } + + if (enabledBorders & KSvg::FrameSvg::BottomBorder && enabledBorders & KSvg::FrameSvg::RightBorder) { + shadow->setBottomRightTile(m_tiles.at(3)); + } else { + shadow->setBottomRightTile(nullptr); + } + + if (enabledBorders & KSvg::FrameSvg::BottomBorder) { + shadow->setBottomTile(m_tiles.at(4)); + } else { + shadow->setBottomTile(nullptr); + } + + if (enabledBorders & KSvg::FrameSvg::BottomBorder && enabledBorders & KSvg::FrameSvg::LeftBorder) { + shadow->setBottomLeftTile(m_tiles.at(5)); + } else { + shadow->setBottomLeftTile(nullptr); + } + + if (enabledBorders & KSvg::FrameSvg::LeftBorder) { + shadow->setLeftTile(m_tiles.at(6)); + } else { + shadow->setLeftTile(nullptr); + } + + if (enabledBorders & KSvg::FrameSvg::TopBorder && enabledBorders & KSvg::FrameSvg::LeftBorder) { + shadow->setTopLeftTile(m_tiles.at(7)); + } else { + shadow->setTopLeftTile(nullptr); + } + + QMargins padding; + + if (enabledBorders & KSvg::FrameSvg::TopBorder) { + const QSize marginHint = q->elementSize(QStringLiteral("shadow-hint-top-margin")).toSize(); + if (marginHint.isValid()) { + padding.setTop(marginHint.height()); + } else { + padding.setTop(m_tiles[0]->image().height()); + } + } + + if (enabledBorders & KSvg::FrameSvg::RightBorder) { + const QSize marginHint = q->elementSize(QStringLiteral("shadow-hint-right-margin")).toSize(); + if (marginHint.isValid()) { + padding.setRight(marginHint.width()); + } else { + padding.setRight(m_tiles[2]->image().width()); + } + } + + if (enabledBorders & KSvg::FrameSvg::BottomBorder) { + const QSize marginHint = q->elementSize(QStringLiteral("shadow-hint-bottom-margin")).toSize(); + if (marginHint.isValid()) { + padding.setBottom(marginHint.height()); + } else { + padding.setBottom(m_tiles[4]->image().height()); + } + } + + if (enabledBorders & KSvg::FrameSvg::LeftBorder) { + const QSize marginHint = q->elementSize(QStringLiteral("shadow-hint-left-margin")).toSize(); + if (marginHint.isValid()) { + padding.setLeft(marginHint.width()); + } else { + padding.setLeft(m_tiles[6]->image().width()); + } + } + + shadow->setPadding(padding); + shadow->setWindow(window); + + if (!shadow->create()) { + qCWarning(LOG_PLASMAQUICK) << "Couldn't create KWindowShadow for" << window; + } +} + +void DialogShadows::Private::clearShadow(QWindow *window) +{ + delete m_shadows.take(window); +} + +bool DialogShadows::enabled() const +{ + return hasElement(QStringLiteral("shadow-left")); +} + +#include "moc_dialogshadows_p.cpp" diff --git a/src/plasmaquick/dialogshadows_p.h b/src/plasmaquick/dialogshadows_p.h new file mode 100644 index 0000000..c6b5ce6 --- /dev/null +++ b/src/plasmaquick/dialogshadows_p.h @@ -0,0 +1,40 @@ +/* + SPDX-FileCopyrightText: 2011 Aaron Seigo + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMA_DIALOGSHADOWS_H +#define PLASMA_DIALOGSHADOWS_H + +#include + +#include +#include + +class DialogShadows : public KSvg::Svg +{ + Q_OBJECT + +public: + static DialogShadows *instance(const QString &prefix = QLatin1String("dialogs/background")); + + explicit DialogShadows(QObject *parent, const QString &prefix); + ~DialogShadows() override; + + void addWindow(QWindow *window, KSvg::FrameSvg::EnabledBorders enabledBorders = KSvg::FrameSvg::AllBorders); + void removeWindow(QWindow *window); + + void setEnabledBorders(QWindow *window, KSvg::FrameSvg::EnabledBorders enabledBorders = KSvg::FrameSvg::AllBorders); + + bool enabled() const; + +private: + class Private; + Private *const d; + + Q_PRIVATE_SLOT(d, void updateShadows()) + Q_PRIVATE_SLOT(d, void windowDestroyed(QObject *deletedObject)) +}; + +#endif diff --git a/src/plasmaquick/edgeeventforwarder.cpp b/src/plasmaquick/edgeeventforwarder.cpp new file mode 100644 index 0000000..dc0e65b --- /dev/null +++ b/src/plasmaquick/edgeeventforwarder.cpp @@ -0,0 +1,183 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "edgeeventforwarder.h" + +#include +#include +#include +#include +#include +#include + +using namespace PlasmaQuick; + +class EdgeEventForwarderPrivate +{ +public: + QWindow *window; + QMargins margins; + Qt::Edges activeEdges; + QMargins activeMargins() const; + bool mainItemContainsPosition(const QPointF &position) const; + QPointF positionAdjustedForMainItem(const QPointF &position) const; +}; + +EdgeEventForwarder::EdgeEventForwarder(QWindow *parent) + : QObject(parent) + , d(new EdgeEventForwarderPrivate) +{ + d->window = parent; + d->window->installEventFilter(this); +} + +EdgeEventForwarder::~EdgeEventForwarder() +{ + d->window->removeEventFilter(this); +} + +void EdgeEventForwarder::setMargins(const QMargins &margins) +{ + d->margins = margins; +} + +QMargins EdgeEventForwarder::margins() +{ + return d->margins; +} + +void EdgeEventForwarder::setActiveEdges(Qt::Edges edges) +{ + d->activeEdges = edges; +} + +Qt::Edges EdgeEventForwarder::activeEdges() +{ + return d->activeEdges; +} + +bool EdgeEventForwarder::eventFilter(QObject *watched, QEvent *event) +{ + Q_UNUSED(watched) + + switch (event->type()) { + case QEvent::MouseMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: { + QMouseEvent *me = static_cast(event); + // don't mess with position if the cursor is actually outside the view: + // somebody is doing a click and drag that must not break when the cursor is outside + + if (d->window->geometry().contains(me->globalPosition().toPoint()) && !d->mainItemContainsPosition(me->scenePosition())) { + QMouseEvent me2(me->type(), + d->positionAdjustedForMainItem(me->scenePosition()), + d->positionAdjustedForMainItem(me->scenePosition()), + d->positionAdjustedForMainItem(me->scenePosition()) + d->window->position(), + me->button(), + me->buttons(), + me->modifiers()); + me2.setTimestamp(me->timestamp()); + + if (d->window->isVisible()) { + QCoreApplication::sendEvent(d->window, &me2); + } + return true; + } + break; + } + + case QEvent::Wheel: { + QWheelEvent *we = static_cast(event); + + const QPoint pos = we->position().toPoint(); + + if (!d->mainItemContainsPosition(pos)) { + QWheelEvent we2(d->positionAdjustedForMainItem(pos), + d->positionAdjustedForMainItem(pos) + d->window->position(), + we->pixelDelta(), + we->angleDelta(), + we->buttons(), + we->modifiers(), + we->phase(), + false /*inverted*/); + we2.setTimestamp(we->timestamp()); + + if (d->window->isVisible()) { + QCoreApplication::sendEvent(this, &we2); + } + return true; + } + break; + } + + case QEvent::DragEnter: { + QDragEnterEvent *de = static_cast(event); + if (!d->mainItemContainsPosition(de->position())) { + QDragEnterEvent de2(d->positionAdjustedForMainItem(de->position()).toPoint(), + de->possibleActions(), + de->mimeData(), + de->buttons(), + de->modifiers()); + + if (d->window->isVisible()) { + QCoreApplication::sendEvent(this, &de2); + } + return true; + } + break; + } + // DragLeave just works + case QEvent::DragLeave: + break; + case QEvent::DragMove: { + QDragMoveEvent *de = static_cast(event); + if (!d->mainItemContainsPosition(de->position())) { + QDragMoveEvent de2(d->positionAdjustedForMainItem(de->position()).toPoint(), de->possibleActions(), de->mimeData(), de->buttons(), de->modifiers()); + + if (d->window->isVisible()) { + QCoreApplication::sendEvent(this, &de2); + } + return true; + } + break; + } + case QEvent::Drop: { + QDropEvent *de = static_cast(event); + if (!d->mainItemContainsPosition(de->position())) { + QDropEvent de2(d->positionAdjustedForMainItem(de->position()), de->possibleActions(), de->mimeData(), de->buttons(), de->modifiers()); + + if (d->window->isVisible()) { + QCoreApplication::sendEvent(this, &de2); + } + return true; + } + break; + } + + default: + break; + } + return false; +} + +QMargins EdgeEventForwarderPrivate::activeMargins() const +{ + return QMargins(activeEdges.testFlag(Qt::LeftEdge) ? margins.left() : 0, + activeEdges.testFlag(Qt::TopEdge) ? margins.top() : 0, + activeEdges.testFlag(Qt::RightEdge) ? margins.right() : 0, + activeEdges.testFlag(Qt::BottomEdge) ? margins.bottom() : 0); +} + +bool EdgeEventForwarderPrivate::mainItemContainsPosition(const QPointF &position) const +{ + const QRectF itemRect = QRectF(QPointF(0, 0), window->size()).marginsRemoved(activeMargins()); + return itemRect.contains(position); +} + +QPointF EdgeEventForwarderPrivate::positionAdjustedForMainItem(const QPointF &position) const +{ + const QRectF itemRect = QRectF(QPointF(0, 0), window->size()).marginsRemoved(activeMargins()); + return QPointF(qBound(itemRect.left(), position.x(), itemRect.right()), qBound(itemRect.top(), position.y(), itemRect.bottom())); +} diff --git a/src/plasmaquick/edgeeventforwarder.h b/src/plasmaquick/edgeeventforwarder.h new file mode 100644 index 0000000..7593c8d --- /dev/null +++ b/src/plasmaquick/edgeeventforwarder.h @@ -0,0 +1,57 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#pragma once + +#include +#include +#include + +#include + +class QWindow; + +class EdgeEventForwarderPrivate; + +namespace PlasmaQuick +{ + +/** + * @brief The EdgeEventForwarder class + * This class forwards edge events to be replayed within the given margin + * This is useful if children do not touch the edge of a window, but want to get input events + */ +class PLASMAQUICK_EXPORT EdgeEventForwarder : public QObject +{ + Q_OBJECT +public: + /** + * @brief EdgeEventForwarder constructor + * @param window The window to intercept and filter + * The event forwarder is parented to the window + */ + EdgeEventForwarder(QWindow *parent); + ~EdgeEventForwarder(); + + /** + * @brief setMargins sets the margins to use for the event forwarding + */ + void setMargins(const QMargins &margins); + QMargins margins(); + + /** + * @brief setActiveEdges sets which margins should be active for edge forwarding + * typically this should match edges touching a screen edge + */ + void setActiveEdges(Qt::Edges edges); + Qt::Edges activeEdges(); + + bool eventFilter(QObject *watched, QEvent *event) override; + +private: + std::unique_ptr d; +}; + +} diff --git a/src/plasmaquick/plasmashellwaylandintegration.cpp b/src/plasmaquick/plasmashellwaylandintegration.cpp new file mode 100644 index 0000000..e8fb47d --- /dev/null +++ b/src/plasmaquick/plasmashellwaylandintegration.cpp @@ -0,0 +1,212 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "plasmashellwaylandintegration.h" + +#include +#include +#include +#include + +#include + +#include + +class PlasmaShellManager : public QWaylandClientExtensionTemplate, public QtWayland::org_kde_plasma_shell +{ +public: + PlasmaShellManager() + : QWaylandClientExtensionTemplate(8) + { + initialize(); + } +}; + +class PlasmaShellSurface : public QtWayland::org_kde_plasma_surface +{ +public: + PlasmaShellSurface(struct ::org_kde_plasma_surface *impl) + : QtWayland::org_kde_plasma_surface(impl) + { + } + ~PlasmaShellSurface() + { + destroy(); + } +}; + +class WaylandIntegrationSingleton +{ +public: + WaylandIntegrationSingleton(); + std::unique_ptr shellManager; + QHash windows; +}; + +WaylandIntegrationSingleton::WaylandIntegrationSingleton() +{ + if (KWindowSystem::isPlatformWayland()) { + shellManager = std::make_unique(); + } +} + +Q_GLOBAL_STATIC(WaylandIntegrationSingleton, s_waylandIntegration) + +class PlasmaShellWaylandIntegrationPrivate +{ +public: + PlasmaShellWaylandIntegrationPrivate(PlasmaShellWaylandIntegration *integration, QWindow *window); + + void platformSurfaceCreated(QWindow *window); + void surfaceCreated(); + void surfaceDestroyed(); + + PlasmaShellWaylandIntegration *q; + QWindow *m_window = nullptr; + std::optional m_position; + QtWayland::org_kde_plasma_surface::panel_behavior m_panelBehavior = QtWayland::org_kde_plasma_surface::panel_behavior_always_visible; + QtWayland::org_kde_plasma_surface::role m_role = QtWayland::org_kde_plasma_surface::role_normal; + bool m_takesFocus = false; + std::unique_ptr m_shellSurface; +}; + +PlasmaShellWaylandIntegrationPrivate::PlasmaShellWaylandIntegrationPrivate(PlasmaShellWaylandIntegration *integration, QWindow *window) + : q(integration) + , m_window(window) +{ +} + +void PlasmaShellWaylandIntegrationPrivate::platformSurfaceCreated(QWindow *window) +{ + auto waylandWindow = window->nativeInterface(); + if (!waylandWindow) { // It may be null, e.g. when called within KWin + return; + } + QObject::connect(waylandWindow, SIGNAL(surfaceCreated()), q, SLOT(surfaceCreated())); + QObject::connect(waylandWindow, SIGNAL(surfaceDestroyed()), q, SLOT(surfaceDestroyed())); + if (waylandWindow->surface()) { + surfaceCreated(); + } +} + +void PlasmaShellWaylandIntegrationPrivate::surfaceCreated() +{ + struct wl_surface *surface = nullptr; + if (!s_waylandIntegration->shellManager || !s_waylandIntegration->shellManager->isActive()) { + return; + } + + if (auto waylandWindow = m_window->nativeInterface()) { + surface = waylandWindow->surface(); + } + + if (!surface) { + return; + } + + m_shellSurface = std::make_unique(s_waylandIntegration->shellManager->get_surface(surface)); + if (m_shellSurface) { + if (m_position) { + m_shellSurface->set_position(m_position->x(), m_position->y()); + } + m_shellSurface->set_panel_takes_focus(m_takesFocus); + m_shellSurface->set_role(m_role); + m_shellSurface->set_skip_switcher(true); + m_shellSurface->set_skip_taskbar(true); + } +} + +void PlasmaShellWaylandIntegrationPrivate::surfaceDestroyed() +{ + m_shellSurface.reset(); +} + +PlasmaShellWaylandIntegration *PlasmaShellWaylandIntegration::get(QWindow *window) +{ + PlasmaShellWaylandIntegration *&it = s_waylandIntegration->windows[window]; + if (!it) { + it = new PlasmaShellWaylandIntegration(window); + } + return it; +} + +PlasmaShellWaylandIntegration::~PlasmaShellWaylandIntegration() +{ + s_waylandIntegration->windows.remove(d->m_window); +} + +PlasmaShellWaylandIntegration::PlasmaShellWaylandIntegration(QWindow *window) + : QObject(window) + , d(new PlasmaShellWaylandIntegrationPrivate(this, window)) +{ + if (!KWindowSystem::isPlatformWayland()) { + return; + } + d->m_window->installEventFilter(this); + d->platformSurfaceCreated(window); +} + +bool PlasmaShellWaylandIntegration::eventFilter(QObject *watched, QEvent *event) +{ + auto window = qobject_cast(watched); + if (!window) { + return false; + } + if (event->type() == QEvent::PlatformSurface) { + auto surfaceEvent = static_cast(event); + if (surfaceEvent->surfaceEventType() == QPlatformSurfaceEvent::SurfaceCreated) { + d->platformSurfaceCreated(window); + } + } + return false; +} + +void PlasmaShellWaylandIntegration::setPosition(const QPoint &position) +{ + if (position == d->m_position) { + return; + } + + d->m_position = position; + if (d->m_shellSurface) { + d->m_shellSurface->set_position(d->m_position->x(), d->m_position->y()); + } +} + +void PlasmaShellWaylandIntegration::setPanelBehavior(QtWayland::org_kde_plasma_surface::panel_behavior panelBehavior) +{ + if (panelBehavior == d->m_panelBehavior) { + return; + } + d->m_panelBehavior = panelBehavior; + if (d->m_shellSurface) { + d->m_shellSurface->set_panel_behavior(panelBehavior); + } +} + +void PlasmaShellWaylandIntegration::setRole(QtWayland::org_kde_plasma_surface::role role) +{ + if (role == d->m_role) { + return; + } + d->m_role = role; + if (d->m_shellSurface) { + d->m_shellSurface->set_role(role); + } +} + +void PlasmaShellWaylandIntegration::setTakesFocus(bool takesFocus) +{ + if (takesFocus == d->m_takesFocus) { + return; + } + d->m_takesFocus = takesFocus; + if (d->m_shellSurface) { + d->m_shellSurface->set_panel_takes_focus(takesFocus); + } +} + +#include "moc_plasmashellwaylandintegration.cpp" diff --git a/src/plasmaquick/plasmashellwaylandintegration.h b/src/plasmaquick/plasmashellwaylandintegration.h new file mode 100644 index 0000000..ec0804f --- /dev/null +++ b/src/plasmaquick/plasmashellwaylandintegration.h @@ -0,0 +1,60 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#ifndef PLASMASHELLWAYLANDINTEGRATION_P_H +#define PLASMASHELLWAYLANDINTEGRATION_P_H + +#include +#include +#include + +#include "qwayland-plasma-shell.h" + +#include + +class QWindow; + +class PlasmaShellSurface; +class PlasmaShellWaylandIntegrationPrivate; + +/** + * @brief The PlasmaWaylandShellIntegration class exposes Plasma specific + * specific wayland extensions for + * + * The class abstracts the wayland protocol tasks, automatically sending + * cached metadata when the underlying platform surfaces are created. + */ + +class PLASMAQUICK_EXPORT PlasmaShellWaylandIntegration : public QObject +{ + Q_OBJECT +public: + /** + * Returns the relevant PlasmaWaylandShellIntegration instance for this window + * creating one if needed. + * + * A valid instance will always returned, it will no-op on unsupported platforms + */ + static PlasmaShellWaylandIntegration *get(QWindow *window); + ~PlasmaShellWaylandIntegration(); + + void setPosition(const QPoint &position); + void setPanelBehavior(QtWayland::org_kde_plasma_surface::panel_behavior panelBehavior); + void setRole(QtWayland::org_kde_plasma_surface::role role); + void setTakesFocus(bool takesFocus); + bool eventFilter(QObject *watched, QEvent *event) override; + +private: + PlasmaShellWaylandIntegration(QWindow *window); + + Q_PRIVATE_SLOT(d, void platformSurfaceCreated(QWindow *window)) + Q_PRIVATE_SLOT(d, void surfaceCreated()) + Q_PRIVATE_SLOT(d, void surfaceDestroyed()) + + const std::unique_ptr d; +}; + +#endif // PLASMASHELLWAYLANDINTEGRATION_P_H diff --git a/src/plasmaquick/plasmawindow.cpp b/src/plasmaquick/plasmawindow.cpp new file mode 100644 index 0000000..86f8be5 --- /dev/null +++ b/src/plasmaquick/plasmawindow.cpp @@ -0,0 +1,246 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "plasmawindow.h" + +#include "dialogbackground_p.h" +#include "dialogshadows_p.h" + +#include +#include + +#include +#include +#include + +#include + +using namespace Plasma; + +namespace PlasmaQuick +{ +class PlasmaWindowPrivate +{ +public: + PlasmaWindowPrivate(PlasmaWindow *_q) + : q(_q) + { + } + void handleFrameChanged(); + void updateMainItemGeometry(); + PlasmaWindow *q; + DialogShadows *shadows; + // Keep a theme instance as a memeber to create one as soon as possible, + // as Theme creation will set KSvg to correctly fetch images form the Plasma Theme. + // This makes sure elements are correct, both in the dialog surface and the shadows. + Plasma::Theme theme; + QPointer mainItem; + DialogBackground *dialogBackground; + PlasmaWindow::BackgroundHints backgroundHints = PlasmaWindow::StandardBackground; +}; + +PlasmaWindow::PlasmaWindow(const QString &svgPrefix) + : QQuickWindow() + , d(new PlasmaWindowPrivate(this)) +{ + setColor(QColor(Qt::transparent)); + setFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + + d->shadows = DialogShadows::instance(svgPrefix); + d->dialogBackground = new DialogBackground(contentItem()); + d->dialogBackground->setImagePath(svgPrefix); + connect(d->dialogBackground, &DialogBackground::fixedMarginsChanged, this, [this]() { + d->updateMainItemGeometry(); + Q_EMIT paddingChanged(); + }); + connect(d->dialogBackground, &DialogBackground::maskChanged, this, [this]() { + d->handleFrameChanged(); + }); + + d->shadows->addWindow(this, d->dialogBackground->enabledBorders()); +} + +PlasmaWindow::~PlasmaWindow() +{ +} + +void PlasmaWindow::setMainItem(QQuickItem *mainItem) +{ + if (d->mainItem == mainItem) + return; + + if (d->mainItem) { + d->mainItem->setParentItem(nullptr); + } + + d->mainItem = mainItem; + Q_EMIT mainItemChanged(); + + if (d->mainItem) { + mainItem->setParentItem(contentItem()); + d->updateMainItemGeometry(); + } +} + +QQuickItem *PlasmaWindow::mainItem() const +{ + return d->mainItem; +} + +static KSvg::FrameSvg::EnabledBorders edgeToBorder(Qt::Edges edges) +{ + KSvg::FrameSvg::EnabledBorders borders = KSvg::FrameSvg::EnabledBorders(0); + + if (edges & Qt::Edge::TopEdge) { + borders |= KSvg::FrameSvg::EnabledBorder::TopBorder; + } + if (edges & Qt::Edge::BottomEdge) { + borders |= KSvg::FrameSvg::EnabledBorder::BottomBorder; + } + if (edges & Qt::Edge::LeftEdge) { + borders |= KSvg::FrameSvg::EnabledBorder::LeftBorder; + } + if (edges & Qt::Edge::RightEdge) { + borders |= KSvg::FrameSvg::EnabledBorder::RightBorder; + } + + return borders; +} + +static Qt::Edges bordersToEdge(KSvg::FrameSvg::EnabledBorders borders) +{ + Qt::Edges edges; + if (borders & KSvg::FrameSvg::EnabledBorder::TopBorder) { + edges |= Qt::Edge::TopEdge; + } + if (borders & KSvg::FrameSvg::EnabledBorder::BottomBorder) { + edges |= Qt::Edge::BottomEdge; + } + if (borders & KSvg::FrameSvg::EnabledBorder::LeftBorder) { + edges |= Qt::Edge::LeftEdge; + } + if (borders & KSvg::FrameSvg::EnabledBorder::RightBorder) { + edges |= Qt::Edge::RightEdge; + } + return edges; +} + +void PlasmaWindow::setBorders(Qt::Edges bordersToShow) +{ + d->dialogBackground->setEnabledBorders(edgeToBorder(bordersToShow)); + d->shadows->setEnabledBorders(this, d->dialogBackground->enabledBorders()); + Q_EMIT bordersChanged(); +} + +Qt::Edges PlasmaWindow::borders() +{ + return bordersToEdge(d->dialogBackground->enabledBorders()); +} + +void PlasmaWindow::showEvent(QShowEvent *e) +{ + // EWMH states that the state is reset every hide + // Qt supports external factors setting state before the next show + if (KWindowSystem::isPlatformX11()) { + KX11Extras::setState(winId(), NET::SkipTaskbar | NET::SkipPager | NET::SkipSwitcher); + } + QQuickWindow::showEvent(e); +} + +void PlasmaWindow::resizeEvent(QResizeEvent *e) +{ + QQuickWindow::resizeEvent(e); + const QSize windowSize = e->size(); + d->dialogBackground->setSize(windowSize); + if (d->mainItem) { + const QSize contentSize = windowSize.shrunkBy(padding()); + d->mainItem->setSize(contentSize); + } +} + +void PlasmaWindowPrivate::handleFrameChanged() +{ + const QRegion mask = dialogBackground->mask(); + KWindowEffects::enableBlurBehind(q, theme.blurBehindEnabled(), mask); + KWindowEffects::enableBackgroundContrast(q, + theme.backgroundContrastEnabled(), + theme.backgroundContrast(), + theme.backgroundIntensity(), + theme.backgroundSaturation(), + mask); + + if (!KWindowSystem::isPlatformX11() || KX11Extras::compositingActive()) { + q->setMask(QRegion()); + } else { + q->setMask(mask); + } +} + +void PlasmaWindowPrivate::updateMainItemGeometry() +{ + if (!mainItem) { + return; + } + const QMargins frameMargins = q->padding(); + const QSize windowSize = q->size(); + + mainItem->setX(frameMargins.left()); + mainItem->setY(frameMargins.top()); + + const QSize contentSize = windowSize.shrunkBy(frameMargins); + mainItem->setSize(contentSize); +} + +QMargins PlasmaWindow::padding() const +{ + return QMargins(d->dialogBackground->leftMargin(), + d->dialogBackground->topMargin(), + d->dialogBackground->rightMargin(), + d->dialogBackground->bottomMargin()); +} + +PlasmaWindow::BackgroundHints PlasmaWindow::backgroundHints() const +{ + return d->backgroundHints; +} + +void PlasmaWindow::setBackgroundHints(BackgroundHints hints) +{ + if (d->backgroundHints == hints) { + return; + } + d->backgroundHints = hints; + + auto prefix = QStringLiteral(""); + if (d->backgroundHints == PlasmaWindow::SolidBackground) { + prefix = QStringLiteral("solid/"); + } + d->dialogBackground->setImagePath(prefix + QStringLiteral("dialogs/background")); + + Q_EMIT backgroundHintsChanged(); +} + +qreal PlasmaWindow::topPadding() const +{ + return d->dialogBackground->topMargin(); +} + +qreal PlasmaWindow::bottomPadding() const +{ + return d->dialogBackground->bottomMargin(); +} + +qreal PlasmaWindow::leftPadding() const +{ + return d->dialogBackground->leftMargin(); +} + +qreal PlasmaWindow::rightPadding() const +{ + return d->dialogBackground->rightMargin(); +} +} + +#include "moc_plasmawindow.cpp" diff --git a/src/plasmaquick/plasmawindow.h b/src/plasmaquick/plasmawindow.h new file mode 100644 index 0000000..8f03410 --- /dev/null +++ b/src/plasmaquick/plasmawindow.h @@ -0,0 +1,104 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMAWINDOW_H +#define PLASMAWINDOW_H + +#include + +#include + +namespace Plasma +{ +class FrameSvgItem; +} + +namespace PlasmaQuick +{ +class PlasmaWindowPrivate; + +/* + * Creates a QQuickWindow themed in a Plasma style with background + */ +class PLASMAQUICK_EXPORT PlasmaWindow : public QQuickWindow +{ + Q_OBJECT + + /** + * The main QML item that will be displayed in the Dialog + */ + Q_PROPERTY(QQuickItem *mainItem READ mainItem WRITE setMainItem NOTIFY mainItemChanged) + + /** + * Defines the background used for the window + */ + Q_PROPERTY(BackgroundHints backgroundHints READ backgroundHints WRITE setBackgroundHints NOTIFY backgroundHintsChanged) + + /** + * Tells what borders are enabled of its background + */ + Q_PROPERTY(Qt::Edges borders READ borders NOTIFY bordersChanged) + + Q_PROPERTY(qreal topPadding READ topPadding NOTIFY paddingChanged) + Q_PROPERTY(qreal bottomPadding READ bottomPadding NOTIFY paddingChanged) + Q_PROPERTY(qreal leftPadding READ leftPadding NOTIFY paddingChanged) + Q_PROPERTY(qreal rightPadding READ rightPadding NOTIFY paddingChanged) + +public: + enum BackgroundHints { + StandardBackground = 0, /**< The standard background from the theme is drawn */ + SolidBackground = 1, /**< The solid version of the background is preferred */ + }; + Q_ENUM(BackgroundHints) + + PlasmaWindow(const QString &svgPrefix = QStringLiteral("dialogs/background")); + ~PlasmaWindow() override; + + /** + * The main QML item that will be displayed in the Dialog + */ + void setMainItem(QQuickItem *mainItem); + + QQuickItem *mainItem() const; + + /** + * Changes which rounded corners are shown on the window. + * Margins remain the same + * The default is all borders + */ + void setBorders(Qt::Edges bordersToShow); + + Qt::Edges borders(); + + /** + * Returns the padding that are placed around the mainItem + * When setting size hints on the window this should be factored in. + */ + QMargins padding() const; + + BackgroundHints backgroundHints() const; + void setBackgroundHints(BackgroundHints hints); + + qreal topPadding() const; + qreal bottomPadding() const; + qreal leftPadding() const; + qreal rightPadding() const; + +Q_SIGNALS: + void mainItemChanged(); + void bordersChanged(); + void backgroundHintsChanged(); + void paddingChanged(); + +protected: + void showEvent(QShowEvent *e) override; + void resizeEvent(QResizeEvent *e) override; + +private: + const std::unique_ptr d; +}; +} + +#endif diff --git a/src/plasmaquick/plasmoid/containmentitem.cpp b/src/plasmaquick/plasmoid/containmentitem.cpp new file mode 100644 index 0000000..3cd7a83 --- /dev/null +++ b/src/plasmaquick/plasmoid/containmentitem.cpp @@ -0,0 +1,1110 @@ +/* + SPDX-FileCopyrightText: 2008 Chani Armitage + SPDX-FileCopyrightText: 2008, 2009 Aaron Seigo + SPDX-FileCopyrightText: 2010 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include + +#include "appletquickitem_p.h" +#include "containmentitem.h" +#include "dropmenu.h" +#include "sharedqmlengine.h" +#include "wallpaperitem.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +ContainmentItem::ContainmentItem(QQuickItem *parent) + : PlasmoidItem(parent) + , m_wallpaperItem(nullptr) + , m_wheelDelta(0) +{ + setAcceptedMouseButtons(Qt::AllButtons); +} + +void ContainmentItem::classBegin() +{ + PlasmoidItem::classBegin(); + m_containment = static_cast(applet()); + if (!m_containment) { + // This can happen only if the client QML code declares a PlasmoidItem somewhere else than the root object + return; + } + + connect(m_containment.data(), &Plasma::Containment::appletAboutToBeRemoved, this, &ContainmentItem::appletRemovedForward); + connect(m_containment.data(), &Plasma::Containment::appletAboutToBeAdded, this, &ContainmentItem::appletAddedForward); + + connect(m_containment->corona(), &Plasma::Corona::editModeChanged, this, &ContainmentItem::editModeChanged); +} + +void ContainmentItem::init() +{ + PlasmoidItem::init(); + if (!m_containment) { + // This can happen only if the client QML code declares a PlasmoidItem somewhere else than the root object + return; + } + + for (auto *applet : m_containment->applets()) { + auto appletGraphicObject = AppletQuickItem::itemForApplet(applet); + m_plasmoidItems.append(appletGraphicObject); + connect(appletGraphicObject, &QObject::destroyed, this, [this, appletGraphicObject]() { + m_plasmoidItems.removeAll(appletGraphicObject); + }); + } + if (!m_plasmoidItems.isEmpty()) { + Q_EMIT appletsChanged(); + } + + // Create the ToolBox + if (m_containment && m_containment->isContainment()) { + KConfigGroup defaults; + if (m_containment->containmentType() == Plasma::Containment::Type::Desktop) { + defaults = KConfigGroup(KSharedConfig::openConfig(m_containment->corona()->kPackage().filePath("defaults")), QStringLiteral("Desktop")); + } else if (m_containment->containmentType() == Plasma::Containment::Type::Panel) { + defaults = KConfigGroup(KSharedConfig::openConfig(m_containment->corona()->kPackage().filePath("defaults")), QStringLiteral("Panel")); + } + + if (defaults.isValid()) { + KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Generic")); + pkg.setDefaultPackageRoot(QStringLiteral("plasma/packages")); + + if (defaults.isValid()) { + pkg.setPath(defaults.readEntry("ToolBox", "org.kde.desktoptoolbox")); + } else { + pkg.setPath(QStringLiteral("org.kde.desktoptoolbox")); + } + + if (pkg.metadata().isValid() && !pkg.metadata().isHidden()) { + if (pkg.isValid()) { + QObject *containmentGraphicObject = qmlObject()->rootObject(); + + QVariantHash toolboxProperties; + toolboxProperties[QStringLiteral("parent")] = QVariant::fromValue(this); + QObject *toolBoxObject = qmlObject()->createObjectFromSource(pkg.fileUrl("mainscript"), nullptr, toolboxProperties); + if (toolBoxObject && containmentGraphicObject) { + connect(this, &QObject::destroyed, [toolBoxObject]() { + delete toolBoxObject; + }); + containmentGraphicObject->setProperty("toolBox", QVariant::fromValue(toolBoxObject)); + } + } else { + qWarning() << "Could not load toolbox package." << pkg.path(); + } + } else { + qWarning() << "Toolbox not loading, toolbox package is either invalid or disabled."; + } + } + } + + connect(m_containment.data(), &Plasma::Containment::wallpaperPluginChanged, this, &ContainmentItem::loadWallpaper); + + connect(m_containment, &Plasma::Containment::internalActionsChanged, this, &ContainmentItem::actionsChanged); + connect(m_containment, &Plasma::Containment::contextualActionsChanged, this, &ContainmentItem::actionsChanged); +} + +PlasmaQuick::AppletQuickItem *ContainmentItem::itemFor(Plasma::Applet *applet) const +{ + if (!applet) { + return nullptr; + } + if (applet->containment() == m_containment) { + return AppletQuickItem::itemForApplet(applet); + } else { + return nullptr; + } +} + +Plasma::Applet *ContainmentItem::createApplet(const QString &plugin, const QVariantList &args, const QRectF &geom) +{ + return m_containment->createApplet(plugin, args, geom); +} + +void ContainmentItem::setAppletArgs(Plasma::Applet *applet, const QString &mimetype, const QVariant &data) +{ + if (!applet) { + return; + } + + PlasmoidItem *plasmoidItem = qobject_cast(AppletQuickItem::itemForApplet(applet)); + + if (plasmoidItem) { + Q_EMIT plasmoidItem->externalData(mimetype, data); + } +} + +QObject *ContainmentItem::containmentItemAt(int x, int y) +{ + QObject *desktop = nullptr; + const auto lst = m_containment->corona()->containments(); + for (Plasma::Containment *c : lst) { + ContainmentItem *contInterface = qobject_cast(AppletQuickItem::itemForApplet(c)); + + if (contInterface && contInterface->isVisible()) { + QWindow *w = contInterface->window(); + if (w && w->geometry().contains(QPoint(window()->x(), window()->y()) + QPoint(x, y))) { + if (c->containmentType() == Plasma::Containment::Type::CustomEmbedded) { + continue; + } + if (c->containmentType() == Plasma::Containment::Type::Desktop) { + desktop = contInterface; + } else { + return contInterface; + } + } + } + } + return desktop; +} + +QPointF ContainmentItem::mapFromApplet(Plasma::Applet *applet, int x, int y) +{ + PlasmoidItem *appletItem = qobject_cast(AppletQuickItem::itemForApplet(applet)); + if (!appletItem || !appletItem->window() || !window()) { + return QPointF(); + } + + // x,y in absolute screen coordinates of current view + QPointF pos = appletItem->mapToScene(QPointF(x, y)); + pos = QPointF(pos + appletItem->window()->geometry().topLeft()); + // return the coordinate in the relative view's coords + return pos - window()->geometry().topLeft(); +} + +QPointF ContainmentItem::mapToApplet(Plasma::Applet *applet, int x, int y) +{ + PlasmoidItem *appletItem = qobject_cast(AppletQuickItem::itemForApplet(applet)); + if (!appletItem || !appletItem->window() || !window()) { + return QPointF(); + } + + // x,y in absolute screen coordinates of current view + QPointF pos(x, y); + pos = QPointF(pos + window()->geometry().topLeft()); + // the coordinate in the relative view's coords + pos = pos - appletItem->window()->geometry().topLeft(); + // make it relative to applet coords + return pos - appletItem->mapToScene(QPointF(0, 0)); +} + +QPointF ContainmentItem::adjustToAvailableScreenRegion(int x, int y, int w, int h) const +{ + QRegion reg; + int screenId = screen(); + if (screenId > -1 && m_containment->corona()) { + reg = m_containment->corona()->availableScreenRegion(screenId); + } + + if (!reg.isEmpty()) { + // make it relative + QRect geometry = m_containment->corona()->screenGeometry(screenId); + reg.translate(-geometry.topLeft()); + } else { + reg = QRect(0, 0, width(), height()); + } + + const QRect rect(qBound(reg.boundingRect().left(), x, reg.boundingRect().right() + 1 - w), + qBound(reg.boundingRect().top(), y, reg.boundingRect().bottom() + 1 - h), + w, + h); + QRect tempRect(rect); + + // To place the rectangle, the idea is the following: + // Each QRegion is the union of some disjoint rectangles. We can imagine + // drawing a vertical line at the left and right sides of each rectangle, and + // an horizontal line at the top and bottom sides of each rectangle. We thus + // construct a grid (or partition) where each cell is either entirely within + // the QRegion or entirely outside. + // We now start "snapping" the given rectangle to all intersections of horizontal + // and vertical lines, until we find a place where the rectangle fits entirely. + // We test by snapping at all possible corners of the rectangle, to test + // all possibilities. + // We do this beginning from the closes grid element to the rect, and then + // we increase the distance. This allows us to find the smallest distance we + // have to displace the rectangle to fit in the QRegion. + // Note that we employ some performance optimizations, such as only left-snapping + // to vertical lines drawn from left-corners of rectangles, only right-snapping + // to vertical lines drawn from right-corners, and so on. + + // We start by reading the left, right, top and bottom values of all QRegion rects. + QSet leftAlignedGrid = {rect.left()}; + QSet rightAlignedGrid = {rect.right()}; + QSet topAlignedGrid = {rect.top()}; + QSet bottomAlignedGrid = {rect.bottom()}; + for (QRegion::const_iterator it = reg.begin(); it != reg.end(); ++it) { + QRect r = *it; + leftAlignedGrid.insert(r.left()); + rightAlignedGrid.insert(r.right()); + topAlignedGrid.insert(r.top()); + bottomAlignedGrid.insert(r.bottom()); + } + + // We then join them together, sorting them so that they + // are from the closes to the furthest away from the rectangle. + QList horizontalGrid = (leftAlignedGrid + rightAlignedGrid).values(); + std::sort(horizontalGrid.begin(), horizontalGrid.end(), [&leftAlignedGrid, &rightAlignedGrid, rect](int a, int b) { + if (leftAlignedGrid.contains(a)) { + a = std::abs(a - rect.left()); + } else { + a = std::abs(a - rect.right()); + } + if (leftAlignedGrid.contains(b)) { + b = std::abs(b - rect.left()); + } else { + b = std::abs(b - rect.right()); + } + return a < b; + }); + QList verticalGrid = (topAlignedGrid + bottomAlignedGrid).values(); + std::sort(verticalGrid.begin(), verticalGrid.end(), [&topAlignedGrid, &bottomAlignedGrid, rect](int a, int b) { + if (topAlignedGrid.contains(a)) { + a = std::abs(a - rect.top()); + } else { + a = std::abs(a - rect.bottom()); + } + if (topAlignedGrid.contains(b)) { + b = std::abs(b - rect.top()); + } else { + b = std::abs(b - rect.bottom()); + } + return a < b; + }); + + // We then move the rect to each grid intersection, and check + // if the rect fits in the QRegion. If so, we return it. + for (int horizontal : horizontalGrid) { + for (int vertical : verticalGrid) { + // Technically speaking a value could be in both left/right or + // top/bottom-aligned lists and we should check both possibilities; + // Instead, I'm only checking the first one to keep the code simple, + // since such occourrence is unlikely. + if (leftAlignedGrid.contains(horizontal)) { + tempRect.moveLeft(horizontal); + } else { + tempRect.moveRight(horizontal); + } + if (topAlignedGrid.contains(vertical)) { + tempRect.moveTop(vertical); + } else { + tempRect.moveBottom(vertical); + } + if (reg.intersected(tempRect) == tempRect) { + return tempRect.topLeft(); + } + } + } + + // The rectangle can't fit in the QRegion in any possible way. We + // return the given value. + return rect.topLeft(); +} + +void ContainmentItem::openContextMenu(const QPointF &globalPos) +{ + if (globalPos.isNull()) { + return; + } + + QMouseEvent me(QEvent::MouseButtonRelease, QPointF(), globalPos, Qt::RightButton, Qt::RightButton, Qt::NoModifier); + mousePressEvent(&me); +} + +void ContainmentItem::processMimeData(QObject *mimeDataProxy, int x, int y, KIO::DropJob *dropJob) +{ + QMimeData *mime = qobject_cast(mimeDataProxy); + if (mime) { + processMimeData(mime, x, y, dropJob); + } else { + processMimeData(mimeDataProxy->property("mimeData").value(), x, y, dropJob); + } +} + +void ContainmentItem::processMimeData(QMimeData *mimeData, int x, int y, KIO::DropJob *dropJob) +{ + if (!mimeData) { + return; + } + + if (m_dropMenu) { + if (dropJob) { + dropJob->kill(); + } + return; + } + m_dropMenu = QPointer(new DropMenu(dropJob, mapToGlobal(QPoint(x, y)).toPoint(), this)); + + // const QMimeData *mimeData = data; + + qDebug() << "Arrived mimeData" << mimeData->urls() << mimeData->formats() << "at" << x << ", " << y; + + // Catch drops from a Task Manager and convert to usable URL. + if (!mimeData->hasUrls() && mimeData->hasFormat(QStringLiteral("text/x-orgkdeplasmataskmanager_taskurl"))) { + QList urls = {QUrl(QString::fromUtf8(mimeData->data(QStringLiteral("text/x-orgkdeplasmataskmanager_taskurl"))))}; + mimeData->setUrls(urls); + } + if (mimeData->hasFormat(QStringLiteral("text/x-plasmoidinstanceid"))) { + QString data = QString::fromUtf8(mimeData->data(QStringLiteral("text/x-plasmoidinstanceid"))); + const QStringList splitData = data.split(QLatin1Char(':'), Qt::SkipEmptyParts); + if (splitData.count() != 2) + return; + + bool ok1, ok2; + uint containmentId = splitData[0].toInt(&ok1); + uint appletId = splitData[1].toInt(&ok2); + if (!ok1 || !ok2) + return; + + auto corona = m_containment->corona(); + auto containments = corona->containments(); + for (auto containment : containments) { + if (containment->id() == containmentId) { + for (auto applet : containment->applets()) { + if (applet->id() == appletId) { + PlasmaQuick::AppletQuickItem *appletItem = PlasmaQuick::AppletQuickItem::itemForApplet(applet); + // Set parent to null and free up from old container only if we are dropping on a different containment + if (applet->containment() != m_containment) { + appletItem->setParentItem(nullptr); + } + m_containment->addApplet(applet, QRect(x, y, -1, -1)); + break; + } + } + break; + } + } + delete m_dropMenu.data(); + } else if (mimeData->hasFormat(QStringLiteral("text/x-plasmoidservicename"))) { + QString data = QString::fromUtf8(mimeData->data(QStringLiteral("text/x-plasmoidservicename"))); + const QStringList appletNames = data.split(QLatin1Char('\n'), Qt::SkipEmptyParts); + for (const QString &appletName : appletNames) { + qDebug() << "adding" << appletName; + metaObject()->invokeMethod(this, + "createApplet", + Qt::QueuedConnection, + Q_ARG(QString, appletName), + Q_ARG(QVariantList, QVariantList()), + Q_ARG(QRectF, QRectF(x, y, -1, -1))); + } + delete m_dropMenu.data(); + } else if (mimeData->hasUrls()) { + // TODO: collect the mimetypes of available script engines and offer + // to create widgets out of the matching URLs, if any + const QList urls = KUrlMimeData::urlsFromMimeData(mimeData); + if (urls.isEmpty()) { + delete m_dropMenu; + return; + } + m_dropMenu->setUrls(urls); + + if (!urls.at(0).isLocalFile()) { + QApplication::setOverrideCursor(Qt::WaitCursor); + } + + QMimeDatabase db; + QMimeType firstMimetype = db.mimeTypeForUrl(urls.at(0)); + for (const QUrl &url : urls) { + if (firstMimetype != db.mimeTypeForUrl(url)) { + m_dropMenu->setMultipleMimetypes(true); + break; + } + } + + // It may be a directory or a file, let's stat + KIO::JobFlags flags = KIO::HideProgressInfo; + KIO::MimetypeJob *job = KIO::mimetype(m_dropMenu->urls().at(0), flags); + + QObject::connect(job, &KJob::result, this, &ContainmentItem::dropJobResult); + QObject::connect(job, &KIO::MimetypeJob::mimeTypeFound, this, &ContainmentItem::mimeTypeRetrieved); + + } else { + bool deleteDropMenu = true; + + const QStringList formats = mimeData->formats(); + QHash seenPlugins; + QHash pluginFormats; + + for (const QString &format : formats) { + const auto plugins = Plasma::PluginLoader::self()->listAppletMetaDataForMimeType(format); + + for (const auto &plugin : plugins) { + if (seenPlugins.contains(plugin.pluginId())) { + continue; + } + + seenPlugins.insert(plugin.pluginId(), plugin); + pluginFormats.insert(plugin.pluginId(), format); + } + } + // qDebug() << "Mimetype ..." << formats << seenPlugins.keys() << pluginFormats.values(); + + QString selectedPlugin; + + if (seenPlugins.isEmpty()) { + // do nothing + // directly create if only one offer only if the containment didn't pass an existing plugin + } else if (seenPlugins.count() == 1) { + selectedPlugin = seenPlugins.constBegin().key(); + Plasma::Applet *applet = createApplet(selectedPlugin, QVariantList(), QRect(x, y, -1, -1)); + setAppletArgs(applet, pluginFormats[selectedPlugin], mimeData->data(pluginFormats[selectedPlugin])); + + } else { + QHash actionsToPlugins; + for (const auto &info : std::as_const(seenPlugins)) { + QAction *action; + if (!info.iconName().isEmpty()) { + action = new QAction(QIcon::fromTheme(info.iconName()), info.name(), m_dropMenu); + } else { + action = new QAction(info.name(), m_dropMenu); + } + m_dropMenu->addAction(action); + action->setData(info.pluginId()); + connect(action, &QAction::triggered, this, [this, x, y, mimeData, action]() { + const QString selectedPlugin = action->data().toString(); + Plasma::Applet *applet = createApplet(selectedPlugin, QVariantList(), QRect(x, y, -1, -1)); + setAppletArgs(applet, selectedPlugin, mimeData->data(selectedPlugin)); + }); + + actionsToPlugins.insert(action, info.pluginId()); + } + m_dropMenu->show(); + deleteDropMenu = false; + } + + if (deleteDropMenu) { + // in case m_dropMenu has not been shown + delete m_dropMenu.data(); + } + } +} + +void ContainmentItem::clearDataForMimeJob(KIO::Job *job) +{ + QObject::disconnect(job, nullptr, this, nullptr); + job->kill(); + + m_dropMenu->show(); + + if (!m_dropMenu->urls().at(0).isLocalFile()) { + QApplication::restoreOverrideCursor(); + } +} + +void ContainmentItem::dropJobResult(KJob *job) +{ + if (job->error()) { + qDebug() << "ERROR" << job->error() << ' ' << job->errorString(); + clearDataForMimeJob(dynamic_cast(job)); + } +} + +void ContainmentItem::mimeTypeRetrieved(KIO::Job *job, const QString &mimetype) +{ + qDebug() << "Mimetype Job returns." << mimetype; + + KIO::TransferJob *tjob = dynamic_cast(job); + if (!tjob) { + qDebug() << "job should be a TransferJob, but isn't"; + clearDataForMimeJob(job); + return; + } + + QList appletList = Plasma::PluginLoader::self()->listAppletMetaDataForUrl(tjob->url()); + if (mimetype.isEmpty() && appletList.isEmpty()) { + clearDataForMimeJob(job); + qDebug() << "No applets found matching the url (" << tjob->url() << ") or the mimetype (" << mimetype << ")"; + return; + } else { + qDebug() << "Received a suitable dropEvent at " << m_dropMenu->dropPoint(); + qDebug() << "Bailing out. Cannot find associated dropEvent related to the TransferJob"; + + qDebug() << "Creating menu for: " << mimetype; + + appletList << Plasma::PluginLoader::self()->listAppletMetaDataForMimeType(mimetype); + + QList wallpaperList; + + if (m_containment->containmentType() != Plasma::Containment::Type::Panel + && m_containment->containmentType() != Plasma::Containment::Type::CustomPanel) { + if (m_wallpaperItem && m_wallpaperItem->supportsMimetype(mimetype)) { + wallpaperList << m_wallpaperItem->kPackage().metadata(); + } else { + wallpaperList = WallpaperItem::listWallpaperMetadataForMimetype(mimetype); + } + } + + const bool isPlasmaPackage = (mimetype == QLatin1String("application/x-plasma")); + + if ((!appletList.isEmpty() || !wallpaperList.isEmpty() || isPlasmaPackage) && !m_dropMenu->isMultipleMimetypes()) { + QAction *installPlasmaPackageAction = nullptr; + if (isPlasmaPackage) { + QAction *action = new QAction(i18n("Plasma Package"), m_dropMenu); + action->setSeparator(true); + m_dropMenu->addAction(action); + + installPlasmaPackageAction = new QAction(QIcon::fromTheme(QStringLiteral("application-x-plasma")), i18n("Install"), m_dropMenu); + m_dropMenu->addAction(installPlasmaPackageAction); + + const QString &packagePath = tjob->url().toLocalFile(); + connect(installPlasmaPackageAction, &QAction::triggered, this, [this, packagePath]() { + using namespace KPackage; + + PackageJob *job = PackageJob::update(QStringLiteral("Plasma/Applet"), packagePath); + connect(job, &KJob::finished, this, [this, packagePath, job]() { + auto fail = [](const QString &text) { + KNotification::event(QStringLiteral("plasmoidInstallationFailed"), + i18n("Package Installation Failed"), + text, + QStringLiteral("dialog-error"), + KNotification::CloseOnTimeout, + QStringLiteral("plasma_workspace")); + }; + + // if the applet is already installed, just add it to the containment + if (job->error() != KJob::NoError && job->error() != PackageJob::PackageAlreadyInstalledError + && job->error() != PackageJob::NewerVersionAlreadyInstalledError) { + fail(job->errorText()); + return; + } + + const Package package = job->package(); + if (!package.isValid() || !package.metadata().isValid()) { + fail(i18n("The package you just dropped is invalid.")); + return; + } + + createApplet(package.metadata().pluginId(), QVariantList(), QRect(m_dropMenu->dropPoint(), QSize(-1, -1))); + }); + }); + } + + QAction *action = new QAction(i18n("Widgets"), m_dropMenu); + action->setSeparator(true); + m_dropMenu->addAction(action); + + for (const auto &info : std::as_const(appletList)) { + const QString actionText = i18nc("Add widget", "Add %1", info.name()); + QAction *action = new QAction(actionText, m_dropMenu); + if (!info.iconName().isEmpty()) { + action->setIcon(QIcon::fromTheme(info.iconName())); + } + m_dropMenu->addAction(action); + action->setData(info.pluginId()); + const QUrl url = tjob->url(); + connect(action, &QAction::triggered, this, [this, action, mimetype, url]() { + Plasma::Applet *applet = createApplet(action->data().toString(), QVariantList(), QRect(m_dropMenu->dropPoint(), QSize(-1, -1))); + setAppletArgs(applet, mimetype, url); + }); + } + { + QAction *action = new QAction(i18nc("Add icon widget", "Add Icon"), m_dropMenu); + m_dropMenu->addAction(action); + action->setData(QStringLiteral("org.kde.plasma.icon")); + const QUrl url = tjob->url(); + connect(action, &QAction::triggered, this, [this, action, mimetype, url]() { + Plasma::Applet *applet = createApplet(action->data().toString(), QVariantList(), QRect(m_dropMenu->dropPoint(), QSize(-1, -1))); + setAppletArgs(applet, mimetype, url); + }); + } + + QHash actionsToWallpapers; + if (!wallpaperList.isEmpty()) { + QAction *action = new QAction(i18n("Wallpaper"), m_dropMenu); + action->setSeparator(true); + m_dropMenu->addAction(action); + + QMap sorted; + for (const auto &info : std::as_const(appletList)) { + sorted.insert(info.name(), info); + } + + for (const KPluginMetaData &info : std::as_const(wallpaperList)) { + const QString actionText = i18nc("Set wallpaper", "Set %1", info.name()); + QAction *action = new QAction(actionText, m_dropMenu); + if (!info.iconName().isEmpty()) { + action->setIcon(QIcon::fromTheme(info.iconName())); + } + m_dropMenu->addAction(action); + actionsToWallpapers.insert(action, info.pluginId()); + const QUrl url = tjob->url(); + connect(action, &QAction::triggered, this, [this, info, url]() { + // Change wallpaper plugin if it's not the current one + if (containment()->wallpaperPlugin() != info.pluginId()) { + containment()->setWallpaperPlugin(info.pluginId()); + } + + // set wallpapery stuff + if (m_wallpaperItem && url.isValid()) { + m_wallpaperItem->requestOpenUrl(url); + } + }); + } + } + } else { + // case in which we created the menu ourselves, just the "fetching type entry, directly create the icon applet + if (!m_dropMenu->isDropjobMenu()) { + Plasma::Applet *applet = createApplet(QStringLiteral("org.kde.plasma.icon"), QVariantList(), QRect(m_dropMenu->dropPoint(), QSize(-1, -1))); + setAppletArgs(applet, mimetype, tjob->url()); + } else { + QAction *action; + QAction *sep = new QAction(i18n("Widgets"), m_dropMenu); + sep->setSeparator(true); + m_dropMenu->addAction(sep); + // we can at least create an icon as a link to the URL + action = new QAction(i18nc("Add icon widget", "Add Icon"), m_dropMenu); + m_dropMenu->addAction(action); + + const QUrl url = tjob->url(); + connect(action, &QAction::triggered, this, [this, mimetype, url]() { + Plasma::Applet *applet = createApplet(QStringLiteral("org.kde.plasma.icon"), QVariantList(), QRect(m_dropMenu->dropPoint(), QSize(-1, -1))); + setAppletArgs(applet, mimetype, url); + }); + } + } + clearDataForMimeJob(tjob); + } +} + +void ContainmentItem::appletAddedForward(Plasma::Applet *applet, const QRectF &geometryHint) +{ + if (!applet) { + return; + } + PlasmoidItem *appletGraphicObject = qobject_cast(AppletQuickItem::itemForApplet(applet)); + m_plasmoidItems.append(appletGraphicObject); + connect(appletGraphicObject, &QObject::destroyed, this, [this, appletGraphicObject]() { + m_plasmoidItems.removeAll(appletGraphicObject); + }); + + QPointF removalPosition = appletGraphicObject->m_positionBeforeRemoval; + QPointF position = appletGraphicObject->position(); + + if (geometryHint.x() > 0 || geometryHint.y() > 0) { + position = geometryHint.topLeft(); + if (geometryHint.width() > 0 && geometryHint.height() > 0) { + appletGraphicObject->setSize(geometryHint.size()); + } + } else if (removalPosition.x() > 0.0 && removalPosition.y() > 0.0) { + position = removalPosition; + } else if (position.isNull() && m_containment->containmentType() == Plasma::Containment::Type::Desktop) { + // If no position was provided, and we're adding an applet to the desktop, + // add the applet to the center. This avoids always placing new applets + // in the top left corner, which is likely to be covered by something. + position = QPointF{width() / 2.0 - appletGraphicObject->width() / 2.0, // + height() / 2.0 - appletGraphicObject->height() / 2.0}; + } + + appletGraphicObject->setX(position.x()); + appletGraphicObject->setY(position.y()); +} + +void ContainmentItem::appletRemovedForward(Plasma::Applet *applet) +{ + if (!AppletQuickItem::hasItemForApplet(applet)) { + return; + } + PlasmoidItem *appletGraphicObject = qobject_cast(AppletQuickItem::itemForApplet(applet)); + if (appletGraphicObject) { + m_plasmoidItems.removeAll(appletGraphicObject); + if (appletGraphicObject->parentItem()) { + appletGraphicObject->m_positionBeforeRemoval = appletGraphicObject->mapToItem(this, QPointF()); + } + } +} + +void ContainmentItem::loadWallpaper() +{ + if (!m_containment->isContainment()) { + return; + } + + if (m_containment->containmentType() != Plasma::Containment::Type::Desktop && m_containment->containmentType() != Plasma::Containment::Type::Custom) { + if (!isLoading()) { + applet()->updateConstraints(Plasma::Applet::UiReadyConstraint); + } + return; + } + + auto *oldWallpaper = m_wallpaperItem; + + if (!m_containment->wallpaperPlugin().isEmpty()) { + m_wallpaperItem = WallpaperItem::loadWallpaper(this); + } + + if (m_wallpaperItem) { + m_wallpaperItem->setZ(-1000); + // Qml seems happier if the parent gets set in this way + m_wallpaperItem->setProperty("parent", QVariant::fromValue(this)); + + if (isLoading()) { + connect( + m_wallpaperItem, + &WallpaperItem::isLoadingChanged, + this, + [this]() { + if (!isLoading()) { + applet()->updateConstraints(Plasma::Applet::UiReadyConstraint); + } + }, + Qt::SingleShotConnection); + } else { + applet()->updateConstraints(Plasma::Applet::UiReadyConstraint); + } + + // set anchors + QQmlExpression expr(qmlObject()->engine()->rootContext(), m_wallpaperItem, QStringLiteral("parent")); + QQmlProperty prop(m_wallpaperItem, QStringLiteral("anchors.fill")); + prop.write(expr.evaluate()); + } + m_containment->setProperty("wallpaperGraphicsObject", QVariant::fromValue(m_wallpaperItem)); + delete oldWallpaper; + + Q_EMIT wallpaperItemChanged(); +} + +// PROTECTED-------------------- + +void ContainmentItem::mouseReleaseEvent(QMouseEvent *event) +{ + event->setAccepted(m_containment->containmentActions().contains(Plasma::ContainmentActions::eventToString(event))); +} + +void ContainmentItem::mousePressEvent(QMouseEvent *event) + +{ + // even if the menu is executed synchronously, other events may be processed + // by the qml incubator when plasma is loading, so we need to guard there + if (m_contextMenu) { + m_contextMenu->close(); + for (const auto actions = m_contextMenu->actions(); auto action : actions) { + if (action->menu()) { + action->menu()->disconnect(m_contextMenu.get()); + } + } + m_contextMenu->disconnect(m_containment); + m_contextMenu->clear(); + } + + const QString trigger = Plasma::ContainmentActions::eventToString(event); + Plasma::ContainmentActions *plugin = m_containment->containmentActions().value(trigger); + + if (!plugin) { + event->setAccepted(false); + return; + } + + const auto contextualActions = plugin->contextualActions(); + if (contextualActions.empty()) { + event->setAccepted(false); + return; + } + + // the plugin can be a single action or a context menu + // Don't have an action list? execute as single action + // and set the event position as action data + if (contextualActions.length() == 1) { + QAction *action = contextualActions.at(0); + action->setData(event->pos()); + action->trigger(); + event->accept(); + return; + } + + // FIXME: very inefficient appletAt() implementation + Plasma::Applet *applet = nullptr; + for (QObject *appletObject : std::as_const(m_plasmoidItems)) { + if (PlasmoidItem *ai = qobject_cast(appletObject)) { + if (ai->isVisible() && ai->contains(ai->mapFromItem(this, event->position()))) { + applet = ai->applet(); + break; + } else { + ai = nullptr; + } + } + } + // qDebug() << "Invoking menu for applet" << applet; + + if (!m_contextMenu) { + m_contextMenu.reset(new QMenu); + m_contextMenu->setAttribute(Qt::WA_TranslucentBackground); + // this is a workaround where Qt now creates the menu widget + // in .exec before oxygen can polish it and set the following attribute + // end workaround + if (m_contextMenu->winId()) { + m_contextMenu->windowHandle()->setTransientParent(window()); + } + m_contextMenu->setAttribute(Qt::WA_DeleteOnClose, false); + KAcceleratorManager::manage(m_contextMenu.get()); + } + + Q_EMIT m_containment->contextualActionsAboutToShow(); + + if (applet) { + Q_EMIT applet->contextualActionsAboutToShow(); + addAppletActions(m_contextMenu.get(), applet, event); + } else { + addContainmentActions(m_contextMenu.get(), event); + } + + // this is a workaround where Qt will fail to realize a mouse has been released + + // this happens if a window which does not accept focus spawns a new window that takes focus and X grab + // whilst the mouse is depressed + // https://bugreports.qt.io/browse/QTBUG-59044 + // this causes the next click to go missing + + // by releasing manually we avoid that situation + auto ungrabMouseHack = [this]() { + if (window() && window()->mouseGrabberItem()) { + window()->mouseGrabberItem()->ungrabMouse(); + } + }; + + // pre 5.8.0 QQuickWindow code is "item->grabMouse(); sendEvent(item, mouseEvent)" + // post 5.8.0 QQuickWindow code is sendEvent(item, mouseEvent); item->grabMouse() + if (QVersionNumber::fromString(QLatin1String(qVersion())) > QVersionNumber(5, 8, 0)) { + QTimer::singleShot(0, this, ungrabMouseHack); + } else { + ungrabMouseHack(); + } + // end workaround + + QPoint pos = event->globalPosition().toPoint(); + if (window() && m_containment->containmentType() == Plasma::Containment::Type::Panel) { + m_contextMenu->adjustSize(); + + if (QScreen *screen = window()->screen()) { + const QRect geo = screen->availableGeometry(); + + pos = QPoint(qBound(geo.left(), pos.x(), geo.right() + 1 - m_contextMenu->width()), + qBound(geo.top(), pos.y(), geo.bottom() + 1 - m_contextMenu->height())); + } + } + + if (m_contextMenu->isEmpty()) { + m_contextMenu.reset(); + event->accept(); + return; + } + + // Bug 344205 keep panel visible while menu is open + const auto oldStatus = m_containment->status(); + m_containment->setStatus(Plasma::Types::RequiresAttentionStatus); + + connect(m_contextMenu.get(), &QMenu::aboutToHide, m_containment, [this, oldStatus] { + m_containment->setStatus(oldStatus); + }); + + for (auto action : m_contextMenu->actions()) { + if (action->menu()) { + connect(action->menu(), &QMenu::aboutToShow, m_contextMenu.get(), [this, action] { + if (action->menu()->windowHandle()) { + // Need to add the transient parent otherwise Qt will create a new toplevel + action->menu()->windowHandle()->setTransientParent(m_contextMenu->windowHandle()); + } + }); + } + } + + m_contextMenu->popup(pos); + event->setAccepted(true); +} + +void ContainmentItem::wheelEvent(QWheelEvent *event) +{ + const QString trigger = Plasma::ContainmentActions::eventToString(event); + Plasma::ContainmentActions *plugin = m_containment->containmentActions().value(trigger); + + if (!plugin) { + event->setAccepted(false); + return; + } + + if (std::abs(event->angleDelta().x()) > std::abs(event->angleDelta().y())) { + m_wheelDelta += event->angleDelta().x(); + } else { + m_wheelDelta += event->angleDelta().y(); + } + + // Angle delta 120 for common "one click" + // See: https://doc.qt.io/qt-5/qml-qtquick-wheelevent.html#angleDelta-prop + while (m_wheelDelta >= 120) { + m_wheelDelta -= 120; + plugin->performPreviousAction(); + } + while (m_wheelDelta <= -120) { + m_wheelDelta += 120; + plugin->performNextAction(); + } +} + +void ContainmentItem::keyPressEvent(QKeyEvent *event) +{ + PlasmoidItem::keyPressEvent(event); + if (event->isAccepted()) { + return; + } + + if (event->key() == Qt::Key_Menu) { + QPointF localPos; + auto focusedItem = window()->activeFocusItem(); + if (focusedItem) { + localPos = focusedItem->mapToItem(this, QPointF(0, 0)); + } + + QMouseEvent me(QEvent::MouseButtonRelease, localPos, QPointF(), Qt::RightButton, Qt::RightButton, event->modifiers()); + mousePressEvent(&me); + event->accept(); + } +} + +void ContainmentItem::addAppletActions(QMenu *desktopMenu, Plasma::Applet *applet, QEvent *event) +{ + const auto listActions = applet->contextualActions(); + for (QAction *action : listActions) { + if (action) { + desktopMenu->addAction(action); + } + } + + if (!applet->failedToLaunch()) { + QAction *configureApplet = applet->internalAction(QStringLiteral("configure")); + if (configureApplet && configureApplet->isEnabled()) { + desktopMenu->addAction(configureApplet); + } + QAction *appletAlternatives = applet->internalAction(QStringLiteral("alternatives")); + if (appletAlternatives && appletAlternatives->isEnabled()) { + desktopMenu->addAction(appletAlternatives); + } + } + + desktopMenu->addSeparator(); + if (m_containment->containmentType() == Plasma::Containment::Type::Desktop) { + auto action = m_containment->corona()->action(QStringLiteral("edit mode")); + if (action) { + desktopMenu->addAction(action); + } + } else { + addContainmentActions(desktopMenu, event); + } + + if (m_containment->immutability() == Plasma::Types::Mutable + && (m_containment->containmentType() != Plasma::Containment::Type::Panel || m_containment->isUserConfiguring())) { + QAction *closeApplet = applet->internalAction(QStringLiteral("remove")); + // qDebug() << "checking for removal" << closeApplet; + if (closeApplet) { + if (!desktopMenu->isEmpty()) { + desktopMenu->addSeparator(); + } + + // qDebug() << "adding close action" << closeApplet->isEnabled() << closeApplet->isVisible(); + desktopMenu->addAction(closeApplet); + } + } +} + +void ContainmentItem::addContainmentActions(QMenu *desktopMenu, QEvent *event) +{ + if (m_containment->corona()->immutability() != Plasma::Types::Mutable // + && !KAuthorized::authorizeAction(QStringLiteral("plasma/containment_actions"))) { + // qDebug() << "immutability"; + return; + } + + // this is what ContainmentPrivate::prepareContainmentActions was + const QString trigger = Plasma::ContainmentActions::eventToString(event); + Plasma::ContainmentActions *plugin = m_containment->containmentActions().value(trigger); + + if (!plugin) { + return; + } + + if (plugin->containment() != m_containment) { + plugin->setContainment(m_containment); + + // now configure it + KConfigGroup cfg(m_containment->corona()->config(), QStringLiteral("ActionPlugins")); + cfg = KConfigGroup(&cfg, QString::number((int)m_containment->containmentType())); + KConfigGroup pluginConfig = KConfigGroup(&cfg, trigger); + plugin->restore(pluginConfig); + } + + QList actions = plugin->contextualActions(); + + if (actions.isEmpty()) { + // it probably didn't bother implementing the function. give the user a chance to set + // a better plugin. note that if the user sets no-plugin this won't happen... + /* clang-format off */ + if ((m_containment->containmentType() != Plasma::Containment::Type::Panel + && m_containment->containmentType() != Plasma::Containment::Type::CustomPanel) + && m_containment->internalAction(QStringLiteral("configure"))) { /* clang-format on */ + desktopMenu->addAction(m_containment->internalAction(QStringLiteral("configure"))); + } + } else { + desktopMenu->addActions(actions); + } + + return; +} + +bool ContainmentItem::isLoading() const +{ + return m_wallpaperItem && m_wallpaperItem->isLoading(); +} + +void ContainmentItem::itemChange(ItemChange change, const ItemChangeData &value) +{ + if (!m_containment) { + // This can happen only if the client QML code declares a PlasmoidItem somewhere else than the root object + PlasmoidItem::itemChange(change, value); + return; + } + if (change == QQuickItem::ItemSceneChange) { + // we have a window: create the representations if needed + if (value.window && !m_containment->wallpaperPlugin().isEmpty()) { + loadWallpaper(); + } else if (m_wallpaperItem) { + deleteWallpaperItem(); + Q_EMIT wallpaperItemChanged(); + } + } + + PlasmoidItem::itemChange(change, value); +} + +void ContainmentItem::deleteWallpaperItem() +{ + m_containment->setProperty("wallpaperGraphicsObject", QVariant()); + m_wallpaperItem->deleteLater(); + m_wallpaperItem = nullptr; +} + +#include "moc_containmentitem.cpp" diff --git a/src/plasmaquick/plasmoid/containmentitem.h b/src/plasmaquick/plasmoid/containmentitem.h new file mode 100644 index 0000000..d732423 --- /dev/null +++ b/src/plasmaquick/plasmoid/containmentitem.h @@ -0,0 +1,154 @@ +/* + SPDX-FileCopyrightText: 2008-2013 Aaron Seigo + SPDX-FileCopyrightText: 2010-2013 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef CONTAINMENTITEM_H +#define CONTAINMENTITEM_H + +#include + +#include + +#include "plasmoiditem.h" + +class AppletQuickItem; +class WallpaperItem; +class DropMenu; +class KJob; + +namespace KIO +{ +class Job; +class DropJob; +} + +/** + * @brief This class is exposed to containments QML as the attached property Plasmoid + * + * Import Statement + * @code import org.kde.plasma.plasmoid @endcode + * @version 2.0 + */ +class ContainmentItem : public PlasmoidItem +{ + Q_OBJECT + + Q_PROPERTY(WallpaperItem *wallpaper READ wallpaperItem NOTIFY wallpaperItemChanged) + + /** + * True if the UI is still loading, for instance a desktop which doesn't have its wallpaper yet + */ + Q_PROPERTY(bool loading READ isLoading NOTIFY isLoadingChanged) + +public: + ContainmentItem(QQuickItem *parent = nullptr); + + void classBegin() override; + + // Not for QML + Plasma::Containment *containment() const + { + return m_containment.data(); + } + + inline WallpaperItem *wallpaperItem() const + { + return m_wallpaperItem; + } + + // For QML use + /** + * Returns the corresponding PlasmoidItem of one of its applets + */ + Q_INVOKABLE AppletQuickItem *itemFor(Plasma::Applet *applet) const; + + /** + * Process the mime data arrived to a particular coordinate, either with a drag and drop or paste with middle mouse button + */ + Q_INVOKABLE void processMimeData(QMimeData *data, int x, int y, KIO::DropJob *dropJob = nullptr); + + /** + * Process the mime data arrived to a particular coordinate, either with a drag and drop or paste with middle mouse button + */ + Q_INVOKABLE void processMimeData(QObject *data, int x, int y, KIO::DropJob *dropJob = nullptr); + + /** + * Search for a containment at those coordinates. + * the coordinates are passed as local coordinates of *this* containment + */ + Q_INVOKABLE QObject *containmentItemAt(int x, int y); + + /** + * Map coordinates from relative to the given applet to relative to this containment + */ + Q_INVOKABLE QPointF mapFromApplet(Plasma::Applet *applet, int x, int y); + + /** + *Map coordinates from relative to this containment to relative to the given applet + */ + Q_INVOKABLE QPointF mapToApplet(Plasma::Applet *applet, int x, int y); + + /** + * Given a geometry, it adjusts it moving it completely inside of the boundaries + * of availableScreenRegion + * @return the toLeft point of the rectangle + */ + Q_INVOKABLE QPointF adjustToAvailableScreenRegion(int x, int y, int w, int h) const; + + /** + * Opens the context menu of the Corona + * + * @param globalPos menu position in the global coordinate system + * @since 5.102 + */ + Q_INVOKABLE void openContextMenu(const QPointF &globalPos); + +protected: + void init() override; + void loadWallpaper(); + void mousePressEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void wheelEvent(QWheelEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + + void addAppletActions(QMenu *desktopMenu, Plasma::Applet *applet, QEvent *event); + void addContainmentActions(QMenu *desktopMenu, QEvent *event); + + bool isLoading() const; + void itemChange(ItemChange change, const ItemChangeData &value) override; + +Q_SIGNALS: + // Property notifiers + void appletsChanged(); + void drawWallpaperChanged(); + void actionsChanged(); + void editModeChanged(); + void wallpaperItemChanged(); + void isLoadingChanged(); + +private Q_SLOTS: + // Used only internally by a metaObject()->invokeMethod + Plasma::Applet *createApplet(const QString &plugin, const QVariantList &args, const QRectF &geom); + +private: + void dropJobResult(KJob *job); + void mimeTypeRetrieved(KIO::Job *job, const QString &mimetype); + void appletAddedForward(Plasma::Applet *applet, const QRectF &geometryHint); + void appletRemovedForward(Plasma::Applet *applet); + void clearDataForMimeJob(KIO::Job *job); + void setAppletArgs(Plasma::Applet *applet, const QString &mimetype, const QVariant &data); + void deleteWallpaperItem(); + + WallpaperItem *m_wallpaperItem = nullptr; + QList m_plasmoidItems; + QPointer m_containment; + std::unique_ptr m_contextMenu; // QTBUG-122409: Keep the context menu so menu actions will keep their accessible interfaces valid + QPointer m_dropMenu; + int m_wheelDelta; + friend class PlasmoidItem; +}; + +#endif diff --git a/src/plasmaquick/plasmoid/dropmenu.cpp b/src/plasmaquick/plasmoid/dropmenu.cpp new file mode 100644 index 0000000..25e9470 --- /dev/null +++ b/src/plasmaquick/plasmoid/dropmenu.cpp @@ -0,0 +1,106 @@ +/* + SPDX-FileCopyrightText: 2008 Chani Armitage + SPDX-FileCopyrightText: 2008, 2009 Aaron Seigo + SPDX-FileCopyrightText: 2010 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "dropmenu.h" +#include "containmentitem.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +DropMenu::DropMenu(KIO::DropJob *dropJob, const QPoint &dropPoint, ContainmentItem *parent) + : QObject(parent) + , m_dropPoint(dropPoint) + , m_dropJob(dropJob) +{ + if (!dropJob) { + m_menu = new QMenu(i18n("Content dropped")); + + // Polish before creating a native window below. The style could want change the surface format + // of the window which will have no effect when the native window has already been created. + m_menu->ensurePolished(); + + connect(m_menu, &QMenu::aboutToHide, this, &QObject::deleteLater); + } else { + connect(m_dropJob, &QObject::destroyed, this, &QObject::deleteLater); + } +} + +DropMenu::~DropMenu() +{ + if (m_menu) { + delete m_menu; + } +} + +QList DropMenu::urls() const +{ + return m_urls; +} + +void DropMenu::setUrls(const QList &urls) +{ + m_urls = urls; +} + +QPoint DropMenu::dropPoint() const +{ + return m_dropPoint; +} + +void DropMenu::show() +{ + QWindow *transientParent = nullptr; + if (auto containmentItem = qobject_cast(parent())) { + transientParent = containmentItem->window(); + } + + if (m_dropJob) { + KJobWindows::setWindow(m_dropJob, transientParent); + + m_dropJob->setApplicationActions(m_dropActions); + m_dropJob->showMenu(m_dropPoint); + } else if (m_menu) { + if (m_menu->winId()) { + m_menu->windowHandle()->setTransientParent(transientParent); + } + m_menu->addActions(m_dropActions); + m_menu->popup(m_dropPoint); + } +} + +void DropMenu::addAction(QAction *action) +{ + m_dropActions << action; +} + +bool DropMenu::isDropjobMenu() const +{ + return (m_dropJob ? true : false); +} + +void DropMenu::setMultipleMimetypes(bool multipleMimetypes) +{ + if (m_multipleMimetypes != multipleMimetypes) { + m_multipleMimetypes = multipleMimetypes; + } +} + +bool DropMenu::isMultipleMimetypes() const +{ + return m_multipleMimetypes; +} + +#include "moc_dropmenu.cpp" diff --git a/src/plasmaquick/plasmoid/dropmenu.h b/src/plasmaquick/plasmoid/dropmenu.h new file mode 100644 index 0000000..24a7612 --- /dev/null +++ b/src/plasmaquick/plasmoid/dropmenu.h @@ -0,0 +1,52 @@ +/* + SPDX-FileCopyrightText: 2008-2013 Aaron Seigo + SPDX-FileCopyrightText: 2010-2013 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef DROPMENU_H +#define DROPMENU_H + +#include +#include + +class QJSValue; +class QMenu; +class QAction; + +namespace KIO +{ +class DropJob; +} + +class ContainmentItem; + +class DropMenu : public QObject +{ + Q_OBJECT + +public: + DropMenu(KIO::DropJob *dropJob, const QPoint &dropPoint, ContainmentItem *parent = nullptr); + ~DropMenu() override; + + QList urls() const; + QPoint dropPoint() const; + void setUrls(const QList &urls); + void setMultipleMimetypes(bool multipleMimetypes); + + void addAction(QAction *action); + bool isDropjobMenu() const; + bool isMultipleMimetypes() const; + void show(); + +private: + QPoint m_dropPoint; + QMenu *m_menu = nullptr; + KIO::DropJob *m_dropJob = nullptr; + QList m_dropActions = QList(); + QList m_urls = QList(); + bool m_multipleMimetypes = false; +}; + +#endif diff --git a/src/plasmaquick/plasmoid/plasmoiditem.cpp b/src/plasmaquick/plasmoid/plasmoiditem.cpp new file mode 100644 index 0000000..d2226b9 --- /dev/null +++ b/src/plasmaquick/plasmoid/plasmoiditem.cpp @@ -0,0 +1,453 @@ +/* + SPDX-FileCopyrightText: 2008-2013 Aaron Seigo + SPDX-FileCopyrightText: 2010-2013 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "plasmoiditem.h" +#include "appletcontext_p.h" +#include "sharedqmlengine.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "containmentitem.h" +#include "wallpaperitem.h" + +#include + +PlasmoidItem::PlasmoidItem(QQuickItem *parent) + : AppletQuickItem(parent) + , m_toolTipTextFormat(0) + , m_toolTipItem(nullptr) + , m_hideOnDeactivate(true) + , m_oldKeyboardShortcut(0) + , m_positionBeforeRemoval(QPointF(-1, -1)) +{ + qmlRegisterAnonymousType("org.kde.plasma.plasmoid", 1); +} + +PlasmoidItem::~PlasmoidItem() +{ +} + +void PlasmoidItem::init() +{ + AppletQuickItem::init(); + + auto *applet = PlasmoidItem::applet(); + if (!applet) { + // This can happen only if the client QML code declares a PlasmoidItem somewhere else than the root object + return; + } + + connect(applet, &Plasma::Applet::contextualActionsAboutToShow, this, &PlasmoidItem::contextualActionsAboutToShow); + + connect(applet, &Plasma::Applet::titleChanged, this, [this]() { + if (m_toolTipMainText.isNull()) { + Q_EMIT toolTipMainTextChanged(); + } + }); + + if (applet->containment()) { + connect(applet->containment(), &Plasma::Containment::screenChanged, this, &PlasmoidItem::screenChanged); + + connect(applet->containment()->corona(), &Plasma::Corona::screenGeometryChanged, this, [this](int id) { + if (id == AppletQuickItem::applet()->containment()->screen()) { + Q_EMIT screenGeometryChanged(); + } + }); + + connect(applet->containment()->corona(), &Plasma::Corona::availableScreenRegionChanged, this, &ContainmentItem::availableScreenRegionChanged); + connect(applet->containment()->corona(), &Plasma::Corona::availableScreenRectChanged, this, &ContainmentItem::availableScreenRectChanged); + } + + connect(this, &PlasmoidItem::expandedChanged, [=, this](bool expanded) { + // if both compactRepresentationItem and fullRepresentationItem exist, + // the applet is in a popup + if (expanded) { + /* clang-format off */ + if (compactRepresentationItem() + && fullRepresentationItem() + && fullRepresentationItem()->window() + && compactRepresentationItem()->window() + && fullRepresentationItem()->window() != compactRepresentationItem()->window() + && fullRepresentationItem()->parentItem()) { + /* clang-format on */ + fullRepresentationItem()->parentItem()->installEventFilter(this); + } else if (fullRepresentationItem() && fullRepresentationItem()->parentItem()) { + fullRepresentationItem()->parentItem()->removeEventFilter(this); + } + } + }); + + geometryChange(QRectF(), QRectF(x(), y(), width(), height())); + + connect(applet, &Plasma::Applet::activated, this, [=, this]() { + // in case the applet doesn't want to get shrunk on reactivation, + // we always expand it again (only in order to conform with legacy behaviour) + bool activate = !(isExpanded() && isActivationTogglesExpanded()); + + setExpanded(activate); + }); + + connect(applet, &Plasma::Applet::destroyedChanged, this, &PlasmoidItem::destroyedChanged); + + auto args = applet->startupArguments(); + + if (args.count() == 1) { + Q_EMIT externalData(QString(), args.first()); + } else if (!args.isEmpty()) { + Q_EMIT externalData(QString(), args); + } +} + +void PlasmoidItem::destroyedChanged(bool destroyed) +{ + // if an item loses its scene before losing the focus, will never + // be able to gain focus again + if (destroyed && window() && window()->activeFocusItem()) { + QQuickItem *focus = window()->activeFocusItem(); + QQuickItem *candidate = focus; + bool isAncestor = false; + + // search if the current focus item is a child or grandchild of the applet + while (candidate) { + if (candidate == this) { + isAncestor = true; + break; + } + candidate = candidate->parentItem(); + } + + if (isAncestor) { + // Found? remove focus for the whole hierarchy + candidate = focus; + + while (candidate && candidate != this) { + candidate->setFocus(false); + candidate = candidate->parentItem(); + } + } + } + + setVisible(!destroyed); +} + +QString PlasmoidItem::toolTipMainText() const +{ + if (m_toolTipMainText.isNull()) { + return applet()->title(); + } else { + return m_toolTipMainText; + } +} + +void PlasmoidItem::setToolTipMainText(const QString &text) +{ + // Here we are abusing the difference between a null and an empty string. + // by default is null so falls back to the name + // the fist time it gets set, an empty non null one is set, and won't fallback anymore + if (!m_toolTipMainText.isNull() && m_toolTipMainText == text) { + return; + } + + if (text.isEmpty()) { + m_toolTipMainText = QStringLiteral(""); // this "" makes it non-null + } else { + m_toolTipMainText = text; + } + + Q_EMIT toolTipMainTextChanged(); +} + +QString PlasmoidItem::toolTipSubText() const +{ + if (m_toolTipSubText.isNull() && applet()->pluginMetaData().isValid()) { + return applet()->pluginMetaData().description(); + } else { + return m_toolTipSubText; + } +} + +void PlasmoidItem::setToolTipSubText(const QString &text) +{ + // Also there the difference between null and empty gets exploited + if (!m_toolTipSubText.isNull() && m_toolTipSubText == text) { + return; + } + + if (text.isEmpty()) { + m_toolTipSubText = QStringLiteral(""); // this "" makes it non-null + } else { + m_toolTipSubText = text; + } + + Q_EMIT toolTipSubTextChanged(); +} + +int PlasmoidItem::toolTipTextFormat() const +{ + return m_toolTipTextFormat; +} + +void PlasmoidItem::setToolTipTextFormat(int format) +{ + if (m_toolTipTextFormat == format) { + return; + } + + m_toolTipTextFormat = format; + Q_EMIT toolTipTextFormatChanged(); +} + +QQuickItem *PlasmoidItem::toolTipItem() const +{ + return m_toolTipItem.data(); +} + +void PlasmoidItem::setToolTipItem(QQuickItem *toolTipItem) +{ + if (m_toolTipItem.data() == toolTipItem) { + return; + } + + m_toolTipItem = toolTipItem; + connect(m_toolTipItem.data(), &QObject::destroyed, this, &PlasmoidItem::toolTipItemChanged); + + Q_EMIT toolTipItemChanged(); +} + +int PlasmoidItem::screen() const +{ + if (Plasma::Containment *c = applet()->containment()) { + return c->screen(); + } + + return -1; +} + +void PlasmoidItem::setHideOnWindowDeactivate(bool hide) +{ + if (m_hideOnDeactivate != hide) { + m_hideOnDeactivate = hide; + Q_EMIT hideOnWindowDeactivateChanged(); + } +} + +bool PlasmoidItem::hideOnWindowDeactivate() const +{ + return m_hideOnDeactivate; +} + +QRect PlasmoidItem::screenGeometry() const +{ + if (!applet() || !applet()->containment() || !applet()->containment()->corona() || applet()->containment()->screen() < 0) { + return QRect(); + } + + return applet()->containment()->corona()->screenGeometry(applet()->containment()->screen()); +} + +QVariantList PlasmoidItem::availableScreenRegion() const +{ + QVariantList regVal; + + if (!applet()->containment() || !applet()->containment()->corona()) { + return regVal; + } + + QRegion reg = QRect(0, 0, width(), height()); + int screenId = screen(); + if (screenId > -1) { + reg = applet()->containment()->corona()->availableScreenRegion(screenId); + } + + auto it = reg.begin(); + const auto itEnd = reg.end(); + for (; it != itEnd; ++it) { + QRect rect = *it; + // make it relative + QRect geometry = applet()->containment()->corona()->screenGeometry(screenId); + rect.moveTo(rect.topLeft() - geometry.topLeft()); + regVal << QVariant::fromValue(QRectF(rect)); + } + return regVal; +} + +QRect PlasmoidItem::availableScreenRect() const +{ + if (!applet()->containment() || !applet()->containment()->corona()) { + return QRect(); + } + + QRect rect(0, 0, width(), height()); + + int screenId = screen(); + + // If corona returned an invalid screenId, try to use lastScreen value if it is valid + if (screenId == -1 && applet()->containment()->lastScreen() > -1) { + screenId = applet()->containment()->lastScreen(); + // Is this a screen not actually valid? + if (screenId >= applet()->containment()->corona()->numScreens()) { + screenId = -1; + } + } + + if (screenId > -1) { + rect = applet()->containment()->corona()->availableScreenRect(screenId); + // make it relative + QRect geometry = applet()->containment()->corona()->screenGeometry(screenId); + rect.moveTo(rect.topLeft() - geometry.topLeft()); + } + + return rect; +} + +bool PlasmoidItem::event(QEvent *event) +{ + // QAction keyboard shortcuts cannot work with QML2 (and probably newver will + // since in Qt qtquick and qwidgets cannot depend from each other in any way) + // so do a simple keyboard shortcut matching here + if (event->type() == QEvent::KeyPress) { + QKeyEvent *ke = static_cast(event); + QKeySequence seq(ke->key() | ke->modifiers()); + + QList actions = applet()->internalActions(); + actions.append(applet()->contextualActions()); + // find the wallpaper action if we are a containment + ContainmentItem *ci = qobject_cast(this); + if (ci) { + WallpaperItem *wi = ci->wallpaperItem(); + if (wi) { + actions << wi->contextualActions(); + } + } + + // add any actions of the corona + if (applet()->containment() && applet()->containment()->corona()) { + actions << applet()->containment()->corona()->actions(); + } + + bool keySequenceUsed = false; + for (auto a : std::as_const(actions)) { + if (a->shortcut().isEmpty()) { + continue; + } + + if (!a->isEnabled()) { + continue; + } + + // this will happen on a normal, non emacs shortcut + if (seq.matches(a->shortcut()) == QKeySequence::ExactMatch) { + event->accept(); + a->trigger(); + m_oldKeyboardShortcut = 0; + return true; + + // first part of an emacs style shortcut? + } else if (seq.matches(a->shortcut()) == QKeySequence::PartialMatch) { + keySequenceUsed = true; + m_oldKeyboardShortcut = ke->key() | ke->modifiers(); + + // no match at all, but it can be the second part of an emacs style shortcut + } else { + QKeySequence seq(m_oldKeyboardShortcut, ke->key() | ke->modifiers()); + + if (seq.matches(a->shortcut()) == QKeySequence::ExactMatch) { + event->accept(); + a->trigger(); + + return true; + } + } + } + + if (!keySequenceUsed) { + m_oldKeyboardShortcut = 0; + } + } + + return AppletQuickItem::event(event); +} + +void PlasmoidItem::prepareContextualActions() +{ + Q_EMIT applet()->contextualActionsAboutToShow(); +} + +bool PlasmoidItem::eventFilter(QObject *watched, QEvent *event) +{ + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *e = static_cast(event); + + // pass it up to the applet + // well, actually we have to pass it to the *containment* + // because all the code for showing an applet's contextmenu is actually in Containment. + Plasma::Containment *c = applet()->containment(); + if (c) { + const QString trigger = Plasma::ContainmentActions::eventToString(event); + Plasma::ContainmentActions *plugin = c->containmentActions().value(trigger); + if (!plugin) { + return false; + } + + ContainmentItem *ci = qobject_cast(AppletQuickItem::itemForApplet(c)); + + if (!ci) { + return false; + } + + // the plugin can be a single action or a context menu + // Don't have an action list? execute as single action + // and set the event position as action data + if (plugin->contextualActions().length() == 1) { + // but first check whether we are not a popup + // we don't want to randomly create applets without confirmation + if (static_cast(watched)->window() != ci->window()) { + return true; + } + + QAction *action = plugin->contextualActions().at(0); + action->setData(e->globalPosition().toPoint()); + action->trigger(); + return true; + } + + QMenu *desktopMenu = new QMenu; + if (desktopMenu->winId()) { + desktopMenu->windowHandle()->setTransientParent(window()); + } + prepareContextualActions(); + ci->addAppletActions(desktopMenu, applet(), event); + + if (!desktopMenu->isEmpty()) { + desktopMenu->setAttribute(Qt::WA_DeleteOnClose); + desktopMenu->popup(e->globalPosition().toPoint()); + return true; + } + + delete desktopMenu; + return false; + } + } + + return AppletQuickItem::eventFilter(watched, event); +} + +#include "moc_plasmoiditem.cpp" diff --git a/src/plasmaquick/plasmoid/plasmoiditem.h b/src/plasmaquick/plasmoid/plasmoiditem.h new file mode 100644 index 0000000..9c8bb1e --- /dev/null +++ b/src/plasmaquick/plasmoid/plasmoiditem.h @@ -0,0 +1,199 @@ +/* + SPDX-FileCopyrightText: 2008 Chani Armitage + SPDX-FileCopyrightText: 2008, 2009 Aaron Seigo + SPDX-FileCopyrightText: 2010 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMOIDITEM_H +#define PLASMOIDITEM_H + +#include +#include +#include + +#include + +#include +#include +#include + +#include + +class QActionGroup; +class QSizeF; +class KConfigPropertyMap; + +namespace Plasma +{ +class ConfigLoader; +} // namespace Plasma + +/** + * @class PlasmoidItem + * + * Import Statement + * @code import org.kde.plasma.plasmoid @endcode + * @version 2.0 + */ +class PlasmoidItem : public PlasmaQuick::AppletQuickItem +{ + Q_OBJECT + + /** + * The QML root object defined in the applet main.qml will be direct child of an PlasmoidItem instance + */ + + /** + * Main title for the plasmoid tooltip or other means of quick information: + * it's the same as the title property by default, but it can be personalized + */ + Q_PROPERTY(QString toolTipMainText READ toolTipMainText WRITE setToolTipMainText NOTIFY toolTipMainTextChanged) + + /** + * Description for the plasmoid tooltip or other means of quick information: + * it comes from the pluginifo comment by default, but it can be personalized + */ + Q_PROPERTY(QString toolTipSubText READ toolTipSubText WRITE setToolTipSubText NOTIFY toolTipSubTextChanged) + + /** + * how to handle the text format of the tooltip subtext: + * * Text.AutoText (default) + * * Text.PlainText + * * Text.StyledText + * * Text.RichText + * Note: in the default implementation the main text is always plain text + */ + Q_PROPERTY(int toolTipTextFormat READ toolTipTextFormat WRITE setToolTipTextFormat NOTIFY toolTipTextFormatChanged) + + /** + * This allows to set fully custom QML item as the tooltip. + * It will ignore all texts set by setToolTipMainText or setToolTipSubText + * + * @since 5.19 + */ + Q_PROPERTY(QQuickItem *toolTipItem READ toolTipItem WRITE setToolTipItem NOTIFY toolTipItemChanged) + + // TODO: This was moved up from ContainmentItem because it is required by the + // Task Manager applet (for "Show only tasks from this screen") and no Qt API exposes + // screen numbering. An alternate solution that doesn't extend the applet interface + // would be preferable if found. + Q_PROPERTY(int screen READ screen NOTIFY screenChanged) + + /** + * Provides access to the geometry of the applet is in. + * Can be useful to figure out what's the absolute position of the applet. + * TODO: move in containment + */ + Q_PROPERTY(QRect screenGeometry READ screenGeometry NOTIFY screenGeometryChanged) + + /** + * Whether the dialog should be hidden when the dialog loses focus. + * + * The default value is @c false. + * TODO KF6: move to Applet? probably not + **/ + Q_PROPERTY(bool hideOnWindowDeactivate READ hideOnWindowDeactivate WRITE setHideOnWindowDeactivate NOTIFY hideOnWindowDeactivateChanged) + + /** + * screen area free of panels: the coordinates are relative to the containment, + * it's independent from the screen position + * For more precise available geometry use availableScreenRegion() + */ + Q_PROPERTY(QRect availableScreenRect READ availableScreenRect NOTIFY availableScreenRectChanged) + + /** + * The available region of this screen, panels excluded. It's a list of rectanglesO: from containment + */ + Q_PROPERTY(QVariantList availableScreenRegion READ availableScreenRegion NOTIFY availableScreenRegionChanged) + +public: + PlasmoidItem(QQuickItem *parent = nullptr); + ~PlasmoidItem() override; + + // QML API------------------------------------------------------------------- + + /** + * Should be called before retrieving any action + * to ensure contents are up to date + * @see contextualActionsAboutToShow + * @since 5.58 + */ + Q_INVOKABLE void prepareContextualActions(); + + QVariantList availableScreenRegion() const; + + QRect availableScreenRect() const; + + // PROPERTY ACCESSORS------------------------------------------------------------------- + QString pluginName() const; + + QString toolTipMainText() const; + void setToolTipMainText(const QString &text); + + QString toolTipSubText() const; + void setToolTipSubText(const QString &text); + + int toolTipTextFormat() const; + void setToolTipTextFormat(int format); + + QQuickItem *toolTipItem() const; + void setToolTipItem(QQuickItem *toolTipItem); + + int screen() const; + QRect screenGeometry() const; + + bool hideOnWindowDeactivate() const; + void setHideOnWindowDeactivate(bool hide); + +Q_SIGNALS: + /** + * somebody else, usually the containment sent some data to the applet + * @param mimetype the mime type of the data such as text/plain + * @param data either the actual data or an URL representing it + */ + void externalData(const QString &mimetype, const QVariant &data); + + /** + * Emitted just before the contextual actions are about to show + * For instance just before the context menu containing the actions + * added with setAction() is shown + */ + void contextualActionsAboutToShow(); + + // PROPERTY change notifiers-------------- + void toolTipMainTextChanged(); + void toolTipSubTextChanged(); + void toolTipTextFormatChanged(); + void toolTipItemChanged(); + void screenChanged(); + void screenGeometryChanged(); + void hideOnWindowDeactivateChanged(); + void availableScreenRegionChanged(); + void availableScreenRectChanged(); + void contextualActionsChanged(); + +protected: + void init() override; + bool event(QEvent *event) override; + bool eventFilter(QObject *watched, QEvent *event) override; + +private: + void destroyedChanged(bool destroyed); + + // UI-specific members ------------------ + + QString m_toolTipMainText; + QString m_toolTipSubText; + int m_toolTipTextFormat; + QPointer m_toolTipItem; + bool m_hideOnDeactivate : 1; + int m_oldKeyboardShortcut; + + friend class ContainmentItem; + // This is used by ContainmentItem + QPointF m_positionBeforeRemoval; +}; + +#endif diff --git a/src/plasmaquick/plasmoid/wallpaperitem.cpp b/src/plasmaquick/plasmoid/wallpaperitem.cpp new file mode 100644 index 0000000..4be47ad --- /dev/null +++ b/src/plasmaquick/plasmoid/wallpaperitem.cpp @@ -0,0 +1,274 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "wallpaperitem.h" +#include "appletcontext_p.h" + +#include "containmentitem.h" +#include "sharedqmlengine.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "debug_p.h" + +WallpaperItem::WallpaperItem(QQuickItem *parent) + : QQuickItem(parent) +{ + // resize at the beginning to avoid as much resize events as possible + if (parent) { + setSize(QSizeF(parent->width(), parent->height())); + } +} + +WallpaperItem::~WallpaperItem() +{ +} + +void WallpaperItem::classBegin() +{ + QQuickItem::classBegin(); + PlasmaQuick::AppletContext *ac = qobject_cast(QQmlEngine::contextForObject(this)->parentContext()); + Q_ASSERT(ac); + m_containment = ac->applet()->containment(); + m_wallpaperPlugin = m_containment->wallpaperPlugin(); + m_qmlObject = ac->sharedQmlEngine(); + m_qmlObject->setParent(this); + + m_pkg = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Wallpaper")); + m_pkg.setPath(m_wallpaperPlugin); + + if (configScheme()) { + m_configuration = new KConfigPropertyMap(configScheme(), this); + } + + connect(m_containment->corona(), &Plasma::Corona::startupCompleted, this, &WallpaperItem::accentColorChanged); +} + +void WallpaperItem::componentComplete() +{ + QQuickItem::componentComplete(); + + m_loading = false; + Q_EMIT isLoadingChanged(); +} + +QList WallpaperItem::listWallpaperMetadataForMimetype(const QString &mimetype, const QString &formFactor) +{ + auto filter = [&mimetype, &formFactor](const KPluginMetaData &md) -> bool { + if (!formFactor.isEmpty() && !md.value(QStringLiteral("X-Plasma-FormFactors")).contains(formFactor)) { + return false; + } + return md.value(QStringLiteral("X-Plasma-DropMimeTypes"), QStringList()).contains(mimetype); + }; + return KPackage::PackageLoader::self()->findPackages(QStringLiteral("Plasma/Wallpaper"), QString(), filter); +} + +KPackage::Package WallpaperItem::kPackage() const +{ + return m_pkg; +} + +QString WallpaperItem::pluginName() const +{ + return m_wallpaperPlugin; +} + +KConfigPropertyMap *WallpaperItem::configuration() const +{ + return m_configuration; +} + +KConfigLoader *WallpaperItem::configScheme() +{ + if (!m_configLoader) { + // FIXME: do we need "mainconfigxml" in wallpaper packagestructures? + const QString xmlPath = m_pkg.filePath("config", QStringLiteral("main.xml")); + + KConfigGroup cfg = m_containment->config(); + cfg = KConfigGroup(&cfg, QStringLiteral("Wallpaper")); + cfg = KConfigGroup(&cfg, m_wallpaperPlugin); + + if (xmlPath.isEmpty()) { + m_configLoader = new KConfigLoader(cfg, nullptr, this); + } else { + QFile file(xmlPath); + m_configLoader = new KConfigLoader(cfg, &file, this); + } + } + + return m_configLoader; +} + +void WallpaperItem::requestOpenUrl(const QUrl &url) +{ + Q_EMIT openUrlRequested(url); +} + +WallpaperItem *WallpaperItem::loadWallpaper(ContainmentItem *containmentItem) +{ + if (containmentItem->containment()->wallpaperPlugin().isEmpty()) { + return nullptr; + } + KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Wallpaper")); + pkg.setPath(containmentItem->containment()->wallpaperPlugin()); + if (!pkg.isValid()) { + qWarning() << "Error loading the wallpaper, no valid package loaded"; + return nullptr; + } + + PlasmaQuick::SharedQmlEngine *qmlObject = new PlasmaQuick::SharedQmlEngine(containmentItem->containment()); + qmlObject->setInitializationDelayed(true); + + const QString rootPath = pkg.metadata().value(QStringLiteral("X-Plasma-RootPath")); + if (!rootPath.isEmpty()) { + qmlObject->setTranslationDomain(QLatin1String("plasma_wallpaper_") + rootPath); + } else { + qmlObject->setTranslationDomain(QLatin1String("plasma_wallpaper_") + pkg.metadata().pluginId()); + } + + /* + * The initialization is delayed, so it's fine to setSource first. + * This also prevents many undefined wallpaper warnings caused by "wallpaper" being set + * when the old wallpaper plugin still exists. + */ + qmlObject->setSource(pkg.fileUrl("mainscript")); + WallpaperItem *wallpaper = qobject_cast(qmlObject->rootObject()); + if (!wallpaper) { + if (qmlObject->mainComponent() && qmlObject->mainComponent()->isError()) { + qWarning() << "Error loading the wallpaper" << qmlObject->mainComponent()->errors(); + } else if (qmlObject->rootObject()) { + qWarning() << "Root item of wallpaper" << containmentItem->containment()->wallpaperPlugin() << "not a WallpaperItem instance, instead is" + << qmlObject->rootObject(); + } + qmlObject->completeInitialization(); + delete qmlObject->rootObject(); + return nullptr; + } + + if (!qEnvironmentVariableIntValue("PLASMA_NO_CONTEXTPROPERTIES")) { + qmlObject->rootContext()->setContextProperty(QStringLiteral("wallpaper"), wallpaper); + } + + // initialize with our size to avoid as much resize events as possible + QVariantHash props; + props[QStringLiteral("parent")] = QVariant::fromValue(containmentItem); + props[QStringLiteral("width")] = containmentItem->width(); + props[QStringLiteral("height")] = containmentItem->height(); + qmlObject->completeInitialization(props); + return wallpaper; +} + +QList WallpaperItem::contextualActions() const +{ + return m_contextualActions; +} + +QQmlListProperty WallpaperItem::qmlContextualActions() +{ + return QQmlListProperty(this, + nullptr, + WallpaperItem::contextualActions_append, + WallpaperItem::contextualActions_count, + WallpaperItem::contextualActions_at, + WallpaperItem::contextualActions_clear, + WallpaperItem::contextualActions_replace, + WallpaperItem::contextualActions_removeLast); +} + +bool WallpaperItem::supportsMimetype(const QString &mimetype) const +{ + return m_pkg.metadata().value(QStringLiteral("X-Plasma-DropMimeTypes"), QStringList()).contains(mimetype); +} + +bool WallpaperItem::isLoading() const +{ + return m_loading; +} + +QColor WallpaperItem::accentColor() const +{ + return m_accentColor.value_or(QColor(Qt::transparent)); +} + +void WallpaperItem::setAccentColor(const QColor &newColor) +{ + if (m_accentColor.has_value() && m_accentColor == newColor) { + return; + } + + m_accentColor = newColor; + Q_EMIT accentColorChanged(); +} + +void WallpaperItem::resetAccentColor() +{ + if (!m_accentColor.has_value()) { + return; + } + + m_accentColor.reset(); + Q_EMIT accentColorChanged(); +} + +void WallpaperItem::contextualActions_append(QQmlListProperty *prop, QAction *action) +{ + WallpaperItem *w = static_cast(prop->object); + w->m_contextualActions.append(action); + QObject::connect(action, &QObject::destroyed, w, [w, action]() { + w->m_contextualActions.removeAll(action); + Q_EMIT w->contextualActionsChanged(w->m_contextualActions); + }); + Q_EMIT w->contextualActionsChanged(w->m_contextualActions); +}; + +qsizetype WallpaperItem::contextualActions_count(QQmlListProperty *prop) +{ + WallpaperItem *w = static_cast(prop->object); + return w->m_contextualActions.count(); +} + +QAction *WallpaperItem::contextualActions_at(QQmlListProperty *prop, qsizetype idx) +{ + WallpaperItem *w = static_cast(prop->object); + return w->m_contextualActions.value(idx); +} + +void WallpaperItem::contextualActions_clear(QQmlListProperty *prop) +{ + WallpaperItem *w = static_cast(prop->object); + w->m_contextualActions.clear(); + Q_EMIT w->contextualActionsChanged(w->m_contextualActions); +} + +void WallpaperItem::contextualActions_replace(QQmlListProperty *prop, qsizetype idx, QAction *action) +{ + WallpaperItem *w = static_cast(prop->object); + w->m_contextualActions.replace(idx, action); + Q_EMIT w->contextualActionsChanged(w->m_contextualActions); +} + +void WallpaperItem::contextualActions_removeLast(QQmlListProperty *prop) +{ + WallpaperItem *w = static_cast(prop->object); + w->m_contextualActions.pop_back(); + Q_EMIT w->contextualActionsChanged(w->m_contextualActions); +} + +#include "moc_wallpaperitem.cpp" diff --git a/src/plasmaquick/plasmoid/wallpaperitem.h b/src/plasmaquick/plasmoid/wallpaperitem.h new file mode 100644 index 0000000..f76a45f --- /dev/null +++ b/src/plasmaquick/plasmoid/wallpaperitem.h @@ -0,0 +1,127 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef WALLPAPERITEM_H +#define WALLPAPERITEM_H + +#include +#include + +#include + +class KConfigLoader; +class KConfigPropertyMap; + +class ContainmentItem; + +namespace Plasma +{ +class Containment; +} + +namespace PlasmaQuick +{ +class SharedQmlEngine; +} + +/** + * @brief This class is exposed to wallpapers as the WallpaperItem root qml item + * + * Import Statement + * @code import org.kde.plasma.plasmoid @endcode + * @version 2.0 + */ +class WallpaperItem : public QQuickItem +{ + Q_OBJECT + + Q_PROPERTY(QString pluginName READ pluginName CONSTANT) + Q_PROPERTY(KConfigPropertyMap *configuration READ configuration CONSTANT) + /** + * Actions to be added in the desktop context menu. To instantiate QActions in a declarative way, + * PlasmaCore.Action {} can be used + */ + Q_PROPERTY(QQmlListProperty contextualActions READ qmlContextualActions NOTIFY contextualActionsChanged) + Q_PROPERTY(bool loading MEMBER m_loading NOTIFY isLoadingChanged) + + /* + * The accent color manually set by the wallpaper plugin. + * By default it's transparent, which means either the dominant color is used + * when "Accent Color From Wallpaper" is enabled, or the theme color is used. + * + * @since 6.0 + */ + Q_PROPERTY(QColor accentColor READ accentColor WRITE setAccentColor NOTIFY accentColorChanged RESET resetAccentColor) + +public: + explicit WallpaperItem(QQuickItem *parent = nullptr); + ~WallpaperItem() override; + + void classBegin() override; + void componentComplete() override; + + /** + * Returns a list of all known wallpapers that can accept the given mimetype + * @param mimetype the mimetype to search for + * @param formFactor the format of the wallpaper being search for (e.g. desktop) + * @return list of wallpapers + */ + static QList listWallpaperMetadataForMimetype(const QString &mimetype, const QString &formFactor = QString()); + + /** + * Instantiate the WallpaperItem for a given containment, using the proper plugin + */ + static WallpaperItem *loadWallpaper(ContainmentItem *ContainmentItem); + + KPackage::Package kPackage() const; + + QString pluginName() const; + + KConfigPropertyMap *configuration() const; + + KConfigLoader *configScheme(); + + void requestOpenUrl(const QUrl &url); + + QList contextualActions() const; + + QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE + QQmlListProperty qmlContextualActions(); + + bool supportsMimetype(const QString &mimetype) const; + + bool isLoading() const; + + QColor accentColor() const; + void setAccentColor(const QColor &newColor); + void resetAccentColor(); + +Q_SIGNALS: + void isLoadingChanged(); + void openUrlRequested(const QUrl &url); + void contextualActionsChanged(const QList &actions); + void accentColorChanged(); + +private: + static void contextualActions_append(QQmlListProperty *prop, QAction *action); + static qsizetype contextualActions_count(QQmlListProperty *prop); + static QAction *contextualActions_at(QQmlListProperty *prop, qsizetype idx); + static void contextualActions_clear(QQmlListProperty *prop); + static void contextualActions_replace(QQmlListProperty *prop, qsizetype idx, QAction *action); + static void contextualActions_removeLast(QQmlListProperty *prop); + + QString m_wallpaperPlugin; + Plasma::Containment *m_containment = nullptr; + PlasmaQuick::SharedQmlEngine *m_qmlObject = nullptr; + KPackage::Package m_pkg; + KConfigPropertyMap *m_configuration = nullptr; + KConfigLoader *m_configLoader = nullptr; + QList m_contextualActions; + bool m_loading = false; + std::optional m_accentColor; +}; + +#endif diff --git a/src/plasmaquick/plasmoidattached_p.cpp b/src/plasmaquick/plasmoidattached_p.cpp new file mode 100644 index 0000000..1f695b3 --- /dev/null +++ b/src/plasmaquick/plasmoidattached_p.cpp @@ -0,0 +1,68 @@ +/* + SPDX-FileCopyrightText: 2023 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "plasmoidattached_p.h" + +#include "appletcontext_p.h" +#include "appletquickitem.h" + +#include +#include + +namespace PlasmaQuick +{ +///////////////////////PlasmoidAttached + +PlasmoidAttached::PlasmoidAttached(QObject *parent) + : QObject(parent) +{ +} + +PlasmoidAttached::~PlasmoidAttached() +{ +} + +Plasma::Applet *PlasmoidAttached::qmlAttachedProperties(QObject *object) +{ + // Special case: we are asking the attached Plasmoid property of an AppletItem itself, which in this case is its own Applet + if (auto *appletItem = qobject_cast(object)) { + return appletItem->applet(); + } else if (auto *applet = qobject_cast(object)) { + // Asked for the Plasmoid of an Applet itself + return applet; + } + + QQmlContext *context = qmlContext(object); + while (context) { + if (auto *appletContext = qobject_cast(context)) { + return appletContext->applet(); + } + + context = context->parentContext(); + } + + return nullptr; +} + +///////////////////////PlasmoidAttached + +ContainmentAttached::ContainmentAttached(QObject *parent) + : QObject(parent) +{ +} + +ContainmentAttached::~ContainmentAttached() +{ +} + +Plasma::Containment *ContainmentAttached::qmlAttachedProperties(QObject *object) +{ + return qobject_cast(PlasmoidAttached::qmlAttachedProperties(object)); +} + +} + +#include "moc_plasmoidattached_p.cpp" diff --git a/src/plasmaquick/plasmoidattached_p.h b/src/plasmaquick/plasmoidattached_p.h new file mode 100644 index 0000000..ef55189 --- /dev/null +++ b/src/plasmaquick/plasmoidattached_p.h @@ -0,0 +1,73 @@ +/* + SPDX-FileCopyrightText: 2023 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMOIDATTACHED_P_H +#define PLASMOIDATTACHED_P_H + +#include +#include +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the public Plasma API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +namespace Plasma +{ +class Applet; +class Containment; +} + +namespace PlasmaQuick +{ +// Class used exclusively to generate the Plasmoid.* attached proeprties, which are Applet instances +class PlasmoidAttached : public QObject +{ + Q_OBJECT + +public: + /** TODO: When the migration to the new action api is done, remove this enum + */ + enum ActionPriority { + LowPriorityAction = QAction::LowPriority, + NormalPriorityAction = QAction::NormalPriority, + HighPriorityAction = QAction::HighPriority, + }; + Q_ENUM(ActionPriority) + + PlasmoidAttached(QObject *parent = nullptr); + ~PlasmoidAttached() override; + + ////NEEDED BY QML TO CREATE ATTACHED PROPERTIES + static Plasma::Applet *qmlAttachedProperties(QObject *object); +}; + +// Class used exclusively to generate the Plasmoid.* attached proeprties, which are Applet instances +class ContainmentAttached : public QObject +{ + Q_OBJECT + +public: + ContainmentAttached(QObject *parent = nullptr); + ~ContainmentAttached() override; + + ////NEEDED BY QML TO CREATE ATTACHED PROPERTIES + static Plasma::Containment *qmlAttachedProperties(QObject *object); +}; + +} + +QML_DECLARE_TYPEINFO(PlasmaQuick::PlasmoidAttached, QML_HAS_ATTACHED_PROPERTIES) +QML_DECLARE_TYPEINFO(PlasmaQuick::ContainmentAttached, QML_HAS_ATTACHED_PROPERTIES) + +#endif diff --git a/src/plasmaquick/popupplasmawindow.cpp b/src/plasmaquick/popupplasmawindow.cpp new file mode 100644 index 0000000..1b59b40 --- /dev/null +++ b/src/plasmaquick/popupplasmawindow.cpp @@ -0,0 +1,388 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "popupplasmawindow.h" + +#include +#include + +#include "debug_p.h" +#include +#include +#include +#include + +#include "plasmashellwaylandintegration.h" +#include "transientplacementhint_p.h" +#include "utils.h" + +namespace PlasmaQuick +{ + +class PopupPlasmaWindowPrivate +{ +public: + PopupPlasmaWindowPrivate(PopupPlasmaWindow *_q); + + void updateEffectivePopupDirection(const QRect &anchorRect, const QRect &relativePopupPosition); + void updateSlideEffect(); + void updatePosition(); + void updatePositionX11(const QPoint &position); + void updatePositionWayland(const QPoint &position); + void updateBorders(const QRect &globalPosition); + void updateVisualParentWindow(); + + PopupPlasmaWindow *q; + QPointer m_visualParent; + QPointer m_visualParentWindow; + PopupPlasmaWindow::RemoveBorders m_removeBorderStrategy = PopupPlasmaWindow::Never; + bool m_needsReposition = false; + bool m_floating = false; + bool m_animated = false; + int m_margin = 0; + Qt::Edge m_popupDirection = Qt::TopEdge; + Qt::Edge m_effectivePopupDirection = Qt::TopEdge; +}; + +PopupPlasmaWindowPrivate::PopupPlasmaWindowPrivate(PopupPlasmaWindow *_q) + : q(_q) +{ +} + +/** + * PopupPlasmaWindowPrivate::updateSlideEffect + * @param anchorRect - the rect around where the popup should be placed relative to the parent window + * @param relativePopupPosition - the final rect of the popup relative to the parent window + * + * This is based purely on position in prepartion for being called in a wayland configure event + */ +void PopupPlasmaWindowPrivate::updateEffectivePopupDirection(const QRect &anchorRect, const QRect &relativePopupPosition) +{ + Qt::Edge effectivePopupDirection = Qt::TopEdge; + if (m_popupDirection == Qt::TopEdge || m_popupDirection == Qt::BottomEdge) { + if (relativePopupPosition.center().y() >= anchorRect.center().y()) { + effectivePopupDirection = Qt::BottomEdge; + } else { + effectivePopupDirection = Qt::TopEdge; + } + } + if (m_popupDirection == Qt::LeftEdge || m_popupDirection == Qt::RightEdge) { + if (relativePopupPosition.center().x() >= anchorRect.center().x()) { + effectivePopupDirection = Qt::RightEdge; + } else { + effectivePopupDirection = Qt::LeftEdge; + } + } + + if (effectivePopupDirection != m_effectivePopupDirection) { + Q_EMIT q->effectivePopupDirectionChanged(); + m_effectivePopupDirection = effectivePopupDirection; + } +} + +void PopupPlasmaWindowPrivate::updateSlideEffect() +{ + KWindowEffects::SlideFromLocation slideLocation = KWindowEffects::NoEdge; + if (!m_animated) { + KWindowEffects::slideWindow(q, slideLocation); + return; + } + switch (m_effectivePopupDirection) { + case Qt::TopEdge: + slideLocation = KWindowEffects::BottomEdge; + break; + case Qt::BottomEdge: + slideLocation = KWindowEffects::TopEdge; + break; + case Qt::LeftEdge: + slideLocation = KWindowEffects::RightEdge; + break; + case Qt::RightEdge: + slideLocation = KWindowEffects::LeftEdge; + break; + } + KWindowEffects::slideWindow(q, slideLocation); +} + +void PopupPlasmaWindowPrivate::updatePosition() +{ + m_needsReposition = false; + + if (!m_visualParent || !m_visualParent->window()) { + qCWarning(LOG_PLASMAQUICK) << "Exposed with no visual parent. Window positioning broken."; + return; + } + q->setTransientParent(m_visualParent->window()); + TransientPlacementHint placementHint; + QRectF parentAnchorRect = QRectF(m_visualParent->mapToScene(QPointF(0, 0)), m_visualParent->size()); + + if (!m_floating) { + QRect windowVisibleRect = m_visualParent->window()->mask().boundingRect(); + // pad parentAnchorRect to the window it's in, so that the popup appears outside the panel + // even if the tooltip area does not fill it + if (m_popupDirection == Qt::TopEdge || m_popupDirection == Qt::BottomEdge) { + parentAnchorRect.setTop(windowVisibleRect.top()); + // QRect::bottom() is off by one + parentAnchorRect.setBottom(windowVisibleRect.bottom() + 1); + } + if (m_popupDirection == Qt::LeftEdge || m_popupDirection == Qt::RightEdge) { + parentAnchorRect.setLeft(windowVisibleRect.left()); + // QRect::right() is off by one + parentAnchorRect.setRight(windowVisibleRect.right() + 1); + } + } + + placementHint.setParentAnchorArea(parentAnchorRect.toRect()); + placementHint.setParentAnchor(m_popupDirection); + placementHint.setPopupAnchor(PlasmaQuickPrivate::oppositeEdge(m_popupDirection)); + placementHint.setConstrainByAnchorWindow(true); + placementHint.setFlipConstraintAdjustments(m_floating ? Qt::Vertical : Qt::Orientations()); + placementHint.setMargin(m_margin); + + const QRect popupPosition = TransientPlacementHelper::popupRect(q, placementHint); + + QRect relativePopupPosition = popupPosition; + if (m_visualParent->window()) { + relativePopupPosition = relativePopupPosition.translated(-m_visualParent->window()->position()); + } + updateEffectivePopupDirection(parentAnchorRect.toRect(), relativePopupPosition); + updateSlideEffect(); + + if (KWindowSystem::isPlatformX11()) { + updatePositionX11(popupPosition.topLeft()); + } else if (KWindowSystem::isPlatformWayland()) { + updatePositionWayland(popupPosition.topLeft()); + } + + updateBorders(popupPosition); +} + +void PopupPlasmaWindowPrivate::updatePositionX11(const QPoint &position) +{ + q->setPosition(position); +} + +void PopupPlasmaWindowPrivate::updatePositionWayland(const QPoint &position) +{ + // still update's Qt internal reference as it's used by the next dialog + // this can be dropped when we're using true semantic positioning in the backend + q->setPosition(position); + + PlasmaShellWaylandIntegration::get(q)->setPosition(position); +} + +void PopupPlasmaWindowPrivate::updateBorders(const QRect &globalPosition) +{ + // disables borders for the edges that are touching the screen edge + + QScreen *screen = QGuiApplication::screenAt(globalPosition.center()); + if (!screen) { + return; + } + const QRect screenGeometry = screen->geometry(); + + Qt::Edges enabledBorders = Qt::LeftEdge | Qt::RightEdge | Qt::TopEdge | Qt::BottomEdge; + + if (m_margin) { + q->setBorders(enabledBorders); + return; + } + + if (m_removeBorderStrategy & PopupPlasmaWindow::AtScreenEdges) { + if (globalPosition.top() <= screenGeometry.top()) { + enabledBorders.setFlag(Qt::TopEdge, false); + } + if (globalPosition.bottom() >= screenGeometry.bottom()) { + enabledBorders.setFlag(Qt::BottomEdge, false); + } + if (globalPosition.left() <= screenGeometry.left()) { + enabledBorders.setFlag(Qt::LeftEdge, false); + } + if (globalPosition.right() >= screenGeometry.right()) { + enabledBorders.setFlag(Qt::RightEdge, false); + } + } + if (m_removeBorderStrategy & PopupPlasmaWindow::AtPanelEdges) { + switch (m_popupDirection) { + case Qt::LeftEdge: + enabledBorders.setFlag(Qt::RightEdge, false); + break; + case Qt::RightEdge: + enabledBorders.setFlag(Qt::LeftEdge, false); + break; + case Qt::BottomEdge: + enabledBorders.setFlag(Qt::TopEdge, false); + break; + case Qt::TopEdge: + default: + enabledBorders.setFlag(Qt::BottomEdge, false); + break; + } + } + q->setBorders(enabledBorders); +} + +void PopupPlasmaWindowPrivate::updateVisualParentWindow() +{ + if (m_visualParentWindow) { + QObject::disconnect(m_visualParentWindow, &QQuickWindow::yChanged, q, &PopupPlasmaWindow::queuePositionUpdate); + QObject::disconnect(m_visualParentWindow, &QQuickWindow::xChanged, q, &PopupPlasmaWindow::queuePositionUpdate); + } + + m_visualParentWindow = m_visualParent ? m_visualParent->window() : nullptr; + + if (m_visualParentWindow) { + QObject::connect(m_visualParentWindow, &QQuickWindow::yChanged, q, &PopupPlasmaWindow::queuePositionUpdate); + QObject::connect(m_visualParentWindow, &QQuickWindow::xChanged, q, &PopupPlasmaWindow::queuePositionUpdate); + } +} + +PopupPlasmaWindow::PopupPlasmaWindow(const QString &svgPrefix) + : PlasmaWindow(svgPrefix) + , d(new PopupPlasmaWindowPrivate(this)) +{ +} + +PopupPlasmaWindow::~PopupPlasmaWindow() +{ +} + +void PopupPlasmaWindow::setVisualParent(QQuickItem *item) +{ + if (item == d->m_visualParent) { + return; + } + + if (d->m_visualParent) { + disconnect(d->m_visualParent, SIGNAL(windowChanged(QQuickWindow *)), this, SLOT(updateVisualParentWindow())); + } + + d->m_visualParent = item; + d->updateVisualParentWindow(); + + if (d->m_visualParent) { + connect(d->m_visualParent, SIGNAL(windowChanged(QQuickWindow *)), this, SLOT(updateVisualParentWindow())); + } + + Q_EMIT visualParentChanged(); + queuePositionUpdate(); +} + +QQuickItem *PopupPlasmaWindow::visualParent() const +{ + return d->m_visualParent; +} + +Qt::Edge PopupPlasmaWindow::popupDirection() const +{ + return d->m_popupDirection; +} + +void PopupPlasmaWindow::setPopupDirection(Qt::Edge popupDirection) +{ + if (popupDirection == d->m_popupDirection) { + return; + } + d->m_popupDirection = popupDirection; + + if (isExposed()) { + qCWarning(LOG_PLASMAQUICK) << "location should be set before showing popup window"; + } + queuePositionUpdate(); + + Q_EMIT popupDirectionChanged(); +} + +Qt::Edge PopupPlasmaWindow::effectivePopupDirection() const +{ + return d->m_effectivePopupDirection; +} + +bool PopupPlasmaWindow::floating() const +{ + return d->m_floating; +} + +void PopupPlasmaWindow::setFloating(bool floating) +{ + if (floating == d->m_floating) { + return; + } + d->m_floating = floating; + queuePositionUpdate(); + Q_EMIT floatingChanged(); +} + +bool PopupPlasmaWindow::animated() const +{ + return d->m_animated; +} + +void PopupPlasmaWindow::setAnimated(bool animated) +{ + d->m_animated = animated; + queuePositionUpdate(); + Q_EMIT animatedChanged(); +} + +PopupPlasmaWindow::RemoveBorders PopupPlasmaWindow::removeBorderStrategy() const +{ + return d->m_removeBorderStrategy; +} + +void PopupPlasmaWindow::setRemoveBorderStrategy(PopupPlasmaWindow::RemoveBorders strategy) +{ + if (d->m_removeBorderStrategy == strategy) { + return; + } + + d->m_removeBorderStrategy = strategy; + queuePositionUpdate(); // This will update borders as well + Q_EMIT removeBorderStrategyChanged(); +} + +int PopupPlasmaWindow::margin() const +{ + return d->m_margin; +} + +void PopupPlasmaWindow::setMargin(int margin) +{ + if (d->m_margin == margin) { + return; + } + + d->m_margin = margin; + queuePositionUpdate(); + Q_EMIT marginChanged(); +} + +bool PopupPlasmaWindow::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::UpdateRequest: + if (d->m_needsReposition) { + d->updatePosition(); + } + break; + case QEvent::Show: + d->updatePosition(); + break; + case QEvent::Resize: + d->updatePosition(); + break; + default: + break; + } + return PlasmaQuick::PlasmaWindow::event(event); +} + +void PopupPlasmaWindow::queuePositionUpdate() +{ + d->m_needsReposition = true; +} +} + +#include "moc_popupplasmawindow.cpp" diff --git a/src/plasmaquick/popupplasmawindow.h b/src/plasmaquick/popupplasmawindow.h new file mode 100644 index 0000000..4ec1eca --- /dev/null +++ b/src/plasmaquick/popupplasmawindow.h @@ -0,0 +1,114 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#pragma once + +#include "plasmawindow.h" + +#include +#include + +namespace PlasmaQuick +{ +class PopupPlasmaWindowPrivate; + +/** + * @brief The PopupPlasmaWindow class is a styled Plasma window that can be positioned + * relative to an existing Item on another window. When shown the popup is placed correctly. + * + * On Wayland this is currently an XdgTopLevel with the PlasmaShellSurface used on top. + * Do not rely on that implementation detail + */ +class PLASMAQUICK_EXPORT PopupPlasmaWindow : public PlasmaWindow +{ + Q_OBJECT + + /** + * The anchor item to place the popup relative to. + */ + Q_PROPERTY(QQuickItem *visualParent READ visualParent WRITE setVisualParent NOTIFY visualParentChanged) + + /** + * Defines the default direction to place the popup relative to the visualParent. + */ + Q_PROPERTY(Qt::Edge popupDirection READ popupDirection WRITE setPopupDirection NOTIFY popupDirectionChanged) + + /** + * Defines the direction the popup was placed relative to the visualParent. + * This property is read-only and is updated when the popup is shown. + * The value whilst the popup is hidden is undefined. + */ + Q_PROPERTY(Qt::Edge effectivePopupDirection READ effectivePopupDirection NOTIFY effectivePopupDirectionChanged) + + /** + * Defines whether the popup can appaer (float) over the parent window. The default is false. + */ + Q_PROPERTY(bool floating READ floating WRITE setFloating NOTIFY floatingChanged) + + /** + * Defines whether the popup is animated on show and close. The default is false. + */ + Q_PROPERTY(bool animated READ animated WRITE setAnimated NOTIFY animatedChanged) + + /** + * Defines which borders should be enabled/disabled when the popup is shown. The default is to show all borders + */ + Q_PROPERTY(RemoveBorders removeBorderStrategy READ removeBorderStrategy WRITE setRemoveBorderStrategy NOTIFY removeBorderStrategyChanged) + + /** + * If set provides a gap between the parent window and all screen edges + */ + Q_PROPERTY(int margin READ margin WRITE setMargin NOTIFY marginChanged) + +public: + enum RemoveBorder { Never = 0x0, AtScreenEdges = 0x1, AtPanelEdges = 0x2 }; + Q_DECLARE_FLAGS(RemoveBorders, RemoveBorder) + Q_ENUM(RemoveBorder); + + PopupPlasmaWindow(const QString &svgPrefix = QStringLiteral("dialogs/background")); + ~PopupPlasmaWindow() override; + QQuickItem *visualParent() const; + void setVisualParent(QQuickItem *parent); + + Qt::Edge popupDirection() const; + void setPopupDirection(Qt::Edge popupDirection); + + Qt::Edge effectivePopupDirection() const; + + bool floating() const; + void setFloating(bool floating); + + bool animated() const; + void setAnimated(bool animated); + + RemoveBorders removeBorderStrategy() const; + void setRemoveBorderStrategy(RemoveBorders borders); + + int margin() const; + void setMargin(int margin); + + bool event(QEvent *event) override; + +Q_SIGNALS: + void visualParentChanged(); + void popupDirectionChanged(); + void effectivePopupDirectionChanged(); + void floatingChanged(); + void animatedChanged(); + void removeBorderStrategyChanged(); + void marginChanged(); + +protected Q_SLOTS: + void queuePositionUpdate(); + +private: + Q_PRIVATE_SLOT(d, void updateVisualParentWindow()) + + friend class PopupPlasmaWindowPrivate; + const std::unique_ptr d; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(PopupPlasmaWindow::RemoveBorders) +} diff --git a/src/plasmaquick/quickviewsharedengine.cpp b/src/plasmaquick/quickviewsharedengine.cpp new file mode 100644 index 0000000..081e0ca --- /dev/null +++ b/src/plasmaquick/quickviewsharedengine.cpp @@ -0,0 +1,244 @@ +/* + This file is part of the KDE libraries + SPDX-FileCopyrightText: 2015 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "quickviewsharedengine.h" +#include "sharedqmlengine.h" + +#include +#include +#include + +#include + +namespace PlasmaQuick +{ +class QuickViewSharedEnginePrivate +{ +public: + QuickViewSharedEnginePrivate(QuickViewSharedEngine *module) + : q(module) + , resizeMode(QuickViewSharedEngine::ResizeMode::SizeRootObjectToView) + , initialSize(0, 0) + { + qmlObject = new SharedQmlEngine(q); + QObject::connect(qmlObject, &SharedQmlEngine::statusChanged, q, &QuickViewSharedEngine::statusChanged); + QObject::connect(qmlObject, &SharedQmlEngine::finished, q, [this]() { + executionFinished(); + }); + } + + void executionFinished(); + void syncResizeMode(); + void syncWidth(); + void syncHeight(); + + QuickViewSharedEngine *q; + SharedQmlEngine *qmlObject; + QuickViewSharedEngine::ResizeMode resizeMode; + QSize initialSize; +}; + +void QuickViewSharedEnginePrivate::executionFinished() +{ + if (!qmlObject->rootObject()) { + return; + } + + QQuickItem *item = qobject_cast(qmlObject->rootObject()); + + if (!item) { + return; + } + + item->setParentItem(q->contentItem()); + initialSize = QSize(item->width(), item->height()); + + if (q->size().isEmpty()) { + q->resize(initialSize); + q->contentItem()->setSize(initialSize); + } + + syncResizeMode(); +} + +void QuickViewSharedEnginePrivate::syncResizeMode() +{ + QQuickItem *item = qobject_cast(qmlObject->rootObject()); + + if (!item) { + return; + } + + if (resizeMode == QuickViewSharedEngine::SizeRootObjectToView) { + item->setSize(QSize(q->width(), q->height())); + + QObject::disconnect(item, &QQuickItem::widthChanged, q, nullptr); + QObject::disconnect(item, &QQuickItem::heightChanged, q, nullptr); + + } else { + QObject::connect(item, &QQuickItem::widthChanged, q, [this]() { + syncWidth(); + }); + QObject::connect(item, &QQuickItem::heightChanged, q, [this]() { + syncHeight(); + }); + + syncWidth(); + syncHeight(); + } +} + +void QuickViewSharedEnginePrivate::syncWidth() +{ + QQuickItem *item = qobject_cast(qmlObject->rootObject()); + + if (!item) { + return; + } + + q->setWidth(item->width()); +} + +void QuickViewSharedEnginePrivate::syncHeight() +{ + QQuickItem *item = qobject_cast(qmlObject->rootObject()); + + if (!item) { + return; + } + + q->setHeight(item->height()); +} + +QuickViewSharedEngine::QuickViewSharedEngine(QWindow *parent) + : QQuickWindow(parent) + , d(new QuickViewSharedEnginePrivate(this)) +{ +} + +QuickViewSharedEngine::~QuickViewSharedEngine() +{ + delete d->qmlObject; +} + +void QuickViewSharedEngine::setTranslationDomain(const QString &translationDomain) +{ + d->qmlObject->setTranslationDomain(translationDomain); +} + +QString QuickViewSharedEngine::translationDomain() const +{ + return d->qmlObject->translationDomain(); +} + +std::shared_ptr QuickViewSharedEngine::engine() const +{ + return d->qmlObject->engine(); +} + +QList QuickViewSharedEngine::errors() const +{ + QList errs; + + if (d->qmlObject->mainComponent()) { + errs = d->qmlObject->mainComponent()->errors(); + } + + return errs; +} + +QSize QuickViewSharedEngine::sizeHint() const +{ + QQuickItem *item = qobject_cast(d->qmlObject->rootObject()); + if (!item) { + return QSize(); + } + + const QSizeF implicitSize(item->implicitWidth(), item->implicitHeight()); + + if (!implicitSize.isEmpty()) { + return implicitSize.toSize(); + } + + return QSize(item->width(), item->height()); +} + +QSize QuickViewSharedEngine::initialSize() const +{ + return d->initialSize; +} + +QuickViewSharedEngine::ResizeMode QuickViewSharedEngine::resizeMode() const +{ + return d->resizeMode; +} + +QQmlContext *QuickViewSharedEngine::rootContext() const +{ + return d->qmlObject->rootContext(); +} + +QQuickItem *QuickViewSharedEngine::rootObject() const +{ + return qobject_cast(d->qmlObject->rootObject()); +} + +void QuickViewSharedEngine::setResizeMode(ResizeMode mode) +{ + if (d->resizeMode == mode) { + return; + } + + d->resizeMode = mode; + + Q_EMIT resizeModeChanged(mode); + + QQuickItem *item = qobject_cast(d->qmlObject->rootObject()); + if (!item) { + return; + } + + d->syncResizeMode(); +} + +void QuickViewSharedEngine::setSource(const QUrl &url) +{ + if (d->qmlObject->source() == url) { + return; + } + + d->qmlObject->setSource(url); + Q_EMIT sourceChanged(url); +} + +QUrl QuickViewSharedEngine::source() const +{ + return d->qmlObject->source(); +} + +QQmlComponent::Status QuickViewSharedEngine::status() const +{ + if (!d->qmlObject->mainComponent()) { + return QQmlComponent::Null; + } + + return QQmlComponent::Status(d->qmlObject->status()); +} + +void QuickViewSharedEngine::resizeEvent(QResizeEvent *e) +{ + QQuickItem *item = qobject_cast(d->qmlObject->rootObject()); + if (item && d->resizeMode == SizeRootObjectToView) { + item->setSize(e->size()); + } + + QQuickWindow::resizeEvent(e); +} + +} + +#include "moc_quickviewsharedengine.cpp" diff --git a/src/plasmaquick/quickviewsharedengine.h b/src/plasmaquick/quickviewsharedengine.h new file mode 100644 index 0000000..480b45d --- /dev/null +++ b/src/plasmaquick/quickviewsharedengine.h @@ -0,0 +1,101 @@ +/* + This file is part of the KDE libraries + SPDX-FileCopyrightText: 2015 Marco Martin + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef QUICKVIEWSHAREDENGINE_H +#define QUICKVIEWSHAREDENGINE_H + +#include "plasmaquick_export.h" + +#include +#include +#include +#include +#include + +class QQuickItem; +class QQmlEngine; + +namespace PlasmaQuick +{ +class QuickViewSharedEnginePrivate; + +/** + * @class PlasmaQuick::QuickViewSharedEngine quickviewsharedengine.h KQuickAddons/QuickViewSharedEngine + */ +class PLASMAQUICK_EXPORT QuickViewSharedEngine : public QQuickWindow +{ + Q_OBJECT + + Q_PROPERTY(ResizeMode resizeMode READ resizeMode WRITE setResizeMode NOTIFY resizeModeChanged) + Q_PROPERTY(QQmlComponent::Status status READ status NOTIFY statusChanged) + Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) + +public: + enum ResizeMode { + SizeViewToRootObject, + SizeRootObjectToView, + }; + Q_ENUM(ResizeMode) + + explicit QuickViewSharedEngine(QWindow *parent = nullptr); + ~QuickViewSharedEngine() override; + + /** + * Installs a translation domain for all + * i18n global functions. If a translation domain is set all i18n calls delegate to the + * matching i18nd calls with the provided translation domain. + * + * The translationDomain affects all i18n calls including those from imports. Because of + * that modules intended to be used as imports should prefer the i18nd variants and set + * the translation domain explicitly in each call. + * + * This method is only required if your declarative usage is inside a library. If it's + * in an application there is no need to set the translation domain as the application's + * domain can be used. + * + * @param translationDomain The translation domain to be used for i18n calls. + */ + void setTranslationDomain(const QString &translationDomain); + + /** + * @return the translation domain for the i18n calls done in this QML engine + */ + QString translationDomain() const; + + std::shared_ptr engine() const; + QList errors() const; + QSize sizeHint() const; + QSize initialSize() const; + QQmlContext *rootContext() const; + QQuickItem *rootObject() const; + QUrl source() const; + QQmlComponent::Status status() const; + ResizeMode resizeMode() const; + void setResizeMode(ResizeMode); + +protected: + void resizeEvent(QResizeEvent *e) override; + +public Q_SLOTS: + void setSource(const QUrl &url); + +Q_SIGNALS: + void statusChanged(QQmlComponent::Status status); + void resizeModeChanged(QuickViewSharedEngine::ResizeMode resizeMode); + void sourceChanged(const QUrl &source); + +private: + const std::unique_ptr d; + + Q_PRIVATE_SLOT(d, void executionFinished()) + Q_PRIVATE_SLOT(d, void syncWidth()) + Q_PRIVATE_SLOT(d, void syncHeight()) +}; + +} + +#endif // QuickViewSharedEngine_H diff --git a/src/plasmaquick/sharedqmlengine.cpp b/src/plasmaquick/sharedqmlengine.cpp new file mode 100644 index 0000000..ef2f889 --- /dev/null +++ b/src/plasmaquick/sharedqmlengine.cpp @@ -0,0 +1,312 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + SPDX-FileCopyrightText: 2023 Alexander Lohnau + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "sharedqmlengine.h" +#include "appletcontext_p.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "debug_p.h" + +namespace PlasmaQuick +{ + +class SharedQmlEnginePrivate +{ +public: + SharedQmlEnginePrivate(SharedQmlEngine *parent) + : q(parent) + , component(nullptr) + , delay(false) + , m_engine(engine()) + { + executionEndTimer = new QTimer(q); + executionEndTimer->setInterval(0); + executionEndTimer->setSingleShot(true); + QObject::connect(executionEndTimer, &QTimer::timeout, q, [this]() { + scheduleExecutionEnd(); + }); + } + + ~SharedQmlEnginePrivate() = default; + + void errorPrint(QQmlComponent *component); + void beginExecute(const QUrl &source); + void beginExecute(QAnyStringView module, QAnyStringView type); + void endExecute(); + void scheduleExecutionEnd(); + void minimumWidthChanged(); + void minimumHeightChanged(); + void maximumWidthChanged(); + void maximumHeightChanged(); + void preferredWidthChanged(); + void preferredHeightChanged(); + + SharedQmlEngine *q; + + QPointer rootObject; + std::unique_ptr component; + QTimer *executionEndTimer; + KLocalizedContext *context{nullptr}; + QQmlContext *rootContext; + bool delay; + std::shared_ptr m_engine; + +private: + static std::shared_ptr engine() + { + if (auto locked = s_engine.lock()) { + return locked; + } + auto createdEngine = std::make_shared(); + s_engine = createdEngine; + return createdEngine; + } + + static std::weak_ptr s_engine; +}; + +std::weak_ptr SharedQmlEnginePrivate::s_engine = {}; + +void SharedQmlEnginePrivate::errorPrint(QQmlComponent *component) +{ + QString errorStr = QStringLiteral("Error loading QML file.\n"); + if (component->isError()) { + const QList errors = component->errors(); + for (const QQmlError &error : errors) { + errorStr += + (error.line() > 0 ? QString(QString::number(error.line()) + QLatin1String(": ")) : QLatin1String("")) + error.description() + QLatin1Char('\n'); + } + } + qWarning(LOG_PLASMAQUICK) << component->url().toString() << '\n' << errorStr; +} + +void SharedQmlEnginePrivate::beginExecute(const QUrl &source) +{ + if (source.isEmpty()) { + qWarning(LOG_PLASMAQUICK) << "File name empty!"; + return; + } + + component = std::make_unique(m_engine.get()); + // Important! Some parts of Plasma are extremely sensitive to status changed + // signal being emit in exactly the same way QQmlComponent does it. So this + // connection needs to happen before any loading of the component happens. + QObject::connect(component.get(), &QQmlComponent::statusChanged, q, &SharedQmlEngine::statusChanged, Qt::QueuedConnection); + component->loadUrl(source); + + endExecute(); +} + +void SharedQmlEnginePrivate::beginExecute(QAnyStringView module, QAnyStringView type) +{ + if (module.isEmpty() || type.isEmpty()) { + qWarning(LOG_PLASMAQUICK) << "No module or type specified"; + return; + } + + component = std::make_unique(m_engine.get()); + // Important! Some parts of Plasma are extremely sensitive to status changed + // signal being emit in exactly the same way QQmlComponent does it. So this + // connection needs to happen before any loading of the component happens. + QObject::connect(component.get(), &QQmlComponent::statusChanged, q, &SharedQmlEngine::statusChanged, Qt::QueuedConnection); + component->loadFromModule(module, type); + + endExecute(); +} + +void SharedQmlEnginePrivate::endExecute() +{ + rootObject = component->beginCreate(rootContext); + + if (delay) { + executionEndTimer->start(0); + } else { + scheduleExecutionEnd(); + } +} + +void SharedQmlEnginePrivate::scheduleExecutionEnd() +{ + if (component->isReady() || component->isError()) { + q->completeInitialization(); + } else { + QObject::connect(component.get(), &QQmlComponent::statusChanged, q, [this]() { + q->completeInitialization(); + }); + } +} + +SharedQmlEngine::SharedQmlEngine(QObject *parent) + : QObject(parent) + , d(new SharedQmlEnginePrivate(this)) +{ + d->rootContext = new QQmlContext(engine().get()); + d->rootContext->setParent(this); // Delete the context when deleting the shared engine + + d->context = new KLocalizedContext(d->rootContext); + d->rootContext->setContextObject(d->context); +} + +SharedQmlEngine::SharedQmlEngine(Plasma::Applet *applet, QObject *parent) + : QObject(parent) + , d(new SharedQmlEnginePrivate(this)) +{ + d->rootContext = new AppletContext(engine().get(), applet, this); + + d->context = new KLocalizedContext(d->rootContext); + d->rootContext->setContextObject(d->context); +} + +SharedQmlEngine::~SharedQmlEngine() +{ + if (QJSEngine::objectOwnership(d->rootObject) == QJSEngine::CppOwnership) { + delete d->rootObject; + } +} + +void SharedQmlEngine::setTranslationDomain(const QString &translationDomain) +{ + d->context->setTranslationDomain(translationDomain); +} + +QString SharedQmlEngine::translationDomain() const +{ + return d->context->translationDomain(); +} + +void SharedQmlEngine::setSource(const QUrl &source) +{ + d->beginExecute(source); +} + +void SharedQmlEngine::setSourceFromModule(QAnyStringView module, QAnyStringView type) +{ + d->beginExecute(module, type); +} + +QUrl SharedQmlEngine::source() const +{ + if (d->component) { + return d->component->url(); + } + return QUrl{}; +} + +void SharedQmlEngine::setInitializationDelayed(const bool delay) +{ + d->delay = delay; +} + +bool SharedQmlEngine::isInitializationDelayed() const +{ + return d->delay; +} + +std::shared_ptr SharedQmlEngine::engine() +{ + return d->m_engine; +} + +QObject *SharedQmlEngine::rootObject() const +{ + return d->rootObject; +} + +QQmlComponent *SharedQmlEngine::mainComponent() const +{ + return d->component.get(); +} + +QQmlContext *SharedQmlEngine::rootContext() const +{ + return d->rootContext; +} + +QQmlComponent::Status SharedQmlEngine::status() const +{ + if (!d->m_engine) { + return QQmlComponent::Error; + } + + if (!d->component) { + return QQmlComponent::Null; + } + + return QQmlComponent::Status(d->component->status()); +} + +void SharedQmlEngine::completeInitialization(const QVariantHash &initialProperties) +{ + d->executionEndTimer->stop(); + + if (!d->component) { + qWarning(LOG_PLASMAQUICK) << "No component for" << source(); + return; + } + + if (d->component->status() != QQmlComponent::Ready || d->component->isError()) { + d->errorPrint(d->component.get()); + return; + } + + for (auto it = initialProperties.constBegin(); it != initialProperties.constEnd(); ++it) { + d->rootObject->setProperty(it.key().toUtf8().data(), it.value()); + } + + d->component->completeCreate(); + Q_EMIT finished(); +} + +QObject *SharedQmlEngine::createObjectFromSource(const QUrl &source, QQmlContext *context, const QVariantHash &initialProperties) +{ + QQmlComponent *component = new QQmlComponent(d->m_engine.get(), this); + component->loadUrl(source); + + return createObjectFromComponent(component, context, initialProperties); +} + +QObject *SharedQmlEngine::createObjectFromComponent(QQmlComponent *component, QQmlContext *context, const QVariantHash &initialProperties) +{ + QObject *object = component->beginCreate(context ? context : d->rootContext); + + for (auto it = initialProperties.constBegin(); it != initialProperties.constEnd(); ++it) { + object->setProperty(it.key().toUtf8().data(), it.value()); + } + component->completeCreate(); + + if (!component->isError() && object) { + // memory management + component->setParent(object); + // reparent to root object if wasn't specified otherwise by initialProperties + if (!initialProperties.contains(QLatin1String("parent"))) { + if (qobject_cast(rootObject())) { + object->setProperty("parent", QVariant::fromValue(rootObject())); + } else { + object->setParent(rootObject()); + } + } + + return object; + + } else { + d->errorPrint(component); + delete object; + return nullptr; + } +} +} + +#include "moc_sharedqmlengine.cpp" diff --git a/src/plasmaquick/sharedqmlengine.h b/src/plasmaquick/sharedqmlengine.h new file mode 100644 index 0000000..4885d04 --- /dev/null +++ b/src/plasmaquick/sharedqmlengine.h @@ -0,0 +1,201 @@ +/* + SPDX-FileCopyrightText: 2013 Marco Martin + SPDX-FileCopyrightText: + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef PLASMA_SHAREDQMLENGINE_H +#define PLASMA_SHAREDQMLENGINE_H + +#include + +#include +#include +#include + +#include + +class QQmlComponent; +class QQmlEngine; +class KLocalizedContext; + +namespace Plasma +{ +class Applet; +} + +namespace PlasmaQuick +{ +class SharedQmlEnginePrivate; + +/** + * @short An object that instantiates an entire QML context, with its own declarative engine + * + * PlasmaQuick::SharedQmlEngine provides a class to conveniently use QML based + * declarative user interfaces. + * A SharedQmlEngine corresponds to one QML file (which can include others). + * It will a shared QQmlEngine with a single root object, described in the QML file. + * + * @since 6.0 + */ +class PLASMAQUICK_EXPORT SharedQmlEngine : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QUrl source READ source WRITE setSource) + Q_PROPERTY(QString translationDomain READ translationDomain WRITE setTranslationDomain) + Q_PROPERTY(bool initializationDelayed READ isInitializationDelayed WRITE setInitializationDelayed) + Q_PROPERTY(QObject *rootObject READ rootObject) + Q_PROPERTY(QQmlComponent::Status status READ status NOTIFY statusChanged) + +public: + /** + * Construct a new PlasmaQuick::SharedQmlEngine + * + * @param parent The QObject parent for this object. + */ + explicit SharedQmlEngine(QObject *parent = nullptr); + explicit SharedQmlEngine(Plasma::Applet *applet, QObject *parent = nullptr); + + ~SharedQmlEngine() override; + + /** + * Call this method before calling setupBindings to install a translation domain for all + * i18n global functions. If a translation domain is set all i18n calls delegate to the + * matching i18nd calls with the provided translation domain. + * + * The translationDomain affects all i18n calls including those from imports. Because of + * that modules intended to be used as imports should prefer the i18nd variants and set + * the translation domain explicitly in each call. + * + * This method is only required if your declarative usage is inside a library. If it's + * in an application there is no need to set the translation domain as the application's + * domain can be used. + * + * @param translationDomain The translation domain to be used for i18n calls. + */ + void setTranslationDomain(const QString &translationDomain); + + /** + * @return the translation domain for the i18n calls done in this QML engine + */ + QString translationDomain() const; + + /** + * Sets the path of the QML file to parse and execute + * + * @param path the absolute path of a QML file + */ + void setSource(const QUrl &source); + + /** + * Sets the QML source to execute from a type in a module. + * + * @param module The module to load the type from. + * @param type The type to load from the module. + */ + void setSourceFromModule(QAnyStringView module, QAnyStringView type); + + /** + * @return the absolute path of the current QML file + */ + QUrl source() const; + + /** + * Sets whether the execution of the QML file has to be delayed later in the event loop. It has to be called before setQmlPath(). + * In this case it will be possible to assign new objects in the main engine context + * before the main component gets initialized. + * In that case it will be possible to access it immediately from the QML code. + * The initialization will either be completed automatically asynchronously + * or explicitly by calling completeInitialization() + * + * @param delay if true the initialization of the QML file will be delayed + * at the end of the event loop + */ + void setInitializationDelayed(const bool delay); + + /** + * @return true if the initialization of the QML file will be delayed + * at the end of the event loop + */ + bool isInitializationDelayed() const; + + /** + * @return the declarative engine that runs the qml file assigned to this widget. + */ + std::shared_ptr engine(); + + /** + * @return the root object of the declarative object tree + */ + QObject *rootObject() const; + + /** + * @return the main QQmlComponent of the engine + */ + QQmlComponent *mainComponent() const; + + /** + * The components's creation context. + */ + QQmlContext *rootContext() const; + + /** + * The component's current status. + */ + QQmlComponent::Status status() const; + + /** + * Creates and returns an object based on the provided url to a Qml file + * with the same QQmlEngine and the same root context as the main object, + * that will be the parent of the newly created object + * @param source url where the QML file is located + * @param context The QQmlContext in which we will create the object, + * if 0 it will use the engine's root context + * @param initialProperties optional properties that will be set on + * the object when created (and before Component.onCompleted + * gets emitted + */ + QObject *createObjectFromSource(const QUrl &source, QQmlContext *context = nullptr, const QVariantHash &initialProperties = QVariantHash()); + + /** + * Creates and returns an object based on the provided QQmlComponent + * with the same QQmlEngine and the same root context as the admin object, + * that will be the parent of the newly created object + * @param component the component we want to instantiate + * @param context The QQmlContext in which we will create the object, + * if 0 it will use the engine's root context + * @param initialProperties optional properties that will be set on + * the object when created (and before Component.onCompleted + * gets emitted + */ + QObject *createObjectFromComponent(QQmlComponent *component, QQmlContext *context = nullptr, const QVariantHash &initialProperties = QVariantHash()); + +public Q_SLOTS: + /** + * Finishes the process of initialization. + * If isInitializationDelayed() is false, calling this will have no effect. + * @param initialProperties optional properties that will be set on + * the object when created (and before Component.onCompleted + * gets emitted + */ + void completeInitialization(const QVariantHash &initialProperties = QVariantHash()); + +Q_SIGNALS: + /** + * Emitted when the parsing and execution of the QML file is terminated + */ + void finished(); + + void statusChanged(QQmlComponent::Status); + +private: + const std::unique_ptr d; + + Q_PRIVATE_SLOT(d, void scheduleExecutionEnd()) +}; + +} + +#endif // multiple inclusion guard diff --git a/src/plasmaquick/transientplacementhint.cpp b/src/plasmaquick/transientplacementhint.cpp new file mode 100644 index 0000000..b480edf --- /dev/null +++ b/src/plasmaquick/transientplacementhint.cpp @@ -0,0 +1,285 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "transientplacementhint_p.h" +#include + +#include +#include +#include +#include + +// This class is proposed for Qt6.something, but it's not there yet. +// keep as an implementation detail, and then drop eventually (famous last words) + +class TransientPlacementHintPrivate : public QSharedData +{ +public: + QRect parentAnchorRect; + bool constrainByAnchorWindow; + Qt::Edges parentAnchor = Qt::BottomEdge | Qt::RightEdge; + Qt::Edges popupAnchor = Qt::TopEdge | Qt::LeftEdge; + Qt::Orientations slideConstraintAdjustments = Qt::Horizontal | Qt::Vertical; + Qt::Orientations flipConstraintAdjustments; + int margin = 0; +}; +/*! + * Constructs a new QTransientPlacementHint + */ +TransientPlacementHint::TransientPlacementHint() + : d(new TransientPlacementHintPrivate) +{ +} + +TransientPlacementHint::~TransientPlacementHint() +{ +} + +TransientPlacementHint::TransientPlacementHint(const TransientPlacementHint &other) +{ + d = other.d; +} +TransientPlacementHint &TransientPlacementHint::operator=(const TransientPlacementHint &other) +{ + d = other.d; + return *this; +} + +bool TransientPlacementHint::isValid() const +{ + return d->parentAnchorRect.isValid(); +} + +void TransientPlacementHint::setParentAnchorArea(const QRect &parentAnchorRect) +{ + d->parentAnchorRect = parentAnchorRect; +} + +QRect TransientPlacementHint::parentAnchorArea() const +{ + return d->parentAnchorRect; +} + +void TransientPlacementHint::setParentAnchor(Qt::Edges parentAnchor) +{ + d->parentAnchor = parentAnchor; +} + +Qt::Edges TransientPlacementHint::parentAnchor() const +{ + return d->parentAnchor; +} + +void TransientPlacementHint::setPopupAnchor(Qt::Edges popupAnchor) +{ + d->popupAnchor = popupAnchor; +} + +Qt::Edges TransientPlacementHint::popupAnchor() const +{ + return d->popupAnchor; +} + +void TransientPlacementHint::setConstrainByAnchorWindow(bool constrainByAnchorWindow) +{ + d->constrainByAnchorWindow = constrainByAnchorWindow; +} + +bool TransientPlacementHint::constrainByAnchorWindow() const +{ + return d->constrainByAnchorWindow; +} + +void TransientPlacementHint::setSlideConstraintAdjustments(Qt::Orientations slideConstraintAdjustments) +{ + d->slideConstraintAdjustments = slideConstraintAdjustments; +} + +Qt::Orientations TransientPlacementHint::slideConstraintAdjustments() const +{ + return d->slideConstraintAdjustments; +} + +void TransientPlacementHint::setFlipConstraintAdjustments(Qt::Orientations flipConstraintAdjustments) +{ + d->flipConstraintAdjustments = flipConstraintAdjustments; +} + +Qt::Orientations TransientPlacementHint::flipConstraintAdjustments() const +{ + return d->flipConstraintAdjustments; +} + +int TransientPlacementHint::margin() const +{ + return d->margin; +} + +void TransientPlacementHint::setMargin(int margin) +{ + d->margin = margin; +} + +static QPoint popupPosition(const QRect &anchorRect, const Qt::Edges parentAnchor, const Qt::Edges popupAnchor, const QSize &popupSize) +{ + QPoint anchorPoint; + switch (parentAnchor & (Qt::LeftEdge | Qt::RightEdge)) { + case Qt::LeftEdge: + anchorPoint.setX(anchorRect.x()); + break; + case Qt::RightEdge: + anchorPoint.setX(anchorRect.x() + anchorRect.width()); + break; + default: + anchorPoint.setX(qRound(anchorRect.x() + anchorRect.width() / 2.0)); + } + switch (parentAnchor & (Qt::TopEdge | Qt::BottomEdge)) { + case Qt::TopEdge: + anchorPoint.setY(anchorRect.y()); + break; + case Qt::BottomEdge: + anchorPoint.setY(anchorRect.y() + anchorRect.height()); + break; + default: + anchorPoint.setY(qRound(anchorRect.y() + anchorRect.height() / 2.0)); + } + // calculate where the top left point of the popup will end up with the applied popup anchor + QPoint popupPosAdjust; + switch (popupAnchor & (Qt::LeftEdge | Qt::RightEdge)) { + case Qt::LeftEdge: + popupPosAdjust.setX(0); + break; + case Qt::RightEdge: + popupPosAdjust.setX(-popupSize.width()); + break; + default: + popupPosAdjust.setX(qRound(-popupSize.width() / 2.0)); + } + switch (popupAnchor & (Qt::TopEdge | Qt::BottomEdge)) { + case Qt::TopEdge: + popupPosAdjust.setY(0); + break; + case Qt::BottomEdge: + popupPosAdjust.setY(-popupSize.height()); + break; + default: + popupPosAdjust.setY(qRound(-popupSize.height() / 2.0)); + } + return anchorPoint + popupPosAdjust; +} + +QRect TransientPlacementHelper::popupRect(QWindow *w, const TransientPlacementHint &placement) +{ + // We are not checking the placement being valid, as visual parents with size 0 is an + // allowed thing, also, every PlasmoidItem will initially be 0x0 when created + QScreen *screen = nullptr; + QRect globalParentAnchorRect = placement.parentAnchorArea(); + if (w->transientParent()) { + globalParentAnchorRect = globalParentAnchorRect.translated(w->transientParent()->position()); + screen = w->transientParent()->screen(); + } + + const QMargins margin(placement.margin(), placement.margin(), placement.margin(), placement.margin()); + QSize paddedWindowSize = w->size().grownBy(margin); + QRect popupRect = QRect(popupPosition(globalParentAnchorRect, placement.parentAnchor(), placement.popupAnchor(), paddedWindowSize), paddedWindowSize); + + if (!screen) + screen = qApp->screenAt(globalParentAnchorRect.center()); + if (!screen) + screen = qApp->primaryScreen(); + + QRect screenArea = screen->geometry(); + + if (placement.constrainByAnchorWindow()) { + QRect parentRect = w->transientParent()->geometry(); + if ((placement.parentAnchor() == Qt::TopEdge || placement.parentAnchor() == Qt::BottomEdge) && popupRect.width() <= parentRect.width()) { + screenArea.setRight(parentRect.right()); + screenArea.setLeft(parentRect.left()); + } else if (popupRect.height() <= parentRect.height()) { + screenArea.setTop(parentRect.top()); + screenArea.setBottom(parentRect.bottom()); + } + } + + QVariant restrictedPopupGeometry = w->property("restrictedPopupGeometry"); + if (restrictedPopupGeometry.canConvert()) { + screenArea = restrictedPopupGeometry.toRect(); + } + + auto inScreenArea = [screenArea](const QRect &target, Qt::Edges edges = Qt::LeftEdge | Qt::RightEdge | Qt::TopEdge | Qt::BottomEdge) -> bool { + if (edges & Qt::LeftEdge && target.left() < screenArea.left()) { + return false; + } + if (edges & Qt::TopEdge && target.top() < screenArea.top()) { + return false; + } + if (edges & Qt::RightEdge && target.right() > screenArea.right()) { + return false; + } + if (edges & Qt::BottomEdge && target.bottom() > screenArea.bottom()) { + return false; + } + return true; + }; + + // if that fits, we don't need to do anything + if (inScreenArea(popupRect)) { + return popupRect.marginsRemoved(margin); + } + // Otherwise, + if (placement.flipConstraintAdjustments() & Qt::Horizontal) { + if (!inScreenArea(popupRect, Qt::LeftEdge | Qt::RightEdge)) { + // flip both edges (if either bit is set, XOR both) + auto flippedParentAnchor = placement.parentAnchor(); + if (flippedParentAnchor & (Qt::LeftEdge | Qt::RightEdge)) { + flippedParentAnchor ^= (Qt::LeftEdge | Qt::RightEdge); + } + auto flippedPopupAnchor = placement.popupAnchor(); + if (flippedPopupAnchor & (Qt::LeftEdge | Qt::RightEdge)) { + flippedPopupAnchor ^= (Qt::LeftEdge | Qt::RightEdge); + } + QRect flippedPopupRect = QRect(popupPosition(globalParentAnchorRect, flippedParentAnchor, flippedPopupAnchor, w->size()), w->size()); + // if it still doesn't fit we should continue with the unflipped version + if (inScreenArea(flippedPopupRect, Qt::LeftEdge | Qt::RightEdge)) { + popupRect.moveLeft(flippedPopupRect.left()); + } + } + } + if (placement.slideConstraintAdjustments() & Qt::Horizontal) { + if (!inScreenArea(popupRect, Qt::LeftEdge)) { + popupRect.moveLeft(screenArea.left()); + } + if (!inScreenArea(popupRect, Qt::RightEdge)) { + popupRect.moveRight(screenArea.right()); + } + } + if (placement.flipConstraintAdjustments() & Qt::Vertical) { + if (!inScreenArea(popupRect, Qt::TopEdge | Qt::BottomEdge)) { + // flip both edges (if either bit is set, XOR both) + auto flippedParentAnchor = placement.parentAnchor(); + if (flippedParentAnchor & (Qt::TopEdge | Qt::BottomEdge)) { + flippedParentAnchor ^= (Qt::TopEdge | Qt::BottomEdge); + } + auto flippedPopupAnchor = placement.popupAnchor(); + if (flippedPopupAnchor & (Qt::TopEdge | Qt::BottomEdge)) { + flippedPopupAnchor ^= (Qt::TopEdge | Qt::BottomEdge); + } + QRect flippedPopupRect = QRect(popupPosition(globalParentAnchorRect, flippedParentAnchor, flippedPopupAnchor, w->size()), w->size()); + // if it still doesn't fit we should continue with the unflipped version + if (inScreenArea(flippedPopupRect, Qt::TopEdge | Qt::BottomEdge)) { + popupRect.moveTop(flippedPopupRect.top()); + } + } + } + if (placement.slideConstraintAdjustments() & Qt::Vertical) { + if (!inScreenArea(popupRect, Qt::TopEdge)) { + popupRect.moveTop(screenArea.top()); + } + if (!inScreenArea(popupRect, Qt::BottomEdge)) { + popupRect.moveBottom(screenArea.bottom()); + } + } + return popupRect.marginsRemoved(margin); +} diff --git a/src/plasmaquick/transientplacementhint_p.h b/src/plasmaquick/transientplacementhint_p.h new file mode 100644 index 0000000..6fd21dd --- /dev/null +++ b/src/plasmaquick/transientplacementhint_p.h @@ -0,0 +1,49 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + SPDX-FileCopyrightText: 2021 Vlad Zahorodnii + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#pragma once + +#include +#include +#include + +// This class is proposed for Qt6.something, but it's not there yet. +// keep as an implementation detail, and then drop eventually (famous last words) + +class TransientPlacementHintPrivate; +class QWindow; + +class TransientPlacementHint +{ +public: + TransientPlacementHint(); + ~TransientPlacementHint(); + TransientPlacementHint(const TransientPlacementHint &other); + TransientPlacementHint &operator=(const TransientPlacementHint &other); + bool isValid() const; + void setParentAnchorArea(const QRect &parentAnchorRect); + QRect parentAnchorArea() const; + void setParentAnchor(Qt::Edges parentAnchor); + Qt::Edges parentAnchor() const; + void setPopupAnchor(Qt::Edges popupAnchor); + Qt::Edges popupAnchor() const; + bool constrainByAnchorWindow() const; + void setConstrainByAnchorWindow(bool constrainByAnchorWindow); + Qt::Orientations slideConstraintAdjustments() const; + void setSlideConstraintAdjustments(Qt::Orientations slideConstraintAdjustments); + Qt::Orientations flipConstraintAdjustments() const; + void setFlipConstraintAdjustments(Qt::Orientations flipConstraintAdjustments); + int margin() const; + void setMargin(int margin); + +private: + QSharedDataPointer d; +}; + +namespace TransientPlacementHelper +{ +QRect popupRect(QWindow *window, const TransientPlacementHint &placement); +} diff --git a/src/plasmaquick/utils.cpp b/src/plasmaquick/utils.cpp new file mode 100644 index 0000000..92efaad --- /dev/null +++ b/src/plasmaquick/utils.cpp @@ -0,0 +1,21 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "utils.h" + +Qt::Edge PlasmaQuickPrivate::oppositeEdge(Qt::Edge edge) +{ + switch (edge) { + case Qt::TopEdge: + return Qt::BottomEdge; + case Qt::BottomEdge: + return Qt::TopEdge; + case Qt::LeftEdge: + return Qt::RightEdge; + case Qt::RightEdge: + return Qt::LeftEdge; + } + Q_UNREACHABLE(); +} diff --git a/src/plasmaquick/utils.h b/src/plasmaquick/utils.h new file mode 100644 index 0000000..5c57319 --- /dev/null +++ b/src/plasmaquick/utils.h @@ -0,0 +1,13 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#pragma once + +#include + +namespace PlasmaQuickPrivate +{ +Qt::Edge oppositeEdge(Qt::Edge edge); +} diff --git a/src/plasmaquick/windowresizehandler.cpp b/src/plasmaquick/windowresizehandler.cpp new file mode 100644 index 0000000..97eb296 --- /dev/null +++ b/src/plasmaquick/windowresizehandler.cpp @@ -0,0 +1,189 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + SPDX-FileCopyrightText: 2022 Luca Carlon + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "windowresizehandler.h" + +#include +#include +#include + +using namespace PlasmaQuick; + +class WindowResizeHandlerPrivate +{ +public: + QWindow *window; + QMargins margins; + Qt::Edges activeEdges; + + bool updateMouseCursor(const QPointF &globalMousePos); + void unsetMouseCursor(); + + Qt::Edges hitTest(const QPointF &pos); + +private: + bool overridingCursor = false; + bool hitTestLeft(const QPointF &pos); + bool hitTestRight(const QPointF &pos); + bool hitTestTop(const QPointF &pos); + bool hitTestBottom(const QPointF &pos); +}; + +PlasmaQuick::WindowResizeHandler::WindowResizeHandler(QWindow *parent) + : QObject(parent) + , d(new WindowResizeHandlerPrivate) +{ + d->window = parent; + d->window->installEventFilter(this); +} + +WindowResizeHandler::~WindowResizeHandler() +{ + d->window->removeEventFilter(this); +} + +void WindowResizeHandler::setMargins(const QMargins &margins) +{ + d->margins = margins; +} + +QMargins WindowResizeHandler::margins() const +{ + return d->margins; +} + +void WindowResizeHandler::setActiveEdges(Qt::Edges edges) +{ + d->activeEdges = edges; +} + +Qt::Edges WindowResizeHandler::activeEdges() const +{ + return d->activeEdges; +} + +bool WindowResizeHandler::eventFilter(QObject *watched, QEvent *event) +{ + Q_UNUSED(watched) + switch (event->type()) { + case QEvent::Enter: { + QEnterEvent *ee = static_cast(event); + d->updateMouseCursor(ee->globalPosition()); + return false; + } + case QEvent::Leave: + d->unsetMouseCursor(); + return false; + case QEvent::MouseMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: { + QMouseEvent *me = static_cast(event); + if (event->type() == QEvent::MouseMove && d->updateMouseCursor(me->globalPosition())) { + return false; + } + if (event->type() == QEvent::MouseButtonPress) { + const QPointF globalMousePos = me->globalPosition(); + const Qt::Edges sides = d->hitTest(globalMousePos) & d->activeEdges; + if (sides) { + d->window->startSystemResize(sides); + return true; + } + } + } break; + default: + break; + } + return false; +} + +bool WindowResizeHandlerPrivate::updateMouseCursor(const QPointF &globalMousePos) +{ + Qt::Edges sides = hitTest(globalMousePos) & activeEdges; + if (!sides) { + unsetMouseCursor(); + return false; + } + + if (sides == Qt::Edges(Qt::LeftEdge | Qt::TopEdge)) { + window->setCursor(Qt::SizeFDiagCursor); + } else if (sides == Qt::Edges(Qt::RightEdge | Qt::TopEdge)) { + window->setCursor(Qt::SizeBDiagCursor); + } else if (sides == Qt::Edges(Qt::LeftEdge | Qt::BottomEdge)) { + window->setCursor(Qt::SizeBDiagCursor); + } else if (sides == Qt::Edges(Qt::RightEdge | Qt::BottomEdge)) { + window->setCursor(Qt::SizeFDiagCursor); + } else if (sides.testFlag(Qt::TopEdge)) { + window->setCursor(Qt::SizeVerCursor); + } else if (sides.testFlag(Qt::LeftEdge)) { + window->setCursor(Qt::SizeHorCursor); + } else if (sides.testFlag(Qt::RightEdge)) { + window->setCursor(Qt::SizeHorCursor); + } else { + window->setCursor(Qt::SizeVerCursor); + } + + overridingCursor = true; + return true; +} + +void WindowResizeHandlerPrivate::unsetMouseCursor() +{ + if (overridingCursor) { + window->unsetCursor(); + overridingCursor = false; + } +} + +Qt::Edges WindowResizeHandlerPrivate::hitTest(const QPointF &pos) +{ + bool left = hitTestLeft(pos); + bool right = hitTestRight(pos); + bool top = hitTestTop(pos); + bool bottom = hitTestBottom(pos); + Qt::Edges edges; + if (left) { + edges.setFlag(Qt::LeftEdge); + } + if (right) { + edges.setFlag(Qt::RightEdge); + } + if (bottom) { + edges.setFlag(Qt::BottomEdge); + } + if (top) { + edges.setFlag(Qt::TopEdge); + } + + return edges; +} + +bool WindowResizeHandlerPrivate::hitTestLeft(const QPointF &pos) +{ + const QRect geometry = window->geometry(); + const QRectF rect(geometry.x(), geometry.y(), margins.left(), geometry.height()); + return rect.contains(pos); +} + +bool WindowResizeHandlerPrivate::hitTestRight(const QPointF &pos) +{ + const QRect geometry = window->geometry(); + const QRectF rect(geometry.x() + geometry.width() - margins.right(), geometry.y(), margins.right(), geometry.height()); + return rect.contains(pos); +} + +bool WindowResizeHandlerPrivate::hitTestTop(const QPointF &pos) +{ + const QRect geometry = window->geometry(); + const QRectF rect(geometry.x(), geometry.y(), geometry.width(), margins.top()); + return rect.contains(pos); +} + +bool WindowResizeHandlerPrivate::hitTestBottom(const QPointF &pos) +{ + const QRect geometry = window->geometry(); + const QRectF rect(geometry.x(), geometry.y() + geometry.height() - margins.bottom(), geometry.width(), margins.bottom()); + return rect.contains(pos); +} diff --git a/src/plasmaquick/windowresizehandler.h b/src/plasmaquick/windowresizehandler.h new file mode 100644 index 0000000..1a6c22a --- /dev/null +++ b/src/plasmaquick/windowresizehandler.h @@ -0,0 +1,46 @@ +/* + SPDX-FileCopyrightText: 2023 David Edmundson + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#pragma once + +#include +#include +#include + +#include + +class QWindow; + +class WindowResizeHandlerPrivate; + +/** + * @brief The EdgeEventForwarder class + * This class forwards edge events to be replayed within the given margin + * This is useful if children do not touch the edge of a window, but want to get input events + */ + +namespace PlasmaQuick +{ + +class PLASMAQUICK_EXPORT WindowResizeHandler : public QObject +{ + Q_OBJECT +public: + WindowResizeHandler(QWindow *parent); + ~WindowResizeHandler(); + + void setMargins(const QMargins &margins); + QMargins margins() const; + + void setActiveEdges(Qt::Edges edges); + Qt::Edges activeEdges() const; + + bool eventFilter(QObject *watched, QEvent *event) override; + +private: + std::unique_ptr d; +}; + +} diff --git a/src/tools/apply-stylesheet.sh b/src/tools/apply-stylesheet.sh new file mode 100755 index 0000000..516e5c6 --- /dev/null +++ b/src/tools/apply-stylesheet.sh @@ -0,0 +1,287 @@ +#!/bin/bash + +PARSED_OPTIONS=$(getopt -n "$0" -o hf: --long "file:,TextFrom:,TextTo:,BackgroundFrom:,BackgroundTo:,HighlightFrom:,HighlightTo:,ViewTextFrom:,ViewTextTo:,ViewBackgroundFrom:,ViewBackgroundTo:,ViewHoverFrom:,ViewHoverTo:,ViewFocusFrom:,ViewFocusTo:,ButtonTextFrom:,ButtonTextTo:,ButtonBackgroundFrom:,ButtonBackgroundTo:,ButtonHoverFrom:,ButtonHoverTo:,ButtonFocusFrom:,ButtonFocusTo:" -- "$@") + +if [ $? -ne 0 ]; +then + exit 1 +fi + +eval set -- "$PARSED_OPTIONS" + +textFrom=\#31363b +backgroundFrom=\#eff0f1 +highlightFrom=\#3daee9 +viewTextFrom=\#31363b +viewBackgroundFrom=\#fcfcfc +viewHoverFrom=\#93cee9 +viewFocusFrom=\#3daee9 +buttonTextFrom=\#31363b +buttonBackgroundFrom=\#eff0f1 +buttonHoverFrom=\#93cee9 +buttonFocusFrom=\#3daee9 + +textTo=\#31363b +backgroundTo=\#eff0f1 +highlightTo=\#3daee9 +viewTextTo=\#31363b +viewBackgroundTo=\#fcfcfc +viewHoverTo=\#93cee9 +viewFocusTo=\#3daee9 +buttonTextTo=\#31363b +buttonBackgroundTo=\#eff0f1 +buttonHoverTo=\#93cee9 +buttonFocusTo=\#3daee9 + +file='' + +while true; +do + case "$1" in + + -h|--help) + echo "usage $0 [-h|options] -f file.svgz" + echo "Where options can be:" + echo " --TextFrom=color html encoded color to replace with the ColorScheme-Text from the stylesheet" + echo " --TextTo=color html encoded that the ColorScheme-Text class will have" + echo + echo " --BackgroundFrom=color html encoded color to replace with the ColorScheme-Background from the stylesheet" + echo " --BackgroundTo=color html encoded that the ColorScheme-Background class will have" + echo + echo " --HighlightFrom=color html encoded color to replace with the ColorScheme-Highlight from the stylesheet" + echo " --HighlightTo=color html encoded that the ColorScheme-Highlight class will have" + echo + echo " --ViewTextFrom=color html encoded color to replace with the ColorScheme-ViewText from the stylesheet" + echo " --ViewTextTo=color html encoded that the ColorScheme-ViewText class will have" + echo + echo " --ViewBackgroundFrom=color html encoded color to replace with the ColorScheme-ViewBackground from the stylesheet" + echo " --ViewBackgroundTo=color html encoded that the ColorScheme-ViewBackground class will have" + echo + echo " --ViewHoverFrom=color html encoded color to replace with the ColorScheme-ViewHover from the stylesheet" + echo " --ViewHoverTo=color html encoded that the ColorScheme-ViewHover class will have" + echo + echo " --ViewFocusFrom=color html encoded color to replace with the ColorScheme-ViewFocus from the stylesheet" + echo " --ViewFocusTo=color html encoded that the ColorScheme-ViewFocus class will have" + echo + echo " --ButtonTextFrom=color html encoded color to replace with the ColorScheme-ButtonText from the stylesheet" + echo " --ButtonTextTo=color html encoded that the ColorScheme-ButtonText class will have" + echo + echo " --ButtonBackgroundFrom=color html encoded color to replace with the ColorScheme-ButtonBackground from the stylesheet" + echo " --ButtonBackgroundTo=color html encoded that the ColorScheme-ButtonBackground class will have" + echo + echo " --ButtonHoverFrom=color html encoded color to replace with the ColorScheme-ButtonHover from the stylesheet" + echo " --ButtonHoverTo=color html encoded that the ColorScheme-ButtonHover class will have" + echo + echo " --ButtonFocusFrom=color html encoded color to replace with the ColorScheme-ButtonFocus from the stylesheet" + echo " --ButtonFocusTo=color html encoded that the ColorScheme-ButtonFocus class will have" + echo + echo "All the colors have default values conformant to the Breeze color palette" + echo + exit + shift;; + + --TextFrom) + textFrom=$2 + shift 2;; + --TextTo) + textTo=$2 + shift 2;; + + --BackgroundFrom) + backgroundFrom=$2 + shift 2;; + --BackgroundTo) + backgroundTo=$2 + shift 2;; + + --HighlightFrom) + highlightFrom=$2 + shift 2;; + --HighlightTo) + highlightTo=$2 + shift 2;; + + --ViewTextFrom) + viewTextFrom=$2 + shift 2;; + --ViewTextTo) + viewTextTo=$2 + shift 2;; + + --ViewBackgroundFrom) + viewBackgroundFrom=$2 + shift 2;; + --ViewBackgroundTo) + viewBackgroundTo=$2 + shift 2;; + + --ViewHoverFrom) + viewHoverFrom=$2 + shift 2;; + --ViewHoverTo) + viewHoverTo=$2 + shift 2;; + + --ViewFocusFrom) + viewFocusFrom=$2 + shift 2;; + --ViewFocusTo) + viewFocusTo=$2 + shift 2;; + + --ButtonTextFrom) + buttonTextFrom=$2 + shift 2;; + --ButtonTextTo) + buttonTextTo=$2 + shift 2;; + + --ButtonBackgroundFrom) + buttonBackgroundFrom=$2 + shift 2;; + --ButtonBackgroundTo) + buttonBackgroundTo=$2 + shift 2;; + + --ButtonHoverFrom) + buttonHoverFrom=$2 + shift 2;; + --ButtonHoverTo) + buttonHoverTo=$2 + shift 2;; + + --ButtonFocusFrom) + buttonFocusFrom=$2 + shift 2;; + --ButtonFocusTo) + buttonFocusTo=$2 + shift 2;; + + -f|--file) + file=`echo $2 | cut -d'.' --complement -f2-` + shift 2;; + + --) + shift + break;; + esac +done + + +if [ -z "$file" ]; + then echo missing svg file + exit 1 +fi + +isSvgz=0 + +if [ ! -f $file.svgz ] && [ ! -f $file.svg ]; then + echo "you must specify a valid svg" + exit 1 +fi + +if [ -f $file.svgz ]; then + isSvgz=1 +fi + + +if [ $isSvgz = 1 ]; then + mv $file.svgz $file.svg.gz + gunzip $file.svg.gz +fi + +echo Processing $file + +stylesheet=" + .ColorScheme-Text { + color:$textTo; + } + .ColorScheme-Background { + color:$backgroundTo; + } + .ColorScheme-Highlight { + color:$highlightTo; + } + .ColorScheme-ViewText { + color:$viewTextTo; + } + .ColorScheme-ViewBackground { + color:$viewBackgroundTo; + } + .ColorScheme-ViewHover { + color:$viewHoverTo; + } + .ColorScheme-ViewFocus{ + color:$viewFocusTo; + } + .ColorScheme-ButtonText { + color:$buttonTextTo; + } + .ColorScheme-ButtonBackground { + color:$buttonBackgroundTo; + } + .ColorScheme-ButtonHover { + color:$buttonHoverTo; + } + .ColorScheme-ButtonFocus{ + color:$buttonFocusTo; + } + " +colors=($textFrom $backgroundFrom $highlightFrom $viewTextFrom $viewBackgroundFrom $viewHoverFrom $viewFocusFrom $buttonTextFrom $buttonBackgroundFrom $buttonHoverFrom $buttonFocusFrom) +colorNames=(ColorScheme-Text ColorScheme-Background ColorScheme-Highlight ColorScheme-ViewText ColorScheme-ViewBackground ColorScheme-ViewHover ColorScheme-ViewFocus ColorScheme-ButtonText ColorScheme-ButtonBackground ColorScheme-ButtonHover ColorScheme-ButtonFocus) + +reorderXslt=' + + + + + + + + + + + + + + + + + + + + +' +echo $reorderXslt > transform.xsl + +if grep -q '"current-color-scheme"' $file.svg; then + echo replacing the stylesheet + xmlstarlet ed --update "/svg:svg/svg:defs/_:style" -v "$stylesheet" $file.svg > temp.svg +else + echo adding the stylesheet +xmlstarlet ed --subnode "/svg:svg/svg:defs" -t elem -n "style" -v "$stylesheet"\ + --subnode "/svg:svg/svg:defs/style" -t attr -n "type" -v "text/css"\ + --subnode "/svg:svg/svg:defs/style" -t attr -n "id" -v "current-color-scheme" $file.svg > temp.svg +fi + +xmlstarlet tr transform.xsl temp.svg > temp2.svg +mv temp2.svg temp.svg + +for i in ${!colors[@]} +do + xmlstarlet ed --subnode "//*/*[contains(@style, '${colors[i]}') and not (@class)]" -t attr -n "class" -v "${colorNames[i]}" temp.svg > temp2.svg + + mv temp2.svg temp.svg + + sed -i 's/\(style=".*\)fill:'${colors[i]}'/\1fill:currentColor/g' temp.svg + sed -i 's/\(style=".*\)stop-color:'${colors[i]}'/\1stop-color:currentColor/g' temp.svg +done + +rm transform.xsl + +mv temp.svg $file.svg +if [ $isSvgz = 1 ]; then + gzip -n $file.svg + mv $file.svg.gz $file.svgz +fi diff --git a/src/tools/currentColorFillFix.sh b/src/tools/currentColorFillFix.sh new file mode 100755 index 0000000..80fa240 --- /dev/null +++ b/src/tools/currentColorFillFix.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +if [ $# -ne 1 ]; + then echo Usage: $0 file.svgz + exit 1 +fi + +if [ ! -f $1 ]; then + echo "you must specify a valid svg" + exit 1 +fi + + +file=`echo $1 | cut -d'.' --complement -f2-` +mv $1 $file.svg.gz +gunzip $file.svg.gz + +echo Processing $file + +/usr/bin/perl -p -i -e "s/color:#[^;]*;(.*)fill:currentColor/\1fill:currentColor/g" $file.svg + +gzip -n $file.svg +mv $file.svg.gz $file.svgz \ No newline at end of file diff --git a/src/tools/inkscape extensions/plasmarename.inx b/src/tools/inkscape extensions/plasmarename.inx new file mode 100644 index 0000000..fca784b --- /dev/null +++ b/src/tools/inkscape extensions/plasmarename.inx @@ -0,0 +1,16 @@ + +> + <_name>PlasmaRename + notmart.filter.plasmarename + plasmarename.py + + + all + + + + + + diff --git a/src/tools/inkscape extensions/plasmarename.py b/src/tools/inkscape extensions/plasmarename.py new file mode 100644 index 0000000..2a6be3d --- /dev/null +++ b/src/tools/inkscape extensions/plasmarename.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +''' +SPDX-FileCopyrightText: 2009 Marco Martin + +SPDX-License-Identifier: GPL-2.0-or-later +''' + + +import sys +sys.path.append('/usr/share/inkscape/extensions') + +import inkex + +from simplestyle import * +from simpletransform import * +import pathmodifier + +class PlasmaNamesEffect(pathmodifier.PathModifier): + """ + Renames 9 selected elements as a plasma theme frame + """ + def __init__(self): + pathmodifier.PathModifier.__init__(self) + + # Define string option "--prefix" with "-p" shortcut and default value "World". + self.OptionParser.add_option('-p', '--prefix', action = 'store', + type = 'string', dest = 'prefix', default = '', + help = 'Prefix of the svg elements') + + def nodeBBox(self, node): + path = node + return computeBBox([path]) + + + def effect(self): + # Get script's "--prefix" option value. + prefix = self.options.prefix + + #9 elements: is a frame. 4 elements: is a border hint + positions = [] + if len(self.selected) == 9: + positions = ['topleft', 'left', 'bottomleft', 'top', 'center', 'bottom', 'topright', 'right', 'bottomright'] + elif len(self.selected) == 4: + positions = ['hint-left-margin', 'hint-top-margin', 'hint-bottom-margin', 'hint-right-margin'] + else: + return + + #some heuristics to normalize the values, find the least coords and size + minX = 9999 + minY = 9999 + minWidth = 9999 + minHeight = 9999 + for id, node in self.selected.iteritems(): + nodeBox = self.nodeBBox(node) + minX = min(minX, int(nodeBox[0])) + minY = min(minY, int(nodeBox[2])) + minWidth = min(minWidth, int(nodeBox[1] - nodeBox[0])) + minHeight = min(minHeight, int(nodeBox[3] - nodeBox[2])) + + + nodedictionary = {} + for id, node in self.selected.iteritems(): + nodeBox = self.nodeBBox(node) + x = int(nodeBox[0])/minWidth - minX + y = int(nodeBox[2])/minHeight - minY + nodedictionary[x*1000 + y] = node + + keys = nodedictionary.keys(); + keys.sort(); + i = 0 + + for (k) in keys: + name = '' + if prefix: + name = '%s-%s' % (prefix, positions[i]) + else: + name = '%s' % (positions[i]) + nodedictionary[k].set('id', name) + i = i+1 + +# Create effect instance and apply it. +effect = PlasmaNamesEffect() +effect.affect() diff --git a/templates/.clang-format b/templates/.clang-format new file mode 100644 index 0000000..9d15924 --- /dev/null +++ b/templates/.clang-format @@ -0,0 +1,2 @@ +DisableFormat: true +SortIncludes: false diff --git a/templates/CMakeLists.txt b/templates/CMakeLists.txt new file mode 100644 index 0000000..9463f18 --- /dev/null +++ b/templates/CMakeLists.txt @@ -0,0 +1,9 @@ +kde_package_app_templates( + TEMPLATES + qml-plasmoid6 + qml-plasmoid6-with-qml-extension + cpp-plasmoid6 + plasma6-wallpaper + plasma6-wallpaper-with-qml-extension + INSTALL_DIR ${KDE_INSTALL_KAPPTEMPLATESDIR} +) diff --git a/templates/cpp-plasmoid6/CMakeLists.txt b/templates/cpp-plasmoid6/CMakeLists.txt new file mode 100644 index 0000000..3d06ad1 --- /dev/null +++ b/templates/cpp-plasmoid6/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.16) + +project(plasma-%{APPNAMELC}) + +set(QT_MIN_VERSION "6.4.0") +set(KF6_MIN_VERSION "5.93.0") + +find_package(ECM ${KF6_MIN_VERSION} REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) + +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDECompilerSettings NO_POLICY_SCOPE) +include(FeatureSummary) + +find_package(KF6 ${KF6_MIN_VERSION} REQUIRED COMPONENTS + Plasma + I18n +) + +find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS + Quick + Core +) + +add_subdirectory(src) + +feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/templates/cpp-plasmoid6/LICENSES/LGPL-2.1-or-later.txt b/templates/cpp-plasmoid6/LICENSES/LGPL-2.1-or-later.txt new file mode 100644 index 0000000..04bb156 --- /dev/null +++ b/templates/cpp-plasmoid6/LICENSES/LGPL-2.1-or-later.txt @@ -0,0 +1,468 @@ +GNU LESSER GENERAL PUBLIC LICENSE + +Version 2.1, February 1999 + +Copyright (C) 1991, 1999 Free Software Foundation, Inc. + +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts as the +successor of the GNU Library Public License, version 2, hence the version +number 2.1.] + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public Licenses are intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. + +This license, the Lesser General Public License, applies to some specially +designated software packages--typically libraries--of the Free Software Foundation +and other authors who decide to use it. You can use it too, but we suggest +you first think carefully about whether this license or the ordinary General +Public License is the better strategy to use in any particular case, based +on the explanations below. + +When we speak of free software, we are referring to freedom of use, not price. +Our General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you +wish); that you receive source code or can get it if you want it; that you +can change the software and use pieces of it in new free programs; and that +you are informed that you can do these things. + +To protect your rights, we need to make restrictions that forbid distributors +to deny you these rights or to ask you to surrender these rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the library or if you modify it. + +For example, if you distribute copies of the library, whether gratis or for +a fee, you must give the recipients all the rights that we gave you. You must +make sure that they, too, receive or can get the source code. If you link +other code with the library, you must provide complete object files to the +recipients, so that they can relink them with the library after making changes +to the library and recompiling it. And you must show them these terms so they +know their rights. + +We protect your rights with a two-step method: (1) we copyright the library, +and (2) we offer you this license, which gives you legal permission to copy, +distribute and/or modify the library. + +To protect each distributor, we want to make it very clear that there is no +warranty for the free library. Also, if the library is modified by someone +else and passed on, the recipients should know that what they have is not +the original version, so that the original author's reputation will not be +affected by problems that might be introduced by others. + +Finally, software patents pose a constant threat to the existence of any free +program. We wish to make sure that a company cannot effectively restrict the +users of a free program by obtaining a restrictive license from a patent holder. +Therefore, we insist that any patent license obtained for a version of the +library must be consistent with the full freedom of use specified in this +license. + +Most GNU software, including some libraries, is covered by the ordinary GNU +General Public License. This license, the GNU Lesser General Public License, +applies to certain designated libraries, and is quite different from the ordinary +General Public License. We use this license for certain libraries in order +to permit linking those libraries into non-free programs. + +When a program is linked with a library, whether statically or using a shared +library, the combination of the two is legally speaking a combined work, a +derivative of the original library. The ordinary General Public License therefore +permits such linking only if the entire combination fits its criteria of freedom. +The Lesser General Public License permits more lax criteria for linking other +code with the library. + +We call this license the "Lesser" General Public License because it does Less +to protect the user's freedom than the ordinary General Public License. It +also provides other free software developers Less of an advantage over competing +non-free programs. These disadvantages are the reason we use the ordinary +General Public License for many libraries. However, the Lesser license provides +advantages in certain special circumstances. + +For example, on rare occasions, there may be a special need to encourage the +widest possible use of a certain library, so that it becomes a de-facto standard. +To achieve this, non-free programs must be allowed to use the library. A more +frequent case is that a free library does the same job as widely used non-free +libraries. In this case, there is little to gain by limiting the free library +to free software only, so we use the Lesser General Public License. + +In other cases, permission to use a particular library in non-free programs +enables a greater number of people to use a large body of free software. For +example, permission to use the GNU C Library in non-free programs enables +many more people to use the whole GNU operating system, as well as its variant, +the GNU/Linux operating system. + +Although the Lesser General Public License is Less protective of the users' +freedom, it does ensure that the user of a program that is linked with the +Library has the freedom and the wherewithal to run that program using a modified +version of the Library. + +The precise terms and conditions for copying, distribution and modification +follow. Pay close attention to the difference between a "work based on the +library" and a "work that uses the library". The former contains code derived +from the library, whereas the latter must be combined with the library in +order to run. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library or other program +which contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Lesser General +Public License (also called "this License"). Each licensee is addressed as +"you". + +A "library" means a collection of software functions and/or data prepared +so as to be conveniently linked with application programs (which use some +of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work which has +been distributed under these terms. A "work based on the Library" means either +the Library or any derivative work under copyright law: that is to say, a +work containing the Library or a portion of it, either verbatim or with modifications +and/or translated straightforwardly into another language. (Hereinafter, translation +is included without limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for making modifications +to it. For a library, complete source code means all the source code for all +modules it contains, plus any associated interface definition files, plus +the scripts used to control compilation and installation of the library. + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running a program +using the Library is not restricted, and output from such a program is covered +only if its contents constitute a work based on the Library (independent of +the use of the Library in a tool for writing it). Whether that is true depends +on what the Library does and what the program that uses the Library does. + +1. You may copy and distribute verbatim copies of the Library's complete source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and disclaimer +of warranty; keep intact all the notices that refer to this License and to +the absence of any warranty; and distribute a copy of this License along with +the Library. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Library or any portion of it, +thus forming a work based on the Library, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + + a) The modified work must itself be a software library. + +b) You must cause the files modified to carry prominent notices stating that +you changed the files and the date of any change. + +c) You must cause the whole of the work to be licensed at no charge to all +third parties under the terms of this License. + +d) If a facility in the modified Library refers to a function or a table of +data to be supplied by an application program that uses the facility, other +than as an argument passed when the facility is invoked, then you must make +a good faith effort to ensure that, in the event an application does not supply +such function or table, the facility still operates, and performs whatever +part of its purpose remains meaningful. + +(For example, a function in a library to compute square roots has a purpose +that is entirely well-defined independent of the application. Therefore, Subsection +2d requires that any application-supplied function or table used by this function +must be optional: if the application does not supply it, the square root function +must still compute square roots.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Library, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Library. + +In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may opt to apply the terms of the ordinary GNU General Public License +instead of this License to a given copy of the Library. To do this, you must +alter all the notices that refer to this License, so that they refer to the +ordinary GNU General Public License, version 2, instead of to this License. +(If a newer version than version 2 of the ordinary GNU General Public License +has appeared, then you can specify that version instead if you wish.) Do not +make any other change in these notices. + +Once this change is made in a given copy, it is irreversible for that copy, +so the ordinary GNU General Public License applies to all subsequent copies +and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of the Library +into a program that is not a library. + +4. You may copy and distribute the Library (or a portion or derivative of +it, under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you accompany it with the complete corresponding +machine-readable source code, which must be distributed under the terms of +Sections 1 and 2 above on a medium customarily used for software interchange. + +If distribution of object code is made by offering access to copy from a designated +place, then offering equivalent access to copy the source code from the same +place satisfies the requirement to distribute the source code, even though +third parties are not compelled to copy the source along with the object code. + +5. A program that contains no derivative of any portion of the Library, but +is designed to work with the Library by being compiled or linked with it, +is called a "work that uses the Library". Such a work, in isolation, is not +a derivative work of the Library, and therefore falls outside the scope of +this License. + +However, linking a "work that uses the Library" with the Library creates an +executable that is a derivative of the Library (because it contains portions +of the Library), rather than a "work that uses the library". The executable +is therefore covered by this License. Section 6 states terms for distribution +of such executables. + +When a "work that uses the Library" uses material from a header file that +is part of the Library, the object code for the work may be a derivative work +of the Library even though the source code is not. Whether this is true is +especially significant if the work can be linked without the Library, or if +the work is itself a library. The threshold for this to be true is not precisely +defined by law. + +If such an object file uses only numerical parameters, data structure layouts +and accessors, and small macros and small inline functions (ten lines or less +in length), then the use of the object file is unrestricted, regardless of +whether it is legally a derivative work. (Executables containing this object +code plus portions of the Library will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may distribute +the object code for the work under the terms of Section 6. Any executables +containing that work also fall under Section 6, whether or not they are linked +directly with the Library itself. + +6. As an exception to the Sections above, you may also combine or link a "work +that uses the Library" with the Library to produce a work containing portions +of the Library, and distribute that work under terms of your choice, provided +that the terms permit modification of the work for the customer's own use +and reverse engineering for debugging such modifications. + +You must give prominent notice with each copy of the work that the Library +is used in it and that the Library and its use are covered by this License. +You must supply a copy of this License. If the work during execution displays +copyright notices, you must include the copyright notice for the Library among +them, as well as a reference directing the user to the copy of this License. +Also, you must do one of these things: + +a) Accompany the work with the complete corresponding machine-readable source +code for the Library including whatever changes were used in the work (which +must be distributed under Sections 1 and 2 above); and, if the work is an +executable linked with the Library, with the complete machine-readable "work +that uses the Library", as object code and/or source code, so that the user +can modify the Library and then relink to produce a modified executable containing +the modified Library. (It is understood that the user who changes the contents +of definitions files in the Library will not necessarily be able to recompile +the application to use the modified definitions.) + +b) Use a suitable shared library mechanism for linking with the Library. A +suitable mechanism is one that (1) uses at run time a copy of the library +already present on the user's computer system, rather than copying library +functions into the executable, and (2) will operate properly with a modified +version of the library, if the user installs one, as long as the modified +version is interface-compatible with the version that the work was made with. + +c) Accompany the work with a written offer, valid for at least three years, +to give the same user the materials specified in Subsection 6a, above, for +a charge no more than the cost of performing this distribution. + +d) If distribution of the work is made by offering access to copy from a designated +place, offer equivalent access to copy the above specified materials from +the same place. + +e) Verify that the user has already received a copy of these materials or +that you have already sent this user a copy. + +For an executable, the required form of the "work that uses the Library" must +include any data and utility programs needed for reproducing the executable +from it. However, as a special exception, the materials to be distributed +need not include anything that is normally distributed (in either source or +binary form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component itself +accompanies the executable. + +It may happen that this requirement contradicts the license restrictions of +other proprietary libraries that do not normally accompany the operating system. +Such a contradiction means you cannot use both them and the Library together +in an executable that you distribute. + +7. You may place library facilities that are a work based on the Library side-by-side +in a single library together with other library facilities not covered by +this License, and distribute such a combined library, provided that the separate +distribution of the work based on the Library and of the other library facilities +is otherwise permitted, and provided that you do these two things: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities. This must be distributed +under the terms of the Sections above. + +b) Give prominent notice with the combined library of the fact that part of +it is a work based on the Library, and explaining where to find the accompanying +uncombined form of the same work. + +8. You may not copy, modify, sublicense, link with, or distribute the Library +except as expressly provided under this License. Any attempt otherwise to +copy, modify, sublicense, link with, or distribute the Library is void, and +will automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +9. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Library or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Library +(or any work based on the Library), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +10. Each time you redistribute the Library (or any work based on the Library), +the recipient automatically receives a license from the original licensor +to copy, distribute, link with or modify the Library subject to these terms +and conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties with this License. + +11. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of +this License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Library at all. For example, if a +patent license would not permit royalty-free redistribution of the Library +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +12. If the distribution and/or use of the Library is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Library under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +13. The Free Software Foundation may publish revised and/or new versions of +the Lesser General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Library specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Library does not specify a license version number, you may choose any version +ever published by the Free Software Foundation. + +14. If you wish to incorporate parts of the Library into other free programs +whose distribution conditions are incompatible with these, write to the author +to ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make exceptions +for this. Our decision will be guided by the two goals of preserving the free +status of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA +OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest possible +use to the public, we recommend making it free software that everyone can +redistribute and change. You can do so by permitting redistribution under +these terms (or, alternatively, under the terms of the ordinary General Public +License). + +To apply these terms, attach the following notices to the library. It is safest +to attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the "copyright" +line and a pointer to where the full notice is found. + + + +Copyright (C) + +This library is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free +Software Foundation; either version 2.1 of the License, or (at your option) +any later version. + +This library 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 Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with this library; if not, write to the Free Software Foundation, Inc., 51 +Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the library, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in + +the library `Frob' (a library for tweaking knobs) written + +by James Random Hacker. + +< signature of Ty Coon > , 1 April 1990 + +Ty Coon, President of Vice + +That's all there is to it! diff --git a/templates/cpp-plasmoid6/Messages.sh b/templates/cpp-plasmoid6/Messages.sh new file mode 100644 index 0000000..8bfc205 --- /dev/null +++ b/templates/cpp-plasmoid6/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT `find . -name \*.js -o -name \*.qml -o -name \*.cpp` -o $podir/plasma_applet_org.kde.plasma.%{APPNAMELC}.pot diff --git a/templates/cpp-plasmoid6/README b/templates/cpp-plasmoid6/README new file mode 100644 index 0000000..05724a5 --- /dev/null +++ b/templates/cpp-plasmoid6/README @@ -0,0 +1,46 @@ +Plasma Applet mixed C++/QML Template +---------------------- + +-- Namespace adaption -- + +Each Plasma plugin has a unique identifier, which is also used to find related +resources (like the translation catalogs). +To avoid naming collisions, Plasma plugins use a reverse domain name notation +for that identifier: + +* org.kde.plasma.* - plugins coming from Plasma modules +* org.kde.* - plugins coming from other software from KDE +* $(my.domain).* - plugins of your 3rd-party + +The generated code uses the "org.kde.plasma" namespace for the plugin identifier. +As this namespace is reserved for use by plugins part of Plasma modules, you will +need to adapt this namespace if you are writing a plugin which is not intended to +end up in the Plasma modules. + + +-- Build instructions -- + +cd /where/your/applet/is/generated +mkdir build +cd build +cmake -DCMAKE_INSTALL_PREFIX=MYPREFIX .. +make +make install + +(MYPREFIX is where you install your Plasma setup, replace it accordingly) + +Restart plasma to load the applet +(in a terminal type: +kquitapp plasmashell +and then +plasmashell) + +or view it with +plasmoidviewer -a YourAppletName + +-- Tutorials and resources -- +The explanation of the template +https://techbase.kde.org/Development/Tutorials/Plasma5/QML2/GettingStarted + +Plasma QML API explained +https://techbase.kde.org/Development/Tutorials/Plasma2/QML2/API diff --git a/templates/cpp-plasmoid6/cpp-plasmoid6.kdevtemplate b/templates/cpp-plasmoid6/cpp-plasmoid6.kdevtemplate new file mode 100644 index 0000000..5b1f09c --- /dev/null +++ b/templates/cpp-plasmoid6/cpp-plasmoid6.kdevtemplate @@ -0,0 +1,90 @@ +[General] +Name=Plasma QML/C++ Applet (Qt6) +Name[ar]=بريمج بلازما ب‍QML/سي++ (كيوت6) +Name[be]=Аплет QML/C++ для Plasma (Qt6) +Name[bg]=QML/C++ приставка за Plasma (Qt6) +Name[ca]=Miniaplicació QML/C++ del Plasma (Qt6) +Name[ca@valencia]=Miniaplicació en QML/C++ de Plasma (Qt6) +Name[cs]=Aplet Plasma QML/C++ (Qt6) +Name[da]=Plasma QML/C++-applet (Qt6) +Name[de]=Plasma-QML/C++-Miniprogramm (Qt6) +Name[en_GB]=Plasma QML/C++ Applet (Qt6) +Name[eo]=Plasma QML/C++ Apleto (Qt6) +Name[es]=Miniaplicación en QML/C++ para Plasma (Qt6) +Name[eu]=Plasma QML/C++ aplikaziotxoa (Qt6) +Name[fi]=Plasman QML/C++-sovelma (Qt6) +Name[fr]=Applet Plasma QML / C++ (Qt6) +Name[gl]=Miniaplicativo QML/C++ para Plasma (Qt 6) +Name[he]=יישומונית פלזמה ב־‎QML/C++‎ ‏(Qt6) +Name[hu]=Plasma QML/C++ kisalkalmazás (Qt6) +Name[ia]=Applet QML/C++ de Plasma (Qt6) +Name[is]=Plasma QML/C++ smáforrit (Qt6) +Name[it]=Applet QML/C++ di Plasma (Qt6) +Name[ka]=Plasma-ის QML/C++ აპლეტი (Qt6) +Name[ko]=Plasma QML/C++ 애플릿(Qt6) +Name[lt]=Plasma QML/C++ programėlė (Qt6) +Name[lv]=Plasma QML/C++ sÄ«klietotne (Qt6) +Name[nl]=Plasma-applet voor QML/C++ Applet (Qt6) +Name[nn]=Plasma QML/C++-element (Qt6) +Name[pl]=Aplet QML/C++ Plazmy (Qt6) +Name[pt_BR]=Miniaplicativo Plasma QML/C++ (Qt6) +Name[ro]=Miniaplicație QML/C++ Plasma (Qt6) +Name[ru]=Виджет Plasma на QML/C++ (Qt6) +Name[sa]=Plasma QML/C++ Applet (Qt6) +Name[sl]=Plasma aplet v QML/C++ (Qt6) +Name[sv]=Plasma QML/C++ miniprogram (Qt6) +Name[tr]=Plasma QML/C++ Uygulamacığı (Qt6) +Name[uk]=Аплет Плазми мовами QML/C++ (Qt6) +Name[vi]=Tiểu ứng dụng QML/C++ cá»§a Plasma (Qt6) +Name[x-test]=xxPlasma QML/C++ Applet (Qt6)xx +Name[zh_CN]=Plasma QML/C++ 小程序 (Qt6) +Name[zh_TW]=Plasma QML/C++ 小程式 (Qt6) +Comment=A Plasma Applet template written in an hybrid mix of QML and C++: a Plasma applet template displaying a SVG picture and a text +Comment[az]=QML və C ++ bir hibrid qarışıqda yazılmış Plazma Əlavəsi şablonu: SVG şəkli və mətni əks etdirən plazma əlavəsi şablonu +Comment[be]=Шаблон аплета Plasma, напісаны на QML і C++: шаблон аплета Plasma, які паказвае выяву SVG і тэкст +Comment[bg]=Шаблон за приставка на Plasma, написан на хибридна комбинация от QML и C++: шаблон на приставка на Plasma, показващ SVG изображение и текст +Comment[ca]=Una plantilla de miniaplicació del Plasma escrita en una barreja híbrida de QML i C++: una plantilla de miniaplicació del Plasma que mostra una imatge SVG i un text +Comment[ca@valencia]=Una plantilla de miniaplicació de Plasma escrita en una barreja híbrida de QML i C++: una plantilla de miniaplicació de Plasma que mostra una imatge SVG i un text +Comment[da]=En skabelon til en Plasma-applet skrevet i et hybrid-miks af QML og C++: En skabelon til Plasma som viser et SVG-billede og en tekst +Comment[de]=Eine Vorlage für ein Plasma-Miniprogramm, das in einer hybriden Mischung von QML und C++ geschrieben ist: Eine Vorlage für ein Plasma-Miniprogramm, das ein SVG-Bild und einen Text anzeigt +Comment[en_GB]=A Plasma Applet template written in an hybrid mix of QML and C++: a Plasma applet template displaying a SVG picture and a text +Comment[eo]=Plasma Applet-ŝablono skribita en hibrida miksaĵo de QML kaj C++: Plasma Applet-ŝablono elmontranta SVG-bildon kaj tekston +Comment[es]=Una plantilla de miniaplicación para Plasma escrita en una mezcla híbrida de QML y C++: una plantilla de miniaplicación para Plasma que muestra una imagen SVG y un texto +Comment[et]=Plasma apleti mall, mis on kirjutatud QML- ja C++ keelte seguna: Plasma apleti mall, mis kuvab SVG-pilti ja teksti +Comment[eu]=Plasma aplikaziotxo-txantiloi bat QML eta C++ arteko nahasketa hibrido batean idatzia: Plasma aplikaziotxo-txantiloi bat SVG irudi bat eta testu bat bistaratzen dituena +Comment[fi]=QML:n ja C++:n hybridikoosteella kirjoitettu Plasma-sovelmamalli, joka näyttää SVG-kuvan ja tekstin +Comment[fr]=Un modèle d'applet Plasma écrit dans un mélange hybride de QML et de C++ : un modèle d'applet Plasma qui affiche une image SVG et du texte +Comment[gl]=Un modelo de miniaplicativo de Plasma escrito nun híbrido de QML e C++: un modelo de miniaplicativo de Plasma que mostra unha imaxe SVG e un texto. +Comment[he]=תבנית יישומונית פלזמה שנכתבה בשילוב של QML ו־C++‎: תבנית יישומונית פלזמה שמציגה תמונת SVG וטקסט +Comment[hu]=Egy SVG-képet és szöveget megjelenítő, QML és C++ keverékével írt Plasma kisalkalmazás-sablon. +Comment[ia]=Un patrono de Applet de plasma scribite in un mixtura hybride de QML e C++: un patrono de applet de Plasma monstrante un imagine SVG e un texto +Comment[id]=Sebuah templat Applet Plasma yang ditulis dalam sebuah campuran hybrid dari QML dan C++: sebuah templat applet Plasma yang menampilkan sebuah teks dan gambar SVG +Comment[is]=Sniðmát fyrir Plasma smáforrit skrifað með blöndu af QML og C++: sniðmát fyrir Plasma smáforrit sem sýnir SVG-mynd og texta +Comment[it]=Un modello di applet di Plasma scritto in un misto di QML e C++: un modello di applet di Plasma che visualizza un'immagine SVG e un testo +Comment[ka]=Plasma-ის აპლეტის შაბლონი, დაწერილი QML-ის და C++-ის ნაზავზე. Plasma-ის აპლეტის შაბლონი, რომელსაც SVG სურათი და ტექსტი გამოაქვს +Comment[ko]=QMLê³¼ C++가 섞여 있는 Plasma 애플릿 템플릿: SVG 그림과 텍스트를 표시하는 Plasma 애플릿 템플릿 +Comment[lt]=Plasma programėlės Å¡ablonas, sukurtas naudojant hibridinį QML ir C++ miÅ¡inį: Plasma programėlės Å¡ablonas, atvaizduojantis SVG paveikslą ir tekstą +Comment[lv]=Plasma sÄ«klietotnes veidne QML un C++ valodā: „Plasma“ programmas veidne, kas parāda SVG attēlu un tekstu +Comment[nl]=Een sjabloon voor Plasma-applet geschreven in een hybride mengel van QML en C++: een Plasma-appletsjabloon die een SVG afbeelding en een tekst toont +Comment[nn]=Plasma-elementmal skriven i ei blanding av QML og C++: Ein mal for eit Plasma-element som viser eit SVG-bilete og litt tekst +Comment[pl]=Szablon apletu Plazmy napisany jako mieszanina QML i C: szablon apletu plazmy wyświetlający obraz SVG i tekst +Comment[pt]=Um modelo de 'applets' do Plasma criado numa mistura híbrida de QML e C++: um modelo de 'applets' do Plasma que mostra uma figura em SVG e um texto +Comment[pt_BR]=Um modelo de miniaplicativo Plasma escrito em uma mistura híbrida de QML e C++: um modelo de miniaplicativo Plasma mostrando uma image SVG e um texto +Comment[ru]=Шаблон виджета Plasma на смеси QML и C++: виджет показывает изображение SVG и текст +Comment[sa]=QML तथा C++ इत्येतयोः संकरमिश्रणे लिखितः Plasma Applet ढांचा: SVG चित्रं पाठ्यं च प्रदर्शयति इति Plasma applet ढांचा +Comment[sk]=Å ablóna na Plasma Applet napísaná v kombinácií QML a C++: Å ablóna Plasma appletu zobrazujúca SVG obrázok a text +Comment[sl]=Predloga Plasma apleta spisanega v meÅ¡anici QML in C++: predloga Plasma apleta, ki prikazuje sliko SVG in besedilo +Comment[sr]=Шаблон плазма аплета написан хибридном мешавином КуМЛ‑а и Ц++а: приказ СВГ слике и текста +Comment[sr@ijekavian]=Шаблон плазма аплета написан хибридном мешавином КуМЛ‑а и Ц++а: приказ СВГ слике и текста +Comment[sr@ijekavianlatin]=Å ablon plasma apleta napisan hibridnom meÅ¡avinom QML‑a i C++a: prikaz SVG slike i teksta +Comment[sr@latin]=Å ablon plasma apleta napisan hibridnom meÅ¡avinom QML‑a i C++a: prikaz SVG slike i teksta +Comment[sv]=En mall för Plasma-miniprogram skriven med en blandning av QML och C++: en mall för ett Plasma-miniprogram som visar en SVG-bild och en text +Comment[tg]=Қолиби зербарномаи Plasma, ки дар асоси омезиши дурагаи QML ва C++ навишта шудааст: Қолиби зербарномаи Plasma матн ва тасвири SVG-ро нишон медиҳад +Comment[tr]=QML ve C'nin karma bir karışımı içinde yazılmış bir Plasma Uygulamacık şablonu: Bir SVG resmi ve metin gösteren bir Plasma uygulamacığı şablonu +Comment[uk]=Шаблон аплету Плазми на гібридній суміші QML і C++: шаблон аплету Плазми, який показує зображення SVG і текст +Comment[vi]=Một bản mẫu Tiểu ứng dụng Plasma viết bằng sá»± pha trộn giữa QML và C++: một bản mẫu tiểu ứng dụng Plasma hiển thị một ảnh SVG và một văn bản +Comment[x-test]=xxA Plasma Applet template written in an hybrid mix of QML and C++: a Plasma applet template displaying a SVG picture and a textxx +Comment[zh_CN]=使用 QML 和 C++ 混合实现的 Plasma 小程序模板:显示 SVG 图片和文字的 Plasma 小程序模板 +Comment[zh_TW]=一個使用 QML 與 C++ 混合編寫的 Plasma 小程式範本:Plasma 小程式範本顯示了一張 SVG 圖片與文字 +Category=Plasma/Plasmoid +Icon=cpp-plasmoid6.png diff --git a/templates/cpp-plasmoid6/cpp-plasmoid6.png b/templates/cpp-plasmoid6/cpp-plasmoid6.png new file mode 100644 index 0000000000000000000000000000000000000000..26748f6cf7d22ef003badbca80cb69a61e2d46d2 GIT binary patch literal 35613 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 z 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 N002ovPDHLkV1id(qSXKZ literal 0 HcmV?d00001 diff --git a/templates/cpp-plasmoid6/src/%{APPNAMELC}.cpp b/templates/cpp-plasmoid6/src/%{APPNAMELC}.cpp new file mode 100644 index 0000000..c27ad38 --- /dev/null +++ b/templates/cpp-plasmoid6/src/%{APPNAMELC}.cpp @@ -0,0 +1,28 @@ +/* + SPDX-FileCopyrightText: %{CURRENT_YEAR} %{AUTHOR} <%{EMAIL}> + SPDX-License-Identifier: LGPL-2.1-or-later +*/ + +#include "%{APPNAMELC}.h" + +#include + +%{APPNAME}::%{APPNAME}(QObject *parent, const KPluginMetaData &data, const QVariantList &args) + : Plasma::Applet(parent, data, args), + m_nativeText(i18n("Text coming from C++ plugin")) +{ +} + +%{APPNAME}::~%{APPNAME}() +{ +} + +QString %{APPNAME}::nativeText() const +{ + return m_nativeText; +} + +K_PLUGIN_CLASS(%{APPNAME}) + +#include "%{APPNAMELC}.moc" +#include "moc_%{APPNAMELC}.cpp" diff --git a/templates/cpp-plasmoid6/src/%{APPNAMELC}.h b/templates/cpp-plasmoid6/src/%{APPNAMELC}.h new file mode 100644 index 0000000..733dec8 --- /dev/null +++ b/templates/cpp-plasmoid6/src/%{APPNAMELC}.h @@ -0,0 +1,26 @@ +/* + SPDX-FileCopyrightText: %{CURRENT_YEAR} %{AUTHOR} <%{EMAIL}> + SPDX-License-Identifier: LGPL-2.1-or-later +*/ + +#ifndef %{APPNAMEUC}_H +#define %{APPNAMEUC}_H + +#include + +class %{APPNAME} : public Plasma::Applet +{ + Q_OBJECT + Q_PROPERTY(QString nativeText READ nativeText CONSTANT) + +public: + explicit %{APPNAME}(QObject *parent, const KPluginMetaData &data, const QVariantList &args); + ~%{APPNAME}(); + + QString nativeText() const; + +private: + QString m_nativeText; +}; + +#endif diff --git a/templates/cpp-plasmoid6/src/CMakeLists.txt b/templates/cpp-plasmoid6/src/CMakeLists.txt new file mode 100644 index 0000000..ab1f698 --- /dev/null +++ b/templates/cpp-plasmoid6/src/CMakeLists.txt @@ -0,0 +1,14 @@ +# TODO: adapt "org.kde.plasma" here & elsewhere if needed (see README) +add_definitions(-DTRANSLATION_DOMAIN=\"plasma_applet_org.kde.plasma.%{APPNAMELC}\") + +add_library(org.kde.plasma.%{APPNAMELC} MODULE %{APPNAMELC}.cpp) + +target_link_libraries(org.kde.plasma.%{APPNAMELC} + Qt6::Gui + Plasma::Plasma + KF6::I18n) + + +install(TARGETS org.kde.plasma.%{APPNAMELC} DESTINATION ${KDE_INSTALL_PLUGINDIR}/plasma/applets) + +plasma_install_package(package org.kde.plasma.%{APPNAMELC}) diff --git a/templates/cpp-plasmoid6/src/package/contents/images/pairs.svg b/templates/cpp-plasmoid6/src/package/contents/images/pairs.svg new file mode 100644 index 0000000..ffab3c4 --- /dev/null +++ b/templates/cpp-plasmoid6/src/package/contents/images/pairs.svg @@ -0,0 +1,1911 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/templates/cpp-plasmoid6/src/package/contents/ui/main.qml b/templates/cpp-plasmoid6/src/package/contents/ui/main.qml new file mode 100644 index 0000000..0f7cf43 --- /dev/null +++ b/templates/cpp-plasmoid6/src/package/contents/ui/main.qml @@ -0,0 +1,25 @@ +/* + SPDX-FileCopyrightText: %{CURRENT_YEAR} %{AUTHOR} <%{EMAIL}> + SPDX-License-Identifier: LGPL-2.1-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.plasmoid +import org.kde.plasma.components as PlasmaComponents3 + +Item { + Plasmoid.fullRepresentation: ColumnLayout { + anchors.fill: parent + Image { + Layout.fillHeight: true + Layout.fillWidth: true + fillMode: Image.PreserveAspectFit + source: "../images/pairs.svg" + } + PlasmaComponents3.Label { + Layout.alignment: Qt.AlignCenter + text: Plasmoid.nativeInterface.nativeText + } + } +} diff --git a/templates/cpp-plasmoid6/src/package/metadata.json b/templates/cpp-plasmoid6/src/package/metadata.json new file mode 100644 index 0000000..aefe525 --- /dev/null +++ b/templates/cpp-plasmoid6/src/package/metadata.json @@ -0,0 +1,152 @@ +{ + "KPackageStructure": "Plasma/Applet", + "KPlugin": { + "Authors": [ + { + "Email": "%{EMAIL}", + "Name": "%{AUTHOR}", + "Name[ar]": "%{المؤلف}", + "Name[az]": "%{MÜƏLLİF}", + "Name[be]": "%{AUTHOR}", + "Name[bg]": "%{AUTHOR}", + "Name[ca@valencia]": "%{AUTHOR}", + "Name[ca]": "%{AUTHOR}", + "Name[cs]": "%{AUTHOR}", + "Name[da]": "%{AUTHOR}", + "Name[de]": "%{AUTHOR}", + "Name[el]": "%{AUTHOR}", + "Name[en_GB]": "%{AUTHOR}", + "Name[eo]": "%{AŬTORO}", + "Name[es]": "%{AUTHOR}", + "Name[eu]": "%{AUTHOR}", + "Name[fi]": "%{AUTHOR}", + "Name[fr]": "%{AUTHOR}", + "Name[gl]": "%{AUTHOR}", + "Name[he]": "%{AUTHOR}", + "Name[hu]": "%{AUTHOR}", + "Name[ia]": "%{AUTHOR}", + "Name[id]": "%{AUTHOR}", + "Name[is]": "%{AUTHOR}", + "Name[it]": "%{AUTHOR}", + "Name[ka]": "%{AUTHOR}", + "Name[ko]": "%{AUTHOR}", + "Name[lt]": "%{AUTHOR}", + "Name[lv]": "%{AUTHOR}", + "Name[nl]": "%{AUTHOR}", + "Name[nn]": "%{AUTHOR}", + "Name[pl]": "%{AUTHOR}", + "Name[pt]": "%{AUTHOR}", + "Name[pt_BR]": "%{AUTHOR}", + "Name[ro]": "%{AUTHOR}", + "Name[ru]": "%{AUTHOR}", + "Name[sa]": "%{AUTHOR}", + "Name[sk]": "%{AUTHOR}", + "Name[sl]": "%{AUTHOR}", + "Name[sv]": "%{AUTHOR}", + "Name[ta]": "%{AUTHOR}", + "Name[tr]": "%{AUTHOR}", + "Name[uk]": "%{AUTHOR}", + "Name[vi]": "%{AUTHOR}", + "Name[x-test]": "xx%{AUTHOR}xx", + "Name[zh_CN]": "%{AUTHOR}", + "Name[zh_TW]": "%{AUTHOR}" + } + ], + "Category": "Utilities", + "Description": "what your app does in a few words", + "Description[az]": "Bu proqramın nə işə yaradığı haqqında bir neçə söz", + "Description[be]": "кароткае апісанне працы вашай праграмы", + "Description[bg]": "какво прави вашето приложение с няколко думи", + "Description[ca@valencia]": "Què fa esta aplicació en poques paraules", + "Description[ca]": "Què fa aquesta aplicació en poques paraules", + "Description[da]": "hvad dit program, helt kort", + "Description[de]": "Was Ihre Anwendung macht (kurze Beschreibung)", + "Description[el]": "τι κάνει η εφαρμογή σας με λίγες λέξεις", + "Description[en_GB]": "what your app does in a few words", + "Description[eo]": "kion via aplikaĵo faras en kelkaj vortoj", + "Description[es]": "Lo que hace su aplicación en pocas palabras", + "Description[eu]": "zure aplikazioak egiten duena hitz gutxitan", + "Description[fi]": "muutama sana siitä, mitä sovelmasi tekee", + "Description[fr]": "ce que votre application fait en quelques mots", + "Description[gl]": "O que fai a aplicación, en poucas palabras.", + "Description[he]": "מה עושה היישום שלך במספר מילים", + "Description[hu]": "Írja le néhány szóban, mit csinál az alkalmazása", + "Description[ia]": "cosa tu app face in pauc parolas", + "Description[id]": "apa yang dilakukan aplikasi Anda dalam beberapa kata", + "Description[is]": "hvað forritið þitt gerir í fáum orðum", + "Description[it]": "Cosa fa la tua applicazione in poche parole", + "Description[ka]": "რამდენიმე სიტყვით, რას აკეთებს თქვენი აპლიკაცია", + "Description[ko]": "앱이 하는 일에 대한 간단한 설명", + "Description[lt]": "keliais žodžiais, ką daro jÅ«sų programa", + "Description[lv]": "uzrakstiet dažos vārdos, ko jÅ«su programma dara", + "Description[nl]": "wat uw app doet in een paar woorden", + "Description[nn]": "nokre fÃ¥ ord om kva programmet gjer", + "Description[pl]": "w kilku słowach opis co robi twój program", + "Description[pt]": "o que faz a sua aplicação em poucas palavras", + "Description[pt_BR]": "o que seu aplicativo faz em poucas palavras", + "Description[ro]": "ce face aplicația, în câteva cuvinte", + "Description[ru]": "Несколько слов о том, что делает ваша программа", + "Description[sa]": "भवतः अनुप्रयोगः कतिपयेषु शब्देषु किं करोति", + "Description[sk]": "čo vaÅ¡a aplikácia robí v niekoľkých slovách", + "Description[sl]": "v parih besedah kar počne vaÅ¡a aplikacija", + "Description[sv]": "vad programmet gör med nÃ¥gra fÃ¥ ord", + "Description[tr]": "uygulamanızı birkaç sözcükle anlatın", + "Description[uk]": "призначення вашої програми у декількох словах", + "Description[vi]": "dùng vài từ để mô tả ứng dụng cá»§a bạn làm việc gì", + "Description[x-test]": "xxwhat your app does in a few wordsxx", + "Description[zh_CN]": "用一个短句概括您的小程序的功能", + "Description[zh_TW]": "幾個詞內簡述您的應用程式所做的事", + "Icon": "applications-system", + "Id": "org.kde.plasma.%{APPNAMELC}", + "License": "LGPL-2.1+", + "Name": "%{APPNAME}", + "Name[ar]": "%{اسم_التطبيق}", + "Name[ast]": "%{APPNAME}", + "Name[az]": "%{TƏTBİQ_ADI}", + "Name[be]": "%{APPNAME}", + "Name[bg]": "%{APPNAME}", + "Name[ca@valencia]": "%{APPNAME}", + "Name[ca]": "%{APPNAME}", + "Name[cs]": "%{APPNAME}", + "Name[da]": "%{APPNAME}", + "Name[de]": "%{APPNAME}", + "Name[el]": "%{APPNAME}", + "Name[en_GB]": "%{APPNAME}", + "Name[eo]": "%{APPNAME}", + "Name[es]": "%{APPNAME}", + "Name[eu]": "%{APPNAME}", + "Name[fi]": "%{APPNAME}", + "Name[fr]": "%{APPNAME}", + "Name[gl]": "%{APPNAME}", + "Name[he]": "%{APPNAME}", + "Name[hu]": "%{APPNAME}", + "Name[ia]": "%{APPNAME}", + "Name[id]": "%{APPNAME}", + "Name[is]": "%{APPNAME}", + "Name[it]": "%{APPNAME}", + "Name[ka]": "%{APPNAME}", + "Name[ko]": "%{APPNAME}", + "Name[lt]": "%{APPNAME}", + "Name[lv]": "%{APPNAME}", + "Name[nl]": "%{APPNAME}", + "Name[nn]": "%{APPNAME}", + "Name[pl]": "%{APPNAME}", + "Name[pt]": "%{APPNAME}", + "Name[pt_BR]": "%{APPNAME}", + "Name[ro]": "%{APPNAME}", + "Name[ru]": "%{APPNAME}", + "Name[sa]": "%{APPNAME}", + "Name[sk]": "%{APPNAME}", + "Name[sl]": "%{APPNAME}", + "Name[sv]": "%{APPNAME}", + "Name[ta]": "%{APPNAME}", + "Name[tr]": "%{APPNAME}", + "Name[uk]": "%{APPNAME}", + "Name[vi]": "%{APPNAME}", + "Name[x-test]": "xx%{APPNAME}xx", + "Name[zh_CN]": "%{APPNAME}", + "Name[zh_TW]": "%{APPNAME}", + "Version": "1.0", + "Website": "https://plasma.kde.org/" + } +} diff --git a/templates/plasma6-wallpaper-with-qml-extension/CMakeLists.txt b/templates/plasma6-wallpaper-with-qml-extension/CMakeLists.txt new file mode 100644 index 0000000..89a9a71 --- /dev/null +++ b/templates/plasma6-wallpaper-with-qml-extension/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.16) + +project(plasma-%{APPNAMELC}) + +find_package(ECM 1.4.0 REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) + +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDECompilerSettings NO_POLICY_SCOPE) +include(FeatureSummary) + +find_package(KF6 REQUIRED COMPONENTS + Plasma + I18n +) + +find_package(Qt6 CONFIG REQUIRED COMPONENTS + Qml + Gui + Core +) + +# wallpaper applet +# TODO: adapt "org.kde.plasma" here & elsewhere if needed (see README) +plasma_install_package(package org.kde.plasma.%{APPNAMELC} wallpapers wallpaper) + +# qml extension plugin +add_subdirectory(plugin) + +feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/templates/plasma6-wallpaper-with-qml-extension/LICENSES/LGPL-2.1-or-later.txt b/templates/plasma6-wallpaper-with-qml-extension/LICENSES/LGPL-2.1-or-later.txt new file mode 100644 index 0000000..04bb156 --- /dev/null +++ b/templates/plasma6-wallpaper-with-qml-extension/LICENSES/LGPL-2.1-or-later.txt @@ -0,0 +1,468 @@ +GNU LESSER GENERAL PUBLIC LICENSE + +Version 2.1, February 1999 + +Copyright (C) 1991, 1999 Free Software Foundation, Inc. + +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts as the +successor of the GNU Library Public License, version 2, hence the version +number 2.1.] + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public Licenses are intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. + +This license, the Lesser General Public License, applies to some specially +designated software packages--typically libraries--of the Free Software Foundation +and other authors who decide to use it. You can use it too, but we suggest +you first think carefully about whether this license or the ordinary General +Public License is the better strategy to use in any particular case, based +on the explanations below. + +When we speak of free software, we are referring to freedom of use, not price. +Our General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you +wish); that you receive source code or can get it if you want it; that you +can change the software and use pieces of it in new free programs; and that +you are informed that you can do these things. + +To protect your rights, we need to make restrictions that forbid distributors +to deny you these rights or to ask you to surrender these rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the library or if you modify it. + +For example, if you distribute copies of the library, whether gratis or for +a fee, you must give the recipients all the rights that we gave you. You must +make sure that they, too, receive or can get the source code. If you link +other code with the library, you must provide complete object files to the +recipients, so that they can relink them with the library after making changes +to the library and recompiling it. And you must show them these terms so they +know their rights. + +We protect your rights with a two-step method: (1) we copyright the library, +and (2) we offer you this license, which gives you legal permission to copy, +distribute and/or modify the library. + +To protect each distributor, we want to make it very clear that there is no +warranty for the free library. Also, if the library is modified by someone +else and passed on, the recipients should know that what they have is not +the original version, so that the original author's reputation will not be +affected by problems that might be introduced by others. + +Finally, software patents pose a constant threat to the existence of any free +program. We wish to make sure that a company cannot effectively restrict the +users of a free program by obtaining a restrictive license from a patent holder. +Therefore, we insist that any patent license obtained for a version of the +library must be consistent with the full freedom of use specified in this +license. + +Most GNU software, including some libraries, is covered by the ordinary GNU +General Public License. This license, the GNU Lesser General Public License, +applies to certain designated libraries, and is quite different from the ordinary +General Public License. We use this license for certain libraries in order +to permit linking those libraries into non-free programs. + +When a program is linked with a library, whether statically or using a shared +library, the combination of the two is legally speaking a combined work, a +derivative of the original library. The ordinary General Public License therefore +permits such linking only if the entire combination fits its criteria of freedom. +The Lesser General Public License permits more lax criteria for linking other +code with the library. + +We call this license the "Lesser" General Public License because it does Less +to protect the user's freedom than the ordinary General Public License. It +also provides other free software developers Less of an advantage over competing +non-free programs. These disadvantages are the reason we use the ordinary +General Public License for many libraries. However, the Lesser license provides +advantages in certain special circumstances. + +For example, on rare occasions, there may be a special need to encourage the +widest possible use of a certain library, so that it becomes a de-facto standard. +To achieve this, non-free programs must be allowed to use the library. A more +frequent case is that a free library does the same job as widely used non-free +libraries. In this case, there is little to gain by limiting the free library +to free software only, so we use the Lesser General Public License. + +In other cases, permission to use a particular library in non-free programs +enables a greater number of people to use a large body of free software. For +example, permission to use the GNU C Library in non-free programs enables +many more people to use the whole GNU operating system, as well as its variant, +the GNU/Linux operating system. + +Although the Lesser General Public License is Less protective of the users' +freedom, it does ensure that the user of a program that is linked with the +Library has the freedom and the wherewithal to run that program using a modified +version of the Library. + +The precise terms and conditions for copying, distribution and modification +follow. Pay close attention to the difference between a "work based on the +library" and a "work that uses the library". The former contains code derived +from the library, whereas the latter must be combined with the library in +order to run. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library or other program +which contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Lesser General +Public License (also called "this License"). Each licensee is addressed as +"you". + +A "library" means a collection of software functions and/or data prepared +so as to be conveniently linked with application programs (which use some +of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work which has +been distributed under these terms. A "work based on the Library" means either +the Library or any derivative work under copyright law: that is to say, a +work containing the Library or a portion of it, either verbatim or with modifications +and/or translated straightforwardly into another language. (Hereinafter, translation +is included without limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for making modifications +to it. For a library, complete source code means all the source code for all +modules it contains, plus any associated interface definition files, plus +the scripts used to control compilation and installation of the library. + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running a program +using the Library is not restricted, and output from such a program is covered +only if its contents constitute a work based on the Library (independent of +the use of the Library in a tool for writing it). Whether that is true depends +on what the Library does and what the program that uses the Library does. + +1. You may copy and distribute verbatim copies of the Library's complete source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and disclaimer +of warranty; keep intact all the notices that refer to this License and to +the absence of any warranty; and distribute a copy of this License along with +the Library. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Library or any portion of it, +thus forming a work based on the Library, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + + a) The modified work must itself be a software library. + +b) You must cause the files modified to carry prominent notices stating that +you changed the files and the date of any change. + +c) You must cause the whole of the work to be licensed at no charge to all +third parties under the terms of this License. + +d) If a facility in the modified Library refers to a function or a table of +data to be supplied by an application program that uses the facility, other +than as an argument passed when the facility is invoked, then you must make +a good faith effort to ensure that, in the event an application does not supply +such function or table, the facility still operates, and performs whatever +part of its purpose remains meaningful. + +(For example, a function in a library to compute square roots has a purpose +that is entirely well-defined independent of the application. Therefore, Subsection +2d requires that any application-supplied function or table used by this function +must be optional: if the application does not supply it, the square root function +must still compute square roots.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Library, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Library. + +In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may opt to apply the terms of the ordinary GNU General Public License +instead of this License to a given copy of the Library. To do this, you must +alter all the notices that refer to this License, so that they refer to the +ordinary GNU General Public License, version 2, instead of to this License. +(If a newer version than version 2 of the ordinary GNU General Public License +has appeared, then you can specify that version instead if you wish.) Do not +make any other change in these notices. + +Once this change is made in a given copy, it is irreversible for that copy, +so the ordinary GNU General Public License applies to all subsequent copies +and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of the Library +into a program that is not a library. + +4. You may copy and distribute the Library (or a portion or derivative of +it, under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you accompany it with the complete corresponding +machine-readable source code, which must be distributed under the terms of +Sections 1 and 2 above on a medium customarily used for software interchange. + +If distribution of object code is made by offering access to copy from a designated +place, then offering equivalent access to copy the source code from the same +place satisfies the requirement to distribute the source code, even though +third parties are not compelled to copy the source along with the object code. + +5. A program that contains no derivative of any portion of the Library, but +is designed to work with the Library by being compiled or linked with it, +is called a "work that uses the Library". Such a work, in isolation, is not +a derivative work of the Library, and therefore falls outside the scope of +this License. + +However, linking a "work that uses the Library" with the Library creates an +executable that is a derivative of the Library (because it contains portions +of the Library), rather than a "work that uses the library". The executable +is therefore covered by this License. Section 6 states terms for distribution +of such executables. + +When a "work that uses the Library" uses material from a header file that +is part of the Library, the object code for the work may be a derivative work +of the Library even though the source code is not. Whether this is true is +especially significant if the work can be linked without the Library, or if +the work is itself a library. The threshold for this to be true is not precisely +defined by law. + +If such an object file uses only numerical parameters, data structure layouts +and accessors, and small macros and small inline functions (ten lines or less +in length), then the use of the object file is unrestricted, regardless of +whether it is legally a derivative work. (Executables containing this object +code plus portions of the Library will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may distribute +the object code for the work under the terms of Section 6. Any executables +containing that work also fall under Section 6, whether or not they are linked +directly with the Library itself. + +6. As an exception to the Sections above, you may also combine or link a "work +that uses the Library" with the Library to produce a work containing portions +of the Library, and distribute that work under terms of your choice, provided +that the terms permit modification of the work for the customer's own use +and reverse engineering for debugging such modifications. + +You must give prominent notice with each copy of the work that the Library +is used in it and that the Library and its use are covered by this License. +You must supply a copy of this License. If the work during execution displays +copyright notices, you must include the copyright notice for the Library among +them, as well as a reference directing the user to the copy of this License. +Also, you must do one of these things: + +a) Accompany the work with the complete corresponding machine-readable source +code for the Library including whatever changes were used in the work (which +must be distributed under Sections 1 and 2 above); and, if the work is an +executable linked with the Library, with the complete machine-readable "work +that uses the Library", as object code and/or source code, so that the user +can modify the Library and then relink to produce a modified executable containing +the modified Library. (It is understood that the user who changes the contents +of definitions files in the Library will not necessarily be able to recompile +the application to use the modified definitions.) + +b) Use a suitable shared library mechanism for linking with the Library. A +suitable mechanism is one that (1) uses at run time a copy of the library +already present on the user's computer system, rather than copying library +functions into the executable, and (2) will operate properly with a modified +version of the library, if the user installs one, as long as the modified +version is interface-compatible with the version that the work was made with. + +c) Accompany the work with a written offer, valid for at least three years, +to give the same user the materials specified in Subsection 6a, above, for +a charge no more than the cost of performing this distribution. + +d) If distribution of the work is made by offering access to copy from a designated +place, offer equivalent access to copy the above specified materials from +the same place. + +e) Verify that the user has already received a copy of these materials or +that you have already sent this user a copy. + +For an executable, the required form of the "work that uses the Library" must +include any data and utility programs needed for reproducing the executable +from it. However, as a special exception, the materials to be distributed +need not include anything that is normally distributed (in either source or +binary form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component itself +accompanies the executable. + +It may happen that this requirement contradicts the license restrictions of +other proprietary libraries that do not normally accompany the operating system. +Such a contradiction means you cannot use both them and the Library together +in an executable that you distribute. + +7. You may place library facilities that are a work based on the Library side-by-side +in a single library together with other library facilities not covered by +this License, and distribute such a combined library, provided that the separate +distribution of the work based on the Library and of the other library facilities +is otherwise permitted, and provided that you do these two things: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities. This must be distributed +under the terms of the Sections above. + +b) Give prominent notice with the combined library of the fact that part of +it is a work based on the Library, and explaining where to find the accompanying +uncombined form of the same work. + +8. You may not copy, modify, sublicense, link with, or distribute the Library +except as expressly provided under this License. Any attempt otherwise to +copy, modify, sublicense, link with, or distribute the Library is void, and +will automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +9. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Library or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Library +(or any work based on the Library), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +10. Each time you redistribute the Library (or any work based on the Library), +the recipient automatically receives a license from the original licensor +to copy, distribute, link with or modify the Library subject to these terms +and conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties with this License. + +11. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of +this License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Library at all. For example, if a +patent license would not permit royalty-free redistribution of the Library +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +12. If the distribution and/or use of the Library is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Library under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +13. The Free Software Foundation may publish revised and/or new versions of +the Lesser General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Library specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Library does not specify a license version number, you may choose any version +ever published by the Free Software Foundation. + +14. If you wish to incorporate parts of the Library into other free programs +whose distribution conditions are incompatible with these, write to the author +to ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make exceptions +for this. Our decision will be guided by the two goals of preserving the free +status of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA +OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest possible +use to the public, we recommend making it free software that everyone can +redistribute and change. You can do so by permitting redistribution under +these terms (or, alternatively, under the terms of the ordinary General Public +License). + +To apply these terms, attach the following notices to the library. It is safest +to attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the "copyright" +line and a pointer to where the full notice is found. + + + +Copyright (C) + +This library is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free +Software Foundation; either version 2.1 of the License, or (at your option) +any later version. + +This library 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 Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with this library; if not, write to the Free Software Foundation, Inc., 51 +Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the library, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in + +the library `Frob' (a library for tweaking knobs) written + +by James Random Hacker. + +< signature of Ty Coon > , 1 April 1990 + +Ty Coon, President of Vice + +That's all there is to it! diff --git a/templates/plasma6-wallpaper-with-qml-extension/Messages.sh b/templates/plasma6-wallpaper-with-qml-extension/Messages.sh new file mode 100644 index 0000000..c6fe3db --- /dev/null +++ b/templates/plasma6-wallpaper-with-qml-extension/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT `find . -name \*.qml -o -name \*.cpp` -o $podir/plasma_wallpaper_org.kde.plasma.%{APPNAMELC}.pot diff --git a/templates/plasma6-wallpaper-with-qml-extension/README b/templates/plasma6-wallpaper-with-qml-extension/README new file mode 100644 index 0000000..a130ef2 --- /dev/null +++ b/templates/plasma6-wallpaper-with-qml-extension/README @@ -0,0 +1,41 @@ +Plasma Wallpaper Template +---------------------- + +-- Namespace adaption -- + +Each Plasma plugin has a unique identifier, which is also used to find related +resources (like the translation catalogs). +To avoid naming collisions, Plasma plugins use a reverse domain name notation +for that identifier: + +* org.kde.plasma.* - plugins coming from Plasma modules +* org.kde.* - plugins coming from other software from KDE +* $(my.domain).* - plugins of your 3rd-party + +The generated code uses the "org.kde.plasma" namespace for the plugin identifier. +As this namespace is reserved for use by plugins part of Plasma modules, you will +need to adapt this namespace if you are writing a plugin which is not intended to +end up in the Plasma modules. + + +-- Build instructions -- + +cd /where/your/wallpaper/is/generated +mkdir build +cd build +cmake -DCMAKE_INSTALL_PREFIX=MYPREFIX .. +make +make install + +(MYPREFIX is where you install your Plasma setup, replace it accordingly) + +Restart plasma to load the wallpaper +(in a terminal or in krunner type: +kquitapp plasmashell +and then +plasmashell) +then go to wallpaper settings and select it + +-- Tutorials and resources -- +Plasma QML API explained +https://techbase.kde.org/Development/Tutorials/Plasma2/QML2/API diff --git a/templates/plasma6-wallpaper-with-qml-extension/package/contents/config/main.xml b/templates/plasma6-wallpaper-with-qml-extension/package/contents/config/main.xml new file mode 100644 index 0000000..fab19a2 --- /dev/null +++ b/templates/plasma6-wallpaper-with-qml-extension/package/contents/config/main.xml @@ -0,0 +1,15 @@ + + + + + + + + Hello World! + + + + diff --git a/templates/plasma6-wallpaper-with-qml-extension/package/contents/ui/config.qml b/templates/plasma6-wallpaper-with-qml-extension/package/contents/ui/config.qml new file mode 100644 index 0000000..a1e20cf --- /dev/null +++ b/templates/plasma6-wallpaper-with-qml-extension/package/contents/ui/config.qml @@ -0,0 +1,39 @@ +/* + SPDX-FileCopyrightText: %{CURRENT_YEAR} %{AUTHOR} <%{EMAIL}> + SPDX-License-Identifier: LGPL-2.1-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls as QQC2 +import org.kde.kirigami as Kirigami + +ColumnLayout { + id: root + property alias cfg_DisplayText: textField.text + + RowLayout { + spacing: Kirigami.Units.largeSpacing + + // To allow aligned integration in the settings form, + // "formAlignment" is a property injected by the config containment + // which defines the offset of the value fields + QQC2.Label { + Layout.minimumWidth: width + Layout.maximumWidth: width + width: formAlignment - Kirigami.Units.largeSpacing * 2 + horizontalAlignment: Text.AlignRight + + // use i18nd in config QML, as the default textdomain is set to that of the config container + text: i18nd("plasma_wallpaper_org.kde.plasma.%{APPNAMELC}", "Text to Display:") + } + QQC2.TextField { + id: textField + Layout.fillWidth: true + } + } + + Item { // tighten layout + Layout.fillHeight: true + } +} diff --git a/templates/plasma6-wallpaper-with-qml-extension/package/contents/ui/main.qml b/templates/plasma6-wallpaper-with-qml-extension/package/contents/ui/main.qml new file mode 100644 index 0000000..4af0567 --- /dev/null +++ b/templates/plasma6-wallpaper-with-qml-extension/package/contents/ui/main.qml @@ -0,0 +1,36 @@ +/* + SPDX-FileCopyrightText: %{CURRENT_YEAR} %{AUTHOR} <%{EMAIL}> + SPDX-License-Identifier: LGPL-2.1-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami +import org.kde.plasma.plasmoid +import org.kde.plasma.private.%{APPNAMELC} 1.0 + +WallpaperItem { + id: root + + Rectangle { + anchors.fill: parent + color: Kirigami.Theme.backgroundColor + } + + ColumnLayout { + anchors.centerIn: parent + + Kirigami.Heading { + Layout.alignment: Qt.AlignCenter + level: 1 + text: wallpaper.configuration.DisplayText || + i18n("") + } + + PlasmaComponents.Label { + Layout.alignment: Qt.AlignCenter + text: HelloWorld.text + } + } +} diff --git a/templates/plasma6-wallpaper-with-qml-extension/package/metadata.json b/templates/plasma6-wallpaper-with-qml-extension/package/metadata.json new file mode 100644 index 0000000..5c4865e --- /dev/null +++ b/templates/plasma6-wallpaper-with-qml-extension/package/metadata.json @@ -0,0 +1,109 @@ +{ + "KPackageStructure": "Plasma/Wallpaper", + "KPlugin": { + "Authors": [ + { + "Email": "%{EMAIL}", + "Name": "%{AUTHOR}", + "Name[ar]": "%{المؤلف}", + "Name[az]": "%{MÜƏLLİF}", + "Name[be]": "%{AUTHOR}", + "Name[bg]": "%{AUTHOR}", + "Name[ca@valencia]": "%{AUTHOR}", + "Name[ca]": "%{AUTHOR}", + "Name[cs]": "%{AUTHOR}", + "Name[da]": "%{AUTHOR}", + "Name[de]": "%{AUTHOR}", + "Name[el]": "%{AUTHOR}", + "Name[en_GB]": "%{AUTHOR}", + "Name[eo]": "%{AŬTORO}", + "Name[es]": "%{AUTHOR}", + "Name[eu]": "%{AUTHOR}", + "Name[fi]": "%{AUTHOR}", + "Name[fr]": "%{AUTHOR}", + "Name[gl]": "%{AUTHOR}", + "Name[he]": "%{AUTHOR}", + "Name[hu]": "%{AUTHOR}", + "Name[ia]": "%{AUTHOR}", + "Name[id]": "%{AUTHOR}", + "Name[is]": "%{AUTHOR}", + "Name[it]": "%{AUTHOR}", + "Name[ka]": "%{AUTHOR}", + "Name[ko]": "%{AUTHOR}", + "Name[lt]": "%{AUTHOR}", + "Name[lv]": "%{AUTHOR}", + "Name[nl]": "%{AUTHOR}", + "Name[nn]": "%{AUTHOR}", + "Name[pl]": "%{AUTHOR}", + "Name[pt]": "%{AUTHOR}", + "Name[pt_BR]": "%{AUTHOR}", + "Name[ro]": "%{AUTHOR}", + "Name[ru]": "%{AUTHOR}", + "Name[sa]": "%{AUTHOR}", + "Name[sk]": "%{AUTHOR}", + "Name[sl]": "%{AUTHOR}", + "Name[sv]": "%{AUTHOR}", + "Name[ta]": "%{AUTHOR}", + "Name[tr]": "%{AUTHOR}", + "Name[uk]": "%{AUTHOR}", + "Name[vi]": "%{AUTHOR}", + "Name[x-test]": "xx%{AUTHOR}xx", + "Name[zh_CN]": "%{AUTHOR}", + "Name[zh_TW]": "%{AUTHOR}" + } + ], + "Description": "", + "Icon": "plasma", + "Id": "org.kde.plasma.%{APPNAMELC}", + "License": "LGPL-2.1+", + "Name": "%{APPNAME}", + "Name[ar]": "%{اسم_التطبيق}", + "Name[ast]": "%{APPNAME}", + "Name[az]": "%{TƏTBİQ_ADI}", + "Name[be]": "%{APPNAME}", + "Name[bg]": "%{APPNAME}", + "Name[ca@valencia]": "%{APPNAME}", + "Name[ca]": "%{APPNAME}", + "Name[cs]": "%{APPNAME}", + "Name[da]": "%{APPNAME}", + "Name[de]": "%{APPNAME}", + "Name[el]": "%{APPNAME}", + "Name[en_GB]": "%{APPNAME}", + "Name[eo]": "%{APPNAME}", + "Name[es]": "%{APPNAME}", + "Name[eu]": "%{APPNAME}", + "Name[fi]": "%{APPNAME}", + "Name[fr]": "%{APPNAME}", + "Name[gl]": "%{APPNAME}", + "Name[he]": "%{APPNAME}", + "Name[hu]": "%{APPNAME}", + "Name[ia]": "%{APPNAME}", + "Name[id]": "%{APPNAME}", + "Name[is]": "%{APPNAME}", + "Name[it]": "%{APPNAME}", + "Name[ka]": "%{APPNAME}", + "Name[ko]": "%{APPNAME}", + "Name[lt]": "%{APPNAME}", + "Name[lv]": "%{APPNAME}", + "Name[nl]": "%{APPNAME}", + "Name[nn]": "%{APPNAME}", + "Name[pl]": "%{APPNAME}", + "Name[pt]": "%{APPNAME}", + "Name[pt_BR]": "%{APPNAME}", + "Name[ro]": "%{APPNAME}", + "Name[ru]": "%{APPNAME}", + "Name[sa]": "%{APPNAME}", + "Name[sk]": "%{APPNAME}", + "Name[sl]": "%{APPNAME}", + "Name[sv]": "%{APPNAME}", + "Name[ta]": "%{APPNAME}", + "Name[tr]": "%{APPNAME}", + "Name[uk]": "%{APPNAME}", + "Name[vi]": "%{APPNAME}", + "Name[x-test]": "xx%{APPNAME}xx", + "Name[zh_CN]": "%{APPNAME}", + "Name[zh_TW]": "%{APPNAME}", + "Version": "%{VERSION}", + "Website": "https://plasma.kde.org/" + } +} diff --git a/templates/plasma6-wallpaper-with-qml-extension/plasma6-wallpaper-with-qml-extension.kdevtemplate b/templates/plasma6-wallpaper-with-qml-extension/plasma6-wallpaper-with-qml-extension.kdevtemplate new file mode 100644 index 0000000..fad25ea --- /dev/null +++ b/templates/plasma6-wallpaper-with-qml-extension/plasma6-wallpaper-with-qml-extension.kdevtemplate @@ -0,0 +1,86 @@ +[General] +Name=Simple Plasma Wallpaper with QML extension (Qt6) +Name[ar]=بريمج بلازما ب‍QML (كيوت6) +Name[be]=Простыя шпалеры для Plasma з пашырэннем QML (Qt6) +Name[bg]=Прост тапет на Plasma с QML разширение (Qt6) +Name[ca]=Fons de pantalla senzill del Plasma amb extensió QML (Qt6) +Name[ca@valencia]=Fons de pantalla senzill de Plasma amb extensió en QML (Qt6) +Name[cs]=Jednoduchá tapeta pro prostředí Plasma s příponou QML (Qt6) +Name[da]=Simpelt Plasma-baggrundsbillede med QML-udvidelse (Qt6) +Name[de]=Einfaches Plasma-Hintergrundbild mit QML-Erweiterung (Qt6) +Name[en_GB]=Simple Plasma Wallpaper with QML extension (Qt6) +Name[eo]=Simpla Plasma-Tapeto kun QML-etendo (Qt6) +Name[es]=Fondo de escritorio de Plasma sencillo con extensión QML (Qt6) +Name[eu]=Plasma horma-paper xumea QML hedapenarekin (Qt6) +Name[fi]=Yksinkertainen Plasma-taustakuva QML-laajennuksella (Qt6) +Name[fr]=Fond d'écran simple sous Plasma avec extension « QML » (Qt6) +Name[gl]=Fondo de escritorio simple de Plasma con extensión de QML (Qt 6) +Name[he]=תמונת רקע פשוטה לשולחן העבודה עם הרחבת QML‏ (Qt6) +Name[hu]=Egyszerű Plasma háttérkép QML bővítménnyel (Qt6) +Name[ia]=Simple tapete de papiro de Plasma con extension QML (Qt6) +Name[is]=Simple Plasma Wallpaper með QML-viðauka (Qt6) +Name[it]=Semplice sfondo di Plasma con estensione QML (Qt6) +Name[ka]=მარტივი Plasma-ის ფონის სურათი QML გაფართოებით (Qt6) +Name[ko]=QML 확장을 사용하는 간단한 Plasma ë°°ê²½ 그림(Qt6) +Name[lt]=Paprastas Plasma darbalaukio fonas su QML plėtiniu (Qt6) +Name[lv]=VienkārÅ¡a „Plasma“ tapete ar QML paplaÅ¡inājumu (Qt6) +Name[nl]=Eenvoudige Plasma-bureaubladachtergrond met QML-extensie (Qt6) +Name[nn]=Enkelt Plasma-bakgrunnsbilete med QML-utviding (Qt6) +Name[pl]=Prosta tapeta Plazmy z rozszerzeniami QML (Qt6) +Name[pt_BR]=Papel de parede simples do Plasma com extensão QML (Qt6) +Name[ru]=Простые обои для Plasma с расширением для QML (Qt6) +Name[sa]=साधारण प्लाज्मा दीवार्पत्तिः च QML प्रसारणः (Qt6) +Name[sl]=Enostavna Plasma ozadje z razÅ¡iritvijo QML (Qt6) +Name[sv]=Enkelt Plasma skrivbordsunderlägg med QML-utökning (Qt6) +Name[ta]=QML துணை நிரலுடன் கூடிய எளிய பிளாஸ்மா பினபுலப் படம் (Qt6) +Name[tr]=QML uzantısıyla Basit Plasma Duvar Kağıdı (Qt6) +Name[uk]=Просте тло стільниці Плазми із розширенням QML (Qt6) +Name[vi]=Phông nền Plasma Đơn giản với phần mở rộng QML (Qt6) +Name[x-test]=xxSimple Plasma Wallpaper with QML extension (Qt6)xx +Name[zh_CN]=带有 QML 扩展的 Plasma 简易壁纸程序 (Qt6) +Name[zh_TW]=含有 QML 延伸元件的簡易 Plasma 桌布 (Qt6) +Comment=A Plasma wallpaper which uses custom API provided by an own QML extension plugin +Comment[az]=QML əlavəsi kimi təqdim edilən öz APİ -sini istifadə edən Plasma üçün divar kağızı nümunələri +Comment[be]=Шпалеры Plasma, якія выкарыстоўваюць уласны API з дапамогай ўласнай убудовы пашырэння QML +Comment[bg]=Тапет на Plasma, който използва потребителски API, предоставен от собствена QML приставка на разширение +Comment[ca]=Un fons de pantalla del Plasma que usa una API personalitzada proporcionada per un connector propi d'una extensió en QML +Comment[ca@valencia]=Un fons de pantalla de Plasma que utilitza una API personalitzada proporcionada per un connector propi d'una extensió en QML +Comment[da]=Et Plasma-baggrundsbillede der bruger et tilpasset API via et eget QML-udvidelsesplugin +Comment[de]=Ein Plasma-Hintergrundbild, das eine benutzerdefinierte Programmierschnittstelle (API) eines eigenen QML-Erweiterungsmoduls verwendet. +Comment[en_GB]=A Plasma wallpaper which uses custom API provided by an own QML extension plugin +Comment[eo]=Plasma tapeto kiu uzas propran API provizitan de propra QML-etendaĵo kromaĵo +Comment[es]=Un fondo de escritorio para Plasma que usa la API personalizada proporcionada por un complemento propio de extensión QML +Comment[et]=Plasma taustapilt, mis kasutab meie oma QML-i laiendusplugina kohandatud API-t +Comment[eu]=Plasma horma-paper bat, QML hedapen plugin propio baten API pertsonalizatu bat erabiltzen duena +Comment[fi]=Plasma-taustakuva, joka käyttää oman QML-laajennusliitännäisen tarjoamaa mukautettua APIa +Comment[fr]=Un modèle de fond d'écran Plasma utilisant une API personnalisée fournie par son propre module externe d'extension QML +Comment[gl]=Un fondo de Plasma que usa unha API personalizada fornecida por un complemento de extensión de QML de seu. +Comment[he]=תמונת רקע לפלזמה שמשתמשת ב־API מותאם שסופק על ידי תוסף הרחבת QML עצמי +Comment[hu]=Saját, QML bővítmény által biztosított API-t használó Plasma háttérkép +Comment[ia]=Un tapete de papiro de Plasma que usa API personalisate fornite per un proprie plgin de extension QML +Comment[id]=Sebuah wallpaper Plasma yang menggunakan kustom API yang disediakan oleh plugin ekstensi QML sendiri +Comment[is]=Plasma-veggfóður sem notar sérsniðið forritunarviðmót (API) sem fengið er frá eigin QML-viðbót +Comment[it]=Uno sfondo di Plasma che utilizza API personalizzate fornite da una propria estensione QML +Comment[ka]=Plasma-ის ფონი, რომელიც ხელით განსაზღვრულ API-ს იყენებს, რომელიც მისი საკუთარი QML-ის გაფართოების დამატების მიერ მოეწოდება +Comment[ko]=QML 확장 플러그인이 추가로 제공하는 API를 사용하는 Plasma ë°°ê²½ 그림 +Comment[lt]=Plasma darbalaukio fonas, naudojantis tinkintą API, kurį teikia nuosavas QML plėtinio įskiepis +Comment[lv]=„Plasma“ tapete, kurā ir izmantots pielāgots API, ko nodroÅ¡ina paÅ¡as QML paplaÅ¡inājuma spraudnis +Comment[nl]=Een Plasma-achtergrond die aangepaste API gebruikt geleverd door een eigen QML-extensie-plug-in +Comment[nn]=Plasma-bakgrunnsbilete som brukar eit eige API som kjem frÃ¥ eit programtillegg for ei QML-utviding +Comment[pl]=Tapeta Plazmy, która używa własnego API dostarczonego przez własną wtyczkę rozszerzeń QML +Comment[pt]=Um papel de parede do Plasma que usa uma API personalizada oferecida por um 'plugin' de extensão próprio em QML +Comment[pt_BR]=Um papel de parede do Plasma que usa API personalizada fornecida por um plug-in de extensão QML próprio +Comment[ru]=Шаблон обоев для Plasma, использующий собственный API, реализованный как расширение для QML +Comment[sa]=एकः प्लाज्मा दीवार्पत्तिः यः स्वस्य QML विस्तारप्लगिन् द्वारा प्रदत्तस्य अनुकूलनीयः API इत्यस्य उपयोगं करोति +Comment[sk]=Tapeta Plasma používajúca vlatné API poskytované vlastným QML rozšírením +Comment[sl]=Ozadje Plasme, ki uporablja API po meri, ponujen s strani lastnega razÅ¡iritvenega vstavka QML +Comment[sv]=Ett Plasma skrivbordsunderlägg som använder ett anpassat programmeringsgränssnitt tillhandahÃ¥llet av en egen QML-utökningsmodul +Comment[tg]=Тасвири заминаи Plasma, ки дар асоси васлкунаки васеъшавии QML низоми API-и фармоиширо истифода мебарад +Comment[tr]=Kendi QML uzantısı tarafından sağlanan özel bir API kullanan bir Plasma duvar kağıdı +Comment[uk]=Тло стільниці Плазми, у якому використовується нетиповий програмний інтерфейс, що надається власним додатком розширення QML +Comment[vi]=Một phông nền Plasma sá»­ dụng API riêng được cung cấp bởi một phần cài cắm mở rộng QML riêng +Comment[x-test]=xxA Plasma wallpaper which uses custom API provided by an own QML extension pluginxx +Comment[zh_CN]=使用自带 QML 扩展插件 API 的 Plasma 壁纸程序 +Comment[zh_TW]=使用由自己的 QML 延伸元件提供的自訂 API 的 Plasma 桌布 +Category=Plasma/Wallpaper +Icon= diff --git a/templates/plasma6-wallpaper-with-qml-extension/plugin/%{APPNAMELC}plugin.cpp b/templates/plasma6-wallpaper-with-qml-extension/plugin/%{APPNAMELC}plugin.cpp new file mode 100644 index 0000000..f885f94 --- /dev/null +++ b/templates/plasma6-wallpaper-with-qml-extension/plugin/%{APPNAMELC}plugin.cpp @@ -0,0 +1,32 @@ +/* + SPDX-FileCopyrightText: %{CURRENT_YEAR} %{AUTHOR} <%{EMAIL}> + SPDX-License-Identifier: LGPL-2.1-or-later +*/ + +#include "%{APPNAMELC}plugin.h" + +// KF +#include +// Qt +#include +#include +#include + +static QJSValue singletonTypeExampleProvider(QQmlEngine* engine, QJSEngine* scriptEngine) +{ + Q_UNUSED(engine) + + QJSValue helloWorld = scriptEngine->newObject(); + helloWorld.setProperty("text", i18n("Hello world!")); + return helloWorld; +} + + +void %{APPNAME}Plugin::registerTypes(const char* uri) +{ + Q_ASSERT(uri == QLatin1String("org.kde.plasma.private.%{APPNAMELC}")); + + qmlRegisterSingletonType(uri, 1, 0, "HelloWorld", singletonTypeExampleProvider); +} + +#include "moc_%{APPNAMELC}plugin.cpp" diff --git a/templates/plasma6-wallpaper-with-qml-extension/plugin/%{APPNAMELC}plugin.h b/templates/plasma6-wallpaper-with-qml-extension/plugin/%{APPNAMELC}plugin.h new file mode 100644 index 0000000..c87bd45 --- /dev/null +++ b/templates/plasma6-wallpaper-with-qml-extension/plugin/%{APPNAMELC}plugin.h @@ -0,0 +1,20 @@ +/* + SPDX-FileCopyrightText: %{CURRENT_YEAR} %{AUTHOR} <%{EMAIL}> + SPDX-License-Identifier: LGPL-2.1-or-later +*/ + +#ifndef %{APPNAMEUC}PLUGIN_H +#define %{APPNAMEUC}PLUGIN_H + +#include + +class %{APPNAME}Plugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") + +public: + void registerTypes(const char *uri) override; +}; + +#endif // %{APPNAMEUC}PLUGIN_H diff --git a/templates/plasma6-wallpaper-with-qml-extension/plugin/CMakeLists.txt b/templates/plasma6-wallpaper-with-qml-extension/plugin/CMakeLists.txt new file mode 100644 index 0000000..ae53805 --- /dev/null +++ b/templates/plasma6-wallpaper-with-qml-extension/plugin/CMakeLists.txt @@ -0,0 +1,11 @@ +add_definitions(-DTRANSLATION_DOMAIN=\"plasma_wallpaper_org.kde.plasma.%{APPNAMELC}\") + +add_library(%{APPNAMELC}plugin SHARED %{APPNAMELC}plugin.cpp) + +target_link_libraries(%{APPNAMELC}plugin + KF6::I18n + Qt6::Gui + Qt6::Qml +) +install(TARGETS %{APPNAMELC}plugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/private/%{APPNAMELC}) +install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/private/%{APPNAMELC}) diff --git a/templates/plasma6-wallpaper-with-qml-extension/plugin/qmldir b/templates/plasma6-wallpaper-with-qml-extension/plugin/qmldir new file mode 100644 index 0000000..e549fc7 --- /dev/null +++ b/templates/plasma6-wallpaper-with-qml-extension/plugin/qmldir @@ -0,0 +1,2 @@ +module org.kde.plasma.private.%{APPNAMELC} +plugin %{APPNAMELC}plugin diff --git a/templates/plasma6-wallpaper/CMakeLists.txt b/templates/plasma6-wallpaper/CMakeLists.txt new file mode 100644 index 0000000..50c0053 --- /dev/null +++ b/templates/plasma6-wallpaper/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.16) + +project(plasma-%{APPNAMELC}) + +find_package(ECM 1.4.0 REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) + +find_package(Plasma REQUIRED) + +# TODO: adapt "org.kde.plasma" here & elsewhere if needed (see README) +plasma_install_package(package org.kde.plasma.%{APPNAMELC} wallpapers wallpaper) diff --git a/templates/plasma6-wallpaper/LICENSES/LGPL-2.1-or-later.txt b/templates/plasma6-wallpaper/LICENSES/LGPL-2.1-or-later.txt new file mode 100644 index 0000000..04bb156 --- /dev/null +++ b/templates/plasma6-wallpaper/LICENSES/LGPL-2.1-or-later.txt @@ -0,0 +1,468 @@ +GNU LESSER GENERAL PUBLIC LICENSE + +Version 2.1, February 1999 + +Copyright (C) 1991, 1999 Free Software Foundation, Inc. + +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts as the +successor of the GNU Library Public License, version 2, hence the version +number 2.1.] + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public Licenses are intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. + +This license, the Lesser General Public License, applies to some specially +designated software packages--typically libraries--of the Free Software Foundation +and other authors who decide to use it. You can use it too, but we suggest +you first think carefully about whether this license or the ordinary General +Public License is the better strategy to use in any particular case, based +on the explanations below. + +When we speak of free software, we are referring to freedom of use, not price. +Our General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you +wish); that you receive source code or can get it if you want it; that you +can change the software and use pieces of it in new free programs; and that +you are informed that you can do these things. + +To protect your rights, we need to make restrictions that forbid distributors +to deny you these rights or to ask you to surrender these rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the library or if you modify it. + +For example, if you distribute copies of the library, whether gratis or for +a fee, you must give the recipients all the rights that we gave you. You must +make sure that they, too, receive or can get the source code. If you link +other code with the library, you must provide complete object files to the +recipients, so that they can relink them with the library after making changes +to the library and recompiling it. And you must show them these terms so they +know their rights. + +We protect your rights with a two-step method: (1) we copyright the library, +and (2) we offer you this license, which gives you legal permission to copy, +distribute and/or modify the library. + +To protect each distributor, we want to make it very clear that there is no +warranty for the free library. Also, if the library is modified by someone +else and passed on, the recipients should know that what they have is not +the original version, so that the original author's reputation will not be +affected by problems that might be introduced by others. + +Finally, software patents pose a constant threat to the existence of any free +program. We wish to make sure that a company cannot effectively restrict the +users of a free program by obtaining a restrictive license from a patent holder. +Therefore, we insist that any patent license obtained for a version of the +library must be consistent with the full freedom of use specified in this +license. + +Most GNU software, including some libraries, is covered by the ordinary GNU +General Public License. This license, the GNU Lesser General Public License, +applies to certain designated libraries, and is quite different from the ordinary +General Public License. We use this license for certain libraries in order +to permit linking those libraries into non-free programs. + +When a program is linked with a library, whether statically or using a shared +library, the combination of the two is legally speaking a combined work, a +derivative of the original library. The ordinary General Public License therefore +permits such linking only if the entire combination fits its criteria of freedom. +The Lesser General Public License permits more lax criteria for linking other +code with the library. + +We call this license the "Lesser" General Public License because it does Less +to protect the user's freedom than the ordinary General Public License. It +also provides other free software developers Less of an advantage over competing +non-free programs. These disadvantages are the reason we use the ordinary +General Public License for many libraries. However, the Lesser license provides +advantages in certain special circumstances. + +For example, on rare occasions, there may be a special need to encourage the +widest possible use of a certain library, so that it becomes a de-facto standard. +To achieve this, non-free programs must be allowed to use the library. A more +frequent case is that a free library does the same job as widely used non-free +libraries. In this case, there is little to gain by limiting the free library +to free software only, so we use the Lesser General Public License. + +In other cases, permission to use a particular library in non-free programs +enables a greater number of people to use a large body of free software. For +example, permission to use the GNU C Library in non-free programs enables +many more people to use the whole GNU operating system, as well as its variant, +the GNU/Linux operating system. + +Although the Lesser General Public License is Less protective of the users' +freedom, it does ensure that the user of a program that is linked with the +Library has the freedom and the wherewithal to run that program using a modified +version of the Library. + +The precise terms and conditions for copying, distribution and modification +follow. Pay close attention to the difference between a "work based on the +library" and a "work that uses the library". The former contains code derived +from the library, whereas the latter must be combined with the library in +order to run. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library or other program +which contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Lesser General +Public License (also called "this License"). Each licensee is addressed as +"you". + +A "library" means a collection of software functions and/or data prepared +so as to be conveniently linked with application programs (which use some +of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work which has +been distributed under these terms. A "work based on the Library" means either +the Library or any derivative work under copyright law: that is to say, a +work containing the Library or a portion of it, either verbatim or with modifications +and/or translated straightforwardly into another language. (Hereinafter, translation +is included without limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for making modifications +to it. For a library, complete source code means all the source code for all +modules it contains, plus any associated interface definition files, plus +the scripts used to control compilation and installation of the library. + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running a program +using the Library is not restricted, and output from such a program is covered +only if its contents constitute a work based on the Library (independent of +the use of the Library in a tool for writing it). Whether that is true depends +on what the Library does and what the program that uses the Library does. + +1. You may copy and distribute verbatim copies of the Library's complete source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and disclaimer +of warranty; keep intact all the notices that refer to this License and to +the absence of any warranty; and distribute a copy of this License along with +the Library. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Library or any portion of it, +thus forming a work based on the Library, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + + a) The modified work must itself be a software library. + +b) You must cause the files modified to carry prominent notices stating that +you changed the files and the date of any change. + +c) You must cause the whole of the work to be licensed at no charge to all +third parties under the terms of this License. + +d) If a facility in the modified Library refers to a function or a table of +data to be supplied by an application program that uses the facility, other +than as an argument passed when the facility is invoked, then you must make +a good faith effort to ensure that, in the event an application does not supply +such function or table, the facility still operates, and performs whatever +part of its purpose remains meaningful. + +(For example, a function in a library to compute square roots has a purpose +that is entirely well-defined independent of the application. Therefore, Subsection +2d requires that any application-supplied function or table used by this function +must be optional: if the application does not supply it, the square root function +must still compute square roots.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Library, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Library. + +In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may opt to apply the terms of the ordinary GNU General Public License +instead of this License to a given copy of the Library. To do this, you must +alter all the notices that refer to this License, so that they refer to the +ordinary GNU General Public License, version 2, instead of to this License. +(If a newer version than version 2 of the ordinary GNU General Public License +has appeared, then you can specify that version instead if you wish.) Do not +make any other change in these notices. + +Once this change is made in a given copy, it is irreversible for that copy, +so the ordinary GNU General Public License applies to all subsequent copies +and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of the Library +into a program that is not a library. + +4. You may copy and distribute the Library (or a portion or derivative of +it, under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you accompany it with the complete corresponding +machine-readable source code, which must be distributed under the terms of +Sections 1 and 2 above on a medium customarily used for software interchange. + +If distribution of object code is made by offering access to copy from a designated +place, then offering equivalent access to copy the source code from the same +place satisfies the requirement to distribute the source code, even though +third parties are not compelled to copy the source along with the object code. + +5. A program that contains no derivative of any portion of the Library, but +is designed to work with the Library by being compiled or linked with it, +is called a "work that uses the Library". Such a work, in isolation, is not +a derivative work of the Library, and therefore falls outside the scope of +this License. + +However, linking a "work that uses the Library" with the Library creates an +executable that is a derivative of the Library (because it contains portions +of the Library), rather than a "work that uses the library". The executable +is therefore covered by this License. Section 6 states terms for distribution +of such executables. + +When a "work that uses the Library" uses material from a header file that +is part of the Library, the object code for the work may be a derivative work +of the Library even though the source code is not. Whether this is true is +especially significant if the work can be linked without the Library, or if +the work is itself a library. The threshold for this to be true is not precisely +defined by law. + +If such an object file uses only numerical parameters, data structure layouts +and accessors, and small macros and small inline functions (ten lines or less +in length), then the use of the object file is unrestricted, regardless of +whether it is legally a derivative work. (Executables containing this object +code plus portions of the Library will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may distribute +the object code for the work under the terms of Section 6. Any executables +containing that work also fall under Section 6, whether or not they are linked +directly with the Library itself. + +6. As an exception to the Sections above, you may also combine or link a "work +that uses the Library" with the Library to produce a work containing portions +of the Library, and distribute that work under terms of your choice, provided +that the terms permit modification of the work for the customer's own use +and reverse engineering for debugging such modifications. + +You must give prominent notice with each copy of the work that the Library +is used in it and that the Library and its use are covered by this License. +You must supply a copy of this License. If the work during execution displays +copyright notices, you must include the copyright notice for the Library among +them, as well as a reference directing the user to the copy of this License. +Also, you must do one of these things: + +a) Accompany the work with the complete corresponding machine-readable source +code for the Library including whatever changes were used in the work (which +must be distributed under Sections 1 and 2 above); and, if the work is an +executable linked with the Library, with the complete machine-readable "work +that uses the Library", as object code and/or source code, so that the user +can modify the Library and then relink to produce a modified executable containing +the modified Library. (It is understood that the user who changes the contents +of definitions files in the Library will not necessarily be able to recompile +the application to use the modified definitions.) + +b) Use a suitable shared library mechanism for linking with the Library. A +suitable mechanism is one that (1) uses at run time a copy of the library +already present on the user's computer system, rather than copying library +functions into the executable, and (2) will operate properly with a modified +version of the library, if the user installs one, as long as the modified +version is interface-compatible with the version that the work was made with. + +c) Accompany the work with a written offer, valid for at least three years, +to give the same user the materials specified in Subsection 6a, above, for +a charge no more than the cost of performing this distribution. + +d) If distribution of the work is made by offering access to copy from a designated +place, offer equivalent access to copy the above specified materials from +the same place. + +e) Verify that the user has already received a copy of these materials or +that you have already sent this user a copy. + +For an executable, the required form of the "work that uses the Library" must +include any data and utility programs needed for reproducing the executable +from it. However, as a special exception, the materials to be distributed +need not include anything that is normally distributed (in either source or +binary form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component itself +accompanies the executable. + +It may happen that this requirement contradicts the license restrictions of +other proprietary libraries that do not normally accompany the operating system. +Such a contradiction means you cannot use both them and the Library together +in an executable that you distribute. + +7. You may place library facilities that are a work based on the Library side-by-side +in a single library together with other library facilities not covered by +this License, and distribute such a combined library, provided that the separate +distribution of the work based on the Library and of the other library facilities +is otherwise permitted, and provided that you do these two things: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities. This must be distributed +under the terms of the Sections above. + +b) Give prominent notice with the combined library of the fact that part of +it is a work based on the Library, and explaining where to find the accompanying +uncombined form of the same work. + +8. You may not copy, modify, sublicense, link with, or distribute the Library +except as expressly provided under this License. Any attempt otherwise to +copy, modify, sublicense, link with, or distribute the Library is void, and +will automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +9. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Library or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Library +(or any work based on the Library), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +10. Each time you redistribute the Library (or any work based on the Library), +the recipient automatically receives a license from the original licensor +to copy, distribute, link with or modify the Library subject to these terms +and conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties with this License. + +11. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of +this License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Library at all. For example, if a +patent license would not permit royalty-free redistribution of the Library +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +12. If the distribution and/or use of the Library is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Library under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +13. The Free Software Foundation may publish revised and/or new versions of +the Lesser General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Library specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Library does not specify a license version number, you may choose any version +ever published by the Free Software Foundation. + +14. If you wish to incorporate parts of the Library into other free programs +whose distribution conditions are incompatible with these, write to the author +to ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make exceptions +for this. Our decision will be guided by the two goals of preserving the free +status of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA +OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest possible +use to the public, we recommend making it free software that everyone can +redistribute and change. You can do so by permitting redistribution under +these terms (or, alternatively, under the terms of the ordinary General Public +License). + +To apply these terms, attach the following notices to the library. It is safest +to attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the "copyright" +line and a pointer to where the full notice is found. + + + +Copyright (C) + +This library is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free +Software Foundation; either version 2.1 of the License, or (at your option) +any later version. + +This library 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 Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with this library; if not, write to the Free Software Foundation, Inc., 51 +Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the library, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in + +the library `Frob' (a library for tweaking knobs) written + +by James Random Hacker. + +< signature of Ty Coon > , 1 April 1990 + +Ty Coon, President of Vice + +That's all there is to it! diff --git a/templates/plasma6-wallpaper/Messages.sh b/templates/plasma6-wallpaper/Messages.sh new file mode 100644 index 0000000..766bdda --- /dev/null +++ b/templates/plasma6-wallpaper/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT `find . -name \*.qml` -o $podir/plasma_wallpaper_org.kde.plasma.%{APPNAMELC}.pot diff --git a/templates/plasma6-wallpaper/README b/templates/plasma6-wallpaper/README new file mode 100644 index 0000000..a130ef2 --- /dev/null +++ b/templates/plasma6-wallpaper/README @@ -0,0 +1,41 @@ +Plasma Wallpaper Template +---------------------- + +-- Namespace adaption -- + +Each Plasma plugin has a unique identifier, which is also used to find related +resources (like the translation catalogs). +To avoid naming collisions, Plasma plugins use a reverse domain name notation +for that identifier: + +* org.kde.plasma.* - plugins coming from Plasma modules +* org.kde.* - plugins coming from other software from KDE +* $(my.domain).* - plugins of your 3rd-party + +The generated code uses the "org.kde.plasma" namespace for the plugin identifier. +As this namespace is reserved for use by plugins part of Plasma modules, you will +need to adapt this namespace if you are writing a plugin which is not intended to +end up in the Plasma modules. + + +-- Build instructions -- + +cd /where/your/wallpaper/is/generated +mkdir build +cd build +cmake -DCMAKE_INSTALL_PREFIX=MYPREFIX .. +make +make install + +(MYPREFIX is where you install your Plasma setup, replace it accordingly) + +Restart plasma to load the wallpaper +(in a terminal or in krunner type: +kquitapp plasmashell +and then +plasmashell) +then go to wallpaper settings and select it + +-- Tutorials and resources -- +Plasma QML API explained +https://techbase.kde.org/Development/Tutorials/Plasma2/QML2/API diff --git a/templates/plasma6-wallpaper/package/contents/config/main.xml b/templates/plasma6-wallpaper/package/contents/config/main.xml new file mode 100644 index 0000000..fab19a2 --- /dev/null +++ b/templates/plasma6-wallpaper/package/contents/config/main.xml @@ -0,0 +1,15 @@ + + + + + + + + Hello World! + + + + diff --git a/templates/plasma6-wallpaper/package/contents/ui/config.qml b/templates/plasma6-wallpaper/package/contents/ui/config.qml new file mode 100644 index 0000000..a1e20cf --- /dev/null +++ b/templates/plasma6-wallpaper/package/contents/ui/config.qml @@ -0,0 +1,39 @@ +/* + SPDX-FileCopyrightText: %{CURRENT_YEAR} %{AUTHOR} <%{EMAIL}> + SPDX-License-Identifier: LGPL-2.1-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls as QQC2 +import org.kde.kirigami as Kirigami + +ColumnLayout { + id: root + property alias cfg_DisplayText: textField.text + + RowLayout { + spacing: Kirigami.Units.largeSpacing + + // To allow aligned integration in the settings form, + // "formAlignment" is a property injected by the config containment + // which defines the offset of the value fields + QQC2.Label { + Layout.minimumWidth: width + Layout.maximumWidth: width + width: formAlignment - Kirigami.Units.largeSpacing * 2 + horizontalAlignment: Text.AlignRight + + // use i18nd in config QML, as the default textdomain is set to that of the config container + text: i18nd("plasma_wallpaper_org.kde.plasma.%{APPNAMELC}", "Text to Display:") + } + QQC2.TextField { + id: textField + Layout.fillWidth: true + } + } + + Item { // tighten layout + Layout.fillHeight: true + } +} diff --git a/templates/plasma6-wallpaper/package/contents/ui/main.qml b/templates/plasma6-wallpaper/package/contents/ui/main.qml new file mode 100644 index 0000000..3fb10c3 --- /dev/null +++ b/templates/plasma6-wallpaper/package/contents/ui/main.qml @@ -0,0 +1,24 @@ +/* + SPDX-FileCopyrightText: %{CURRENT_YEAR} %{AUTHOR} <%{EMAIL}> + SPDX-License-Identifier: LGPL-2.1-or-later +*/ + +import QtQuick +import org.kde.plasma.plasmoid +import org.kde.kirigami as Kirigami + +WallpaperItem { + id: root + + Rectangle { + anchors.fill: parent + color: Kirigami.Theme.backgroundColor + } + + Kirigami.Heading { + anchors.centerIn: parent + level: 1 + text: wallpaper.configuration.DisplayText || + i18n("") + } +} diff --git a/templates/plasma6-wallpaper/package/metadata.json b/templates/plasma6-wallpaper/package/metadata.json new file mode 100644 index 0000000..5c4865e --- /dev/null +++ b/templates/plasma6-wallpaper/package/metadata.json @@ -0,0 +1,109 @@ +{ + "KPackageStructure": "Plasma/Wallpaper", + "KPlugin": { + "Authors": [ + { + "Email": "%{EMAIL}", + "Name": "%{AUTHOR}", + "Name[ar]": "%{المؤلف}", + "Name[az]": "%{MÜƏLLİF}", + "Name[be]": "%{AUTHOR}", + "Name[bg]": "%{AUTHOR}", + "Name[ca@valencia]": "%{AUTHOR}", + "Name[ca]": "%{AUTHOR}", + "Name[cs]": "%{AUTHOR}", + "Name[da]": "%{AUTHOR}", + "Name[de]": "%{AUTHOR}", + "Name[el]": "%{AUTHOR}", + "Name[en_GB]": "%{AUTHOR}", + "Name[eo]": "%{AŬTORO}", + "Name[es]": "%{AUTHOR}", + "Name[eu]": "%{AUTHOR}", + "Name[fi]": "%{AUTHOR}", + "Name[fr]": "%{AUTHOR}", + "Name[gl]": "%{AUTHOR}", + "Name[he]": "%{AUTHOR}", + "Name[hu]": "%{AUTHOR}", + "Name[ia]": "%{AUTHOR}", + "Name[id]": "%{AUTHOR}", + "Name[is]": "%{AUTHOR}", + "Name[it]": "%{AUTHOR}", + "Name[ka]": "%{AUTHOR}", + "Name[ko]": "%{AUTHOR}", + "Name[lt]": "%{AUTHOR}", + "Name[lv]": "%{AUTHOR}", + "Name[nl]": "%{AUTHOR}", + "Name[nn]": "%{AUTHOR}", + "Name[pl]": "%{AUTHOR}", + "Name[pt]": "%{AUTHOR}", + "Name[pt_BR]": "%{AUTHOR}", + "Name[ro]": "%{AUTHOR}", + "Name[ru]": "%{AUTHOR}", + "Name[sa]": "%{AUTHOR}", + "Name[sk]": "%{AUTHOR}", + "Name[sl]": "%{AUTHOR}", + "Name[sv]": "%{AUTHOR}", + "Name[ta]": "%{AUTHOR}", + "Name[tr]": "%{AUTHOR}", + "Name[uk]": "%{AUTHOR}", + "Name[vi]": "%{AUTHOR}", + "Name[x-test]": "xx%{AUTHOR}xx", + "Name[zh_CN]": "%{AUTHOR}", + "Name[zh_TW]": "%{AUTHOR}" + } + ], + "Description": "", + "Icon": "plasma", + "Id": "org.kde.plasma.%{APPNAMELC}", + "License": "LGPL-2.1+", + "Name": "%{APPNAME}", + "Name[ar]": "%{اسم_التطبيق}", + "Name[ast]": "%{APPNAME}", + "Name[az]": "%{TƏTBİQ_ADI}", + "Name[be]": "%{APPNAME}", + "Name[bg]": "%{APPNAME}", + "Name[ca@valencia]": "%{APPNAME}", + "Name[ca]": "%{APPNAME}", + "Name[cs]": "%{APPNAME}", + "Name[da]": "%{APPNAME}", + "Name[de]": "%{APPNAME}", + "Name[el]": "%{APPNAME}", + "Name[en_GB]": "%{APPNAME}", + "Name[eo]": "%{APPNAME}", + "Name[es]": "%{APPNAME}", + "Name[eu]": "%{APPNAME}", + "Name[fi]": "%{APPNAME}", + "Name[fr]": "%{APPNAME}", + "Name[gl]": "%{APPNAME}", + "Name[he]": "%{APPNAME}", + "Name[hu]": "%{APPNAME}", + "Name[ia]": "%{APPNAME}", + "Name[id]": "%{APPNAME}", + "Name[is]": "%{APPNAME}", + "Name[it]": "%{APPNAME}", + "Name[ka]": "%{APPNAME}", + "Name[ko]": "%{APPNAME}", + "Name[lt]": "%{APPNAME}", + "Name[lv]": "%{APPNAME}", + "Name[nl]": "%{APPNAME}", + "Name[nn]": "%{APPNAME}", + "Name[pl]": "%{APPNAME}", + "Name[pt]": "%{APPNAME}", + "Name[pt_BR]": "%{APPNAME}", + "Name[ro]": "%{APPNAME}", + "Name[ru]": "%{APPNAME}", + "Name[sa]": "%{APPNAME}", + "Name[sk]": "%{APPNAME}", + "Name[sl]": "%{APPNAME}", + "Name[sv]": "%{APPNAME}", + "Name[ta]": "%{APPNAME}", + "Name[tr]": "%{APPNAME}", + "Name[uk]": "%{APPNAME}", + "Name[vi]": "%{APPNAME}", + "Name[x-test]": "xx%{APPNAME}xx", + "Name[zh_CN]": "%{APPNAME}", + "Name[zh_TW]": "%{APPNAME}", + "Version": "%{VERSION}", + "Website": "https://plasma.kde.org/" + } +} diff --git a/templates/plasma6-wallpaper/plasma6-wallpaper.kdevtemplate b/templates/plasma6-wallpaper/plasma6-wallpaper.kdevtemplate new file mode 100644 index 0000000..3e6f3ae --- /dev/null +++ b/templates/plasma6-wallpaper/plasma6-wallpaper.kdevtemplate @@ -0,0 +1,93 @@ +[General] +Name=Simple Plasma Wallpaper (Qt6) +Name[ar]=خلفيّة بلازما بسيطة (كيوت6) +Name[be]=Простыя шпалеры для Plasma (Qt6) +Name[bg]=Прост тапет на Plasma (Qt6) +Name[ca]=Fons de pantalla senzill del Plasma (Qt6) +Name[ca@valencia]=Fons de pantalla senzill de Plasma (Qt6) +Name[cs]=Jednoduchá tapeta pro prostředí Plasma (Qt6) +Name[da]=Simpelt Plasma-baggrundsbillede (Qt6) +Name[de]=Einfaches Plasma-Hintergrundbild (Qt6) +Name[en_GB]=Simple Plasma Wallpaper (Qt6) +Name[eo]=Simpla Plasma-Tapeto (Qt6) +Name[es]=Fondo de escritorio sencillo para Plasma (Qt6) +Name[eu]=Plasmaren horma-paper xumea (Qt6) +Name[fi]=Yksinkertainen Plasma-taustakuva (Qt6) +Name[fr]=Fond d'écran simple sous Plasma (Qt6) +Name[gl]=Fondo de escritorio de Plasma sinxelo (Qt 6) +Name[he]=תמונת רקע פשוטה לפלזמה (Qt6) +Name[hu]=Egyszerű Plasma háttérkép (Qt6) +Name[ia]=Simple tapete de papiro de Plasma (Qt6) +Name[is]=Simple Plasma Wallpaper (Qt6) +Name[it]=Sfondo semplice di Plasma (Qt6) +Name[ka]=მარტივი Plasma-ის ფონის სურათი (Qt6) +Name[ko]=간단한 Plasma ë°°ê²½ 그림(Qt6) +Name[lt]=Paprastas Plasma darbalaukio fonas (Qt6) +Name[lv]=VienkārÅ¡a „Plasma“ tapete (Qt6) +Name[nb]=Enkelt Plasma-bakgrunnsbilde (Qt6) +Name[nl]=Eenvoudige Plasma-bureaubladachtergrond (Qt6) +Name[nn]=Enkelt Plasma-bakgrunnsbilete (Qt6) +Name[pl]=Prosta Tapeta Plazmy (Qt6) +Name[pt_BR]=Papel de parede simples do Plasma (Qt6) +Name[ro]=Tapet Plasma simplu (Qt6) +Name[ru]=Простые обои для Plasma (Qt6) +Name[sa]=सरल प्लाज्मा दीवार्पत्तिः (Simple Plasma Wallpaper) (Qt6) +Name[sl]=Preprosta slika ozadja za Plasmo (Qt6) +Name[sv]=Enkelt Plasma skrivbordsunderlägg (Qt6) +Name[ta]=எளிய பிளாஸ்மா பின்புலப் படம் (Qt6) +Name[tr]=Basit Plasma Duvar Kağıdı (Qt6) +Name[uk]=Просте тло стільниці Плазми (Qt6) +Name[vi]=Phông nền Plasma đơn giản (Qt6) +Name[x-test]=xxSimple Plasma Wallpaper (Qt6)xx +Name[zh_CN]=Plasma 简易壁纸 (Qt6) +Name[zh_TW]=簡易 Plasma 桌布 (Qt6) +Comment=Simple Plasma Wallpaper template: a Plasma wallpaper template displaying a text +Comment[az]=Sadə Plasma Divar kağızı nümunəsi: Plasma divar kağızı nümunəsi timsalında mətn görünür +Comment[be]=Шаблон простых шпалер Plasma: шаблон шпалер Plasma, які паказвае тэкст +Comment[bg]=Прост шаблон за тапет на Plasma: показване на текст +Comment[ca]=Plantilla de fons de pantalla senzill del Plasma: una plantilla de fons de pantalla del Plasma que mostra un text +Comment[ca@valencia]=Plantilla de fons de pantalla senzill de Plasma: una plantilla de fons de pantalla de Plasma que mostra un text +Comment[da]=Simpel skabelon til Plasma-baggrundsbillede: En skabelon til et Plasma-baggrundsbillede som viser en tekst +Comment[de]=Vorlage für ein einfaches Plasma-Hintergrundbild: Es zeigt einen Text +Comment[en_GB]=Simple Plasma Wallpaper template: a Plasma wallpaper template displaying a text +Comment[eo]=Simpla Plasma Tapeta ŝablono: Plasma Tapeta ŝablono montranta tekston +Comment[es]=Plantilla de fondo de escritorio sencillo para Plasma: una plantilla de fondo de escritorio para Plasma que muestra un texto +Comment[et]=Lihtsa Plasma taustapildi mall: Plasma taustapildi mall, mis kuvab teksti +Comment[eu]=Plasma horma-paper txantiloi xume bat: Plasma horma-paper txantiloi bat testu bat bistaratzen duena +Comment[fi]=Yksinkertainen Plasma-taustakuvamalli, joka näyttää tekstin +Comment[fr]=Modèle de fond d'écran Plasma simple : un modèle de fond d'écran Plasma qui affiche du texte +Comment[gl]=Modelo de fondo de Plasma sinxelo: un modelo de fondo de Plasma que mostra un texto. +Comment[he]=תבנית תמונת רקע פשוטה לפלזמה: תבנית תמונת רקע של פלזמה שמציגה טקסט +Comment[hu]=Szöveget megjelenítő Plasma háttérkép-sablon +Comment[ia]=Ptrono de Simple tapete de papiro de Plasma: un tapete de papiro d Plasma monstrante un texto +Comment[id]=Templat Wallpaper Plasma: sebuah templat wallpaper Plasma yang menampilkan sebuah teks +Comment[is]=Sniðmát fyrir Simple Plasma Wallpaper: Veggfóðurssniðmát fyrir Plasma sem sýnir texta +Comment[it]=Modello di sfondo semplice di Plasma: un modello di sfondo di Plasma che visualizza un testo +Comment[ka]=Plasma-ის მარტივი ფონის შაბლონი: Plasma-ის ფონის შაბლონი, რომელსაც ტექსტი გამოაქვს +Comment[ko]=간단한 Plasma ë°°ê²½ 그림 템플릿: 텍스트를 표시하는 Plasma ë°°ê²½ 그림 템플릿 +Comment[lt]=Paprastas Plasma darbalaukio fono Å¡ablonas: Plasma darbalaukio fono Å¡ablonas, atvaizduojantis tekstą +Comment[lv]=VienkārÅ¡s „Plasma“ tapetes motÄ«vs: „Plasma“ tapetes veidne ar parādÄ«tu tekstu +Comment[nl]=Sjabloon voor eenvoudige Plasma-bureaubladachtergrond: een sjabloon voor het tonen een Plasma-bureaubladachtergrond met een tekst +Comment[nn]=Enkel mal for Plasma-bakgrunnsbilete: Eit Plasma-bakgrunnsbilete med litt tekst +Comment[pl]=Szablon Prostej Tapety Plazmy: tapeta Plazmy wyświetlająca tekst +Comment[pt]=Modelo de Papel de Parede Simples do Plasma: um modelo de papel de parede do Plasma que mostra um texto +Comment[pt_BR]=Modelo de papel de parede simples do Plasma: Um modelo de papel de parede do Plasma mostrando um texto +Comment[ru]=Простой шаблон обоев для Plasma: в качестве обоев показывается текст +Comment[sa]=सरलं प्लाज्मा दीवार्पत्तिः ढांचा: पाठं प्रदर्शयन् एकः प्लाज्मा दीवार्पत्तिः ढांचा +Comment[sk]=Jednoduchá Å¡ablóna Tapety Plasma: Å¡ablóna Tapety Plasma zobrazujúca text +Comment[sl]=Predloga preproste slike ozadja za Plasmo: predloga slike ozadja za Plasmo, ki prikazuje besedilo +Comment[sr]=Шаблон једноставног плазма тапета: тапет који приказује текст +Comment[sr@ijekavian]=Шаблон једноставног плазма тапета: тапет који приказује текст +Comment[sr@ijekavianlatin]=Å ablon jednostavnog plasma tapeta: tapet koji prikazuje tekst +Comment[sr@latin]=Å ablon jednostavnog plasma tapeta: tapet koji prikazuje tekst +Comment[sv]=Enkel mall för Plasma-skrivbordsunderlägg: en mall för ett Plasma-skrivbordsunderlägg som visar en text +Comment[ta]=எளிய பிளாஸ்மா பின்புலப் பட வார்ப்புரு: உரையை மட்டும் காட்டும் ஒரு பிளாஸ்மா பின்புலப் பட வார்ப்புரு +Comment[tg]=Қолиби тасвири заминаи содаи Plasma: Қолиби тасвири заминаи Plasma матнеро нишон медиҳад +Comment[tr]=Basit Plasma Duvar Kağıdı şablonu: Metin görüntüleyen bir Plasma duvar kağıdı şablonu +Comment[uk]=Простий шаблон тла стільниці Плазми: шаблон шпалер, який показує текст +Comment[vi]=Bản mẫu Phông nền Plasma Đơn giản: một bản mẫu phông nền Plasma hiển thị một văn bản +Comment[x-test]=xxSimple Plasma Wallpaper template: a Plasma wallpaper template displaying a textxx +Comment[zh_CN]=Plasma 简易壁纸模板:显示一段文字的 Plasma 壁纸模板 +Comment[zh_TW]=簡易 Plasma 桌布範本:顯示了文字的一個 Plasma 桌布範本 +Category=Plasma/Wallpaper +Icon= diff --git a/templates/qml-plasmoid6-with-qml-extension/CMakeLists.txt b/templates/qml-plasmoid6-with-qml-extension/CMakeLists.txt new file mode 100644 index 0000000..389d90b --- /dev/null +++ b/templates/qml-plasmoid6-with-qml-extension/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.16) + +project(plasma-%{APPNAMELC}) + +find_package(ECM 1.4.0 REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) + +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDECompilerSettings NO_POLICY_SCOPE) +include(FeatureSummary) + +find_package(KF6 REQUIRED COMPONENTS + Plasma + I18n +) + +find_package(Qt6 CONFIG REQUIRED COMPONENTS + Qml + Gui + Core +) + +# plasmoid +# TODO: adapt "org.kde.plasma" here & elsewhere if needed (see README) +plasma_install_package(package org.kde.plasma.%{APPNAMELC}) + +# qml extension plugin +add_subdirectory(plugin) + +feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/templates/qml-plasmoid6-with-qml-extension/LICENSES/LGPL-2.1-or-later.txt b/templates/qml-plasmoid6-with-qml-extension/LICENSES/LGPL-2.1-or-later.txt new file mode 100644 index 0000000..04bb156 --- /dev/null +++ b/templates/qml-plasmoid6-with-qml-extension/LICENSES/LGPL-2.1-or-later.txt @@ -0,0 +1,468 @@ +GNU LESSER GENERAL PUBLIC LICENSE + +Version 2.1, February 1999 + +Copyright (C) 1991, 1999 Free Software Foundation, Inc. + +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts as the +successor of the GNU Library Public License, version 2, hence the version +number 2.1.] + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public Licenses are intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. + +This license, the Lesser General Public License, applies to some specially +designated software packages--typically libraries--of the Free Software Foundation +and other authors who decide to use it. You can use it too, but we suggest +you first think carefully about whether this license or the ordinary General +Public License is the better strategy to use in any particular case, based +on the explanations below. + +When we speak of free software, we are referring to freedom of use, not price. +Our General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you +wish); that you receive source code or can get it if you want it; that you +can change the software and use pieces of it in new free programs; and that +you are informed that you can do these things. + +To protect your rights, we need to make restrictions that forbid distributors +to deny you these rights or to ask you to surrender these rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the library or if you modify it. + +For example, if you distribute copies of the library, whether gratis or for +a fee, you must give the recipients all the rights that we gave you. You must +make sure that they, too, receive or can get the source code. If you link +other code with the library, you must provide complete object files to the +recipients, so that they can relink them with the library after making changes +to the library and recompiling it. And you must show them these terms so they +know their rights. + +We protect your rights with a two-step method: (1) we copyright the library, +and (2) we offer you this license, which gives you legal permission to copy, +distribute and/or modify the library. + +To protect each distributor, we want to make it very clear that there is no +warranty for the free library. Also, if the library is modified by someone +else and passed on, the recipients should know that what they have is not +the original version, so that the original author's reputation will not be +affected by problems that might be introduced by others. + +Finally, software patents pose a constant threat to the existence of any free +program. We wish to make sure that a company cannot effectively restrict the +users of a free program by obtaining a restrictive license from a patent holder. +Therefore, we insist that any patent license obtained for a version of the +library must be consistent with the full freedom of use specified in this +license. + +Most GNU software, including some libraries, is covered by the ordinary GNU +General Public License. This license, the GNU Lesser General Public License, +applies to certain designated libraries, and is quite different from the ordinary +General Public License. We use this license for certain libraries in order +to permit linking those libraries into non-free programs. + +When a program is linked with a library, whether statically or using a shared +library, the combination of the two is legally speaking a combined work, a +derivative of the original library. The ordinary General Public License therefore +permits such linking only if the entire combination fits its criteria of freedom. +The Lesser General Public License permits more lax criteria for linking other +code with the library. + +We call this license the "Lesser" General Public License because it does Less +to protect the user's freedom than the ordinary General Public License. It +also provides other free software developers Less of an advantage over competing +non-free programs. These disadvantages are the reason we use the ordinary +General Public License for many libraries. However, the Lesser license provides +advantages in certain special circumstances. + +For example, on rare occasions, there may be a special need to encourage the +widest possible use of a certain library, so that it becomes a de-facto standard. +To achieve this, non-free programs must be allowed to use the library. A more +frequent case is that a free library does the same job as widely used non-free +libraries. In this case, there is little to gain by limiting the free library +to free software only, so we use the Lesser General Public License. + +In other cases, permission to use a particular library in non-free programs +enables a greater number of people to use a large body of free software. For +example, permission to use the GNU C Library in non-free programs enables +many more people to use the whole GNU operating system, as well as its variant, +the GNU/Linux operating system. + +Although the Lesser General Public License is Less protective of the users' +freedom, it does ensure that the user of a program that is linked with the +Library has the freedom and the wherewithal to run that program using a modified +version of the Library. + +The precise terms and conditions for copying, distribution and modification +follow. Pay close attention to the difference between a "work based on the +library" and a "work that uses the library". The former contains code derived +from the library, whereas the latter must be combined with the library in +order to run. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library or other program +which contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Lesser General +Public License (also called "this License"). Each licensee is addressed as +"you". + +A "library" means a collection of software functions and/or data prepared +so as to be conveniently linked with application programs (which use some +of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work which has +been distributed under these terms. A "work based on the Library" means either +the Library or any derivative work under copyright law: that is to say, a +work containing the Library or a portion of it, either verbatim or with modifications +and/or translated straightforwardly into another language. (Hereinafter, translation +is included without limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for making modifications +to it. For a library, complete source code means all the source code for all +modules it contains, plus any associated interface definition files, plus +the scripts used to control compilation and installation of the library. + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running a program +using the Library is not restricted, and output from such a program is covered +only if its contents constitute a work based on the Library (independent of +the use of the Library in a tool for writing it). Whether that is true depends +on what the Library does and what the program that uses the Library does. + +1. You may copy and distribute verbatim copies of the Library's complete source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and disclaimer +of warranty; keep intact all the notices that refer to this License and to +the absence of any warranty; and distribute a copy of this License along with +the Library. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Library or any portion of it, +thus forming a work based on the Library, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + + a) The modified work must itself be a software library. + +b) You must cause the files modified to carry prominent notices stating that +you changed the files and the date of any change. + +c) You must cause the whole of the work to be licensed at no charge to all +third parties under the terms of this License. + +d) If a facility in the modified Library refers to a function or a table of +data to be supplied by an application program that uses the facility, other +than as an argument passed when the facility is invoked, then you must make +a good faith effort to ensure that, in the event an application does not supply +such function or table, the facility still operates, and performs whatever +part of its purpose remains meaningful. + +(For example, a function in a library to compute square roots has a purpose +that is entirely well-defined independent of the application. Therefore, Subsection +2d requires that any application-supplied function or table used by this function +must be optional: if the application does not supply it, the square root function +must still compute square roots.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Library, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Library. + +In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may opt to apply the terms of the ordinary GNU General Public License +instead of this License to a given copy of the Library. To do this, you must +alter all the notices that refer to this License, so that they refer to the +ordinary GNU General Public License, version 2, instead of to this License. +(If a newer version than version 2 of the ordinary GNU General Public License +has appeared, then you can specify that version instead if you wish.) Do not +make any other change in these notices. + +Once this change is made in a given copy, it is irreversible for that copy, +so the ordinary GNU General Public License applies to all subsequent copies +and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of the Library +into a program that is not a library. + +4. You may copy and distribute the Library (or a portion or derivative of +it, under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you accompany it with the complete corresponding +machine-readable source code, which must be distributed under the terms of +Sections 1 and 2 above on a medium customarily used for software interchange. + +If distribution of object code is made by offering access to copy from a designated +place, then offering equivalent access to copy the source code from the same +place satisfies the requirement to distribute the source code, even though +third parties are not compelled to copy the source along with the object code. + +5. A program that contains no derivative of any portion of the Library, but +is designed to work with the Library by being compiled or linked with it, +is called a "work that uses the Library". Such a work, in isolation, is not +a derivative work of the Library, and therefore falls outside the scope of +this License. + +However, linking a "work that uses the Library" with the Library creates an +executable that is a derivative of the Library (because it contains portions +of the Library), rather than a "work that uses the library". The executable +is therefore covered by this License. Section 6 states terms for distribution +of such executables. + +When a "work that uses the Library" uses material from a header file that +is part of the Library, the object code for the work may be a derivative work +of the Library even though the source code is not. Whether this is true is +especially significant if the work can be linked without the Library, or if +the work is itself a library. The threshold for this to be true is not precisely +defined by law. + +If such an object file uses only numerical parameters, data structure layouts +and accessors, and small macros and small inline functions (ten lines or less +in length), then the use of the object file is unrestricted, regardless of +whether it is legally a derivative work. (Executables containing this object +code plus portions of the Library will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may distribute +the object code for the work under the terms of Section 6. Any executables +containing that work also fall under Section 6, whether or not they are linked +directly with the Library itself. + +6. As an exception to the Sections above, you may also combine or link a "work +that uses the Library" with the Library to produce a work containing portions +of the Library, and distribute that work under terms of your choice, provided +that the terms permit modification of the work for the customer's own use +and reverse engineering for debugging such modifications. + +You must give prominent notice with each copy of the work that the Library +is used in it and that the Library and its use are covered by this License. +You must supply a copy of this License. If the work during execution displays +copyright notices, you must include the copyright notice for the Library among +them, as well as a reference directing the user to the copy of this License. +Also, you must do one of these things: + +a) Accompany the work with the complete corresponding machine-readable source +code for the Library including whatever changes were used in the work (which +must be distributed under Sections 1 and 2 above); and, if the work is an +executable linked with the Library, with the complete machine-readable "work +that uses the Library", as object code and/or source code, so that the user +can modify the Library and then relink to produce a modified executable containing +the modified Library. (It is understood that the user who changes the contents +of definitions files in the Library will not necessarily be able to recompile +the application to use the modified definitions.) + +b) Use a suitable shared library mechanism for linking with the Library. A +suitable mechanism is one that (1) uses at run time a copy of the library +already present on the user's computer system, rather than copying library +functions into the executable, and (2) will operate properly with a modified +version of the library, if the user installs one, as long as the modified +version is interface-compatible with the version that the work was made with. + +c) Accompany the work with a written offer, valid for at least three years, +to give the same user the materials specified in Subsection 6a, above, for +a charge no more than the cost of performing this distribution. + +d) If distribution of the work is made by offering access to copy from a designated +place, offer equivalent access to copy the above specified materials from +the same place. + +e) Verify that the user has already received a copy of these materials or +that you have already sent this user a copy. + +For an executable, the required form of the "work that uses the Library" must +include any data and utility programs needed for reproducing the executable +from it. However, as a special exception, the materials to be distributed +need not include anything that is normally distributed (in either source or +binary form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component itself +accompanies the executable. + +It may happen that this requirement contradicts the license restrictions of +other proprietary libraries that do not normally accompany the operating system. +Such a contradiction means you cannot use both them and the Library together +in an executable that you distribute. + +7. You may place library facilities that are a work based on the Library side-by-side +in a single library together with other library facilities not covered by +this License, and distribute such a combined library, provided that the separate +distribution of the work based on the Library and of the other library facilities +is otherwise permitted, and provided that you do these two things: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities. This must be distributed +under the terms of the Sections above. + +b) Give prominent notice with the combined library of the fact that part of +it is a work based on the Library, and explaining where to find the accompanying +uncombined form of the same work. + +8. You may not copy, modify, sublicense, link with, or distribute the Library +except as expressly provided under this License. Any attempt otherwise to +copy, modify, sublicense, link with, or distribute the Library is void, and +will automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +9. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Library or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Library +(or any work based on the Library), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +10. Each time you redistribute the Library (or any work based on the Library), +the recipient automatically receives a license from the original licensor +to copy, distribute, link with or modify the Library subject to these terms +and conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties with this License. + +11. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of +this License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Library at all. For example, if a +patent license would not permit royalty-free redistribution of the Library +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +12. If the distribution and/or use of the Library is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Library under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +13. The Free Software Foundation may publish revised and/or new versions of +the Lesser General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Library specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Library does not specify a license version number, you may choose any version +ever published by the Free Software Foundation. + +14. If you wish to incorporate parts of the Library into other free programs +whose distribution conditions are incompatible with these, write to the author +to ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make exceptions +for this. Our decision will be guided by the two goals of preserving the free +status of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA +OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest possible +use to the public, we recommend making it free software that everyone can +redistribute and change. You can do so by permitting redistribution under +these terms (or, alternatively, under the terms of the ordinary General Public +License). + +To apply these terms, attach the following notices to the library. It is safest +to attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the "copyright" +line and a pointer to where the full notice is found. + + + +Copyright (C) + +This library is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free +Software Foundation; either version 2.1 of the License, or (at your option) +any later version. + +This library 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 Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with this library; if not, write to the Free Software Foundation, Inc., 51 +Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the library, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in + +the library `Frob' (a library for tweaking knobs) written + +by James Random Hacker. + +< signature of Ty Coon > , 1 April 1990 + +Ty Coon, President of Vice + +That's all there is to it! diff --git a/templates/qml-plasmoid6-with-qml-extension/Messages.sh b/templates/qml-plasmoid6-with-qml-extension/Messages.sh new file mode 100644 index 0000000..a8a1548 --- /dev/null +++ b/templates/qml-plasmoid6-with-qml-extension/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT `find . -name \*.qml -o -name \*.cpp` -o $podir/plasma_applet_org.kde.plasma.%{APPNAMELC}.pot diff --git a/templates/qml-plasmoid6-with-qml-extension/README b/templates/qml-plasmoid6-with-qml-extension/README new file mode 100644 index 0000000..8d1e5d7 --- /dev/null +++ b/templates/qml-plasmoid6-with-qml-extension/README @@ -0,0 +1,46 @@ +Plasma Applet Template +---------------------- + +-- Namespace adaption -- + +Each Plasma plugin has a unique identifier, which is also used to find related +resources (like the translation catalogs). +To avoid naming collisions, Plasma plugins use a reverse domain name notation +for that identifier: + +* org.kde.plasma.* - plugins coming from Plasma modules +* org.kde.* - plugins coming from other software from KDE +* $(my.domain).* - plugins of your 3rd-party + +The generated code uses the "org.kde.plasma" namespace for the plugin identifier. +As this namespace is reserved for use by plugins part of Plasma modules, you will +need to adapt this namespace if you are writing a plugin which is not intended to +end up in the Plasma modules. + + +-- Build instructions -- + +cd /where/your/applet/is/generated +mkdir build +cd build +cmake -DCMAKE_INSTALL_PREFIX=MYPREFIX .. +make +make install + +(MYPREFIX is where you install your Plasma setup, replace it accordingly) + +Restart plasma to load the applet +(in a terminal type: +kquitapp plasmashell +and then +plasmashell) + +or view it with +plasmoidviewer -a YourAppletName + +-- Tutorials and resources -- +The explanation of the QML part of the template +https://techbase.kde.org/Development/Tutorials/Plasma5/QML2/GettingStarted + +Plasma QML API explained +https://techbase.kde.org/Development/Tutorials/Plasma2/QML2/API diff --git a/templates/qml-plasmoid6-with-qml-extension/package/contents/ui/main.qml b/templates/qml-plasmoid6-with-qml-extension/package/contents/ui/main.qml new file mode 100644 index 0000000..a876954 --- /dev/null +++ b/templates/qml-plasmoid6-with-qml-extension/package/contents/ui/main.qml @@ -0,0 +1,21 @@ +/* + SPDX-FileCopyrightText: %{CURRENT_YEAR} %{AUTHOR} <%{EMAIL}> + SPDX-License-Identifier: LGPL-2.1-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.plasmoid +import org.kde.plasma.components as PlasmaComponents + +import org.kde.plasma.private.%{APPNAMELC} 1.0 + +Item { + Plasmoid.fullRepresentation: ColumnLayout { + anchors.fill: parent + PlasmaComponents.Label { + Layout.alignment: Qt.AlignCenter + text: HelloWorld.text + } + } +} diff --git a/templates/qml-plasmoid6-with-qml-extension/package/metadata.json b/templates/qml-plasmoid6-with-qml-extension/package/metadata.json new file mode 100644 index 0000000..b13d49d --- /dev/null +++ b/templates/qml-plasmoid6-with-qml-extension/package/metadata.json @@ -0,0 +1,153 @@ +{ + "KPackageStructure": "Plasma/Applet", + "KPlugin": { + "Authors": [ + { + "Email": "%{EMAIL}", + "Name": "%{AUTHOR}", + "Name[ar]": "%{المؤلف}", + "Name[az]": "%{MÜƏLLİF}", + "Name[be]": "%{AUTHOR}", + "Name[bg]": "%{AUTHOR}", + "Name[ca@valencia]": "%{AUTHOR}", + "Name[ca]": "%{AUTHOR}", + "Name[cs]": "%{AUTHOR}", + "Name[da]": "%{AUTHOR}", + "Name[de]": "%{AUTHOR}", + "Name[el]": "%{AUTHOR}", + "Name[en_GB]": "%{AUTHOR}", + "Name[eo]": "%{AŬTORO}", + "Name[es]": "%{AUTHOR}", + "Name[eu]": "%{AUTHOR}", + "Name[fi]": "%{AUTHOR}", + "Name[fr]": "%{AUTHOR}", + "Name[gl]": "%{AUTHOR}", + "Name[he]": "%{AUTHOR}", + "Name[hu]": "%{AUTHOR}", + "Name[ia]": "%{AUTHOR}", + "Name[id]": "%{AUTHOR}", + "Name[is]": "%{AUTHOR}", + "Name[it]": "%{AUTHOR}", + "Name[ka]": "%{AUTHOR}", + "Name[ko]": "%{AUTHOR}", + "Name[lt]": "%{AUTHOR}", + "Name[lv]": "%{AUTHOR}", + "Name[nl]": "%{AUTHOR}", + "Name[nn]": "%{AUTHOR}", + "Name[pl]": "%{AUTHOR}", + "Name[pt]": "%{AUTHOR}", + "Name[pt_BR]": "%{AUTHOR}", + "Name[ro]": "%{AUTHOR}", + "Name[ru]": "%{AUTHOR}", + "Name[sa]": "%{AUTHOR}", + "Name[sk]": "%{AUTHOR}", + "Name[sl]": "%{AUTHOR}", + "Name[sv]": "%{AUTHOR}", + "Name[ta]": "%{AUTHOR}", + "Name[tr]": "%{AUTHOR}", + "Name[uk]": "%{AUTHOR}", + "Name[vi]": "%{AUTHOR}", + "Name[x-test]": "xx%{AUTHOR}xx", + "Name[zh_CN]": "%{AUTHOR}", + "Name[zh_TW]": "%{AUTHOR}" + } + ], + "Category": "Utilities", + "Description": "what your app does in a few words", + "Description[az]": "Bu proqramın nə işə yaradığı haqqında bir neçə söz", + "Description[be]": "кароткае апісанне працы вашай праграмы", + "Description[bg]": "какво прави вашето приложение с няколко думи", + "Description[ca@valencia]": "Què fa esta aplicació en poques paraules", + "Description[ca]": "Què fa aquesta aplicació en poques paraules", + "Description[da]": "hvad dit program, helt kort", + "Description[de]": "Was Ihre Anwendung macht (kurze Beschreibung)", + "Description[el]": "τι κάνει η εφαρμογή σας με λίγες λέξεις", + "Description[en_GB]": "what your app does in a few words", + "Description[eo]": "kion via aplikaĵo faras en kelkaj vortoj", + "Description[es]": "Lo que hace su aplicación en pocas palabras", + "Description[eu]": "zure aplikazioak egiten duena hitz gutxitan", + "Description[fi]": "muutama sana siitä, mitä sovelmasi tekee", + "Description[fr]": "ce que votre application fait en quelques mots", + "Description[gl]": "O que fai a aplicación, en poucas palabras.", + "Description[he]": "מה עושה היישום שלך במספר מילים", + "Description[hu]": "Írja le néhány szóban, mit csinál az alkalmazása", + "Description[ia]": "cosa tu app face in pauc parolas", + "Description[id]": "apa yang dilakukan aplikasi Anda dalam beberapa kata", + "Description[is]": "hvað forritið þitt gerir í fáum orðum", + "Description[it]": "Cosa fa la tua applicazione in poche parole", + "Description[ka]": "რამდენიმე სიტყვით, რას აკეთებს თქვენი აპლიკაცია", + "Description[ko]": "앱이 하는 일에 대한 간단한 설명", + "Description[lt]": "keliais žodžiais, ką daro jÅ«sų programa", + "Description[lv]": "uzrakstiet dažos vārdos, ko jÅ«su programma dara", + "Description[nl]": "wat uw app doet in een paar woorden", + "Description[nn]": "nokre fÃ¥ ord om kva programmet gjer", + "Description[pl]": "w kilku słowach opis co robi twój program", + "Description[pt]": "o que faz a sua aplicação em poucas palavras", + "Description[pt_BR]": "o que seu aplicativo faz em poucas palavras", + "Description[ro]": "ce face aplicația, în câteva cuvinte", + "Description[ru]": "Несколько слов о том, что делает ваша программа", + "Description[sa]": "भवतः अनुप्रयोगः कतिपयेषु शब्देषु किं करोति", + "Description[sk]": "čo vaÅ¡a aplikácia robí v niekoľkých slovách", + "Description[sl]": "v parih besedah kar počne vaÅ¡a aplikacija", + "Description[sv]": "vad programmet gör med nÃ¥gra fÃ¥ ord", + "Description[tr]": "uygulamanızı birkaç sözcükle anlatın", + "Description[uk]": "призначення вашої програми у декількох словах", + "Description[vi]": "dùng vài từ để mô tả ứng dụng cá»§a bạn làm việc gì", + "Description[x-test]": "xxwhat your app does in a few wordsxx", + "Description[zh_CN]": "用一个短句概括您的小程序的功能", + "Description[zh_TW]": "幾個詞內簡述您的應用程式所做的事", + "EnabledByDefault": true, + "Icon": "applications-system", + "Id": "org.kde.plasma.%{APPNAMELC}", + "License": "LGPL-2.1+", + "Name": "%{APPNAME}", + "Name[ar]": "%{اسم_التطبيق}", + "Name[ast]": "%{APPNAME}", + "Name[az]": "%{TƏTBİQ_ADI}", + "Name[be]": "%{APPNAME}", + "Name[bg]": "%{APPNAME}", + "Name[ca@valencia]": "%{APPNAME}", + "Name[ca]": "%{APPNAME}", + "Name[cs]": "%{APPNAME}", + "Name[da]": "%{APPNAME}", + "Name[de]": "%{APPNAME}", + "Name[el]": "%{APPNAME}", + "Name[en_GB]": "%{APPNAME}", + "Name[eo]": "%{APPNAME}", + "Name[es]": "%{APPNAME}", + "Name[eu]": "%{APPNAME}", + "Name[fi]": "%{APPNAME}", + "Name[fr]": "%{APPNAME}", + "Name[gl]": "%{APPNAME}", + "Name[he]": "%{APPNAME}", + "Name[hu]": "%{APPNAME}", + "Name[ia]": "%{APPNAME}", + "Name[id]": "%{APPNAME}", + "Name[is]": "%{APPNAME}", + "Name[it]": "%{APPNAME}", + "Name[ka]": "%{APPNAME}", + "Name[ko]": "%{APPNAME}", + "Name[lt]": "%{APPNAME}", + "Name[lv]": "%{APPNAME}", + "Name[nl]": "%{APPNAME}", + "Name[nn]": "%{APPNAME}", + "Name[pl]": "%{APPNAME}", + "Name[pt]": "%{APPNAME}", + "Name[pt_BR]": "%{APPNAME}", + "Name[ro]": "%{APPNAME}", + "Name[ru]": "%{APPNAME}", + "Name[sa]": "%{APPNAME}", + "Name[sk]": "%{APPNAME}", + "Name[sl]": "%{APPNAME}", + "Name[sv]": "%{APPNAME}", + "Name[ta]": "%{APPNAME}", + "Name[tr]": "%{APPNAME}", + "Name[uk]": "%{APPNAME}", + "Name[vi]": "%{APPNAME}", + "Name[x-test]": "xx%{APPNAME}xx", + "Name[zh_CN]": "%{APPNAME}", + "Name[zh_TW]": "%{APPNAME}", + "Version": "1.0", + "Website": "https://plasma.kde.org/" + } +} diff --git a/templates/qml-plasmoid6-with-qml-extension/plugin/%{APPNAMELC}plugin.cpp b/templates/qml-plasmoid6-with-qml-extension/plugin/%{APPNAMELC}plugin.cpp new file mode 100644 index 0000000..f885f94 --- /dev/null +++ b/templates/qml-plasmoid6-with-qml-extension/plugin/%{APPNAMELC}plugin.cpp @@ -0,0 +1,32 @@ +/* + SPDX-FileCopyrightText: %{CURRENT_YEAR} %{AUTHOR} <%{EMAIL}> + SPDX-License-Identifier: LGPL-2.1-or-later +*/ + +#include "%{APPNAMELC}plugin.h" + +// KF +#include +// Qt +#include +#include +#include + +static QJSValue singletonTypeExampleProvider(QQmlEngine* engine, QJSEngine* scriptEngine) +{ + Q_UNUSED(engine) + + QJSValue helloWorld = scriptEngine->newObject(); + helloWorld.setProperty("text", i18n("Hello world!")); + return helloWorld; +} + + +void %{APPNAME}Plugin::registerTypes(const char* uri) +{ + Q_ASSERT(uri == QLatin1String("org.kde.plasma.private.%{APPNAMELC}")); + + qmlRegisterSingletonType(uri, 1, 0, "HelloWorld", singletonTypeExampleProvider); +} + +#include "moc_%{APPNAMELC}plugin.cpp" diff --git a/templates/qml-plasmoid6-with-qml-extension/plugin/%{APPNAMELC}plugin.h b/templates/qml-plasmoid6-with-qml-extension/plugin/%{APPNAMELC}plugin.h new file mode 100644 index 0000000..c87bd45 --- /dev/null +++ b/templates/qml-plasmoid6-with-qml-extension/plugin/%{APPNAMELC}plugin.h @@ -0,0 +1,20 @@ +/* + SPDX-FileCopyrightText: %{CURRENT_YEAR} %{AUTHOR} <%{EMAIL}> + SPDX-License-Identifier: LGPL-2.1-or-later +*/ + +#ifndef %{APPNAMEUC}PLUGIN_H +#define %{APPNAMEUC}PLUGIN_H + +#include + +class %{APPNAME}Plugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") + +public: + void registerTypes(const char *uri) override; +}; + +#endif // %{APPNAMEUC}PLUGIN_H diff --git a/templates/qml-plasmoid6-with-qml-extension/plugin/CMakeLists.txt b/templates/qml-plasmoid6-with-qml-extension/plugin/CMakeLists.txt new file mode 100644 index 0000000..2f3b659 --- /dev/null +++ b/templates/qml-plasmoid6-with-qml-extension/plugin/CMakeLists.txt @@ -0,0 +1,11 @@ +add_definitions(-DTRANSLATION_DOMAIN=\"plasma_applet_org.kde.plasma.%{APPNAMELC}\") + +add_library(%{APPNAMELC}plugin SHARED %{APPNAMELC}plugin.cpp) + +target_link_libraries(%{APPNAMELC}plugin + KF6::I18n + Qt6::Gui + Qt6::Qml +) +install(TARGETS %{APPNAMELC}plugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/private/%{APPNAMELC}) +install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/private/%{APPNAMELC}) diff --git a/templates/qml-plasmoid6-with-qml-extension/plugin/qmldir b/templates/qml-plasmoid6-with-qml-extension/plugin/qmldir new file mode 100644 index 0000000..e549fc7 --- /dev/null +++ b/templates/qml-plasmoid6-with-qml-extension/plugin/qmldir @@ -0,0 +1,2 @@ +module org.kde.plasma.private.%{APPNAMELC} +plugin %{APPNAMELC}plugin diff --git a/templates/qml-plasmoid6-with-qml-extension/qml-plasmoid6-with-qml-extension.kdevtemplate b/templates/qml-plasmoid6-with-qml-extension/qml-plasmoid6-with-qml-extension.kdevtemplate new file mode 100644 index 0000000..d271697 --- /dev/null +++ b/templates/qml-plasmoid6-with-qml-extension/qml-plasmoid6-with-qml-extension.kdevtemplate @@ -0,0 +1,89 @@ +[General] +Name=Plasma QML Applet with QML extension (Qt6) +Name[ar]=بريمج بلازما ب‍QML (كيوت6) +Name[be]=Аплет QML для Plasma з пашырэннем QML (Qt6) +Name[bg]=QML аплет на Plasma с QML разширение (Qt6) +Name[ca]=Miniaplicació QML del Plasma amb una extensió QML (Qt6) +Name[ca@valencia]=Miniaplicació en QML de Plasma amb una extensió en QML (Qt6) +Name[cs]=Aplet QML Plasma s rozšířením QML (Qt6) +Name[da]=Plasma QML-applet med QML-udvidelse (Qt6) +Name[de]=Plasma-QML-Miniprogramm mit QML-Erweiterung (Qt6) +Name[en_GB]=Plasma QML Applet with QML extension (Qt6) +Name[eo]=Plasma QML-apleto kun QML-etendo (Qt6) +Name[es]=Miniaplicación en QML para Plasma con extensión QML (Qt6) +Name[eu]=Plasma QML aplikaziotxoa QML hedapenarekin (Qt6) +Name[fi]=Plasman QML-sovelma QML-laajennuksella (Qt6) +Name[fr]=Applet « QML » pour Plasma avec extension QML (Qt6) +Name[gl]=Miniaplicativo QML para Plasma con extensión de QML (Qt 6) +Name[he]=יישומונית QML לפלזמה עם הרחבת QML‏ (Qt6) +Name[hu]=Plasma QML kisalkalmazás QML bővítménnyel (Qt6) +Name[ia]=Applet QML de Plasma con extension QML (Qt6) +Name[is]=Plasma QML smáforrit með QML-viðauka (Qt6) +Name[it]=Applet QML di Plasma con estensione QML (Qt6) +Name[ka]=Plasma-ის QML აპლეტი QML გაფართოებით (Qt6) +Name[ko]=QML 확장을 사용하는 Plasma QML 애플릿(Qt6) +Name[lt]=Plasma QML programėlė su QML plėtiniu (Qt6) +Name[lv]=„Plasma“ QML sÄ«klietotne ar QML paplaÅ¡inājumu (Qt6) +Name[nl]=Plasma QML-applet met QML-extensie (Qt6) +Name[nn]=Plasma QML-element med QML-utviding (Qt6) +Name[pl]=Aplet QML Plazmy z rozszerzeniami QML (Qt6) +Name[pt_BR]=Miniaplicativo QML do Plasma com extensão QML (Qt6) +Name[ru]=Виджет Plasma на QML с расширением для QML (Qt6) +Name[sa]=QML विस्तारयुक्तः Plasma QML Applet (Qt6) +Name[sl]=Plasma aplet v QML z razÅ¡iritvijo QML (Qt6) +Name[sv]=Plasma QML-miniprogram med QML-utökning (Qt6) +Name[tr]=QML uzantısıyla ile Plasma QML Uygulamacığı (Qt6) +Name[uk]=Аплет Плазми мовою QML із розширенням QML (Qt6) +Name[vi]=Tiểu ứng dụng QML cá»§a Plasma với phần mở rộng QML (Qt6) +Name[x-test]=xxPlasma QML Applet with QML extension (Qt6)xx +Name[zh_CN]=带有 QML 扩展的 Plasma QML 小程序 (Qt6) +Name[zh_TW]=含有 QML 延伸元件的 Plasma QML 小程式 (Qt6) +Comment=A template for a Plasma applet which uses custom API provided by an own QML extension plugin +Comment[az]=QML əlavəsi kimi təqdim edilən öz APİ -sini istifadə edən Plasma üçün divar kağızı nümunələri +Comment[be]=Шаблон аплета для Plasma, які выкарыстоўвае уласны API з дапамогай ўласнай убудовы пашырэння QML +Comment[bg]=Шаблон за аплет на Plasma, който използва потребителски API, предоставен от собствена QML приставка на разширение +Comment[ca]=Una plantilla per a una miniaplicació Plasma que usa una API personalitzada proporcionada per un connector propi d'una extensió en QML +Comment[ca@valencia]=Una plantilla per a una miniaplicació Plasma que utilitza una API personalitzada proporcionada per un connector propi d'una extensió en QML +Comment[da]=En skabelon til en Plasma-applet som bruger tilpasset API leveret af ens eget QML-udvidelsesplugin +Comment[de]=Vorlage für ein Plasma-Miniprogramm, das ein eigenes QML-Erweiterungsmodul verwendet. +Comment[en_GB]=A template for a Plasma applet which uses custom API provided by an own QML extension plugin +Comment[eo]=Ŝablono por Plasma apleto kiu uzas propran API provizitan de propra QML-etenda kromaĵo +Comment[es]=Una plantilla para una miniaplicación de Plasma que usa la API común proporcionada por un complemento de extensión QML propio +Comment[et]=Plasma apleti mall, mis kasutab meie oma QML-i laiendusplugina kohandatud API-t +Comment[eu]=Plasma aplikaziotxo baterako txantiloi bat, QML hedapen plugin propio baten API pertsonalizatu bat erabiltzen duena +Comment[fi]=Plasma-sovelman malli, joka käyttää oman QML-laajennusliitännäisen tarjoamaa mukautettua APIa +Comment[fr]=Un modèle d'applet Plasma utilisant une API personnalisée fournie par son propre module externe d'extension QML +Comment[gl]=Un modelo para un trebello de Plasma que usa unha API personalizada fornecida por un complemento de extensión de QML de seu. +Comment[he]=תבנית ליישומונית פלזמה שמשתמשת ב־API מותאם שמסופק על ידי תוספת הרחבת QML עצמית +Comment[hu]=Saját, QML bővítmény által biztosított API-t használó Plasma kisalkalmazás-sablon +Comment[ia]=Un patrono per un applet de Plasma que usa API personalisate per un proprie plugin de extension QML +Comment[id]=Sebuah templat untuk applet Plasma yang menggunakan kustom yang disediakan API oleh plugin ekstensi QML sendiri +Comment[is]=Sniðmát fyrir Plasma smáforrit sem notar sérsniðið forritunarviðmót (API) sem fengið er frá eigin QML-viðbót +Comment[it]=Un modello per un'applet di Plasma che utilizza API personalizzate fornite da una propria estensione QML +Comment[ka]=Plasma-ის აპლეტის ნიმუში, რომელიც ხელით განსაზღვრულ API-ს იყენებს, რომელიც მისი საკუთარი QML-ის გაფართოების დამატების მიერ მოეწოდება +Comment[ko]=QML 확장 플러그인이 추가로 제공하는 API를 사용하는 Plasma 애플릿 템플릿 +Comment[lt]=Å ablonas, skirtas Plasma programėlei, naudojančiai tinkintą API, kurį teikia nuosavas QML plėtinio įskiepis +Comment[lv]=„Plasma“ sÄ«klietotnes veidne, kas izmanto pielāgotu API, ko nodroÅ¡ina paÅ¡as QML paplaÅ¡inājuma spraudnis +Comment[nl]=Een sjabloon voor een Plasma-applet die aangepaste API gebruikt geleverd door een eigen QML-extensie-plug-in +Comment[nn]=MAl for Plasma-element som brukar eit eige API som kjem frÃ¥ eit programtillegg for ei QML-utviding +Comment[pl]=Szablon dla apletu Plazmy, który używa własnego API dostarczonego przez własną wtyczkę rozszerzeń QML +Comment[pt]=Um modelo para uma 'applet' do Plasma que usa uma API personalizada oferecida por um 'plugin' de extensão em QML +Comment[pt_BR]=Um modelo para um miniaplicativo Plasma que usa API personalizada fornecida por um plugin de extensão QML próprio +Comment[ru]=Шаблон виджета Plasma, использующий собственный API, реализованный как расширение для QML +Comment[sa]=Plasma applet कृते एकः ढांचा यः स्वस्य QML विस्तारप्लगिन् द्वारा प्रदत्तस्य अनुकूलनीयः API इत्यस्य उपयोगं करोति +Comment[sk]=Å ablóna na na Plasma applet používajúci vlatné API poskytované vlastným QML rozšírením +Comment[sl]=Predloga za aplet Plasme, ki uporablja API po meri, ponujen s strani lastnega razÅ¡iritvenega vstavka QML +Comment[sr]=Шаблон за плазма аплет који користи посебан АПИ дат сопственим КуМЛ прикључком за проширења +Comment[sr@ijekavian]=Шаблон за плазма аплет који користи посебан АПИ дат сопственим КуМЛ прикључком за проширења +Comment[sr@ijekavianlatin]=Å ablon za plasma aplet koji koristi poseban API dat sopstvenim QML priključkom za proÅ¡irenja +Comment[sr@latin]=Å ablon za plasma aplet koji koristi poseban API dat sopstvenim QML priključkom za proÅ¡irenja +Comment[sv]=En mall för ett Plasma-miniprogram som använder ett anpassat programmeringsgränssnitt tillhandahÃ¥llet av en egen QML-utökningsmodul +Comment[tg]=Қолиб барои зербарномаи Plasma, ки дар асоси васлкунаки васеъшавии QML низоми API-и фармоиширо истифода мебарад +Comment[tr]=Kendi QML eklentisi için sağlanan özel bir API kullanan Plasma uygulamacığı için bir şablon +Comment[uk]=Шаблон для аплету Плазми, у якому використовується нетиповий програмний інтерфейс, що надається власним додатком розширення QML +Comment[vi]=Một bản mẫu tiểu ứng dụng Plasma sá»­ dụng API riêng được cung cấp bởi một phần cài cắm mở rộng QML riêng +Comment[x-test]=xxA template for a Plasma applet which uses custom API provided by an own QML extension pluginxx +Comment[zh_CN]=使用自带 QML 扩展插件 API 的 Plasma 小程序模板 +Comment[zh_TW]=使用由自己的 QML 延伸元件提供的自訂 API 的 Plasma 小程式範本 +Category=Plasma/Plasmoid +Icon=qml-plasmoid6-with-qml-extension.png diff --git a/templates/qml-plasmoid6-with-qml-extension/qml-plasmoid6-with-qml-extension.png b/templates/qml-plasmoid6-with-qml-extension/qml-plasmoid6-with-qml-extension.png new file mode 100644 index 0000000000000000000000000000000000000000..26748f6cf7d22ef003badbca80cb69a61e2d46d2 GIT binary patch literal 35613 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 z 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 N002ovPDHLkV1id(qSXKZ literal 0 HcmV?d00001 diff --git a/templates/qml-plasmoid6/CMakeLists.txt b/templates/qml-plasmoid6/CMakeLists.txt new file mode 100644 index 0000000..ffe0180 --- /dev/null +++ b/templates/qml-plasmoid6/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.16) + +project(plasma-%{APPNAMELC}) + +find_package(ECM 1.4.0 REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) + +find_package(Plasma REQUIRED) + +# TODO: adapt "org.kde.plasma" here & elsewhere if needed (see README) +plasma_install_package(package org.kde.plasma.%{APPNAMELC}) diff --git a/templates/qml-plasmoid6/LICENSES/LGPL-2.1-or-later.txt b/templates/qml-plasmoid6/LICENSES/LGPL-2.1-or-later.txt new file mode 100644 index 0000000..04bb156 --- /dev/null +++ b/templates/qml-plasmoid6/LICENSES/LGPL-2.1-or-later.txt @@ -0,0 +1,468 @@ +GNU LESSER GENERAL PUBLIC LICENSE + +Version 2.1, February 1999 + +Copyright (C) 1991, 1999 Free Software Foundation, Inc. + +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts as the +successor of the GNU Library Public License, version 2, hence the version +number 2.1.] + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public Licenses are intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. + +This license, the Lesser General Public License, applies to some specially +designated software packages--typically libraries--of the Free Software Foundation +and other authors who decide to use it. You can use it too, but we suggest +you first think carefully about whether this license or the ordinary General +Public License is the better strategy to use in any particular case, based +on the explanations below. + +When we speak of free software, we are referring to freedom of use, not price. +Our General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you +wish); that you receive source code or can get it if you want it; that you +can change the software and use pieces of it in new free programs; and that +you are informed that you can do these things. + +To protect your rights, we need to make restrictions that forbid distributors +to deny you these rights or to ask you to surrender these rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the library or if you modify it. + +For example, if you distribute copies of the library, whether gratis or for +a fee, you must give the recipients all the rights that we gave you. You must +make sure that they, too, receive or can get the source code. If you link +other code with the library, you must provide complete object files to the +recipients, so that they can relink them with the library after making changes +to the library and recompiling it. And you must show them these terms so they +know their rights. + +We protect your rights with a two-step method: (1) we copyright the library, +and (2) we offer you this license, which gives you legal permission to copy, +distribute and/or modify the library. + +To protect each distributor, we want to make it very clear that there is no +warranty for the free library. Also, if the library is modified by someone +else and passed on, the recipients should know that what they have is not +the original version, so that the original author's reputation will not be +affected by problems that might be introduced by others. + +Finally, software patents pose a constant threat to the existence of any free +program. We wish to make sure that a company cannot effectively restrict the +users of a free program by obtaining a restrictive license from a patent holder. +Therefore, we insist that any patent license obtained for a version of the +library must be consistent with the full freedom of use specified in this +license. + +Most GNU software, including some libraries, is covered by the ordinary GNU +General Public License. This license, the GNU Lesser General Public License, +applies to certain designated libraries, and is quite different from the ordinary +General Public License. We use this license for certain libraries in order +to permit linking those libraries into non-free programs. + +When a program is linked with a library, whether statically or using a shared +library, the combination of the two is legally speaking a combined work, a +derivative of the original library. The ordinary General Public License therefore +permits such linking only if the entire combination fits its criteria of freedom. +The Lesser General Public License permits more lax criteria for linking other +code with the library. + +We call this license the "Lesser" General Public License because it does Less +to protect the user's freedom than the ordinary General Public License. It +also provides other free software developers Less of an advantage over competing +non-free programs. These disadvantages are the reason we use the ordinary +General Public License for many libraries. However, the Lesser license provides +advantages in certain special circumstances. + +For example, on rare occasions, there may be a special need to encourage the +widest possible use of a certain library, so that it becomes a de-facto standard. +To achieve this, non-free programs must be allowed to use the library. A more +frequent case is that a free library does the same job as widely used non-free +libraries. In this case, there is little to gain by limiting the free library +to free software only, so we use the Lesser General Public License. + +In other cases, permission to use a particular library in non-free programs +enables a greater number of people to use a large body of free software. For +example, permission to use the GNU C Library in non-free programs enables +many more people to use the whole GNU operating system, as well as its variant, +the GNU/Linux operating system. + +Although the Lesser General Public License is Less protective of the users' +freedom, it does ensure that the user of a program that is linked with the +Library has the freedom and the wherewithal to run that program using a modified +version of the Library. + +The precise terms and conditions for copying, distribution and modification +follow. Pay close attention to the difference between a "work based on the +library" and a "work that uses the library". The former contains code derived +from the library, whereas the latter must be combined with the library in +order to run. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library or other program +which contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Lesser General +Public License (also called "this License"). Each licensee is addressed as +"you". + +A "library" means a collection of software functions and/or data prepared +so as to be conveniently linked with application programs (which use some +of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work which has +been distributed under these terms. A "work based on the Library" means either +the Library or any derivative work under copyright law: that is to say, a +work containing the Library or a portion of it, either verbatim or with modifications +and/or translated straightforwardly into another language. (Hereinafter, translation +is included without limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for making modifications +to it. For a library, complete source code means all the source code for all +modules it contains, plus any associated interface definition files, plus +the scripts used to control compilation and installation of the library. + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running a program +using the Library is not restricted, and output from such a program is covered +only if its contents constitute a work based on the Library (independent of +the use of the Library in a tool for writing it). Whether that is true depends +on what the Library does and what the program that uses the Library does. + +1. You may copy and distribute verbatim copies of the Library's complete source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and disclaimer +of warranty; keep intact all the notices that refer to this License and to +the absence of any warranty; and distribute a copy of this License along with +the Library. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Library or any portion of it, +thus forming a work based on the Library, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + + a) The modified work must itself be a software library. + +b) You must cause the files modified to carry prominent notices stating that +you changed the files and the date of any change. + +c) You must cause the whole of the work to be licensed at no charge to all +third parties under the terms of this License. + +d) If a facility in the modified Library refers to a function or a table of +data to be supplied by an application program that uses the facility, other +than as an argument passed when the facility is invoked, then you must make +a good faith effort to ensure that, in the event an application does not supply +such function or table, the facility still operates, and performs whatever +part of its purpose remains meaningful. + +(For example, a function in a library to compute square roots has a purpose +that is entirely well-defined independent of the application. Therefore, Subsection +2d requires that any application-supplied function or table used by this function +must be optional: if the application does not supply it, the square root function +must still compute square roots.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Library, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Library. + +In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may opt to apply the terms of the ordinary GNU General Public License +instead of this License to a given copy of the Library. To do this, you must +alter all the notices that refer to this License, so that they refer to the +ordinary GNU General Public License, version 2, instead of to this License. +(If a newer version than version 2 of the ordinary GNU General Public License +has appeared, then you can specify that version instead if you wish.) Do not +make any other change in these notices. + +Once this change is made in a given copy, it is irreversible for that copy, +so the ordinary GNU General Public License applies to all subsequent copies +and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of the Library +into a program that is not a library. + +4. You may copy and distribute the Library (or a portion or derivative of +it, under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you accompany it with the complete corresponding +machine-readable source code, which must be distributed under the terms of +Sections 1 and 2 above on a medium customarily used for software interchange. + +If distribution of object code is made by offering access to copy from a designated +place, then offering equivalent access to copy the source code from the same +place satisfies the requirement to distribute the source code, even though +third parties are not compelled to copy the source along with the object code. + +5. A program that contains no derivative of any portion of the Library, but +is designed to work with the Library by being compiled or linked with it, +is called a "work that uses the Library". Such a work, in isolation, is not +a derivative work of the Library, and therefore falls outside the scope of +this License. + +However, linking a "work that uses the Library" with the Library creates an +executable that is a derivative of the Library (because it contains portions +of the Library), rather than a "work that uses the library". The executable +is therefore covered by this License. Section 6 states terms for distribution +of such executables. + +When a "work that uses the Library" uses material from a header file that +is part of the Library, the object code for the work may be a derivative work +of the Library even though the source code is not. Whether this is true is +especially significant if the work can be linked without the Library, or if +the work is itself a library. The threshold for this to be true is not precisely +defined by law. + +If such an object file uses only numerical parameters, data structure layouts +and accessors, and small macros and small inline functions (ten lines or less +in length), then the use of the object file is unrestricted, regardless of +whether it is legally a derivative work. (Executables containing this object +code plus portions of the Library will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may distribute +the object code for the work under the terms of Section 6. Any executables +containing that work also fall under Section 6, whether or not they are linked +directly with the Library itself. + +6. As an exception to the Sections above, you may also combine or link a "work +that uses the Library" with the Library to produce a work containing portions +of the Library, and distribute that work under terms of your choice, provided +that the terms permit modification of the work for the customer's own use +and reverse engineering for debugging such modifications. + +You must give prominent notice with each copy of the work that the Library +is used in it and that the Library and its use are covered by this License. +You must supply a copy of this License. If the work during execution displays +copyright notices, you must include the copyright notice for the Library among +them, as well as a reference directing the user to the copy of this License. +Also, you must do one of these things: + +a) Accompany the work with the complete corresponding machine-readable source +code for the Library including whatever changes were used in the work (which +must be distributed under Sections 1 and 2 above); and, if the work is an +executable linked with the Library, with the complete machine-readable "work +that uses the Library", as object code and/or source code, so that the user +can modify the Library and then relink to produce a modified executable containing +the modified Library. (It is understood that the user who changes the contents +of definitions files in the Library will not necessarily be able to recompile +the application to use the modified definitions.) + +b) Use a suitable shared library mechanism for linking with the Library. A +suitable mechanism is one that (1) uses at run time a copy of the library +already present on the user's computer system, rather than copying library +functions into the executable, and (2) will operate properly with a modified +version of the library, if the user installs one, as long as the modified +version is interface-compatible with the version that the work was made with. + +c) Accompany the work with a written offer, valid for at least three years, +to give the same user the materials specified in Subsection 6a, above, for +a charge no more than the cost of performing this distribution. + +d) If distribution of the work is made by offering access to copy from a designated +place, offer equivalent access to copy the above specified materials from +the same place. + +e) Verify that the user has already received a copy of these materials or +that you have already sent this user a copy. + +For an executable, the required form of the "work that uses the Library" must +include any data and utility programs needed for reproducing the executable +from it. However, as a special exception, the materials to be distributed +need not include anything that is normally distributed (in either source or +binary form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component itself +accompanies the executable. + +It may happen that this requirement contradicts the license restrictions of +other proprietary libraries that do not normally accompany the operating system. +Such a contradiction means you cannot use both them and the Library together +in an executable that you distribute. + +7. You may place library facilities that are a work based on the Library side-by-side +in a single library together with other library facilities not covered by +this License, and distribute such a combined library, provided that the separate +distribution of the work based on the Library and of the other library facilities +is otherwise permitted, and provided that you do these two things: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities. This must be distributed +under the terms of the Sections above. + +b) Give prominent notice with the combined library of the fact that part of +it is a work based on the Library, and explaining where to find the accompanying +uncombined form of the same work. + +8. You may not copy, modify, sublicense, link with, or distribute the Library +except as expressly provided under this License. Any attempt otherwise to +copy, modify, sublicense, link with, or distribute the Library is void, and +will automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +9. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Library or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Library +(or any work based on the Library), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +10. Each time you redistribute the Library (or any work based on the Library), +the recipient automatically receives a license from the original licensor +to copy, distribute, link with or modify the Library subject to these terms +and conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties with this License. + +11. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of +this License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Library at all. For example, if a +patent license would not permit royalty-free redistribution of the Library +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +12. If the distribution and/or use of the Library is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Library under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +13. The Free Software Foundation may publish revised and/or new versions of +the Lesser General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Library specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Library does not specify a license version number, you may choose any version +ever published by the Free Software Foundation. + +14. If you wish to incorporate parts of the Library into other free programs +whose distribution conditions are incompatible with these, write to the author +to ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make exceptions +for this. Our decision will be guided by the two goals of preserving the free +status of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA +OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest possible +use to the public, we recommend making it free software that everyone can +redistribute and change. You can do so by permitting redistribution under +these terms (or, alternatively, under the terms of the ordinary General Public +License). + +To apply these terms, attach the following notices to the library. It is safest +to attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the "copyright" +line and a pointer to where the full notice is found. + + + +Copyright (C) + +This library is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free +Software Foundation; either version 2.1 of the License, or (at your option) +any later version. + +This library 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 Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with this library; if not, write to the Free Software Foundation, Inc., 51 +Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the library, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in + +the library `Frob' (a library for tweaking knobs) written + +by James Random Hacker. + +< signature of Ty Coon > , 1 April 1990 + +Ty Coon, President of Vice + +That's all there is to it! diff --git a/templates/qml-plasmoid6/Messages.sh b/templates/qml-plasmoid6/Messages.sh new file mode 100644 index 0000000..b7b1d79 --- /dev/null +++ b/templates/qml-plasmoid6/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT `find . -name \*.qml` -o $podir/plasma_applet_org.kde.plasma.%{APPNAMELC}.pot diff --git a/templates/qml-plasmoid6/README b/templates/qml-plasmoid6/README new file mode 100644 index 0000000..38c59a5 --- /dev/null +++ b/templates/qml-plasmoid6/README @@ -0,0 +1,46 @@ +Plasma Applet Template +---------------------- + +-- Namespace adaption -- + +Each Plasma plugin has a unique identifier, which is also used to find related +resources (like the translation catalogs). +To avoid naming collisions, Plasma plugins use a reverse domain name notation +for that identifier: + +* org.kde.plasma.* - plugins coming from Plasma modules +* org.kde.* - plugins coming from other software from KDE +* $(my.domain).* - plugins of your 3rd-party + +The generated code uses the "org.kde.plasma" namespace for the plugin identifier. +As this namespace is reserved for use by plugins part of Plasma modules, you will +need to adapt this namespace if you are writing a plugin which is not intended to +end up in the Plasma modules. + + +-- Build instructions -- + +cd /where/your/applet/is/generated +mkdir build +cd build +cmake -DCMAKE_INSTALL_PREFIX=MYPREFIX .. +make +make install + +(MYPREFIX is where you install your Plasma setup, replace it accordingly) + +Restart plasma to load the applet +(in a terminal type: +kquitapp plasmashell +and then +plasmashell) + +or view it with +plasmoidviewer -a YourAppletName + +-- Tutorials and resources -- +The explanation of the template +https://techbase.kde.org/Development/Tutorials/Plasma5/QML2/GettingStarted + +Plasma QML API explained +https://techbase.kde.org/Development/Tutorials/Plasma2/QML2/API diff --git a/templates/qml-plasmoid6/package/contents/images/pairs.svgz b/templates/qml-plasmoid6/package/contents/images/pairs.svgz new file mode 100644 index 0000000000000000000000000000000000000000..4d1be5de09f8e7c4352e650ee4e6e6c8ae69511d GIT binary patch literal 103064 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

(W_{U|3 zaEVDoA`cOwbb2E{boF_$H%plBWD{6G(j^85e=8&jces$*Sbcr+>FLT80(2MP4Kq`u z+tkgA_8t#-fc=mSXUcuQ$9_Ku&+cdIaik&{q3C<3k42hl-_dV_SOoedY@N(&W;BS`p@SwM~H+nrffyn5PAOn%t?k zAOL8+sRjfF`W7>uS|{2XEH3bjO~vXQC4=3^q9yox>o~FXwGKQB@jR-cu=r3ENI|u` zIxOv@TwJ`#0;b)6|5XB7u4*KJ7iU$*uuhxY)P*HjFjLJt2`E2}=)bgJm6K0K@0?K# zgK*aI0);?OVoJa2=%=oxJ(Ksk%%su-s?ac&&OV_P_N`aW+=Vghux}FF1-};R1jaV{ zoU{)Defen=-?&jVE=PlqT~+NhM;Oh^wDIphTVlOcR;jIrn*z2v`@2?+z& z5mfN6UGM129NI<{qXDBomWo2*ZSRm6ynHjOpDwlT7B%p*VMi8*w(cKLEP+%df%}ur zU-;D!rZ__}VwBIW!cE6g0bj70g#+}V%Un}dv-L%}IYx-tSN9-IsaKa;iXs4P+u8d% z)HL0{-|-SK`PH}Q&7by`9b}~%pR4>Bv@V+its{Ks)j0IFM~%X)rRjM)_~-R~`H;^7w%G@q0?A&tRM*9Cq)a+Vrx)6zf|LNRE+N={SOZE2wxz>Rx3YE(<&>6s$$ybw? z2`hhYE5P*bUmV3&ysI+fL=nGWSoa3&Xr69@zWBZF4CSleTZYsQiI$-(d8~w^ejXf8 z&nQicrN_y1bFMcIl5vWodDv6TZ?VL5Ab~^Lxn1qZwnDddFkcdP+B98;2dWM{Cuw!T z?YXiV;f=Xk^I;%O@0lw2(R(|7Mg@8SVmo8d%W{Ok_i#gp7!h`fJdL|W-c)m%=&weT zSGnYY1q>GE=S7$+!jlwwuc28duhdJW74@y%$^^6ZeA>ch2&~MV5H0RfZYeda6y=!L z7XVexm}=4OF|-6vb5XpGztvL{2pI0t)R-%BG$Qh~RWm`h_s zIXyFN`S|d@#M00$h~=BOFn*Ut=@vS6H1c9Pss?!?)J{67e1_=n`8)WllTw-{6uH&< zm!{twSqFK=03MAHm>|)&L?Jp6?Ke489OcmRWvc#kMs%&ihNb-udX-!X2N00@qSO!H z`x6|%6G(evjpn^BAlrCL&Spq;j9EIgKe8u*e=8Hlztx@;NUC};EXsf>02t;_?4&O$ zqjtNrAe@oly_F^S{*f~h8-n8_8mc77U8#svqb1klv7h+*AeBYBn~(f!nI6;X8+@@g4keH^dxqa7JsPmQMaeB9uMfn$b^PHf>)(F| zwn;DD=7as&YPH#muHz0`hz}or;-H|4fxuLEsz%g~(lf!j11Vl!gVTXhwKhkumNy(< z=#RwcUY1!y_|;klOreBKA&mB5%z-h>3T~Zg;=ytr@D-^qo~vKT0wYsyR5JBX+62)_ z8=I=o^e6=_f!yCY-6;HZmo<%H!GK&f#DAF;FWYe! zA4r>^N)la#`cDktUu}uT_3GO+I#bgcpQhwPC+$_*3gmN2cGPdU68Qqr!`o~525p&3 z*B)EQ^>l3l=?>xVe(K-K(>d^33xj05eN!~{48Olmd1gDP58vD9YgZaRlvm_m$xOj>qEIk z<6L(ZJWmE`kzJEu;FPZul9?OrGu$B6mxu9R6Z9eR40rW60iyKpztCg-q^c*uYox&Z zHOKYgz6o9nre~qbZ@Wy%s6GX4ql|T#Y=nJq3VfUoj$O)e(NcRb0rh>IpC8{GVy`H} z*(OiI^&7|?N7i+~=B!MTQtt~A=!}@d^P!|^{Ge5-p$l0n;Smjo#v2CjV4Z+6L&1?p zO}!2XJw;ip_vg&~m&SDdVPt+{__*q2mDjUxXi!Z@!=E1h*b9?g*pC>$lb(Ff6&-&h zCeRZ=SF-t8{8y0*Msjqz5;9+VW7n^z0R&BMrXWr)lXQS_%cePlmZzyCXD`wHG5t>j zX&r|L{^23(U>WhY4$NzS>P_WlGzb8fGvy7Nb9t$Flc# zPru=-8WT+uFJ-6M#i@%vGap(+F(Jv%#$+-{WG&)lXRBoi#_f#i=J;3YIy!9tJ*&h^ zvG+^MSeE6Iy+_X8`jYhVsB~g6=R}v)WN>Xbh$0@}&}C$nOuge)GKPrQT-IrwpVvQ% zxyefkgRYNXk-nPF;II4I`C+l-V^WF_z{a*eJW*XaJM;~H7gMgcBGR;rycI$_fo$C- z*|%v$_o>n#o#U<$!&xH5RIMO=B&MzGk{8jswmRQnh^3Ng`X|%;@9y|@0DfLT(bk83 z-C5FTieErV#ud~zIs&f;ey=KpVb#TUn>i6aklwNap_8u)b`*^yJS6n2UubOCo^C-z zHEGbpORj(P(cbf@XR4B_7fl$3mcwQm%+Wx|2xUjhD@wUSC9lY%32t=W?wcvk99YX= zR`}q9RLgj63Wt3cR!&+!#N9>D>3M4mTDw4;`+K_!P2EKtEfg zkVYaoUbU}x8YJ?Uh^HD%LSQd%y?q&*fk?Ya(&V$@A+)e6PfES%*~j?H`eMRU1@Fi# zKR5KOBYO|50WjsCU7$uZy#{FSC2-Fq@UdT(d1S`$;$3`8Qs`eUag?}c#}+6)pu_Oa zYi$v32k7GJdlw&B(7XT$Jk+e-$|;>^x8 zp!QwZjTm$!^(#h`{EK|uxYC^d9-kuTDL~7mhx<9^_6jy`ZK9-UcJ^JUS@ec?PNn=% z#dSWnfVE@tsRNqGt*J7(c#;#hileqn_X##Z#LwqJiux*y1jNo1Si*Qm+GTAyTpuFF z7<@ac$Z-h3Na?dNv^TE)uin8VJ`>n)p@=eI zzYh&VM(pdT>-S3S^u;C|j?weE*6txuGCXc+P6zndh1J-6D*Qa(mmD&KB4d!+h%Z=r z(hnvDr=IXVY5NE?wHqy8+ARyP4be9NaUKj0#QTTJP>Rell}RdkVX&P;G&Tsc^$F*P z{PEfEP10e35!Id|lqn20RXq~}j>DT&tDPQ+6?>~_dk=(zi)XVZx_l=zJp+E>RY1Q? znF5-9?KC#3>d|X`W4RfcI(5j~t6VCbrohO@dA*)bYskiTg;0@8MoT?yza%-3N2s}a zTq)EHIIM}-^Q|JP`J*thhn(dbieK^zrmwd?8<<6XBZfVs{QK{tTIx;hJg)Ulwj~$W zn4i#fZ0tKpyCkl@_^Y@cT%rk#QJoJ1barn$N%jJ5NL4A60+F)Ha%9B~X!#~>MB zua8NYW>Ym<@rI|}T4U6y#?dHQe*O{L9(-Sc_j~`U^52SbzcJz8JW>E%cZW^CDO;N8 zj$>KO_0iuxr3+ZU%41oOQW;&dr!oAE1dy@zue92;%NqLhqA)+w45UNY#KoyOu+V^y z&Kjdc?{gz|%JV|#+`s=2S75`W-}POWM{{t6=Cmn%4TtG!xT^GsGk~F!AYBa>u>FaS zxm7eYNrq4V_tMYp0ECWJ)Xxi@_1}No9=rANOUn|%spr$F{wWcyg;H%b^W!kM)asb0 zUa~=t%P%sYNG5@hNun_ON+gG7jl6gXynU)`c1OOD%2jEA=Dg4*O3=jaFb^wC zEZhlrO`82qQ4x}CNTd4=P)Rg?hB5Y(k0T-H0RSL|dHVKdB!`qY6dlpi27ybXaO4Ai zuCOS8bfx1Ds|Sl#%5sh1D_?#R35k9nrh{Vs8d|HWGlHVfc^oGKI>6^8Ba9qRP~Qau zcDTt2KNe8j5*HJ0f~UW}0oFu8oks(|$s+)q_>0a^(+|~{)rfGvmAR25amA)L2g|?z z6u+i&`56cX zC4_`&-!pRO4)VHO`n>Gy5Z*+$lOM$-jfOk=5Ej$mzqGExdJi+3W~LMkCqzzaq2)fk zf5ks&PSI`ZDP7m5et<$%q23nGvOj98yMVEDh;LN6@kIa)INDUdv;6*wQT=${VcT7^ zH?i)9I;k9zx_*MD&J={+7|D~X9;e@0o#m8qUFNl-x*f#j4F%Y#qZ*nMR z6ma~yYf`rJ5rh7yL6%!C)F$fJ%pzFyd7q`A*OkK(_q#@b+Pix7B78yv@&Xp({J0yf)ycID<(@1P02kj$nS8^AUBMZj)JBsG-p)?Aij%10+k)P^n&zI}7=+{T*X5Vyx8O3Fx}n(;x+&M_9x{ZP_h!C|4V(_axx z7;{L(M%Xo#J^P1|u-m|Kj4zswL}|RZyuHwa%4bSj5K<%!|A1E;B2PnGwVE=R_GX!j z5B+uxddoqmT|wdiq>BoqKPQ$cvs^^KXyfa(=H;k(b8l_XJK;03cwwA?<;k};iE~_G z{s$7})m17&#J2sxi z7|be)Hp{sgrZ;hTS~>jeAN#YEFLS?vXI2!L)-Sra%z#Da=Jo(gK(oJ9>OWl}=l&U+09TT3_oZN|KL6@v zbF=U3g^^}iP>Qisb^PzY?%|`0ly!zy!&Uv-db?K8VgwisDSA!~74s1}a-x8I3fKHi zQ`vX}=aTH&csPPK-W5_U`A8k^{-&A_HV11cAyY!RHWLf`M<6XKQG+WG5V<3}F&owf-ToB;V=p5JRhA*mvYqG=IJI#zbXB3qJ?e zNmFyHdf`Jvd2mh1tjKf^@HpG1*Z==BB$KEjZykF1q z9Rj3=vOq;6Yey?B{86+DT4h*lP8O;>+}5Jw@*`Y;2SM^@8A18OJe+UFn!AQJ;#}NC z!l?_x?<^!Ddf-YH#!S&)CJ_xlQPekI3HNKdM>zaCoJxM%O-_u*G8bQiW~jv=ElVsH zKpvYm^}<-arOnCo@4u#ov~`0PrxixuKJ(Y9gqe)()jOQmB?!d&DkfFdK=s48TM2Ir zPG&2G+*heT1Xh+uI5Rj{sg2yevw%ap>2bF3>{moK;A?pn>na|d#_j$boNz1SrSoTo z8Ei(dX9m1lgD+xK9Qhj`&IDO3!KII-rvIK%(u$x$&(2FUv$frtOyO|e@vDf9quJ%% z4g+MidT_jf{;UOhfZkZUlz=`j2)O!2&Txwi%4n9B**vO35g!s2EYAkI6AARc$@s-hmnf{e$oh&UnTDF)oZteK`#RcU*obN1vf><=> zn9VBRIKe5hJT$b{s1J5x>J)F3;rNy>zxmB#Wbdt7f(2urzLuhcf@IY?#Kb7wUuIV7 z!>VgvX1%(e*c-(LEi{Mk5P@)mgH(awF?= zZQ0~(UD_f+e3S>?UMws39rT?~ovs6sl;7m=iX%mIa|jYs_aaD6 zR9t*Q8sl}Pk@Q@9Rj3wbG)|Yia?gFLX8?#iY^jlP!ui)eSB2hep04`&|8}lGU8DMO zDP<*O{XM5e3|gqE2wV*vwGLIBA~9X}u1H^9?{s`RSLwYU!vahhC8xsBW%D+MbQUWA z{de8uehop43+m1Vzqo5nVKoOJ)Mf#0LRcuN{R@5{2|O(Txyc++c!(YZkkLLnh0LS0 z){=5YT276+h)mu= z+jFaTnSP#LsW~(u|{|3kairq1|a!NCX{3K$BZ`lM-Hi28NzqJIU-x$VHBVDkt z!FaT21f52!TO>0(cmmymUEJGzmthp8btH?#qsFNLQ7YE@d0k)lFaKV8_aGPgYRDk) z@R6G{0$?*#7PU1%_kBld{19Lq6kR~J2|d1+x?U+4xL{tH-{KadG(TJa;xyEuK+e*O za?6l^|DpLQZukPM79d31rhDckAeUUWYu2i0k3wWL7r%Su{JR8V*5BD@<5ZG~hv@4& zbI72G?5X=JUcsAcj&Rwd(IS*D#sfd@?^S|F!qa7F&|XQ;8S@RKB=ri2COT(y?V|M` z%F&xZ9SOT4`h57&L3JEbU2naO9#*AOgXF_8_Bwi&tCjsIEMpDBykg3szT87 zZU}Xn7hxTan8~+ll(fL&4&s9oAqc)k@T#Sh1E5`iAJ7dYvE06lzVc0TVx(JkkI?m( zhTk!-T_TPn&hMPo+p7iy&)=pn9S}X>=L`YLtaQ3pH=>W7pRa*#BoaS@5@(MQu}Y>Dn91-6jA(AMXts^ z00=y;A=#R4VvtA|gyaz6=f_?{EbBzpzM0}M`)9U%#+%mBy^1t~NcYEG&|3;?-Fn#Id0)DdBrAii6fTF^CBHv1!f6BM=X| zzqgiZvHhBDfRVJaEDpOiy?;72IbKsD4hZ`6)WOJ3i&Rr?HbO1TAD^r2&5`XJ-iIJB z&s7P*TOp~xb%P=4?d%WH+{V3*372vto^08;8N7n;k2xJwGT04|ju`{SS;QSOL*tdw z@v7#F!Yy&-V|q>_nza9Y(;x+l38NSa#lD>?Gvr)x;u6U6_Xc9G^@rx7a&C9*aLd9iPm{$w7o+lew|x~!G@D?b4nC(fR=3iMZdS)Ff>UyP{tYW)W$`7< zXOs2ZZ+_z|Jc*xk~fj1yr_%wV#9 zCZS|RErDfT+Xfy&(3FQW^8QNhaBpimeI=ItUfZ3((&o|VJO76IMu6G;_n$mTNGF-t z=Irq?hNt~)UQtKE2?Vbp^->sUnxA7|KV-$}CxdPk`-*yT(6V>U`EG@u5+Kb2Q$`QeF8wpGW zaBV@fg(v>|FC%VEmn9AAVIHHEW{B88waIli!%YzsKRQU4FIZKwQ zibjk`u$S&(hvp2LdB3!4KHEe7vh3*I+&1W69#@Xsu!gNk+UB4zRn1GAFut5ZYFk%@ zVAKieB0#$ExA+7&!_Ys~6+8Eq zBZUcSm)Zt8B}FN>a6Q3|3{hb4capblb53A`+lhzb_rNV;v$oQfR*F9dWKArjR#+A* zovYdBv%~lNY@mUUO6+J$FD7Wgn7K)k&lQ(B;Z*{qoD55PuB+u##}h>HL%ck&J>eZU zv6h^JWqB>AmhYI6sz%Z<$DMEFxPb$|_TQmJ*7jrf4iztCdkMwUs7~UpoB1&ErSgES zQIdhe(A%ffaceY@cQjea)gpe64@h+@rU7p!fSSc&9Q$(l&qxOl^^c0$%H3!^+SW3 z`R4JcumU_`T4vW`y`;2glYuj)_EiiW0RQ(NUMlm7+8b*)(~}`&dpD1H|E)|gC)$rX zl17L(Xt>J@;R~V8c0zp!nJ2}~rkF+V4gi2OokV<3_`MA1f*u=80|}ml>T+00?r~Mf zjI}1MNH$Tfw#Jh`4YLaRZK5&MAPdv{qy*1S9{AKvD0axN31aK-IUqm7G|GO1m(_P& z_`P+ghTM)KXYn=4x8@Brg4ZF0N92LpEGwi4QjURtEj|vU^xGSKa9`q_%*)?ya&5^3 zpPb$eIOTGPHFE!XnNbdHMa0K&61t@UIX_^gA+2nzP5`<}Ho??4c3;Ys_0n|( zUBjkrC->m$+#IsuhACX?0je$N%j`n|A2^B2=jE)=(9zo7!gt_~nS>oK2d{pcJ;f@v z2L^mh5HZ#(lNkMuHK-wA5tRuhy={;J`d?#RQe5%7r_^s4|M#B+K68yN{Sbmw^MDj- z807@q_F?E13bQeS0C-_q{YL<~0xgZkgaWcxPCWtrO)CwG+l@Qi;za)by%|JoI(_Zy zRhd|KZl21humSpwWIb8vK+5RGPYMu2v^Lk&!7_?@|<312fsTX6;#`rtP>gCdLYsfXK2$%M+oz$pOL$IlZ$`4bqQhNx?J*#spGYk&N&`;U7>kRPYvU zU^GiwkNa<7w#2Xwj<^0Y+{YhG94T}lHedkbH74u9*8#g5Dtyj$OYcS)Wg_3Kv3rKG z(_DjTE7d?%Z&%D&i7a)|ZaAksPG-kg-PCWf^YFIQ#vWmWEy?XoHEl5oZ)T|JQB!5F zaggMmYIj(nO9aeQC~U+{&8)Ct;aA5ql^|r52vczWlFG%Z?_r6^ebMkzCFnb+#~}?- zBOo>$SKFNC$5-<&O=K=>0v5r$#h6nD6A2WpM_q0Xg3tK1M#xCWWoA1lmbysKnZ0oG z>&ASuQ+#?ReVGQno6O4iU!XYt|K6U)b9RPB@#p+PoUugRyfrq-JBDDKhx24D8Hf-?d4#c#jiau>eEc2r zx541s3e>pN4`y&10?oVr{YO&)J8KQN`!wXEXzJH*AiTc$r@wW3dPL#tZ73EwSY@x2K9+*p2N?X>!mkr64zFTZF9bU16# z)Fa`LBSlQdd;XrJ9@)>vwB|JDbZ_4&t)vZYmHkclx)dyb?=We26?sf$v(?XMEjp|@ zPnv06CUG;%zmjyC5#SKe)n`>7zG|R^>qh9bSpX9eivEd#kUMD&=$2+X+sV+2**$LK#TC_kie=CT-9dAU7 z8afhMDm@{VM134NzY}A?=6o`(P$N&&kY^r{y)2weh{u4fXiOCa7o=*b}XZg|NZ+SS}!$@+>5`?@sZKew}zbA0xd-AyjH4ir_ zKodV2Ei1BASyS0AR%c(LB>O5ZQvYlc8rj{2IbN&G5B`gOH3YA-vQ#-#O|*!WF`8xg zfKKDcuUjX+0GTPadR}N$WlZsKE^?t35hzW@8-+!v*S;EUPUrIJOJDfy2 zs!D6Bf8TbgWkxlISvNz5iIq-cUq1QtOiTZ^)84(V?dRmEUUcxBtfjSA$!|?`MdS>r zFeZ0-vP(fq?6=u7hNB6~rhnHkPbgh1P?zmt+rIM67MluJB@Dt~2|%h@f`FS4XZ`kq z;bi5(3qP6*=cwPVh$;Io%(~2O-L#C5ZpU%ABxVmveyk5Hwl3CP9`@TSXmC)Ct}@z{ zB`aD?{N)9P{wf#Ue(d~L-iV_Rm%YU)9B{q(Yqi0`w3MH5>e?grV43;r(Hns9kdmBy zu>IYc#k=49a~+zx->w(ByJN|^-KkIaP1=67ji~L!%(q@?vhxz}M4Uqz@>_bNpdd_A2488t)UHI{M+T=vbvkT)UhMI&zp64%Q`aH z>o8h-Ps5n4iEfEp78(9)x`y+=7hKkMs&_%7@8)tc`AaI%NIO8n{;izXX~{u4ZNKAJ zPs?)@E58q55=83}ZLur;z;2|5fA1o05P_MIs8LBMh*5XN8GXp|_JIYqKbY8k6TTce z-3v={qdYA%P(ZC)fwf{kW_Cl-{ppb}+HKiqDJD1dHK!_@)?dW(M2mfk1&QYtOn4N{ zki~zyK6eJA9mTE(a-@Stk4$o8x1Chb3l!3kI6r3BLoCt{20_cq0trR^yZvH+vyCZi zVcAUtI&u@=MBX{gSC3lh{{HM_fW}q}3C53XMq>?9BuU4KtJ|Z?!-r`GWK2$ECj!AY zQ{-^taCq_FHS{!?UG|CI3ejXyb>1+naeydC*9XrmK1~*O{-ocu!5}E{W@=rKF`v7D zS--OeH;XnHz;T6{6E#n~h_DK;)!x46hOaB_M%+GH=AFMI02?y4uI}X%^PU=+3zLys zd=(v2nA2&#VQ#)7jF~==1wDy^Z9pcdQG)=e=KGtte$i8Da8J^OifyWE8pm)YQP)2z zDOw--L80S+Z>9|(_&Z(*#NY+HSn=YBAyqc#_;pI$Duy_=FByg7vcth;mhu#azCb#6 zRjVLr*6f&ieV3RLPt=vI*Gn`l%Q6p3D(m}?x=BTcNJghn&{X(UUew{$kffLq7^=}s zUy!P~3|2YJDvzuQ_c}IKwl^iOJ-@uDZ}vmp>q>P}W{pr@vimCF4-%1hM zqVp+7ZElYlLB)ks1&q7TP~zx0K0wL-_Y`BUJ@uE5cpX9#w?U`&mcIldbw~!kt?W_| z+(GT2UhPeZCts8V4G3g_ijkk~*iAvc=gB6SOi(RmfBEqQhLnz0?mQB>dPaR9E>Vmw z$n_iXe?UIGk$u2luJ4hhCi4S*=L7`h0t8vGn8-3M*1Z=QRNICpZCZTNowWH*YX>Ll z)mJ~N=878D(x&WiQODYj2+jN7e}lL$koVl%nm8?2UEcRmKRU1vHHMsR{PP*C@cV0! zEl69~9(EnXG1GXr_Ap7?a@pTO00a;uc<^sOuKNT_twg>lNF*ftfs%GU20{TBe8YMb zCFwq>4<>v2Bro(mjqwE~-%1YcW0-#aXd%WW=^4}pN&EI`MN8X3a#X&!?sMBukk;Y` zPQ=$wR{tp$Kh($|b#?lgNG(=UU_y|Ls3;3(NBfOrAD5) z=?#esfN0-C%y@Z(%~6oi6RfU1pCx+0g1eLPPM~XQ{C(Sj9G)`{ZGBanOZsy_u4Uv) zflN>@5KU`?H-6usGKlxkrVtoBbhRDU2p^n0~N27F@vTf}E~0W==Bp(j7Mb`gJz zKHqb1n(Z0Mzx%!MOSM+F6Euze?N{ZVWbzd~)lkw3H~MrRNXspnzvh24B)28>rkp}{ zvcUL^>K&tN;JsRk=%pI``|oK-=VayNoy~5RX;*cw-nnzup{NN$&ydXQ*g33yMkM}d zi;szz;P;a3WM0rS8#m?f&Y;%o@ms!%1hd(gV&T9O3Zhf)+tyNArO=_}#1Vfr0~sTv z0}V|)0pa^j}3PRu!LW6SD}|`K`&T^=w=^6!g3) zBz^%8O0_Gbbci$bNvkm!p?stQ>El$ee$Z#=7~Ua%REIEqC+k@_{R}p#p}0Hr>Ra4&z>h2D zlkufPaPsYE9L4JFnO+h5B83KN_HhZcvzr+cqC;yv8B>l7&rfTAVs}^B?0nruXT9ZR znNRg5+%~$gB$3iANNH+?36MUCP_&TD$r3=8%tZ|A%K-=;;7%Ss-V8&G7u)ayNgz_( z1bXr`-kAUU&z*H8VqcA;TBGAXmiv}ms-2QY7BhuCnkiG0xx&@@*;BPP^GJcct3$N? zZTFiT;?hq>8gUh)-IIU+{g!?Y56>~(9QB3RLnxL}lwAy9VH;mzst9XST$@d9Rs33# zQgaYg3GKrM7t%$q?XD3#%!ip4{yT0QyyV8nbTWH< zOHsir5Rzk8X&Iha_9El}!R zi0+TV?Xy~U?t`}X6t@T*I#f%Fj2yJfs$X)D$r%w_H7H3nW4JhdAN=hkfDf)L#3cDc z2=ar6ji5mCYslODvndq#21$Z@nTbd+eKO!iq?FcZVJL0{W z+;}Z3>=53a##%yd$|;hJ7SEMe5+qK2NzdaWtdX+xmxF@UqPa6o@f5!g{eDhS6eYvv zM^euhT>h@~LEMxAsnbDsDh*xZTj?IrL@7hCH7xRjaQ+onYL~1g|E?~$NF?b~gjAC@ zTs)S2M<(m|?}5J52FhX+b6S#4!?H|Mvk|bYvd_-;_Vi)hF0~$$wdrFE)Sj{^9Rn~p z_4dx@^JnNTnznR=Q_asAj>o_MfZRNROe*gpeAXa-sABEM1UBBbSAtPb?aKa6nOU(7 zlc25UU@t3rO9y4ZmoUQOceUPa1)l0%)9dx%TtVry#(nF<_q|W%cBPxaX*6JZ=HEJ? zP^-zWxAur1?*p0|+(H?!IQa6%WvodV+txvpREIU|Z%^hN1Zc3#08;yw#pG)Hc_Z=W z@hl-D^k!g@Vt3IS&OW`VG_HGntX~m093{>W#j{^Fc2G8DaZ{20i1N$Hx0P5*pB9R(9*W&WyR5YYc~zQT7ybbv&5Pl;iOf{+T`1bM2brUUY3)#N&4@< zfWkrS+bZ4zqBj7>NKSr!at7w#u>m3!7ICCzP)mNAML$}``HBECrq6kw334)CCq#ZC zHkiXY{_B9is}Ifxgs`h*y+)$|gSmn70V=EnFaQKXkb9s)AIY^{$rFT9kn&f5`n@TC zBtB`tBr@sL`SLV=_p;1wf4@s?D>|X8v4~cis`hI>-)z=(87By%N%?ebY=}HJ{3~M< zc-72;1kL#7dhkBpKQM?<;P+Sl?ZCjIDjwWhxnu5+a593%14LzZ!|3#@cZ+OGjB~7# z^kqkBVvQd@PLZn_Awk0Fd=rI+z(<6hXM(*XuKdK)Cr;R1#mhX;i)+VU^Sf_*bv73L zeS5m&fqG9rYf911SC2ncyGD+Cu&PJVs0{E#yQA~Y?e8oA8yP4kZ%xygZDy>G%8BiW z{eR~)r4^`u#RbywT7jH&a?C^b#za?QT#?}!urqayjfwpEewqJ${Y`1nlTFQ*9dN6s z@#aqXK(eRk*eRnn)Pv>ZFEp~8eMJHO#cYQRSXfLBEfTz}USCjXSMUTROw!+R+uBj0 z>g=F!Qp3|JvKsZt<_x5>B69MAM#aTaY!~2bdj0yeI4E3Lbx5Zwk>%jXE4%yt zt<8g!o6e9iHhT2l`!p^}c@1%aT8*(jydd2%ir)uFw zlGq8JEdIRa)!x(Pt-cupl{yl8fwb5&Tz^=RwElo&&s^>x3C?^1{;_eL%UzbM ztGyP;rPe~_BJr)I_o+J_*;6eJC;$CtkN^hKItZ-s`8`7)$0-Ww_MiLJ72YyCQvs}u z$!Dd%Ep`^Qyc_83@<)DG?l%ion9z)$GacrKd>POOh%XBj_njLbt9yPkW~CAX@UtY~ z_Xc`Re zs~imi>ddVlYdNUkSbl9K;}`PZEPA~8ZEkv{!cyt^z3Br@mQ7`DB3THN-SBmKeD>`1$>Fq4 zynKv9YZQfw<=o>>Gx`xi$Nn0osps36;J;*)k7dw^N;BSX38w_4l}=&?M%QEp$wb`WZ7?gR^TEileCdOtQ1lB*k%gD$SmT$#_NVQ7 zc7Jt!ii=ChYa8qTV)Ja92nhW=rj{yEI_`$%7b=b@lv-$-i!`I(a|_rfc8?(dqqPOZ zOM6lzE5d@abV5Lt(})M5J_rNd*Nn=XJ?@9T+ZLb2%J3|z9V$TQ{2qQ}9Q)rJE)~iu zL3J;V8Xl||WK>5;ZfGKP%z|GH*O9l~_H~EHIyXmh>*NHR+TKiLykD5_K>>EcSTc1F=e#p-M&EBR+f`WESTwQ^4J1JOdTWk>>hB&IXZ>!&H*}?6}qy zf)*04dgFSnzWRo&OHuEHwqfUKV)^&)6|cE0z<$+u9@xdo&C zG^50>Tp01yz13-?7($xC%ew_dLtCRXoMEuz*IZD3as*v_hH#N_Bj`)J!Z2D>Ds}uT zM0mGg$&UXt;dBIUSOW(|Yo~U;*n@&MLFL;gnBg-7KKU=zcSK`M41A^|A-5Z0y1(j; z*A$Nt&A&=h(m$T#K?psc zpsEw|GNAe^?rw<)$v18ibno*3ZxY{Oi_5>5xJN-Odq^XDlnTBqFsF=1&B9MUfNHU+wS~!RXVma^vO#XyMv-A24$zh z73E9vBY+3fSb-I6n9+V%Ep`5$eW25#4Odj)R0O%Zp^7sNrBwITbn^|61i^)4qa}~}=p^~JZEUBbG6VxW_y12$+-pAs~Zl?Ck& zA5ht=V~A5Kgg5^ESK%wKhH@M#Rjf0TIR|4=QKSRzy8+==-BfVyc`OC3?*8|xx|X5D zGE$Nz0LU4PHybIF12Dw*CXv?xp#&r6JVC3E_vO(f_WgdZ>W_W8A)smBkwcSS43+ze zuyJv7rTFIHTcn5KE(NCrx;q!^8l&17MF0Mi%%2+i&3>Dq&!urLe}k`F8D>q6q!PETcH~R7dgjhIBp~|zAvhKtu9X`kM z(+GK4q;|ex&ebXV3{(A3QQ8CF(cd41=hjqTLswjqPzeacPYPfS-Ycb44JuDRU_UJ; zy^aUwEDVV@>Sg`Fp$!=di-Zzn5lB`_*~tQYe?yS6OeiX$cwt*ja>K5RN}*(b>uLza z?Cb11j7yrIR+<^YY<{D`zku!u7XsN|%n)SM7y^8&jih};F^%~OeoL=H)6k=7z=b7J zVt)Spcjo55-+EjqBj6yZk(Jo)#6 z7ugnLPY#b9i6AUE&P~rD`uC1!_4)e>2*ln#oS=|v&EgP#IR5agf)Sur9xY-GZh+x3 z{Y?6v9TGB0-K8%zWYRV{b&nc|EQk;|=HGwU+K*(AK7><%@)&(w*IzIClth zcMQ&t5Kv=}WXAqIBDr{=1vtk*fmf$q&6Y3?l&|=r`uCq_Xj)mHpy&F)T)<=A!v(n$ z$z=LBLgc4ze%RgpfYnxa+jVFTx~zUa#`X#@VhgAcw;-Dx-VUC|Z)X)3hf0AK$5W2* zw(qA+({<8;oIQNz`b)7`ewbl}1*YUaAhnuEBx#c=kg{#snLYVtEppktkq>QbsB!rlk+A(z&QOf}lgf7o zJ2fctWM>=;{O`Ztk0J}L(dFcz*F;Z(TLedT)JcipgANFK?;6tIylZZzF$EX=`lR;s zdHAeDR+ech0K|u)-0hmBHzPfDC|OB@(CaF4aJ@NWhFUEk$HnL)W037P`+v$)s2K#Q z7-U-+51+By#|Y9A26YfZ{(|*}%&)#t(CvZ7TQ_`pC|34agDElM-0?G?V)_cz3Z{pQ z-zb+>(F0sr5OjKRmT%_G$f?>VoLf&Fuo3dK^k8 ze+Fq_&0I+`OPlybkhxISx#D4j4A1#ITyNYk<7nxOF5UY2La!1{EXD%|4L3bzQoDoG zZdm#tj52XUQaU^tLRW^|k?Gus<)tu{>*;Kdbg!HXu0vLpLiIZcMgRNO`P?Je1m1AGrlh_(`g`kfeL&I$9t5u8KTWS0acNy{QU(lst~)fhhJ%Yc%C zevJkQhcIDo`74L8n{)|J;uD$qv$_RcDwPhKu9~w1@HBALqfLa-Wh>i-`5x@~uhJpk zmdoMw1xk{k(;kEj(my`yr^9**pg&;fX`R^If9^EdkTq^iEM9JT*BG)u)5?Afq(JgG z-?#JF>*X^!JpA^;o2_;`o}7c%B3)N7s(c&7}D$AVla!j z1rXyt zN>|?Gl@9>(xh8AK{yva4V7)H-3|h}AnY9H8Ir)5U{ZRbCr|{k@MMf0M!R)Ag_~^a# z2uBtdU=luU=R%O$62}~ekI_rhg9}K+2py!hZi3?X%2!->PA^9;>}22Xqm}( zXjZizUiTz(jGcl#`Av=tWv#BA_4$FtJ}{xwun)_srB~#OpM5mHGrVt~>lAo-q3nL# z?%#i|hWi?j-$k}VoVv68lzkCmS@zXEF9tE{9R>wqXf$ykKp+fO|bSYtj;9pvpqiNz5*7}g*K!JT6QTI2VdoD`xRz|RPX z!1~Hiqn!)UMO=Fb&@v@&4mmC67uz9gW5!%fqh^w?K&cpGAiSm|Y;b?x3#Fj4)f;D7 z=D1LJXboeKx39)nj7wWF+{>_X{Pp#}|7e=7Xujty-$A|@L!jv%#|2}sUeY=(7JY|j zJzwSw^93!*jCYrkRGMZnZ8dVC+NayB?}G1CHGlVety%X(vWhJ(IB%}+cewtIXq{4z zvyp0ifVRV|NJ-(5gaUN%o=I(h)NSsE{SEzyf$$h?ksoy>$9uH1J797sB~re%P2nQX zZNiBgC|LBa@9utE>Q#BdJ`$jsbUWuSOKBqFYq7%X zGC`CwWHe}x7gI0i#l*dZvETnvL`Tey1esy~)%^CeI@V^6(BeR#>YxRSKf5^Xhy}}QPk97Ori?U5QaMuYcK0};@y>ZdT%&q=gHN! zUm>=`3$w^CuQW$S73S@%2#_+FFBxwx^*a6`9f<8>E)U;G(2%aqVq>i?0vT%NY`CAM zsWXExXruo9G!q)fAsYNs`FySquaf77(FLf4Gtvb8AQr>s-zjghASrgj@jKx8a5YSo ze*||vPxgakF|Ge90;$ovfyXyz7#YxtveIAgoYrqbd^?#d`Fm}$Yhk#^RzjH*i6qYm zQ;!^*4H(8L4v?H()xAW8HKPM=V9V0xbLTQySl*wj)aK=Shz{GGcPf?{?Cctoy4~+y zn`o z!`qgw{jJ&AL3bHGiua1ABr}+g;>XP2R?z6hLm2{OgXIU@#N;M#7`5@Nqb?KTn`*G@ zw{cH3^xl9uRvjkF3_m~NC}ei3wc`T<+**R1@pviKWLbgkb2k0t7CBFsMrJ-}fWXQpBtJ5U*hAj<0w*Gde z?Sn#?Ku6aX$wv0J9l(}g`0rawI4mRW4RRJ^?LitF-a{~ZFRCUd6j$Z{=1>xNmRLdl zer`R0kn_l#UsS`@!#SE$S8~51_gH6DQ~bT}Y~Mhju1Ls~6MG~X+b8xNXEI9|ER>R1 z2MAj0|TpLeQYT z={JXDTVDoid2Jh0LxKa2wIBcgjZIn*F(>GlXMMkW@uO1`bn>h&NIs0a( zoPPDl@TdSSjjoNVm%|p0ZxXBBYTx9kEqB`kyRxZ!70fbx5e{BoQ{qy0ot1BA2|$bm zd%A8S7gSvrYTWov72V_`Hx_lm7I%1jiwe>1j_g?r+uk%P3V$EfsLKk+Mq!%`ocfU5 z^Xl7qnuYZVnq!@v6V>7}3i~z9@^82|+c=zm2)4+R;KS*8Ri zmlXQU?1?LUuQWqmvZK%G?c`dT>tNS^CNbFy<7?_sNN^~q({pHm03A-N9srf5xC)fH zK}q;194ic=u6cfUI3QoOq&C9F-v4PxAa3=C)B9I&nk!&@xaQNR_`?}rJ^Jk5;L%Dg zzPN|5Yi18Wx)4;7+C*L3)?;H)lefI|AyO<%AF=~DY{!UB*1{=#vzZ}#IV7?L6`*Z# zqTV;#LU#b;e*exn`)K0~q-Y4OapETjI?n{f+Hc}|6ZnI>12V42rwS=Z6!vl$f%Cm6 z@H0r~hd~^#`XZNVzhW|U-u3beQ>U`62{OChGCXe1=d(r3{O>D-=L30%GHz949E*2s6Y7eQ#h(47Xsk+@}a}Sn<#c%Q}Ou+ zfVrMgHG<*){_EBqfM0T%%WODlaj_%J!t~@dm*_nQtrzRZB6%6Q7Eiud(-40uolvta z(4aU9)yqITdPWyUOTXt;^2XFMX6b@$gA9bqv=6EGM>>GE5<@|XN(6j_98YM@E6Z4l zuyzSt5xg1I7lfA&r0!k{b_dAq*UK{bOMD#jb{hmxvvGKl}kqhJ%XY$p^mDOCJJ&Y66VE_SQ=*9pQ%I zL!#TY})9? zjB`j)F*jBc8=6O)Dccb8%Cc8lMF4~{EzAX@nx*eem=xH3UOoTt@7Y=t;YZJJ=_4=g zPD4^j3N|0kAWuY|ZRriI3ek#$y+(T<+&3}-<(Rh^8GC^(`KxM1&uluBcX#IlZeTWC zn!Lq$|0Y$qC#dm@9td^9)C)#6ZOc|A|M-?>c}!?IJ*7p{lrNWm5C)UlO`-?UAFMI5 zbgHdIZf|Jj_zIu+Z@)pNsp(XRzI3-I5=@YPds~(Tm4juEY6dh?_@W`XpO@vFLD<>* zLmb4T59G+($cY1#6zKaoNaaEJ<~QFL328spC)oGf&b&=xFh{1L0Dbu#z12-zn*P~x zZX~v*qH$GSC7R^WJOlnd-a$SjvJQRh!N>XUzfr?@#E$Ruph2Y2OfCSSdpsWn>{9Y zOEtN|m%J@awHZ*{ZbhMyUv(KYmS5I_b!EliW<4h!XbjBZheF?H+q&@Ke5W*<#9LQJ z!aSCxfky)NL3sojGi8LB$NtpygWREswgex|=5?8Ic!wUJ_8+;7P`w%c&S!n7p|0gw z57XeRPtE6){och@^LsU`J`eD6;ziY=fH2uH?SqSALG4P|8qC`RbT;60e*0~&+WLvo z%k|AK(mIl*7!u*==H6&fK}b;vwugDId30Wikhyc;ujdi9z~E?r6WRb6Wilu7xM5&r z|LSGB0QsAzKrGppY!hpQ`q}O-=HTX>(IIq|6B9(AWclRv0p&WtY{=4P$LnqAAC`Pd zn;(k&vMIzkRicx&e*Js9QW3{iik$BF$)-k@~6H`(|V z7g$fBCv^P$mbg*fuKfBGZ|D^=S)o3`_SYxa0BS(b+J4m_p1e6@$?5CucD~61u_7kh zgE^NAp+MnUL~k^VZ+K|YK*a6iAGU{nc81cNey?9;85m;o|@Wz`QC?u|v%Bbw6 zyJJm+)b-$%j&hEWYdwZ4_ zCm54IFM}FDa@e*__78|^>je^L4E_j`M#yT_De0q@QE7fdI?%eR7@iU-vYs@kPeyp9 z%K%@*j(Oq&{<;mCDUk|HR*@G{)SsQ?s(6pJrHoo4i8{Y2b8-(=S3Oj=R}lKvnx5x> zweuR$$n09)x8PaSSsM&RzPvKN989>%63e!jipz;)m-aiq!27lw5K;uaQDveV*_`tG8tZu^UKZag^*GBDOux)R(5%M-6Wj?vd=>c zKQLWz=rvNW2Lwtv5lj%MPJ8@3Wi!y1mp9Df0`luDzaQtEj%#Azu-JR4MQFl2T}e(z zG;SOCsU-LNu%2~qy7Bp|fchzwGh&QN&a~e)+CS8$e=A>tr**mbmYa>a$WN=F8^}${ z#M|pmRnmn zjxD5S>kW*&C|dNCB{pGd*o|Nb8LCGO;jfxRW0+yVV0K|t4C+!WdkU^M$G{82H#2MOm`YaDr}SsYt@ zey`rRv{QM?eagp*xyey{eR)U!I6|a;05w_yuYO?Cg#T2aEFpC@FUvd9{8Kb#fzPY7 z5K+3{**DzD*dMO~u2KvyJIbPDUD^Zx*rfz9vaOCWW2ip#Hg#>b-ky{qe)BR5@p8SI z;Km79%dm_~JIEM&fkzruwlByc$G#zLB;sm!w5SUD+!{2RUsPd{1t+{N?j(^IDed7n z?C8vi7vF?Ro4a_7?l71**V${Yyuj8KO&kP$W6Emd)}eCah;L*j<)Z^S)4{>cPoxbd z#D_6FHvDd;?bY{RZDBiLLL=ZV#@6(t&ZK>O4zNCa>|r0hWnO%#lT7Gn&i*8bJ{+nL zKR)*hK5|RSjBCq?#EC?aSZIa~xoZn}!esE*ytx&i4brJpf4 zszp$|i(L98^N}0RRh-?1FYaP+8|UC&^6QNJ2ZTiUVlo>>6tf$;JKxeW9@+t06$5p4*?#oTO5?;@tB&`}_g)e?`XGyk~?3><{Y!BA7j~{wwFEfU)zHNr@&*De( z4A(G1D`bCNn=xbphx5edkNxilf3fe{E2~!_f4#yE{cxRC5ihSUTbU3PB3+-aoLeVK zQkJ~OstUhLWmRQb+o6$R+{v4lYVj z)1VG(zIK$KbVfs&gTE9~8{(@}!>@x)N-Rij_1PPwp*MW$@BLdG1X_HkS7nC@ z1nFo-bi*t#LNAeOm&ilruCsM>;+FTi%ZzgKuISu{7_si}Y{og-wm2$gdk7f?KSY*ZU z5(6~+Fn*8pjX4xI(J)`t6En8jB@9(g-Q3xQ2Kfhfs)eVnZ|~?0J2emeMz2Mva8fY~ zW8v?@>+6ssQ74&XElH=r z-f)KxTL0g_`zHu%!gQwV#YgXJjxxN10HC2RE;o-;vAcd)rGKvt;Xr=d7M)6Bx!h6a z2yT7I=1&>-$KIFEy1y(F!7yU>x^XMbc6V;*2u{XIH4gN54!l%MuIU@+)=Xtr`?{V?1&x zL(A;g9t*!>5bEk^ z-MHp3S|)n35Uk?PzMekjSW%zG52|Y~e7VgiGshCF*i1u(;q(uQJCjFsNF!3Yh%hg{ z`5(#kzyiHPvd6k$@8_a^K2XMOWu=Lv@!?`_h7rN;+z+;HB1I^hN^cx6dHUFBbz#c{ z#=wi=TJOAZ8lAv`@8bp|lzR|SALE0i2mto46gc{9cr&*EvW^fm|NMPo< zsTfg!1bH5SjM*y&s~~_?Byx3|{Ed_?v5Gf(2YVLKpMr_^-Na@72@!V|Nh?_$Tswmv7z zLOE+rz~AU*g2u|rgvq~ux_37YX9f$S=rwe(X(O=s zn{+FVM)l}MM43@-1^lIxrY%4v82|P;M0d_UH_1&Lely`_xm8X(D=<#`^@3r|mT>yH zRg3qVU2Q9f1DZ#_TjiY9ox*H;@=YhQ{4Q<0>2F7_lbnyKnNLB!8g+TyHmdcO%=kvG z78GQHM&wOfnEM+mxHe;%dL_Ucg16xT1I1h42&qI$2AEYkb)*8M05{xruLm z1Wu+{Ak4JfLrAs-jz71Z^}`i2p_8P7{@rXt4;w}igzqm4UII{^q|LrBzP&8sdX`U1 zgZ&HE#2gEXeVsWHDmXn-Y3~ZL_AMV+0~B{~zr=2KhW8c2BcrZn!lpZ3Z_Wku$Laq2 zw-E<&X{o5&TK8?{XW{vTY`||lLWgSZ8prr}c4urFu2Jz}KYVZ?-;{G0RpX`L|L(|g)nr-b z8@>C2zWDKDrBUOtNH9Aw<~J?uBkZd=6J~jl-((D|?Q@t&D-WPSZ;4B6@us(aqiem~ zQ2?e;^Q^zl!l`*uy{L*!tM}}eSu*VbGGF*2(5!eucQulm|IL|D@E^wEvz_tP{o^#Y zQ@o=dKfQFVN+`gqL?3_e9JZAP$bx?{zO0DuRVrH5Yj++7EnP>R^Nqs-D9*D&N)lZD z4qx*0NmjH4tlUnu)Yglxcy_F6{#9{-1Usx-lf#OsYjQe2_!nP`w(Jn~8#hdU#hylf zI@M$v6XO=F&P|Da+4v#}FjsUYIIhx@w`p14XUn}4eD5yU^3S$S=lUxUz$Rkdyd1na z&6KmJ>}b+s)fzDd=hcGR%d5?&;Q?{`%0SgMY}3&YoJW5>MkPoA8~a`7FcgE(g+R*N zC*(s46a>l-QGL5;FAVx%n@Pa%9j`LIjlv@Ld>Q+MCWHnwkZpM{D{q86PRa^QqFx_n ziihKSb|TVK{N#5+!}s$R5u(}Nai47`gTxEtOGh#fX#V{|kMC@E{%ghY*ofzS*!S67 zta0_mYdZa;yQSDS$j&}=`m8O}baN0UW)Kl)I1tCG5&KHnfRHC<16fol>uwkZkYt+I zBz-sSzkfETfsa)J!m?k3_#vSEiyS$nayijz$}(gyZ=3V962CpqfGsZ<~-GupbR_n zOTNq3b>`uDFJRen^Z{X5HBQ?Gig_64NFAU&+XQVt_CLhBm}30zU-20w+tpS|r>&W^ z?(L)FNp^;x))XNBXWl?~_lbB3i22Z(lg7HXyGrO1j3-w@_YGntY5))fTk!AAPXN+n z3M9GB#x)p=v~^1c_Zl-P9O`}W{)zzl9m`$OVE$nr*IUBsLUxe;oHeZt+iF2_v}%y* z|IPzGq6v}j0*%j{mPKkQ7J#F}TC3~hE-Y1Cua<=1U>xW0NCv{As1wtmOk%3;D7(J!$|J^WJ)J<5>MWx zb#b>0s#U$}C?Be!Q*OVEi-H@<_BRau7dA2zT6!h8PMX_?0ul|utE1qJ zUM2?y7{+O!$YArzczc8K#I~6Rx0wq{ny^9nSDMElhK?t?g5&{LIL0n%5jt(LYpFA# zUXR0^{#O-^sGTbfd$X0V38W^$#o6jJf7sm@$8bw{1e-*8{NRFy&~n`+pg(}15ooGL z&EtkLY^rufA*8^g*e}b_LnJS&7Sq<{8+#^wK5!(&JtQl)M`j_$Mqh~Pyhb#<`C2pY zDd_XncWI!(H6#^{wa;Ao7*)o+x_6X|$H}$5HJo2zXvQ~jos9T7TWApaRp;CpgdCjh zt>QUVd(FDqXO*PpTi8mgw9J!v&v6lE+_}Q9imt=N4O@9PAYnSyXas{-n{z92-V-sZ zD#h3X@J54)tkE|U*XYJAbVKaS+k+si5cKfy+6%1FBL2F9dMM7uz{s0yQX?v@URy&} zj4^A#{&QN)bf4KRLlu+lC)jiA`~(IApW84^kNPt6UoT)a5F8Kr`XZx% z0%GAtYgr9f*WV8Y6+|3aY$+#|LoT0%(sid^HpEoPm0a;Omu_QIe&VZb)NBX;dQX?m zBi#*7>aLu_dv?rrwRi$Sx8@wd0gBCsVT3{)=DNKRozoAR2-zNy4FNL&uJ&6aX?G<- znL7Se(Xw^`;uHe-YYO7z2m;ecVr}Et`nND|en3Bk!Kv76Gt{!DW%~aWYIu0=Zk@EqghiwdpqAeJhI+@WU})m4sb| zU?6`M{6nu(8}|>65Q4>o$@^?7rQwCJET0d@Zr;x_n~c@e)aF!$P9G|azqZH5wc4PciH2}XJa zhmJ=9v`4$!0trFUt!nTwnCf_P?z>q{+>`#hjy@|Wwg$1UNuet(3c|mg+zt3wg|A8u z?%+i-4_7}V>F}8V%tj>2<6*L>xCfTQFd8dVshY{3F!{xY(UCMLzqEN$dCS@Jk*yFt zdo@zw^_t>#N*)B5Vh!1ZZ^&E`{_&fBtfoLZV6=UIE9=oBDDVS5UfkPfdRBz%AWPK+XKa$^W@%fK~0Sa*mEkfUkIt{Ut~ z?W|yu?^@iz%WIoC45o;(fJj2Q-Ivb!jP~I{CV6koFdW1D_sp3sA7f$>^ypM150L0F zL)ekoKd1T7#T~p#l{_l8^Tp^lRn${TS2kQZU=j^_?UejeUP*IvTVJu;%d4?@CdbQ$ zSPc>~h+l$`)L>N9-1{UH{Jab}$K$BD0?jZvtJWXx;Q%rlo|U(k8r&`Wx+3XE=6*zd z_OW4t3v;&v9Ba^6?Am%|6($NqH-R*0y?F|kYd#kT^5d9pLo`A4tIo~1gzA(yEO`N! z(D03-ULLeM@w4Lt7PAw+N`b!b>^Fwa`1B40(!qkf@kXRerwPXM&N6H41Sej3ObRvZ zvDE2(#=VNdJn=FX3d(see!9#BiUq^y9F6Rk-bmEva6+Ie2v7UJio4q9WAu`DwZnqQ zN5Kwf&K)efB&4u)OH?72Zu==S<8?azlu>-~5=$@A(Mz1grl8%iPXZZsQ|MikB%HpCZ zy?)_Io{4D(sdz=gT#>BvM$dk0Yj=d+V>I90gW6EC^hbdvp5I<)vZ2$7ma!8HXNbw! zzFpR5t;6qvzP>)m#qOauRBY3_qGWsg&~#Y=)D+wDhlc0y)7LDe=>t8M;`cQhvBy<` zXIzJc(VyqkIT!_K2s5_kzkj@;T)u+Ct>t{emS=qS!_nl!(5PuoY$E7p4VpaNB4ryr zoB&_#SMjsujU3+7?UY9Q1rwjio$V_a!qip%H@seA|H6rrc`zt<7yeo8H#pMa89Qv`5*PreZ{6*Ac zOgqN_raj6lQfy3ixcc99D_`9BSZix*tiN42f@<&@EWt-JbLR@wKBcvEGL299Xc4)* zSG(_b5?B5^CSDSH0Qc2NInX}?v|WOeWMF4}b9TfyrtdC2jaIc}7h{)TfBK7+{-AcPg^VOeU9I|Sk;A^(@arPfLTk6Y4YAN z2X88F_?oOVU@@U5%k8h`l`jT)J4S$jc!!`pP4JsJz~9)$NqLc|D*E+?pGr_~jf?(45A@LznOiXD%8f z`2?E$uI0Uhe+-QBLzO-5&1=+I$mZ!>d^R{gAoSMe!B8 zo8=_)E2bU_+n126!$AKuHcw*mN#?*X%uGX?0a8v|y5Q&4ZxKEJI(5JVa#kHZ?;4-L zK67l}#Eziq-I4zKBBp#(-F_O8?kDNxA!0sGB)X(ZoTP5$9=-Tggyp|~!}aBE_{i!; zD;XjabMb7OT>Ih-841Gi>xOM8^yb&&*{a)+&>y{R!MXho;yGqo?R8(>i&sov>-oQ~Seg^M`10$dq%4~7Eh{sF=URnC?!-&dgVFpBvHK#>~&sv?M^FMN|l;MM^} z0zC5pOe||l$S`N|N_4#ZsS;+1qsL;M-UcscnZ8k=h{5!6dVl0pS(Y`-&e&W-0|aIR zYd?fm8BJ)`j0PvdJu26x_GuNk3gIwO2XJ&Q@iruo{F!{f=-O@HQ30 z*ySsGC(#E5{_2*#%p8i&>-t;|w_yG1Dd&wc9CJ(SUKl}cx*up>-dED3$fX+awyZk zZgb#in+;IbtMPqEaEOSJcp7WAc&Gp}c{T#Yy#KtaO}{3kxPrzhsxJl^c642Uvn`{l>=YLj8QAUuHX>bD}fla=LBSfyP_gzd8j?hh#zresg?DhuWJv zo)^Q=-Ek=}{wm$suecC1d`41oEnh;7&4R_i0cl^DstwlEnl*nB2`)rk;;eua{a@o1 zmtY>OgEkqRH^seb^Afm@^dizK;W6c?CQR3>=6|;i8YBF;-~mbBkWYuE-ylTS5nM+@ z*dSi*a8|LIe`T@hdIA&8HacaaaJk>hfUija4@F55BsLmuKJP4OP$r_STW|59%~VhG2mFpe(M<-h*;iDWp*hqD92%3) zA6#BSdxt>Q*A3y=`SAABg8Jdz9perl@)Hj0lDL*}Zq59Le`k3DkJ0mZ(3$+1quTTR zfr4K-N#w>U98(w^XiT8?8Z9+avgk(AMB(PgoAU9*ww??K{l(`<`l^m#e>M37us&OD z9N#M<_T6ug%s$_=jqF#}{puRn@UupF@Hwg)aP3%f86#dV*Mj}@P4O)ZXzt#Rj;y}W zfB%$<8gT`?Y(Gd&_#k?W6C@uDT%mq|`7{*v4Q$v@g>FK_PvXz=*HL+jU9rjI>iUXv zIiZ`DdeHCnhi~a~RrO!Yu{aigs5;Z{#u&`B{-+S zWkN>yTFD5s&?;E1+x+j}YG2&z4P;+nG(~rm*{MAbo_;nW5;#KY#On=XXatVgtr*57`xKBAwJ2+C{O0?F z@|Qq0C>Pc%@O>jBVwod^a1JOFrfTTp8nqt_Xe~SPfCGRPP$($K5^6@NKTgVTaoLn< z76diCF73kU{fkCb#8T5Ut$({FVu(X%@{RFV4)cbkyqRPpUp=(ntm5+xqF{*p;Gh}N z1X%gvbq~!dxjW?ncJ#x&$Bkj9Mbq{^{(L>;S**>aN%ks2A5r|T1seIh2Nm$qG1sr5A#(+MqIf`E^D$U?>_lQ_^>{JaUpp4%k{{dJm&#P^uZrVuwT%66OBC(R zEE~M5e5pyOrNO57-oEov<&U^%*S@x$+Zujtn^Bn5;aX=oSdCrM(mUDQ1Ld;)vsyGN zEK2-Ke$0#H3MUo|EIqF_G$DXN=3!di6k-LrvtDCXej7Fflr{8xpqK9)-C7s4wY17*j((=pw_c`=gTsIA?v4@T>GasHqnQ*>xZ z$nj-U0YaXU_nu|_{&%jNPF_|G|N95Q9%fx2FRODC1T>MB}noSXm(1hW+;Xkc%hCwvXm>%={$$Esv+NDhHxpMGAb2*lT6lACCv z=(cTb6gpj?4sV$D>z$^>C#ON^iU69bbUnzcniYef&XB*#Jjz1vt9Bp$nB-6e$f!@i zdv7kX@my~na#FjL9cABocqxz5{K6?B&3L8*4xEW#lLfC`hbbP>c6wD!bkayd(?`#- z!A^FG+pFJ)&;Q=K&?srskO5Q0Rf8yjLU)qaT-FaE>z-EdAxV^&GwSPq-Ht2#SHHpY z>MneM!sA9(^d6(X2JHawjG_XWj9YBgU5WY*>!p&N4ew{Q8kOyn)9sMss_cc}s1=Q- z2$SBs3Qr!QV9m%UILRYED-ns?UCC7(rGIPO9-5I+Hw0|}a3?L2T;-M47!F;(CvYAf zJG~B}SPTC13m^Kwf7D(v%fw8EYXld}?gD~~z*C>T?J1!T7#W%bS57!tYaXq0>B4}l z*9ZK3>2ZyiZ#XI8Z)RkNY@atz>A!aOPZ^Cbo98HsLlod?;|U+#Vyuk{5*SG?G0A?Q6I~i`%p1L_Z?nk9^+V@?zTuj9DJE1`=|0)LuMU~X z^~d84se#Do9L>^DAQB4|^y8X`^^2}T1f8|vE9AQEna1>8tmQ6YQlC$H0z^u zQ5$mLL;|>sI&yH@xHh5ryqe(7rfjGeW|9R=I*BN4+8RaL4l3x@gT6C`gYwN$nYXEW#JmehJOOQqn5Q8d^ z#tx9K3b_*kF-Hfjzche*RW#Q`CFbTTN2BReHjU9knukwSr zPGEbi|3+<@*RVSB5Tk0)5_3AY#$7cO(7*C7j9&&^ukVnx${XaE0ZT>h1T?&1w&Ru# ztPA&=W_OzXrqVl+2J($&xe3~ACWW?p3UGz3lEI=*77YH|7d;x1<9_YnD+9Lt_2898 zq)(nyr{nN|507N^%&1=;?CW~ZHeUwfY@fAhl}c0(w(#G%%Pu35JjH$0AQM3((^p30 z=-Kiepe@$~o3k28nhM9m4F0f%38S6^;U{TgTG+)})c7f$+@jbC3m}xuw-R=ePauEi zvo3A%FKfbm2SbGH5yq|{MNAHT!@rsGv!|FYom^TRh-^T7^qU^XYbIi5L$f@z$!r9L zSdEulU%yb`aT|S;0g&q+niSV5S01JK+?(B!GpC)m{nS>=w;&%Uuym(dHcR`Nh?6=hJ?$L4P~Ijc~b>VhS=@1Z$?K>D(eGE6$T3CA828tY86{@Vz zBiq;Q){X1E?s05;#j&}o32Dzrxx8<#1#&y|3m2axlA{B?!oQAoP0??aP<`8Ah?Vge zpDDA}m*Mfl$Np;d8*595U+vE9-!2O_BhTcEJnu6d!b4G1aR?JaC|pF7H*r@&QZ)wK z3r@ZRBt}kFlQnq1s6eoG@70>gBNav;{YJ5=*5E-kHhWq2hUM>0ck6FXJ)3S&*Z`f(|fFW z2zFzWJ5Ay}2x_*uduhaR0j7uqhjT-8t-j-HLb3h#PtZYQ^HtFg;H)zFY*nKD+1lOD zifpz3+v1Dr6X9mT5lV~T$GwmeJS@c+AJLH$DIkV2h$Iz>G@t+eg+?y^YOz^CbiqlI z!VjA80U~Vlj(RL-X9HHXpg6?4Mc7r~vN*@TX4DH;X%7SIrExLI;rUe+#qjE0z$_3{ z5#`-A8+XPunL2`Y$h@!l?LUZIjKS-vart_6`CqMQi9)Gvt4FY#=kBejlGCyVTweD37muL9o=3J2FCqU~}fIY=2YDsVO=Y_TTM)x6I(KfaLAHF9&FJhehs6nqN}T=`$sVq^%B&tI#}9uybS0~3vN@+WJP71!CeFY zXf14_$@E_enHBUav@aJzeTfOegr0}ioA9evm+QV~7Qf3*&V+0>pU2Q&CoVZ~Gpq84 z3c~%@U`LuQIO|@yZi!)z1nL=$XGMlf71t= zyu-&^!0i4`ElqXdVTn8{Gj$Qvp+;!M@}duaf-QQuwJgvc+X}v300h~$QI3e!V~mjH zwsr4imNFW+w2)?=UL;>lZH&`n%`S=tmV8}Flp}Zi_q&&*?OM+ip!AgS6&1M?p$Ba6 z)$WpR$vJXP9cnaf%uav=KYXfJljoG}>>FGlr_*)YoM0ERx7m-U#{xU}91`))Oh)+y z*bn!lefB8JwT($@`w)ec_Xd0y@C?lyjsH#t#hFpPsY2%Tz1eya(v{v}?^7#S=>;BM zR7bOuXp64sb`1zRf700GGJ7J3SG=O1lYgQX867ex{`MaKfO?Y0L1l>#YX}yZOaXL|OK3z)`m+|HJ?e-T>Zn8*%J#8Q@y&Cy zn!hz2UQTvWu|i5$t@;Q z_WN&VU4@42>rcrzsjA~{^M^#4RiaXtJBS~?jU!H(I^^Wj(6Y@_%fH_mf1p3vaSK4l z*4--wc6=c#ig?Z+?sxH<3kc1l5Ka8@@5mz&KX+ou9mYuCd-#J@XN2HhM!cu6SP1QI zJKQ(DQcRmE{2Rz9d_tJR%XxKHVvGInUy{@<%Cicr3U_Fb7g;oQOlgJPv^4rIqWYJy!^z=0z%QgUr9p2Iv(y{N;NQLl>hQH6q53DmTrZlUtTrp zmh?~U@hzg2Fj_G?JA#GVoIbAy{v8nce{C&3@gdZUf z-5v3`N9`fx_M_)!FejVgfT;HAxH!wtCNvT}R6gk*!E8{WKR<&H>2mjdF$fdOPA#>3 z*;#8D6GP!!IZ+vShusr5Fo#a?##4o(I{(lBMbBZdd>?_s8V%Jxw*>C--}|f4FS|`= zsDMnAM|gexK8FJ{ABtPlnx|O8sX(vMWx^4%JinwW0oejMz!1r*RH!2|>5N_>YLKs6 zvpg$rm(D&uNi~j9@cUz#I=$l@AC_pHn?6jA<9lF1^lE_)stq4g^x_=9GysyNlLP3) zY(4{5vIct(StXLr{h*#O%BX19Q%O1B!2+$FcF(Em}?P$m2F1XpXZ|Kj9&BEyEPcxs`=ROcx{RpWZZTf4PuO7rlNlTtW1aY9<{<^LZd!9a3p?7Pp zcS|Bv5;qF6mVRGF?KnNfx33wJsIkU>Jac`^Dd)RZ{1^rqtvTH_J!5L+_(tF#kU2wS$OejpWbWzdI? z#m)S_@diUo^@ewA?uC`oZl0vm&H&2Pb1XoPeYTE7Vsd=T95swA=IPY?=~R2QBI-Dn z?iIN4$|QD;U9aM*Eky=B777y6NxnP#8ocUJrtfzx-Bs%wTgb5BHJB_hUU!x|YCpld z<2NVB)0iJlu;etlOXB6F56rjPZfGa;eFQyW&by@4T$;}Q z`$zu(NEibh@Rd?^jE@XSYP-au<_arz@8p~~q;1lhDN!4@X~KzH;X34z29|AP zWpP$z;K%Qp@@nDwLGep2RfGc-tn|jDGh~QR<^{GMX0=C62jRBDCJh~9BBx0s`38Q1 z`=|##=~H_9t{A$B_4408zXOTZQwbNu%Y^n=V`H*cM_Dt{8{@{1pWYi?26Q2+UQS*mZt zAYWdA-g*DCkVu$ASoj!a2loBY&vdrK5AB3L@*+8^-qeb}>Ia~WsDaap0#A|JNU}L5 zMDMihJHabjHQBt5{IIMMO*9ESL^wGf{D<2DQGgb69e?*U>U^zY}t5P5rV^rF;v*)y5M zPl6JkiWD?!|47(Yefpr1X;%L=!(Z)f4a#ON_N6UVCbw6wJNI)m_;kGj%N~|rpfSEW zgv4L5CaWKO7lrb7W&Ql(lAn}$9YecOw!=3I+*_!}JIJ>81Clc(!==Lnyu%Q*Zhl(4 zu8L^x?j0#LW>MPcXf{MuN1SxVhGo~F??Q2>Ti`4CvfAd(^ zX-hDb&iqyeP=t1x{dJl!AL5H3_kPG!6^xkZ_^p5yeA&xI_g4iGTmZ-R^KQw6A_8#q zU`aY$O0Ola7vK9&dD8InN&E7>nq?4d6z=8<8tM^{@ubf11{)Dp;suG0C zq47Yx0xta2HUse_0BKH(Q4DiFb~fdG55c*Z|EVvQz(BfC0+Z>{5d84sAop_a{+*Homa*38F-pF= z1bIKHsj~d^hjACKt}&RUI&*2s;C&nyY!2lbn8*5(Z_=p2r=o;HufIo1uKIydua^<( ztIJCdZBxyx%MTpjmaZISk-YL#XVkt4T|uh&L>>8_B_XY_ex}a_=WGcaJf5Z)X!hfCv-hRTRugu0^^7oaU;uam{!^H$6j2M!(#0!4?d>9$- zl^Me@3d5=|mjv&cmLy9Yvv|;iaV@-mj^PH$p`~%^_P2}Z$g>~q&;ah25&RT&bv!D4 zlE)7v(H-7N>uR^|$|2p!{?6RNm6St-q7UG>Pqh|mqYMR18E?hP4$=^@!4v?m10D4h zGEnpLeI-g4j7Gzn9#nhV!OaU3X*&S$|NYYp3QzEdCjr#S0a4 zwyXr#4SoUqd3|@Ss7#-tKc;2cnCDZ@B1r^5a!CuESCgA(&&y%C1J`S)*KLeI@=|J$ zwm~{}-~-Q%5%w7&B*o*;x^wZVX-1zp`hBpwnEqN_K%$EZc(bz0{88dy*vZ0VJ|WmKma@f>fd%Ag zeqL?)V}lSgtwyF2_BYFOm#s?ugE3mH`ZsEYfh<05p_`Bkm$;^JjCl;^Bg02i?;t3F zU=e{JOw*#VZhzm#HX!&i6ojRxKR<)>`xQl2DIe!Vu4cAWF)%+rE;8U(ng$>r0^L)s|C*98gQ-YN^IThgX$-Ww-R2IMmFm3w;0H=Q4=M_GQ-O zK-R;Ek?EWzdh>KnC9w&wFZ;uS`zHp&$UkY%9L@FQ zzfmyo2u+X!MulgiIQzQnIFdb^!85=c$9v}UzWM|vQO?#xUmN3rmg!J zY%$b_I@btS=<|+K{s@eBLoK&A4*EESRE1rP=%-hQG4i!RuHpePzWnV|J&Dts)Ltc| zz3_O8Rnk;Pzq#%IcR-1( zCqoT{&A$;Ye$pVwMa)j9IbkJ2kpx3$egU3YhY+oth_;5(?U$Z?`_t-A6-iZqN$&ogd@Kq`)IlZ6a9F95GwYMH-M)Hf?3h$>e9;V1!wPa! ze)M=J0={d_bIz~tfX#N59BwC2;1o9(G~LnmVbiKe>FqzH3UI*)2+I6hXb5dw0(v;RaCU9c=dKi0e5fC<+pVJc zo7YH#M(a*e*B90GGGcy?Oe;3J!+;zYl%0x$L#a*?t`#| zh&o8v?u)GHQxO0CQ!mJPan(@{&w#zSh$Tp^KY}uH2dq0ero^7)g6q~L2E^<%h?V_m z*D{3AD|vtnK9*F^UfH3Ve`h>%XCSzByqT)+c|&g08~o-4iNK1h3i2nX5dw|S^GH}m zuzP%$tbr(nWF6{4W zqCPL5f=Q0=*PIcS`<@i&c=g&C%1_DdOL$$s=~1llUd_E>tKjd~z_2S*yf+}^ukLD# zG5~2)rB~#SgTwWbzOb4p8-Bn7i_^KqC4PFp>8HJd1W3ne@C}nU7q&51dKT{Hfo&FA zjLSZp;zMfH1GQ>t$9%3y&COu8J@?Dk1cX6yn&#}nqM}fNvYUlB0m8k$qW^C{xw{Az z*X! zEjF*5r8n&Jg-6Ju;ZeqFyB#Wk0^AqLImkHAOGrmy{_0Bb=D@&y#h{MS^~sjyQvyHT zIRWd}V1et=)ESYKJ^nSs{@$A{(PdFSbVQ6<_p(efJ~9p7CjBMHxvBuyT1ZTJQPMF> zxfAL$wjE%<#y74$n=d^)hC%EVs;qg}uI=wDZY zl|x;Yay)6$3iOy9e|bfNk42-OB45w}OWIS;jx|FLM}^7NssUU-%V`E*XN14=;nnwd z5o>oKNFKAAGpER^4`HO?RkU~c05Rn13-ws2s>;+nJ%cyykOF|l0PTB&%RXRI z*Q!NrYo-iw$S3V*>$ zzL8*5E{q6^U{qT z&>Ad+7u$>&vEtuF=Fr19o32WfSh)7Y9m@M`?4Ra*4$iHd9Tm(14FEVw6wv1XcBh}U zXZ>IUtU0H;D>&dLr&=n7*7n3Wu89o z28sNgZX5ku;ndH-Oq7XB?=Igw65Xvki2QYfLH+FdgHR`l0pp735;M}nV7k$n7zgt5HnLKIt73WH%>6wD*Sv79a&A0W<(iVnMYBFHb3=Oi^I?<c88J^YOPe{V8h?Caz&nk-XCjB={(G#ZLwbs_|1aLmEnGGMAIKEP1`NeQIO)qcNT;I93lAm40MY*kP`c zh|S$QpMyY(W9+WFFi`+Y!;zjD_-Eeyq+YbBzqx=`T2cn9K`Kab_>@4TVq@$wIbAL=(vlv?_3 zakcK~$Nc{E(u8ae(2{Q$hV!BZV_L2cm7wzPBVv5%;uHq|jwD0sDl6x|s@>0y;&Xv5 zt!aF>sYO8TgK<-n-`f)_iQ8yheVLUKr4pz07KSmMJCr$gl=hjXMTO=#O#%1Up^)|E z`g|S`gKRF1*!>317J6{<7_B$r*P7f>igW^4Li^eeoFJ(u)r)Y0#iX|Bjuxrdg*o=| zj>yTg?~A?2o1WY48!fd@WhB*ps~;bOVy^}dhy3Y$9d6-jak5@q&L83KzkTG_^n5tI zSgn{TeCu!X$d5JYSJlMurZ+3^lNEXFDo$9}eMEFlt|1YFewU2)ID`cbYoBj8uciHQ)^7ExBf5Et!l;Mskd2dPe% z{fkla50T}`>bLt1Ah~=n}?N58HyVll;O{zLT$k z(`d>G+90FRVXA3)rfWY+^(CLbM+yBXGz!1ftwQ2uN;d!pT%Nn(`uDA(hKPqUv7*>S z%kGMHYh|$big8M1hXRPjw6!6@(+?plM&A}{68Hn98gzJ-2I^`-#a3`~0{N@;ir2@H zgsqI+hf~NWU7tt8P|=o@bBihXXdK;V-)NfdfDyjN;TtS*UZEj}7$EBt>ICtw&jr?6 z&#&&~8NFP&BEA5ubQMwGlgnQej>4m2+dMu2m@oHH+ZKl>>uSPhpq%yqPC&80D@)5T z*UoCB3ucEr3X6>lpf4}jOzfND&*m`Qp;46gcuaF1dZnt)zl&QoVVp3NdEjx`)aRf> zfOX)$9CTa9l78&p02PwcYh;qK>3{#sy0fQlg!ckH$Q_=U%%fDNt8fo`xlEvMGkWc; zqj%G%AgjH$?OG{;+=l4}gOPn_5e)P=;z|VJy_y9Q6B2b0($r<#f?7m$7WRB@yQ?P=gT^YT^RfZT&_dhYp)6BMWB88l=WM8(TeD08Oa*18TVlD zfWo(cL}rfoA?ZLz6{>sbl|zO5Pr&}_N0C>0>tbX z-MaJufQgLXYBx>2^A=mIBPy4hCnb7b@MlWM?%TRg8Y{VDhs{9?jZ-qX9I;4vvBdI% zHqm$tRtBEEVYN`x*|G)m*qEL5*-=&9- z(Z+s7J+F)}SGurW=c@@=PFA}&me2P~)6^OjQ-ICI&AV2RJ zTvdZtuO4>>;&hOC=kVj_2+Z%%apo<&!h1uBSjWcUovU@fjqKrT zr+;sy4gmk58~FpwmNdx8-}p!RmgdVQ%u?+LuxrWg4ceGO`WI5(CF&{?nT4NvIpJDe zUp0n5uLsC6`@etJQT?y}fEv9XwY63ZEj7v?Q31n|#0Q#IRouKMmSxlHLVeIiz`VS} zS$S_kw{ICGA+ovV0iQ>GibD%g#o>VcrKiYpe+UT>@$?^0;z|Vs1@xAxNE8 zeObFm)G4wB(kpq$01dIh^zk69Qd2|ZcY$BAPJ8d=g-L1JH6Up3mVlrs(b;{*04v&n zI8!G9X2}i>PTt*PFv7z0NE%KolUhl19!eY%W;8Z)6%YR;_J9A@AU$4xOa?(a!fp8~ z^8@?{I0;fm4SFtxe&A_y=dZZJbnh_z!^i+HKK}N}5Pyc~nt0V6=#yxLkgs#u4w636OOS!#(@i!9ybJzw_*;BvP$8mFbw*aYBV* zyuRKL@8A;n?;jac?x8QaCVu3^PSwWKJw+J!Q@?qPeqK0UF6E)=-;wtWmY`6iqo_gwK$@d?71Qg z0{j$^lT@oZZeCK*Fv}wOZ>)$0rJ`L>e?>6K@74B3KlF&Iw%YM2R%;ztXfU4yVDXf5 zpd+Sg%vN>to+dk6=1dT>`+T*R+ND9_T-ucwkB?{B8B*}oA$)^1q@QFnI+diW#Mo!3v6SULocIwx&x*gUjXHE$9rTa9 zWW~u6=Ieci;)1-in!-eTDkb)LdVVpf==l7xmsaGw?icst^z*Dabao-*}sXJI$6x=Z|C2aK5O}1XVN@Z z{Y@cxTgM4W3P; zU?(CuorQInocy@)&kOcQ9eOH;4X)=GvWceMYZ1|QOOaQf@IGPH+44GZ7=&n1*N?DY#` z!{ClLR5W{5;!FpeeLnGgqnI&K@=4NE z@o;_eD*VKilhSr%8o-J%cr?NF!-kt`u-RkB;t(v+KdvNv@@Kq5-&FqIp^B{Te#;NE95AvnsUXr^& zct_ae7};ar#$9ZY1M*v714`*IeX}{1r`H+XOnQ8R=D`;@z(iD#r*hX`rB*>$2YmR{ z{m_;At2T|*0Vg@$A^Q=-u~IUfB%vCK^K!IYLmACm~90`ZEQL!J##G4Lqev^M|y=PZPy zkeRrQ`9cn@higYBXO)n_?G*z~w&(LPD8o;FnQ{ecgzjlXCe)6a^Ufz)qTVzpp4Dpx zix=O-mS+>xf3c0*4(de)Q;aFS0AI^FvLXB`7<> zFSUuJo%zsYRlsMSA#{{{|ND0aYC`-K?TDH{OjW};%Fv5~qSnOu2l*Abprfr7aIHue z)TSt=g!{Ml4ZaL6Z2CS@WxPH(gKzKmj`UEg#RTL^19?MZmx^;yOxw9Uu+aChrJiaN zJ}s_vvdH!8spnQ3kuO37=4jp8s1}Q}3T(&~m{IeKZ!3Y&UTXRPh)Y8Glim;KLHbG= zOAvMO0q*mMn?YC@KK3vKwQ0!0Cxxq&I|sWfgkW}O&rD5O7ws95 zYp;;4DuR6@g#MUcw-2!I??A*n{6XQj++^&?R6((oaKdxT>M=(h%iY3nmS@HQ($N4D z&?7G-j9Sb_AAl9Ri|fCC0>F6%+xz;$zw~fxhu=y#Ka&(M|H74ESig%!GBxv-fsPi> zWF=)JH;dwy^+M+&Cwf)NTd%_)eYK@?d{8BTbF;K(_U3QX+_Y;Pd{S41uNCaZ^L>|- zVs)bEQT|6W5m`wk{L4Ci)ecYToI6lf<{jFf`}kC*BZa6eulkN_*LmyJ^8GYYmkz5m zSWD1gioSNF~VGsRt3{5=@b~p!rh4{w%j(1EftdfT?CgI zV=tR81LoJ_JKbbCHUS=5F?z_n+)WRdqICJDh_}MHL_R7E}KDO3?OE zPn$3V7rAmPKlsD+E4r)plk zQ63%H4dmhk-NVr_RnmlekK8GEYBy`LaQK43^nv>`T5D-iCII}dq_$Y99OL<% z@70>#Z-B{;h->L1bl1&P(_xDLQqO{>G%&2H^LbtyW`D1N4}a=m-FHt+ZTWi+S0XEn z(XQNiy-P@fZ}iTnvvPQNL3(BEk55VD|GqC^8d7?kHELK@b_^_R2gtp$qi&dIRuOjm z3D}}pLZlNsc8KFoYWcs83GAjfygvHVw+{3CD|)wl6SH)1_wP|0y^@u1ZX^DM@69J4 zOpMYzKEnN1UxKN$9VU?L`&l6(ufIH1eWjT8;!)hq;!8D%Bm{SP&%YbRdl&m?jhT^| zt!TDysx$774u^;)`@9qZiyyF8!?C=1b$#-A(NZqBZv`u&uj~#yPjP&>5fXeG2I$9) z12&iy9#UwN#f;Z-fdIm;UIj+c6)F>o6o16-;%(Q9NAYi$&b|bD4iB9FQ0$6q^Yc+Z zSBDTEC7s6{zK9S#tD1gd@U?4YS<^9k8ay*afEVH2(%>B4>z1oGiLU+kZ@bavf#@cS z%bU30g!Pt0@b}qDyp;e~+`H&`8Oh(2ln07_KD~sv321+`hW&k%@Rx!Q@FN)`H@5b_ ze-T5(RB&T%!C=WX2-4-VXnMvEe$h3Ez#(Nb`Y+2r6JQ8r)A#9dDp?FjX(r_H;O|gO zd}GBJn>zgOpE*^`VkQfB<8lZ8qOY7MGW0Sa&9tuqsDDV%qvrS9n5vi`n0CwTfwrvv%afuR z4X~+A;TH<{)da;?5&VI8W6Jp{iaZ>GaY}ppysLl!E6&Bu+D;r)$b z06)^Nt;aVva--qLy3upJ(J?NF?{80F2B2QptCW6Rauluj=7Mn8g%(OtFG0B6;h(B% zP0%T3E-fpl{rwJ3EiPsp@t3gF6Z~nysq9DR)QvKzmh5@>^m&=}b$!g=9$Ke~9ZFJe zsPhWkWNvCec;4$38RN?1KiB|mg z@A6(>rLdpg*)GeizCWnn^cS)xWCoZo9tX~^AoZ&^I-JlEx_;P+k)Qk^`Ht$ud)t^m zi=qtq#()0w&8Onc9FaOz=Fn}OQGPqBe}4vF-%=@Pjr)qGkDX7GiQ0rnupQ9~zBN>S zKg5<}$jV%R64_t3{*IJ`PHP_@Eh3VS_ieCMWL;4}{p;Zr3~hlCRMaml%TkQ$O8786 zv0bbCp?K8=)Ndo@KGDUahOogc{Z&?6XO(hh=$`V3DC2N1Y~(!lGlhy)*<@$(^?Y+T z_e%*^69=&qK_os0cAzP-`7|9mD|;WwG;6+BGdOewwMZUEQa)f1_?~$J9{ng_N^=8dLw*H1whnxAU!BgXL z;}?5Hf!u$#*aU+7vdJK5WIsTU$5ZSK*G)y1$Ejf{a7L?s)xa+Pb@_P&s()ka$PQgh z?*tkn7SUZH&lbY4t@^OuW%eZ%+>_2KsPtYqzF2wtntM78iy zU_aJBpU&wv&Mn^PB{7`g4DU@GZ*9zkHGXS6s@vKjexBfeyXmsTc;UU|?;h{bUL1?C zctxe#T6{qiV?X?INqK?W)a4g@`GMT{kMzYnU7EFUdH6lA9BfdVd`-F3dbZ6A?lvw4 zM5Uy0e0b|u{46n1uZ}R3H=`Cr?;ZwE&j0=ujW{QSIHka^=m%tU&PjEB{T{JhAr3_h z)%IfQTDsQesYft~)pu4B>G#eGiB&55=I~;(3uSgt^WQ(e#Uo{`-4=@Y9y9w_6E|>A z|D9^Q{mxOv+kR!`SRjssou;Kw(yjmAQvRox)D_kaJAK67(*^K-KmrM2s!HdZ~(B`HT8o@<#tTUW{%^30j=De7G-a@rg)dd_%5MQ zi=y5W=rjmw0T5L5u5Vv3JLYCkaK|q@L)&i6O5T|R`IClR97W;H#pR`5#u2|_3pvsi z>%zO%i9`yuv2gKLG{$?jxxOcpzoHEQH{Jm4va%s89Y+3ds*FaW1=}MiZHj@YP zt9z|| z(F#ua*#xqSa3@V@74QH47@p@q^Z$Ao{okKK?Rr*=uK)Xa>tx0X`%#f}Q)pG4;l3~S z{;zY?|N9lKQRdtW{=a`$1*hoJ*4uCo`TyQ#b{!!Pdd21XU5)UmsABWBDEYq|xrE)q%Utlf$LN{|xin(*Jh zzuU1!Yk{?{Dfr!v(#oNXiK(ZblKN*HML4e8R6H$8^E2 zaoIHrf_@~f>sGJ$+tUb7?%&+Kw@tcf@}n(?KhGD7Q#w3^?gg$rI{unu^_vxczni>& zBHb*UlK5a)|5ZHJW54=e+pe*H8SsA{x)dx_7fkzm{c|Bix>~{BDv-i_Utjc5K5?!F zbzm}*j4vy;P`zf+wI$bbps5lpMz!P%x;VTH`2T`on_1F9=R|D=fHAC_O|>^Fbj}G` zBvCqTy#-fjNFaa5LO#*Y{azt#S@l=Xys3FLQdQ-SGPTJ@x!z=Ixw;%L@k1zY zT8xiAHh(F#h2hO&d&u=GmR);|H5*vWfYZ#JY>w;R+|4Q80vhisbaWy3UZxSHHIiTG z6~x1RO!-Q}HvnX2y-@k@^(|BQTWOBhBAuEHcj!GyIgZ>5KOED_mMdwvVE^||ENM?$ zajgF@j8>vW%iW81JYU1gTe^MK4vJk(fmdd%w(%mm{3jzj&aS0C$3j z`|Dl!p@+qoh%vD99l+3?tRd8+&m61?)NckPeogPpzNGwh`Y=k#r(YLXXs3C5S`F*j zgJ~H*rep;C+uuv+G7`i=lWMO&c3*Iv3}^Tb=5BlYrgnM@iljKyogCw{%I6J};_}S2 z>@$6FzTrx*&)ti6YvOg3-{0U}UVKlLntN}oV{#cg576EVZT;K;MG=ekh`u}qz)Z< z>?1Ju5WckT@mRwzrnh(JS0-s zjGL>WFf@E9%>9ysx|o4^L7zjHn1QD(!ACJ1B4&;XJ6ZMxi%C?EO_CZ6kTh zj0KkwBb2j?vDUHJb9q{NdEVa072@6fC2m4ZEPCT7-4zybXu4)l;(ZXlKyOjT{NX_WP_tcRO+YeRBcw9eRrp8C%n6q2qTwKoV_0 zutLEV#nF(WG?5~~`-75gh?4tArN2>yUsvJ+Jx{R2Hw~x0nTvgRIg9$fZe84P6%&^4 z@$0waZ$6}#cuODIX8o`0plWgXn+Ggp!)aEI+HbwTe%6*!2+khVmx$muS5s5}{rhXv zfJvamlgMwYi4p||AjL^sRDI!?lk_nAP;5QNbuz8D=BVkGh`7qv3hW0etns&z`v(`A zS@qS|?Mn0)>#YN!uViqml z3W=f372u#hh7M)F{B35g4^BKcD9_j=Y}eo#|DA%P zL4vmLLnoh$&RxA4#+;V4H$tvw!!~Uwgu^RZ{g-T;NGBC)8v|~I4fi1?&wu$V1x$i^ zC4-~n<&>)KE8T}+5|$x_O>uyTnD){5^{3F!Ht`<_ga-&_?;l~$BlviZ6Ffnn2FuEp z__Bm;^CMHVsv}rBZ+vI9V=?#i!T(H^fp+RAip}5o`mmVuL@t&-bBJ5wV+Mp2n;^uP zQUjhnv(VzrfG|TkMr$GbLEpnx%lg-}AU(bAc&{s(ejt#3ALR9bl92QyT-9~F&wnM3nDkf)zp0d>G-7@>BDiNDG_@5GR#Y<|LfTekP(Wl z$+h8b+Em|RpMgLiL{AW~__NPw;dO{Il@V(5{&Nmd0np`W*C82~V(fpdJK{qr8T9>C zs>N~jIGvz2ZmgJ!pL$)PvEu@ZEve>P4diRWeA~Fw zXzXmQa`0YF#w8@#-^qy;m}0P5cZ zUN|wO$1-!7bKGh#5-*a|aIa1JI3~iF=vhzcf&|GwQQiniF_kuac#CzEhY{e zPx|}OpwME|Ip#2)LNAlT)d%>i|HfIMq(^Zaen~L9S~c;;KKnG3Fa6A#LJ9F8w{7Sq9WHVog<(*2`F z4RL%9_zv(*eS0E#>XN#aBfDeg(nBd_u-m($?-~h-c;oN9A!S3bA&68v8i6B*IGa8r$03L2Gk7M`L{CBx&8cg6g1{R10#P@3F@p#^(OcCi! zWva645}GDFP5C#N;{GpaVcYlWYB?#eLa0oCQxJ^@yh3gqJ)wQ~=<`syVBX0hoqk^8V_C>! zJ^pr0RNok;Uv5Pu75+U?SFA8@Am;CbayBi~Uo&^Im@OhJ~Z( z9CE8do9lwgH~fLBLuDofa)UdWh4}V@tc2WewFWrit&sj?9#${_F#R4f=7Jt_9rxhZ zaW-qzLKxoAF-)nXTYw)B2ak7-4@M*fKg;6!RZF22(Z#K&Z-wBH3@3FQnO}%c!2eCt`2vq-_g_fB(bu*5(nBLmrjqN6k$L-1UZdHZ1Qrsfid<0;`GjvVIJ$HTVN!W=x#5AYMg<`n<;Z#=AX1KX_5 zzyxnO$J;_s&D})J-k^{7&Ls4i8+IrY_gy-J8z5m-jvsB)MAjlbsFFQ{Ugqw?}R_rFnVC|ZUWA|Tk~FctanRkJUM86-^8l$OY6*AhfAxC ztwO>{7sU7@3raEFuPIMgs+*YPB1w;(%E5l{3yKlWN%Zpz4YX4 z2iCT1>lr;TzL9dh{aFN*(0|8Dd^^tD58};$Dm4xawk;q(4sV9EY+}ju(QNC*oP?ak zGi>H%URx2^2W5b4u`Zp~(So~u9s)G9{n4F4RPo?+3|>WgooGp401_BRB1x2rK7B~7 z_R5c2Y2acMP|4KfcwHMPKGmuNqT811&d2_FN)s)ufhl(45qmuTJrAKCbSA7-$l-ZY z;k>TCx-sTONm1RGC>n*OoZ+qY~K${@-}Tv;~h5XRVx9a|Ukn*4o39PhI4_{)6qt97ea zs#il~&9ts|emO+8>T}RZ)c3ozaDK6+z`HM1n$^$@U+Qs=)fV+@1xaHH)~JW7ZyN|w z1il!xLe^U1V3h>*3|2G$&NxWfU>Zvdj?EVVXl>rFe%|WUl4jxYRy=bylzxMuIfVqD z^VHr2xWoxXN+xp2l#y-QX>doKkD1PY{}wkx+V`exIdRoW5{~BAA5W}tPnAD9jaC#D zH4Jc|Io};Wap=q?olkXgH^m7Z>HV%53_tvR^S<=X!Wg(N5mdk29R0qB;B@lQz5G~p zatHSttNF-uJF_=TN^15>b*Zu}-5kft&&+hM34W;gz-ezy`ZvpbuX7gr-_}F-zS6;q ze(!%rB2@dEz9ByOcYO0!tz9f_-WvB!#@=5*Y5d=J*u~nBX(!&C2cMhYIrICK zf9IcC0~7lhnjGVc54WA_wo~UjpF`xEi4{!oq_IhTXZg)B0>R4seq#+=a)#&K{E>UE zEz%%%6yfIo`)5tQNu~xC^yz1|1Q~h3X5Kdh&iTN>S7y#62&#YshBmbFqq?#cW&a46 zpUt`Mu@bkbp*#zOL}GABjaDU6<)F^oE|jE(ZATU$l)IB`7QFUVn#3{{WuP#20|tr2e$K zObzfCPbu6{t`TUBo26X!5IVMsQ%!T3A1;gs{lM zvPK-OtYp0SJA`c1jW*ZfhuLkUD;>Y4Zee~38dRw!f>d?6bL;fL;$%E24OzLP*a`A|10}Y=Z&%gpga?_2m z@9}gv)}jLGg}kFZc`W^4#fK=wX06-J4Ma>2e>})HwQVgrb(QpX%h2x*L89P~)u{9A zv7@DTR)L-5Gj8ozd2-(7Qq*^Efh&5JB0HYCe@6vKd#*=FbI->+3kelP{M!&DOn&gA zc#HeWMC;zw@pO}2dlJ>rt@cr^-|Xs*I@kWnP$;|6$N&K-Odcspo?ikC3H6-?M`LZD z=k_pyME=T$5;&GOjkLet$FnP)MbORH-RqAee#RiJR)TlZg-RuAjxLElD14y8oy)_+o8@dqyR*2OC zB5+7VYeb~f;T~iNZp#5mA^2U2?<;lx{mUQqDx9xYXtI)iUOPe6j%UId3t&glEeEOs z)c3|A9Xcgs4n_E7o)vtEQEYa-HWPf1)6ti@l=ok+_iLIz;ZHzDXM{dufIgodRrhE6 z)^Ht8d5i)_5%N7Wdu2&U2ABJaS}tY;r}-^=NdH+qt3a=WSi1lI&7rbU8Zx_l)oA+) zEQEm=i8n%X>1_3MEp0QeuZA@pU5S!c?J&G*2Z5cb31V&mk}^otB$tq)tTJ_!7gH-M8v$;ksm{15WfJHWAd-Wh1q6En1V1MDgJJkff@b4FAUNbG zc8V&S-U_zA>Elit&!(|X_RDpxNS$hw+7DjE&M_nstzM{v84{4lY;*B#tH0; zyA-H^eG4hmOM)o9L@FSw0O3PzthYisRPftLK8jvV;2(AvpYg^&A@sxk4r3`0StIhd zg$WB~HTFY%O>wG$0%E@FzIcs|dD2!tsR8FX@;YD{&itLP-&uLKqwjFOd-Excx+Pk; z{iVUaPi7totywZo%Z`9s!F4^$gr*%k;La0n~;-|{X9O~5R z^lW@dQd$<`0qjGKKR=)U?x8NepqZ;131_L51_NO-(im0pJ4EEX>A_3*R;skTw|_j- z_JUH!IQ!yBTExWh_66=`D(&DmYk?C_yK?@Ag)IK$0r;7J@de31Hv%F|KOhEf|2xqS zb2R=7{GbjP(w7zW?C96;mG(XMEHhl<4k~pjp;u{w%dIf_RF}fHBX!f1zF}N)g0H8* zGA_}7ck2A?v&Svfk?J-Pf)@yJR#NM)p=fVT;KzM~X86|yjkImJzvr6+wMv9X|D!Z5 z=swdA`L%;yQ_K5l8L!QX+I+g3dc%hq@5k|(dTVmXlDuKblAOFi9%F#*N7&BS#EkLp zQ}u0YI}{TR{dGF!UJ}GtUawa}|D+u+&z-(ahQIT!Cm)$FE>|{(;q}+G;nAWl{8Qfb z$n~c@ASsW)=v;iM$eE97QV%(( zby+*R zI=@MikF0sLw)~ww81u$wPjf>-qUz^6>SVyZCwFnXNztHijhnyY_C_X~4m`B~#N}9U zuUn|2g6xjX&Q>m*aU2^c^HK1fQj#|Rtf4fa&N*qy8r$hFNtZTx@!p=&?E5OYU@32` zV?r5$VP{-JyIq53x&n+-(X1s}qV}<&aZ2UYSfdYCkgJn2&Fe#TQq}gqkn){-QB}FW zH5h$OO}sGmPM-CQR~Z#QOh7ew=$$!1La2}%!BtPtaC?0C7ZEs~#DnjLhno`n-Mz5Q ziziEUs7t?>Lkd~KQ>AC`d)k|v`drqODY`3jujZPOeK54d9gNK1mwc-?wxGeM*ujak z2X{(?HVipao`raL$?sL9DTwYs#oZftU4>70YlT)kpCQd*CyE!V8v80?1r|r5rgGIC zf)4lE%tlj`3L}oxWI_?mc+K8Yj{p6u&WR6)qV|_XnhHGOZpVn%fB)G1_|3SZhVs7M=OJ>2 zTb|RtP^F))ue}811aQ9Z4iwcc5MZ$a3R7yXIGu@&m81CY;P|+`f3)pYq`gAAa>}SD z2r2}LB?yNi0P;O6=86Y^qi2To#uU(>A9;36{;k6#*; zudYGr#!j@*mwXSsex7Kr^e*1fyl{Vq0>jF(3uj8GM6&!U&8WH-38JbFv zq>Kmuc1l@lNSB^OOII;~wqqv2M3@4S&R1%y(}?M3`;aSb|0dM2IrGtyiHrb~zrBIi ztB-{L^*7BDPR?xYJEz{Prw?z%(dU7JZhA9CmqJ2Nicy=~o78!R(^ntGF_yBgW!NA( zngDp@gOyO@m${}(jr^RlVuKn%u z4iv4Ui&VNKNsoSq>aYDdwpI(lwH^tBpiHBZ{df5_2MqV6rcF+~o`Ghxeb&^wt z$JfHtc4M<@`m6t4hiUcoh_YKS-Yd18CoF%JidS-a&bhgzrr9377RD0>(c8No@<-~12ryHWCZdN^i zDIgRGq5=0nxun*3rZ&D5{=zhO9C?mQJlb2#b1UL@jB9Y&M1b@#3InR5s zez7z0^#u2&x9OwV)!$0L@nI7CjjZAx3!hu^eC8|Dz7j2Zs0Cf->lCE@SX;6 z;NNfRnB|bC8~B+oV1eJQ$nA6ZMVWcUIQxul({5h*l0sejJeOLUPJ} zEs+B+nuZ`8g24L^Y?^uw%XbZpyF^h8ML92&`m|Y)U#XN>>b9p3 zztU?mLE5J?P-?tn9cTZZKBj4u%&%*&y&QnatUX7kKsZYAp*;6FRN7MW`l-n!aDmcT z26XR~6Q} zsI^(vzIxbqfXpTr-wOFS0f)0WK%`)Vyo`u9IWTU;dm+U1`fp*{wO(~u_-dc1MAPz3B{?Id3n_J-+m5?Br&pQ#r=nwUoWF(ey9{>)S5Vr6AhNA@KY`@BgvRHu$?sBokL1?zHpqEs<`ot`XYnfV;o)HA?Ll9(b+N(g)q68v-)PMhC6k=xTbMA?; zHO5b8X3u@cdsJd*H9o&3e(Ov{!!@;F%7WfJ;U`}MAdo3qi%Y!JjJEhw%J%*%RWHBA zLz}Qaqar9vB5RryAj3gCa-JBNjwELT#$P{p$lFVvJrl|lT0|__{3n`r<=p7`7t}~S6CoLBAOMN>Pd9M}t)1IkznxA|)6f|%5A&rRmCe$Z zex`xWH|5;VixR=>&Rw;!8`0{zMDLapPysqOlsvc_e3SKQXLhO}W9>G$qr8+V2VpY2 zLNUkBPv`B%4wof^(NKbi7I?FB<{|a=_ro;q!f;|A4sk?7VQ*}2egUd!e$DOeb_P29|0%BbqPR@DU zB`$4YQ@wc*99UA`rTlEXI}32d%t<`G+&iN% zlpWwt!N1K*rs~gJmyiIyhNunLLuWd{KEHk7-VP)XFO|_1bb#y?p)dmJVuFI$dq2Kk zpYQK=8N8{Yyhr7})+gM71{H4Ujl@~IMyMTqt?_S8*He`F`78dVwiszS=p~&28qzgR(cgjU6Q8D_`>?DtqE? zYst0*a%`1`k`7vuo|MsbGg0mdWmncarRng8Z+(Cm$uA{VG?b1uJ2 z`B;Zv8!*tdAEUeNZ0v@Yuxo#hr;v-XlveZ4@OMU4{_^e2*yQ~sL&a(-lzWg`s3HGH zL;A;O#^fWRS@m%om|C<%4F+cc8hpjmWQ@H&ZFK|7*(&P$5B=uTQuDpHM_$mSs^8yk z9)wa4g%~f)5b05%Gx?9at!b53 zNvkiTmDwl(@{L_ucw<&NCDFy#Z*M~0PHFZ*m(tP>Hu8!sa4xtocEDlLNm2aPsNe4; zu0w&XA;4+1{giE!zjtid^meB57HUYTg~=`Orx@Ia07)%; zJU1NF&$zx3LvFJ+!8l?(G)(FXdcsEkaXp+XpZug@kxYCJB}%$GSfn zh&EwMI`RJ-Th&dKcif^G>3Retf5AZ(nL(C-vCQ9Htw95qSErG^-cnTvC?mKKzl+kr zQ1DgmNkOHzL}Hb%W+IrB6gA#@gNz}aetv6cr$X~rw-PZWBgEo~$mB`Sm540)-XV%$ z*^r;6DO&iBXKNbjdwD5veTF8actR5D>f80g^?RJ-k2z>vfMrHDAFyXVmCuUzO$$DF!1drE( z4;;EGLezijPZK(`LK&my2HHyUoK6npsEW?QscIX!~WY7My0cl zeZR)r_c^V%Mvzb4T842ryOwtQ^NFY;sy=WYXc+V=ckpa2^@8F4%rMX9P8W7Fqo(B+ zzbKdy|1t?DbtmZ6|Id zP5Cp~ZT|7cN9dTWz-?`c5vjT)(#Qx&j-`eBjcU&t49UxeM(sxJ+82E_}SAs1h7j9G(&#Z+g z2hVi%8oBvY;1{z%C-O81E#zpx^GooAlV3*uzkkL6rw%=x+1GZ>e4JZNvsJ^tvu=hR z(T_ex@JOMha_;ki=3P`jpas8uSu>+l9;TXsv!rHbOFn-qa$E4SsxO71O>VFYyHvq1 zd`OVQLX)MGm^KLwCyMy@pnP(3j0Gn6a83LaeB$jeMK>jWCX4eO-Dc!}|A=qsVs_Y0nS0&&ZOyaFGe zh`5=QHR;Xu3|FvF!PeZdR$t4YzPXhL0OOx1Q4n3(h)`&wVX;G4&`8n?K!=Hn8x4OU z>tJnreqnIWI$Sw9@}(NWlKr<2)rF5eP@GIZqxc>&W;#H8)8{Ym3FLqXonl+oH}oil zKzb9r0$)#abN~CHrAF5P^}_+=+Y1AmcQm&~_oW1JiV~TqL-& z=uu{M)*UCEZ<);@b?{*hHEe?gr0SwJR1RWkl0huJTK`UUKRpQ3@!)z#8?K_UBPze- zwcANxWTw5XMHM*)1N_Io%&R9K=r$@Ed@S>UL?->#=ku&5ILzLcdaD-_#y19Ud}KR4 zZ#An5$s^E6d(^ViOPO{we+4$N@O=e6{aHxKcT;Zq6fNMte~C12{+xFR9g)+_VY;{T)+eTQ?@<=1+)wOtGy-im8ij?G)|cF& zTb$&as=rS4aGq7G{}9glpx|2}H%6D_cTNCjK$yRe#9n|`3t#|sVC>TrU^g5sS9~DS zK*3{6k?-Q`G^BhJU=l4AuPZ|_GN{5$1zK|6ulM=&tWpRE_zO6*;h4dZCd1EkcO3Zc zQRwc(uK*Y9i~ouOoi1{_^G4Zqt43RB8K=oN59~E;*D`}vYG5r`_Q;Fod`q|CN!iFhGD7j5S*Ktut* zZ@uBha>n3SCB815<^$`xIkQNIM56asQQhtK0|lQFO8%iCgwI@npegF(h8nFiiEhV1 zAl-R$sgl3F@KSN6D~Rq-zK%+>6Li<_PI-!Qm+Yk~I)p@hdYN@B8(ahlJHM)0YHMZ} zZ~xh72DZ4hf94XeX3edX-(#EoWPy zvRlbIAwx^At^3$#);^B~CpeS8Up(1FjqK@+nu^1g9;f`Txgd-Ox!#g*eP=;RsG-H* zLl&IBfnq>Gw0JXm`Le4&bvvzGmh;AJ{?A|DYb)aE6oOetb|Nl*H4UoQ&uqTmOalRR z2jO5sQLV#%A}phLyB@0_b(G3AKF0NNkf&47oR>FsXtlqcwV{cOK$6A?5&8ppzIH90 zW)c;;GLw+Cm|shV`GxR1?z+#Y8q1wu9}Z$6$VJt9d9M)~&Wfitmfs5b!FA^;&ZQ!o zQ;HNGm#X$iQxwvzQ+6JAz+81Hl7-6D9c& z3UYJbPJZz&y9tl-A?C71x1@Df2m26e+4KmU!=Wl>HEGiE$q!$NCndl^#$bdYNd7}Cu#G4Dr=kSN-q?skr*cCuajgo*KdNdJx z7)CLh5=>>wy5C%{(b!i?puJ?d%f3Y3r=%+2o*M0vj^l_dGb{mv-kj}N(im`2(?j^S z3AdZ?{qsRcwS(ZZWYU(wh5!CtH+Hu=JO@!CE52-=#hnk}fX^@q0vHIA2T9&Aq(d9M zA%4XTnEoJBhF;`QzR9?5#wCQcHgo_? zl$@|6T|1?m<0txU|FOk3fGP;Fe0Dzp4N2Uy;S6h?kDevIz|VfY-bv>G^pJ0KJ+H`q zsXs^|7Q}tk3;?wR{4#(60&I>M!?dxSVCO%XfM6pe?lQF&hHt6k0HOZ#i~oKzdL8Hh zC6xdPWV^pVa|08ZxP1BVnU)MZh1X82De_Fw=6pmNS;p!y4j{5XYzeaoe`^f8Bu=;N zezlkU>dIc!sYMilSW4Ul1kksrZ=OYC?9DKycYh@sZX+>`9E+q0Cg|+pyaMyITtlH5 zKxN9R;#;_V`?Obf?}g3;sQH(3O7(-l-F*8XwAQ`7nQ)}45-FX``E$QoRU0lroXBp2 z;Djvh1@LLHcL!*NApLzki;?l4ntIOJXGL+Sr%Qm~wful$2e<960Pt%U0IQkDanKV9 zey}J4I7invOwM^;cq&?7V)-kE!eHRQ4m(6%eYh&m;J6thQXs=# zcB?!q$B0F%@H7fDI_g#>8!Gv*2IDxbF=vMGd%GUhOUf~#p9E^5CP4C_$aA)AQ8KVN zp1N3>KxpXtu(i?W*#prK@?dcP?EzNavVka1v4LBu!9dq4NtwX*V>wApjf)2|Qq+iFTmu0pfa( zzo7P##06yj>qs9f$mQg?}$9H(I4R?>#u#$D{r7BMMIf-toNj25JilM@R zA`~xVe+9%%e;dkrT9ya8wP2A;p4in6fIN#1%>&LK%Q#EQlt6{g$s9)HRP z-Z4WAuISs5+oNHX!Or~}(92S8`jxfhc^&M6ea7k;{kZJ6md{+2ee;6Qf1&+>d9fcv zX^R&JN=IscAiLTpn4-Gott?Ro$lzpB^gMaOT46PDG3M7KU+o?d`fZP4+NbID(<<$( zttl&U9UIZ+%!rs+8*uyO?mod&JigzN*4)AlUj0tmb4%_T=gUC#?>XB`p>$3#c0s>C zGH<+{rD42>CHm(%#_iY8G?mc<<^k|MxGPi!`?{1kOzK(D~7zd%e)fl+JGkOkk$)l!^>SK2$zH z4O>%2ZIrlJ{JaSp+(Hu#@64b(w#|EgE19Qoga1}-n^{4iKqym5jF_!f8n_8_8mPp)HCGCm2JkagNkC z-r@*L;&@KbpnK#c2)76o;wYF4=!Ja^0_0bu#={84Zb0rLyf5Ee&u{~3$rBKOevO1F z8WJF8ve*rSm za&NEeNlA3i)dYCz7>4>bZCj=IRCS%fLD~XEXN}mne~sJ<*~zz*YSNs{A~9Y3_Iv1_ zDvAe*t1AB9YrFid^iS+I#BadyPiZz#8iYI(>|f-C*CJ5RdRwHmn>rhSoRVM9Ykh5{ zOO_Wjuyq!;w|>(p?Ebp`M}3^7#p@92q5Ufc*WPfus_H2cbA|I9b zd-GAUK0C-ph75oURLI6O>ev`X7NcnofJK?=p#ReicN;U6OC^J7&*Zhglri&qm zUfnJ712^h)Zsjv=BY#dCQO8?^18T{YIfJyBcN zu7+dN+0V{3GF}v5vl4P}6iG*HYNn?i=i+uM{r3+}WF~=K$=+K);Jgaqq_Rg~Z-d9G zODa=Q?H>?_suNgF{(&n57(e;=^+OE_rtDXLGwZ|*-WDM0odxjlp*2tDN+{L8)#h5V zzIkiDX+}WSVX`IkbJhN8;Dq5Lzf!`p>PKoqe|U&VWXA-19w@-dN56hA)l8_|WGIa{ zJjkK4^%^^_`w(JAKsSGZDbZwC-0TwAk37DJ-%-E(p#N;ir=?A|NFN%rDo%%3~t-}fkWBt!lX#EhIeJnzOY6S z+}(}PNr#LX>(ueiM;=cbO9>{fv?p(DK>IPeGvZVw=b~U-X6KUT((nIPCd?Qslj`(P zLSGNsvySp~m`J<#ORnK}Y~r^jjg|1lbjzg{y{l%@IrD*fqW-pl7VEwkH1hf5{_S3f z0nFPK?WzGZtvD@$Ny{7?038MFQdI34?3D7g366VKfBl|MX1K<;C6?D`W0A6-lV#W$ z5u$*3`;>DfvAguKQ4jJp`f=sd6q=PS+hpkVnU$KIF4Wjmd>M|WhpB7br!UoosKq8| zl)MP;%B#|N+Wr`cZW3nwEaA`LsdLgN-9fSkhlu5-N{Mb!DfxRHnm~rmGgX-%j1uKw z3XT=|+d=2d(6SIm*TsL+`mJ8Z(}wwe&}+QU=}d>>Q(R&uL8R7*bTK(!?NemMj8Ky_ zemG@FiGKH6iC~B-qee>D%;#!Vnz(Z1r5e^%w)_oo!+AFv#|U`d1POah8*;Kl9XAk>^4)E5B<0IrX1@9C<~r#ab{~2+Vnb0Gvl#U z_&=?ralk4M`YK^)*PjBXPoq9xEnP){qNQA~GUeCqHZA?OEd1|ZSs1GtSAlt3#Y7m9 z<;gvL?{}{Vx!2IqphoD|v%|BhI4_+Tp^oEPyf5uaXKAh8q&pbsG{ZXGy`EKukQH*6 zk_%~r%ZbT2+@8P5H~2alys%Jr`V|B4F|D zTW?!^mZUjMPp;q5jaY1e!=Z!uqgpTL{J_R>lEM3Tp=`)e;ub;tM2h8s(SnZsGff5R-D7tL zc{{9Dm&E?+wIjuoNcR#K`!aVxz^JIs)~{KjeW|XZ?{j~ zofxm1+w4)F2=nZCN#Ga{j)#r(C4^Fhfi5rmp{eFJ5 z#3_%R6t2nKzFk`#=Np>qwb-y&b>aPG8O%qF4n70V@*xJcO_Y=j0=0>SKrgt;ozf(iLrz#*hY->4ZYLITS*@a4drS2bg zgITMLmks{!ANgax5d-Y=D7~_^@J#5cftqfH@ZM{aLr8_XYfrx*fx0#6P65o^=tbRP z@GETL+Lcu=g@91(h5vi%-m-}Ah0?jzgBawI-2=yl0#HokYrUX9L$y`_cz7TaFY|x{ z?=%PXoAj0c0l+wX=l+3iD=UByf5)vqq*d7jQdCASrs!;CIBl={W4S;_yyq8x`EH9j z8-#C}hT_sBBwacevi1ry+K)Ykp>sLizcadCwZ#3n_@r;DJ|<{}N_Xq}y%q4r3#^=! zOqW5EU^7g-DO^CKszD+r!_9CycLn(e?Y>owx)ZGYrxD&yyM2@KW)#v`;5P}t)c|km zeCph}uP#)_)z)cgB6*$7klN|jA)bZ=i87CNX%%PU2Y9opeAii1#?{}BAE|1;N>>b{ z-&DyfHg;oK1QG|MeGMhFn*?-5py_S{mwwHPeChP0%aDYnv#|Dd@qqJT(_FV&bI`w7JC=5tP(GA=35=T&l_F3PN{|3+Rsf4FZ49$@(A*dGOzZkozqbg{4ilirOq}|NYB4#bD>%&JGTxv|o36j?vXSuavW`m-Mec#EexNs1qx!?=vLo+c!(Ps@cUCeq*YprwQPAJ+)4KAe4T?t!hv*F+PhOa7KlkcL5~y>fXq{JGf3_Q+xdbS#YamrhAnbP*vJDUKJW!1_ z^OQrXrM#^pGW4?2Fhq;^8Ql2|%IFrwBxeqbe=uJ-BRZ41H$&OJf^v(yh1M9#FX02R zr}nC`i4unGBxLV{U+)wA11DfVe5Z@}0V)CZgM{Y~%?FYl=qhF)$=`n57bAzwTDV%} zB3Utq_fGro;IVr?_a|;T!0*`~>eG;FA1AF5*ue<20;yhmkVbOrk(6%oL0UmW*ir={ zcbm2{9o?QR_tnAw{l4IN5z+=YZ2?u}QT`J{#BVwJo8ZrYjuI2|+ftavc#BEcXFK6_C#Ko__c=+I_if|i7uGU_m-DQ z>*lu#O+Y08{98s?yJ08f$()YT>1XL5_)Q;{zFw)8B`ivF(wsk#fuG{_3;8QkTiY`2 z8i9Bx>F!J7oMpiD9Pabko%9{VRVGZS`Mjg3)ncf7N%f1AprLMB*FKZ>^yg!w#t>sK zJuc7ZWiLFfay;BUZ8w&=(EWA~U6{EffzEbq5R&_Y>hO2H{UD|O`={0UTgN)6BssjI zfi*h7vSVT19puVO2rJSkA9)(}%{-YesG_)xTGaaAQF@D%rLqa#H6u^`N8Gtr-}0Kd zf2^j_5C>%v{&h3TKI@ptbD{j@COxNlwd8`^jU+~4^p(JvR9RNlW6_>#(cFCHyJRri zd#ra(cK~U~_S{TC+qDi;X)djrlq@q6NIdiJFcP9Ac?_2o>4~tIB{xk{cLz2G_$xA4 zpm&8vHyy;MFO$Q~{M<*Nw6ilt>zRs9{~%DsZoo-B2H{tklTL7@pU(+=c`|!FV2>A% zyJNjo83>E>Xltl#SkCJGw1;ZUxS?1LqkoND`SOE3ujQzh`2SSm6Kt>sq79nt6jJamD@hWFAhsmNbu};33T9%#T;i zkH7#;4z?`Xz}@uIbrn*PFkn-ny0LUxWs-l)Nc3jsglN_Ax!e>imjQ5>ePmEY*>~TY zJ}g6zvY2rr9Zk(C9bV^L+*35#uZg`-)AxlS#!|-xDQds{`)O)LR5$wtH~VTpyym|) zma(r1IPr-JMriSW%QTe^3Oot9pS%0Nu^n7mdb40lbC$f7=tHbg^LIk7U6~-_cQx&u zRlad&ABQs6B{GA=Fe~zx^_(6Tm*OfjUKo{AoZtRxJHcF84iB}R+M981wpN5tuLIsh zRCf&%%VQGa6au()D z-z%pydlM^~iTjt|;NQrhV@bwf(OcVw#Pxw6`;Rz_{;7Xxnfn)^eah{d)zWr|wvhP^ z^!n4i_>rN=Vm!pBJi1!{jbH7>C$IBG1M_9h+uT@!Zp0*GaSOqk+D*=)x$T4G?WHWp zkw9}MiQOw!_do%@VSc}-WPBWG$b? zmmI3h9Tst_==nOCkfrgim6y(%R`DG;c=a&Widi{MsQyPWR}r}R7xlu@w`nc>@EV^} zD_30btawEEw^K?WNoVM62=z4r1Z{eTYSh}`YYXHzkzv1lWSG==!wSx9h=QogpBm_<|`JC$=0b=n$gj- z4}Xs_3&xm}Q@v8e#N9V{21DdIBJ+9e(#+Gv zjyDtBw@)}XSRVRUKAgZH-NG>ZWNNvxNyi-F@8tAyrkbD+WETi)7SltAZsJ-78Y5R=D5nhQ~V3o!>iAbx=#zz4sd zkZi8QH$@bE6-gjKT>QrDC=VCyv2|2Pjoj&Hw`j}iAA1$`AEHrvR}we%6vVFGPnE$!2> zX6ze}Egf)Y7`u)t4ML9}vDPmso(eBpzLzjIq1TtjO(`f(S`}m9nGOXQ{={Ux8k#tX zJ2g%md1B)6%WYO@3C9>;l~{MEf-r31NU5j?4*2gM7yW4AbQ+Dnv6$!1d_uV}AUnOG z&&ouX87pLMKSPFNI6iI#iKbz~hk{KAd5m^THQTOWK}gUc$v08r1%UYAXS;j2u@>k9x`(y(}#Tf(H?*+H4v?dJ}ClZWe?iv?G*iu}LA9ZOvCh zvRh2}08ROs4W3x^>7asuC9zcCy(~m*t6mEm_J>Iy`|`ezK6c8boI7Sx=lT-OTAQ>A z3Am#Qjr!J`t`mQU^pYiDro+c*<0AL_l*2v^8~kKO_5E9YbD(MnLhO2x^9`cy>71$Z z90-Bxd}MA$r5V;ZU(ceJ0hAtW>?U5z=m!^?KNmE6X#dwo_TuD@1l zPFpnyal)o^ab9$92))iQRS#3lSNbej0^$h@dGw`+jQ%otL@GBIWG;yGa%zqq$|?cX zt#h=$Xv3dGH9jNiwGdiJ*O`C$0cTrx`~JNFdAFD+gdFjs?QHg$KYfGfl+(_GIL2H! z@7;By<-t*qM9D8`nghO}c>mTWK^U58qTq=I)mi*cF#V5S^(M6erc`kud?oGQZgM^I zE1QJko_78$W4GvUG|5!H)Es)rHCF;_>_mF-YPEpTPBoB9O(ud=oVdFEedX-sBa}+w zPx|J1{|YVDWR{!lT z^e4iftXRI^-|yA8OVU9*$2n?;Pg9+c3o*^?tCay=4p!5hb2RO?*YQU8R?b26Ycn~s z9VpNb*_=A}G+seBK$r;)eaCHUdP;3EE3Jb^#VOh+?hBbg!}+M(C+Nocwwd5!T{TE2 zL}nQrsm?ea18qgyX8Vq;(Kak);@uaSUwuQDh(~qK6Ta)J&DqS=in68}3SWVJ&#+Zj zh98o)|Eqn_nv6|?rvI(|B?0E%SN9Y!Ha$ex!M5UmyUAs2iVNwaX9>Nlae&4v%>W(g zRI(4$cwFW|f)ig07I_lxv)eV+IZg4+w)Prb4sl5kqcSMhe!HIDpx`^JZwaY^%1j?h zE?8g=dFf;)!OxjZM$}esDdU9#o(KqBQPV~uxFG+)`;20yQcV8Z;HC~uub)a$Oo?do zxvuQ1i~A&i&wj7`PKV84rCEOpUNiEk@s!W9*<%lb$|sw=S4ad$^LH3^)e~)4oc>#x zfL?cg)ab$Al{K7{vhbOTmMw)EDw33Wc1o`xhUyg6$+N4yFglQx$CZ2hs$k?@&Q?Sx zmk-wvikB_94ekN;UJDDKtNufS798(q8a2hpd2A(+mVhoSZ1aHsIP=6*soMAB4>@P+ z_qT$f((b_U4tr()k`XkxYKo!;(UcI4m4~}E0Zn0*FPT#$6wU??d6!J4qELgafMdzrwm@n6X}wY_X1Lp z-&^=i2K9IN?;}xa$K;v4%UjD-Gnu<{R11Ia10wQ@pPF2c3Hb_dy>S~N*oB#nyfhu` z1=%rwkG>4J=-M1_v#5)1O=tbtz3B~Ljs{@(4IzAh(Et6LH3Rzfo~+;3vTtx1B&Emt zTlM~XA3g$({u28nyO>=@-sx#va=zcc_tiTb)riI|{hoB%+S)NXdbJmPV6@3RVZ@w=t6)>Cgu?K5Dron$ z^G$PEL|XWGHn!COzUs2*I9HEyC)LlhdpGkD z$mrkBJj%+2%m>*0(p#cd-6@wfKqGC^get>llwRcB5d&7K6;>O^6Kg{KdI>brD)9F( z&NEQUq!G&Y_y7L&)v|C;liqu>-^a|Y^&YkyQKwU)HTs5aR8Tkl_Iig0H9hW+&c>f4 z(L017_#!nOh=S99$N47rJ8mhDCtiG6u*@Yq{^s0LN-|-E74PftSXHB(isU7~Ro>vH zVJ!ZgA8x@vrCLy(2LYjEr{{|;c4{T&n@?x^*a(kNbio=&!uxZOY|iMM9*qc8L{Ti#BC5$ZJkYRID2EG{r8K&|Mm}*HUvt9GSNmx zeDIU5!;BJIM<;KF6KhgH?arCcE`xG}9w`22yfY0eeo|8R6onu4hZ^s<{r8XOmfcOf znn#F7&hT5?e{8i$TLJv)?NlRgu4hY$pUXy~-%IH8AN>BH;y9jHL(|+Cjw=^w@{JLn z|Nd!zr^YnY_`$=SWDpc9EyHiEkJnUW@KqYRdknw#RjiJjZk=*X?c9Xfw7*9Ydf(${ z5NC_*^az3?e=D!d6lM%R@rUgdt<(hH6ysxsb-2!qldmry1ry$dxz3fE)U%htDtb!# z&Z(h7khc-F9I7fpj_KEXr_i$t+dKzyYEkOs^R(u(@ec0c4e-LD>TiGIQ}}~s&6eC! zIlrQBCq-)8v~l%jk!RXD8NlKZLh>qkfPHM9>sYP((_RRZW>1rvc2Dz1(`^6HRzEMv ztxVF?jUyNhaOB~;mkReX>o!h4t7X&=iah`J8}xzqW}ekFkA>1WMA?6)ov~I1On7LQ zj(2n2!0^tH;=4TBi8+_bt{Gqk@wRcjA&}ZO`t6q_ZSvQh;lUvgS03~z-czD-7Y6bn z1{t$KFB=v{3GvwBH$%}fWtD@-K})+>PDgE5|NT?Y=Le`JKnLLsy%e2S@=04R)rWjX z!Iz~?0nxv;gCA9J<5v$U5axfTogupaeG@O{L6O(;eW}t_`<~(YL7x)&XRKdE$`=Zt zZ2O?7f>P5DkXXZl*HNgfw`UM{ZokUuHS+cQ8dy76%VtzAntcvIhnUme>Jf!_+>PDw ziC?xHwoZMC5Ebm}YHxQ6K18n#>-tgcb!BHc_;8h$&B?vN-KP5;69$vDOg^mEJpw!k z5bRB1eTJ)>-%q>pu$?5{K;d+#AA^JCkXC=Tmu8eNWX!HHL?jyAKHjL6tB1U9&9mUj z#_8q6a02I=BY66jEx^;uA#GNpJF-S-sGcei@R9K0X8rx}VySmGn;5m`{Tl7M&&FZ9 zwre#W(dqEw;|jgiaxX@Q%qaJ>%JS{3B}|TkEH)wy6SUwlgT{;s(-sufF2%i2n1iQ% z_vi4+hE$auHiwuY{p3LxR@~^{?&j_1>DLB&fBtrHYt%4SYRv{QHgaMpGO(^8(mrlvu!9XeBEG)kY); z6jya~slSJ!BhC~9t?YX!YRMn{Yi(pJHctP23_j=$iuZbg=w8By>QV*#eW8A zXOXKMDLy^XQ{mig8sBeb=}bn^_4xj;FHO)SyrZ}{h|xIne8aS62{7Sx{_W!OY5ii} ziUZho`1>^*&Z1_6CPBA431b*;JnAm{(eqL1UJ4A=m)+tdO6M&2oI^5sLIQA^fiKTX z4$6TDxA9|KpxXl5;0HdYDpu)IBHP-n3%mTAOH@(9hq^GpIb)LIG~8;#eP3+sI@~H9 zn1fvJG4{6$Us?f+&X=pnOh7iKHkcQ9?SD{ZRS95rrjX51VT!!iI@ zem?^}>C|53>LM>H65udzc0=u4Fymc_Y0mS#U!|aHtK55zx0Vk4D-mwD>|P zONFRK!lvN=$Qc~RLlP^N(nKA}hWam`GAk({h@DCwY8hW`PkJVo<>_<=>k- zT5NwHJWOxh+5H?H-39G+S>Cm$>8jDx9TL1X#|^qO&OGti)(!vQY23f=ET$-1`^h~) ze8bL&Ym=2geMIaN${~BAg-Nvdfi3j6F2%Mz#cA2ZMtQ5IFr|~Kq0v~3qJi`kFQp?Ej{UhIAY*LEfF6tNk{IaMz}#)5=|9s^6`O{E!`gLb%g zHfxmp<&*J@wG z*iWz{f3V(pJc{>E2EbB|2i*fDfvOa`lnb3CKu-%&VFf}Kl1%FH{aR5w(LNlRQRJc`y0YfJhM+=FW5W* zX{*}w;@}{ue=+-Gj^*<4>aSzaV(9{(W4bJ;g#x{OpjXMab-2)iC_(M2{@$pVurITq zcAjp{aj3mmA_trb03bmJ1+v|W{00*wfE+OVdB^Z3jnL`WAtTD`Z`y@-J%dvhx1$mM zocWu4sbuz#?HLj`V>`Z2$dW(2Es}j^NgkBk!1Zc8wO%0Uoco0!A6&xO>LTA>cyg?0 z)})WzSB(D_;|2P~hY{+~l_6J#HeHB#X8hF=#L+)0 zk@%Seo22Uc&reYkC^j2gQ{vh{$uYz z-orZHm|Gu-Li#1Fr5$1kII8qj?u2r!)hJ7~d(#IpdV0M|uy*qHULs6M$@?i_s{s1M z5qtcs{K#Si9U^R6+ZOs{HQO-y{_H@eF3B0X|12&Vw1ZUhFSE{ z3{rk%{)yClY`i%B)MWAbt44n@o;*3Vb(i0&Ev+@LkfM9?NEGw36nstDyd6ZjT}*A1INu} znBg@bP*h9#Si{%d^OS{FYkq~GK>OoE_VxO?($@X8O0Tl95!(h>Jq~t<1N8=T@9+uq z$Dh1pRfUU1thtjz-}iR?xVa>vXYng!hSa$W%5sZ*wRhiPBYCVEyF^-$PoTM9`e?8# zjdvJ~wE|q3+!ctY^N^26v~Oz26$pTZ`z7o3uYsY|U2GO?ygxsMOHVOA2|#;eh{^Fe zmqIvW!nfB?0%e`Ae>K>#XP+gFE3}-BY7bX5L~^KxyO5hvciD=O#VZ7W|8|MD00-L$ z`}f`&41quQo6=KmrL<|&;5Qhavw+(0nhhXI!>5|I_!``=F*LC55(SL1%X5DB>w{K* zI|+DBs=+~>+VQmO@Dk+WzGMl#emQAP2Tgs;;lmMu1;v|DY_qfd9sj@QA%M>|IBUb<#5WFPFajIip}UdWclQ79uEvuI zU*NJG|CU;z-`>I9vj+O^;Ra`RjNu{NU~eh@_wTzC^!JU1!+aqy!MrZfy6CmhHPe*d zVa62Utq>7yDDp$sp$AeDcVsA%$Z*SB?Tk!RBufSc$zC2`ww(0+!hdg0pLyyFh~>S1 zb5PYw+;r^^@HG*5CA<0+#qMR_sqe4}nh`?DaP5Gy*jL(*WgMj@j-mD6KQ(9H)W-vR z@;}$Br!@*O>P_0(@pI01n6aLSsgQ9q9TSrHlN;HuaHS-qfJ5C|H+>}I{4(DvN~XVa zQp6n%yDb}_U}sD-4m`HoAjD<2rj}vEfcO-sa(a8IUJZ$Pzcr>7V3g~Xp4X2pUl!Sh zxHI0(_P>8@Gv`}BF#dK#C{p-)_X~4$4Ik|HlE<1;W?6jX{pDWfx+gU@MPB)PAwKMY zx=B{9R;1(OZPW&__J99g=5^H#97t_{JT&sR1afot_uoGQA>al|2N&f$+Qd1trtVbvJ)4z;o#R6WZrVNj zLCxq301LXSBD@$jT8K`{5vq&VcUSp~aQ?kr@^T0YM%s*i-t_jCO3bc(?1eu(LQV&= zgEY;Kh-#?shjADO|8XL4GKu%Ad35u8iEP_%%`CW^94aZk`u4Xo;Pl(yaUH$A>A8S^ z2C8vzgAzwlfzKS0J$9hfC0%q}!iFqvt8z3iI5rKi-QsR1HX_$Wd(*tP>xV;Bu>dfL zPrIR-Eto=n@qK<|M$f*Q$W}y~?(Exjv zCe5iSbpLiLhDM)sBdpPGs$I9_39^#&FRiV{pFFt zfKth?G8B6wTBIl5)W&8;J*nHIW*TPd4QdMCtof8F{YqP;HepN}{utIy&D2VLB>|pC zCzf?88n_?M}_;DjHxPJ-i2vYK%u>7N5m+g1Grq#9s-yN=bzIVG>5PyP3E#s=P* zX1mC5G!`(nD2gg6uH!7m@6oaEdevC(PgE=k*F(foNCE|NAFTp1k$Oms~%z z)qCFh$`EJ{4SfMY-K@iBo|SEmau;PZSCUzaWhlD!nQQd0kZTCU>|5vHrq05xu43f7lt!k#_;P=k(AZdUNqDDbNMnw_&nr7TEzD3v-FNz?3BR*u|QA%P@3;T z`sNqv38SwWd%e(9dXuw(Z3p2AAtm~?fnTr%bO zzkkd012meY(#pj~)fYGHQ*97uY?Q||I5NAtf1dx_xA75xS5=FGxJqzwH+&3ajMl@Y z^ktMez0HRI`={G>RD>v_zX?eq6-puLk#)s3^6%kF;wCb+X46YJX=meQxC@eQ(=Jwx zYWtVQLC--SWJvKeA>eg8h}y3Tv)TW4zX1yKJ0!k@C*;D+3AdsvD{fjP^BVr?#o9`U zz)MMvMrwcy-&m-{9(S&9dHNS>Yb{1IAMzq(?IJj``FMp*ZQ~CB;9>w?iuU6405*^y z_wP~2&g005>vLfWsT<>0Yr?lj%ne_FJYACTq&ngtRKQm<(2X<+y+?uPvOv$Q->AQp zSG;f;(d#{~6i@w-Hah}woD@Z05-xI(y^A+Q2snMu&aTUly2ec!VTQ^*73T#Y{%ZG< zZu|aQneD%SYsrKM(JLSueQWE$Gy}icY=(~lLYZmT#*xk8Gi-K@+>P3e#Q1S(Na@iZ zoFd;8>}wywqot{V;_a-JUABCu#9ndk0Em|q0G!}jaJkRwttpT8>%x{g~Zm89Fctiq3iLHO)7mRtCQ2w4Y`WyFf;}PN* zAQ2NGADi{9F@5QmhNj0>t2#02v#t<0r8w{w)f~XTYQ*pH>5WmYu0zNUq3F@y|NVmi ztgOw*XaIl&<&hAV>0}JWagjyB;1}(K#zRf36pQEERwFK|I~!|Dk&VKd z(LR5tG)7RkUh27zei)$`#MP^jiQ?&RC-!J@tg^nJXpPT=$me2clCMRx)t)5>E66gik_0(EK-O>xFI5V& z2XjMs2#;1l7bY8=uoc--_e+CO7*KE^^6*!%IChO~hf}VRC${_^K55Y8+TozJNc!Um z0=Y73p5jdReRakp;Hq@r;0H(cdt%oQC zPS9Q7$LSy1q)ouaYSJ+!YpG@iqh=4*Z&tVHX3gJgQ+9t*?xk@8m-C8eJ3tE{z z0fD~UEx*A>kZ7u~&H*S=W&r|30b<%1(lENk3>F213$anat)FGK$ms<`cL^Ks4+a#-7`=2=571l8N%GRQbchW3_oSc)AS#qE7alhQ{Wu=> zrrm7cC0_8-Fu;!#VavbGY9Jg%feyiQkS3k5LpJ`*{@%i0YFv~6ffPdNS+ndpYnW0n ztA;}?4JGHz3xK0f>VfvJLDIpQP`Xhj!j^Pg)Sxi>$(bOnajj(4^URF40pc4@^iQ)O3F6t&Z~ONa@W<)(P5N6ugY_2_U6MFj7+=h0J9P*Crfo(947j_kc^B#L z{v5ztK~k$MrK$&CXj@aa3U(sj|56(RS(MsX8ug@EI+N%s+TUE14;LgF5OBe-b%2Jt zM(CJ;M+kx}2!I+dRy}VJ7+*nP+BPAcz77=p<*XFW4{c!plL03Lwfr+EHI1S%K@$0= z{eh1C2PAtov@yfVpEjm>wOstCVsf(CbNT~>0&c9yqx_xz*6KF7;+wib{TILxT3evgQE62J)8NuJRm0&IU zP*vrEhgak1qtMp$_t0Z2m14K`17=9RK$nDQ^3XCq?p-<@aY#zuOc-~Mn}#U?^1j}8 z+TV%HANQgL7uP#zjxmO7ECc`4#DT|KOLX^Yvw_vXAn*WHK&rncIp^`fx?Dn<<*+vd zJQI!`$Ej8v#lb_MFfTa>X9#S@4U4TH5qxwkoh+>cU}RT=qXL=UGv*(lw!=ZWIP%|9 zvLVdnBR7XHydEx6bp~HwCiTqr@i(V~xt2ANRWon>m=7_O7--ZiiN2cuny(2S1BeeX z^_DZZBOu@dx{aCkS6|SBrL;_QFL#mkG4sJ!L&)0j?Rq;GKRRi@HWnZ#2VPXaY3M!^ zp^^xqbB=(gPRJ4Cex|t=eb+v~{U}ux8|=k3Y8J=DKFsT2HI^ zI;P-skiyr1z~xbvOw5(g$}s}dpl;4l=-H}9;Eord29&b+np99AJ*%DSlSsf zMBaVf{4FW=B>Ynvj><@;LBYHz{#ZCRFC8|IOF`R+9>9AnU_b89Wm^R z6@~Ez=;_h?S3~sEiYiYW@)cn7$Bsqj_Ytk>v!u9Pw2!9ur|33fy`<%s(d?Aat5E7(K9v2gK;gisu)Zv?+T4Y;- zf?5Q3Z(*dGE3z5mbr2Z-#^e$B8_;jqrg{Ic!JB1F^MsBzX}*LXSJ4@)%Pb%fj)vh? z)zA&ngDqB6Y1Jwh0+yDkBY{qhoBwU6@O|5WU%bOsH+x{H`M-a4oAfEzM%-TI6oT>S z=u0vxhPMo4uTo<93GT&)?u2UCY3Yr_lvif%?0))Yl?k3q^MShRkdifi`K={Q?Kq+E z&9nhI@ztt)241juLgY!T#|T*dVy1v1^u4C6;xz%bJ{iY~?C+kf4 zAhWs`nlnd4{K>xQ@F>iOwmMqluz$T_Tce-lp;ek3w+kb3W==pjobhh325z3V3)3Z#AyDnA?&dl5&!)( z0@E-GB0)rO<1lNSgq5E)^mO4(yp?Dd6T3OcL#H=q8y7r6#?=`dE3Fq6U1DuY3>%*1 zCVnvTdD&9Oy4?=<1zaaU1Ijo2$8{ovQ*iT0{WSHqfL`zcEY+g)UG_ix9m*|H`G#D| z7{KBnr&-}O>?Hp|-Z@>1b{p)-6sS$B;h&DnmB>Q?m~d#Zh-En*RbLPwxf1Xl3QfJs zq3XB4=ld9Gt1@(1bIdF#D)_u!51wjKGRsX_vx2nL9L1(g9OJbe{w#~@Ph5AC=+Xkg z(ZKwL$-_?fa38S&5_%t)vbIMzQV|wzs>6G2H^|{8?yqTIhcTapYKEpQc6ygHEL$24 zrmX)xRVf!$>n1L`y>Xv_Lv{;|s2oKscmzx*=?+EeggI?Ku{(es zI*LE&Mz}vPih~v=M2VsGH#WOe;*0lk$i8laTYXBwu3c~NU;TF$=DusS0_l&IcQv(+ zLKQaD=YxZ)YsTZzbLG>G772)cPf2^m-`5TxK#A*EEK)oWzF^4V=ZD=b zKu---{+#To@BjTvAOlW+2qC>3!M=f$PuNeOza+SGI;{S5therAxU;4MgIn1zXVf6u z9}0LRQC}<`0#4NJoK3W7lb3r*;Qy)a&6-kMx^}_)9kKrdvFhfWKy+rGS#jQq0HskB z6&28%3h5CP>BV1P;~5DyEOj^M`zos5i+63N%sDehj^-IHv)dMS>Z?tmFDq^R7*_4l zMZv5Vt@X5-9S*wP<^!!*WVjuVx41$M(n=%zs;SDyIEd z7^fSr$ICL3wSFy{UwP}bN2f1RO&Tb zQ-Tzv$qVz2ILn`9t2edw=%&7Q%e(nOZEl<%7i-C*Z8To*UXRI>D_#)6TQ`gASJOF} zFQ4_je69@KV2B7n5H|ydUrtZwF5T_PwXfx-{rbaAb9ApxD>HwP)y1(=j{`HBKVPo% zPlfyS@L0}mtM1abwp}~T`_7#iszPf}ekc!C)d3-gf*jUg#!}_dk9B$Gvg1WM86^4Q z+;`+dEh`@uH|-mFc3P=)O5!*?%5$5mt%S9?bnf&fWM9<7@zbPLnjDc|UpS~$Zf_P- zElRUMn5;Tq)aQ>fFXoTwN>Ao*2klz7+3(gKZtQ5XoIlp*xrg$Bym&gjZJg_ux*x8Q z4;wA)DbcOl6}|NRd3m_JdL}egZg)-nk?h*t$@$~c#bESQsw~Rqr?v3dUM+m#f$Vc_ z=FdA*Q>qlbshr>B^~FPd*w3H+`N#8fx>p%rjLxcRF~9Vpaj~49KM!)ZqqaXUte*P$ z`v-CIaC%=^)=!=ZDM?kU6z8MDdD5NTwg;|vlbF}OJ|9(X|NNs?zZA*!eQB{KFj79z z&r0|5qo+}=Tb${U7@nOSJW89sZWpeW=lRKcJbWoX-u8#8^!T)zoHT7|?u+t46dq8I z7!ot>gP>Unz!<`?&`FDP&yvF z!f0r^{$AN(t=el}JwArRVy&#s@5jq(dlW_&!)0+Q$Nr&HF3pFzqd)(6I-ebf$?P~e zz7nmj7>dHWd3|CRH-%R1apmu-i{qYnHRS&iW=j0xwbLj+4$$X*OFHzmRXr-))N6M3 zdgVwKl4`kI$iFu8-TCVB?qQU>Sah2GMTOiKW!$=0Z{=$8Y_cxj-Rozv>gB=oQZ_EH zTZ@xPQ;mw!+zm(Vbhy6vWMz7*PSU&`tjhD*ydKDHzgn-$B_m&&$H)E3tG^Jcd2m

#(2`{rml#gDhvU+%*7wII8Yo$3AynXTHZ&-F*w*;?C`XM@MO z${sKDbaH(TMp4-)h2g;=Le^KhohFOBm3sq&ie#mQsQ3U_-roy&3k z^7xe2rq9dGi_yp*Dkt*mL!X_v!=uAN_Fh#Ag;KXQ8lQ%Cw^6(CcZGI(JiDB|)LQZ| zxws#%AJ_KPEM694KfkD&7Gd&Aecd!_*{mFPSNTDCVz2MIO~NJhm)hM?^JehWt{&7D zvqJUksoH-uul{;^T%ULKeK{*1U+UAkuQtv?WnN9t0~Kydr-!$1-aXI!$t4r*w|_>cYH?*nCxoaj2D-ew`z5IGF@5Hy=S+Bb+0^s>|5Q>T6dT| z?u||B{GuY3cQP549`f`4-SEOrZ;#JU#%uX>b$uEdQ(GNeHO7AUr}f@s z+Hbx(`@DQPIyuRYx-X02=&({qTDkP)P5a6&%TK6BdP=5iyPo)ma@PsD*7sF=-Rx#X zZSla|bN5_SvnxdwH+?ic>}IoTJ?Sqd&H60K`sr1AdTfvK9djqEB=ybwUGvdCKUeM- zxlng%`PhG*XdSAB(b@cUI_--|$X)5Dr_x=nUL(<*+&1%Sb+Bqb-6HDt2rv`%|z z{ZuZ#jFOi^`}|?Cn3aoa;YB#di*~RcK)QWe{CNj9@h4ydpb<#nx)R@ko3!NaBT)fQii7A zD;5^T!*0H+X26#1Qmxj#xH{=p=hJXV2KfHq)-3Nkx#!oHQu8>xtg|SbICzl5(oOH+ z@=`2JHdpX{)$pzRo9=j?Yu4tit4{yVKk`Y(G{z4Enz{qKP

~j9}@R;!H~)4QWyI9Rlwo2$FW#>GLMtc=SK+oZ?H@}>vr zQ9W6o94}^#wIOUVez;lb!nn{l>n`Uv=H+o;+T8QWD%)J%7GBzSbCqwj zuJvJ$?jPNRQLBEGwEz5L>G~$L>W!rh%SxwNKfhScyTN&%4&CdJKA6yYub!TIx3!0{ zxx66vqjEDo%C7Rg1D#aQ9$uzbVtQO!JtzJ4iU^gh zua~DY-&uOOs^s*eoL=V+TJ!U6@3#MP(Yjim5oIsxm5F<)4CYx;Bz`Mho@N{C)zQ%) z?K-)`OV?UGT=eRb>|vujJUGgU)$`q@T+h-Ym%dTrV0m9U&p(yNqldG*gPZxQxVx(L zr~SM7fV>aaPVRcgv$D~bt4BY-6nE|HDCFhIdEua%uBT1GohgYTP^7X(KPloH+B71l`n_itSk5@1Go5UVwTjkP~ zd0Fchyx}5?(xC@(MEdSw(d*R8y_c-< zna!pV8Ih~IZE$~%8( z^GByoLR&hsi<@Wjm@noRXNQDkn!|FXJDH43WmW7oC(Gyaxj(Aa(!4 zvVTyTA2-^`pMR__Zf46-qqCmsb~)AHmYyX>5;P4BwXYnaiv*_-F(?Rn|C zd6g_qOiz!W=BsXTSs4_rO6s_Mw<*K%C# zxYKbvd8{W#wWYq#^*iCNSsbP>nr_(4os8y3_OLZR&)%Ld&axz@ZftycJ-L)m)k}HO zJAIj4pWf#d-k*loT&*1X4S72*=bDGvM(e3{uj*&+JiU6#_RbdBdw1BkmoK-I^y0YK zZqwTC^B1-^ee7M6-kbN%sx^5aPH!JN+4>V03)#i0CdsWJ=mdjbKO{S=Q zUrJB)QMXrqBnRxSeM8(j&dVJ^ftyBdXpygxfR=&WqN(_8jOeauc@G;;nv z{Zcr+ylV|tLUfCAAq%78S+1=I+2wsY8Im3IB|E-6CT(BR&CA>7WovwJ(VCnN+R53t zo*h0umD9P~TlCB1+vFTK^lfMQbd)}5Hik7lIVOoX2)AV5PRF&oyL92=N@-s#CZ)1< zo$_d$?OZ?RUXO1dAMbDT{Z1*#uXKfUZ)N=STB@EE8(G)XS|8pUe>ZxW%)A}E)K*D8 zX*Q3q7H4)KR_FJ{=Ak$$%+tBqgF9?JH4kz}>HPKG!{jl$I%yG7%^j-eOM5msIP2XU zj3nJx&gD;Du5w2xbt}m1wa&>r?Ei}zUr=QPzYu&$H+#B+Us}J?{NxM3l)ros*r&mYgR`2*S zyqsU%m8z!OP_K4T=^mVq)t`Tqlv>;Fb$fA;PN&Phr--+Z|S&;jcRd{ zt{>;7om#$`^oM8db<1Dmt6_3AyG+-HSE4<51cD{W3X}4B^)xvhy7D23L;r9!9w)uw zIFyEdIc+Qt)WomTX>$F>=6=zAXf+?Y2e0!}^;jR(Z~D*I>w|~m)2bP!*MyP$x|9W1 zp5wRUPv@5xlWwKAlqXKgi(R?{H34__}#P*w6Ul)y{c&g3a@wmI3 zzI1IMjFj$<#^m>=ym5WndBnuF*RCBbFU0iXd11$sf~!0~9lw^3r=j_p>%P{Tcb$6U z-U>_V;DOFA9bWwT2kFhl)gWI~#f$Z`?GyCP4#)c8=JMX%+x3IGxgF5s9!}2(x1@6iHaV3p zS3T`sEL($gqC>jm4u{?4<@MDgFnQh{_lom_#?5l`w8M!S*3ENSAJ2x5MB@8del;mJ z$EAn*%e+`Q%pD)zTpYQ>4w=qgy>(Kb&u$;`eTj_cT>Ssynmd= z?oQ4JwrUS$@g^_Ei&7=rhy3wPHtniug7t&e<-A|LSWhPXtSRP)H!4R~W|o}wZ?D{V zIG|TRP^W{pDZ295E%wetN7m$) zP@%5oT&YW1IrpLl*@yGRZ1`GgxlvPJ5~{8C=k?~eeC!PITP@MO*{M*ieyOV;#@D19 zve|C;wp+bQS4*eOn_;dcj80DEb%HVJNn4SGsYd!p6S^Y&mL-6E zYV!X6>gl!-I-PLX8FswvNmacx>we?F=A}44=w!*Ht&`QTnH;xNn7kY<4pjQ$DobLR z&0QXJu2#2*m=&js%T;(;-FF7rXHm(iTCdh^zf6|1llfV7yiQLBXJ_M+)kSe$yE<5$ zq_cW4&u6o>ZmCpluWs({<%zs&-LC3K^t6^Oo*#;0UEGyg*CT>!H)Q-9$*O;IOH(fQGpdOBa6_s>tqMgJgge(^7zW>^_2YiIf(rnthwHP-WPNsa{W85RRQ&~Ev8#g? zS$drdudDQGw0g|G9B1#khqiN>J)idKYeHl7i)X0j+RDZsg2fXR~uT zubdB>N&D`)TFVdh!{G4hxI9~rPRSDwL%-_Q@+-2yx0i&7RX$|fxs}#AYaaaIzII{r zi`-=~%r6@+gT{KczM4K37dAIOIe%#qOV90de?CoapH4`!+6`gC)yesAay)j6``3lP znUT+A58WU)s$LK{&aDZNwvR^18DY+w*5PC8b*6fkx_^3G&s~(N{f0^M?MmVL?9V@P z^>9*9w@sMd90GogQF`ZOS&o8U3n@Q(7Yac4B!_wl6EYFpbrw7-Q;e#vZCk1nOu=Kgx z!Yi$_e*RF)^8c=GYUkCmIlMhS{?D(2|Le~`QmNGcI_PcwqnDb^*Q3sVezit}=gjl{ zy#IeLrlbGye+=64fByRX<+p$FtyF7tKb!sMS9dTvcoET>^*=0fM3j3cAbgTj@ten|*_& zX}az_EzHY(pJ=fs+`dzuzA41M@_Rb&LAre-oZjPqy-I1lAG{KK*6b%CgcN;EDo=Y) z?7s10M622lHlfGZeImYUWyHSJPW!!#GW#NNA(fGOUz$KW@(K@esf>2}Hj$F{M32#0 z@pm+lH2zDUjo(j<6!es^Z*-8UOrRAQ`*wlIzTH|z5y?OzBB)FDtx}yca?>l^SbUs$vNTZGzG(bcCD#NLkulLfhXEeRBkxkKdiJ++lGoiJIyIi_=+2W%!JVikj$4D@%N! z=PO!=+M}&W8B#J3arXHC6FO18xMu?q#HsDac#C|K2Td%>&sUxZ!H?bJw+P83`*05t zIX*hRg2X32di(m!=jD8opZ6_fHc#K%yls0MsJ3~|_BGr8cw0z(BXRHBh4<}b-uDyV zrhSUvK=j{kXy>lf=NF~;=~lljWM^TokJ}9qlM$23Pdii)JL8yF=>TEQD1W;TD=%h3B|lKA%v@0(Br5OYTe3o@)ERcSAQI5&pkPeVE`9ootNTM%3T` zX30DI^b8N81fBI7B>?5Ya51 zo+GS6FR;YcYL5;@f(x zAfd>O0I1l#fCo!DBO@V535gmJnEs{XHxU(R4;2NeO_-gCugDO|eF8BFctH|Nfa0_$ z0*QOf0rVnzMxr#}7>O-ZDA5*5m=r_MgiMIQIvCc1v|{~(VA4)L3Z~r%W}u}6k@5*? zPia~iA_l1(;w1VnMIxaiE~38?U+inbJ*+Z_f+Uv2xdgxFaqbK{Qwaq z?HD@6LSZ^^G*O8Z4D*_m#7Y4mjAYG_=vl$Q)FpHZLcL}#dM01pXCHVa!PXcdtj zaTV(=BOO!MD2Zi}@cYE-6aiGvFwFuQOW1Ym@R`oXY6E2<0$CN>hBuHglaNHyu_wZU zZHcoJLl#W}@+LSfYhkU46-lUGfA@2C0G*38wt;R`CPmvN`D(G2lf>E1?Q4P$Dd0*? zY(#SBNi#sn81U5|tzzG?MkcN6v3cT?;Gr`>a&My=N)px(v~172+g^cXOo*Zh!=yl` zO6tRt0}(wQ86@jP5ZWZJ~PT_}Q1*yh~V!r`(}IU{p%d17pW*D4{obS5QT7SN=H-{J)}s z{(%NzO9Rc;l)N^gf!!ejFb#Q#WMCs7IPkn6T_@>K;=An6MA+`)oe0}2-w?r*^80&4 zfce*-h!EGcA%Z0$FmV1$KG19u2w`h7Z1A*5`Fb*Rq&*ENy$3@_{@nH>)F0_C(y!32 zQ1YZ%$hNvYPZ*KxJ?)JY*ZU_!CX}cFEMds(!cdc^DFsl>+ZEb}a+dHdZ4!?qkrVW$ zU>M;L9RTe&>)Cw%c4H#h-5H&x6kqHNj;bP6yWJWdoT%;A%!jREc}~6U?d{{=-<*5j zoZj7Bva`A5hs}wPn^P$RUKh3{q3JCcD*i6Zx_gvC(ya%RRY5RyOP59FlB_< zU~TuraZ<$?t9v{@<*eK9B=I#uifjD>eQ2mnmEWvVNqcetMuv&F0hOub!$bX%c!6Kh?pu z*dL#&zkMoid$ zE&?NxSS{EXh9G^LLLdvlBg8p0x%6aj$)zA~mfR88c;abfZ52BlN;tgTp><$ge<@fbTC#CsHep!iAWN85tcM~%%$9@*j|4y|da#18Y5*2V(FcOaZx=q15PnJo z41%4yw<~0Af;1l~m;m2+$*w^}X9SuRL=z`q$pl3b;u}mtvLvJzXsO%B(F?Fo1%cgM zcqieTm+Z(@@x-6MV^&38TY{OhA2F-2JG3Tj;J@To+8McZ@BE5jBf)9dK~h4XwSZFu zEa}LM`I zhwg6onW%0@$0u-X?RO09cNsW*=3oM+A2=A!+$Ro}=A#n$#KCr#gYCcMV9@k`pM%vd z2P^Rf;(rhLSmG=tzhY%l$4RiC<04`Uj1zL4LOlOj~YNTLth}U z!oE)s-ovHSz=H}`Y?1`Q0Y9<|1n%|~eI?)k_Q6Q7$-p!uKME*~4n!evM}B^QYyCA3 zDiZm`8v7~yCAJV5&N(fIp67@cTM`jP@W4j}Z^@vppO*hqyh_ULwXo4xx4eJfgisG-=-u7b0-O(Uv{M(H8=D z5CFQJ7)axN7Vm>tLbDs4VnQR13`&!0&1?vdjXe^Jh*rkY+7sbp*qbA8tc`s1jScyi zALzDWv)?JGwfV$PasxvRIV_w!fEOrR%uWa-ZP_Wq{G>ndQ|1#xX`Hjc?)4i#F+0f( zJ0a-c5S4vrCvZ~|Y~&{7ram(h0Z{OgfKRdIrOan$qL(l$i8oeaPBJob(mO$Zql1CW zeZfhZ98OMWAtoFY3DyoPWp;Tfv%^f89d63}#!kE3l=;X`UI4N0@Ka`&p)xxhmHEU{ zmV@EDJeB#Ksea?B?^)_M3MwN%1%~7X^P7b9dJ3s1BYg|hPy!H}JU>zl*qkGRDFkO} zT^fuGb&36ZyfcAeAft+S3~6bb7z8PW#<~MpMN8|ZEs?I_t&zTxDI^qw;MkLO+9Gkr zv6#ICOyVJ7g!rwHdq@m8@qshmRPr}MBgrZ_V?Hs9++^G&8BHI^^f@4M!?9?KfOVk7 z69>|oI7y<&`Nd)p7bH(-pG1f~Z*VTT>u}>qcjAKZaVX7^lb2G+3bH{!G|_%>fkWxU=fNjrS_LBQ z1Sw4Lfsr|hLm-JXbov%oqO2!MG z9*FE}fGtSK4JO`H2;dQS_!R!ZinL;?fEXlCYR@9>rt~Ni6e}xmh4NziB6^JWj-#`Q zb&~C!gBWHETN?)@ON56d7wp(0=?f8*?6`QRVg}Q(aFd#`h~OglVl5{k$-2`r-v8qp zVL^O~@XRN}CDle)kcL*!ViKT`sI|!){P$4{G9#Tv%8|B0dx`!%344stdgl!XxdjId zXV0A;5R2#!U4|Wz`29c|y@R;7OhX1435*mie4jMQ2&A z1Y0tG@Z&fS0EvJ)wFvb}BnIFeBj1R+4Zc8FkZvU}%y4qpv*RG3{2d2_ zH5pAL&@7U08P3)Q1~4H(s>dUS<>{mmoD&=^ra!re4z2hJyIDd>pN`)Cf8QL_v60dQ zv;_#35QKzOmS){z9Qk8_xSYF1>>4?GdODGxR4){T31GN_gp$bOeL?6KI}_pfcD9^^$r?WlHG+bdk|i6tc+WnQ0`u=7$L|rFXI0D>%XZ06BU@Ohr5s z^4!UgNhma6L_p{mg7)rXDCBpm6}0~Kxe$b%hXjF4OV->WL(bcQ{t1a>c_h_`5~9HV z3luIXq7;jW<1zqkQ3FQj1&<=e7nm~;hJt;iGt{(ll)sQ!PK4MfdXBD>N}xvuP+xch zyURq?8l{0F9)+u7ofHM237jKt&5o=xI~m8^@2dYMR^Os zbfSPljeAA@vKKgNPM!0t({82|yAP_IG*xoKUA_3e7@KTxQ}G zAB@@KLPtcQAX}O?xMw`7Zdl7H61G@1!!Z`byDf4TK%w4@xK)8j z9u_MY_N2(?+CyLyHJgG%rvMCqOLD~J6^SHpfiR3?9O&^blw=~+Wl_hM;rao|3EOyo zX7d2PViOn3LM5sj1UZNat5Z}&AjSlofX^rolJu3H)6B9c1w|?$12qVb9aU2aTzZf40upnn8RL@WrV}SSglYuD^GP~5 z{fEFGN7Vwc7#$mgMvb_%gzVOLoE81pM1K|Z;Lt5fb;*+=(8^kcmZyQF1)fgaE`a|O zOdKI$F2p746i~i|Z#v86chFO@poi=r7d`P!n|r=nm?bOmIbg4n_hSOABydir$?Jlu z0HsAhD%!n$CYdBw_-AT`%!-omW}y`kYL$V#LIp<0MLJU_nDjCPzCZ|(OHKo0pFI`< zj$t@NWOO`E&VFw%;ANz4kPIEvKVu*zc8`*lA>I2? ziru3W@ho}q0GJ8D2%ja_NSTez**QzGx4G%3rOD66QNAyY#5n~yPlD&AIn)kD&(V|2 z^U@GtCJAsh21XT9*JSlbLV*%3oP6YdC6^FyZ^&%!_(2t@&p{lub-|;fkU|-!u{u&r z?=w_ja2^uHUYit-HlHLe>O2?V#lYjjG7KVWdno(hVD0w%nRvtZt5Vv1UKM9+w}(j_ z0~AMVA+2Frg5QQ^#X?n0C_qC5;hK>rm$CpG9$_!!9<4P9gpvATFfV*0s8fkXDn*e# z;7~M9o@>~GiuHehO^DKQd8~x&k^ZNx+JFd%;c$zB%R$)JaX?QC1PxHDrF|@wCu}CU zl7PWID)PB^!5}ya3LX5$a_#3nljzwG=i`MyFtOk za>oRK2nBE?oPskFRzkBlM75AM*k(pETr;Y<64poIkz95c{Yww0#i4k~Gu%(eymQQbRWjxBq1GE+*+yOxj^6=p=AtLW%7>U89hszN-as#$f9O5RsrGO>l zO_|MIe=EBqcKnhJbR;7SzE5%0oj_1FX#weY#VU&YPnfxc4|Y!>FKeJW$Uc%g1igr6 zhX7qfLhTWB50F^Ig;2|i+>1ps1S~NMNdi(ghQKDL#IYH2Ou1wyQL!q|TMi8D@k`h* z#d27~8fPtJ1eVOiT2PcfW$;zSMhf3y+2h_F!)D9J3Uo3G$cV!VTeC?mSb-2HFN@PP zyxj=(JV_Ss7v6j%fKF{TyqAd-_{I^GNFfnk{^TI3@PXhl8W_l*U=QpaVYJ}dlUK+1 zK`O^~jCckR07a}i#+gYiT7+eY=@lyWNwp)^=HL|~+D)turXyV&fXmTSB)JMq1A@}7 z$SFYFQ^o>d+BOM_MWTrHEp0VK7>`yDf=mR65hfs~pX0vd>cbA8_Ca%a0yR2&CSiY; zTn$<|v5$vp1L8%s70Ma{vU*%1VH47v2)0|~)5t_5%v@T*iU<}??j_N}x#*3fF#~qS zc;GNnWT;F-6+GF76hew5PKY{?O@@;Pbre-MA!V+PS6Bf~n2Wd7m! zhWnGyuZ7@HKq;|Bkv=L8IK>~My9Dt;QzY#wB`7*m8v`lYo-z1obomC&^uJQP!dUxW0o6>AAj;aEt-hB6oulN0c|foIuhg zn1diWxDh_9MD@9+&-9{TEr*po3V2vWq*(J??)H=LcoAX~oF!1mS0u#q!U%LpNKbMJ z-XkAZ3GRZ>Msm_adKv5KVP>!~8RM=v+?3|FL4oE`5+j=;_tt6>a0?uW(g}n7KrDta zfs4dZde6NYKw6y7hrg}D`zEyATYxVYKS$5dYCggvAa?$kGMFVt4 zArT^dutA?$b`TI{Y9g*~kphlQ*wC|G#t4&_0pqK3xf_$&H64Oby1+)RTa zA@C{UaRf1unMoh4u!oaRlfLCtTv|;9e77dpgC4>jPR>f_#wcJhUA3nNJxzmLWMY5 z6u6;@5Dlzc;j7qDSHSKOR1)wG@uiv@HK1En_%|vw0&GG=Fk*0hf&**AETUfrekHP> zDi(fe_Hzs@jrmJutWcS+?B}R~-WC%J27@U@N-mI#2gjUqOo(M;WB~F<+y}-{ZU6fP z00V{U9P|n4gyj=RRY&y!N6axK<#s5N2b3%MghRt<$r3QH01O6cTtZ8lJ8E|?aApK= zvIZtKXcRD`6@X1HLZ@i5A{qy_BVJ%3sCR|`$(kF^dcrOVFP_j(_(t7Ein-68(Z+fa z3WF|8DLg{Nstc?OO{=^v^=VzGG5C$B#Ks0aeHoMN@!Xxot;4VnVp#gqN0^Ya4 zPzV87ze(;n$BG>#XqoMswl9LfkeT77@QZdY{J8({nPco$<2aZbg+PQfBecIt!``Rm z##Y7cb?p7eh#W>LAZ-qvLKaCOju1FjMpnh41P`fwhA|p#Z;{CZ+CyV^73+vMX9%Gx z5;7#fxi!&CR%SxlNC3oCV3CPa0?R*f4^orlGjb&_y@P-hY@OqA5v)6CH4Y7uHU@0i z(^3d}FsPEquA!5Oq*BJ>Q*3b?a~z=%fV=?W0|Z$a&}g)!N;oz+283%707G-HXUBrC zpym}!k^p`>g#8dMB#VoD6UR&u06=b&@u#uu?0V8;-{J&MCQX0N2I;M-@Th1b&P7|U zC8UpRe+-yt!p<(mNgfZ39-DG^KO?CMN0B2{cr;x7iPSP{Y;3m$Wt<>P(@yNGXuoCb5SYa|g&pMl>Dm zksnjBguWHDhC>T5n)*=or63$S)?sK4o+f}UR`R8IOD5j)53w1R?}Yq{(kP z`X2DY*qEV_2AU1})WI!6l!Fu)Kpg=x0H1_I;@`z&Sf6~xW7~=(C1LtvP#RUBEqJgR zz2uH7=iuCcBM9P~XzbZr=1Oi5$B+sJG9x!_5BWrNd!p)+jK-coQ<*p z2lWhk1x5@Q)GpFzWGp3%P(TIB-UhQ`k_xnhMt>= zkqJ6t=n^!kC&VF&L%y3*EI=TP7O`B7DA-y5s}dFDw8c(ktx2{mA+V3g{2)1ITN%rh zpN6qN$*7KXGu+n?N@$*6M7{{hsZe=Ne~Bpu6fbM!Nfg3kkx9w)2`F@vBqClSpAmJ8 znAc>JSX`7K9?IySoO+vb2=tLne~- z1eJ^mihq z=jmz~iQ|D#EOU#*P6Y3ejvr#O55JgW+DPU&xTB7fsqm15h_VduDN)#h5o_B$YJ`-m z`Kf4Qw;af*4|^mn`o2fhUfWIQDcVc`19*?fN@Lm=?NRCQzDGJ561x}~lF)&cXJy3j zK!Q#?Ot^>xW#H%{N`~m3V!J?gHsKN{g6|q>!^ES&nd^TPJLz-_n_yxQ0)G%Yhc5)y z$aDvW!o+4hk^uCXao05$K%m0T{dDxn?!cf;9Ks?tEzBEPScII1apr1F6m-Db2Hs_t zgvUswxcbf--l^SZzrZk5je{{z5gOB*!o|TLmeZRU5M#O0ooi(s94B(fG*3|@BJi9f zLW^8Z%lR7KZNfR_O-&dI!b9?NNtoJEa%Q{Pz}c0z%?j?g^1M~aZ?mWzU?&;zImgsD zBC-Wp8qU^(k98c&;sS>hC3hyp*tB$;EC<(ZDQ@r6|El^;Bju~UJ=WL{@HxC>>{gva zjicm2MP#laN=d|q!okR9Ajy^!%bXbE_j`ocH-Ct0M!EZ^B_k30Y01jGFPUrEw20vx z&2_@42_dY7_BDl+83!x{x8Ek3gE^ay&KCDQO14hK}_csdV?sNxcT zVu8;A46_{)lc2JmT+V=m)TS@O0Xqe>0pt)H@6wVZfZ9dQ%WPuX9#yEAN5>;;$d?b; zi#Conhw&U(D8!w;JOoP>f z;O-mvk?aA*kefvC5{1`_7KtzmG~CWdUIwV+d1f67l_GW_?4*&N4VEjm5Ta42Q%VRw zdp7q0WxhO;<3no^sY{$Q+RikB^aSyFu%m`n0^Cj#$Acot+;a^u@l@buCGx}skA_6b z%kU+L7iM>m>J9NrhTQaEVvirsrum2=0ujr9tf#hYBKTXIgcpX8A?AXtp^EVy2K0;Kd5Vut{Rd}E*6|3X2Q7u&&fI1 z_Sga-QLf2Tq&&W2QJMm04QYdb;&HUNY4;F>K`Zz9tI77#17rH8Nle0YU zkVMcVT%4tdSNzvr%tpn0omr;!qx?3dQ7I?kK89dXcV?kIBwP+S&K$}_Yy?v1(N>Cf z5R5otVuW2{IQJtlj3rwQY9R1{M;H?r^b%J~MkbESPw^k#v5)1^1-fUseu+&Vml`vs zuyF(*8B#-93Y7=3I4OzI?+winFi9X6B<~&rEi$|?u1$*Tq6HEruwWlTvB5|5V!4SH zL)navmEt_cj{G+=cRzJ_sm~6(`pC0x!?S9`vm){=*H3SFHu;TbVrPWe5r# zgW?g0iGbh4eN5aMPK;%NdK^kBQKzL zGA4oBqPJVx?uZwjaNQNDCmYMtrHe^Q%#ZN=Ug%QKm;$pMerlGo;%gA`jghUtY3uMogYyAn>A+T)FQRO2QCB<5>+7zM+W1 zu2Dn=$YNN1VN@=LbaN_}bUjyn!E;rqtwd$EA|-t68AahE=6`HuFtZgxSUwde7+8h_ zYM%!fY-%x3ld;XI5`K)(N6Y9t#L;BTVbIoS3$*^-5+Qo$?cdfnoV1ra&Vzjmk_ED& zGNoe?VGF7clO6UpE+MZ%p!bi1j6fmaV+WVT!*8}2r492ZVOCLtjt*;!AzwVG4zVKS zxD`()L@^lq76{fekaP%nf_E*C)s`G0WH{_%<13os;U&?#qw(j7`5vit#NUY+32e^W z>=E3<(@40cOvk27qj+8}2Y@xobOT3>IorjpO^`YNUAHl229ed!Un(4gvPoFAVZewS zhDDajVE6}D0%JTYmyMyGIhNl`{9UrA&9sQPN5d>cS}-4QafFSu(C@Ucbo_#wSTJ%} zAdY5$h&cD?cupX^Brae8$FS1y-159BqKlp3Dj-QJ$riGAhALH@DIG|{!)8nZ&lLp6 zs3u?uh3ZTPiAdr^Uv^;3e#}jyNlEZXAE}j$Y6Ou%lzD3%`+EbX6{C(DHTd7*BE-Ci zR>_wt<9Bu?T#0;^4zVBh1G~y##AkLj(G@1!rCH4cGy!ek68oHjTWGC^8WKEsi&ZR{ z{DeCJ2{u^{>1YhaVV#la80eFPab(PADua4gl*%wX!zelMFh*d;CSm~}k{1>j1ILwZ zH?xh$-~yqJ2(^OZf_%xf%$_j^l1ee5$bsm9kRRY0dh?LtO?Y-y(5(A0KN07|j z&eo`CLA+o;gOGOM+&}5I*!sxxf;O_mKUopSe?(b=zT&W;_8VCesB!1D{YB_rq8o&i z#b>P~w*Cfc-$P1aoSJPx>Bg)8u#rJNl{@?PVkeya?Q`ZGwZ13U_?HF9!3Br#(8w6( z^RaXa4O^I4fAQuKcDLC`s zTQmi$6jCsri1$Ohlg|0`9A>$NJREyTDbze^j9(+BkS3O~L0H%niB0Z3a9#h-1x{xs zn0Ee7E)D-tZfZ6#PXR4Fo`0+2jTo5YhH!W0onrVBrmnnyXXiqsmm%{?=F{;Ho7lJ_ zxwl=90^UJQ3!6s8qlDnaDOeMW21<;V`!Xo-b;%Uyhak@<`n@@~@FXnfMoB4g%AZ?= z;8rU9XoZ9OV!#(~=m()c&z+8>ZW0j#DujnvHZhJmhQvq@z6r?omUzc^rAk<--5E_~ zwfLvPb&hoy?rp|4ihMH0JRcAhE?S%`l0* z-OuJ?f1V=S`p0n?4WH`JM3fZIg5^;C=P-*IyMHfKjq^DSolhc4Hn9%O`N6Tp?{Ik;^rwdUd4WH zXfJl*U93i6<84JuP`g+RV>Qn`M};`gwlX~6@vrB!Z_6uOK#2osar~M_i$^j>mynBb zQ|Jyyrxl(L7ZPz826UKwf{`7hd)>z=n8qoFjPSqMhv6S(3aGXGGzk~KSrI-=7FF?l z-zSSIZmx+#Ffjlo#x#JwslB3>2+fntP@R7CXPBNffRr=rl?2{>^!0kjycU_{FU5ak~#au$P^71C#MDn8dKp!+is zF-{N?C;aOp#%sI4MGcON3P=1{Qg({#o|t#gDHAKSEjK`aevTLB^^s@SV!{c*I70qr zgx)C>sb{vMSW=uzz(8pHR!95^6!a#bdI-N*<6Zckaol#xP_Oh7%)CXX-S&cXC;&pq zJZjhCKt%1h&UDl8`fy;laY`&cAZ6A$ZJWQ?0Y+nn} z<%w9E3*TFp-KicnylkFpYj2xH%3k>JzWTQdUu>0g zotz|myR!Xy^8UW?}^N;s^c831Z^0a zn>SW3{Fk#h0M_Up;}`?imMU&_y%<@Dz*zA3G^#m%oyU|OmV8_weAsx4=!AcFaw zvvz)V50t}iSvb^K#^2qu4%MCF{df2HM@m2Z?jBmbee%w=JCDRl`H`$3{@o*=$D?&` z{Is*s=kefaP9Hrd#ls%CWcwJS6Gm59pt{{;ZT+umt1wc&loP|4QtSl?X$qIRu>`oT)P0}!|8^}c_8H-6$rZr<(vKX~`Ohq24jIR_(U3yQ45Kdv5OMZMYyE||MG95pesI!KVl}8 zcV9bIE+Mt`9RgH4S&5G-4P((zYr1u+cI5GsTlIF~3$^x}TlE|C{oQxjs{cT^CfF3{J5~TZ%);hKG0{@Qopm-N4M&uy~O7)+_bGv^@+81T&m2wwftMGW%271 zU$WL_i~j{ql~e*A#CIg#=|KCewVXrv^UbT;@d!ToRhb_gtKa;p-`uL-otLds^}SC8 zV(XynyHl0<`(9NDU$Yi|2tZ;M_{OXH#tGW^P+vJ#yMEQKTlJ-%7M-e}e5%a5Q + SPDX-License-Identifier: LGPL-2.1-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.plasmoid +import org.kde.plasma.components as PlasmaComponents + +Item { + Plasmoid.fullRepresentation: ColumnLayout { + anchors.fill: parent + Image { + Layout.fillHeight: true + Layout.fillWidth: true + fillMode: Image.PreserveAspectFit + source: "../images/pairs.svgz" + } + PlasmaComponents.Label { + Layout.alignment: Qt.AlignCenter + text: "This is Plasma!" + } + } +} diff --git a/templates/qml-plasmoid6/package/metadata.json b/templates/qml-plasmoid6/package/metadata.json new file mode 100644 index 0000000..b13d49d --- /dev/null +++ b/templates/qml-plasmoid6/package/metadata.json @@ -0,0 +1,153 @@ +{ + "KPackageStructure": "Plasma/Applet", + "KPlugin": { + "Authors": [ + { + "Email": "%{EMAIL}", + "Name": "%{AUTHOR}", + "Name[ar]": "%{المؤلف}", + "Name[az]": "%{MÜƏLLİF}", + "Name[be]": "%{AUTHOR}", + "Name[bg]": "%{AUTHOR}", + "Name[ca@valencia]": "%{AUTHOR}", + "Name[ca]": "%{AUTHOR}", + "Name[cs]": "%{AUTHOR}", + "Name[da]": "%{AUTHOR}", + "Name[de]": "%{AUTHOR}", + "Name[el]": "%{AUTHOR}", + "Name[en_GB]": "%{AUTHOR}", + "Name[eo]": "%{AŬTORO}", + "Name[es]": "%{AUTHOR}", + "Name[eu]": "%{AUTHOR}", + "Name[fi]": "%{AUTHOR}", + "Name[fr]": "%{AUTHOR}", + "Name[gl]": "%{AUTHOR}", + "Name[he]": "%{AUTHOR}", + "Name[hu]": "%{AUTHOR}", + "Name[ia]": "%{AUTHOR}", + "Name[id]": "%{AUTHOR}", + "Name[is]": "%{AUTHOR}", + "Name[it]": "%{AUTHOR}", + "Name[ka]": "%{AUTHOR}", + "Name[ko]": "%{AUTHOR}", + "Name[lt]": "%{AUTHOR}", + "Name[lv]": "%{AUTHOR}", + "Name[nl]": "%{AUTHOR}", + "Name[nn]": "%{AUTHOR}", + "Name[pl]": "%{AUTHOR}", + "Name[pt]": "%{AUTHOR}", + "Name[pt_BR]": "%{AUTHOR}", + "Name[ro]": "%{AUTHOR}", + "Name[ru]": "%{AUTHOR}", + "Name[sa]": "%{AUTHOR}", + "Name[sk]": "%{AUTHOR}", + "Name[sl]": "%{AUTHOR}", + "Name[sv]": "%{AUTHOR}", + "Name[ta]": "%{AUTHOR}", + "Name[tr]": "%{AUTHOR}", + "Name[uk]": "%{AUTHOR}", + "Name[vi]": "%{AUTHOR}", + "Name[x-test]": "xx%{AUTHOR}xx", + "Name[zh_CN]": "%{AUTHOR}", + "Name[zh_TW]": "%{AUTHOR}" + } + ], + "Category": "Utilities", + "Description": "what your app does in a few words", + "Description[az]": "Bu proqramın nə işə yaradığı haqqında bir neçə söz", + "Description[be]": "кароткае апісанне працы вашай праграмы", + "Description[bg]": "какво прави вашето приложение с няколко думи", + "Description[ca@valencia]": "Què fa esta aplicació en poques paraules", + "Description[ca]": "Què fa aquesta aplicació en poques paraules", + "Description[da]": "hvad dit program, helt kort", + "Description[de]": "Was Ihre Anwendung macht (kurze Beschreibung)", + "Description[el]": "τι κάνει η εφαρμογή σας με λίγες λέξεις", + "Description[en_GB]": "what your app does in a few words", + "Description[eo]": "kion via aplikaĵo faras en kelkaj vortoj", + "Description[es]": "Lo que hace su aplicación en pocas palabras", + "Description[eu]": "zure aplikazioak egiten duena hitz gutxitan", + "Description[fi]": "muutama sana siitä, mitä sovelmasi tekee", + "Description[fr]": "ce que votre application fait en quelques mots", + "Description[gl]": "O que fai a aplicación, en poucas palabras.", + "Description[he]": "מה עושה היישום שלך במספר מילים", + "Description[hu]": "Írja le néhány szóban, mit csinál az alkalmazása", + "Description[ia]": "cosa tu app face in pauc parolas", + "Description[id]": "apa yang dilakukan aplikasi Anda dalam beberapa kata", + "Description[is]": "hvað forritið þitt gerir í fáum orðum", + "Description[it]": "Cosa fa la tua applicazione in poche parole", + "Description[ka]": "რამდენიმე სიტყვით, რას აკეთებს თქვენი აპლიკაცია", + "Description[ko]": "앱이 하는 일에 대한 간단한 설명", + "Description[lt]": "keliais žodžiais, ką daro jūsų programa", + "Description[lv]": "uzrakstiet dažos vārdos, ko jūsu programma dara", + "Description[nl]": "wat uw app doet in een paar woorden", + "Description[nn]": "nokre få ord om kva programmet gjer", + "Description[pl]": "w kilku słowach opis co robi twój program", + "Description[pt]": "o que faz a sua aplicação em poucas palavras", + "Description[pt_BR]": "o que seu aplicativo faz em poucas palavras", + "Description[ro]": "ce face aplicația, în câteva cuvinte", + "Description[ru]": "Несколько слов о том, что делает ваша программа", + "Description[sa]": "भवतः अनुप्रयोगः कतिपयेषु शब्देषु किं करोति", + "Description[sk]": "čo vaša aplikácia robí v niekoľkých slovách", + "Description[sl]": "v parih besedah kar počne vaša aplikacija", + "Description[sv]": "vad programmet gör med några få ord", + "Description[tr]": "uygulamanızı birkaç sözcükle anlatın", + "Description[uk]": "призначення вашої програми у декількох словах", + "Description[vi]": "dùng vài từ để mô tả ứng dụng của bạn làm việc gì", + "Description[x-test]": "xxwhat your app does in a few wordsxx", + "Description[zh_CN]": "用一个短句概括您的小程序的功能", + "Description[zh_TW]": "幾個詞內簡述您的應用程式所做的事", + "EnabledByDefault": true, + "Icon": "applications-system", + "Id": "org.kde.plasma.%{APPNAMELC}", + "License": "LGPL-2.1+", + "Name": "%{APPNAME}", + "Name[ar]": "%{اسم_التطبيق}", + "Name[ast]": "%{APPNAME}", + "Name[az]": "%{TƏTBİQ_ADI}", + "Name[be]": "%{APPNAME}", + "Name[bg]": "%{APPNAME}", + "Name[ca@valencia]": "%{APPNAME}", + "Name[ca]": "%{APPNAME}", + "Name[cs]": "%{APPNAME}", + "Name[da]": "%{APPNAME}", + "Name[de]": "%{APPNAME}", + "Name[el]": "%{APPNAME}", + "Name[en_GB]": "%{APPNAME}", + "Name[eo]": "%{APPNAME}", + "Name[es]": "%{APPNAME}", + "Name[eu]": "%{APPNAME}", + "Name[fi]": "%{APPNAME}", + "Name[fr]": "%{APPNAME}", + "Name[gl]": "%{APPNAME}", + "Name[he]": "%{APPNAME}", + "Name[hu]": "%{APPNAME}", + "Name[ia]": "%{APPNAME}", + "Name[id]": "%{APPNAME}", + "Name[is]": "%{APPNAME}", + "Name[it]": "%{APPNAME}", + "Name[ka]": "%{APPNAME}", + "Name[ko]": "%{APPNAME}", + "Name[lt]": "%{APPNAME}", + "Name[lv]": "%{APPNAME}", + "Name[nl]": "%{APPNAME}", + "Name[nn]": "%{APPNAME}", + "Name[pl]": "%{APPNAME}", + "Name[pt]": "%{APPNAME}", + "Name[pt_BR]": "%{APPNAME}", + "Name[ro]": "%{APPNAME}", + "Name[ru]": "%{APPNAME}", + "Name[sa]": "%{APPNAME}", + "Name[sk]": "%{APPNAME}", + "Name[sl]": "%{APPNAME}", + "Name[sv]": "%{APPNAME}", + "Name[ta]": "%{APPNAME}", + "Name[tr]": "%{APPNAME}", + "Name[uk]": "%{APPNAME}", + "Name[vi]": "%{APPNAME}", + "Name[x-test]": "xx%{APPNAME}xx", + "Name[zh_CN]": "%{APPNAME}", + "Name[zh_TW]": "%{APPNAME}", + "Version": "1.0", + "Website": "https://plasma.kde.org/" + } +} diff --git a/templates/qml-plasmoid6/qml-plasmoid6.kdevtemplate b/templates/qml-plasmoid6/qml-plasmoid6.kdevtemplate new file mode 100644 index 0000000..7381f06 --- /dev/null +++ b/templates/qml-plasmoid6/qml-plasmoid6.kdevtemplate @@ -0,0 +1,91 @@ +[General] +Name=Plasma QML Applet (Qt6) +Name[ar]=بريمج بلازما ب‍QML (كيوت6) +Name[be]=Аплет QML/C++ для Plasma (Qt6) +Name[bg]=QML приставка за Plasma (Qt6) +Name[ca]=Miniaplicació QML del Plasma (Qt6) +Name[ca@valencia]=Miniaplicació en QML de Plasma (Qt6) +Name[cs]=Aplet QML Plasma (Qt6) +Name[da]=Plasma QML-applet (Qt6) +Name[de]=Plasma-QML-Miniprogramm (Qt6) +Name[en_GB]=Plasma QML Applet (Qt6) +Name[eo]=Plasma QML-apleto (Qt6) +Name[es]=Miniaplicación en QML para Plasma (Qt6) +Name[eu]=Plasma QML aplikaziotxoa (Qt6) +Name[fi]=Plasman QML-sovelma (Qt6) +Name[fr]=Applet « QML » pour Plasma (Qt6) +Name[gl]=Miniaplicativo QML para Plasma (Qt 6) +Name[he]=יישומונית QML לפלזמה (Qt6) +Name[hu]=Plasma QML kisalkalmazás (Qt6) +Name[ia]=Applet QML de Plasma (Qt6) +Name[is]=Plasma QML smáforrit (Qt6) +Name[it]=Applet QML di Plasma (Qt6) +Name[ka]=Plasma-ის QML აპლეტი (Qt6) +Name[ko]=Plasma QML 애플릿(Qt6) +Name[lt]=Plasma QML programėlė (Qt6) +Name[lv]=„Plasma“ QML sīklietotne (Qt6) +Name[nl]=Plasma QML-applet (Qt6) +Name[nn]=Plasma QML-element (Qt6) +Name[pl]=Aplet QML Plazmy (Qt6) +Name[pt_BR]=Miniaplicativo QML do Plasma (Qt6) +Name[ro]=Miniaplicație QML Plasma (Qt6) +Name[ru]=Виджет Plasma на QML (Qt6) +Name[sa]=Plasma QML Applet (Qt6) +Name[sl]=Plasma aplet v QML (Qt6) +Name[sv]=Plasma QML-miniprogram (Qt6) +Name[ta]=பிளாஸ்மா QML பிளாஸ்மாய்ட் (Qt6) +Name[tr]=Plasma QML Uygulamacığı (Qt6) +Name[uk]=Аплет Плазми мовою QML (Qt6) +Name[vi]=Tiểu ứng dụng QML Plasma (Qt6) +Name[x-test]=xxPlasma QML Applet (Qt6)xx +Name[zh_CN]=Plasma QML 小程序 (Qt6) +Name[zh_TW]=Plasma QML 小程式 (Qt6) +Comment=Plasma QML Applet template: a Plasma applet template displaying a SVG picture and a text +Comment[az]=Plasma QML əlavəsi nümunəsi: Plasma əlavəsi nümunəsi SVG şəkli və mətn kimi görünür +Comment[be]=Шаблон аплета QML для Plasma: шаблон аплета Plasma, які паказвае выяву SVG і тэкст +Comment[bg]=Шаблон на QML приставка на Plasma: показване на SVG изображение и текст +Comment[ca]=Una plantilla de miniaplicació del Plasma en QML: una plantilla de miniaplicació del Plasma que mostra una imatge SVG i un text +Comment[ca@valencia]=Una plantilla de miniaplicació de Plasma en QML: una plantilla de miniaplicació de Plasma que mostra una imatge SVG i un text +Comment[da]=En skabelon til en Plasma QML-applet: En skabelon til Plasma som viser et SVG-billede og en tekst +Comment[de]=Eine Vorlage für ein QML-Miniprogramm: Eine Vorlage für ein Plasma-Miniprogramm, das ein SVG-Bild und einen Text anzeigt +Comment[en_GB]=Plasma QML Applet template: a Plasma applet template displaying a SVG picture and a text +Comment[eo]=Plasma QML-apleto-ŝablono: Plasma-apleta ŝablono montranta SVG-bildon kaj tekston +Comment[es]=Una plantilla de miniaplicación en QML para Plasma: una plantilla de miniaplicación para Plasma que muestra una imagen SVG y un texto +Comment[et]=Plasma QML-i apleti mall: Plasma apleti mall, mis kuvab SVG-pilti ja teksti +Comment[eu]=Plasma QML aplikaziotxo-txantiloia: Plasma aplikaziotxo-txantiloi bat SVG irudi bat eta testu bat bistaratzen dituena +Comment[fi]=Plasman QML-sovelmamalli, joka näyttää SVG-kuvan ja tekstin +Comment[fr]=Modèle d'applet Plasma QML : un modèle d'applet Plasma qui affiche une image SVG et du texte +Comment[gl]=Modelo de miniaplicativo para Plasma: un modelo de miniaplicativo para Plasma que mostra unha imaxe SVG e un texto. +Comment[he]=תבנית יישומונית QML לפלזמה: תבנית יישומונית פלזמה שמציגה תמונת SVG וטקסט +Comment[hu]=Egy SVG-képet és szöveget megjelenítő Plasma kisalkalmazás-sablon. +Comment[ia]=Patrono de Applet QML de Plasma: un patrono de applet e Plasma monstrante un imagine SVG e un texto +Comment[id]=Templat Applet QML Plasma: sebuah templat applet Plasma yang menampilkan sebuah teks dan gambar SVG +Comment[is]=Sniðmát fyrir Plasma QML smáforrit: Plasma smáforritasniðmát sem birtir SVG-mynd og texta +Comment[it]=Un modello di applet di Plasma scritto in QML: un modello di applet di Plasma che visualizza un'immagine SVG e un testo +Comment[ka]=Plasma-ის QML აპლეტის ნიმუში: Plasma-ის აპლეტი, რომელსაც SVG სურათი და ტექსტი გამოაქვს +Comment[ko]=Plasma QML 애플릿 템플릿: SVG 그림과 텍스트를 표시하는 Plasma 애플릿 템플릿 +Comment[lt]=Plasma QML programėlės šablonas: Plasma programėlės šablonas, atvaizduojantis SVG paveikslą ir tekstą +Comment[lv]=Plasma QML sīklietotnes veidne: „Plasma“ sīklietotnes veidne, kurā ir redzams SVG attēls un teksts +Comment[nl]=Sjabloon voor Plasma-QML-applet: een sjabloon voor een plasma-applet dat een svg-afbeelding en een tekst toont +Comment[nn]=Plasma-elementmal skriven i QML: Ein mal for eit Plasma-element som viser eit SVG-bilete og litt tekst +Comment[pl]=Szablon apletu Plazmy QML: szablon apletu plazmy wyświetlający obraz SVG i tekst +Comment[pt]=Modelo de 'Applet' do Plasma em QML: um modelo de 'applets' do Plasma que mostra uma figura em SVG e um texto +Comment[pt_BR]=Modelo do miniaplicativo QML do Plasma: um modelo de miniaplicativo do Plasma mostrando uma imagem SVG e um texto +Comment[ru]=Шаблон виджета Plasma на QML: виджет показывает изображение SVG и текст +Comment[sa]=PLasma QML Applet ढांचा : SVG चित्रं पाठ्यम् च प्रदर्शयति इति PLasma Applet ढांचा +Comment[sk]=Šablóna appletu Plasma QML: šablóna plasma appletu zobrazujúca svg obrázok a text. +Comment[sl]=Predloga Plasma apleta v QML: predloga Plasma apleta, ki prikazuje sliko SVG in besedilo +Comment[sr]=Шаблон плазма КуМЛ аплета: приказ СВГ слике и текста +Comment[sr@ijekavian]=Шаблон плазма КуМЛ аплета: приказ СВГ слике и текста +Comment[sr@ijekavianlatin]=Šablon plasma QML apleta: prikaz SVG slike i teksta +Comment[sr@latin]=Šablon plasma QML apleta: prikaz SVG slike i teksta +Comment[sv]=Mall för Plasma QML-miniprogram. En mall för ett Plasma-miniprogram som visar en SVG-bild och en text +Comment[tg]=Қолиби зербарномаи Plasma дар асоси QML: Қолиби зербарномаи Plasma матн ва тасвири SVG-ро нишон медиҳад +Comment[tr]=Plasma QML Uygulamacığı şablonu: SVG resmi ve metin gösteren bir Plasma uygulamacığı şablonu +Comment[uk]=Шаблон аплету Плазми. Шаблон аплету Плазми, який показу зображення SVG і текст +Comment[vi]=Bản mẫu Tiểu ứng dụng QML của Plasma: một bản mẫu tiểu ứng dụng Plasma hiển thị một ảnh SVG và một văn bản +Comment[x-test]=xxPlasma QML Applet template: a Plasma applet template displaying a SVG picture and a textxx +Comment[zh_CN]=Plasma QML 小程序模板:显示 SVG 图片和文字的 Plasma 小程序模板 +Comment[zh_TW]=Plasma QML 小程式範本:Plasma 小程式範本顯示了一張 SVG 圖片與文字 +Category=Plasma/Plasmoid +Icon=qml-plasmoid6.png diff --git a/templates/qml-plasmoid6/qml-plasmoid6.png b/templates/qml-plasmoid6/qml-plasmoid6.png new file mode 100644 index 0000000000000000000000000000000000000000..26748f6cf7d22ef003badbca80cb69a61e2d46d2 GIT binary patch literal 35613 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 z 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 N002ovPDHLkV1id(qSXKZ literal 0 HcmV?d00001 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..5e0a613 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(dpi) diff --git a/tests/buttons_pc3.0.qml b/tests/buttons_pc3.0.qml new file mode 100644 index 0000000..ebfe330 --- /dev/null +++ b/tests/buttons_pc3.0.qml @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2018 Aleix Pol + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick + +import org.kde.plasma.components as PlasmaComponents + +Rectangle +{ + width: 500 + height: 300 + color: "white" + + Flow { + anchors.fill: parent + anchors.margins: 20 + spacing: 20 + + PlasmaComponents.Button { + text: "test" + } + PlasmaComponents.Button { + text: "test" + flat: true + } + PlasmaComponents.ToolButton { + text: "test" + } + } +} + diff --git a/tests/components/ComponentBase.qml b/tests/components/ComponentBase.qml new file mode 100644 index 0000000..8af80e6 --- /dev/null +++ b/tests/components/ComponentBase.qml @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2019 David Edmundson + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +PlasmaComponents.Page { + id: mainPage + title: "Test" + width: Math.max(mainPage.contentWidth, mainPage.implicitHeaderWidth, mainPage.implicitFooterWidth) + + leftPadding + rightPadding + height: mainPage.contentHeight + mainPage.implicitHeaderHeight + mainPage.implicitFooterHeight + + topPadding + bottomPadding + + padding: Kirigami.Units.gridUnit + + header: PlasmaComponents.ToolBar { + leftPadding: mainPage.padding + rightPadding: mainPage.padding + contentItem: Kirigami.Heading { + text: mainPage.title + /* FIXME: this line is needed to prevent vertical pixel + * misalignment of controls, such as checkboxes. + * The cause of the problem is unknown. + */ + level: 2 + } + } + + background: Rectangle { + color: Kirigami.Theme.backgroundColor + } +} + diff --git a/tests/components/busyindicator3.qml b/tests/components/busyindicator3.qml new file mode 100644 index 0000000..1d93481 --- /dev/null +++ b/tests/components/busyindicator3.qml @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: 2019 David Edmundson + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +ComponentBase { + id: root + title: "Plasma Components 3 BusyIndicator" + contentItem: ColumnLayout { + spacing: Kirigami.Units.gridUnit + + PlasmaComponents.Label { + wrapMode: Text.WordWrap + text: "The BusyIndicator should have a height of 16px and should have a 1:1 aspect ratio" + Layout.preferredWidth: Math.max(busyIndicatorLayout.width, root.implicitHeaderWidth) + } + PlasmaComponents.BusyIndicator { + Layout.preferredHeight: 16 + } + + PlasmaComponents.Label { + wrapMode: Text.WordWrap + text: "The BusyIndicator should use its implicit size." + Layout.preferredWidth: Math.max(busyIndicatorLayout.width, root.implicitHeaderWidth) + } + PlasmaComponents.BusyIndicator {} + + PlasmaComponents.Label { + wrapMode: Text.WordWrap + text: "The BusyIndicator should maintain a 1:1 aspect ratio, disappear when unchecked and restart when checked." + Layout.preferredWidth: Math.max(busyIndicatorLayout.width, root.implicitHeaderWidth) + } + + RowLayout { + id: busyIndicatorLayout + spacing: Kirigami.Units.gridUnit + + PlasmaComponents.BusyIndicator { + Layout.fillWidth: true + Layout.fillHeight: true + running: runningButton.checked + } + + PlasmaComponents.CheckBox { + id: runningButton + text: "Running" + checked: true + } + } + } +} diff --git a/tests/components/button3.qml b/tests/components/button3.qml new file mode 100644 index 0000000..c60ce33 --- /dev/null +++ b/tests/components/button3.qml @@ -0,0 +1,245 @@ +/* + * SPDX-FileCopyrightText: 2019 David Edmundson + * SPDX-FileCopyrightText: 2020 Marco Martin + * SPDX-FileCopyrightText: 2020 Nate Graham + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +ComponentBase { + id: root + title: "PlasmaComponents 3 Button" + contentItem: ColumnLayout { + GridLayout { + rowSpacing: Kirigami.Units.smallSpacing + columnSpacing: Kirigami.Units.gridUnit + columns: 2 + + PlasmaComponents.Label { + text: "icon + text" + } + + PlasmaComponents.Button { + icon.name: "start-here-kde-plasma" + text: "test" + } + + PlasmaComponents.Label { + text: "icon alone, should look small and square" + } + + PlasmaComponents.Button { + icon.name: "start-here-kde-plasma" + } + + PlasmaComponents.Label { + text: "text alone, should be about as wide as the text itself" + } + + PlasmaComponents.Button { + text: "test" + } + + PlasmaComponents.Label { + text: "This should look highlighted on load" + } + + PlasmaComponents.Button { + text: "test" + focus: true + } + + PlasmaComponents.Label { + text: "long text, should expand to fit" + } + + PlasmaComponents.Button { + icon.name: "start-here-kde-plasma" + text: "This is a really really really really long button" + } + + PlasmaComponents.Label { + text: "long text but constrained, should be 150px and elided" + } + + PlasmaComponents.Button { + icon.name: "start-here-kde-plasma" + text: "This is a really really really really long button" + Layout.maximumWidth: 150 + } + + PlasmaComponents.Label { + text: "disabled icon + text" + } + + PlasmaComponents.Button { + icon.name: "start-here-kde-plasma" + text: "test" + enabled: false + } + + PlasmaComponents.Label { + text: "button (with or without icon) and textfield should have the same height" + } + + RowLayout { + PlasmaComponents.Button { + text: "test" + } + PlasmaComponents.Button { + icon.name: "application-menu" + text: "test" + } + PlasmaComponents.TextField { + } + } + + PlasmaComponents.Label { + text: "Display property" + } + RowLayout { + PlasmaComponents.Button { + icon.name: "application-menu" + text: "Icon Only" + display: PlasmaComponents.Button.IconOnly + } + PlasmaComponents.Button { + icon.name: "application-menu" + text: "Text Beside Icon" + display: PlasmaComponents.Button.TextBesideIcon + } + PlasmaComponents.Button { + icon.name: "application-menu" + text: "Text Under Icon" + display: PlasmaComponents.Button.TextUnderIcon + } + PlasmaComponents.Button { + icon.name: "application-menu" + text: "Text Only" + display: PlasmaComponents.Button.TextOnly + } + } + } + Kirigami.Heading { + text: "Flat Buttons" + } + GridLayout { + rowSpacing: Kirigami.Units.smallSpacing + columnSpacing: Kirigami.Units.gridUnit + columns: 2 + + PlasmaComponents.Label { + text: "icon + text" + } + + PlasmaComponents.Button { + icon.name: "start-here-kde-plasma" + text: "test" + flat: true + } + + PlasmaComponents.Label { + text: "icon alone, should look small and square" + } + + PlasmaComponents.Button { + icon.name: "start-here-kde-plasma" + flat: true + } + + PlasmaComponents.Label { + text: "text alone, should be about as wide as the text itself" + } + + PlasmaComponents.Button { + text: "test" + flat: true + } + + PlasmaComponents.Label { + text: "long text, should expand to fit" + } + + PlasmaComponents.Button { + icon.name: "start-here-kde-plasma" + text: "This is a really really really really long button" + flat: true + } + + PlasmaComponents.Label { + text: "long text but constrained, should be 150px and elided" + } + + PlasmaComponents.Button { + icon.name: "start-here-kde-plasma" + text: "This is a really really really really long button" + Layout.maximumWidth: 150 + flat: true + } + + PlasmaComponents.Label { + text: "disabled icon + text" + } + + PlasmaComponents.Button { + icon.name: "start-here-kde-plasma" + text: "test" + flat: true + enabled: false + } + + PlasmaComponents.Label { + text: "button (with or without icon) and textfield should have the same height" + } + + RowLayout { + PlasmaComponents.Button { + text: "test" + flat: true + } + PlasmaComponents.Button { + icon.name: "application-menu" + text: "test" + flat: true + } + PlasmaComponents.TextField { + } + } + + PlasmaComponents.Label { + text: "Display property" + } + RowLayout { + PlasmaComponents.Button { + icon.name: "application-menu" + text: "Icon Only" + display: PlasmaComponents.Button.IconOnly + flat: true + } + PlasmaComponents.Button { + icon.name: "application-menu" + text: "Text Beside Icon" + display: PlasmaComponents.Button.TextBesideIcon + flat: true + } + PlasmaComponents.Button { + icon.name: "application-menu" + text: "Text Under Icon" + display: PlasmaComponents.Button.TextUnderIcon + flat: true + } + PlasmaComponents.Button { + icon.name: "application-menu" + text: "Text Only" + display: PlasmaComponents.Button.TextOnly + flat: true + } + } + } + } +} + diff --git a/tests/components/checkbox3.qml b/tests/components/checkbox3.qml new file mode 100644 index 0000000..a4de1a6 --- /dev/null +++ b/tests/components/checkbox3.qml @@ -0,0 +1,84 @@ +/* + * SPDX-FileCopyrightText: 2019 David Edmundson + * SPDX-FileCopyrightText: 2020 Nate Graham + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +ComponentBase { + id: root + title: "Plasma Components 3 CheckBox" + contentItem: GridLayout { + columnSpacing: Kirigami.Units.gridUnit + rowSpacing: Kirigami.Units.smallSpacing + columns: 2 + + PlasmaComponents.Label { + text: "text" + } + PlasmaComponents.CheckBox { + text: "Some awesome checkbox" + } + + PlasmaComponents.Label { + text: "icon" + } + PlasmaComponents.CheckBox { + icon.name: "start-here-kde-plasma" + } + + PlasmaComponents.Label { + text: "text plus icon" + } + PlasmaComponents.CheckBox { + text: "text" + icon.name: "start-here-kde-plasma" + } + + PlasmaComponents.Label { + text: "focus" + } + PlasmaComponents.CheckBox { + text: "Some awesome checkbox" + focus: true + } + + PlasmaComponents.Label { + text: "checked" + } + PlasmaComponents.CheckBox { + text: "Some awesome checkbox" + checkState: Qt.Checked + } + + PlasmaComponents.Label { + text: "tri-state" + } + PlasmaComponents.CheckBox { + text: "Some awesome checkbox" + checkState: Qt.PartiallyChecked + } + + PlasmaComponents.Label { + text: "disabled" + } + PlasmaComponents.CheckBox { + text: "Some awesome checkbox" + enabled: false + } + + PlasmaComponents.Label { + text: "disabled and checked" + } + PlasmaComponents.CheckBox { + text: "Some awesome checkbox" + enabled: false + checkState: Qt.Checked + } + } +} + diff --git a/tests/components/combobox3.qml b/tests/components/combobox3.qml new file mode 100644 index 0000000..fde7b30 --- /dev/null +++ b/tests/components/combobox3.qml @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2019 David Edmundson + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components +import org.kde.kirigami as Kirigami + +ComponentBase { + id: root + title: "Plasma Components 3 ComboBox" + contentItem: ColumnLayout { + spacing: Kirigami.Units.gridUnit + ListModel { + id: demoModel + ListElement { text: "Banana"; color: "Yellow" } + ListElement { text: "Apple"; color: "Green" } + ListElement { text: "Coconut"; color: "Brown" } + } + + ComboBox { + model:demoModel + textRole: "text" + } + ComboBox { + editable: true + model: demoModel + textRole: "text" + } + } +} diff --git a/tests/components/menu-placement.qml b/tests/components/menu-placement.qml new file mode 100644 index 0000000..c2383b6 --- /dev/null +++ b/tests/components/menu-placement.qml @@ -0,0 +1,93 @@ +/* + * SPDX-FileCopyrightText: 2015 Kai Uwe Broulik + * SPDX-FileCopyrightText: 2019 David Edmundson + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-FileCopyrightText: 2023 ivan tkachenko + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.extras as PlasmaExtras +import org.kde.plasma.components as PC3 +import org.kde.kirigami as Kirigami + +ComponentBase { + id: root + + title: "Plasma Extras Menu Placement" + + PlasmaExtras.Menu { + id: menu + + visualParent: centralButton + + placement: PlasmaExtras.Menu.BottomPosedRightAlignedPopup + preferSeamlessEdges: false + + PlasmaExtras.MenuItem { text: "Hello"; section: true } + PlasmaExtras.MenuItem { text: "This is just a simple" } + PlasmaExtras.MenuItem { text: "Menu" } + PlasmaExtras.MenuItem { separator: true } + PlasmaExtras.MenuItem { text: "With separators" } + PlasmaExtras.MenuItem { text: "And other stuff" } + } + + component PlacementRadioButton : PC3.RadioButton { + required property string placementName + + anchors.margins: Kirigami.Units.gridUnit + text: placementName.replace("Popup", "").replace(/([a-z])([A-Z])/g, "$1 $2") + checked: menu.placement === PlasmaExtras.Menu[placementName] + onToggled: menu.placement = PlasmaExtras.Menu[placementName] + } + + contentItem: Item { + implicitWidth: 600 + implicitHeight: 500 + + PC3.Button { + id: centralButton + anchors.centerIn: parent + width: 200 + height: 200 + text: "Open Relative" + onClicked: { + menu.openRelative() + } + } + + Repeater { + model: [ + { placementName: "TopPosedLeftAlignedPopup", bottom: "top", right: "horizontalCenter" }, + { placementName: "TopPosedRightAlignedPopup", bottom: "top", left: "horizontalCenter" }, + { placementName: "LeftPosedTopAlignedPopup", right: "left", bottom: "verticalCenter" }, + { placementName: "LeftPosedBottomAlignedPopup", right: "left", top: "verticalCenter" }, + { placementName: "BottomPosedLeftAlignedPopup", top: "bottom", right: "horizontalCenter" }, + { placementName: "BottomPosedRightAlignedPopup", top: "bottom", left: "horizontalCenter" }, + { placementName: "RightPosedTopAlignedPopup", left: "right", bottom: "verticalCenter" }, + { placementName: "RightPosedBottomAlignedPopup", left: "right", top: "verticalCenter" }, + ] + PlacementRadioButton { + required property var modelData + placementName: modelData.placementName + anchors.top: centralButton[modelData.top] + anchors.left: centralButton[modelData.left] + anchors.right: centralButton[modelData.right] + anchors.bottom: centralButton[modelData.bottom] + } + } + } + + footer: PC3.ToolBar { + contentItem: RowLayout { + spacing: Kirigami.Units.smallSpacing + + PC3.CheckBox { + Layout.alignment: Qt.AlignHCenter + text: "Prefer Seamless Edges" + checked: menu.preferSeamlessEdges + onToggled: menu.preferSeamlessEdges = checked; + } + } + } +} diff --git a/tests/components/menu.qml b/tests/components/menu.qml new file mode 100644 index 0000000..049db67 --- /dev/null +++ b/tests/components/menu.qml @@ -0,0 +1,122 @@ +/* + * SPDX-FileCopyrightText: 2015 Kai Uwe Broulik + * SPDX-FileCopyrightText: 2019 David Edmundson + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.extras as PlasmaExtras +import org.kde.plasma.components as PC3 +import org.kde.kirigami as Kirigami + +ComponentBase { + id: root + title: "Plasma Extras Menu" + contentItem: ColumnLayout { + spacing: Kirigami.Units.gridUnit + + PC3.Button { + text: "Simple menu" + onClicked: simpleMenu.open(0, height) + + PlasmaExtras.Menu { + id: simpleMenu + + PlasmaExtras.MenuItem { text: "Hello" } + PlasmaExtras.MenuItem { text: "This is just a simple" } + PlasmaExtras.MenuItem { text: "Menu" } + PlasmaExtras.MenuItem { text: "without separators" } + PlasmaExtras.MenuItem { text: "and other stuff" } + } + } + + PC3.Button { + text: "Checkable menu items" + onClicked: checkableMenu.open(0, height) + + PlasmaExtras.Menu { + id: checkableMenu + + PlasmaExtras.MenuItem { text: "Apple"; checkable: true } + PlasmaExtras.MenuItem { text: "Banana"; checkable: true } + PlasmaExtras.MenuItem { text: "Orange"; checkable: true } + } + } + + + PC3.Button { + text: "Icons" + onClicked: iconsMenu.open(0, height) + + PlasmaExtras.Menu { + id: iconsMenu + + PlasmaExtras.MenuItem { text: "Error"; icon: "dialog-error" } + PlasmaExtras.MenuItem { text: "Warning"; icon: "dialog-warning" } + PlasmaExtras.MenuItem { text: "Information"; icon: "dialog-information" } + } + } + + PC3.Button { + text: "Separators and sections" + onClicked: sectionsMenu.open(0, height) + + PlasmaExtras.Menu { + id: sectionsMenu + + PlasmaExtras.MenuItem { text: "A menu"; section: true } + PlasmaExtras.MenuItem { text: "One entry" } + PlasmaExtras.MenuItem { text: "Another entry" } + PlasmaExtras.MenuItem { separator: true } + PlasmaExtras.MenuItem { text: "One item" } + PlasmaExtras.MenuItem { text: "Another item" } + } + } + + RowLayout { + spacing: Kirigami.Units.smallSpacing + + PC3.Button { + id: minMaxButton + text: "Fixed minimum and maximum width" + onClicked: minMaxMenu.open(0, height) + + PlasmaExtras.Menu { + id: minMaxMenu + + minimumWidth: minMaxButton.width + maximumWidth: limitMenuMaxWidth.checked ? minMaxButton.width : undefined // has a RESET property + + PlasmaExtras.MenuItem { text: "Hello" } + PlasmaExtras.MenuItem { text: "This is just a simple" } + PlasmaExtras.MenuItem { text: "Menu" } + PlasmaExtras.MenuItem { text: "with some very very long text in one item that will " + + "make the menu super huge if you don't do anything about it" } + PlasmaExtras.MenuItem { text: "and other stuff" } + } + } + + PC3.CheckBox { + id: limitMenuMaxWidth + anchors.verticalCenter: parent.verticalCenter + text: "Limit maximum width" + checked: true + } + } + + PC3.Button { + text: "Don't crash on null MenuItem action" + onClicked: noActionCrashMenu.open(0, height) + + PlasmaExtras.Menu { + id: noActionCrashMenu + + PlasmaExtras.MenuItem { text: "This is an item" } + PlasmaExtras.MenuItem { text: "Below me should NOT be an empty item"} + PlasmaExtras.MenuItem { action: null } + PlasmaExtras.MenuItem { text: "I am not empty" } + } + } + } +} diff --git a/tests/components/progressbar3.qml b/tests/components/progressbar3.qml new file mode 100644 index 0000000..6421da0 --- /dev/null +++ b/tests/components/progressbar3.qml @@ -0,0 +1,199 @@ +/* + * SPDX-FileCopyrightText: 2019 David Edmundson + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +ComponentBase { + id: root + title: "Plasma Components 3 ProgressBar" + property int progressBarWidth: testProgressBar.width + + PlasmaComponents.ProgressBar { + id: testProgressBar + visible: false + } + + contentItem: GridLayout { + columns: 6 + columnSpacing: Kirigami.Units.gridUnit + rowSpacing: Kirigami.Units.gridUnit + + ColumnLayout { + PlasmaComponents.Label { + text: "0%" + } + PlasmaComponents.ProgressBar { + from: 0 + to: 100 + value: 0 + } + } + + ColumnLayout { + PlasmaComponents.Label { + text: "50%" + } + PlasmaComponents.ProgressBar { + from: 0 + to: 100 + value: 50 + } + } + + ColumnLayout { + PlasmaComponents.Label { + text: "100%" + } + PlasmaComponents.ProgressBar { + from: 0 + to: 100 + value: 100 + } + } + + ColumnLayout { + PlasmaComponents.Label { + id: progressBarAndSliderLabel + text: "The progress bar and slider grooves should have the same visual width." + wrapMode: Text.WordWrap + Layout.preferredWidth: progressBarWidth + } + GridLayout { + id: progressBarAndSliderGrid + columns: 1 + rows: 2 + PlasmaComponents.ProgressBar { + id: progressBar + from: 0 + to: 100 + value: 50 + } + PlasmaComponents.Slider { + Layout.preferredWidth: progressBar.width + Layout.preferredHeight: progressBar.height + from: 0 + to: 100 + value: 50 + } + } + } + + ColumnLayout { + PlasmaComponents.Label { + text: "Min: 0; Max: 200; Value: 1\nMake sure the bar does not leak outside." + wrapMode: Text.WordWrap + Layout.preferredWidth: progressBarWidth + } + PlasmaComponents.ProgressBar { + from: 0 + to: 200 + value: 1 + } + } + + ColumnLayout { + PlasmaComponents.Label { + text: "Min: 0; Max: 100; Value: 110\nThe progress bar should look like it is at 100%." + wrapMode: Text.WordWrap + Layout.preferredWidth: progressBarWidth + } + PlasmaComponents.ProgressBar { + from: 0 + to: 100 + value: 110 + } + } + + ColumnLayout { + PlasmaComponents.Label { + text: "Min: -100; Max: 100; Value: 0\nThe progress bar should look like it is at 50%." + wrapMode: Text.WordWrap + Layout.preferredWidth: progressBarWidth + } + PlasmaComponents.ProgressBar { + from: -100 + to: 100 + value: 0 + } + } + + ColumnLayout { + PlasmaComponents.Label { + text: "Min: 0; Max: 100; Value: -10\nThe progress bar should look like it is at 0%." + wrapMode: Text.WordWrap + Layout.preferredWidth: progressBarWidth + } + PlasmaComponents.ProgressBar { + from: 0 + to: 100 + value: -10 + } + } + + ColumnLayout { + PlasmaComponents.Label { + text: "This should have a continuous movement from one end to the other and back." + wrapMode: Text.WordWrap + Layout.preferredWidth: progressBarWidth + } + PlasmaComponents.ProgressBar { + indeterminate: indeterminateCheckBox.checked + value: 0.5 + } + } + + ColumnLayout { + PlasmaComponents.Label { + text: "Checking and unchecking should not break the layout. The progress bar should look like it is at 50% if unchecked." + wrapMode: Text.WordWrap + Layout.preferredWidth: progressBarWidth + } + PlasmaComponents.CheckBox { + id: indeterminateCheckBox + text: "Indeterminate" + checked: true + } + } + + ColumnLayout { + PlasmaComponents.Label { + text: "This should do one 'indefinite' animation cycle and then continuously animate to 100% in chunks of 10%." + wrapMode: Text.WordWrap + Layout.preferredWidth: progressBarWidth + } + PlasmaComponents.ProgressBar { + id: animatingProgressBar + from: 0 + to: 100 + // Bug 430544: A ProgressBar that was indeterminate once will + // not update its bar size according to its value anymore + // Set to false again in the Timer below + indeterminate: true + + Timer { + interval: 500 + triggeredOnStart: true + running: true + repeat: true + onTriggered: { + animatingProgressBar.indeterminate = false; + + // ProgressBar clamps "value" by "to" (100), so we can't + // just blindly increase and then check >= 100 + if (animatingProgressBar.value === 100) { + animatingProgressBar.value = 0; + } else { + animatingProgressBar.value += 10; + } + } + } + } + } + + } +} diff --git a/tests/components/radiobutton3.qml b/tests/components/radiobutton3.qml new file mode 100644 index 0000000..b2b0a93 --- /dev/null +++ b/tests/components/radiobutton3.qml @@ -0,0 +1,61 @@ +/* + * SPDX-FileCopyrightText: 2019 David Edmundson + * SPDX-FileCopyrightText: 2020 George Vogiatzis + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +ComponentBase { + id: root + title: "Plasma Components 3 RadioButton" + contentItem: GridLayout { + columnSpacing: Kirigami.Units.gridUnit + rowSpacing: Kirigami.Units.smallSpacing + columns: 2 + + PlasmaComponents.Label { + text: "text" + } + PlasmaComponents.RadioButton { + text: "Some awesome radiobutton" + } + + PlasmaComponents.Label { + text: "focus" + } + PlasmaComponents.RadioButton { + text: "Some awesome radiobutton" + focus: true + } + + PlasmaComponents.Label { + text: "checked" + } + PlasmaComponents.RadioButton { + text: "Some awesome radiobutton" + checked: true + } + + PlasmaComponents.Label { + text: "disabled" + } + PlasmaComponents.RadioButton { + text: "Some awesome radiobutton" + enabled: false + } + + PlasmaComponents.Label { + text: "disabled and checked" + } + PlasmaComponents.RadioButton { + text: "Some awesome radiobutton" + enabled: false + checked: true + } + } +} + diff --git a/tests/components/roundbutton3.qml b/tests/components/roundbutton3.qml new file mode 100644 index 0000000..5098999 --- /dev/null +++ b/tests/components/roundbutton3.qml @@ -0,0 +1,267 @@ +/* + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ + +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +ComponentBase { + id: root + title: "Plasma Components 3 RoundButton" + contentItem: ColumnLayout { + GridLayout { + rowSpacing: Kirigami.Units.smallSpacing + columnSpacing: Kirigami.Units.gridUnit + columns: 2 + + PlasmaComponents.Label { + text: "icon + text" + } + + PlasmaComponents.RoundButton { + icon.name: "start-here-kde-plasma" + text: "test" + } + + PlasmaComponents.Label { + text: "icon alone, should look small and square" + } + + PlasmaComponents.RoundButton { + icon.name: "start-here-kde-plasma" + } + + PlasmaComponents.Label { + text: "text alone, should be about as wide as the text itself" + } + + PlasmaComponents.RoundButton { + text: "test" + } + + PlasmaComponents.Label { + text: "This should look highlighted on load" + } + + PlasmaComponents.RoundButton { + text: "test" + focus: true + } + + PlasmaComponents.Label { + text: "long text, should expand to fit" + } + + PlasmaComponents.RoundButton { + icon.name: "start-here-kde-plasma" + text: "This is a really really really really long button" + } + + PlasmaComponents.Label { + text: "long text but constrained, should be 150px and elided" + } + + PlasmaComponents.RoundButton { + icon.name: "start-here-kde-plasma" + text: "This is a really really really really long button" + Layout.maximumWidth: 150 + } + + + PlasmaComponents.Label { + text: "button (with or without icon) and textfield should have the same height" + } + + RowLayout { + PlasmaComponents.RoundButton { + text: "test" + } + PlasmaComponents.RoundButton { + icon.name: "application-menu" + text: "test" + } + PlasmaComponents.TextField { + } + } + + PlasmaComponents.Label { + text: "minimum width property. Should be two letters wide" + } + + RowLayout { + PlasmaComponents.RoundButton { + text: "AA" + implicitWidth: Layout.minimumWidth + } + PlasmaComponents.RoundButton { + icon.name: "application-menu" + text: "AA" + implicitWidth: Layout.minimumWidth + } + PlasmaComponents.RoundButton { + icon.name: "application-menu" + implicitWidth: Layout.minimumWidth + } + } + + PlasmaComponents.Label { + text: "Display property" + } + RowLayout { + PlasmaComponents.RoundButton { + icon.name: "application-menu" + text: "Icon Only" + display: PlasmaComponents.RoundButton.IconOnly + } + PlasmaComponents.RoundButton { + icon.name: "application-menu" + text: "Text Beside Icon" + display: PlasmaComponents.RoundButton.TextBesideIcon + } + PlasmaComponents.RoundButton { + icon.name: "application-menu" + text: "Text Under Icon" + display: PlasmaComponents.RoundButton.TextUnderIcon + } + PlasmaComponents.RoundButton { + icon.name: "application-menu" + text: "Text Only" + display: PlasmaComponents.RoundButton.TextOnly + } + } + + } + Kirigami.Heading { + text: "Flat Buttons" + } + GridLayout { + rowSpacing: Kirigami.Units.smallSpacing + columnSpacing: Kirigami.Units.gridUnit + columns: 2 + + PlasmaComponents.Label { + text: "icon + text" + } + + PlasmaComponents.RoundButton { + icon.name: "start-here-kde-plasma" + text: "test" + flat: true + } + + PlasmaComponents.Label { + text: "icon alone, should look small and square" + } + + PlasmaComponents.RoundButton { + icon.name: "start-here-kde-plasma" + flat: true + } + + PlasmaComponents.Label { + text: "text alone, should be about as wide as the text itself" + } + + PlasmaComponents.RoundButton { + text: "test" + flat: true + } + + PlasmaComponents.Label { + text: "long text, should expand to fit" + } + + PlasmaComponents.RoundButton { + icon.name: "start-here-kde-plasma" + text: "This is a really really really really long button" + flat: true + } + + PlasmaComponents.Label { + text: "long text but constrained, should be 150px and elided" + } + + PlasmaComponents.RoundButton { + icon.name: "start-here-kde-plasma" + text: "This is a really really really really long button" + Layout.maximumWidth: 150 + flat: true + } + + + PlasmaComponents.Label { + text: "button (with or without icon) and textfield should have the same height" + } + + RowLayout { + PlasmaComponents.RoundButton { + text: "test" + flat: true + } + PlasmaComponents.RoundButton { + icon.name: "application-menu" + text: "test" + flat: true + } + PlasmaComponents.TextField { + } + } + + PlasmaComponents.Label { + text: "minimum width property. Should be two letters wide" + } + + RowLayout { + PlasmaComponents.RoundButton { + text: "AA" + implicitWidth: Layout.minimumWidth + flat: true + } + PlasmaComponents.RoundButton { + icon.name: "application-menu" + text: "AA" + implicitWidth: Layout.minimumWidth + flat: true + } + PlasmaComponents.RoundButton { + icon.name: "application-menu" + implicitWidth: Layout.minimumWidth + flat: true + } + } + + PlasmaComponents.Label { + text: "Display property" + } + RowLayout { + PlasmaComponents.RoundButton { + icon.name: "application-menu" + text: "Icon Only" + display: PlasmaComponents.RoundButton.IconOnly + flat: true + } + PlasmaComponents.RoundButton { + icon.name: "application-menu" + text: "Text Beside Icon" + display: PlasmaComponents.RoundButton.TextBesideIcon + flat: true + } + PlasmaComponents.RoundButton { + icon.name: "application-menu" + text: "Text Under Icon" + display: PlasmaComponents.RoundButton.TextUnderIcon + flat: true + } + PlasmaComponents.RoundButton { + icon.name: "application-menu" + text: "Text Only" + display: PlasmaComponents.RoundButton.TextOnly + flat: true + } + } + } + } +} diff --git a/tests/components/slider3.qml b/tests/components/slider3.qml new file mode 100644 index 0000000..4fc1c54 --- /dev/null +++ b/tests/components/slider3.qml @@ -0,0 +1,73 @@ +/* + * SPDX-FileCopyrightText: 2019 Aleix Pol + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami +// Run with qmlscene to use qqc2-desktop-style + +ComponentBase { + id: root + title: "Plasma Components 3 Slider" + contentItem: GridLayout { + columnSpacing: Kirigami.Units.gridUnit + rowSpacing: Kirigami.Units.gridUnit + columns: 2 + + PlasmaComponents.Label { + text: "Horizontal slider" + } + PlasmaComponents.Slider { + id: horizontalSlider + from: minSpinBox.value + to: maxSpinBox.value + stepSize: stepSizeSpinBox.value + } + + PlasmaComponents.Label { + text: "Vertical slider" + } + PlasmaComponents.Slider { + id: verticalSlider + from: minSpinBox.value + to: maxSpinBox.value + stepSize: stepSizeSpinBox.value + orientation: Qt.Vertical + } + + PlasmaComponents.Label { + text: "from: " + } + PlasmaComponents.SpinBox { + id: minSpinBox + value: 0 + from: -999 + to: 999 + editable: true + } + + PlasmaComponents.Label { + text: "to: " + } + PlasmaComponents.SpinBox { + id: maxSpinBox + value: 100 + from: -999 + to: 999 + editable: true + } + + PlasmaComponents.Label { + text: "stepSize: " + } + PlasmaComponents.SpinBox { + id: stepSizeSpinBox + value: 1 + to: 999 + editable: true + } + } +} diff --git a/tests/components/tabbar3.qml b/tests/components/tabbar3.qml new file mode 100644 index 0000000..f60608d --- /dev/null +++ b/tests/components/tabbar3.qml @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2020 Marco Martin + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components as PlasmaComponents + +ComponentBase { + id: root + title: "Plasma Components 3 TabBar with TabButtons" + contentItem: PlasmaComponents.TabBar { + implicitWidth: tabButton2.implicitWidth*4 + PlasmaComponents.TabButton { + icon.name: "application-menu" + text: "Icon Only" + display: PlasmaComponents.TabButton.IconOnly + } + PlasmaComponents.TabButton { + id: tabButton2 + icon.name: "application-menu" + text: "Text Beside Icon" + display: PlasmaComponents.TabButton.TextBesideIcon + } + PlasmaComponents.TabButton { + icon.name: "application-menu" + text: "Text Under Icon" + display: PlasmaComponents.TabButton.TextUnderIcon + } + PlasmaComponents.TabButton { + icon.name: "application-menu" + text: "Text Only" + display: PlasmaComponents.TabButton.TextOnly + } + } +} + diff --git a/tests/components/textarea3.qml b/tests/components/textarea3.qml new file mode 100644 index 0000000..2a42fd9 --- /dev/null +++ b/tests/components/textarea3.qml @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2019 David Edmundson + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +ComponentBase { + id: root + title: "Plasma Components 3 TextArea" + + property string longText: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed at volutpat nibh, non elementum nulla. Nunc sem magna, semper sit amet sollicitudin et, vestibulum sed metus. Fusce tempor dolor purus, non posuere urna sodales in. Aenean eu erat ipsum. Fusce egestas pulvinar nisi. Mauris vel enim tincidunt, elementum diam sed, tincidunt nulla. Maecenas tempus vitae ligula et convallis. Nullam justo velit, dignissim a nisl at, blandit posuere leo. Maecenas ac scelerisque odio, eget placerat ipsum. Ut iaculis, tortor et ullamcorper fringilla, mauris neque dapibus arcu, eget suscipit libero libero ut nunc. Sed maximus enim a ligula facilisis, non efficitur dolor blandit. Curabitur venenatis mattis erat ac gravida." + + contentItem: Flow { + spacing: Kirigami.Units.gridUnit + + PlasmaComponents.TextArea { + placeholderText: "CHEESE" + wrapMode: TextEdit.Wrap + width: 150 + height: 100 + } + + PlasmaComponents.TextArea { + text: root.longText + wrapMode: TextEdit.Wrap + width: 150 + height: 100 + } + + + PlasmaComponents.TextArea { + text: root.longText + wrapMode: TextEdit.Wrap + width: 150 + height: 100 + } + } +} diff --git a/tests/components/textfield3.qml b/tests/components/textfield3.qml new file mode 100644 index 0000000..be2b803 --- /dev/null +++ b/tests/components/textfield3.qml @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2019 David Edmundson + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +ComponentBase { + id: root + title: "Plasma Components 3 TextField" + property string longText: "This is a longer sentence" + + contentItem: Flow { + spacing: Kirigami.Units.gridUnit + + PlasmaComponents.TextField { + placeholderText: longText + } + + PlasmaComponents.TextField { + text: root.longText + } + + PlasmaComponents.TextField { + width: 400 + placeholderText: longText + } + + PlasmaComponents.TextField { + text: root.longText + echoMode: TextInput.Password + } + } +} diff --git a/tests/components/toolbutton3.qml b/tests/components/toolbutton3.qml new file mode 100644 index 0000000..58450f7 --- /dev/null +++ b/tests/components/toolbutton3.qml @@ -0,0 +1,127 @@ +/* + * SPDX-FileCopyrightText: 2019 David Edmundson + * SPDX-FileCopyrightText: 2020 Marco Martin + * SPDX-FileCopyrightText: 2020 Noah Davis + * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +import QtQuick +import QtQuick.Layouts +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +ComponentBase { + id: root + title: "Plasma Components 3 ToolButton" + + contentItem: ColumnLayout { + Flow { + Layout.fillWidth: true + Layout.fillHeight: true + spacing: Kirigami.Units.gridUnit + + PlasmaComponents.ToolButton { + icon.name: "start-here-kde-plasma" + text: "test" + flat: true + } + PlasmaComponents.ToolButton { + icon.name: "start-here-kde-plasma" + flat: true + } + PlasmaComponents.ToolButton { + text: "test" + flat: true + } + PlasmaComponents.ToolButton { + icon.name: "start-here-kde-plasma" + text: "test" + flat: false + } + PlasmaComponents.ToolButton { + icon.name: "start-here-kde-plasma" + flat: false + } + PlasmaComponents.ToolButton { + text: "test" + flat: false + } + PlasmaComponents.ToolButton { + icon.name: "application-menu" + text: "Icon Only" + display: PlasmaComponents.ToolButton.IconOnly + } + PlasmaComponents.ToolButton { + icon.name: "application-menu" + text: "Text Beside Icon" + display: PlasmaComponents.ToolButton.TextBesideIcon + } + PlasmaComponents.ToolButton { + icon.name: "application-menu" + text: "Text Under Icon" + display: PlasmaComponents.ToolButton.TextUnderIcon + } + PlasmaComponents.ToolButton { + icon.name: "application-menu" + text: "Text Only" + display: PlasmaComponents.ToolButton.TextOnly + } + } + RowLayout { + Layout.fillWidth: true + PlasmaComponents.Label { + Layout.fillWidth: true + text: "They should always be square:" + } + PlasmaComponents.ToolButton { + icon.name: "start-here-kde-plasma" + } + PlasmaComponents.ToolButton { + icon.name: "start-here-kde-plasma" + } + PlasmaComponents.ToolButton { + icon.name: "start-here-kde-plasma" + } + PlasmaComponents.ToolButton { + icon.name: "start-here-kde-plasma" + } + } + PlasmaComponents.Label { + text: "Fixed size and stretching size buttons" + } + GridLayout { + id: layout + rows: 2 + columns:2 + Layout.fillWidth: true + Layout.fillHeight: true + PlasmaComponents.ToolButton { + id: closeButton + icon.name: "window-close" + text: "Text" + } + PlasmaComponents.ToolButton { + id: closeButton2 + icon.name: "window-close" + Layout.fillWidth: true + Layout.fillHeight: true + icon.width: Kirigami.Units.iconSizes.small + icon.height: Kirigami.Units.iconSizes.small + text: "Text" + } + PlasmaComponents.ToolButton { + id: closeButton3 + icon.name: "window-close" + Layout.fillHeight: true + text: "Text" + } + PlasmaComponents.ToolButton { + id: closeButton4 + icon.name: "window-close" + Layout.fillWidth: true + Layout.fillHeight: true + text: "Text" + } + } + } +} + diff --git a/tests/dialog.qml b/tests/dialog.qml new file mode 100644 index 0000000..eda680e --- /dev/null +++ b/tests/dialog.qml @@ -0,0 +1,25 @@ +/* + SPDX-FileCopyrightText: 2014 David Edmundson + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import QtQuick.Layouts + +import org.kde.plasma.core as PlasmaCore + +PlasmaCore.Dialog { + visible: true + + mainItem: Item { + width: 200 + height: 200 + + MouseArea { + anchors.fill: parent + onClicked: Qt.quit() + } + } +} diff --git a/tests/dialog_fullscreen.qml b/tests/dialog_fullscreen.qml new file mode 100644 index 0000000..f329acb --- /dev/null +++ b/tests/dialog_fullscreen.qml @@ -0,0 +1,46 @@ +/* + SPDX-FileCopyrightText: 2014 Vishesh Handa + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import QtQuick.Controls as Controls +import QtQuick.Layouts + +import org.kde.plasma.core as PlasmaCore + + +PlasmaCore.Dialog { + id: dialog + location: PlasmaCore.Types.Floating + + ColumnLayout { + Controls.Label { + Layout.maximumWidth: rect.width + wrapMode: Text.WordWrap + text: "Clicking on the rectangle should toggle the full screen mode. Make sure it retains its original geometry when jumping in between full screen and normal" + } + + Rectangle { + id: rect + color: "green" + + width: 500 + height: 500 + + MouseArea { + anchors.fill: parent + onClicked: { + if (dialog.location != PlasmaCore.Types.FullScreen) { + dialog.location = PlasmaCore.Types.FullScreen; + } + else { + dialog.location = PlasmaCore.Types.Floating; + } + } + } + } + } +} diff --git a/tests/dialog_minWidthHeightRepositioning.qml b/tests/dialog_minWidthHeightRepositioning.qml new file mode 100644 index 0000000..9d0c3d4 --- /dev/null +++ b/tests/dialog_minWidthHeightRepositioning.qml @@ -0,0 +1,62 @@ +/* + SPDX-FileCopyrightText: 2014 Vishesh Handa + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import QtQuick.Controls as Controls +import QtQuick.Layouts + +import org.kde.plasma.core as PlasmaCore + +PlasmaCore.Dialog { + id: root + location: PlasmaCore.Types.Floating + + Rectangle { + id: rect + Layout.minimumWidth: 300 + Layout.minimumHeight: 300 + + color: "red" + + Rectangle { + width: rect.Layout.minimumWidth + height: rect.Layout.minimumHeight + } + ColumnLayout { + anchors.top: parent.top + Controls.Label { + Layout.maximumWidth: rect.Layout.minimumWidth + text: "Use Alt + Left Click to move the window to a side and then increase the minWidth/Height. The window should reposition itself" + wrapMode: Text.WordWrap + } + Controls.Button { + text: "Increase MinWidth" + onClicked: { + rect.Layout.minimumWidth = rect.Layout.minimumWidth + 10 + } + } + Controls.Button { + text: "Increase MinHeight" + onClicked: { + rect.Layout.minimumHeight = rect.Layout.minimumHeight + 10 + } + } + Controls.Button { + text: "Increase dialog width" + onClicked: { + root.width = root.width + 10 + } + } + Controls.Button { + text: "Increase dialog height" + onClicked: { + root.height = root.height + 10 + } + } + } + } +} diff --git a/tests/dialog_positioning.qml b/tests/dialog_positioning.qml new file mode 100644 index 0000000..712d997 --- /dev/null +++ b/tests/dialog_positioning.qml @@ -0,0 +1,104 @@ +/* + SPDX-FileCopyrightText: 2014 David Edmundson + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import QtQuick.Controls as Controls +import QtQuick.Layouts + +import org.kde.plasma.core as PlasmaCore + + +/*This test is for checking PlasmaDialog visualParent and related function work +*To test move the window towards various edges and press the button. +The Red rectangle should always be on screen and on the right screen + +*/ + +PlasmaCore.Dialog { + + type: windowIsDockControl.checked ? PlasmaCore.Dialog.Dock : PlasmaCore.Dialog.Normal + visible: true + + Rectangle { + color: "#ffffff" + width: 300 + height: 300 + + Rectangle { + id: innerRect + color: "#ddffdd" + width: 200 + height: layout.height + anchors.centerIn: parent + + ColumnLayout { + id: layout + anchors.margins: 5 + anchors.top: parent.top + anchors.left:parent.left + anchors.right:parent.right + + Controls.Label { + Layout.fillWidth: true + text: "alt + left click and move the window to various edges to test popup position" + wrapMode: Text.WordWrap + } + + Controls.ComboBox { + id: alignmentControl + //order must match Location in plasma.h + model: ["Left", "Right", "Top", "Bottom"] + currentIndex: 0 + } + + Controls.CheckBox { + id: windowIsDockControl + text: "Window is a dock" + } + + Controls.Button { + text: "Show Popup" + onClicked: { + dialog.visible = !dialog.visible + console.log(alignmentControl.currentIndex); + } + } + } + + PlasmaCore.Dialog + { + id: dialog + visualParent: innerRect + location: { + switch (alignmentControl.currentIndex) { + case 0: + return PlasmaCore.Types.LeftEdge + case 1: + return PlasmaCore.Types.RightEdge + case 2: + return PlasmaCore.Types.TopEdge + default: + return PlasmaCore.Types.BottomEdge + } + } + + + Rectangle { + color: "#FF0000" + width: 150 + height: 150 + } + + Component.onCompleted: { + console.log(alignmentControl.currentIndex); + console.log(dialog.location); + + } + } + } + } +} diff --git a/tests/dialog_positioning2.qml b/tests/dialog_positioning2.qml new file mode 100644 index 0000000..b908d23 --- /dev/null +++ b/tests/dialog_positioning2.qml @@ -0,0 +1,76 @@ +/* + SPDX-FileCopyrightText: 2014 Vishesh Handa + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import QtQuick.Controls as Controls +import QtQuick.Layouts + +import org.kde.plasma.core as PlasmaCore +import org.kde.plasma.components as PC3 +import org.kde.kirigami as Kirigami + +ColumnLayout +{ + Controls.Label { + text: "Press the button and make sure the popup is on the correct place" + wrapMode: Text.WordWrap + } + PC3.Button { + id: settingsButton + icon.name: "configure" + text: "Press Me" + Layout.alignment: Qt.AlignHCenter + + onClicked: { + contextMenu.visible = !contextMenu.visible; + } + } + + PlasmaCore.Dialog { + id: contextMenu + visualParent: settingsButton + + location: PlasmaCore.Types.BottomEdge + type: PlasmaCore.Dialog.PopupMenu + flags: Qt.Popup | Qt.FramelessWindowHint | Qt.WindowDoesNotAcceptFocus + + mainItem: ColumnLayout { + id: menuColumn + Layout.minimumWidth: menuColumn.implicitWidth + Layout.minimumHeight: menuColumn.implicitHeight + spacing: Kirigami.Units.smallSpacing + + Kirigami.Heading { + level: 3 + text: "Panel Alignment" + } + + Column { + spacing: 5 + Layout.fillWidth: true + PC3.ToolButton { + anchors { + left: parent.left + right: parent.right + } + text: "Left" + checkable: true + flat: false + } + PC3.ToolButton { + anchors { + left: parent.left + right: parent.right + } + text: "Center" + checkable: true + flat: false + } + } + } + } +} diff --git a/tests/dialog_positioning_parentrotated.qml b/tests/dialog_positioning_parentrotated.qml new file mode 100644 index 0000000..65925f4 --- /dev/null +++ b/tests/dialog_positioning_parentrotated.qml @@ -0,0 +1,80 @@ +/* + SPDX-FileCopyrightText: 2014 Vishesh Handa + SPDX-FileCopyrightText: 2015 Marco Martin + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import QtQuick.Controls as Controls +import QtQuick.Layouts + +import org.kde.plasma.core as PlasmaCore +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +ColumnLayout +{ + height: Kirigami.Units.gridUnit * 20 + Controls.Label { + id: label + text: "Press the button and make sure the popup is on the correct place" + wrapMode: Text.WordWrap + } + PlasmaComponents.Button { + id: settingsButton + iconSource: "configure" + text: "Press Me" + Layout.alignment: Qt.AlignHCenter + rotation: 90 + + onClicked: { + contextMenu.visible = !contextMenu.visible; + } + } + + PlasmaCore.Dialog { + id: contextMenu + visualParent: settingsButton + + location: PlasmaCore.Types.BottomEdge + type: PlasmaCore.Dialog.PopupMenu + flags: Qt.Popup | Qt.FramelessWindowHint | Qt.WindowDoesNotAcceptFocus + + mainItem: ColumnLayout { + id: menuColumn + Layout.minimumWidth: menuColumn.implicitWidth + Layout.minimumHeight: menuColumn.implicitHeight + spacing: Kirigami.Units.smallSpacing + + Kirigami.Heading { + level: 3 + text: "Panel Alignment" + } + + PlasmaComponents.ButtonColumn { + spacing: 0 + Layout.fillWidth: true + PlasmaComponents.ToolButton { + anchors { + left: parent.left + right: parent.right + } + text: "Left" + checkable: true + flat: false + } + PlasmaComponents.ToolButton { + anchors { + left: parent.left + right: parent.right + } + text: "Center" + checkable: true + flat: false + } + } + } + } +} diff --git a/tests/dialog_resizeWithParent.qml b/tests/dialog_resizeWithParent.qml new file mode 100644 index 0000000..a655dae --- /dev/null +++ b/tests/dialog_resizeWithParent.qml @@ -0,0 +1,63 @@ +/* + SPDX-FileCopyrightText: 2014 Vishesh Handa + SPDX-FileCopyrightText: 2014 Marco Martin + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import QtQuick.Controls as Controls +import QtQuick.Layouts + +import org.kde.plasma.core as PlasmaCore + +Item { + id: root + Layout.minimumWidth: 300 + Layout.minimumHeight: 300 + Controls.Button { + id: button + anchors.centerIn: parent + text: "Show Dialog" + onClicked: { + //changing the minimumHeight of the mainItem of an hidden dialog + //shouldn't + rect.Layout.minimumHeight = rect.Layout.minimumHeight + 1 + rect.Layout.minimumWidth = rect.Layout.minimumWidth + 1 + subDialog.visible = !subDialog.visible + } + } + PlasmaCore.Dialog { + id: subDialog + location: PlasmaCore.Types.Floating + visualParent: button + visible: false + + Rectangle { + id: rect + Layout.minimumWidth: 300 + Layout.minimumHeight: 300 + Layout.maximumHeight: 500 + property int fixedHeight: 500 + width: 500 + height: fixedHeight + + color: "red" + border { + color: "blue" + width: 3 + } + + Controls.Button { + text: "Resize" + anchors.centerIn: parent + onClicked: { + rect.fixedHeight = rect.Layout.minimumHeight = rect.Layout.maximumHeight = (rect.fixedHeight == 500 ? rect.fixedHeight = 100 : rect.fixedHeight = 500) + + //subDialog.height = (subDialog.height == 500 ? subDialog.height = 100 : subDialog.height = 500) + } + } + } + } +} diff --git a/tests/dialog_sizeMoreThanMin.qml b/tests/dialog_sizeMoreThanMin.qml new file mode 100644 index 0000000..5adedb0 --- /dev/null +++ b/tests/dialog_sizeMoreThanMin.qml @@ -0,0 +1,58 @@ +/* + SPDX-FileCopyrightText: 2014 Vishesh Handa + SPDX-FileCopyrightText: 2014 Marco Martin + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import QtQuick.Controls as Controls +import QtQuick.Layouts + +import org.kde.plasma.core as PlasmaCore + +Item { + id: root + Layout.minimumWidth: 300 + Layout.minimumHeight: 300 + Controls.Button { + id: button + anchors.centerIn: parent + text: "Show Dialog" + onClicked: { + //changing the minimumHeight of the mainItem of an hidden dialog + //shouldn't + rect.Layout.minimumHeight = rect.Layout.minimumHeight + 1 + rect.Layout.minimumWidth = rect.Layout.minimumWidth + 1 + subDialog.visible = !subDialog.visible + } + } + PlasmaCore.Dialog { + id: subDialog + location: PlasmaCore.Types.Floating + visualParent: button + visible: false + + Rectangle { + id: rect + width: 500 + height: 500 + Layout.minimumWidth: 300 + Layout.minimumHeight: 300 + + color: "red" + + Rectangle { + anchors.centerIn: parent + width: rect.Layout.minimumWidth + height: rect.Layout.minimumHeight + Text { + anchors.fill: parent + wrapMode: Text.WordWrap + text: "you should see a red border around this white area" + } + } + } + } +} diff --git a/tests/dialog_tooltip.qml b/tests/dialog_tooltip.qml new file mode 100644 index 0000000..3b144fa --- /dev/null +++ b/tests/dialog_tooltip.qml @@ -0,0 +1,67 @@ +/* + SPDX-FileCopyrightText: 2014 Vishesh Handa + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import QtQuick.Controls as Controls +import QtQuick.Layouts + +import org.kde.plasma.core as PlasmaCore + +ColumnLayout { + Controls.Label { + Layout.maximumWidth: mainLayout.width + wrapMode: Text.WordWrap + text: "Hover over every rectangle so that the tooltip pops up. It should popup in the correct position" + } + + RowLayout { + id: mainLayout + Rectangle { + width: 300 + height: 100 + color: "red" + + PlasmaCore.ToolTipArea { + width: 300 + height: 50 + + mainText: "Title Number 1" + subText: "subtext" + icon: "plasma" + } + } + + Rectangle { + width: 300 + height: 100 + color: "blue" + + PlasmaCore.ToolTipArea { + width: 500 + height: 110 + + mainText: "Title Number 2" + subText: "This is some really really really long subtext. So lets write stores about the woods and the trees and how we're going hiking. Yaye!" + icon: "configure" + } + } + + Rectangle { + width: 300 + height: 100 + color: "green" + + PlasmaCore.ToolTipArea { + width: 350 + height: 70 + + mainText: "Wakka Wakka" + subText: "It's time for Africa" + } + } + } +} diff --git a/tests/dialog_visualParentChange.qml b/tests/dialog_visualParentChange.qml new file mode 100644 index 0000000..d93a932 --- /dev/null +++ b/tests/dialog_visualParentChange.qml @@ -0,0 +1,107 @@ +/* + SPDX-FileCopyrightText: 2014 Vishesh Handa + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import QtQuick.Controls as Controls +import QtQuick.Layouts + +import org.kde.plasma.core as PlasmaCore + +ColumnLayout { + Controls.Label { + Layout.maximumWidth: mainLayout.width + wrapMode: Text.WordWrap + text: "Click on each coloured box to make a dialog popup. It should popup in the correct position. The popup should also move from one rectangle to the other on hovering" + } + + RowLayout { + id: mainLayout + Rectangle { + width: 300 + height: 100 + color: "red" + + MouseArea { + anchors.fill: parent + hoverEnabled: true + onClicked: { + dialog.visualParent = parent; + dialog.visible = !dialog.visible; + } + onEntered: { + dialog.visualParent = parent; + } + } + } + + Rectangle { + width: 300 + height: 100 + color: "blue" + + MouseArea { + anchors.fill: parent + hoverEnabled: true + onClicked: { + dialog.visualParent = parent; + dialog.visible = !dialog.visible; + } + onEntered: { + dialog.visualParent = parent; + } + } + } + + Rectangle { + width: 300 + height: 100 + color: "green" + + MouseArea { + anchors.fill: parent + hoverEnabled: true + onClicked: { + dialog.visualParent = parent; + dialog.visible = !dialog.visible; + } + onEntered: { + dialog.visualParent = parent; + } + } + } + + Rectangle { + width: 300 + height: 100 + color: "yellow" + + MouseArea { + anchors.fill: parent + hoverEnabled: true + onClicked: { + dialog.visualParent = parent; + dialog.visible = !dialog.visible; + } + onEntered: { + dialog.visualParent = parent; + } + } + } + + PlasmaCore.Dialog { + id: dialog + location: PlasmaCore.Types.BottomEdge + visible: false + + Rectangle { + color: "black" + width: 150 + height: 150 + } + } + } +} diff --git a/tests/dpi/CMakeLists.txt b/tests/dpi/CMakeLists.txt new file mode 100644 index 0000000..76f661c --- /dev/null +++ b/tests/dpi/CMakeLists.txt @@ -0,0 +1,7 @@ +add_executable(dpitest + main.cpp + dpitest.cpp +) + +target_link_libraries(dpitest Plasma::Plasma KF6::I18n Qt6::Gui) + diff --git a/tests/dpi/dpitest.cpp b/tests/dpi/dpitest.cpp new file mode 100644 index 0000000..d90cc7e --- /dev/null +++ b/tests/dpi/dpitest.cpp @@ -0,0 +1,50 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "dpitest.h" + +#include + +#include + +#include +#include +#include +#include +#include + +namespace Plasma +{ +class DPITestPrivate +{ +public: + QString pluginName; + QCommandLineParser *parser; +}; + +DPITest::DPITest(int &argc, char **argv, QCommandLineParser *parser) + : QGuiApplication(argc, argv) +{ + d = new DPITestPrivate; + d->parser = parser; + QTimer::singleShot(0, this, &DPITest::runMain); +} + +DPITest::~DPITest() +{ + delete d; +} + +void DPITest::runMain() +{ + qDebug() << "DPI test runs: "; + exit(0); + return; +} + +} + +#include "moc_dpitest.cpp" diff --git a/tests/dpi/dpitest.h b/tests/dpi/dpitest.h new file mode 100644 index 0000000..69ee8d3 --- /dev/null +++ b/tests/dpi/dpitest.h @@ -0,0 +1,36 @@ +/* + SPDX-FileCopyrightText: 2012 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef DPITEST_H +#define DPITEST_H + +#include +#include + +class QCommandLineParser; + +namespace Plasma +{ +class DPITestPrivate; + +class DPITest : public QGuiApplication +{ + Q_OBJECT + +public: + DPITest(int &argc, char **argv, QCommandLineParser *parser); + ~DPITest() override; + +public Q_SLOTS: + void runMain(); + +private: + DPITestPrivate *d; +}; + +} + +#endif diff --git a/tests/dpi/main.cpp b/tests/dpi/main.cpp new file mode 100644 index 0000000..c9b8325 --- /dev/null +++ b/tests/dpi/main.cpp @@ -0,0 +1,34 @@ +/* + SPDX-FileCopyrightText: 2008 Aaron Seigo + SPDX-FileCopyrightText: 2013 Sebastian Kügler + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include +#include +#include +#include + +#include + +#include "dpitest.h" + +int main(int argc, char **argv) +{ + QCommandLineParser *parser = new QCommandLineParser; + Plasma::DPITest app(argc, argv, parser); + + const QString description = i18n("DPI test app"); + const QString version = QStringLiteral("2.0"); + + app.setApplicationVersion(version); + parser->addVersionOption(); + parser->setApplicationDescription(description); + + parser->addOption(QCommandLineOption(QStringList() << QStringLiteral("s") << QStringLiteral("show"), + i18nc("Do not translate ", "Show icon sizes"), + QStringLiteral("name"))); + + return app.exec(); +} diff --git a/tests/extras/expandablelistitem.qml b/tests/extras/expandablelistitem.qml new file mode 100644 index 0000000..ba49f61 --- /dev/null +++ b/tests/extras/expandablelistitem.qml @@ -0,0 +1,66 @@ +import QtQuick +import QtQuick.Layouts + +import QtQml.Models +import org.kde.plasma.extras as PlasmaExtras +import org.kde.plasma.components as PlasmaComponents +import org.kde.kirigami as Kirigami + +Rectangle { + height: 800 + width: 500 + color: Kirigami.Theme.backgroundColor + PlasmaComponents.ScrollView { + anchors.fill: parent + ListView { + anchors.fill: parent + focus: true + currentIndex: -1 + clip: true + model: myModel + highlight: PlasmaExtras.Highlight {} + highlightMoveDuration: Kirigami.Units.longDuration + highlightResizeDuration: Kirigami.Units.longDuration + delegate: PlasmaExtras.ExpandableListItem { + title: model.title + subtitle: model.subtitle + icon: model.icon + isBusy: model.busy + subtitleCanWrap: model.subtitleCanWrap || false + + customExpandedViewContent: Component { + ColumnLayout { + PlasmaComponents.Label { + text: "I am some expanded text" + } + PlasmaComponents.Button { + text: "with an expanded button" + } + } + } + } + } + } + + ListModel { + id: myModel + ListElement { + title: "Item 1" + subtitle: "Default with icon" + icon: "system-file-manager" + isDefault: true + } + ListElement { + title: "Item 2" + subtitle: "A really long subtitle that probably won't fit in this constrained example because of how long it is." + isDefault: false + } + ListElement { + title: "Item 4" + subtitle: "Busy" + isDefault: false + busy: true + } + + } +} diff --git a/tests/frames.qml b/tests/frames.qml new file mode 100644 index 0000000..7639afb --- /dev/null +++ b/tests/frames.qml @@ -0,0 +1,40 @@ +/* + SPDX-FileCopyrightText: 2020 David Edmundson + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + + +import QtQuick +import QtQuick.Layouts + +import org.kde.ksvg as KSvg + +Item +{ + width: 500 + height: 500 + + + + Grid { + anchors.fill: parent + columns: 3 + + Repeater { + model: ["widgets/background", + "widgets/panel-background", + "opaque/widgets/panel-background", + "widgets/tooltip", + "opaque/widgets/tooltip" + ] + + delegate: KSvg.FrameSvgItem { + width: 100 + height: 100 + imagePath: modelData + } + } + } +} + diff --git a/tests/selected_svg.qml b/tests/selected_svg.qml new file mode 100644 index 0000000..b831098 --- /dev/null +++ b/tests/selected_svg.qml @@ -0,0 +1,42 @@ +/* + SPDX-FileCopyrightText: 2016 Marco Martin + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Controls as Controls +import org.kde.kirigami as Kirigami +import org.kde.ksvg as KSvg + +KSvg.FrameSvgItem { + id: root + imagePath: "widgets/background" + state: KSvg.Svg.Normal + width: 600 + height: 800 + + Column { + anchors.centerIn: parent + spacing: 4 + + Controls.Button { + text: "Switch Selected State" + onClicked: root.state = (root.state == KSvg.Svg.Selected ? KSvg.Svg.Normal : KSvg.Svg.Selected) + } + + KSvg.SvgItem { + svg: KSvg.Svg { + id: svg + imagePath: "icons/phone" + state: root.state + } + } + + Kirigami.Icon { + id: icon + source: "phone" + state: root.state + } + } +} diff --git a/tests/shadows.qml b/tests/shadows.qml new file mode 100644 index 0000000..1cacbba --- /dev/null +++ b/tests/shadows.qml @@ -0,0 +1,44 @@ +/* + SPDX-FileCopyrightText: 2021 Arjen Hiemstra + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts + +import org.kde.ksvg as KSvg + +Rectangle { + color: "white" + width: 600 + height: 600 + + GridLayout { + anchors.fill: parent + columns: 3 + + Repeater { + model: [ + "shadow-topleft", + "shadow-top", + "shadow-topright", + "shadow-left", + "shadow-middle", + "shadow-right", + "shadow-bottomleft", + "shadow-bottom", + "shadow-bottomright" + ] + + KSvg.SvgItem { + elementId: modelData + + svg: KSvg.Svg { + imagePath: "dialogs/background" + } + } + } + } +} + diff --git a/tests/testborders.qml b/tests/testborders.qml new file mode 100644 index 0000000..e76cf72 --- /dev/null +++ b/tests/testborders.qml @@ -0,0 +1,93 @@ +/* + SPDX-FileCopyrightText: 2014 Aleix Pol Gonzalez + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +import org.kde.ksvg as KSvg + +Item +{ + width: 500 + height: 500 + + KSvg.FrameSvgItem { + id: theItem + + imagePath: "widgets/background" + anchors { + fill: parent + margins: 10 + } + + Button { + text: "left" + checkable: true + checked: true + anchors { + horizontalCenterOffset: -50 + centerIn: parent + } + onClicked: { + if (checked) + theItem.enabledBorders |= KSvg.FrameSvg.LeftBorder; + else + theItem.enabledBorders &=~KSvg.FrameSvg.LeftBorder; + } + } + Button { + text: "right" + checkable: true + checked: true + + anchors { + horizontalCenterOffset: 50 + centerIn: parent + } + onClicked: { + if (checked) + theItem.enabledBorders |= KSvg.FrameSvg.RightBorder; + else + theItem.enabledBorders &=~KSvg.FrameSvg.RightBorder; + } + } + Button { + text: "top" + checkable: true + checked: true + + anchors { + verticalCenterOffset: -50 + centerIn: parent + } + onClicked: { + if (checked) + theItem.enabledBorders |= KSvg.FrameSvg.TopBorder; + else + theItem.enabledBorders &=~KSvg.FrameSvg.TopBorder; + } + } + Button { + text: "bottom" + checkable: true + checked: true + + anchors { + verticalCenterOffset: 50 + centerIn: parent + } + onClicked: { + if (checked) + theItem.enabledBorders |= KSvg.FrameSvg.BottomBorder; + else + theItem.enabledBorders &=~KSvg.FrameSvg.BottomBorder; + } + } + } +} + diff --git a/tests/tooltip-icons.qml b/tests/tooltip-icons.qml new file mode 100644 index 0000000..e38c30a --- /dev/null +++ b/tests/tooltip-icons.qml @@ -0,0 +1,33 @@ +/* + SPDX-FileCopyrightText: 2014 Bhushan Shah + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick +import org.kde.plasma.core as PlasmaCore +import org.kde.kirigami as Kirigami + +Row { + height: 200 + width: 400 + Kirigami.Icon { + source: "plasma" + PlasmaCore.ToolTipArea { + anchors.fill: parent + mainText: "Tooltip Title" + subText: "Some explanation." + icon: "plasma" + } + } + + Kirigami.Icon { + source: "ark" + PlasmaCore.ToolTipArea { + anchors.fill: parent + mainText: "Tooltip title" + subText: "No icon!" + } + } +} + diff --git a/tests/tooltip.qml b/tests/tooltip.qml new file mode 100644 index 0000000..aab251f --- /dev/null +++ b/tests/tooltip.qml @@ -0,0 +1,154 @@ +/* + SPDX-FileCopyrightText: 2014 David Edmundson + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +import QtQuick + +import org.kde.plasma.core as PlasmaCore + +Rectangle { + color: "white" + width: 600 + height: 800 + + Column { + anchors.centerIn: parent + spacing: 4 + + PlasmaCore.ToolTipArea { + width: 300 + height: 50 + + mainText: "This is some really really really really long text that should be truncated" + subText: "subtext" + + Rectangle { + color: "red" + anchors.fill: parent + } + + Text { + anchors.fill: parent + text: "long tooltip" + } + + } + + PlasmaCore.ToolTipArea { + width: 300 + height: 50 + + mainText: "A" + subText: "B" + + Rectangle { + color: "red" + anchors.fill: parent + } + + Text { + anchors.fill: parent + text: "short tooltip" + } + } + + PlasmaCore.ToolTipArea { + width: 300 + height: 50 + + mainText: "A" + subText: "Lorem ipsum dolor sit amet, consectetur adipiscing spaghetti italiano random cheesecake blah blah" + + Rectangle { + color: "red" + anchors.fill: parent + } + + Text { + anchors.fill: parent + text: "long subtext" + } + } + + PlasmaCore.ToolTipArea { + width: 300 + height: 50 + + active: false + + mainText: "A" + subText: "B" + + Rectangle { + color: "red" + anchors.fill: parent + } + + Text { + anchors.fill: parent + text: "tooltip exists but inactive" + } + } + + PlasmaCore.ToolTipArea { + width: 300 + height: 50 + + icon: "document-edit" + mainText: "A title" + subText: "A subtext" + + Rectangle { + color: "red" + anchors.fill: parent + } + + Text { + anchors.fill: parent + text: "with icon" + } + } + + PlasmaCore.ToolTipArea { + width: 300 + height: 50 + + image: "/usr/share/icons/oxygen/128x128/devices/multimedia-player.png" + mainText: "A title" + subText: "A subtext" + + Rectangle { + color: "red" + anchors.fill: parent + } + + Text { + anchors.fill: parent + text: "with image" + } + } + + PlasmaCore.ToolTipArea { + width: 300 + height: 50 + + icon: "kde" + mainText: "Notifications" + subText: "Display notifications and jobs" + + Rectangle { + color: "red" + anchors.fill: parent + } + + Text { + anchors.fill: parent + text: "Notification applet tooltip" + } + } + + } +} + diff --git a/tests/window.qml b/tests/window.qml new file mode 100644 index 0000000..4658cb2 --- /dev/null +++ b/tests/window.qml @@ -0,0 +1,110 @@ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import org.kde.plasma.core as PlasmaCore + +import org.kde.graphicaleffects + +import QtGraphicalEffects + +ApplicationWindow { + + width: 1000 + height: 500 + RowLayout { + id: topRow + Label { + text: "Win ID (find via xwininfo)" + } + TextField { + id: winIdInput + text: "" + placeholderText: "0x000000" + } + + GridLayout { + columns: 3 + Label { + text: "Resolution" + } + Slider { + id: resolutionSlider + from: 0 + to: 1 + value: 0.5 + } + Label { + text: resolutionSlider.value + } + Label { + text: "Window Sin C" + } + Slider { + id: windowSincSlider + from: 0 + to: 1 + value: 0.5 + } + Label { + text: windowSincSlider.value + } + Label { + text: "Sin C" + } + Slider { + id: sincSlider + from: 0 + to: 1 + value: 0.5 + } + Label { + text: sincSlider.value + } + } + } + + + + GridLayout { + anchors.left: parent.left + anchors.right: parent.right + anchors.top: topRow.bottom + height: 200 + + columns: 2 + Label { + text: "Window" + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + } + + Label { + text: "Lanczos" + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + } + + PlasmaCore.WindowThumbnail { + id: thumb + + Layout.fillWidth: true + Layout.fillHeight: true + + winId: parseInt(winIdInput.text, 16) + visible: true + } + + + Lanczos { + source: thumb + Layout.fillWidth: true + Layout.fillHeight: true + sourceSize: Qt.size(thumb.paintedWidth, thumb.paintedHeight) + resolution: resolutionSlider.value + windowSinc: windowSincSlider.value + sinc: sincSlider.value + } + } +} -- 2.30.2