├── .editorconfig ├── .github ├── dependabot.yml └── workflows │ ├── ci.yml │ └── flatpak-x-checker.yml ├── .gitignore ├── .valalintignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── RELEASE_HOWTO.md ├── build-aux ├── appcenter │ └── com.github.ryonakano.pinit.Devel.yml └── flathub │ └── com.github.ryonakano.pinit.Devel.yml ├── com.github.ryonakano.pinit.yml ├── data ├── icons │ ├── 16 │ │ ├── com.github.ryonakano.pinit.png │ │ └── com.github.ryonakano.pinit.svg │ ├── 32 │ │ ├── com.github.ryonakano.pinit.png │ │ └── com.github.ryonakano.pinit.svg │ ├── 48 │ │ ├── com.github.ryonakano.pinit.png │ │ └── com.github.ryonakano.pinit.svg │ ├── 64 │ │ ├── com.github.ryonakano.pinit.png │ │ └── com.github.ryonakano.pinit.svg │ └── 128 │ │ ├── com.github.ryonakano.pinit.png │ │ └── com.github.ryonakano.pinit.svg ├── meson.build ├── pinit.desktop.in.in ├── pinit.gresource.xml.in ├── pinit.gschema.xml.in ├── pinit.metainfo.xml.in.in ├── screenshots │ ├── gnome │ │ ├── screenshot-dark.png │ │ └── screenshot-light.png │ └── pantheon │ │ ├── screenshot-dark.png │ │ ├── screenshot-edit-view.png │ │ ├── screenshot-files-view.png │ │ ├── screenshot-light.png │ │ └── screenshot-welcome-view.png └── ui │ └── help-overlay.blp ├── meson.build ├── meson_options.txt ├── po ├── LINGUAS ├── POTFILES ├── ca.po ├── com.github.ryonakano.pinit.pot ├── cs.po ├── de.po ├── es.po ├── et.po ├── fi.po ├── fr.po ├── hi.po ├── it.po ├── ja.po ├── lt.po ├── meson.build ├── nb_NO.po ├── nl.po ├── pl.po ├── pt_BR.po ├── ru.po ├── sk.po ├── ta.po ├── tr.po ├── uk.po └── zh_Hans.po ├── src ├── Application.vala ├── Config.vala.in ├── Define.vala ├── MainWindow.vala ├── Model │ ├── DesktopFile.vala │ └── DesktopFileModel.vala ├── Util.vala ├── Util │ ├── DesktopFileUtil.vala │ └── KeyFileUtil.vala ├── View │ ├── EditView.vala │ └── FilesView.vala ├── Widget │ ├── CategoriesRow.vala │ └── KeywordsRow.vala └── meson.build └── subprojects └── blueprint-compiler.wrap /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig 2 | root = true 3 | 4 | # default rule 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_size = tab 9 | indent_style = space 10 | insert_final_newline = true 11 | max_line_length = 120 12 | tab_width = 4 13 | 14 | # Markup files 15 | [{*.html,*.xml,*.xml.in*,*.yml}] 16 | tab_width = 2 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | flatpak: 7 | name: Flatpak (${{ matrix.arch }}, ${{ matrix.repository-name }}) 8 | runs-on: ${{ matrix.runs-on }} 9 | 10 | strategy: 11 | matrix: 12 | include: 13 | - arch: x86_64 14 | runs-on: ubuntu-latest 15 | container-image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-48 16 | repository-name: flathub 17 | repository-url: https://flathub.org/repo/flathub.flatpakrepo 18 | - arch: aarch64 19 | runs-on: ubuntu-24.04-arm 20 | container-image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-48 21 | repository-name: flathub 22 | repository-url: https://flathub.org/repo/flathub.flatpakrepo 23 | - arch: x86_64 24 | runs-on: ubuntu-latest 25 | container-image: ghcr.io/elementary/flatpak-platform/runtime:8.1-x86_64 26 | repository-name: appcenter 27 | repository-url: https://flatpak.elementary.io/repo.flatpakrepo 28 | - arch: aarch64 29 | runs-on: ubuntu-24.04-arm 30 | container-image: ghcr.io/elementary/flatpak-platform/runtime:8.1-aarch64 31 | repository-name: appcenter 32 | repository-url: https://flatpak.elementary.io/repo.flatpakrepo 33 | # Don't fail the whole workflow if one architecture fails 34 | fail-fast: false 35 | 36 | container: 37 | image: ${{ matrix.container-image }} 38 | options: --privileged 39 | 40 | steps: 41 | - name: Checkout 42 | uses: actions/checkout@v4 43 | 44 | - name: Build 45 | uses: flatpak/flatpak-github-actions/flatpak-builder@v6 46 | with: 47 | bundle: pinit-${{ matrix.repository-name }}.flatpak 48 | manifest-path: build-aux/${{ matrix.repository-name }}/com.github.ryonakano.pinit.Devel.yml 49 | run-tests: true 50 | repository-name: ${{ matrix.repository-name }} 51 | repository-url: ${{ matrix.repository-url }} 52 | cache-key: "flatpak-builder-${sha256(manifestPath)}-${{ github.sha }}" 53 | arch: ${{ matrix.arch }} 54 | 55 | lint: 56 | name: Lint 57 | runs-on: ubuntu-latest 58 | 59 | container: 60 | image: valalang/lint 61 | 62 | steps: 63 | - name: Checkout 64 | uses: actions/checkout@v4 65 | 66 | - name: Lint 67 | run: io.elementary.vala-lint -d . 68 | -------------------------------------------------------------------------------- /.github/workflows/flatpak-x-checker.yml: -------------------------------------------------------------------------------- 1 | name: Flatpak Manifest 2 | on: 3 | schedule: 4 | - cron: '0 0 * * 1' # run weekly 5 | workflow_dispatch: # can be manually dispatched under GitHub's "Actions" tab 6 | 7 | jobs: 8 | flatpak-external-data-checker: 9 | name: Check for updates 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v4 15 | 16 | - name: Update Flathub development manifest 17 | uses: docker://ghcr.io/flathub/flatpak-external-data-checker:latest 18 | env: 19 | GIT_AUTHOR_NAME: github-actions[bot] 20 | GIT_COMMITTER_NAME: github-actions[bot] 21 | # email sets "github-actions[bot]" as commit author, see https://github.com/orgs/community/discussions/26560 22 | GIT_AUTHOR_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com 23 | GIT_COMMITTER_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com 24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 25 | with: 26 | # use --edit-only instead of --update to create single PR that updates all manifests 27 | args: --edit-only --never-fork build-aux/flathub/com.github.ryonakano.pinit.Devel.yml 28 | 29 | - name: Update AppCenter development manifest 30 | uses: docker://ghcr.io/flathub/flatpak-external-data-checker:latest 31 | env: 32 | GIT_AUTHOR_NAME: github-actions[bot] 33 | GIT_COMMITTER_NAME: github-actions[bot] 34 | # email sets "github-actions[bot]" as commit author, see https://github.com/orgs/community/discussions/26560 35 | GIT_AUTHOR_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com 36 | GIT_COMMITTER_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com 37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | with: 39 | # use --edit-only instead of --update to create single PR that updates all manifests 40 | args: --edit-only --never-fork build-aux/appcenter/com.github.ryonakano.pinit.Devel.yml 41 | 42 | - name: Update AppCenter stable manifest 43 | uses: docker://ghcr.io/flathub/flatpak-external-data-checker:latest 44 | env: 45 | GIT_AUTHOR_NAME: github-actions[bot] 46 | GIT_COMMITTER_NAME: github-actions[bot] 47 | # email sets "github-actions[bot]" as commit author, see https://github.com/orgs/community/discussions/26560 48 | GIT_AUTHOR_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com 49 | GIT_COMMITTER_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com 50 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 51 | with: 52 | args: --update --never-fork com.github.ryonakano.pinit.yml 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # build dirs 2 | .flatpak-builder 3 | builddir* 4 | 5 | # vim 6 | *.swp 7 | *~ 8 | *.un~ 9 | 10 | # subprojects 11 | subprojects/blueprint-compiler 12 | -------------------------------------------------------------------------------- /.valalintignore: -------------------------------------------------------------------------------- 1 | # build dirs 2 | .flatpak-builder 3 | builddir* 4 | 5 | # translations and metainfo 6 | po 7 | data 8 | 9 | # subprojects 10 | subprojects 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guideline 2 | Thank you for getting interested in contributing to the project! We really appreciate it. 😊 3 | 4 | ## Submit Bug Reports or Feature Requests 5 | 1. [Search for existing issues](https://github.com/ryonakano/pinit/issues) to check if it's a known issue. 6 | 2. [Create a new issue](https://github.com/ryonakano/pinit/issues/new) if it's not reported yet. 7 | 8 | > [!TIP] 9 | > If you are not used to do, [this section](https://docs.elementary.io/contributor-guide/feedback/reporting-issues#creating-a-new-issue-report) is for you. 10 | 11 | ## Translate the Project 12 | We accept translations through [Weblate](https://hosted.weblate.org/projects/rosp/pinit/). 13 | 14 | Alternatively, you can fork this repository, edit the `*.po` files directly, and submit changes through pull requests. 15 | 16 | ## Propose Code Changes 17 | We accept changes to the source code through pull requests. Even a small typo fix is welcome. 18 | 19 | We follow [the coding style by elementary](https://docs.elementary.io/develop/writing-apps/code-style). Try to respect them. 20 | 21 | > [!TIP] 22 | > Again, [the guideline by elementary](https://docs.elementary.io/contributor-guide/development/prepare-code-for-review) would be helpful here too. 23 | 24 | ### Documentation 25 | We use documentation comments for clarifying interfaces (so-called "Black Box"). 26 | 27 | You can refer to them locally to help your coding and you should edit them if you change the internal behavior 28 | or the interface of methods. 29 | 30 | #### Generate Documentation From Source Code 31 | Building the source code with the option `doc` to `true` will generate HTML documentation. 32 | 33 | You'll need the following extra dependencies to generate documentation: 34 | 35 | * valadoc 36 | 37 | Assuming that you've already built the project as written in the [README](README.md#from-source-code-native): 38 | 39 | ```bash 40 | meson configure builddir -Ddoc=true 41 | meson compile -C builddir 42 | xdg-open builddir/valadoc/index.html 43 | ``` 44 | 45 | #### Edit Documentation Comments 46 | You should edit documentation comments if you: 47 | 48 | - change the internal behavior of existing methods. 49 | - change the interface (parameters, the return value, etc.) of existing methods. 50 | - add new methods, classes, structs, etc. 51 | 52 | You should clarify the behavior, parameters, and the return value in case of methods. Here is an example: 53 | 54 | ```vala 55 | /** 56 | * Returns true if this and other contains the same values. 57 | * 58 | * @param other Another DesktopFile. 59 | * @return true if this and other contains the same values. 60 | */ 61 | public bool equals (DesktopFile other) { 62 | ``` 63 | 64 | Refer to [Valadoc](https://valadoc.org/markup.htm) for available markups. 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pin It! 2 | ![App window in the light mode](data/screenshots/gnome/screenshot-light.png#gh-light-mode-only) 3 | 4 | ![App window in the dark mode](data/screenshots/gnome/screenshot-dark.png#gh-dark-mode-only) 5 | 6 | Pin shortcuts for portable apps like raw executable files, AppImage files, etc. to the app launcher on your desktop. 7 | 8 | Other features include: 9 | 10 | - Edit or delete created app entries without opening the file manager 11 | - Automatically add execution permission to the file you select 12 | 13 | ## Installation 14 | ### From Flathub or AppCenter (Recommended) 15 | You can install Pin It! from Flathub: 16 | 17 | [Download on Flathub](https://flathub.org/apps/com.github.ryonakano.pinit) 18 | 19 | You should install Pin It! from AppCenter if you're on elementary OS. This build is optimized for elementary OS: 20 | 21 | [![Get it on AppCenter](https://appcenter.elementary.io/badge.svg)](https://appcenter.elementary.io/com.github.ryonakano.pinit) 22 | 23 | ### From Source Code (Flatpak) 24 | You'll need `flatpak` and `flatpak-builder` commands installed on your system. 25 | 26 | Run `flatpak remote-add` to add Flathub remote for dependencies: 27 | 28 | ``` 29 | flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo 30 | ``` 31 | 32 | To build and install, use `flatpak-builder`, then execute with `flatpak run`: 33 | 34 | ``` 35 | flatpak-builder builddir --user --install --force-clean --install-deps-from=flathub build-aux/flathub/com.github.ryonakano.pinit.Devel.yml 36 | flatpak run com.github.ryonakano.pinit.Devel 37 | ``` 38 | 39 | ### From Source Code (Native) 40 | You'll need the following dependencies to build: 41 | 42 | * blueprint-compiler 43 | * libadwaita-1-dev (>= 1.5.0) 44 | * libgee-0.8-dev 45 | * libglib2.0-dev (>= 2.74) 46 | * libgranite-7-dev (>= 7.2.0, required only when you build with `granite` feature enabled) 47 | * libgtk-4-dev (>= 4.10) 48 | * meson (>= 0.58.0) 49 | * valac 50 | 51 | Run `meson setup` to configure the build environment and run `meson compile` to build: 52 | 53 | ```bash 54 | meson setup builddir --prefix=/usr 55 | meson compile -C builddir 56 | ``` 57 | 58 | To install, use `meson install`, then execute with `com.github.ryonakano.pinit`: 59 | 60 | ```bash 61 | meson install -C builddir 62 | com.github.ryonakano.pinit 63 | ``` 64 | 65 | ## Contributing 66 | Please refer to [the contribution guideline](CONTRIBUTING.md) if you would like to: 67 | 68 | - submit bug reports / feature requests 69 | - propose coding changes 70 | - translate the project 71 | 72 | ## Get Support 73 | Need help in use of the app? Refer to [the discussions page](https://github.com/ryonakano/pinit/discussions) to search for existing discussions or [start a new discussion](https://github.com/ryonakano/pinit/discussions/new/choose) if none is relevant. 74 | 75 | ## History 76 | The original idea of the app is inspired from [Desktopius by Alex K](https://github.com/alexkdeveloper/dfc). 77 | -------------------------------------------------------------------------------- /RELEASE_HOWTO.md: -------------------------------------------------------------------------------- 1 | # Release Flow 2 | ## Work in Project Repository 3 | - Repository URL: https://github.com/ryonakano/pinit 4 | - Decide the version number of the release 5 | - Versioning should follow [Semantic Versioning](https://semver.org/) 6 | - Create a new branch named `release-X.Y.Z` from latest `origin/main` (`X.Y.Z` is the version number) 7 | - See changes since the previous release 8 | ``` 9 | $ git diff $(git describe --tags --abbrev=0)..release-X.Y.Z 10 | ``` 11 | - Update screenshots if there are visual changes between releases 12 | - Create a pull request with the following changes and merge it once the build succeeds 13 | - Write a release note in `data/pinit.metainfo.xml.in.in` 14 | - Refer to [the Metainfo guidelines by Flathub](https://docs.flathub.org/docs/for-app-authors/metainfo-guidelines) 15 | - Credits contributors with their GitHub username 16 | - Bump `version` in `meson.build` 17 | ```meson 18 | project( 19 | 'com.github.ryonakano.pinit', 20 | 'vala', 'c', 21 | version: '2.1.1', 22 | meson_version: '>=0.58.0' 23 | ) 24 | ``` 25 | - [Create a new release on GitHub](https://github.com/ryonakano/pinit/releases/new) 26 | - Create a new tag named `X.Y.Z` 27 | - Release title: ` X.Y.Z Released` 28 | - Publish it when completed 29 | 30 | ## Work in AppCenter Review Repository 31 | - Repository URL: https://github.com/elementary/appcenter-reviews 32 | - Fork the repository if you don't have write access to it 33 | - Create a new branch named `com.github.ryonakano.pinit-X.Y.Z` from latest `origin/main` 34 | - Create a pull request with the following changes and await for review approval and merge 35 | - Change `commit` and `version` in the `applications/com.github.ryonakano.pinit.json` 36 | - `commit` should be the release commit just we published on the project repository 37 | - `version` for the relase version 38 | - The new release should be available on AppCenter after some time 39 | 40 | ## Work in Flathub Repository 41 | - Repository URL: https://github.com/flathub/com.github.ryonakano.pinit 42 | - Create a new branch named `release-X.Y.Z` from latest `origin/master` 43 | - Create a pull request with the following changes and merge it once the build succeeds 44 | - Sync the content of the manifest file with the upstream except for the project module 45 | - Change `tag` and `commit` of the project module in the manifest file 46 | - These two parameters should point to the tag/revision that we published on the project repository 47 | - The new release should be available on Flathub after some time 48 | -------------------------------------------------------------------------------- /build-aux/appcenter/com.github.ryonakano.pinit.Devel.yml: -------------------------------------------------------------------------------- 1 | id: com.github.ryonakano.pinit.Devel 2 | runtime: io.elementary.Platform 3 | runtime-version: '8.1' 4 | sdk: io.elementary.Sdk 5 | command: com.github.ryonakano.pinit.Devel 6 | finish-args: 7 | - --share=ipc 8 | - --socket=wayland 9 | - --socket=fallback-x11 10 | - --filesystem=home 11 | # For drawing icons 12 | - --device=dri 13 | modules: 14 | - name: blueprint-compiler 15 | buildsystem: meson 16 | cleanup: 17 | - '*' 18 | sources: 19 | - type: git 20 | url: https://gitlab.gnome.org/jwestman/blueprint-compiler.git 21 | tag: v0.16.0 22 | commit: 04ef0944db56ab01307a29aaa7303df6067cb3c0 23 | x-checker-data: 24 | type: git 25 | tag-pattern: ^v([\d.]+)$ 26 | 27 | - name: pinit 28 | buildsystem: meson 29 | config-opts: 30 | - -Ddevelopment=true 31 | - -Dgranite=enabled 32 | sources: 33 | - type: dir 34 | path: ../../ 35 | -------------------------------------------------------------------------------- /build-aux/flathub/com.github.ryonakano.pinit.Devel.yml: -------------------------------------------------------------------------------- 1 | id: com.github.ryonakano.pinit.Devel 2 | runtime: org.gnome.Platform 3 | runtime-version: '48' 4 | sdk: org.gnome.Sdk 5 | command: com.github.ryonakano.pinit.Devel 6 | finish-args: 7 | - --share=ipc 8 | - --socket=wayland 9 | - --socket=fallback-x11 10 | - --filesystem=home 11 | # For drawing icons 12 | - --device=dri 13 | modules: 14 | - name: blueprint-compiler 15 | buildsystem: meson 16 | cleanup: 17 | - '*' 18 | sources: 19 | - type: git 20 | url: https://gitlab.gnome.org/jwestman/blueprint-compiler.git 21 | tag: v0.16.0 22 | commit: 04ef0944db56ab01307a29aaa7303df6067cb3c0 23 | x-checker-data: 24 | type: git 25 | tag-pattern: ^v([\d.]+)$ 26 | 27 | - name: pinit 28 | buildsystem: meson 29 | config-opts: 30 | - -Ddevelopment=true 31 | sources: 32 | - type: dir 33 | path: ../../ 34 | -------------------------------------------------------------------------------- /com.github.ryonakano.pinit.yml: -------------------------------------------------------------------------------- 1 | id: com.github.ryonakano.pinit 2 | runtime: io.elementary.Platform 3 | runtime-version: '8.1' 4 | sdk: io.elementary.Sdk 5 | command: com.github.ryonakano.pinit 6 | finish-args: 7 | - --share=ipc 8 | - --socket=wayland 9 | - --socket=fallback-x11 10 | - --filesystem=home 11 | # For drawing icons 12 | - --device=dri 13 | modules: 14 | - name: blueprint-compiler 15 | buildsystem: meson 16 | cleanup: 17 | - '*' 18 | sources: 19 | - type: git 20 | url: https://gitlab.gnome.org/jwestman/blueprint-compiler.git 21 | tag: v0.16.0 22 | commit: 04ef0944db56ab01307a29aaa7303df6067cb3c0 23 | x-checker-data: 24 | type: git 25 | tag-pattern: ^v([\d.]+)$ 26 | 27 | - name: pinit 28 | buildsystem: meson 29 | config-opts: 30 | - -Dgranite=enabled 31 | sources: 32 | - type: dir 33 | path: . 34 | -------------------------------------------------------------------------------- /data/icons/128/com.github.ryonakano.pinit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryonakano/pinit/0ca667f8c0829c9816a1b72a177a782eb3f396a4/data/icons/128/com.github.ryonakano.pinit.png -------------------------------------------------------------------------------- /data/icons/16/com.github.ryonakano.pinit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryonakano/pinit/0ca667f8c0829c9816a1b72a177a782eb3f396a4/data/icons/16/com.github.ryonakano.pinit.png -------------------------------------------------------------------------------- /data/icons/32/com.github.ryonakano.pinit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryonakano/pinit/0ca667f8c0829c9816a1b72a177a782eb3f396a4/data/icons/32/com.github.ryonakano.pinit.png -------------------------------------------------------------------------------- /data/icons/48/com.github.ryonakano.pinit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryonakano/pinit/0ca667f8c0829c9816a1b72a177a782eb3f396a4/data/icons/48/com.github.ryonakano.pinit.png -------------------------------------------------------------------------------- /data/icons/64/com.github.ryonakano.pinit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryonakano/pinit/0ca667f8c0829c9816a1b72a177a782eb3f396a4/data/icons/64/com.github.ryonakano.pinit.png -------------------------------------------------------------------------------- /data/meson.build: -------------------------------------------------------------------------------- 1 | icon_sizes = ['16', '32', '48', '64', '128'] 2 | 3 | foreach i : icon_sizes 4 | install_data( 5 | 'icons' / i / meson.project_name() + '.png', 6 | rename: app_id + '.png', 7 | install_dir: get_option('datadir') / 'icons' / 'hicolor' / i + 'x' + i / 'apps' 8 | ) 9 | endforeach 10 | 11 | desktop_conf = configuration_data() 12 | desktop_conf.set('APP_NAME', app_name) 13 | desktop_conf.set('APP_ID', app_id) 14 | desktop_file_in = configure_file( 15 | input: 'pinit.desktop.in.in', 16 | output: '@0@.desktop.in'.format(app_id), 17 | configuration: desktop_conf 18 | ) 19 | 20 | desktop_file = i18n.merge_file( 21 | input: desktop_file_in, 22 | output: '@0@.desktop'.format(app_id), 23 | po_dir: meson.project_source_root() / 'po', 24 | type: 'desktop', 25 | install: true, 26 | install_dir: get_option('datadir') / 'applications' 27 | ) 28 | 29 | appstream_conf = configuration_data() 30 | appstream_conf.set('APP_ID', app_id) 31 | appstream_conf.set('GETTEXT_PACKAGE', meson.project_name()) 32 | # Use screenshots taken on Pantheon, which is a publishing requirement for AppCenter, if build with granite. 33 | appstream_conf.set('DE', get_option('granite').enabled() ? 'pantheon' : 'gnome') 34 | appstream_conf.set('VERSION', meson.project_version()) 35 | appstream_file_in = configure_file( 36 | input: 'pinit.metainfo.xml.in.in', 37 | output: '@0@.metainfo.xml.in'.format(app_id), 38 | configuration: appstream_conf 39 | ) 40 | 41 | appstream_file = i18n.merge_file( 42 | input: appstream_file_in, 43 | output: '@0@.metainfo.xml'.format(app_id), 44 | po_dir: meson.project_source_root() / 'po', 45 | install: true, 46 | install_dir: get_option('datadir') / 'metainfo' 47 | ) 48 | 49 | gschema_conf = configuration_data() 50 | gschema_conf.set('APP_ID', app_id) 51 | gschema_file = configure_file( 52 | input: 'pinit.gschema.xml.in', 53 | output: '@0@.gschema.xml'.format(app_id), 54 | configuration: gschema_conf 55 | ) 56 | 57 | install_data( 58 | gschema_file, 59 | install_dir: get_option('datadir') / 'glib-2.0' / 'schemas' 60 | ) 61 | 62 | blueprints = custom_target('blueprints', 63 | input: files( 64 | 'ui/help-overlay.blp', 65 | ), 66 | output: '.', 67 | command: [ 68 | find_program('blueprint-compiler'), 69 | 'batch-compile', 70 | '@OUTPUT@', 71 | '@CURRENT_SOURCE_DIR@', 72 | '@INPUT@' 73 | ] 74 | ) 75 | 76 | gresource_conf = configuration_data() 77 | gresource_conf.set('APP_ID', app_id) 78 | gresource_file_in = configure_file( 79 | input: 'pinit.gresource.xml.in', 80 | output: '@0@.gresource.xml'.format(app_id), 81 | configuration: gresource_conf 82 | ) 83 | 84 | asresources = gnome.compile_resources( 85 | 'as-resources', 86 | gresource_file_in, 87 | dependencies: [ 88 | appstream_file, 89 | blueprints, 90 | ], 91 | source_dir: 'data', 92 | c_name: 'as' 93 | ) 94 | 95 | # Test definitions 96 | desktop_utils = find_program('desktop-file-validate', required: false) 97 | if desktop_utils.found() 98 | test('Validate desktop file', desktop_utils, args: [desktop_file]) 99 | endif 100 | 101 | appstreamcli = find_program('appstreamcli', required: false, disabler: true) 102 | test('Validate appstream file', appstreamcli, 103 | args: ['validate', '--no-net', '--explain', appstream_file]) 104 | 105 | compile_schemas = find_program('glib-compile-schemas', required: false, disabler: true) 106 | test('Validate schema file', 107 | compile_schemas, 108 | args: ['--strict', '--dry-run', meson.current_source_dir()]) 109 | -------------------------------------------------------------------------------- /data/pinit.desktop.in.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=@APP_NAME@ 3 | GenericName=Desktop File Creator 4 | Comment=Pin portable apps to the launcher 5 | Categories=System;Utility; 6 | Exec=@APP_ID@ 7 | Icon=@APP_ID@ 8 | Terminal=false 9 | Type=Application 10 | Keywords=Desktop;File;Create;Edit;Info;Icon;AppImage; 11 | -------------------------------------------------------------------------------- /data/pinit.gresource.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ui/help-overlay.ui 5 | 6 | @APP_ID@.metainfo.xml 7 | 8 | 9 | -------------------------------------------------------------------------------- /data/pinit.gschema.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 'default' 12 | Color scheme 13 | Whether to show the window in a dark style or not 14 | 15 | 16 | 600 17 | Most recent window width 18 | The saved width of the window last open 19 | 20 | 21 | 500 22 | Most recent window height 23 | The saved height of the window last open 24 | 25 | 26 | false 27 | Window maximized 28 | The saved value for whether the window is maximized or not 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /data/pinit.metainfo.xml.in.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @APP_ID@ 5 | @APP_ID@.desktop 6 | @GETTEXT_PACKAGE@ 7 | CC0-1.0 8 | GPL-3.0-or-later 9 | 10 | Pin It! 11 | Pin portable apps to the launcher 12 | 13 |

14 | Pin shortcuts for portable apps like raw executable files, AppImage files, etc. to the app launcher on your desktop. 15 |

16 |

17 | Other features include: 18 |

19 |
    20 |
  • Edit or delete created app entries without opening the file manager
  • 21 |
  • Automatically add the execute permission to the file you select
  • 22 |
23 |
24 | 25 | 26 | 27 | App window in the light mode 28 | https://raw.githubusercontent.com/ryonakano/pinit/@VERSION@/data/screenshots/@DE@/screenshot-light.png 29 | 30 | 31 | 32 | App window in the dark mode 33 | https://raw.githubusercontent.com/ryonakano/pinit/@VERSION@/data/screenshots/@DE@/screenshot-dark.png 34 | 35 | 36 | 37 | 38 | #28bca3 39 | #89ffdd 40 | #007367 41 | 42 | 43 | 44 | 45 | 46 | pointing 47 | keyboard 48 | 49 | 50 | 51 | Ryo Nakano 52 | 53 | Ryo Nakano 54 | 55 | 56 | https://github.com/ryonakano/pinit 57 | https://github.com/ryonakano/pinit/issues 58 | https://github.com/ryonakano/pinit/discussions 59 | https://github.com/ryonakano/pinit 60 | https://hosted.weblate.org/projects/rosp 61 | 62 | 63 | 64 | 65 |
    66 |
  • Support development build
  • 67 |
  • Support AppCenter build (again)
  • 68 |
  • Update translations
  • 69 |
70 |
71 |
72 | 73 | 74 | 75 |

76 | Bug fixes: 77 |

78 |
    79 |
  • Fix fd leak when opening .desktop files externally
  • 80 |
  • Fix the order of categories changes randomly
  • 81 |
82 |

83 | Improvements: 84 |

85 |
    86 |
  • Redesign the app for better responsible support
  • 87 |
  • Automatically decides .desktop filename instead of the user
  • 88 |
  • Do not navigate to files view after saving in case the user wants to continue editing
  • 89 |
  • Support setting GenericName and Keywords
  • 90 |
  • Load .desktop files asynchronously
  • 91 |
  • Flatpak: Update GNOME runtime to 46
  • 92 |
  • Code refactoring and organize project structure
  • 93 |
  • Update translations
  • 94 |
95 |
96 |
97 | 98 | 99 | 100 |

101 | This release fixes some critical issues and plus add some improvements. 102 |

103 |

104 | Bug fixes: 105 |

106 |
    107 |
  • Regain access to HOME to fix several issues that pinned apps disappear after reboot/upgrade of OS
  • 108 |
  • Avoid listing errored entries in FilesView
  • 109 |
  • Avoid errors when optional keys not found
  • 110 |
  • Save desktop files without locales
  • 111 |
112 |

113 | Improvements: 114 |

115 |
    116 |
  • Mark release descriptions as untranslatable (thanks to @sabriunal)
  • 117 |
  • Add keyboard shortcuts window
  • 118 |
  • Update translations
  • 119 |
120 |
121 |
122 | 123 | 124 | 125 |

126 | The release for celebrating the 2nd anniversary of the app! 127 |

128 |
    129 |
  • Fix deprecations in GTK 4.10
  • 130 |
  • English grammatical changes (thanks to @BraidenPsiuk)
  • 131 |
  • EditView: Make keys that is not required by the freedesktop.org specification optional
  • 132 |
  • CategoryChooser: Improve layout management
  • 133 |
  • Fix navigate back shows empty window
  • 134 |
  • Update Flatpak runtime version
  • 135 |
  • Update translations
  • 136 |
137 |
138 |
139 | 140 | 141 | 142 |
    143 |
  • Update Flatpak runtime version
  • 144 |
  • Update translations
  • 145 |
146 |
147 |
148 | 149 | 150 | 151 |

152 | The biggest and greatest updates come to "Pin It!": 153 |

154 |
    155 |
  • Redesign to fit modern desktop environments, including support for responsive design
  • 156 |
  • Migrate to GTK 4, the latest version of GTK
  • 157 |
158 |

159 | Other changes: 160 |

161 |
    162 |
  • Support setting ".ico" files as the app icon
  • 163 |
  • Support opening in a text editor
  • 164 |
  • Fix window size cannot be resized on small displays
  • 165 |
  • Show error dialogs when saving/deleting failed
  • 166 |
  • Make sure not to add blank elements in generated desktop files
  • 167 |
  • Don't overwrite the entire permission of the selected executable files
  • 168 |
  • Give executable permission for the user only when they don't have it
  • 169 |
  • Update translations
  • 170 |
171 |
172 |
173 | 174 | 175 | 176 |
    177 |
  • AppData: Fix release year
  • 178 |
179 |

Translation updates:

180 |
    181 |
  • Update Italian translation (thanks to @albanobattistella)
  • 182 |
183 |
184 |
185 | 186 | 187 | 188 |
    189 |
  • Check desktop environment on runtime
  • 190 |
  • Lessen scope of file access
  • 191 |
  • Make window resizable
  • 192 |
  • EditView: Less strict on file names
  • 193 |
194 |

Translation updates:

195 |
    196 |
  • Add Italian translation (thanks to @albanobattistella)
  • 197 |
  • Add Dutch translation (thanks to @Vistaus)
  • 198 |
  • Update Japanese translation
  • 199 |
200 |
201 |
202 | 203 | 204 | 205 |
    206 |
  • Fix build error on other distros
  • 207 |
  • FilesView: Properly center the dialog against the app window
  • 208 |
  • Restore last opened view and its state
  • 209 |
  • Add new style switcher
  • 210 |
  • Correct titlebar label when no app name specified
  • 211 |
  • Readable copies
  • 212 |
213 |

Translation updates:

214 |
    215 |
  • Update Japanese translation
  • 216 |
217 |
218 |
219 | 220 | 221 | 222 |
    223 |
  • FilesView: Ellipsize if label texts are too long
  • 224 |
  • Tell accepted file formats in FileChooser
  • 225 |
226 |

Translation updates:

227 |
    228 |
  • Add Brazilian Porguguese translation (thanks to @DanielTolentino)
  • 229 |
  • Update Japanese translation
  • 230 |
231 |
232 |
233 | 234 | 235 | 236 |
    237 |
  • EditView: Focus on file name entry by default
  • 238 |
  • FilesView: Make scrollable and fix the window get bigger if many entries
  • 239 |
240 |

Translation updates:

241 |
    242 |
  • Add French translation (thanks to @NathanBnm)
  • 243 |
  • Update Japanese translation
  • 244 |
245 |
246 |
247 | 248 | 249 | 250 |
    251 |
  • Improved support for other desktop environments
  • 252 |
  • Add execution permission on clicking the "Pin It!" button
  • 253 |
254 |

Translation updates:

255 |
    256 |
  • Update Japanese translation
  • 257 |
258 |
259 |
260 | 261 | 262 | 263 |
    264 |
  • Add CategoryChooser
  • 265 |
  • Support Alt+Home to show welcome
  • 266 |
  • Allow GPU acceralation by default
  • 267 |
268 |

Translation updates:

269 |
    270 |
  • Update Japanese translation
  • 271 |
272 |
273 |
274 | 275 | 276 | 277 |
    278 |
  • Add 128px app icon (thanks to @hanaral)
  • 279 |
  • Rounded window corners on any stylesheet (thanks to @JeysonFlores)
  • 280 |
  • Support multitouch gestures (thanks to @JeysonFlores)
  • 281 |
  • Fix unreadable description text in AppCenter
  • 282 |
  • Save and restore window position
  • 283 |
284 |

Translation updates:

285 |
    286 |
  • Add Spanish translation (thanks to @JeysonFlores)
  • 287 |
  • Update Japanese translation
  • 288 |
289 |
290 |
291 | 292 | 293 | 294 |
    295 |
  • Initial release
  • 296 |
297 |
298 |
299 |
300 | 301 |
302 | -------------------------------------------------------------------------------- /data/screenshots/gnome/screenshot-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryonakano/pinit/0ca667f8c0829c9816a1b72a177a782eb3f396a4/data/screenshots/gnome/screenshot-dark.png -------------------------------------------------------------------------------- /data/screenshots/gnome/screenshot-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryonakano/pinit/0ca667f8c0829c9816a1b72a177a782eb3f396a4/data/screenshots/gnome/screenshot-light.png -------------------------------------------------------------------------------- /data/screenshots/pantheon/screenshot-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryonakano/pinit/0ca667f8c0829c9816a1b72a177a782eb3f396a4/data/screenshots/pantheon/screenshot-dark.png -------------------------------------------------------------------------------- /data/screenshots/pantheon/screenshot-edit-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryonakano/pinit/0ca667f8c0829c9816a1b72a177a782eb3f396a4/data/screenshots/pantheon/screenshot-edit-view.png -------------------------------------------------------------------------------- /data/screenshots/pantheon/screenshot-files-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryonakano/pinit/0ca667f8c0829c9816a1b72a177a782eb3f396a4/data/screenshots/pantheon/screenshot-files-view.png -------------------------------------------------------------------------------- /data/screenshots/pantheon/screenshot-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryonakano/pinit/0ca667f8c0829c9816a1b72a177a782eb3f396a4/data/screenshots/pantheon/screenshot-light.png -------------------------------------------------------------------------------- /data/screenshots/pantheon/screenshot-welcome-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryonakano/pinit/0ca667f8c0829c9816a1b72a177a782eb3f396a4/data/screenshots/pantheon/screenshot-welcome-view.png -------------------------------------------------------------------------------- /data/ui/help-overlay.blp: -------------------------------------------------------------------------------- 1 | using Gtk 4.0; 2 | 3 | ShortcutsWindow help_overlay { 4 | modal: true; 5 | 6 | ShortcutsSection { 7 | section-name: "shortcuts"; 8 | 9 | ShortcutsGroup { 10 | title: C_("shortcut window", "General"); 11 | 12 | ShortcutsShortcut { 13 | action-name: "win.show-help-overlay"; 14 | title: C_("shortcut window", "Keyboard Shortcuts"); 15 | } 16 | 17 | ShortcutsShortcut { 18 | action-name: "app.quit"; 19 | title: C_("shortcut window", "Quit"); 20 | } 21 | } 22 | 23 | ShortcutsGroup { 24 | title: C_("shortcut window", "Edit"); 25 | 26 | ShortcutsShortcut { 27 | action-name: "win.new"; 28 | title: C_("shortcut window", "New Entry"); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project( 2 | 'com.github.ryonakano.pinit', 3 | 'vala', 'c', 4 | version: '2.1.1', 5 | meson_version: '>=0.58.0' 6 | ) 7 | 8 | app_name = 'Pin It!' 9 | app_id = meson.project_name() 10 | app_version = meson.project_version() 11 | if get_option('development') 12 | app_name += ' (Development)' 13 | app_id += '.Devel' 14 | 15 | ret = run_command('git', 'rev-parse', '--short', 'HEAD', check: false) 16 | if ret.returncode() != 0 17 | version_suffix = '-devel' 18 | else 19 | version_suffix = '-@0@'.format(ret.stdout().strip()) 20 | endif 21 | 22 | app_version += version_suffix 23 | endif 24 | 25 | gnome = import('gnome') 26 | i18n = import('i18n') 27 | 28 | add_project_arguments( 29 | '-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()), 30 | language: 'c' 31 | ) 32 | 33 | subdir('data') 34 | subdir('po') 35 | subdir('src') 36 | 37 | gnome.post_install( 38 | glib_compile_schemas: true, 39 | gtk_update_icon_cache: true 40 | ) 41 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('doc', type: 'boolean', value: false, description: 'Whether to generate valadoc') 2 | option('granite', type: 'feature', value: 'disabled', description: 'Enable elementary OS integration. Requires Granite') 3 | option('development', type: 'boolean', value: false, description: 'If this is a development build') 4 | -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | ca 2 | cs 3 | de 4 | es 5 | fi 6 | fr 7 | it 8 | ja 9 | lt 10 | nb_NO 11 | nl 12 | pl 13 | pt_BR 14 | ru 15 | sk 16 | tr 17 | uk 18 | zh_Hans 19 | hi 20 | et 21 | ta 22 | -------------------------------------------------------------------------------- /po/POTFILES: -------------------------------------------------------------------------------- 1 | data/pinit.desktop.in.in 2 | data/pinit.metainfo.xml.in.in 3 | data/ui/help-overlay.blp 4 | src/Application.vala 5 | src/MainWindow.vala 6 | src/View/EditView.vala 7 | src/View/FilesView.vala 8 | src/Widget/CategoriesRow.vala 9 | src/Widget/KeywordsRow.vala 10 | -------------------------------------------------------------------------------- /po/ca.po: -------------------------------------------------------------------------------- 1 | # Catalan translation for com.github.ryonakano.pinit. 2 | # Copyright (C) 2021-2025 Ryo Nakano 3 | # This file is distributed under the same license as the com.github.ryonakano.pinit package. 4 | # Maite Guix , 2022. 5 | # Fill read-only add-on , 2024. 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: com.github.ryonakano.pinit\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2025-03-16 19:27+0900\n" 11 | "PO-Revision-Date: 2024-05-04 15:05+0000\n" 12 | "Last-Translator: Fill read-only add-on \n" 13 | "Language-Team: Catalan \n" 14 | "Language: ca\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Plural-Forms: nplurals=2; plural=n != 1;\n" 19 | "X-Generator: Weblate 5.5.3\n" 20 | 21 | #: data/pinit.desktop.in.in:3 22 | msgid "@APP_NAME@" 23 | msgstr "@APP_NAME@" 24 | 25 | #: data/pinit.desktop.in.in:4 26 | msgid "Desktop File Creator" 27 | msgstr "" 28 | 29 | #: data/pinit.desktop.in.in:5 data/pinit.metainfo.xml.in.in:11 30 | msgid "Pin portable apps to the launcher" 31 | msgstr "" 32 | 33 | #: data/pinit.desktop.in.in:11 34 | msgid "Desktop;File;Create;Edit;Info;Icon;AppImage;" 35 | msgstr "" 36 | 37 | #: data/pinit.metainfo.xml.in.in:13 38 | msgid "" 39 | "Pin shortcuts for portable apps like raw executable files, AppImage files, " 40 | "etc. to the app launcher on your desktop." 41 | msgstr "" 42 | 43 | #: data/pinit.metainfo.xml.in.in:16 44 | msgid "Other features include:" 45 | msgstr "" 46 | 47 | #: data/pinit.metainfo.xml.in.in:20 48 | msgid "Edit or delete created app entries without opening the file manager" 49 | msgstr "" 50 | 51 | #: data/pinit.metainfo.xml.in.in:21 52 | msgid "Automatically add the execute permission to the file you select" 53 | msgstr "" 54 | 55 | #: data/pinit.metainfo.xml.in.in:27 56 | msgid "App window in the light mode" 57 | msgstr "" 58 | 59 | #: data/pinit.metainfo.xml.in.in:32 60 | msgid "App window in the dark mode" 61 | msgstr "" 62 | 63 | #: data/ui/help-overlay.blp:10 64 | msgctxt "shortcut window" 65 | msgid "General" 66 | msgstr "" 67 | 68 | #: data/ui/help-overlay.blp:14 69 | msgctxt "shortcut window" 70 | msgid "Keyboard Shortcuts" 71 | msgstr "" 72 | 73 | #: data/ui/help-overlay.blp:19 74 | msgctxt "shortcut window" 75 | msgid "Quit" 76 | msgstr "" 77 | 78 | #: data/ui/help-overlay.blp:24 79 | msgctxt "shortcut window" 80 | msgid "Edit" 81 | msgstr "" 82 | 83 | #: data/ui/help-overlay.blp:28 84 | msgctxt "shortcut window" 85 | msgid "New Entry" 86 | msgstr "" 87 | 88 | #. TRANSLATORS: A newline-separated list of translators. Don't translate literally. 89 | #. You can optionally add your name if you want, plus you may add your email address or website. 90 | #. e.g.: 91 | #. John Doe 92 | #. John Doe 93 | #. John Doe https://example.com 94 | #: src/Application.vala:310 95 | msgid "translator-credits" 96 | msgstr "" 97 | 98 | #: src/MainWindow.vala:78 99 | #, c-format 100 | msgid "Failed to Delete Entry of “%s”" 101 | msgstr "" 102 | 103 | #: src/MainWindow.vala:79 104 | msgid "There was an error while removing the app entry." 105 | msgstr "" 106 | 107 | #: src/MainWindow.vala:82 src/MainWindow.vala:132 src/View/EditView.vala:400 108 | #: src/View/EditView.vala:481 109 | msgid "_Close" 110 | msgstr "" 111 | 112 | #: src/MainWindow.vala:93 113 | msgid "Entry deleted." 114 | msgstr "" 115 | 116 | #: src/MainWindow.vala:106 117 | msgid "Entry updated." 118 | msgstr "" 119 | 120 | #: src/MainWindow.vala:129 121 | msgid "Failed to Load Entries" 122 | msgstr "" 123 | 124 | #: src/MainWindow.vala:130 125 | msgid "There was an error while loading app entries." 126 | msgstr "" 127 | 128 | #: src/MainWindow.vala:158 129 | msgid "Save Changes?" 130 | msgstr "" 131 | 132 | #: src/MainWindow.vala:159 133 | msgid "" 134 | "Open entries contain unsaved changes. Changes which are not saved will be " 135 | "permanently lost." 136 | msgstr "" 137 | 138 | #: src/MainWindow.vala:163 src/View/FilesView.vala:164 139 | msgid "_Cancel" 140 | msgstr "" 141 | 142 | #: src/MainWindow.vala:164 143 | msgid "_Discard" 144 | msgstr "" 145 | 146 | #: src/MainWindow.vala:165 src/View/EditView.vala:40 147 | #, fuzzy 148 | msgid "_Save" 149 | msgstr "Desar" 150 | 151 | #: src/View/EditView.vala:69 152 | msgid "Required Fields" 153 | msgstr "" 154 | 155 | #: src/View/EditView.vala:70 156 | msgid "The following fields need to be filled to save." 157 | msgstr "" 158 | 159 | #: src/View/EditView.vala:74 160 | msgid "App Name" 161 | msgstr "Nom de l'aplicació" 162 | 163 | #: src/View/EditView.vala:75 164 | #, fuzzy 165 | #| msgid "Shown in the launcher or Dock." 166 | msgid "Shown in the launcher or dock." 167 | msgstr "Es mostra al llançador o al Dock." 168 | 169 | #: src/View/EditView.vala:80 170 | msgid "Exec File" 171 | msgstr "Fitxer executable" 172 | 173 | #: src/View/EditView.vala:81 174 | msgid "" 175 | "The command/app launched when you click the app entry in the launcher. " 176 | "Specify in an absolute path or an app's alias name." 177 | msgstr "" 178 | "L'ordre/aplicació es llança quan feu clic a l'entrada de l'aplicació al " 179 | "llançador. Especifiqueu-ho en un camí absolut o amb el nom de l'àlies d'una " 180 | "aplicació." 181 | 182 | #: src/View/EditView.vala:84 183 | msgid "Select an executable file…" 184 | msgstr "" 185 | 186 | #: src/View/EditView.vala:95 187 | msgid "Optional Fields" 188 | msgstr "" 189 | 190 | #: src/View/EditView.vala:96 191 | msgid "Filling these fields improves discoverability in the app launcher." 192 | msgstr "" 193 | 194 | #: src/View/EditView.vala:100 195 | msgid "Icon File" 196 | msgstr "" 197 | 198 | #: src/View/EditView.vala:101 199 | #, fuzzy 200 | #| msgid "" 201 | #| "The command/app launched when you click the app entry in the launcher. " 202 | #| "Specify in an absolute path or an app's alias name." 203 | msgid "" 204 | "The icon branding the app. Specify in an absolute path or an icon's alias " 205 | "name." 206 | msgstr "" 207 | "L'ordre/aplicació es llança quan feu clic a l'entrada de l'aplicació al " 208 | "llançador. Especifiqueu-ho en un camí absolut o amb el nom de l'àlies d'una " 209 | "aplicació." 210 | 211 | #: src/View/EditView.vala:104 212 | msgid "Select an icon file…" 213 | msgstr "" 214 | 215 | #: src/View/EditView.vala:112 216 | msgid "Generic Name" 217 | msgstr "" 218 | 219 | #: src/View/EditView.vala:113 220 | msgid "" 221 | "Generic name of the app, for example \"Web Browser\" or \"Mail Client\"." 222 | msgstr "" 223 | 224 | #: src/View/EditView.vala:118 225 | msgid "Comment" 226 | msgstr "Comentari" 227 | 228 | #: src/View/EditView.vala:119 229 | msgid "" 230 | "Descibes the app. May appear as a tooltip when you hover over the app entry " 231 | "in the launcher/dock." 232 | msgstr "" 233 | 234 | #: src/View/EditView.vala:133 235 | msgid "Advanced Configurations" 236 | msgstr "" 237 | 238 | #: src/View/EditView.vala:134 239 | msgid "" 240 | "You can create most app entries just by filling in the sections above. " 241 | "However, some apps may require the advanced configuration options below." 242 | msgstr "" 243 | 244 | #: src/View/EditView.vala:138 245 | msgid "Startup WM Class" 246 | msgstr "" 247 | 248 | #: src/View/EditView.vala:139 249 | msgid "" 250 | "Associate the app with a window that has this ID. Use this if a different or " 251 | "duplicated icon appears in the dock when the app launches." 252 | msgstr "" 253 | 254 | #: src/View/EditView.vala:144 255 | msgid "Run in Terminal" 256 | msgstr "" 257 | 258 | #: src/View/EditView.vala:145 259 | msgid "Turn on if you want to register a CUI app." 260 | msgstr "" 261 | 262 | #: src/View/EditView.vala:150 263 | msgid "Hide in Applications Menu" 264 | msgstr "" 265 | 266 | #: src/View/EditView.vala:151 267 | msgid "" 268 | "Useful when you won't launch the app by itself, but want to associate it " 269 | "with filetypes to open files with the app from file managers." 270 | msgstr "" 271 | 272 | #: src/View/EditView.vala:155 273 | msgid "_Open" 274 | msgstr "" 275 | 276 | #: src/View/EditView.vala:159 277 | msgid "Open with Text Editor" 278 | msgstr "" 279 | 280 | #: src/View/EditView.vala:160 281 | msgid "You can also edit more options by opening with a text editor." 282 | msgstr "" 283 | 284 | #: src/View/EditView.vala:205 285 | msgid "New Entry" 286 | msgstr "" 287 | 288 | #: src/View/EditView.vala:221 src/View/EditView.vala:429 289 | msgid "Untitled App" 290 | msgstr "" 291 | 292 | #: src/View/EditView.vala:241 293 | msgid "Select Executable File" 294 | msgstr "" 295 | 296 | #: src/View/EditView.vala:242 src/View/EditView.vala:299 297 | msgid "_Select" 298 | msgstr "" 299 | 300 | #: src/View/EditView.vala:295 301 | msgid "ICO, PNG, SVG, or XMP files" 302 | msgstr "" 303 | 304 | #: src/View/EditView.vala:298 305 | msgid "Select Icon File" 306 | msgstr "" 307 | 308 | #: src/View/EditView.vala:397 309 | msgid "Failed to Open with External App" 310 | msgstr "" 311 | 312 | #: src/View/EditView.vala:398 313 | msgid "There was an error while opening the file with an external app." 314 | msgstr "" 315 | 316 | #: src/View/EditView.vala:453 317 | msgid "Edit Entry" 318 | msgstr "" 319 | 320 | #: src/View/EditView.vala:455 321 | #, c-format 322 | msgid "Edit “%s”" 323 | msgstr "" 324 | 325 | #: src/View/EditView.vala:471 326 | msgid "Failed to Save Entry" 327 | msgstr "" 328 | 329 | #: src/View/EditView.vala:474 330 | #, c-format 331 | msgid "Failed to Save Entry of “%s”" 332 | msgstr "" 333 | 334 | #: src/View/EditView.vala:479 335 | msgid "There was an error while saving the app entry." 336 | msgstr "" 337 | 338 | #: src/View/FilesView.vala:32 339 | msgid "Create a new entry" 340 | msgstr "" 341 | 342 | #: src/View/FilesView.vala:39 343 | #, fuzzy 344 | msgid "S_ystem" 345 | msgstr "Sistema" 346 | 347 | #: src/View/FilesView.vala:40 348 | #, fuzzy 349 | msgid "_Light" 350 | msgstr "Clar" 351 | 352 | #: src/View/FilesView.vala:41 353 | #, fuzzy 354 | msgid "_Dark" 355 | msgstr "Fosc" 356 | 357 | #: src/View/FilesView.vala:44 358 | msgid "_Style" 359 | msgstr "" 360 | 361 | #: src/View/FilesView.vala:45 362 | msgid "_Keyboard Shortcuts" 363 | msgstr "" 364 | 365 | #. TRANSLATORS: %s will be replaced by the app name 366 | #: src/View/FilesView.vala:49 367 | #, c-format 368 | msgid "_About %s" 369 | msgstr "" 370 | 371 | #: src/View/FilesView.vala:53 372 | msgid "Main Menu" 373 | msgstr "" 374 | 375 | #: src/View/FilesView.vala:69 376 | msgid "No Entries Found" 377 | msgstr "" 378 | 379 | #: src/View/FilesView.vala:70 380 | msgid "Click the + button on the top to create one." 381 | msgstr "" 382 | 383 | #: src/View/FilesView.vala:117 384 | msgid "Delete…" 385 | msgstr "" 386 | 387 | #: src/View/FilesView.vala:154 388 | msgid "Delete Entry?" 389 | msgstr "" 390 | 391 | #: src/View/FilesView.vala:156 392 | #, c-format 393 | msgid "Delete Entry of “%s”?" 394 | msgstr "" 395 | 396 | #: src/View/FilesView.vala:161 397 | msgid "This removes the app from the launcher." 398 | msgstr "" 399 | 400 | #: src/View/FilesView.vala:165 401 | msgid "_Delete" 402 | msgstr "" 403 | 404 | #: src/Widget/CategoriesRow.vala:63 405 | msgid "Sound & Video" 406 | msgstr "" 407 | 408 | #: src/Widget/CategoriesRow.vala:64 409 | msgid "Audio" 410 | msgstr "" 411 | 412 | #: src/Widget/CategoriesRow.vala:65 413 | msgid "Video" 414 | msgstr "" 415 | 416 | #: src/Widget/CategoriesRow.vala:66 417 | msgid "Programming" 418 | msgstr "" 419 | 420 | #: src/Widget/CategoriesRow.vala:67 421 | msgid "Education" 422 | msgstr "" 423 | 424 | #: src/Widget/CategoriesRow.vala:68 425 | msgid "Games" 426 | msgstr "" 427 | 428 | #: src/Widget/CategoriesRow.vala:69 429 | msgid "Graphics" 430 | msgstr "" 431 | 432 | #: src/Widget/CategoriesRow.vala:70 433 | msgid "Internet" 434 | msgstr "" 435 | 436 | #: src/Widget/CategoriesRow.vala:71 437 | msgid "Office" 438 | msgstr "" 439 | 440 | #: src/Widget/CategoriesRow.vala:72 441 | msgid "Science" 442 | msgstr "" 443 | 444 | #: src/Widget/CategoriesRow.vala:73 445 | msgid "Settings" 446 | msgstr "" 447 | 448 | #: src/Widget/CategoriesRow.vala:74 449 | #, fuzzy 450 | msgid "System Tools" 451 | msgstr "Sistema" 452 | 453 | #: src/Widget/CategoriesRow.vala:75 454 | msgid "Accessories" 455 | msgstr "" 456 | 457 | #: src/Widget/CategoriesRow.vala:82 458 | msgid "Categories" 459 | msgstr "" 460 | 461 | #: src/Widget/CategoriesRow.vala:83 462 | msgid "Categories applicable to the app. (You can select more than one.)" 463 | msgstr "" 464 | 465 | #: src/Widget/KeywordsRow.vala:32 466 | msgid "Keyword" 467 | msgstr "" 468 | 469 | #: src/Widget/KeywordsRow.vala:36 470 | msgid "Delete keyword" 471 | msgstr "" 472 | 473 | #: src/Widget/KeywordsRow.vala:57 474 | msgid "Keywords" 475 | msgstr "" 476 | 477 | #: src/Widget/KeywordsRow.vala:58 478 | msgid "These words can be used as search terms." 479 | msgstr "" 480 | 481 | #: src/Widget/KeywordsRow.vala:63 482 | msgid "Add a new keyword" 483 | msgstr "" 484 | 485 | #~ msgid "Pin It!" 486 | #~ msgstr "Pin It!" 487 | 488 | #~ msgid "Ryo Nakano" 489 | #~ msgstr "Ryo Nakano" 490 | 491 | #, fuzzy 492 | #~| msgid "Exec File" 493 | #~ msgctxt "shortcut window" 494 | #~ msgid "New File" 495 | #~ msgstr "Fitxer executable" 496 | 497 | #~ msgid "File Name" 498 | #~ msgstr "Nom del fitxer" 499 | 500 | #, fuzzy 501 | #~| msgid "Name of the file where these app info is saved." 502 | #~ msgid "Name of the .desktop file, where this app's info will be saved." 503 | #~ msgstr "Nom del fitxer on es desa aquesta informació de l'aplicació." 504 | 505 | #~ msgid "Suffix of the file" 506 | #~ msgstr "Sufix del fitxer" 507 | 508 | #~ msgid "Preferences" 509 | #~ msgstr "Preferències" 510 | 511 | #~ msgid "A tooltip text to describe what the app helps you to do." 512 | #~ msgstr "Una descripció sobre què ajuda a fer l'aplicació." 513 | -------------------------------------------------------------------------------- /po/com.github.ryonakano.pinit.pot: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the com.github.ryonakano.pinit package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: com.github.ryonakano.pinit\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2025-03-16 19:27+0900\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "Language: \n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | 20 | #: data/pinit.desktop.in.in:3 21 | msgid "@APP_NAME@" 22 | msgstr "" 23 | 24 | #: data/pinit.desktop.in.in:4 25 | msgid "Desktop File Creator" 26 | msgstr "" 27 | 28 | #: data/pinit.desktop.in.in:5 data/pinit.metainfo.xml.in.in:11 29 | msgid "Pin portable apps to the launcher" 30 | msgstr "" 31 | 32 | #: data/pinit.desktop.in.in:11 33 | msgid "Desktop;File;Create;Edit;Info;Icon;AppImage;" 34 | msgstr "" 35 | 36 | #: data/pinit.metainfo.xml.in.in:13 37 | msgid "" 38 | "Pin shortcuts for portable apps like raw executable files, AppImage files, " 39 | "etc. to the app launcher on your desktop." 40 | msgstr "" 41 | 42 | #: data/pinit.metainfo.xml.in.in:16 43 | msgid "Other features include:" 44 | msgstr "" 45 | 46 | #: data/pinit.metainfo.xml.in.in:20 47 | msgid "Edit or delete created app entries without opening the file manager" 48 | msgstr "" 49 | 50 | #: data/pinit.metainfo.xml.in.in:21 51 | msgid "Automatically add the execute permission to the file you select" 52 | msgstr "" 53 | 54 | #: data/pinit.metainfo.xml.in.in:27 55 | msgid "App window in the light mode" 56 | msgstr "" 57 | 58 | #: data/pinit.metainfo.xml.in.in:32 59 | msgid "App window in the dark mode" 60 | msgstr "" 61 | 62 | #: data/ui/help-overlay.blp:10 63 | msgctxt "shortcut window" 64 | msgid "General" 65 | msgstr "" 66 | 67 | #: data/ui/help-overlay.blp:14 68 | msgctxt "shortcut window" 69 | msgid "Keyboard Shortcuts" 70 | msgstr "" 71 | 72 | #: data/ui/help-overlay.blp:19 73 | msgctxt "shortcut window" 74 | msgid "Quit" 75 | msgstr "" 76 | 77 | #: data/ui/help-overlay.blp:24 78 | msgctxt "shortcut window" 79 | msgid "Edit" 80 | msgstr "" 81 | 82 | #: data/ui/help-overlay.blp:28 83 | msgctxt "shortcut window" 84 | msgid "New Entry" 85 | msgstr "" 86 | 87 | #. TRANSLATORS: A newline-separated list of translators. Don't translate literally. 88 | #. You can optionally add your name if you want, plus you may add your email address or website. 89 | #. e.g.: 90 | #. John Doe 91 | #. John Doe 92 | #. John Doe https://example.com 93 | #: src/Application.vala:310 94 | msgid "translator-credits" 95 | msgstr "" 96 | 97 | #: src/MainWindow.vala:78 98 | #, c-format 99 | msgid "Failed to Delete Entry of “%s”" 100 | msgstr "" 101 | 102 | #: src/MainWindow.vala:79 103 | msgid "There was an error while removing the app entry." 104 | msgstr "" 105 | 106 | #: src/MainWindow.vala:82 src/MainWindow.vala:132 src/View/EditView.vala:400 107 | #: src/View/EditView.vala:481 108 | msgid "_Close" 109 | msgstr "" 110 | 111 | #: src/MainWindow.vala:93 112 | msgid "Entry deleted." 113 | msgstr "" 114 | 115 | #: src/MainWindow.vala:106 116 | msgid "Entry updated." 117 | msgstr "" 118 | 119 | #: src/MainWindow.vala:129 120 | msgid "Failed to Load Entries" 121 | msgstr "" 122 | 123 | #: src/MainWindow.vala:130 124 | msgid "There was an error while loading app entries." 125 | msgstr "" 126 | 127 | #: src/MainWindow.vala:158 128 | msgid "Save Changes?" 129 | msgstr "" 130 | 131 | #: src/MainWindow.vala:159 132 | msgid "" 133 | "Open entries contain unsaved changes. Changes which are not saved will be " 134 | "permanently lost." 135 | msgstr "" 136 | 137 | #: src/MainWindow.vala:163 src/View/FilesView.vala:164 138 | msgid "_Cancel" 139 | msgstr "" 140 | 141 | #: src/MainWindow.vala:164 142 | msgid "_Discard" 143 | msgstr "" 144 | 145 | #: src/MainWindow.vala:165 src/View/EditView.vala:40 146 | msgid "_Save" 147 | msgstr "" 148 | 149 | #: src/View/EditView.vala:69 150 | msgid "Required Fields" 151 | msgstr "" 152 | 153 | #: src/View/EditView.vala:70 154 | msgid "The following fields need to be filled to save." 155 | msgstr "" 156 | 157 | #: src/View/EditView.vala:74 158 | msgid "App Name" 159 | msgstr "" 160 | 161 | #: src/View/EditView.vala:75 162 | msgid "Shown in the launcher or dock." 163 | msgstr "" 164 | 165 | #: src/View/EditView.vala:80 166 | msgid "Exec File" 167 | msgstr "" 168 | 169 | #: src/View/EditView.vala:81 170 | msgid "" 171 | "The command/app launched when you click the app entry in the launcher. " 172 | "Specify in an absolute path or an app's alias name." 173 | msgstr "" 174 | 175 | #: src/View/EditView.vala:84 176 | msgid "Select an executable file…" 177 | msgstr "" 178 | 179 | #: src/View/EditView.vala:95 180 | msgid "Optional Fields" 181 | msgstr "" 182 | 183 | #: src/View/EditView.vala:96 184 | msgid "Filling these fields improves discoverability in the app launcher." 185 | msgstr "" 186 | 187 | #: src/View/EditView.vala:100 188 | msgid "Icon File" 189 | msgstr "" 190 | 191 | #: src/View/EditView.vala:101 192 | msgid "" 193 | "The icon branding the app. Specify in an absolute path or an icon's alias " 194 | "name." 195 | msgstr "" 196 | 197 | #: src/View/EditView.vala:104 198 | msgid "Select an icon file…" 199 | msgstr "" 200 | 201 | #: src/View/EditView.vala:112 202 | msgid "Generic Name" 203 | msgstr "" 204 | 205 | #: src/View/EditView.vala:113 206 | msgid "" 207 | "Generic name of the app, for example \"Web Browser\" or \"Mail Client\"." 208 | msgstr "" 209 | 210 | #: src/View/EditView.vala:118 211 | msgid "Comment" 212 | msgstr "" 213 | 214 | #: src/View/EditView.vala:119 215 | msgid "" 216 | "Descibes the app. May appear as a tooltip when you hover over the app entry " 217 | "in the launcher/dock." 218 | msgstr "" 219 | 220 | #: src/View/EditView.vala:133 221 | msgid "Advanced Configurations" 222 | msgstr "" 223 | 224 | #: src/View/EditView.vala:134 225 | msgid "" 226 | "You can create most app entries just by filling in the sections above. " 227 | "However, some apps may require the advanced configuration options below." 228 | msgstr "" 229 | 230 | #: src/View/EditView.vala:138 231 | msgid "Startup WM Class" 232 | msgstr "" 233 | 234 | #: src/View/EditView.vala:139 235 | msgid "" 236 | "Associate the app with a window that has this ID. Use this if a different or " 237 | "duplicated icon appears in the dock when the app launches." 238 | msgstr "" 239 | 240 | #: src/View/EditView.vala:144 241 | msgid "Run in Terminal" 242 | msgstr "" 243 | 244 | #: src/View/EditView.vala:145 245 | msgid "Turn on if you want to register a CUI app." 246 | msgstr "" 247 | 248 | #: src/View/EditView.vala:150 249 | msgid "Hide in Applications Menu" 250 | msgstr "" 251 | 252 | #: src/View/EditView.vala:151 253 | msgid "" 254 | "Useful when you won't launch the app by itself, but want to associate it " 255 | "with filetypes to open files with the app from file managers." 256 | msgstr "" 257 | 258 | #: src/View/EditView.vala:155 259 | msgid "_Open" 260 | msgstr "" 261 | 262 | #: src/View/EditView.vala:159 263 | msgid "Open with Text Editor" 264 | msgstr "" 265 | 266 | #: src/View/EditView.vala:160 267 | msgid "You can also edit more options by opening with a text editor." 268 | msgstr "" 269 | 270 | #: src/View/EditView.vala:205 271 | msgid "New Entry" 272 | msgstr "" 273 | 274 | #: src/View/EditView.vala:221 src/View/EditView.vala:429 275 | msgid "Untitled App" 276 | msgstr "" 277 | 278 | #: src/View/EditView.vala:241 279 | msgid "Select Executable File" 280 | msgstr "" 281 | 282 | #: src/View/EditView.vala:242 src/View/EditView.vala:299 283 | msgid "_Select" 284 | msgstr "" 285 | 286 | #: src/View/EditView.vala:295 287 | msgid "ICO, PNG, SVG, or XMP files" 288 | msgstr "" 289 | 290 | #: src/View/EditView.vala:298 291 | msgid "Select Icon File" 292 | msgstr "" 293 | 294 | #: src/View/EditView.vala:397 295 | msgid "Failed to Open with External App" 296 | msgstr "" 297 | 298 | #: src/View/EditView.vala:398 299 | msgid "There was an error while opening the file with an external app." 300 | msgstr "" 301 | 302 | #: src/View/EditView.vala:453 303 | msgid "Edit Entry" 304 | msgstr "" 305 | 306 | #: src/View/EditView.vala:455 307 | #, c-format 308 | msgid "Edit “%s”" 309 | msgstr "" 310 | 311 | #: src/View/EditView.vala:471 312 | msgid "Failed to Save Entry" 313 | msgstr "" 314 | 315 | #: src/View/EditView.vala:474 316 | #, c-format 317 | msgid "Failed to Save Entry of “%s”" 318 | msgstr "" 319 | 320 | #: src/View/EditView.vala:479 321 | msgid "There was an error while saving the app entry." 322 | msgstr "" 323 | 324 | #: src/View/FilesView.vala:32 325 | msgid "Create a new entry" 326 | msgstr "" 327 | 328 | #: src/View/FilesView.vala:39 329 | msgid "S_ystem" 330 | msgstr "" 331 | 332 | #: src/View/FilesView.vala:40 333 | msgid "_Light" 334 | msgstr "" 335 | 336 | #: src/View/FilesView.vala:41 337 | msgid "_Dark" 338 | msgstr "" 339 | 340 | #: src/View/FilesView.vala:44 341 | msgid "_Style" 342 | msgstr "" 343 | 344 | #: src/View/FilesView.vala:45 345 | msgid "_Keyboard Shortcuts" 346 | msgstr "" 347 | 348 | #. TRANSLATORS: %s will be replaced by the app name 349 | #: src/View/FilesView.vala:49 350 | #, c-format 351 | msgid "_About %s" 352 | msgstr "" 353 | 354 | #: src/View/FilesView.vala:53 355 | msgid "Main Menu" 356 | msgstr "" 357 | 358 | #: src/View/FilesView.vala:69 359 | msgid "No Entries Found" 360 | msgstr "" 361 | 362 | #: src/View/FilesView.vala:70 363 | msgid "Click the + button on the top to create one." 364 | msgstr "" 365 | 366 | #: src/View/FilesView.vala:117 367 | msgid "Delete…" 368 | msgstr "" 369 | 370 | #: src/View/FilesView.vala:154 371 | msgid "Delete Entry?" 372 | msgstr "" 373 | 374 | #: src/View/FilesView.vala:156 375 | #, c-format 376 | msgid "Delete Entry of “%s”?" 377 | msgstr "" 378 | 379 | #: src/View/FilesView.vala:161 380 | msgid "This removes the app from the launcher." 381 | msgstr "" 382 | 383 | #: src/View/FilesView.vala:165 384 | msgid "_Delete" 385 | msgstr "" 386 | 387 | #: src/Widget/CategoriesRow.vala:63 388 | msgid "Sound & Video" 389 | msgstr "" 390 | 391 | #: src/Widget/CategoriesRow.vala:64 392 | msgid "Audio" 393 | msgstr "" 394 | 395 | #: src/Widget/CategoriesRow.vala:65 396 | msgid "Video" 397 | msgstr "" 398 | 399 | #: src/Widget/CategoriesRow.vala:66 400 | msgid "Programming" 401 | msgstr "" 402 | 403 | #: src/Widget/CategoriesRow.vala:67 404 | msgid "Education" 405 | msgstr "" 406 | 407 | #: src/Widget/CategoriesRow.vala:68 408 | msgid "Games" 409 | msgstr "" 410 | 411 | #: src/Widget/CategoriesRow.vala:69 412 | msgid "Graphics" 413 | msgstr "" 414 | 415 | #: src/Widget/CategoriesRow.vala:70 416 | msgid "Internet" 417 | msgstr "" 418 | 419 | #: src/Widget/CategoriesRow.vala:71 420 | msgid "Office" 421 | msgstr "" 422 | 423 | #: src/Widget/CategoriesRow.vala:72 424 | msgid "Science" 425 | msgstr "" 426 | 427 | #: src/Widget/CategoriesRow.vala:73 428 | msgid "Settings" 429 | msgstr "" 430 | 431 | #: src/Widget/CategoriesRow.vala:74 432 | msgid "System Tools" 433 | msgstr "" 434 | 435 | #: src/Widget/CategoriesRow.vala:75 436 | msgid "Accessories" 437 | msgstr "" 438 | 439 | #: src/Widget/CategoriesRow.vala:82 440 | msgid "Categories" 441 | msgstr "" 442 | 443 | #: src/Widget/CategoriesRow.vala:83 444 | msgid "Categories applicable to the app. (You can select more than one.)" 445 | msgstr "" 446 | 447 | #: src/Widget/KeywordsRow.vala:32 448 | msgid "Keyword" 449 | msgstr "" 450 | 451 | #: src/Widget/KeywordsRow.vala:36 452 | msgid "Delete keyword" 453 | msgstr "" 454 | 455 | #: src/Widget/KeywordsRow.vala:57 456 | msgid "Keywords" 457 | msgstr "" 458 | 459 | #: src/Widget/KeywordsRow.vala:58 460 | msgid "These words can be used as search terms." 461 | msgstr "" 462 | 463 | #: src/Widget/KeywordsRow.vala:63 464 | msgid "Add a new keyword" 465 | msgstr "" 466 | -------------------------------------------------------------------------------- /po/de.po: -------------------------------------------------------------------------------- 1 | # German translation for com.github.ryonakano.pinit. 2 | # Copyright (C) 2021-2025 Ryo Nakano 3 | # This file is distributed under the same license as the com.github.ryonakano.pinit package. 4 | # J. Lavoie , 2022. 5 | # Philipp Kiemle , 2023. 6 | # Fill read-only add-on , 2024. 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: com.github.ryonakano.pinit\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2025-03-16 19:27+0900\n" 12 | "PO-Revision-Date: 2024-05-04 15:05+0000\n" 13 | "Last-Translator: Fill read-only add-on \n" 14 | "Language-Team: German \n" 15 | "Language: de\n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | "Plural-Forms: nplurals=2; plural=n != 1;\n" 20 | "X-Generator: Weblate 5.5.3\n" 21 | 22 | #: data/pinit.desktop.in.in:3 23 | msgid "@APP_NAME@" 24 | msgstr "@APP_NAME@" 25 | 26 | #: data/pinit.desktop.in.in:4 27 | msgid "Desktop File Creator" 28 | msgstr "" 29 | 30 | #: data/pinit.desktop.in.in:5 data/pinit.metainfo.xml.in.in:11 31 | #, fuzzy 32 | msgid "Pin portable apps to the launcher" 33 | msgstr "Dadurch wird die Anwendung aus dem Startprogramm entfernt." 34 | 35 | #: data/pinit.desktop.in.in:11 36 | msgid "Desktop;File;Create;Edit;Info;Icon;AppImage;" 37 | msgstr "" 38 | 39 | #: data/pinit.metainfo.xml.in.in:13 40 | msgid "" 41 | "Pin shortcuts for portable apps like raw executable files, AppImage files, " 42 | "etc. to the app launcher on your desktop." 43 | msgstr "" 44 | 45 | #: data/pinit.metainfo.xml.in.in:16 46 | msgid "Other features include:" 47 | msgstr "" 48 | 49 | #: data/pinit.metainfo.xml.in.in:20 50 | msgid "Edit or delete created app entries without opening the file manager" 51 | msgstr "" 52 | 53 | #: data/pinit.metainfo.xml.in.in:21 54 | msgid "Automatically add the execute permission to the file you select" 55 | msgstr "" 56 | 57 | #: data/pinit.metainfo.xml.in.in:27 58 | msgid "App window in the light mode" 59 | msgstr "" 60 | 61 | #: data/pinit.metainfo.xml.in.in:32 62 | msgid "App window in the dark mode" 63 | msgstr "" 64 | 65 | #: data/ui/help-overlay.blp:10 66 | msgctxt "shortcut window" 67 | msgid "General" 68 | msgstr "" 69 | 70 | #: data/ui/help-overlay.blp:14 71 | msgctxt "shortcut window" 72 | msgid "Keyboard Shortcuts" 73 | msgstr "" 74 | 75 | #: data/ui/help-overlay.blp:19 76 | msgctxt "shortcut window" 77 | msgid "Quit" 78 | msgstr "" 79 | 80 | #: data/ui/help-overlay.blp:24 81 | msgctxt "shortcut window" 82 | msgid "Edit" 83 | msgstr "" 84 | 85 | #: data/ui/help-overlay.blp:28 86 | #, fuzzy 87 | msgctxt "shortcut window" 88 | msgid "New Entry" 89 | msgstr "Neuer Eintrag" 90 | 91 | #. TRANSLATORS: A newline-separated list of translators. Don't translate literally. 92 | #. You can optionally add your name if you want, plus you may add your email address or website. 93 | #. e.g.: 94 | #. John Doe 95 | #. John Doe 96 | #. John Doe https://example.com 97 | #: src/Application.vala:310 98 | msgid "translator-credits" 99 | msgstr "" 100 | 101 | #: src/MainWindow.vala:78 102 | #, fuzzy, c-format 103 | msgid "Failed to Delete Entry of “%s”" 104 | msgstr "Sind Sie sicher, dass Sie „%s“ löschen wollen?" 105 | 106 | #: src/MainWindow.vala:79 107 | msgid "There was an error while removing the app entry." 108 | msgstr "" 109 | 110 | #: src/MainWindow.vala:82 src/MainWindow.vala:132 src/View/EditView.vala:400 111 | #: src/View/EditView.vala:481 112 | msgid "_Close" 113 | msgstr "" 114 | 115 | #: src/MainWindow.vala:93 116 | msgid "Entry deleted." 117 | msgstr "" 118 | 119 | #: src/MainWindow.vala:106 120 | msgid "Entry updated." 121 | msgstr "" 122 | 123 | #: src/MainWindow.vala:129 124 | msgid "Failed to Load Entries" 125 | msgstr "" 126 | 127 | #: src/MainWindow.vala:130 128 | msgid "There was an error while loading app entries." 129 | msgstr "" 130 | 131 | #: src/MainWindow.vala:158 132 | msgid "Save Changes?" 133 | msgstr "" 134 | 135 | #: src/MainWindow.vala:159 136 | msgid "" 137 | "Open entries contain unsaved changes. Changes which are not saved will be " 138 | "permanently lost." 139 | msgstr "" 140 | 141 | #: src/MainWindow.vala:163 src/View/FilesView.vala:164 142 | #, fuzzy 143 | msgid "_Cancel" 144 | msgstr "Abbrechen" 145 | 146 | #: src/MainWindow.vala:164 147 | msgid "_Discard" 148 | msgstr "" 149 | 150 | #: src/MainWindow.vala:165 src/View/EditView.vala:40 151 | #, fuzzy 152 | msgid "_Save" 153 | msgstr "Speichern" 154 | 155 | #: src/View/EditView.vala:69 156 | msgid "Required Fields" 157 | msgstr "" 158 | 159 | #: src/View/EditView.vala:70 160 | msgid "The following fields need to be filled to save." 161 | msgstr "" 162 | 163 | #: src/View/EditView.vala:74 164 | msgid "App Name" 165 | msgstr "Name der Anwendung" 166 | 167 | #: src/View/EditView.vala:75 168 | #, fuzzy 169 | #| msgid "Shown in the launcher or Dock." 170 | msgid "Shown in the launcher or dock." 171 | msgstr "Wird im Launcher oder im Dock angezeigt." 172 | 173 | #: src/View/EditView.vala:80 174 | msgid "Exec File" 175 | msgstr "Exec-Datei" 176 | 177 | #: src/View/EditView.vala:81 178 | msgid "" 179 | "The command/app launched when you click the app entry in the launcher. " 180 | "Specify in an absolute path or an app's alias name." 181 | msgstr "" 182 | "Der Befehl/die Anwendung, der/die gestartet wird, wenn Sie auf den App-" 183 | "Eintrag im Launcher klicken. Geben Sie einen absoluten Pfad oder einen Alias-" 184 | "Namen der Anwendung an." 185 | 186 | #: src/View/EditView.vala:84 187 | #, fuzzy 188 | msgid "Select an executable file…" 189 | msgstr "Wählen Sie eine ausführbare Datei" 190 | 191 | #: src/View/EditView.vala:95 192 | msgid "Optional Fields" 193 | msgstr "" 194 | 195 | #: src/View/EditView.vala:96 196 | msgid "Filling these fields improves discoverability in the app launcher." 197 | msgstr "" 198 | 199 | #: src/View/EditView.vala:100 200 | msgid "Icon File" 201 | msgstr "Symbol-Datei" 202 | 203 | #: src/View/EditView.vala:101 204 | msgid "" 205 | "The icon branding the app. Specify in an absolute path or an icon's alias " 206 | "name." 207 | msgstr "" 208 | "Das Symbol, das die Anwendung kennzeichnet. Geben Sie einen absoluten Pfad " 209 | "oder einen Aliasnamen des Symbols an." 210 | 211 | #: src/View/EditView.vala:104 212 | #, fuzzy 213 | msgid "Select an icon file…" 214 | msgstr "Wählen Sie eine Symboldatei" 215 | 216 | #: src/View/EditView.vala:112 217 | msgid "Generic Name" 218 | msgstr "" 219 | 220 | #: src/View/EditView.vala:113 221 | msgid "" 222 | "Generic name of the app, for example \"Web Browser\" or \"Mail Client\"." 223 | msgstr "" 224 | 225 | #: src/View/EditView.vala:118 226 | msgid "Comment" 227 | msgstr "Kommentar" 228 | 229 | #: src/View/EditView.vala:119 230 | msgid "" 231 | "Descibes the app. May appear as a tooltip when you hover over the app entry " 232 | "in the launcher/dock." 233 | msgstr "" 234 | 235 | #: src/View/EditView.vala:133 236 | msgid "Advanced Configurations" 237 | msgstr "" 238 | 239 | #: src/View/EditView.vala:134 240 | msgid "" 241 | "You can create most app entries just by filling in the sections above. " 242 | "However, some apps may require the advanced configuration options below." 243 | msgstr "" 244 | 245 | #: src/View/EditView.vala:138 246 | msgid "Startup WM Class" 247 | msgstr "" 248 | 249 | #: src/View/EditView.vala:139 250 | msgid "" 251 | "Associate the app with a window that has this ID. Use this if a different or " 252 | "duplicated icon appears in the dock when the app launches." 253 | msgstr "" 254 | 255 | #: src/View/EditView.vala:144 256 | msgid "Run in Terminal" 257 | msgstr "Im Terminal ausführen" 258 | 259 | #: src/View/EditView.vala:145 260 | #, fuzzy 261 | msgid "Turn on if you want to register a CUI app." 262 | msgstr "Tragen Sie dies ein, wenn Sie eine CUI-Anwendung registrieren möchten." 263 | 264 | #: src/View/EditView.vala:150 265 | msgid "Hide in Applications Menu" 266 | msgstr "" 267 | 268 | #: src/View/EditView.vala:151 269 | msgid "" 270 | "Useful when you won't launch the app by itself, but want to associate it " 271 | "with filetypes to open files with the app from file managers." 272 | msgstr "" 273 | 274 | #: src/View/EditView.vala:155 275 | #, fuzzy 276 | msgid "_Open" 277 | msgstr "Öffnen" 278 | 279 | #: src/View/EditView.vala:159 280 | msgid "Open with Text Editor" 281 | msgstr "" 282 | 283 | #: src/View/EditView.vala:160 284 | msgid "You can also edit more options by opening with a text editor." 285 | msgstr "" 286 | 287 | #: src/View/EditView.vala:205 288 | msgid "New Entry" 289 | msgstr "Neuer Eintrag" 290 | 291 | #: src/View/EditView.vala:221 src/View/EditView.vala:429 292 | msgid "Untitled App" 293 | msgstr "" 294 | 295 | #: src/View/EditView.vala:241 296 | #, fuzzy 297 | msgid "Select Executable File" 298 | msgstr "Wählen Sie eine ausführbare Datei" 299 | 300 | #: src/View/EditView.vala:242 src/View/EditView.vala:299 301 | #, fuzzy 302 | msgid "_Select" 303 | msgstr "Auswählen" 304 | 305 | #: src/View/EditView.vala:295 306 | msgid "ICO, PNG, SVG, or XMP files" 307 | msgstr "ICO-, PNG-, SVG- oder XMP-Dateien" 308 | 309 | #: src/View/EditView.vala:298 310 | #, fuzzy 311 | msgid "Select Icon File" 312 | msgstr "Wählen Sie eine Symboldatei" 313 | 314 | #: src/View/EditView.vala:397 315 | msgid "Failed to Open with External App" 316 | msgstr "" 317 | 318 | #: src/View/EditView.vala:398 319 | msgid "There was an error while opening the file with an external app." 320 | msgstr "" 321 | 322 | #: src/View/EditView.vala:453 323 | #, fuzzy 324 | msgid "Edit Entry" 325 | msgstr "Eintrag wird bearbeitet" 326 | 327 | #: src/View/EditView.vala:455 328 | #, fuzzy, c-format 329 | msgid "Edit “%s”" 330 | msgstr "Bearbeitung von „%s“" 331 | 332 | #: src/View/EditView.vala:471 333 | msgid "Failed to Save Entry" 334 | msgstr "" 335 | 336 | #: src/View/EditView.vala:474 337 | #, c-format 338 | msgid "Failed to Save Entry of “%s”" 339 | msgstr "" 340 | 341 | #: src/View/EditView.vala:479 342 | msgid "There was an error while saving the app entry." 343 | msgstr "" 344 | 345 | #: src/View/FilesView.vala:32 346 | msgid "Create a new entry" 347 | msgstr "Einen neuen Eintrag erstellen" 348 | 349 | #: src/View/FilesView.vala:39 350 | #, fuzzy 351 | msgid "S_ystem" 352 | msgstr "System" 353 | 354 | #: src/View/FilesView.vala:40 355 | #, fuzzy 356 | msgid "_Light" 357 | msgstr "Hell" 358 | 359 | #: src/View/FilesView.vala:41 360 | #, fuzzy 361 | msgid "_Dark" 362 | msgstr "Dunkel" 363 | 364 | #: src/View/FilesView.vala:44 365 | #, fuzzy 366 | msgid "_Style" 367 | msgstr "Stil" 368 | 369 | #: src/View/FilesView.vala:45 370 | msgid "_Keyboard Shortcuts" 371 | msgstr "" 372 | 373 | #. TRANSLATORS: %s will be replaced by the app name 374 | #: src/View/FilesView.vala:49 375 | #, fuzzy, c-format 376 | msgid "_About %s" 377 | msgstr "Über %s …" 378 | 379 | #: src/View/FilesView.vala:53 380 | msgid "Main Menu" 381 | msgstr "" 382 | 383 | #: src/View/FilesView.vala:69 384 | #, fuzzy 385 | msgid "No Entries Found" 386 | msgstr "Keine gültigen App-Einträge gefunden" 387 | 388 | #: src/View/FilesView.vala:70 389 | msgid "Click the + button on the top to create one." 390 | msgstr "" 391 | 392 | #: src/View/FilesView.vala:117 393 | msgid "Delete…" 394 | msgstr "Löschen …" 395 | 396 | #: src/View/FilesView.vala:154 397 | #, fuzzy 398 | msgid "Delete Entry?" 399 | msgstr "Gelöschter Eintrag." 400 | 401 | #: src/View/FilesView.vala:156 402 | #, c-format 403 | msgid "Delete Entry of “%s”?" 404 | msgstr "" 405 | 406 | #: src/View/FilesView.vala:161 407 | msgid "This removes the app from the launcher." 408 | msgstr "Dadurch wird die Anwendung aus dem Startprogramm entfernt." 409 | 410 | #: src/View/FilesView.vala:165 411 | #, fuzzy 412 | msgid "_Delete" 413 | msgstr "Löschen" 414 | 415 | #: src/Widget/CategoriesRow.vala:63 416 | #, fuzzy 417 | msgid "Sound & Video" 418 | msgstr "Audio und Video" 419 | 420 | #: src/Widget/CategoriesRow.vala:64 421 | msgid "Audio" 422 | msgstr "Audio" 423 | 424 | #: src/Widget/CategoriesRow.vala:65 425 | msgid "Video" 426 | msgstr "Video" 427 | 428 | #: src/Widget/CategoriesRow.vala:66 429 | msgid "Programming" 430 | msgstr "" 431 | 432 | #: src/Widget/CategoriesRow.vala:67 433 | msgid "Education" 434 | msgstr "Bildung" 435 | 436 | #: src/Widget/CategoriesRow.vala:68 437 | #, fuzzy 438 | msgid "Games" 439 | msgstr "Spiel" 440 | 441 | #: src/Widget/CategoriesRow.vala:69 442 | msgid "Graphics" 443 | msgstr "Grafiken" 444 | 445 | #: src/Widget/CategoriesRow.vala:70 446 | msgid "Internet" 447 | msgstr "" 448 | 449 | #: src/Widget/CategoriesRow.vala:71 450 | msgid "Office" 451 | msgstr "Buröautomation" 452 | 453 | #: src/Widget/CategoriesRow.vala:72 454 | msgid "Science" 455 | msgstr "Wissenschaft" 456 | 457 | #: src/Widget/CategoriesRow.vala:73 458 | msgid "Settings" 459 | msgstr "Einstellungen" 460 | 461 | #: src/Widget/CategoriesRow.vala:74 462 | #, fuzzy 463 | msgid "System Tools" 464 | msgstr "System" 465 | 466 | #: src/Widget/CategoriesRow.vala:75 467 | msgid "Accessories" 468 | msgstr "" 469 | 470 | #: src/Widget/CategoriesRow.vala:82 471 | #, fuzzy 472 | msgid "Categories" 473 | msgstr "Anwendungskategorien" 474 | 475 | #: src/Widget/CategoriesRow.vala:83 476 | msgid "Categories applicable to the app. (You can select more than one.)" 477 | msgstr "" 478 | 479 | #: src/Widget/KeywordsRow.vala:32 480 | msgid "Keyword" 481 | msgstr "" 482 | 483 | #: src/Widget/KeywordsRow.vala:36 484 | #, fuzzy 485 | msgid "Delete keyword" 486 | msgstr "Gelöschter Eintrag." 487 | 488 | #: src/Widget/KeywordsRow.vala:57 489 | msgid "Keywords" 490 | msgstr "" 491 | 492 | #: src/Widget/KeywordsRow.vala:58 493 | msgid "These words can be used as search terms." 494 | msgstr "" 495 | 496 | #: src/Widget/KeywordsRow.vala:63 497 | msgid "Add a new keyword" 498 | msgstr "" 499 | 500 | #~ msgid "Pin It!" 501 | #~ msgstr "Pin It!" 502 | 503 | #~ msgid "Ryo Nakano" 504 | #~ msgstr "Ryo Nakano" 505 | 506 | #, fuzzy 507 | #~| msgid "Exec File" 508 | #~ msgctxt "shortcut window" 509 | #~ msgid "New File" 510 | #~ msgstr "Exec-Datei" 511 | 512 | #~ msgid "Updated entry." 513 | #~ msgstr "Aktualisierter Eintrag." 514 | 515 | #, fuzzy 516 | #~| msgid "" 517 | #~| "Create the shortcut to your favorite portable apps into your app launcher" 518 | #~ msgid "Pin shortcuts for your favorite portable apps to your app launcher" 519 | #~ msgstr "" 520 | #~ "Erstellen Sie eine Verknüpfung zu Ihren bevorzugten mobilen Anwendungen " 521 | #~ "in Ihrem Startprogramm" 522 | 523 | #~ msgid "File Name" 524 | #~ msgstr "Dateiname" 525 | 526 | #, fuzzy 527 | #~| msgid "Name of the file where these app info is saved." 528 | #~ msgid "Name of the .desktop file, where this app's info will be saved." 529 | #~ msgstr "" 530 | #~ "Name der Datei, in der diese Anwendungsinformationen gespeichert sind." 531 | 532 | #~ msgid "Suffix of the file" 533 | #~ msgstr "Suffix der Datei" 534 | 535 | #~ msgid "Recommendations for naming" 536 | #~ msgstr "Empfehlungen für die Namensgebung" 537 | 538 | #, fuzzy 539 | #~| msgid "" 540 | #~| "Only use alphabets, numbers, and underscores, and none begins with " 541 | #~| "numbers." 542 | #~ msgid "" 543 | #~ "It is recommended to use only alphanumeric characters and underscores. " 544 | #~ "Don't begin with a number." 545 | #~ msgstr "" 546 | #~ "Verwenden Sie nur Buchstaben, Zahlen und Unterstriche, und beginnen Sie " 547 | #~ "nicht mit Zahlen." 548 | 549 | #, c-format 550 | #~ msgid "For more info, see %s." 551 | #~ msgstr "Weitere Informationen finden Sie unter %s." 552 | 553 | #~ msgid "the file naming specification by freedesktop.org" 554 | #~ msgstr "die Dateibenennungsspezifikation von freedesktop.org" 555 | 556 | #~ msgid "Preferences" 557 | #~ msgstr "Einstellungen" 558 | 559 | #~ msgid "If you've never created one, click the + button on the top." 560 | #~ msgstr "" 561 | #~ "Wenn Sie noch nie einen erstellt haben, klicken Sie oben auf die " 562 | #~ "Schaltfläche +." 563 | 564 | #, c-format 565 | #~ msgid "Are you sure you want to delete “%s”?" 566 | #~ msgstr "Sind Sie sicher, dass Sie „%s“ löschen wollen?" 567 | 568 | #~ msgid "Development" 569 | #~ msgstr "Entwicklung" 570 | 571 | #~ msgid "Network" 572 | #~ msgstr "Netzwerk" 573 | 574 | #~ msgid "Utility" 575 | #~ msgstr "Dienstprogramm" 576 | 577 | #~ msgid "A tooltip text to describe what the app helps you to do." 578 | #~ msgstr "Ein Text, der beschreibt, was die Anwendung für Sie tun kann." 579 | 580 | #, fuzzy 581 | #~| msgid "Type of the app, multiplly selectable." 582 | #~ msgid "Type of the app, multiply selectable." 583 | #~ msgstr "Typ der Anwendung, mehrfach wählbar." 584 | 585 | #, fuzzy 586 | #~| msgid "" 587 | #~| "Use at least one period to make sure to be separated into at least two " 588 | #~| "elements." 589 | #~ msgid "" 590 | #~ "Also, use at least one period to make sure to be separated into at least " 591 | #~ "two elements." 592 | #~ msgstr "" 593 | #~ "Verwenden Sie mindestens einen Punkt, um sicherzustellen, dass sie in " 594 | #~ "mindestens zwei Elemente unterteilt sind." 595 | -------------------------------------------------------------------------------- /po/et.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the com.github.ryonakano.pinit package. 4 | # Priit Jõerüüt , 2024, 2025. 5 | # Fill read-only add-on , 2024. 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: com.github.ryonakano.pinit\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2025-03-16 19:27+0900\n" 11 | "PO-Revision-Date: 2025-03-23 06:44+0000\n" 12 | "Last-Translator: Priit Jõerüüt \n" 13 | "Language-Team: Estonian " 14 | "\n" 15 | "Language: et\n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | "Plural-Forms: nplurals=2; plural=n != 1;\n" 20 | "X-Generator: Weblate 5.11-dev\n" 21 | 22 | #: data/pinit.desktop.in.in:3 23 | msgid "@APP_NAME@" 24 | msgstr "@APP_NAME@" 25 | 26 | #: data/pinit.desktop.in.in:4 27 | msgid "Desktop File Creator" 28 | msgstr "Töölaua seadistusfailide looja" 29 | 30 | #: data/pinit.desktop.in.in:5 data/pinit.metainfo.xml.in.in:11 31 | msgid "Pin portable apps to the launcher" 32 | msgstr "" 33 | "Kinnita üksikuid ja/või süsteemiväliseid rakendusi rakenduste käivitajasse" 34 | 35 | #: data/pinit.desktop.in.in:11 36 | msgid "Desktop;File;Create;Edit;Info;Icon;AppImage;" 37 | msgstr "" 38 | "Desktop;File;fail;loo;muuda;lisa;teave;rakendus;käivitaja;start;ikoon;" 39 | "AppImage;töölaud;töölauafail;" 40 | 41 | #: data/pinit.metainfo.xml.in.in:13 42 | msgid "" 43 | "Pin shortcuts for portable apps like raw executable files, AppImage files, " 44 | "etc. to the app launcher on your desktop." 45 | msgstr "" 46 | "Kinnita viiteid üksikutele ja/või süsteemivälistele rakendustele, näiteks " 47 | "AppImage failidele, skriptidele või juhuslike programmide failidele oma " 48 | "töölaua rakenduste käivitajasse ja muudesse sarnastesse vaadetesse. Põhineb " 49 | "standardsete .desktop failide haldusel." 50 | 51 | #: data/pinit.metainfo.xml.in.in:16 52 | msgid "Other features include:" 53 | msgstr "Lisavõimalused:" 54 | 55 | #: data/pinit.metainfo.xml.in.in:20 56 | msgid "Edit or delete created app entries without opening the file manager" 57 | msgstr "Muuda või kustuta rakenduste kirjeid ilma failihaldurit kasutamata" 58 | 59 | #: data/pinit.metainfo.xml.in.in:21 60 | msgid "Automatically add the execute permission to the file you select" 61 | msgstr "Luba lisatud failile automaatselt käivitusõigused" 62 | 63 | #: data/pinit.metainfo.xml.in.in:27 64 | msgid "App window in the light mode" 65 | msgstr "Heledas kujunduses rakenduse aken" 66 | 67 | #: data/pinit.metainfo.xml.in.in:32 68 | msgid "App window in the dark mode" 69 | msgstr "Tumedas kujunduses rakenduse aken" 70 | 71 | #: data/ui/help-overlay.blp:10 72 | msgctxt "shortcut window" 73 | msgid "General" 74 | msgstr "Üldised seadistused" 75 | 76 | #: data/ui/help-overlay.blp:14 77 | msgctxt "shortcut window" 78 | msgid "Keyboard Shortcuts" 79 | msgstr "Klaviatuuri kiirklahvid" 80 | 81 | #: data/ui/help-overlay.blp:19 82 | msgctxt "shortcut window" 83 | msgid "Quit" 84 | msgstr "Välju" 85 | 86 | #: data/ui/help-overlay.blp:24 87 | msgctxt "shortcut window" 88 | msgid "Edit" 89 | msgstr "Muuda" 90 | 91 | #: data/ui/help-overlay.blp:28 92 | msgctxt "shortcut window" 93 | msgid "New Entry" 94 | msgstr "Uus kirje" 95 | 96 | #. TRANSLATORS: A newline-separated list of translators. Don't translate literally. 97 | #. You can optionally add your name if you want, plus you may add your email address or website. 98 | #. e.g.: 99 | #. John Doe 100 | #. John Doe 101 | #. John Doe https://example.com 102 | #: src/Application.vala:310 103 | msgid "translator-credits" 104 | msgstr "Priit Jõerüüt 2024-2025" 105 | 106 | #: src/MainWindow.vala:78 107 | #, c-format 108 | msgid "Failed to Delete Entry of “%s”" 109 | msgstr "„%s“ kirje kustutamine ei õnnestunud" 110 | 111 | #: src/MainWindow.vala:79 112 | msgid "There was an error while removing the app entry." 113 | msgstr "Antud rakenduse kirje kustutamisel tekkis viga." 114 | 115 | #: src/MainWindow.vala:82 src/MainWindow.vala:132 src/View/EditView.vala:400 116 | #: src/View/EditView.vala:481 117 | msgid "_Close" 118 | msgstr "_Sulge" 119 | 120 | #: src/MainWindow.vala:93 121 | msgid "Entry deleted." 122 | msgstr "Kirje on kustutatud." 123 | 124 | #: src/MainWindow.vala:106 125 | msgid "Entry updated." 126 | msgstr "Kirje on uuendatud." 127 | 128 | #: src/MainWindow.vala:129 129 | msgid "Failed to Load Entries" 130 | msgstr "Kirjete laadimine ei õnnestunud" 131 | 132 | #: src/MainWindow.vala:130 133 | msgid "There was an error while loading app entries." 134 | msgstr "Rakenduste kirjete laadimisel tekkis viga." 135 | 136 | #: src/MainWindow.vala:158 137 | msgid "Save Changes?" 138 | msgstr "Kas salvestame muudatused?" 139 | 140 | #: src/MainWindow.vala:159 141 | msgid "" 142 | "Open entries contain unsaved changes. Changes which are not saved will be " 143 | "permanently lost." 144 | msgstr "" 145 | "Avatud kirjetes on salvestamata muudatusi. Kui sa ei salvesta ja sulged, " 146 | "siis lähevad muudatused jäädavalt kaotsi." 147 | 148 | #: src/MainWindow.vala:163 src/View/FilesView.vala:164 149 | msgid "_Cancel" 150 | msgstr "_Katkesta" 151 | 152 | #: src/MainWindow.vala:164 153 | msgid "_Discard" 154 | msgstr "_Loobu" 155 | 156 | #: src/MainWindow.vala:165 src/View/EditView.vala:40 157 | msgid "_Save" 158 | msgstr "_Salvesta" 159 | 160 | #: src/View/EditView.vala:69 161 | msgid "Required Fields" 162 | msgstr "Kohustuslikud väljad" 163 | 164 | #: src/View/EditView.vala:70 165 | msgid "The following fields need to be filled to save." 166 | msgstr "Nende väljade täitmine on salvestamise eelduseks." 167 | 168 | #: src/View/EditView.vala:74 169 | msgid "App Name" 170 | msgstr "Rakenduse nimi" 171 | 172 | #: src/View/EditView.vala:75 173 | msgid "Shown in the launcher or dock." 174 | msgstr "Näidatakse rakenduste käivitajas, dokis ja mujal töölaual." 175 | 176 | #: src/View/EditView.vala:80 177 | msgid "Exec File" 178 | msgstr "Rakenduse käivitusfail" 179 | 180 | #: src/View/EditView.vala:81 181 | msgid "" 182 | "The command/app launched when you click the app entry in the launcher. " 183 | "Specify in an absolute path or an app's alias name." 184 | msgstr "" 185 | "Kui klõpsid käivitajas seda kirjet, siis käivitatakse antud käivitusfail või " 186 | "käsk. Pead näitama täpse asukoha või kasutama rakenduse toimivat aliast." 187 | 188 | #: src/View/EditView.vala:84 189 | msgid "Select an executable file…" 190 | msgstr "Vali rakenduse käivitusfail…" 191 | 192 | #: src/View/EditView.vala:95 193 | msgid "Optional Fields" 194 | msgstr "Täiendavad väljad" 195 | 196 | #: src/View/EditView.vala:96 197 | msgid "Filling these fields improves discoverability in the app launcher." 198 | msgstr "" 199 | "Nende väljade täitmine parandab rakenduse leitavust ning menüüdes ja " 200 | "käivitajates kuvamise kvaliteeti." 201 | 202 | #: src/View/EditView.vala:100 203 | msgid "Icon File" 204 | msgstr "Ikoonifail" 205 | 206 | #: src/View/EditView.vala:101 207 | msgid "" 208 | "The icon branding the app. Specify in an absolute path or an icon's alias " 209 | "name." 210 | msgstr "" 211 | "Fail rakenduse graafilise tunnuse või logoga. Pead näitama täpse asukoha või " 212 | "kasutama ikoonifaili toimivat aliast." 213 | 214 | #: src/View/EditView.vala:104 215 | msgid "Select an icon file…" 216 | msgstr "Vali ikoonifail…" 217 | 218 | #: src/View/EditView.vala:112 219 | msgid "Generic Name" 220 | msgstr "Üldine nimi" 221 | 222 | #: src/View/EditView.vala:113 223 | msgid "" 224 | "Generic name of the app, for example \"Web Browser\" or \"Mail Client\"." 225 | msgstr "Rakenduse üldnimi, nagu näiteks „Veebibrauser“ või „E-posti klient“." 226 | 227 | #: src/View/EditView.vala:118 228 | msgid "Comment" 229 | msgstr "Kommentaar" 230 | 231 | #: src/View/EditView.vala:119 232 | msgid "" 233 | "Descibes the app. May appear as a tooltip when you hover over the app entry " 234 | "in the launcher/dock." 235 | msgstr "" 236 | "Rakendust kirjeldav nimi. Sõltuvalt kasutajaliidesest võidakse seda kasutada " 237 | "kohtvihjena käivitajas, dokis või mujal." 238 | 239 | #: src/View/EditView.vala:133 240 | msgid "Advanced Configurations" 241 | msgstr "Täiendavad seadistused" 242 | 243 | #: src/View/EditView.vala:134 244 | msgid "" 245 | "You can create most app entries just by filling in the sections above. " 246 | "However, some apps may require the advanced configuration options below." 247 | msgstr "" 248 | "Enamuste rakenduste jaoks piisab ülaltoodud andmetest. Aga mõned rakendused " 249 | "võivad vajada järgnevaid lisaseadistusi." 250 | 251 | #: src/View/EditView.vala:138 252 | msgid "Startup WM Class" 253 | msgstr "Aknahalduri klass käivitamisel (WM Class)" 254 | 255 | #: src/View/EditView.vala:139 256 | msgid "" 257 | "Associate the app with a window that has this ID. Use this if a different or " 258 | "duplicated icon appears in the dock when the app launches." 259 | msgstr "" 260 | "Seosta rakendus aknaga, millele on nimetatud tunnus. Kasuta seda võimalust, " 261 | "kui rakenduse käivitamisel tekib tegumiribale topeltikoon või teistsugune " 262 | "ikoon." 263 | 264 | #: src/View/EditView.vala:144 265 | msgid "Run in Terminal" 266 | msgstr "Käivita terminalis" 267 | 268 | #: src/View/EditView.vala:145 269 | msgid "Turn on if you want to register a CUI app." 270 | msgstr "" 271 | "Vajad seda valikut, kui soovid lisada kirjet käsurearakendusele, mis kasutab " 272 | "tekstiliidest (CUI)." 273 | 274 | #: src/View/EditView.vala:150 275 | msgid "Hide in Applications Menu" 276 | msgstr "Peida rakenduste menüüst" 277 | 278 | #: src/View/EditView.vala:151 279 | msgid "" 280 | "Useful when you won't launch the app by itself, but want to associate it " 281 | "with filetypes to open files with the app from file managers." 282 | msgstr "" 283 | "See eelistus on mõeldud kasutamiseks näiteks siis, kui sa ei käivita " 284 | "rakendust rakenduste menüüst või valijast, vaid pigem failihalduri " 285 | "kontekstimenüüst." 286 | 287 | #: src/View/EditView.vala:155 288 | msgid "_Open" 289 | msgstr "_Ava" 290 | 291 | #: src/View/EditView.vala:159 292 | msgid "Open with Text Editor" 293 | msgstr "Ava tekstitoimetiga" 294 | 295 | #: src/View/EditView.vala:160 296 | msgid "You can also edit more options by opening with a text editor." 297 | msgstr "" 298 | "Lisaks on sul võimalik tekstitoimetis lisada kõiki muid väärtusi vastavalt " 299 | "standardile, mille leiad siit: https://specifications.freedesktop.org/" 300 | "desktop-entry-spec/latest/ ." 301 | 302 | #: src/View/EditView.vala:205 303 | msgid "New Entry" 304 | msgstr "Uus kirje" 305 | 306 | #: src/View/EditView.vala:221 src/View/EditView.vala:429 307 | msgid "Untitled App" 308 | msgstr "Ilma nimeta rakendus" 309 | 310 | #: src/View/EditView.vala:241 311 | msgid "Select Executable File" 312 | msgstr "Vali käivitusfail" 313 | 314 | #: src/View/EditView.vala:242 src/View/EditView.vala:299 315 | msgid "_Select" 316 | msgstr "_Vali" 317 | 318 | #: src/View/EditView.vala:295 319 | msgid "ICO, PNG, SVG, or XMP files" 320 | msgstr "ICO, PNG, SVG või XMP failid" 321 | 322 | #: src/View/EditView.vala:298 323 | msgid "Select Icon File" 324 | msgstr "Vali ikoonifail" 325 | 326 | #: src/View/EditView.vala:397 327 | msgid "Failed to Open with External App" 328 | msgstr "Välise rakendusega käivitamine ei õnnestunud" 329 | 330 | #: src/View/EditView.vala:398 331 | msgid "There was an error while opening the file with an external app." 332 | msgstr "Selle faili avamisel välise rakendusega tekkis viga." 333 | 334 | #: src/View/EditView.vala:453 335 | msgid "Edit Entry" 336 | msgstr "Muuda kirjet" 337 | 338 | #: src/View/EditView.vala:455 339 | #, c-format 340 | msgid "Edit “%s”" 341 | msgstr "Muuda kirjet: „%s“" 342 | 343 | #: src/View/EditView.vala:471 344 | msgid "Failed to Save Entry" 345 | msgstr "Kirje salvestamine ei õnnestunud" 346 | 347 | #: src/View/EditView.vala:474 348 | #, c-format 349 | msgid "Failed to Save Entry of “%s”" 350 | msgstr "„%s“ kirje salvestamine ei õnnestunud" 351 | 352 | #: src/View/EditView.vala:479 353 | msgid "There was an error while saving the app entry." 354 | msgstr "Rakenduse kirje salvestamisel tekkis viga." 355 | 356 | #: src/View/FilesView.vala:32 357 | msgid "Create a new entry" 358 | msgstr "Lisa uus kirje" 359 | 360 | #: src/View/FilesView.vala:39 361 | msgid "S_ystem" 362 | msgstr "S_üsteemi kujundus" 363 | 364 | #: src/View/FilesView.vala:40 365 | msgid "_Light" 366 | msgstr "_Hele kujundus" 367 | 368 | #: src/View/FilesView.vala:41 369 | msgid "_Dark" 370 | msgstr "_Tume kujundus" 371 | 372 | #: src/View/FilesView.vala:44 373 | msgid "_Style" 374 | msgstr "_Kujundus" 375 | 376 | #: src/View/FilesView.vala:45 377 | msgid "_Keyboard Shortcuts" 378 | msgstr "_Klaviatuuri kiirklahvid" 379 | 380 | #. TRANSLATORS: %s will be replaced by the app name 381 | #: src/View/FilesView.vala:49 382 | #, c-format 383 | msgid "_About %s" 384 | msgstr "R_akenduse teave: %s" 385 | 386 | #: src/View/FilesView.vala:53 387 | msgid "Main Menu" 388 | msgstr "Põhimenüü" 389 | 390 | #: src/View/FilesView.vala:69 391 | msgid "No Entries Found" 392 | msgstr "Kirjeid ei leidu" 393 | 394 | #: src/View/FilesView.vala:70 395 | msgid "Click the + button on the top to create one." 396 | msgstr "Lisamiseks klõpsi „+“ ikooni." 397 | 398 | #: src/View/FilesView.vala:117 399 | msgid "Delete…" 400 | msgstr "Delete…" 401 | 402 | #: src/View/FilesView.vala:154 403 | msgid "Delete Entry?" 404 | msgstr "Kas kustutame kirje?" 405 | 406 | #: src/View/FilesView.vala:156 407 | #, c-format 408 | msgid "Delete Entry of “%s”?" 409 | msgstr "Kas kustutame „%s“ kirje?" 410 | 411 | #: src/View/FilesView.vala:161 412 | msgid "This removes the app from the launcher." 413 | msgstr "Sellega kustutatakse rakendus käivitajast, dokilt ja mujalt." 414 | 415 | #: src/View/FilesView.vala:165 416 | msgid "_Delete" 417 | msgstr "_Kustuta" 418 | 419 | #: src/Widget/CategoriesRow.vala:63 420 | msgid "Sound & Video" 421 | msgstr "Multimeedia" 422 | 423 | #: src/Widget/CategoriesRow.vala:64 424 | msgid "Audio" 425 | msgstr "Heli" 426 | 427 | #: src/Widget/CategoriesRow.vala:65 428 | msgid "Video" 429 | msgstr "Video" 430 | 431 | #: src/Widget/CategoriesRow.vala:66 432 | msgid "Programming" 433 | msgstr "Programmeerimine" 434 | 435 | #: src/Widget/CategoriesRow.vala:67 436 | msgid "Education" 437 | msgstr "Haridus" 438 | 439 | #: src/Widget/CategoriesRow.vala:68 440 | msgid "Games" 441 | msgstr "Mängud" 442 | 443 | #: src/Widget/CategoriesRow.vala:69 444 | msgid "Graphics" 445 | msgstr "Graafika" 446 | 447 | #: src/Widget/CategoriesRow.vala:70 448 | msgid "Internet" 449 | msgstr "Internet" 450 | 451 | #: src/Widget/CategoriesRow.vala:71 452 | msgid "Office" 453 | msgstr "Kontoritarvikud" 454 | 455 | #: src/Widget/CategoriesRow.vala:72 456 | msgid "Science" 457 | msgstr "Teadus" 458 | 459 | #: src/Widget/CategoriesRow.vala:73 460 | msgid "Settings" 461 | msgstr "Seadistused" 462 | 463 | #: src/Widget/CategoriesRow.vala:74 464 | msgid "System Tools" 465 | msgstr "Süsteemi tarvikud" 466 | 467 | #: src/Widget/CategoriesRow.vala:75 468 | msgid "Accessories" 469 | msgstr "Tarvikud" 470 | 471 | #: src/Widget/CategoriesRow.vala:82 472 | msgid "Categories" 473 | msgstr "Kategooriad" 474 | 475 | #: src/Widget/CategoriesRow.vala:83 476 | msgid "Categories applicable to the app. (You can select more than one.)" 477 | msgstr "Rakendusekohased kategooriad . (Võid valida enam kui ühe.)" 478 | 479 | #: src/Widget/KeywordsRow.vala:32 480 | msgid "Keyword" 481 | msgstr "Märksõna" 482 | 483 | #: src/Widget/KeywordsRow.vala:36 484 | msgid "Delete keyword" 485 | msgstr "Kustuta märksõna" 486 | 487 | #: src/Widget/KeywordsRow.vala:57 488 | msgid "Keywords" 489 | msgstr "Märksõnad" 490 | 491 | #: src/Widget/KeywordsRow.vala:58 492 | msgid "These words can be used as search terms." 493 | msgstr "Neid sõnu kasutatakse tihtipeale otsingusõnadena." 494 | 495 | #: src/Widget/KeywordsRow.vala:63 496 | msgid "Add a new keyword" 497 | msgstr "Lisa uus märksõna" 498 | -------------------------------------------------------------------------------- /po/fi.po: -------------------------------------------------------------------------------- 1 | # Finnish translations for com.github.ryonakano.pinit. 2 | # Copyright (C) 2021-2025 Ryo Nakano 3 | # This file is distributed under the same license as the com.github.ryonakano.pinit package. 4 | # Jiri Grönroos , 2023. 5 | # Fill read-only add-on , 2024. 6 | # Ricky Tigg , 2025. 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: com.github.ryonakano.pinit\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2025-03-16 19:27+0900\n" 12 | "PO-Revision-Date: 2025-02-04 13:02+0000\n" 13 | "Last-Translator: Ricky Tigg \n" 14 | "Language-Team: Finnish \n" 15 | "Language: fi\n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | "Plural-Forms: nplurals=2; plural=n != 1;\n" 20 | "X-Generator: Weblate 5.10-dev\n" 21 | 22 | #: data/pinit.desktop.in.in:3 23 | msgid "@APP_NAME@" 24 | msgstr "@APP_NAME@" 25 | 26 | #: data/pinit.desktop.in.in:4 27 | msgid "Desktop File Creator" 28 | msgstr "" 29 | 30 | #: data/pinit.desktop.in.in:5 data/pinit.metainfo.xml.in.in:11 31 | #, fuzzy 32 | msgid "Pin portable apps to the launcher" 33 | msgstr "Tämä poistaa sovelluksen käynnistimestä." 34 | 35 | #: data/pinit.desktop.in.in:11 36 | msgid "Desktop;File;Create;Edit;Info;Icon;AppImage;" 37 | msgstr "" 38 | 39 | #: data/pinit.metainfo.xml.in.in:13 40 | msgid "" 41 | "Pin shortcuts for portable apps like raw executable files, AppImage files, " 42 | "etc. to the app launcher on your desktop." 43 | msgstr "" 44 | 45 | #: data/pinit.metainfo.xml.in.in:16 46 | msgid "Other features include:" 47 | msgstr "" 48 | 49 | #: data/pinit.metainfo.xml.in.in:20 50 | msgid "Edit or delete created app entries without opening the file manager" 51 | msgstr "" 52 | 53 | #: data/pinit.metainfo.xml.in.in:21 54 | msgid "Automatically add the execute permission to the file you select" 55 | msgstr "" 56 | 57 | #: data/pinit.metainfo.xml.in.in:27 58 | msgid "App window in the light mode" 59 | msgstr "" 60 | 61 | #: data/pinit.metainfo.xml.in.in:32 62 | msgid "App window in the dark mode" 63 | msgstr "" 64 | 65 | #: data/ui/help-overlay.blp:10 66 | msgctxt "shortcut window" 67 | msgid "General" 68 | msgstr "" 69 | 70 | #: data/ui/help-overlay.blp:14 71 | msgctxt "shortcut window" 72 | msgid "Keyboard Shortcuts" 73 | msgstr "" 74 | 75 | #: data/ui/help-overlay.blp:19 76 | msgctxt "shortcut window" 77 | msgid "Quit" 78 | msgstr "" 79 | 80 | #: data/ui/help-overlay.blp:24 81 | msgctxt "shortcut window" 82 | msgid "Edit" 83 | msgstr "" 84 | 85 | #: data/ui/help-overlay.blp:28 86 | #, fuzzy 87 | msgctxt "shortcut window" 88 | msgid "New Entry" 89 | msgstr "Uusi tietue" 90 | 91 | #. TRANSLATORS: A newline-separated list of translators. Don't translate literally. 92 | #. You can optionally add your name if you want, plus you may add your email address or website. 93 | #. e.g.: 94 | #. John Doe 95 | #. John Doe 96 | #. John Doe https://example.com 97 | #: src/Application.vala:310 98 | msgid "translator-credits" 99 | msgstr "" 100 | 101 | #: src/MainWindow.vala:78 102 | #, fuzzy, c-format 103 | msgid "Failed to Delete Entry of “%s”" 104 | msgstr "Tiedostoa “%s” ei voitu poistaa" 105 | 106 | #: src/MainWindow.vala:79 107 | msgid "There was an error while removing the app entry." 108 | msgstr "" 109 | 110 | #: src/MainWindow.vala:82 src/MainWindow.vala:132 src/View/EditView.vala:400 111 | #: src/View/EditView.vala:481 112 | #, fuzzy 113 | msgid "_Close" 114 | msgstr "Sulje" 115 | 116 | #: src/MainWindow.vala:93 117 | msgid "Entry deleted." 118 | msgstr "" 119 | 120 | #: src/MainWindow.vala:106 121 | msgid "Entry updated." 122 | msgstr "" 123 | 124 | #: src/MainWindow.vala:129 125 | msgid "Failed to Load Entries" 126 | msgstr "" 127 | 128 | #: src/MainWindow.vala:130 129 | msgid "There was an error while loading app entries." 130 | msgstr "" 131 | 132 | #: src/MainWindow.vala:158 133 | msgid "Save Changes?" 134 | msgstr "" 135 | 136 | #: src/MainWindow.vala:159 137 | msgid "" 138 | "Open entries contain unsaved changes. Changes which are not saved will be " 139 | "permanently lost." 140 | msgstr "" 141 | 142 | #: src/MainWindow.vala:163 src/View/FilesView.vala:164 143 | #, fuzzy 144 | msgid "_Cancel" 145 | msgstr "Peru" 146 | 147 | #: src/MainWindow.vala:164 148 | msgid "_Discard" 149 | msgstr "" 150 | 151 | #: src/MainWindow.vala:165 src/View/EditView.vala:40 152 | #, fuzzy 153 | msgid "_Save" 154 | msgstr "Tallenna" 155 | 156 | #: src/View/EditView.vala:69 157 | msgid "Required Fields" 158 | msgstr "" 159 | 160 | #: src/View/EditView.vala:70 161 | msgid "The following fields need to be filled to save." 162 | msgstr "" 163 | 164 | #: src/View/EditView.vala:74 165 | msgid "App Name" 166 | msgstr "Sovelluksen nimi" 167 | 168 | #: src/View/EditView.vala:75 169 | msgid "Shown in the launcher or dock." 170 | msgstr "Näytetään käynnistimessä tai telakassa." 171 | 172 | #: src/View/EditView.vala:80 173 | msgid "Exec File" 174 | msgstr "" 175 | 176 | #: src/View/EditView.vala:81 177 | msgid "" 178 | "The command/app launched when you click the app entry in the launcher. " 179 | "Specify in an absolute path or an app's alias name." 180 | msgstr "" 181 | 182 | #: src/View/EditView.vala:84 183 | #, fuzzy 184 | msgid "Select an executable file…" 185 | msgstr "Valitse suoritustiedosto" 186 | 187 | #: src/View/EditView.vala:95 188 | msgid "Optional Fields" 189 | msgstr "" 190 | 191 | #: src/View/EditView.vala:96 192 | msgid "Filling these fields improves discoverability in the app launcher." 193 | msgstr "" 194 | 195 | #: src/View/EditView.vala:100 196 | msgid "Icon File" 197 | msgstr "Kuvaketiedosto" 198 | 199 | #: src/View/EditView.vala:101 200 | msgid "" 201 | "The icon branding the app. Specify in an absolute path or an icon's alias " 202 | "name." 203 | msgstr "" 204 | 205 | #: src/View/EditView.vala:104 206 | #, fuzzy 207 | msgid "Select an icon file…" 208 | msgstr "Valitse kuvaketiedosto" 209 | 210 | #: src/View/EditView.vala:112 211 | msgid "Generic Name" 212 | msgstr "" 213 | 214 | #: src/View/EditView.vala:113 215 | msgid "" 216 | "Generic name of the app, for example \"Web Browser\" or \"Mail Client\"." 217 | msgstr "" 218 | 219 | #: src/View/EditView.vala:118 220 | msgid "Comment" 221 | msgstr "Kommentti" 222 | 223 | #: src/View/EditView.vala:119 224 | msgid "" 225 | "Descibes the app. May appear as a tooltip when you hover over the app entry " 226 | "in the launcher/dock." 227 | msgstr "" 228 | 229 | #: src/View/EditView.vala:133 230 | #, fuzzy 231 | msgid "Advanced Configurations" 232 | msgstr "Lisäasetukset" 233 | 234 | #: src/View/EditView.vala:134 235 | msgid "" 236 | "You can create most app entries just by filling in the sections above. " 237 | "However, some apps may require the advanced configuration options below." 238 | msgstr "" 239 | 240 | #: src/View/EditView.vala:138 241 | msgid "Startup WM Class" 242 | msgstr "Käynnistyksen WM-luokka" 243 | 244 | #: src/View/EditView.vala:139 245 | msgid "" 246 | "Associate the app with a window that has this ID. Use this if a different or " 247 | "duplicated icon appears in the dock when the app launches." 248 | msgstr "" 249 | 250 | #: src/View/EditView.vala:144 251 | msgid "Run in Terminal" 252 | msgstr "Suorita päätteessä" 253 | 254 | #: src/View/EditView.vala:145 255 | msgid "Turn on if you want to register a CUI app." 256 | msgstr "" 257 | 258 | #: src/View/EditView.vala:150 259 | msgid "Hide in Applications Menu" 260 | msgstr "" 261 | 262 | #: src/View/EditView.vala:151 263 | msgid "" 264 | "Useful when you won't launch the app by itself, but want to associate it " 265 | "with filetypes to open files with the app from file managers." 266 | msgstr "" 267 | 268 | #: src/View/EditView.vala:155 269 | msgid "_Open" 270 | msgstr "" 271 | 272 | #: src/View/EditView.vala:159 273 | #, fuzzy 274 | msgid "Open with Text Editor" 275 | msgstr "Avaa tekstimuokkaimessa" 276 | 277 | #: src/View/EditView.vala:160 278 | #, fuzzy 279 | msgid "You can also edit more options by opening with a text editor." 280 | msgstr "Voit muokata lisää valintoja avaamalla tekstimuokkaimen." 281 | 282 | #: src/View/EditView.vala:205 283 | msgid "New Entry" 284 | msgstr "Uusi tietue" 285 | 286 | #: src/View/EditView.vala:221 src/View/EditView.vala:429 287 | msgid "Untitled App" 288 | msgstr "" 289 | 290 | #: src/View/EditView.vala:241 291 | #, fuzzy 292 | msgid "Select Executable File" 293 | msgstr "Valitse suoritustiedosto" 294 | 295 | #: src/View/EditView.vala:242 src/View/EditView.vala:299 296 | #, fuzzy 297 | msgid "_Select" 298 | msgstr "Valitse" 299 | 300 | #: src/View/EditView.vala:295 301 | msgid "ICO, PNG, SVG, or XMP files" 302 | msgstr "ICO-, PNG-, SVG- tai XMP-tiedostot" 303 | 304 | #: src/View/EditView.vala:298 305 | #, fuzzy 306 | msgid "Select Icon File" 307 | msgstr "Valitse kuvaketiedosto" 308 | 309 | #: src/View/EditView.vala:397 310 | #, fuzzy 311 | msgid "Failed to Open with External App" 312 | msgstr "Ei voitu avata erillisellä sovelluksella" 313 | 314 | #: src/View/EditView.vala:398 315 | msgid "There was an error while opening the file with an external app." 316 | msgstr "" 317 | 318 | #: src/View/EditView.vala:453 319 | #, fuzzy 320 | msgid "Edit Entry" 321 | msgstr "Uusi tietue" 322 | 323 | #: src/View/EditView.vala:455 324 | #, fuzzy, c-format 325 | msgid "Edit “%s”" 326 | msgstr "Muokataan “%s”" 327 | 328 | #: src/View/EditView.vala:471 329 | msgid "Failed to Save Entry" 330 | msgstr "" 331 | 332 | #: src/View/EditView.vala:474 333 | #, c-format 334 | msgid "Failed to Save Entry of “%s”" 335 | msgstr "" 336 | 337 | #: src/View/EditView.vala:479 338 | msgid "There was an error while saving the app entry." 339 | msgstr "" 340 | 341 | #: src/View/FilesView.vala:32 342 | msgid "Create a new entry" 343 | msgstr "Luo uusi tietue" 344 | 345 | #: src/View/FilesView.vala:39 346 | #, fuzzy 347 | msgid "S_ystem" 348 | msgstr "Järjestelmä" 349 | 350 | #: src/View/FilesView.vala:40 351 | #, fuzzy 352 | msgid "_Light" 353 | msgstr "Vaalea" 354 | 355 | #: src/View/FilesView.vala:41 356 | #, fuzzy 357 | msgid "_Dark" 358 | msgstr "Tumma" 359 | 360 | #: src/View/FilesView.vala:44 361 | #, fuzzy 362 | msgid "_Style" 363 | msgstr "Tyyli" 364 | 365 | #: src/View/FilesView.vala:45 366 | msgid "_Keyboard Shortcuts" 367 | msgstr "" 368 | 369 | #. TRANSLATORS: %s will be replaced by the app name 370 | #: src/View/FilesView.vala:49 371 | #, fuzzy, c-format 372 | msgid "_About %s" 373 | msgstr "Tietoja - %s" 374 | 375 | #: src/View/FilesView.vala:53 376 | msgid "Main Menu" 377 | msgstr "" 378 | 379 | #: src/View/FilesView.vala:69 380 | msgid "No Entries Found" 381 | msgstr "" 382 | 383 | #: src/View/FilesView.vala:70 384 | msgid "Click the + button on the top to create one." 385 | msgstr "" 386 | 387 | #: src/View/FilesView.vala:117 388 | msgid "Delete…" 389 | msgstr "Poista…" 390 | 391 | #: src/View/FilesView.vala:154 392 | #, fuzzy 393 | msgid "Delete Entry?" 394 | msgstr "Uusi tietue" 395 | 396 | #: src/View/FilesView.vala:156 397 | #, c-format 398 | msgid "Delete Entry of “%s”?" 399 | msgstr "" 400 | 401 | #: src/View/FilesView.vala:161 402 | msgid "This removes the app from the launcher." 403 | msgstr "Tämä poistaa sovelluksen käynnistimestä." 404 | 405 | #: src/View/FilesView.vala:165 406 | #, fuzzy 407 | msgid "_Delete" 408 | msgstr "Poista" 409 | 410 | #: src/Widget/CategoriesRow.vala:63 411 | #, fuzzy 412 | msgid "Sound & Video" 413 | msgstr "Ääni ja video" 414 | 415 | #: src/Widget/CategoriesRow.vala:64 416 | msgid "Audio" 417 | msgstr "Ääni" 418 | 419 | #: src/Widget/CategoriesRow.vala:65 420 | msgid "Video" 421 | msgstr "Video" 422 | 423 | #: src/Widget/CategoriesRow.vala:66 424 | msgid "Programming" 425 | msgstr "" 426 | 427 | #: src/Widget/CategoriesRow.vala:67 428 | msgid "Education" 429 | msgstr "Koulutus" 430 | 431 | #: src/Widget/CategoriesRow.vala:68 432 | #, fuzzy 433 | msgid "Games" 434 | msgstr "Peli" 435 | 436 | #: src/Widget/CategoriesRow.vala:69 437 | msgid "Graphics" 438 | msgstr "Grafiikka" 439 | 440 | #: src/Widget/CategoriesRow.vala:70 441 | msgid "Internet" 442 | msgstr "" 443 | 444 | #: src/Widget/CategoriesRow.vala:71 445 | msgid "Office" 446 | msgstr "Toimisto" 447 | 448 | #: src/Widget/CategoriesRow.vala:72 449 | msgid "Science" 450 | msgstr "Tiede" 451 | 452 | #: src/Widget/CategoriesRow.vala:73 453 | msgid "Settings" 454 | msgstr "Asetukset" 455 | 456 | #: src/Widget/CategoriesRow.vala:74 457 | #, fuzzy 458 | msgid "System Tools" 459 | msgstr "Järjestelmä" 460 | 461 | #: src/Widget/CategoriesRow.vala:75 462 | msgid "Accessories" 463 | msgstr "" 464 | 465 | #: src/Widget/CategoriesRow.vala:82 466 | #, fuzzy 467 | msgid "Categories" 468 | msgstr "Sovellusluokat" 469 | 470 | #: src/Widget/CategoriesRow.vala:83 471 | msgid "Categories applicable to the app. (You can select more than one.)" 472 | msgstr "Sovellukseen soveltuvat luokat. (Voit valita enemmän kuin yhden)" 473 | 474 | #: src/Widget/KeywordsRow.vala:32 475 | msgid "Keyword" 476 | msgstr "" 477 | 478 | #: src/Widget/KeywordsRow.vala:36 479 | #, fuzzy 480 | msgid "Delete keyword" 481 | msgstr "Poista" 482 | 483 | #: src/Widget/KeywordsRow.vala:57 484 | msgid "Keywords" 485 | msgstr "" 486 | 487 | #: src/Widget/KeywordsRow.vala:58 488 | msgid "These words can be used as search terms." 489 | msgstr "" 490 | 491 | #: src/Widget/KeywordsRow.vala:63 492 | msgid "Add a new keyword" 493 | msgstr "" 494 | 495 | #~ msgid "Pin It!" 496 | #~ msgstr "Pin It!" 497 | 498 | #~ msgid "Ryo Nakano" 499 | #~ msgstr "Ryo Nakano" 500 | 501 | #, fuzzy 502 | #~ msgid "Support opening in a text editor" 503 | #~ msgstr "Voit muokata lisää valintoja avaamalla tekstimuokkaimen." 504 | 505 | #, c-format 506 | #~ msgid "Cannot open %s: %s" 507 | #~ msgstr "Ei voi avata %s: %s" 508 | 509 | #~ msgid "File Name" 510 | #~ msgstr "Tiedostonimi" 511 | 512 | #~ msgid "Name of the .desktop file, where this app's info will be saved." 513 | #~ msgstr "" 514 | #~ ".desktop-tiedoston nimi, johon tämän sovelluksen tiedot tallennetaan." 515 | 516 | #~ msgid "Suffix of the file" 517 | #~ msgstr "Tiedostopääte" 518 | 519 | #, c-format 520 | #~ msgid "Could not write to file “%s”" 521 | #~ msgstr "Tiedostoon “%s” ei voitu kirjoittaa" 522 | 523 | #~ msgid "Recommendations for naming" 524 | #~ msgstr "Suositukset nimeämiseen" 525 | 526 | #~ msgid "Preferences" 527 | #~ msgstr "Asetukset" 528 | 529 | #~ msgid "If you've never created one, click the + button on the top." 530 | #~ msgstr "Jos et ole luonut yhtäkään, napsauta ylhäältä +." 531 | 532 | #, c-format 533 | #~ msgid "Are you sure you want to delete “%s”?" 534 | #~ msgstr "Haluatko varmasti poistaa “%s”?" 535 | 536 | #~ msgid "Development" 537 | #~ msgstr "Kehitys" 538 | 539 | #~ msgid "Network" 540 | #~ msgstr "Verkko" 541 | 542 | #~ msgid "Utility" 543 | #~ msgstr "Työkalu" 544 | -------------------------------------------------------------------------------- /po/hi.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the com.github.ryonakano.pinit package. 4 | # Scrambled777 , 2024. 5 | # Fill read-only add-on , 2024. 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: com.github.ryonakano.pinit\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2025-03-16 19:27+0900\n" 11 | "PO-Revision-Date: 2024-05-16 15:02+0000\n" 12 | "Last-Translator: Scrambled777 \n" 13 | "Language-Team: Hindi \n" 14 | "Language: hi\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Plural-Forms: nplurals=2; plural=n > 1;\n" 19 | "X-Generator: Weblate 5.6-dev\n" 20 | 21 | #: data/pinit.desktop.in.in:3 22 | msgid "@APP_NAME@" 23 | msgstr "@APP_NAME@" 24 | 25 | #: data/pinit.desktop.in.in:4 26 | msgid "Desktop File Creator" 27 | msgstr "डेस्कटॉप फाइल निर्माता" 28 | 29 | #: data/pinit.desktop.in.in:5 data/pinit.metainfo.xml.in.in:11 30 | msgid "Pin portable apps to the launcher" 31 | msgstr "पोर्टेबल ऐप्स को लॉन्चर पर पिन करें" 32 | 33 | #: data/pinit.desktop.in.in:11 34 | msgid "Desktop;File;Create;Edit;Info;Icon;AppImage;" 35 | msgstr "डेस्कटॉप;फाइल;बनाएं;संपादित करें;जानकारी;आइकन;AppImage;" 36 | 37 | #: data/pinit.metainfo.xml.in.in:13 38 | msgid "" 39 | "Pin shortcuts for portable apps like raw executable files, AppImage files, " 40 | "etc. to the app launcher on your desktop." 41 | msgstr "" 42 | "अपने डेस्कटॉप पर ऐप लॉन्चर पर पोर्टेबल ऐप्स जैसे रॉ निष्पादन-योग्य फाइलें, AppImage फाइलें " 43 | "इत्यादि के लिए शॉर्टकट पिन करें।" 44 | 45 | #: data/pinit.metainfo.xml.in.in:16 46 | msgid "Other features include:" 47 | msgstr "अन्य विशेषताओं में शामिल हैं:" 48 | 49 | #: data/pinit.metainfo.xml.in.in:20 50 | msgid "Edit or delete created app entries without opening the file manager" 51 | msgstr "फाइल प्रबंधक खोले बिना बनाई गई ऐप प्रविष्टियां संपादित करें या मिटाएं" 52 | 53 | #: data/pinit.metainfo.xml.in.in:21 54 | msgid "Automatically add the execute permission to the file you select" 55 | msgstr "आपके द्वारा चुनी गई फाइल में स्वचालित रूप से निष्पादन अनुमति जोड़ें" 56 | 57 | #: data/pinit.metainfo.xml.in.in:27 58 | msgid "App window in the light mode" 59 | msgstr "ऐप खिड़की हल्के मोड में" 60 | 61 | #: data/pinit.metainfo.xml.in.in:32 62 | msgid "App window in the dark mode" 63 | msgstr "ऐप खिड़की गहरे मोड में" 64 | 65 | #: data/ui/help-overlay.blp:10 66 | msgctxt "shortcut window" 67 | msgid "General" 68 | msgstr "सामान्य" 69 | 70 | #: data/ui/help-overlay.blp:14 71 | msgctxt "shortcut window" 72 | msgid "Keyboard Shortcuts" 73 | msgstr "कीबोर्ड शॉर्टकट" 74 | 75 | #: data/ui/help-overlay.blp:19 76 | msgctxt "shortcut window" 77 | msgid "Quit" 78 | msgstr "छोड़ें" 79 | 80 | #: data/ui/help-overlay.blp:24 81 | msgctxt "shortcut window" 82 | msgid "Edit" 83 | msgstr "संपादित करें" 84 | 85 | #: data/ui/help-overlay.blp:28 86 | msgctxt "shortcut window" 87 | msgid "New Entry" 88 | msgstr "नई प्रविष्टि" 89 | 90 | #. TRANSLATORS: A newline-separated list of translators. Don't translate literally. 91 | #. You can optionally add your name if you want, plus you may add your email address or website. 92 | #. e.g.: 93 | #. John Doe 94 | #. John Doe 95 | #. John Doe https://example.com 96 | #: src/Application.vala:310 97 | msgid "translator-credits" 98 | msgstr "Scrambled777 " 99 | 100 | #: src/MainWindow.vala:78 101 | #, c-format 102 | msgid "Failed to Delete Entry of “%s”" 103 | msgstr "“%s” की प्रविष्टि मिटाने में विफल" 104 | 105 | #: src/MainWindow.vala:79 106 | msgid "There was an error while removing the app entry." 107 | msgstr "ऐप प्रविष्टि हटाते समय त्रुटि हुई।" 108 | 109 | #: src/MainWindow.vala:82 src/MainWindow.vala:132 src/View/EditView.vala:400 110 | #: src/View/EditView.vala:481 111 | msgid "_Close" 112 | msgstr "बंद करें (_C)" 113 | 114 | #: src/MainWindow.vala:93 115 | msgid "Entry deleted." 116 | msgstr "प्रविष्टि मिटाई गई।" 117 | 118 | #: src/MainWindow.vala:106 119 | msgid "Entry updated." 120 | msgstr "प्रविष्टि अद्यतित।" 121 | 122 | #: src/MainWindow.vala:129 123 | msgid "Failed to Load Entries" 124 | msgstr "प्रविष्टियां लोड करने में विफल" 125 | 126 | #: src/MainWindow.vala:130 127 | msgid "There was an error while loading app entries." 128 | msgstr "ऐप प्रविष्टियां लोड करते समय एक त्रुटि हुई।" 129 | 130 | #: src/MainWindow.vala:158 131 | msgid "Save Changes?" 132 | msgstr "परिवर्तन सहेजें?" 133 | 134 | #: src/MainWindow.vala:159 135 | msgid "" 136 | "Open entries contain unsaved changes. Changes which are not saved will be " 137 | "permanently lost." 138 | msgstr "" 139 | "खुली प्रविष्टियों में सहेजे न गए परिवर्तन शामिल हैं। जो परिवर्तन सहेजे नहीं गए वे स्थायी रूप से " 140 | "नष्ट हो जाएंगे।" 141 | 142 | #: src/MainWindow.vala:163 src/View/FilesView.vala:164 143 | msgid "_Cancel" 144 | msgstr "रद्द करें (_C)" 145 | 146 | #: src/MainWindow.vala:164 147 | msgid "_Discard" 148 | msgstr "त्यागें (_D)" 149 | 150 | #: src/MainWindow.vala:165 src/View/EditView.vala:40 151 | msgid "_Save" 152 | msgstr "सहेजें (_S)" 153 | 154 | #: src/View/EditView.vala:69 155 | msgid "Required Fields" 156 | msgstr "आवश्यक क्षेत्र" 157 | 158 | #: src/View/EditView.vala:70 159 | msgid "The following fields need to be filled to save." 160 | msgstr "सहेजने के लिए निम्नलिखित क्षेत्र भरने की आवश्यकता है।" 161 | 162 | #: src/View/EditView.vala:74 163 | msgid "App Name" 164 | msgstr "ऐप नाम" 165 | 166 | #: src/View/EditView.vala:75 167 | msgid "Shown in the launcher or dock." 168 | msgstr "लॉन्चर या डॉक में दिखाया गया।" 169 | 170 | #: src/View/EditView.vala:80 171 | msgid "Exec File" 172 | msgstr "निष्पादन फाइल" 173 | 174 | #: src/View/EditView.vala:81 175 | msgid "" 176 | "The command/app launched when you click the app entry in the launcher. " 177 | "Specify in an absolute path or an app's alias name." 178 | msgstr "" 179 | "जब आप लॉन्चर में ऐप प्रविष्टि पर क्लिक करते हैं तो कमांड/ऐप लॉन्च होता है। निरपेक्ष पथ या " 180 | "ऐप के उपनाम नाम में निर्दिष्ट करें।" 181 | 182 | #: src/View/EditView.vala:84 183 | msgid "Select an executable file…" 184 | msgstr "निष्पादन-योग्य फाइल चुनें…" 185 | 186 | #: src/View/EditView.vala:95 187 | msgid "Optional Fields" 188 | msgstr "वैकल्पिक क्षेत्र" 189 | 190 | #: src/View/EditView.vala:96 191 | msgid "Filling these fields improves discoverability in the app launcher." 192 | msgstr "इन क्षेत्र को भरने से ऐप लॉन्चर में खोज योग्यता में सुधार होता है।" 193 | 194 | #: src/View/EditView.vala:100 195 | msgid "Icon File" 196 | msgstr "आइकन फाइल" 197 | 198 | #: src/View/EditView.vala:101 199 | msgid "" 200 | "The icon branding the app. Specify in an absolute path or an icon's alias " 201 | "name." 202 | msgstr "" 203 | "ऐप की ब्रांडिंग करने वाला आइकन। किसी पूर्ण पथ या आइकन के उपनाम नाम में निर्दिष्ट करें।" 204 | 205 | #: src/View/EditView.vala:104 206 | msgid "Select an icon file…" 207 | msgstr "आइकन फाइल चुनें…" 208 | 209 | #: src/View/EditView.vala:112 210 | msgid "Generic Name" 211 | msgstr "सामान्य नाम" 212 | 213 | #: src/View/EditView.vala:113 214 | msgid "" 215 | "Generic name of the app, for example \"Web Browser\" or \"Mail Client\"." 216 | msgstr "ऐप का सामान्य नाम, उदाहरण के लिए \"वेब ब्राउज़र\" या \"मेल क्लाइंट\"।" 217 | 218 | #: src/View/EditView.vala:118 219 | msgid "Comment" 220 | msgstr "टिप्पणी" 221 | 222 | #: src/View/EditView.vala:119 223 | msgid "" 224 | "Descibes the app. May appear as a tooltip when you hover over the app entry " 225 | "in the launcher/dock." 226 | msgstr "" 227 | "ऐप का वर्णन करता है। जब आप लॉन्चर/डॉक में ऐप प्रविष्टि पर मंडराते हैं तो यह टूलटिप के रूप " 228 | "में दिखाई दे सकता है।" 229 | 230 | #: src/View/EditView.vala:133 231 | msgid "Advanced Configurations" 232 | msgstr "उन्नत विन्यास" 233 | 234 | #: src/View/EditView.vala:134 235 | msgid "" 236 | "You can create most app entries just by filling in the sections above. " 237 | "However, some apps may require the advanced configuration options below." 238 | msgstr "" 239 | "आप उपरोक्त अनुभागों को भरकर अधिकांश ऐप प्रविष्टियां बना सकते हैं। हालांकि, कुछ ऐप्स को " 240 | "नीचे दिए गए उन्नत विन्यास विकल्पों की आवश्यकता हो सकती है।" 241 | 242 | #: src/View/EditView.vala:138 243 | msgid "Startup WM Class" 244 | msgstr "स्टार्टअप WM क्लास" 245 | 246 | #: src/View/EditView.vala:139 247 | msgid "" 248 | "Associate the app with a window that has this ID. Use this if a different or " 249 | "duplicated icon appears in the dock when the app launches." 250 | msgstr "" 251 | "ऐप को उस विंडो से संबद्ध करें जिसमें यह ID है। यदि ऐप लॉन्च होने पर डॉक में कोई भिन्न या " 252 | "डुप्लिकेट आइकन दिखाई देता है तो इसका उपयोग करें।" 253 | 254 | #: src/View/EditView.vala:144 255 | msgid "Run in Terminal" 256 | msgstr "टर्मिनल में चलाएं" 257 | 258 | #: src/View/EditView.vala:145 259 | msgid "Turn on if you want to register a CUI app." 260 | msgstr "यदि आप CUI ऐप पंजीकृत करना चाहते हैं तो चालू करें।" 261 | 262 | #: src/View/EditView.vala:150 263 | msgid "Hide in Applications Menu" 264 | msgstr "" 265 | 266 | #: src/View/EditView.vala:151 267 | msgid "" 268 | "Useful when you won't launch the app by itself, but want to associate it " 269 | "with filetypes to open files with the app from file managers." 270 | msgstr "" 271 | 272 | #: src/View/EditView.vala:155 273 | msgid "_Open" 274 | msgstr "खोलें (_O)" 275 | 276 | #: src/View/EditView.vala:159 277 | msgid "Open with Text Editor" 278 | msgstr "पाठ संपादक के साथ खोलें" 279 | 280 | #: src/View/EditView.vala:160 281 | msgid "You can also edit more options by opening with a text editor." 282 | msgstr "आप पाठ संपादक से खोलकर अधिक विकल्प भी संपादित कर सकते हैं।" 283 | 284 | #: src/View/EditView.vala:205 285 | msgid "New Entry" 286 | msgstr "नई प्रविष्टि" 287 | 288 | #: src/View/EditView.vala:221 src/View/EditView.vala:429 289 | msgid "Untitled App" 290 | msgstr "शीर्षकहीन ऐप" 291 | 292 | #: src/View/EditView.vala:241 293 | msgid "Select Executable File" 294 | msgstr "निष्पादन-योग्य फाइल चुनें" 295 | 296 | #: src/View/EditView.vala:242 src/View/EditView.vala:299 297 | msgid "_Select" 298 | msgstr "चुनें (_S)" 299 | 300 | #: src/View/EditView.vala:295 301 | msgid "ICO, PNG, SVG, or XMP files" 302 | msgstr "ICO, PNG, SVG, या XMP फाइलें" 303 | 304 | #: src/View/EditView.vala:298 305 | msgid "Select Icon File" 306 | msgstr "आइकन फाइल चुनें" 307 | 308 | #: src/View/EditView.vala:397 309 | msgid "Failed to Open with External App" 310 | msgstr "बाहरी ऐप से खुलने में विफल" 311 | 312 | #: src/View/EditView.vala:398 313 | msgid "There was an error while opening the file with an external app." 314 | msgstr "बाहरी ऐप से फाइल खोलते समय एक त्रुटि हुई।" 315 | 316 | #: src/View/EditView.vala:453 317 | msgid "Edit Entry" 318 | msgstr "प्रविष्टि संपादित करें" 319 | 320 | #: src/View/EditView.vala:455 321 | #, c-format 322 | msgid "Edit “%s”" 323 | msgstr "“%s” संपादित करें" 324 | 325 | #: src/View/EditView.vala:471 326 | msgid "Failed to Save Entry" 327 | msgstr "प्रविष्टि सहेजने में विफल" 328 | 329 | #: src/View/EditView.vala:474 330 | #, c-format 331 | msgid "Failed to Save Entry of “%s”" 332 | msgstr "“%s” की प्रविष्टि सहेजने में विफल" 333 | 334 | #: src/View/EditView.vala:479 335 | msgid "There was an error while saving the app entry." 336 | msgstr "ऐप प्रविष्टि सहेजते समय त्रुटि हुई।" 337 | 338 | #: src/View/FilesView.vala:32 339 | msgid "Create a new entry" 340 | msgstr "नई प्रविष्टि बनाएं" 341 | 342 | #: src/View/FilesView.vala:39 343 | msgid "S_ystem" 344 | msgstr "सिस्टम (_y)" 345 | 346 | #: src/View/FilesView.vala:40 347 | msgid "_Light" 348 | msgstr "हल्की (_L)" 349 | 350 | #: src/View/FilesView.vala:41 351 | msgid "_Dark" 352 | msgstr "गहरी (_D)" 353 | 354 | #: src/View/FilesView.vala:44 355 | msgid "_Style" 356 | msgstr "शैली (_S)" 357 | 358 | #: src/View/FilesView.vala:45 359 | msgid "_Keyboard Shortcuts" 360 | msgstr "कीबोर्ड शॉर्टकट (_K)" 361 | 362 | #. TRANSLATORS: %s will be replaced by the app name 363 | #: src/View/FilesView.vala:49 364 | #, c-format 365 | msgid "_About %s" 366 | msgstr "%s के बारे में (_A)" 367 | 368 | #: src/View/FilesView.vala:53 369 | msgid "Main Menu" 370 | msgstr "मुख्य मेनू" 371 | 372 | #: src/View/FilesView.vala:69 373 | msgid "No Entries Found" 374 | msgstr "कोई प्रविष्टियां नहीं मिलीं" 375 | 376 | #: src/View/FilesView.vala:70 377 | msgid "Click the + button on the top to create one." 378 | msgstr "बनाने के लिए शीर्ष पर + बटन पर क्लिक करें।" 379 | 380 | #: src/View/FilesView.vala:117 381 | msgid "Delete…" 382 | msgstr "मिटाएं…" 383 | 384 | #: src/View/FilesView.vala:154 385 | msgid "Delete Entry?" 386 | msgstr "प्रविष्टि मिटाएं?" 387 | 388 | #: src/View/FilesView.vala:156 389 | #, c-format 390 | msgid "Delete Entry of “%s”?" 391 | msgstr "“%s” की प्रविष्टि मिटाएं?" 392 | 393 | #: src/View/FilesView.vala:161 394 | msgid "This removes the app from the launcher." 395 | msgstr "यह ऐप को लॉन्चर से हटा देता है।" 396 | 397 | #: src/View/FilesView.vala:165 398 | msgid "_Delete" 399 | msgstr "मिटाएं (_D)" 400 | 401 | #: src/Widget/CategoriesRow.vala:63 402 | msgid "Sound & Video" 403 | msgstr "ध्वनि & वीडियो" 404 | 405 | #: src/Widget/CategoriesRow.vala:64 406 | msgid "Audio" 407 | msgstr "ऑडियो" 408 | 409 | #: src/Widget/CategoriesRow.vala:65 410 | msgid "Video" 411 | msgstr "वीडियो" 412 | 413 | #: src/Widget/CategoriesRow.vala:66 414 | msgid "Programming" 415 | msgstr "प्रोग्रामिंग" 416 | 417 | #: src/Widget/CategoriesRow.vala:67 418 | msgid "Education" 419 | msgstr "शिक्षा" 420 | 421 | #: src/Widget/CategoriesRow.vala:68 422 | msgid "Games" 423 | msgstr "खेल" 424 | 425 | #: src/Widget/CategoriesRow.vala:69 426 | msgid "Graphics" 427 | msgstr "चित्रोपमा" 428 | 429 | #: src/Widget/CategoriesRow.vala:70 430 | msgid "Internet" 431 | msgstr "इंटरनेट" 432 | 433 | #: src/Widget/CategoriesRow.vala:71 434 | msgid "Office" 435 | msgstr "कार्यालय" 436 | 437 | #: src/Widget/CategoriesRow.vala:72 438 | msgid "Science" 439 | msgstr "विज्ञान" 440 | 441 | #: src/Widget/CategoriesRow.vala:73 442 | msgid "Settings" 443 | msgstr "सेटिंग" 444 | 445 | #: src/Widget/CategoriesRow.vala:74 446 | msgid "System Tools" 447 | msgstr "सिस्टम औजार" 448 | 449 | #: src/Widget/CategoriesRow.vala:75 450 | msgid "Accessories" 451 | msgstr "सहायक सामग्री" 452 | 453 | #: src/Widget/CategoriesRow.vala:82 454 | msgid "Categories" 455 | msgstr "श्रेणियां" 456 | 457 | #: src/Widget/CategoriesRow.vala:83 458 | msgid "Categories applicable to the app. (You can select more than one.)" 459 | msgstr "ऐप पर लागू श्रेणियां। (आप एक से अधिक का चयन कर सकते हैं।)" 460 | 461 | #: src/Widget/KeywordsRow.vala:32 462 | msgid "Keyword" 463 | msgstr "खोजशब्द" 464 | 465 | #: src/Widget/KeywordsRow.vala:36 466 | msgid "Delete keyword" 467 | msgstr "खोजशब्द मिटाएं" 468 | 469 | #: src/Widget/KeywordsRow.vala:57 470 | msgid "Keywords" 471 | msgstr "खोजशब्द" 472 | 473 | #: src/Widget/KeywordsRow.vala:58 474 | msgid "These words can be used as search terms." 475 | msgstr "इन शब्दों का उपयोग खोज शब्दों के रूप में किया जा सकता है।" 476 | 477 | #: src/Widget/KeywordsRow.vala:63 478 | msgid "Add a new keyword" 479 | msgstr "नया खोजशब्द जोड़ें" 480 | -------------------------------------------------------------------------------- /po/meson.build: -------------------------------------------------------------------------------- 1 | i18n.gettext(meson.project_name(), 2 | args: [ 3 | '--directory=' + meson.project_source_root(), 4 | '--from-code=UTF-8', 5 | '-cTRANSLATORS' 6 | ], 7 | preset: 'glib' 8 | ) 9 | -------------------------------------------------------------------------------- /po/ta.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the com.github.ryonakano.pinit package. 4 | # தமிழ்நேரம் , 2025. 5 | # Fill read-only add-on , 2025. 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: com.github.ryonakano.pinit\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2025-03-16 19:27+0900\n" 11 | "PO-Revision-Date: 2025-04-20 23:37+0000\n" 12 | "Last-Translator: தமிழ்நேரம் \n" 13 | "Language-Team: Tamil \n" 14 | "Language: ta\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Plural-Forms: nplurals=2; plural=n != 1;\n" 19 | "X-Generator: Weblate 5.11.1-dev\n" 20 | 21 | #: data/pinit.desktop.in.in:3 22 | msgid "@APP_NAME@" 23 | msgstr "@APP_NAME@" 24 | 25 | #: data/pinit.desktop.in.in:4 26 | msgid "Desktop File Creator" 27 | msgstr "டெச்க்டாப் கோப்பு உருவாக்கியவர்" 28 | 29 | #: data/pinit.desktop.in.in:5 data/pinit.metainfo.xml.in.in:11 30 | msgid "Pin portable apps to the launcher" 31 | msgstr "சிறிய பயன்பாடுகளை துவக்கிக்கு முள்" 32 | 33 | #: data/pinit.desktop.in.in:11 34 | msgid "Desktop;File;Create;Edit;Info;Icon;AppImage;" 35 | msgstr "டெச்க்டாப்; கோப்பு; உருவாக்கு; திருத்து; தகவல்; ஐகான்; அபிமேச்;" 36 | 37 | #: data/pinit.metainfo.xml.in.in:13 38 | msgid "" 39 | "Pin shortcuts for portable apps like raw executable files, AppImage files, " 40 | "etc. to the app launcher on your desktop." 41 | msgstr "" 42 | "உங்கள் டெச்க்டாப்பில் உள்ள பயன்பாட்டு துவக்கிக்கு மூல இயங்கக்கூடிய கோப்புகள், அபிமேச் " 43 | "கோப்புகள் போன்ற சிறிய பயன்பாடுகளுக்கான குறுக்குவழிகள்." 44 | 45 | #: data/pinit.metainfo.xml.in.in:16 46 | msgid "Other features include:" 47 | msgstr "பிற நற்பொருத்தங்கள் பின்வருமாறு:" 48 | 49 | #: data/pinit.metainfo.xml.in.in:20 50 | msgid "Edit or delete created app entries without opening the file manager" 51 | msgstr "" 52 | "கோப்பு மேலாளரைத் திறக்காமல் உருவாக்கிய பயன்பாட்டு உள்ளீடுகளைத் திருத்தவும் அல்லது நீக்கவும்" 53 | 54 | #: data/pinit.metainfo.xml.in.in:21 55 | msgid "Automatically add the execute permission to the file you select" 56 | msgstr "நீங்கள் தேர்ந்தெடுக்கும் கோப்பில் தானாகவே இயக்க அனுமதியைச் சேர்க்கவும்" 57 | 58 | #: data/pinit.metainfo.xml.in.in:27 59 | msgid "App window in the light mode" 60 | msgstr "ஒளி பயன்முறையில் பயன்பாட்டு சாளரம்" 61 | 62 | #: data/pinit.metainfo.xml.in.in:32 63 | msgid "App window in the dark mode" 64 | msgstr "இருண்ட பயன்முறையில் பயன்பாட்டு சாளரம்" 65 | 66 | #: data/ui/help-overlay.blp:10 67 | msgctxt "shortcut window" 68 | msgid "General" 69 | msgstr "பொது" 70 | 71 | #: data/ui/help-overlay.blp:14 72 | msgctxt "shortcut window" 73 | msgid "Keyboard Shortcuts" 74 | msgstr "விசைப்பலகை குறுக்குவழிகள்" 75 | 76 | #: data/ui/help-overlay.blp:19 77 | msgctxt "shortcut window" 78 | msgid "Quit" 79 | msgstr "வெளியேறு" 80 | 81 | #: data/ui/help-overlay.blp:24 82 | msgctxt "shortcut window" 83 | msgid "Edit" 84 | msgstr "தொகு" 85 | 86 | #: data/ui/help-overlay.blp:28 87 | msgctxt "shortcut window" 88 | msgid "New Entry" 89 | msgstr "புதிய நுழைவு" 90 | 91 | #. TRANSLATORS: A newline-separated list of translators. Don't translate literally. 92 | #. You can optionally add your name if you want, plus you may add your email address or website. 93 | #. e.g.: 94 | #. John Doe 95 | #. John Doe 96 | #. John Doe https://example.com 97 | #: src/Application.vala:310 98 | msgid "translator-credits" 99 | msgstr "மொழிபெயர்ப்பாளர்-வரவு" 100 | 101 | #: src/MainWindow.vala:78 102 | #, c-format 103 | msgid "Failed to Delete Entry of “%s”" 104 | msgstr "“%s” இன் நுழைவை நீக்கத் தவறிவிட்டது" 105 | 106 | #: src/MainWindow.vala:79 107 | msgid "There was an error while removing the app entry." 108 | msgstr "பயன்பாட்டு உள்ளீட்டை அகற்றும்போது பிழை ஏற்பட்டது." 109 | 110 | #: src/MainWindow.vala:82 src/MainWindow.vala:132 src/View/EditView.vala:400 111 | #: src/View/EditView.vala:481 112 | msgid "_Close" 113 | msgstr "மூடு (_C)" 114 | 115 | #: src/MainWindow.vala:93 116 | msgid "Entry deleted." 117 | msgstr "நுழைவு நீக்கப்பட்டது." 118 | 119 | #: src/MainWindow.vala:106 120 | msgid "Entry updated." 121 | msgstr "நுழைவு புதுப்பிக்கப்பட்டது." 122 | 123 | #: src/MainWindow.vala:129 124 | msgid "Failed to Load Entries" 125 | msgstr "உள்ளீடுகளை ஏற்றுவதில் தோல்வி" 126 | 127 | #: src/MainWindow.vala:130 128 | msgid "There was an error while loading app entries." 129 | msgstr "பயன்பாட்டு உள்ளீடுகளை ஏற்றும்போது பிழை ஏற்பட்டது." 130 | 131 | #: src/MainWindow.vala:158 132 | msgid "Save Changes?" 133 | msgstr "மாற்றங்களைச் சேமிக்கவா?" 134 | 135 | #: src/MainWindow.vala:159 136 | msgid "" 137 | "Open entries contain unsaved changes. Changes which are not saved will be " 138 | "permanently lost." 139 | msgstr "" 140 | "திறந்த உள்ளீடுகளில் சேமிக்கப்படாத மாற்றங்கள் உள்ளன. சேமிக்கப்படாத மாற்றங்கள் நிரந்தரமாக " 141 | "இழக்கப்படும்." 142 | 143 | #: src/MainWindow.vala:163 src/View/FilesView.vala:164 144 | msgid "_Cancel" 145 | msgstr "_CANCEL" 146 | 147 | #: src/MainWindow.vala:164 148 | msgid "_Discard" 149 | msgstr "_ டிச்கார்ட்" 150 | 151 | #: src/MainWindow.vala:165 src/View/EditView.vala:40 152 | msgid "_Save" 153 | msgstr "_சேவ்" 154 | 155 | #: src/View/EditView.vala:69 156 | msgid "Required Fields" 157 | msgstr "தேவையான புலங்கள்" 158 | 159 | #: src/View/EditView.vala:70 160 | msgid "The following fields need to be filled to save." 161 | msgstr "சேமிக்க பின்வரும் புலங்கள் நிரப்பப்பட வேண்டும்." 162 | 163 | #: src/View/EditView.vala:74 164 | msgid "App Name" 165 | msgstr "பயன்பாட்டு பெயர்" 166 | 167 | #: src/View/EditView.vala:75 168 | msgid "Shown in the launcher or dock." 169 | msgstr "துவக்கி அல்லது கப்பல்துறையில் காட்டப்பட்டுள்ளது." 170 | 171 | #: src/View/EditView.vala:80 172 | msgid "Exec File" 173 | msgstr "EXEC கோப்பு" 174 | 175 | #: src/View/EditView.vala:81 176 | msgid "" 177 | "The command/app launched when you click the app entry in the launcher. " 178 | "Specify in an absolute path or an app's alias name." 179 | msgstr "" 180 | "துவக்கத்தில் பயன்பாட்டு உள்ளீட்டைக் சொடுக்கு செய்யும் போது கட்டளை/பயன்பாடு தொடங்கப்பட்டது. " 181 | "ஒரு முழுமையான பாதை அல்லது பயன்பாட்டின் மாற்றுப்பெயர் பெயரில் குறிப்பிடவும்." 182 | 183 | #: src/View/EditView.vala:84 184 | msgid "Select an executable file…" 185 | msgstr "இயங்கக்கூடிய கோப்பைத் தேர்ந்தெடுக்கவும்…" 186 | 187 | #: src/View/EditView.vala:95 188 | msgid "Optional Fields" 189 | msgstr "விருப்ப புலங்கள்" 190 | 191 | #: src/View/EditView.vala:96 192 | msgid "Filling these fields improves discoverability in the app launcher." 193 | msgstr "இந்த புலங்களை நிரப்புவது பயன்பாட்டு துவக்கத்தில் கண்டுபிடிப்பதை மேம்படுத்துகிறது." 194 | 195 | #: src/View/EditView.vala:100 196 | msgid "Icon File" 197 | msgstr "படவுரு கோப்பு" 198 | 199 | #: src/View/EditView.vala:101 200 | msgid "" 201 | "The icon branding the app. Specify in an absolute path or an icon's alias " 202 | "name." 203 | msgstr "" 204 | "படவுரு பயன்பாட்டை முத்திரை குத்துகிறது. ஒரு முழுமையான பாதை அல்லது ஒரு ஐகானின் " 205 | "மாற்றுப்பெயர் பெயரில் குறிப்பிடவும்." 206 | 207 | #: src/View/EditView.vala:104 208 | msgid "Select an icon file…" 209 | msgstr "ஒரு படவுரு கோப்பைத் தேர்ந்தெடுக்கவும்…" 210 | 211 | #: src/View/EditView.vala:112 212 | msgid "Generic Name" 213 | msgstr "பொதுவான பெயர்" 214 | 215 | #: src/View/EditView.vala:113 216 | msgid "" 217 | "Generic name of the app, for example \"Web Browser\" or \"Mail Client\"." 218 | msgstr "" 219 | "பயன்பாட்டின் பொதுவான பெயர், எடுத்துக்காட்டாக \"வலை உலாவி\" அல்லது \"அஞ்சல் கிளையண்ட்\"." 220 | 221 | #: src/View/EditView.vala:118 222 | msgid "Comment" 223 | msgstr "கருத்து" 224 | 225 | #: src/View/EditView.vala:119 226 | msgid "" 227 | "Descibes the app. May appear as a tooltip when you hover over the app entry " 228 | "in the launcher/dock." 229 | msgstr "" 230 | "பயன்பாட்டை விவரிக்கிறது. துவக்கி/கப்பல்துறையில் பயன்பாட்டு நுழைவுக்கு மேல் நீங்கள் " 231 | "வட்டமிடும்போது ஒரு உதவிக்குறிப்பாக தோன்றலாம்." 232 | 233 | #: src/View/EditView.vala:133 234 | msgid "Advanced Configurations" 235 | msgstr "மேம்பட்ட உள்ளமைவுகள்" 236 | 237 | #: src/View/EditView.vala:134 238 | msgid "" 239 | "You can create most app entries just by filling in the sections above. " 240 | "However, some apps may require the advanced configuration options below." 241 | msgstr "" 242 | "மேலே உள்ள பிரிவுகளை நிரப்புவதன் மூலம் பெரும்பாலான பயன்பாட்டு உள்ளீடுகளை உருவாக்கலாம். " 243 | "இருப்பினும், சில பயன்பாடுகளுக்கு கீழே மேம்பட்ட உள்ளமைவு விருப்பங்கள் தேவைப்படலாம்." 244 | 245 | #: src/View/EditView.vala:138 246 | msgid "Startup WM Class" 247 | msgstr "தொடக்க WM வகுப்பு" 248 | 249 | #: src/View/EditView.vala:139 250 | msgid "" 251 | "Associate the app with a window that has this ID. Use this if a different or " 252 | "duplicated icon appears in the dock when the app launches." 253 | msgstr "" 254 | "இந்த ஐடியைக் கொண்ட ஒரு சாளரத்துடன் பயன்பாட்டை இணைக்கவும். பயன்பாடு தொடங்கும்போது " 255 | "கப்பல்துறையில் வேறு அல்லது நகல் படவுரு தோன்றினால் இதைப் பயன்படுத்தவும்." 256 | 257 | #: src/View/EditView.vala:144 258 | msgid "Run in Terminal" 259 | msgstr "முனையத்தில் இயக்கவும்" 260 | 261 | #: src/View/EditView.vala:145 262 | msgid "Turn on if you want to register a CUI app." 263 | msgstr "நீங்கள் ஒரு CUI பயன்பாட்டை பதிவு செய்ய விரும்பினால் இயக்கவும்." 264 | 265 | #: src/View/EditView.vala:150 266 | msgid "Hide in Applications Menu" 267 | msgstr "பயன்பாடுகள் பட்டியலில் மறை" 268 | 269 | #: src/View/EditView.vala:151 270 | msgid "" 271 | "Useful when you won't launch the app by itself, but want to associate it " 272 | "with filetypes to open files with the app from file managers." 273 | msgstr "" 274 | "நீங்கள் பயன்பாட்டைத் தானே தொடங்காமல், கோப்பு மேலாளர்களிடமிருந்து பயன்பாட்டுடன் கோப்புகளைத் " 275 | "திறக்க கோப்பு வகைகளுடன் அதை இணைக்க விரும்பும் போது பயனுள்ளதாக இருக்கும்." 276 | 277 | #: src/View/EditView.vala:155 278 | msgid "_Open" 279 | msgstr "_OPEN" 280 | 281 | #: src/View/EditView.vala:159 282 | msgid "Open with Text Editor" 283 | msgstr "உரை எடிட்டருடன் திறக்கவும்" 284 | 285 | #: src/View/EditView.vala:160 286 | msgid "You can also edit more options by opening with a text editor." 287 | msgstr "உரை எடிட்டருடன் திறப்பதன் மூலம் கூடுதல் விருப்பங்களையும் திருத்தலாம்." 288 | 289 | #: src/View/EditView.vala:205 290 | msgid "New Entry" 291 | msgstr "புதிய நுழைவு" 292 | 293 | #: src/View/EditView.vala:221 src/View/EditView.vala:429 294 | msgid "Untitled App" 295 | msgstr "பெயரிடப்படாத பயன்பாடு" 296 | 297 | #: src/View/EditView.vala:241 298 | msgid "Select Executable File" 299 | msgstr "இயங்கக்கூடிய கோப்பைத் தேர்ந்தெடுக்கவும்" 300 | 301 | #: src/View/EditView.vala:242 src/View/EditView.vala:299 302 | msgid "_Select" 303 | msgstr "_ தேர்ந்தெடுக்கவும்" 304 | 305 | #: src/View/EditView.vala:295 306 | msgid "ICO, PNG, SVG, or XMP files" 307 | msgstr "ஐ.சி.ஓ, பி.என்.சி, எச்.வி.சி அல்லது எக்ச்எம்பி கோப்புகள்" 308 | 309 | #: src/View/EditView.vala:298 310 | msgid "Select Icon File" 311 | msgstr "படவுரு கோப்பைத் தேர்ந்தெடுக்கவும்" 312 | 313 | #: src/View/EditView.vala:397 314 | msgid "Failed to Open with External App" 315 | msgstr "வெளிப்புற பயன்பாட்டுடன் திறக்கத் தவறிவிட்டது" 316 | 317 | #: src/View/EditView.vala:398 318 | msgid "There was an error while opening the file with an external app." 319 | msgstr "வெளிப்புற பயன்பாட்டுடன் கோப்பைத் திறக்கும்போது பிழை ஏற்பட்டது." 320 | 321 | #: src/View/EditView.vala:453 322 | msgid "Edit Entry" 323 | msgstr "நுழைவு திருத்து" 324 | 325 | #: src/View/EditView.vala:455 326 | #, c-format 327 | msgid "Edit “%s”" 328 | msgstr "“%s” திருத்து" 329 | 330 | #: src/View/EditView.vala:471 331 | msgid "Failed to Save Entry" 332 | msgstr "நுழைவு சேமிப்பதில் தோல்வி" 333 | 334 | #: src/View/EditView.vala:474 335 | #, c-format 336 | msgid "Failed to Save Entry of “%s”" 337 | msgstr "“%s” இன் நுழைவைச் சேமிப்பதில் தோல்வி" 338 | 339 | #: src/View/EditView.vala:479 340 | msgid "There was an error while saving the app entry." 341 | msgstr "பயன்பாட்டு உள்ளீட்டைச் சேமிக்கும்போது பிழை ஏற்பட்டது." 342 | 343 | #: src/View/FilesView.vala:32 344 | msgid "Create a new entry" 345 | msgstr "புதிய நுழைவை உருவாக்கவும்" 346 | 347 | #: src/View/FilesView.vala:39 348 | msgid "S_ystem" 349 | msgstr "முறைமை" 350 | 351 | #: src/View/FilesView.vala:40 352 | msgid "_Light" 353 | msgstr "விளக்கு" 354 | 355 | #: src/View/FilesView.vala:41 356 | msgid "_Dark" 357 | msgstr "_ டார்க்" 358 | 359 | #: src/View/FilesView.vala:44 360 | msgid "_Style" 361 | msgstr "பாணி" 362 | 363 | #: src/View/FilesView.vala:45 364 | msgid "_Keyboard Shortcuts" 365 | msgstr "விசைப்பலகை குறுக்குவழிகள்" 366 | 367 | #. TRANSLATORS: %s will be replaced by the app name 368 | #: src/View/FilesView.vala:49 369 | #, c-format 370 | msgid "_About %s" 371 | msgstr "%s பற்றி" 372 | 373 | #: src/View/FilesView.vala:53 374 | msgid "Main Menu" 375 | msgstr "பட்டியல் விளையாடுங்கள்" 376 | 377 | #: src/View/FilesView.vala:69 378 | msgid "No Entries Found" 379 | msgstr "உள்ளீடுகள் எதுவும் கிடைக்கவில்லை" 380 | 381 | #: src/View/FilesView.vala:70 382 | msgid "Click the + button on the top to create one." 383 | msgstr "ஒன்றை உருவாக்க மேலே உள்ள + பொத்தானைக் சொடுக்கு செய்க." 384 | 385 | #: src/View/FilesView.vala:117 386 | msgid "Delete…" 387 | msgstr "நீக்கு…" 388 | 389 | #: src/View/FilesView.vala:154 390 | msgid "Delete Entry?" 391 | msgstr "நுழைவை நீக்கவா?" 392 | 393 | #: src/View/FilesView.vala:156 394 | #, c-format 395 | msgid "Delete Entry of “%s”?" 396 | msgstr "“%s” இன் நுழைவை நீக்கவா?" 397 | 398 | #: src/View/FilesView.vala:161 399 | msgid "This removes the app from the launcher." 400 | msgstr "இது துவக்கத்திலிருந்து பயன்பாட்டை நீக்குகிறது." 401 | 402 | #: src/View/FilesView.vala:165 403 | msgid "_Delete" 404 | msgstr "_Delete" 405 | 406 | #: src/Widget/CategoriesRow.vala:63 407 | msgid "Sound & Video" 408 | msgstr "ஒலி & வீடியோ" 409 | 410 | #: src/Widget/CategoriesRow.vala:64 411 | msgid "Audio" 412 | msgstr "ஆடியோ" 413 | 414 | #: src/Widget/CategoriesRow.vala:65 415 | msgid "Video" 416 | msgstr "ஒளிதோற்றம்" 417 | 418 | #: src/Widget/CategoriesRow.vala:66 419 | msgid "Programming" 420 | msgstr "நிரலாக்க" 421 | 422 | #: src/Widget/CategoriesRow.vala:67 423 | msgid "Education" 424 | msgstr "கல்வி" 425 | 426 | #: src/Widget/CategoriesRow.vala:68 427 | msgid "Games" 428 | msgstr "விளையாட்டுகள்" 429 | 430 | #: src/Widget/CategoriesRow.vala:69 431 | msgid "Graphics" 432 | msgstr "கிராபிக்ச்" 433 | 434 | #: src/Widget/CategoriesRow.vala:70 435 | msgid "Internet" 436 | msgstr "இணையம்" 437 | 438 | #: src/Widget/CategoriesRow.vala:71 439 | msgid "Office" 440 | msgstr "அலுவலகம்" 441 | 442 | #: src/Widget/CategoriesRow.vala:72 443 | msgid "Science" 444 | msgstr "அறிவியல்" 445 | 446 | #: src/Widget/CategoriesRow.vala:73 447 | msgid "Settings" 448 | msgstr "அமைப்புகள்" 449 | 450 | #: src/Widget/CategoriesRow.vala:74 451 | msgid "System Tools" 452 | msgstr "கணினி கருவிகள்" 453 | 454 | #: src/Widget/CategoriesRow.vala:75 455 | msgid "Accessories" 456 | msgstr "பாகங்கள்" 457 | 458 | #: src/Widget/CategoriesRow.vala:82 459 | msgid "Categories" 460 | msgstr "வகைகள்" 461 | 462 | #: src/Widget/CategoriesRow.vala:83 463 | msgid "Categories applicable to the app. (You can select more than one.)" 464 | msgstr "" 465 | "பயன்பாட்டிற்கு பொருந்தக்கூடிய வகைகள். (நீங்கள் ஒன்றுக்கு மேற்பட்டவற்றைத் தேர்ந்தெடுக்கலாம்.)" 466 | 467 | #: src/Widget/KeywordsRow.vala:32 468 | msgid "Keyword" 469 | msgstr "முக்கிய சொல்" 470 | 471 | #: src/Widget/KeywordsRow.vala:36 472 | msgid "Delete keyword" 473 | msgstr "முக்கிய சொல்லை நீக்கு" 474 | 475 | #: src/Widget/KeywordsRow.vala:57 476 | msgid "Keywords" 477 | msgstr "முக்கிய வார்த்தைகள்" 478 | 479 | #: src/Widget/KeywordsRow.vala:58 480 | msgid "These words can be used as search terms." 481 | msgstr "இந்த சொற்களை தேடல் சொற்களாகப் பயன்படுத்தலாம்." 482 | 483 | #: src/Widget/KeywordsRow.vala:63 484 | msgid "Add a new keyword" 485 | msgstr "புதிய முக்கிய சொல்லைச் சேர்க்கவும்" 486 | -------------------------------------------------------------------------------- /po/zh_Hans.po: -------------------------------------------------------------------------------- 1 | # Simplified Chinese translations for com.github.ryonakano.pinit. 2 | # Copyright (C) 2021-2025 Ryo Nakano 3 | # This file is distributed under the same license as the com.github.ryonakano.pinit package. 4 | # TSc2end , 2023. 5 | # Ryo Nakano , 2024. 6 | # Fill read-only add-on , 2024. 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: com.github.ryonakano.pinit\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2025-03-16 19:27+0900\n" 12 | "PO-Revision-Date: 2024-05-04 15:05+0000\n" 13 | "Last-Translator: Fill read-only add-on \n" 14 | "Language-Team: Chinese (Simplified) \n" 16 | "Language: zh_Hans\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Plural-Forms: nplurals=1; plural=0;\n" 21 | "X-Generator: Weblate 5.5.3\n" 22 | 23 | #: data/pinit.desktop.in.in:3 24 | msgid "@APP_NAME@" 25 | msgstr "@APP_NAME@" 26 | 27 | #: data/pinit.desktop.in.in:4 28 | msgid "Desktop File Creator" 29 | msgstr "" 30 | 31 | #: data/pinit.desktop.in.in:5 data/pinit.metainfo.xml.in.in:11 32 | #, fuzzy 33 | msgid "Pin portable apps to the launcher" 34 | msgstr "这将从启动器中移除应用。" 35 | 36 | #: data/pinit.desktop.in.in:11 37 | msgid "Desktop;File;Create;Edit;Info;Icon;AppImage;" 38 | msgstr "" 39 | 40 | #: data/pinit.metainfo.xml.in.in:13 41 | msgid "" 42 | "Pin shortcuts for portable apps like raw executable files, AppImage files, " 43 | "etc. to the app launcher on your desktop." 44 | msgstr "" 45 | 46 | #: data/pinit.metainfo.xml.in.in:16 47 | msgid "Other features include:" 48 | msgstr "" 49 | 50 | #: data/pinit.metainfo.xml.in.in:20 51 | msgid "Edit or delete created app entries without opening the file manager" 52 | msgstr "" 53 | 54 | #: data/pinit.metainfo.xml.in.in:21 55 | msgid "Automatically add the execute permission to the file you select" 56 | msgstr "" 57 | 58 | #: data/pinit.metainfo.xml.in.in:27 59 | msgid "App window in the light mode" 60 | msgstr "" 61 | 62 | #: data/pinit.metainfo.xml.in.in:32 63 | msgid "App window in the dark mode" 64 | msgstr "" 65 | 66 | #: data/ui/help-overlay.blp:10 67 | msgctxt "shortcut window" 68 | msgid "General" 69 | msgstr "" 70 | 71 | #: data/ui/help-overlay.blp:14 72 | msgctxt "shortcut window" 73 | msgid "Keyboard Shortcuts" 74 | msgstr "" 75 | 76 | #: data/ui/help-overlay.blp:19 77 | msgctxt "shortcut window" 78 | msgid "Quit" 79 | msgstr "" 80 | 81 | #: data/ui/help-overlay.blp:24 82 | msgctxt "shortcut window" 83 | msgid "Edit" 84 | msgstr "" 85 | 86 | #: data/ui/help-overlay.blp:28 87 | #, fuzzy 88 | msgctxt "shortcut window" 89 | msgid "New Entry" 90 | msgstr "新条目" 91 | 92 | #. TRANSLATORS: A newline-separated list of translators. Don't translate literally. 93 | #. You can optionally add your name if you want, plus you may add your email address or website. 94 | #. e.g.: 95 | #. John Doe 96 | #. John Doe 97 | #. John Doe https://example.com 98 | #: src/Application.vala:310 99 | msgid "translator-credits" 100 | msgstr "" 101 | 102 | #: src/MainWindow.vala:78 103 | #, fuzzy, c-format 104 | msgid "Failed to Delete Entry of “%s”" 105 | msgstr "无法删除文件“%s”" 106 | 107 | #: src/MainWindow.vala:79 108 | msgid "There was an error while removing the app entry." 109 | msgstr "" 110 | 111 | #: src/MainWindow.vala:82 src/MainWindow.vala:132 src/View/EditView.vala:400 112 | #: src/View/EditView.vala:481 113 | #, fuzzy 114 | msgid "_Close" 115 | msgstr "关闭" 116 | 117 | #: src/MainWindow.vala:93 118 | msgid "Entry deleted." 119 | msgstr "" 120 | 121 | #: src/MainWindow.vala:106 122 | msgid "Entry updated." 123 | msgstr "" 124 | 125 | #: src/MainWindow.vala:129 126 | msgid "Failed to Load Entries" 127 | msgstr "" 128 | 129 | #: src/MainWindow.vala:130 130 | msgid "There was an error while loading app entries." 131 | msgstr "" 132 | 133 | #: src/MainWindow.vala:158 134 | msgid "Save Changes?" 135 | msgstr "" 136 | 137 | #: src/MainWindow.vala:159 138 | msgid "" 139 | "Open entries contain unsaved changes. Changes which are not saved will be " 140 | "permanently lost." 141 | msgstr "" 142 | 143 | #: src/MainWindow.vala:163 src/View/FilesView.vala:164 144 | #, fuzzy 145 | msgid "_Cancel" 146 | msgstr "取消" 147 | 148 | #: src/MainWindow.vala:164 149 | msgid "_Discard" 150 | msgstr "" 151 | 152 | #: src/MainWindow.vala:165 src/View/EditView.vala:40 153 | #, fuzzy 154 | msgid "_Save" 155 | msgstr "保存" 156 | 157 | #: src/View/EditView.vala:69 158 | msgid "Required Fields" 159 | msgstr "" 160 | 161 | #: src/View/EditView.vala:70 162 | msgid "The following fields need to be filled to save." 163 | msgstr "" 164 | 165 | #: src/View/EditView.vala:74 166 | msgid "App Name" 167 | msgstr "应用名" 168 | 169 | #: src/View/EditView.vala:75 170 | #, fuzzy 171 | #| msgid "Shown in the launcher or Dock." 172 | msgid "Shown in the launcher or dock." 173 | msgstr "在启动器或Dock中显示。" 174 | 175 | #: src/View/EditView.vala:80 176 | msgid "Exec File" 177 | msgstr "执行文件" 178 | 179 | #: src/View/EditView.vala:81 180 | msgid "" 181 | "The command/app launched when you click the app entry in the launcher. " 182 | "Specify in an absolute path or an app's alias name." 183 | msgstr "" 184 | "当你点击启动器中的应用快捷方式时启动的命令/程序(填写可执行文件的绝对路径或程" 185 | "序别名)。" 186 | 187 | #: src/View/EditView.vala:84 188 | #, fuzzy 189 | msgid "Select an executable file…" 190 | msgstr "选择一个可执行文件" 191 | 192 | #: src/View/EditView.vala:95 193 | msgid "Optional Fields" 194 | msgstr "" 195 | 196 | #: src/View/EditView.vala:96 197 | msgid "Filling these fields improves discoverability in the app launcher." 198 | msgstr "" 199 | 200 | #: src/View/EditView.vala:100 201 | msgid "Icon File" 202 | msgstr "图标文件" 203 | 204 | #: src/View/EditView.vala:101 205 | msgid "" 206 | "The icon branding the app. Specify in an absolute path or an icon's alias " 207 | "name." 208 | msgstr "应用的图标(填写图标文件的绝对路径或图标别名)。" 209 | 210 | #: src/View/EditView.vala:104 211 | #, fuzzy 212 | msgid "Select an icon file…" 213 | msgstr "选择一个图标文件" 214 | 215 | #: src/View/EditView.vala:112 216 | msgid "Generic Name" 217 | msgstr "" 218 | 219 | #: src/View/EditView.vala:113 220 | msgid "" 221 | "Generic name of the app, for example \"Web Browser\" or \"Mail Client\"." 222 | msgstr "" 223 | 224 | #: src/View/EditView.vala:118 225 | msgid "Comment" 226 | msgstr "评论" 227 | 228 | #: src/View/EditView.vala:119 229 | msgid "" 230 | "Descibes the app. May appear as a tooltip when you hover over the app entry " 231 | "in the launcher/dock." 232 | msgstr "" 233 | 234 | #: src/View/EditView.vala:133 235 | #, fuzzy 236 | msgid "Advanced Configurations" 237 | msgstr "高级配置" 238 | 239 | #: src/View/EditView.vala:134 240 | #, fuzzy 241 | msgid "" 242 | "You can create most app entries just by filling in the sections above. " 243 | "However, some apps may require the advanced configuration options below." 244 | msgstr "" 245 | "在大多数情况下,填写上面的部分足以创建应用条目。但如果还不起作用,可以添加下" 246 | "面的配置。" 247 | 248 | #: src/View/EditView.vala:138 249 | msgid "Startup WM Class" 250 | msgstr "WM启动类" 251 | 252 | #: src/View/EditView.vala:139 253 | #, fuzzy 254 | #| msgid "" 255 | #| "Associate the app with a window that has this ID. Fill in this if a " 256 | #| "different or duplicated icon comes up to the dock when the app launches." 257 | msgid "" 258 | "Associate the app with a window that has this ID. Use this if a different or " 259 | "duplicated icon appears in the dock when the app launches." 260 | msgstr "" 261 | "将应用与具有此 ID 的窗口相关联。如果应用启动时出现不同或重复的图标,请填写此" 262 | "项。" 263 | 264 | #: src/View/EditView.vala:144 265 | msgid "Run in Terminal" 266 | msgstr "在终端中运行" 267 | 268 | #: src/View/EditView.vala:145 269 | #, fuzzy 270 | msgid "Turn on if you want to register a CUI app." 271 | msgstr "运行CUI程序时勾选此项。" 272 | 273 | #: src/View/EditView.vala:150 274 | msgid "Hide in Applications Menu" 275 | msgstr "" 276 | 277 | #: src/View/EditView.vala:151 278 | msgid "" 279 | "Useful when you won't launch the app by itself, but want to associate it " 280 | "with filetypes to open files with the app from file managers." 281 | msgstr "" 282 | 283 | #: src/View/EditView.vala:155 284 | #, fuzzy 285 | msgid "_Open" 286 | msgstr "打开" 287 | 288 | #: src/View/EditView.vala:159 289 | #, fuzzy 290 | msgid "Open with Text Editor" 291 | msgstr "在文本编辑器中打开" 292 | 293 | #: src/View/EditView.vala:160 294 | #, fuzzy 295 | msgid "You can also edit more options by opening with a text editor." 296 | msgstr "在文本编辑器中修改更多选项。" 297 | 298 | #: src/View/EditView.vala:205 299 | msgid "New Entry" 300 | msgstr "新条目" 301 | 302 | #: src/View/EditView.vala:221 src/View/EditView.vala:429 303 | msgid "Untitled App" 304 | msgstr "" 305 | 306 | #: src/View/EditView.vala:241 307 | #, fuzzy 308 | msgid "Select Executable File" 309 | msgstr "选择一个可执行文件" 310 | 311 | #: src/View/EditView.vala:242 src/View/EditView.vala:299 312 | msgid "_Select" 313 | msgstr "" 314 | 315 | #: src/View/EditView.vala:295 316 | msgid "ICO, PNG, SVG, or XMP files" 317 | msgstr "ICO、PNG、SVG 或 XMP 文件" 318 | 319 | #: src/View/EditView.vala:298 320 | #, fuzzy 321 | msgid "Select Icon File" 322 | msgstr "选择一个图标文件" 323 | 324 | #: src/View/EditView.vala:397 325 | #, fuzzy 326 | msgid "Failed to Open with External App" 327 | msgstr "无法使用外部应用打开" 328 | 329 | #: src/View/EditView.vala:398 330 | msgid "There was an error while opening the file with an external app." 331 | msgstr "" 332 | 333 | #: src/View/EditView.vala:453 334 | #, fuzzy 335 | msgid "Edit Entry" 336 | msgstr "编辑条目" 337 | 338 | #: src/View/EditView.vala:455 339 | #, fuzzy, c-format 340 | msgid "Edit “%s”" 341 | msgstr "编辑“%s”" 342 | 343 | #: src/View/EditView.vala:471 344 | msgid "Failed to Save Entry" 345 | msgstr "" 346 | 347 | #: src/View/EditView.vala:474 348 | #, c-format 349 | msgid "Failed to Save Entry of “%s”" 350 | msgstr "" 351 | 352 | #: src/View/EditView.vala:479 353 | msgid "There was an error while saving the app entry." 354 | msgstr "" 355 | 356 | #: src/View/FilesView.vala:32 357 | msgid "Create a new entry" 358 | msgstr "创建一个新条目" 359 | 360 | #: src/View/FilesView.vala:39 361 | #, fuzzy 362 | msgid "S_ystem" 363 | msgstr "系统" 364 | 365 | #: src/View/FilesView.vala:40 366 | #, fuzzy 367 | msgid "_Light" 368 | msgstr "亮" 369 | 370 | #: src/View/FilesView.vala:41 371 | #, fuzzy 372 | msgid "_Dark" 373 | msgstr "暗" 374 | 375 | #: src/View/FilesView.vala:44 376 | #, fuzzy 377 | msgid "_Style" 378 | msgstr "主题" 379 | 380 | #: src/View/FilesView.vala:45 381 | msgid "_Keyboard Shortcuts" 382 | msgstr "" 383 | 384 | #. TRANSLATORS: %s will be replaced by the app name 385 | #: src/View/FilesView.vala:49 386 | #, fuzzy, c-format 387 | msgid "_About %s" 388 | msgstr "关于%s……" 389 | 390 | #: src/View/FilesView.vala:53 391 | msgid "Main Menu" 392 | msgstr "" 393 | 394 | #: src/View/FilesView.vala:69 395 | #, fuzzy 396 | msgid "No Entries Found" 397 | msgstr "找不到有效的应用条目" 398 | 399 | #: src/View/FilesView.vala:70 400 | msgid "Click the + button on the top to create one." 401 | msgstr "" 402 | 403 | #: src/View/FilesView.vala:117 404 | msgid "Delete…" 405 | msgstr "删除……" 406 | 407 | #: src/View/FilesView.vala:154 408 | #, fuzzy 409 | msgid "Delete Entry?" 410 | msgstr "删除的条目。" 411 | 412 | #: src/View/FilesView.vala:156 413 | #, c-format 414 | msgid "Delete Entry of “%s”?" 415 | msgstr "" 416 | 417 | #: src/View/FilesView.vala:161 418 | msgid "This removes the app from the launcher." 419 | msgstr "这将从启动器中移除应用。" 420 | 421 | #: src/View/FilesView.vala:165 422 | #, fuzzy 423 | msgid "_Delete" 424 | msgstr "删除" 425 | 426 | #: src/Widget/CategoriesRow.vala:63 427 | #, fuzzy 428 | msgid "Sound & Video" 429 | msgstr "影音" 430 | 431 | #: src/Widget/CategoriesRow.vala:64 432 | msgid "Audio" 433 | msgstr "音乐" 434 | 435 | #: src/Widget/CategoriesRow.vala:65 436 | msgid "Video" 437 | msgstr "视频" 438 | 439 | #: src/Widget/CategoriesRow.vala:66 440 | msgid "Programming" 441 | msgstr "" 442 | 443 | #: src/Widget/CategoriesRow.vala:67 444 | msgid "Education" 445 | msgstr "教育" 446 | 447 | #: src/Widget/CategoriesRow.vala:68 448 | #, fuzzy 449 | msgid "Games" 450 | msgstr "游戏" 451 | 452 | #: src/Widget/CategoriesRow.vala:69 453 | msgid "Graphics" 454 | msgstr "图形" 455 | 456 | #: src/Widget/CategoriesRow.vala:70 457 | msgid "Internet" 458 | msgstr "" 459 | 460 | #: src/Widget/CategoriesRow.vala:71 461 | msgid "Office" 462 | msgstr "办公" 463 | 464 | #: src/Widget/CategoriesRow.vala:72 465 | msgid "Science" 466 | msgstr "科学" 467 | 468 | #: src/Widget/CategoriesRow.vala:73 469 | msgid "Settings" 470 | msgstr "设置" 471 | 472 | #: src/Widget/CategoriesRow.vala:74 473 | #, fuzzy 474 | msgid "System Tools" 475 | msgstr "系统" 476 | 477 | #: src/Widget/CategoriesRow.vala:75 478 | msgid "Accessories" 479 | msgstr "" 480 | 481 | #: src/Widget/CategoriesRow.vala:82 482 | #, fuzzy 483 | msgid "Categories" 484 | msgstr "应用类别" 485 | 486 | #: src/Widget/CategoriesRow.vala:83 487 | msgid "Categories applicable to the app. (You can select more than one.)" 488 | msgstr "" 489 | 490 | #: src/Widget/KeywordsRow.vala:32 491 | msgid "Keyword" 492 | msgstr "" 493 | 494 | #: src/Widget/KeywordsRow.vala:36 495 | #, fuzzy 496 | msgid "Delete keyword" 497 | msgstr "删除的条目。" 498 | 499 | #: src/Widget/KeywordsRow.vala:57 500 | msgid "Keywords" 501 | msgstr "" 502 | 503 | #: src/Widget/KeywordsRow.vala:58 504 | msgid "These words can be used as search terms." 505 | msgstr "" 506 | 507 | #: src/Widget/KeywordsRow.vala:63 508 | msgid "Add a new keyword" 509 | msgstr "" 510 | 511 | #~ msgid "Pin It!" 512 | #~ msgstr "Pin It!" 513 | 514 | #~ msgid "Ryo Nakano" 515 | #~ msgstr "Ryo Nakano" 516 | 517 | #, fuzzy 518 | #~ msgid "Support opening in a text editor" 519 | #~ msgstr "在文本编辑器中修改更多选项。" 520 | 521 | #, fuzzy 522 | #~| msgid "Exec File" 523 | #~ msgctxt "shortcut window" 524 | #~ msgid "New File" 525 | #~ msgstr "执行文件" 526 | 527 | #, c-format 528 | #~ msgid "Cannot open %s: %s" 529 | #~ msgstr "无法打开%s:%s" 530 | 531 | #~ msgid "Updated entry." 532 | #~ msgstr "更新的条目。" 533 | 534 | #, fuzzy 535 | #~| msgid "" 536 | #~| "Create the shortcut to your favorite portable apps into your app launcher" 537 | #~ msgid "Pin shortcuts for your favorite portable apps to your app launcher" 538 | #~ msgstr "在应用启动器中创建便携式程序快捷方式" 539 | 540 | #~ msgid "File Name" 541 | #~ msgstr "文件名" 542 | 543 | #, fuzzy 544 | #~| msgid "Name of the file where these app info is saved." 545 | #~ msgid "Name of the .desktop file, where this app's info will be saved." 546 | #~ msgstr "保存应用信息的文件名。" 547 | 548 | #~ msgid "Suffix of the file" 549 | #~ msgstr "文件后缀" 550 | 551 | #, c-format 552 | #~ msgid "Could not write to file “%s”" 553 | #~ msgstr "无法写入文件“%s”" 554 | 555 | #~ msgid "Recommendations for naming" 556 | #~ msgstr "命名建议" 557 | 558 | #, fuzzy 559 | #~| msgid "" 560 | #~| "It is recommended to use only alphabets, numbers, and underscores, and " 561 | #~| "none begins with numbers." 562 | #~ msgid "" 563 | #~ "It is recommended to use only alphanumeric characters and underscores. " 564 | #~ "Don't begin with a number." 565 | #~ msgstr "建议只使用字母、数字和下划线,且不要以数字开头。" 566 | 567 | #, c-format 568 | #~ msgid "For example, you should use \"%s\" for the 2D game, SuperTux." 569 | #~ msgstr "举个例子,你应该为2D游戏- SuperTux使用“%s”。" 570 | 571 | #, c-format 572 | #~ msgid "For more info, see %s." 573 | #~ msgstr "更多信息参见%s。" 574 | 575 | #~ msgid "the file naming specification by freedesktop.org" 576 | #~ msgstr "文件命名规范由freedesktop.org制定" 577 | 578 | #~ msgid "Preferences" 579 | #~ msgstr "首选项" 580 | 581 | #~ msgid "If you've never created one, click the + button on the top." 582 | #~ msgstr "如果你从未进行过创建操作,请点击顶部的 + 按钮。" 583 | 584 | #, c-format 585 | #~ msgid "Are you sure you want to delete “%s”?" 586 | #~ msgstr "你确定要删除“%s”吗?" 587 | 588 | #~ msgid "Development" 589 | #~ msgstr "开发" 590 | 591 | #~ msgid "Network" 592 | #~ msgstr "网络" 593 | 594 | #~ msgid "Utility" 595 | #~ msgstr "公共" 596 | 597 | #~ msgid "A tooltip text to describe what the app helps you to do." 598 | #~ msgstr "描述此应用的用途。" 599 | 600 | #~ msgid "Type of the app, multiply selectable." 601 | #~ msgstr "应用类型(可多选)。" 602 | 603 | #~ msgid "" 604 | #~ "Also, use at least one period to make sure to be separated into at least " 605 | #~ "two elements." 606 | #~ msgstr "同时,至少要使用一个句号,以确保最少分成两个元素。" 607 | -------------------------------------------------------------------------------- /src/Application.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * SPDX-FileCopyrightText: 2021-2025 Ryo Nakano 4 | */ 5 | 6 | /** 7 | * The foundation class to manage the app and its window. 8 | */ 9 | public class Application : Adw.Application { 10 | /** 11 | * The instance of the application settings. 12 | */ 13 | public static Settings settings { get; private set; } 14 | 15 | /** 16 | * Action names and their callbacks. 17 | */ 18 | private const ActionEntry[] ACTION_ENTRIES = { 19 | { "quit", on_quit_activate }, 20 | { "about", on_about_activate }, 21 | }; 22 | 23 | private MainWindow main_window; 24 | 25 | public Application () { 26 | Object ( 27 | application_id: Config.APP_ID, 28 | flags: ApplicationFlags.DEFAULT_FLAGS, 29 | resource_base_path: Config.RESOURCE_PREFIX 30 | ); 31 | } 32 | 33 | static construct { 34 | settings = new Settings (Config.APP_ID); 35 | } 36 | 37 | /** 38 | * Make it possible to change the app style with the following action names 39 | * and remember that preference to {@link settings}. 40 | * 41 | * You can change the app style by passsing {@link Define.ColorScheme} value as a target value 42 | * to the ``app.color-scheme`` action. 43 | */ 44 | private void setup_style () { 45 | var style_action = new SimpleAction.stateful ( 46 | "color-scheme", VariantType.STRING, new Variant.string (Define.ColorScheme.DEFAULT) 47 | ); 48 | style_action.bind_property ( 49 | "state", 50 | style_manager, "color-scheme", 51 | BindingFlags.BIDIRECTIONAL | BindingFlags.SYNC_CREATE, 52 | (binding, state_scheme, ref adw_scheme) => { 53 | Variant? state_scheme_dup = state_scheme.dup_variant (); 54 | if (state_scheme_dup == null) { 55 | warning ("Failed to Variant.dup_variant"); 56 | return false; 57 | } 58 | 59 | adw_scheme = Util.to_adw_scheme ((string) state_scheme_dup); 60 | return true; 61 | }, 62 | (binding, adw_scheme, ref state_scheme) => { 63 | string str_scheme = Util.to_str_scheme ((Adw.ColorScheme) adw_scheme); 64 | state_scheme = new Variant.string (str_scheme); 65 | return true; 66 | } 67 | ); 68 | settings.bind_with_mapping ( 69 | "color-scheme", 70 | style_manager, "color-scheme", SettingsBindFlags.DEFAULT, 71 | (adw_scheme, gschema_scheme, user_data) => { 72 | adw_scheme = Util.to_adw_scheme ((string) gschema_scheme); 73 | return true; 74 | }, 75 | (adw_scheme, expected_type, user_data) => { 76 | string str_scheme = Util.to_str_scheme ((Adw.ColorScheme) adw_scheme); 77 | Variant gschema_scheme = new Variant.string (str_scheme); 78 | return gschema_scheme; 79 | }, 80 | null, null 81 | ); 82 | add_action (style_action); 83 | } 84 | 85 | /** 86 | * Setup localization, app style, and accel keys. 87 | */ 88 | protected override void startup () { 89 | #if USE_GRANITE 90 | // Use both compile-time and runtime conditions to: 91 | // 92 | // * make Granite optional dependency 93 | // * make sure to respect currently running DE 94 | if (Util.is_on_pantheon ()) { 95 | // Apply elementary stylesheet instead of default Adwaita stylesheet 96 | Granite.init (); 97 | } 98 | #endif 99 | 100 | base.startup (); 101 | 102 | // Make sure the app is shown in the user's language. 103 | // https://docs.gtk.org/glib/i18n.html#internationalization 104 | Intl.setlocale (LocaleCategory.ALL, ""); 105 | Intl.bindtextdomain (Config.GETTEXT_PACKAGE, Config.LOCALEDIR); 106 | Intl.bind_textdomain_codeset (Config.GETTEXT_PACKAGE, "UTF-8"); 107 | Intl.textdomain (Config.GETTEXT_PACKAGE); 108 | 109 | setup_style (); 110 | 111 | add_action_entries (ACTION_ENTRIES, this); 112 | set_accels_for_action ("app.quit", { "q" }); 113 | set_accels_for_action ("win.new", { "n" }); 114 | } 115 | 116 | /** 117 | * Show {@link MainWindow}. 118 | * 119 | * If there is an instance of {@link MainWindow}, show it and leave the method.<
> 120 | * Otherwise, initialize it, show it, and binding window sizes/states. 121 | */ 122 | protected override void activate () { 123 | if (main_window != null) { 124 | main_window.present (); 125 | return; 126 | } 127 | 128 | main_window = new MainWindow (); 129 | main_window.set_application (this); 130 | // The window seems to need showing before restoring its size in Gtk4 131 | main_window.present (); 132 | 133 | settings.bind ("window-height", main_window, "default-height", SettingsBindFlags.DEFAULT); 134 | settings.bind ("window-width", main_window, "default-width", SettingsBindFlags.DEFAULT); 135 | 136 | // Binding of window maximization with "SettingsBindFlags.DEFAULT" results the window getting bigger and bigger on open. 137 | // So we use the prepared binding only for setting 138 | bool is_maximized = Application.settings.get_boolean ("window-maximized"); 139 | if (is_maximized) { 140 | main_window.maximize (); 141 | } 142 | 143 | settings.bind ("window-maximized", main_window, "maximized", SettingsBindFlags.SET); 144 | } 145 | 146 | /** 147 | * The callback for "app.quit" action. 148 | * 149 | * Quit the app immediately if there is no instance of {@link MainWindow}.<
> 150 | * Otherwise, destory it after checking if we can. 151 | */ 152 | private void on_quit_activate () { 153 | if (main_window == null) { 154 | quit (); 155 | return; 156 | } 157 | 158 | bool can_destroy = main_window.check_destroy (); 159 | if (can_destroy) { 160 | main_window.destroy (); 161 | } 162 | } 163 | 164 | /** 165 | * The callback for "app.about" action. 166 | * 167 | * Show the about dialog. 168 | */ 169 | private void on_about_activate () { 170 | // List of maintainers 171 | const string[] DEVELOPERS = { 172 | "Ryo Nakano https://github.com/ryonakano", 173 | }; 174 | // List of icon authors 175 | const string[] ARTISTS = { 176 | "hanaral https://github.com/hanaral", 177 | }; 178 | 179 | var about_dialog = new Adw.AboutDialog.from_appdata ( 180 | "%s/%s.metainfo.xml".printf (Config.RESOURCE_PREFIX, Config.APP_ID), 181 | null 182 | ) { 183 | version = Config.APP_VERSION, 184 | copyright = "© 2021-2025 Ryo Nakano", 185 | developers = DEVELOPERS, 186 | artists = ARTISTS, 187 | ///TRANSLATORS: A newline-separated list of translators. Don't translate literally. 188 | ///You can optionally add your name if you want, plus you may add your email address or website. 189 | ///e.g.: 190 | ///John Doe 191 | ///John Doe 192 | ///John Doe https://example.com 193 | translator_credits = _("translator-credits") 194 | }; 195 | about_dialog.present (get_active_window ()); 196 | } 197 | 198 | public static int main (string[] args) { 199 | var app = new Application (); 200 | return app.run (); 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /src/Config.vala.in: -------------------------------------------------------------------------------- 1 | namespace Config { 2 | public const string LOCALEDIR = @LOCALEDIR@; 3 | public const string GETTEXT_PACKAGE = @GETTEXT_PACKAGE@; 4 | public const string APP_ID = @APP_ID@; 5 | public const string APP_VERSION = @APP_VERSION@; 6 | public const string RESOURCE_PREFIX = @RESOURCE_PREFIX@; 7 | } 8 | -------------------------------------------------------------------------------- /src/Define.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * SPDX-FileCopyrightText: 2021-2025 Ryo Nakano 4 | */ 5 | 6 | /** 7 | * Defines constants used in the project widely. 8 | */ 9 | namespace Define { 10 | /** 11 | * The name of the application. 12 | * 13 | * Use this constant to prevent the app name from being translated. 14 | */ 15 | public const string APP_NAME = "Pin It!"; 16 | 17 | /** 18 | * Response IDs used in ``Adw.AlertDialog``. 19 | */ 20 | namespace DialogResponse { 21 | /** Use this constant instead of the literal string ``close``. */ 22 | public const string CLOSE = "close"; 23 | /** Use this constant instead of the literal string ``cancel``. */ 24 | public const string CANCEL = "cancel"; 25 | /** Use this constant instead of the literal string ``ok``. */ 26 | public const string OK = "ok"; 27 | /** Use this constant instead of the literal string ``discard``. */ 28 | public const string DISCARD = "discard"; 29 | /** Use this constant instead of the literal string ``save``. */ 30 | public const string SAVE = "save"; 31 | } 32 | 33 | /** 34 | * String representation of ``Adw.ColorScheme``. 35 | * 36 | * Note: Only defines necessary strings for the app. 37 | */ 38 | namespace ColorScheme { 39 | /** Inherit the parent color-scheme. */ 40 | public const string DEFAULT = "default"; 41 | /** Always use light appearance. */ 42 | public const string FORCE_LIGHT = "force-light"; 43 | /** Always use dark appearance. */ 44 | public const string FORCE_DARK = "force-dark"; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/MainWindow.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * SPDX-FileCopyrightText: 2021-2025 Ryo Nakano 4 | */ 5 | 6 | /** 7 | * The window of the application. 8 | * 9 | * It contains a ``Adw.NavigationSplitView`` as a view which has a {@link View.FilesView} and 10 | * {@link View.EditView} inside. 11 | * 12 | * It also has a instance of {@link Model.DesktopFileModel} and calls {@link Model.DesktopFileModel.load} when 13 | * constructed. If the call succeeded, it calls {@link View.FilesView.set_list_data} to reflect 14 | * load result.<
> 15 | * Otherwise, it shows a dialog to tell the user about the failure. 16 | */ 17 | public class MainWindow : Adw.ApplicationWindow { 18 | private const ActionEntry[] ACTION_ENTRIES = { 19 | { "new", on_new_activate }, 20 | }; 21 | 22 | private View.FilesView files_view; 23 | private View.EditView edit_view; 24 | private Adw.NavigationSplitView split_view; 25 | 26 | private Model.DesktopFileModel model; 27 | 28 | public MainWindow () { 29 | } 30 | 31 | construct { 32 | // Distinct development build visually 33 | if (".Devel" in Config.APP_ID) { 34 | add_css_class ("devel"); 35 | } 36 | 37 | add_action_entries (ACTION_ENTRIES, this); 38 | 39 | width_request = 450; 40 | height_request = 400; 41 | title = Define.APP_NAME; 42 | 43 | model = new Model.DesktopFileModel (); 44 | model.load_failure.connect (on_load_failure); 45 | model.load_success.connect (on_load_success); 46 | 47 | model.load.begin (); 48 | 49 | files_view = new View.FilesView (); 50 | edit_view = new View.EditView (); 51 | 52 | split_view = new Adw.NavigationSplitView () { 53 | sidebar = files_view, 54 | content = edit_view 55 | }; 56 | 57 | var breakpoint = new Adw.Breakpoint ( 58 | new Adw.BreakpointCondition.length (Adw.BreakpointConditionLengthType.MAX_WIDTH, 800, Adw.LengthUnit.SP) 59 | ); 60 | breakpoint.add_setter (split_view, "collapsed", true); 61 | add_breakpoint (breakpoint); 62 | 63 | var overlay = new Adw.ToastOverlay () { 64 | child = split_view 65 | }; 66 | 67 | content = overlay; 68 | 69 | files_view.delete_activated.connect ((file) => { 70 | edit_view.hide_all (); 71 | 72 | bool ret = model.delete_file (file); 73 | if (!ret) { 74 | var error_dialog = new Adw.AlertDialog ( 75 | _("Failed to Delete Entry of “%s”").printf (file.value_name), 76 | _("There was an error while removing the app entry.") 77 | ); 78 | 79 | error_dialog.add_response (Define.DialogResponse.CLOSE, _("_Close")); 80 | 81 | error_dialog.default_response = Define.DialogResponse.CLOSE; 82 | error_dialog.close_response = Define.DialogResponse.CLOSE; 83 | 84 | error_dialog.present ((Adw.ApplicationWindow) get_root ()); 85 | return; 86 | } 87 | 88 | show_files_view (); 89 | 90 | var deleted_toast = new Adw.Toast (_("Entry deleted.")) { 91 | timeout = 5 92 | }; 93 | overlay.add_toast (deleted_toast); 94 | }); 95 | 96 | files_view.selected.connect ((entry) => { 97 | show_edit_view (entry); 98 | }); 99 | 100 | edit_view.saved.connect (() => { 101 | files_view.set_list_data (model.files_list); 102 | 103 | var updated_toast = new Adw.Toast (_("Entry updated.")) { 104 | timeout = 5 105 | }; 106 | overlay.add_toast (updated_toast); 107 | }); 108 | 109 | close_request.connect (() => { 110 | bool can_destroy = check_destroy (); 111 | if (can_destroy) { 112 | return Gdk.EVENT_PROPAGATE; 113 | } 114 | 115 | return Gdk.EVENT_STOP; 116 | }); 117 | } 118 | 119 | /** 120 | * The callback when loading the list of desktop files failed. 121 | * 122 | * Tell the user the failure through a dialog. 123 | */ 124 | private void on_load_failure () { 125 | var error_dialog = new Adw.AlertDialog ( 126 | _("Failed to Load Entries"), 127 | _("There was an error while loading app entries.") 128 | ); 129 | error_dialog.add_response (Define.DialogResponse.CLOSE, _("_Close")); 130 | error_dialog.default_response = Define.DialogResponse.CLOSE; 131 | error_dialog.close_response = Define.DialogResponse.CLOSE; 132 | error_dialog.present (this); 133 | } 134 | 135 | /** 136 | * The callback when loading the list of desktop files succeeded. 137 | */ 138 | private void on_load_success () { 139 | files_view.set_list_data (model.files_list); 140 | } 141 | 142 | /** 143 | * Check if we can quit the app immediately. 144 | * 145 | * If we have unsaved changes and can't, confirm interactivelly by presenting a dialog. 146 | * 147 | * @return true if we can quit the app, false otherwise. 148 | */ 149 | public bool check_destroy () { 150 | if (!model.has_unsaved_changes ()) { 151 | return true; 152 | } 153 | 154 | var unsaved_dialog = new Adw.AlertDialog ( 155 | _("Save Changes?"), 156 | _("Open entries contain unsaved changes. Changes which are not saved will be permanently lost.") 157 | ); 158 | unsaved_dialog.add_css_class ("save-changes"); 159 | unsaved_dialog.add_responses ( 160 | Define.DialogResponse.CANCEL, _("_Cancel"), 161 | Define.DialogResponse.DISCARD, _("_Discard"), 162 | Define.DialogResponse.SAVE, _("_Save") 163 | ); 164 | unsaved_dialog.set_response_appearance (Define.DialogResponse.DISCARD, Adw.ResponseAppearance.DESTRUCTIVE); 165 | unsaved_dialog.set_response_appearance (Define.DialogResponse.SAVE, Adw.ResponseAppearance.SUGGESTED); 166 | unsaved_dialog.close_response = Define.DialogResponse.CANCEL; 167 | 168 | string unsaved_dialog_resp = Define.DialogResponse.CANCEL; 169 | var resp_wait_loop = new MainLoop (); 170 | unsaved_dialog.response.connect ((response) => { 171 | unsaved_dialog_resp = response; 172 | resp_wait_loop.quit (); 173 | }); 174 | 175 | // Show the dialog and wait for its response 176 | unsaved_dialog.present (this); 177 | resp_wait_loop.run (); 178 | 179 | switch (unsaved_dialog_resp) { 180 | case Define.DialogResponse.CANCEL: 181 | return false; 182 | case Define.DialogResponse.SAVE: 183 | edit_view.save_file (); 184 | break; 185 | case Define.DialogResponse.DISCARD: 186 | break; 187 | default: 188 | assert_not_reached (); 189 | } 190 | 191 | unsaved_dialog.destroy (); 192 | return true; 193 | } 194 | 195 | /** 196 | * Refresh and show the file list. 197 | */ 198 | public void show_files_view () { 199 | files_view.set_list_data (model.files_list); 200 | split_view.show_content = false; 201 | } 202 | 203 | /** 204 | * Start editing the given {@link Model.DesktopFile}. 205 | * 206 | * @param file the {@link Model.DesktopFile} to edit 207 | */ 208 | public void show_edit_view (Model.DesktopFile file) { 209 | edit_view.load_file (file); 210 | split_view.show_content = true; 211 | } 212 | 213 | /** 214 | * The callback for new file. 215 | * 216 | * Create a new DesktopFile and start editing it. 217 | */ 218 | private void on_new_activate () { 219 | Model.DesktopFile file = model.create_file (); 220 | 221 | files_view.set_list_data (model.files_list); 222 | show_edit_view (file); 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /src/Model/DesktopFile.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * SPDX-FileCopyrightText: 2021-2025 Ryo Nakano 4 | */ 5 | 6 | /** 7 | * A class to represents a single desktop file. 8 | */ 9 | public class Model.DesktopFile : Object { 10 | /** 11 | * The suffix of the desktop files. 12 | */ 13 | public const string DESKTOP_SUFFIX = ".desktop"; 14 | 15 | /** 16 | * The absolute path to the desktop file. 17 | */ 18 | public string path { get; construct; } 19 | 20 | /** 21 | * Value of "Name" entry. 22 | */ 23 | public string value_name { 24 | owned get { 25 | Value? name = Util.KeyFileUtil.get_value (keyfile_dirty, KeyFileDesktop.KEY_NAME, Util.KeyFileUtil.get_locale_string); 26 | if (name == null) { 27 | return ""; 28 | } 29 | 30 | return (string) name; 31 | } 32 | 33 | set { 34 | Value? name = null; 35 | if (value != "") { 36 | name = value; 37 | } 38 | 39 | Util.KeyFileUtil.set_value (keyfile_dirty, KeyFileDesktop.KEY_NAME, name, Util.KeyFileUtil.set_string); 40 | } 41 | } 42 | 43 | /** 44 | * Value of "Exec" entry. 45 | */ 46 | public string value_exec { 47 | owned get { 48 | Value? exec = Util.KeyFileUtil.get_value (keyfile_dirty, KeyFileDesktop.KEY_EXEC, Util.KeyFileUtil.get_string); 49 | if (exec == null) { 50 | return ""; 51 | } 52 | 53 | return (string) exec; 54 | } 55 | 56 | set { 57 | Value? exec = null; 58 | if (value != "") { 59 | exec = value; 60 | } 61 | 62 | Util.KeyFileUtil.set_value (keyfile_dirty, KeyFileDesktop.KEY_EXEC, exec, Util.KeyFileUtil.set_string); 63 | } 64 | } 65 | 66 | /** 67 | * Value of "Icon" entry. 68 | */ 69 | public string value_icon { 70 | owned get { 71 | Value? icon = Util.KeyFileUtil.get_value (keyfile_dirty, KeyFileDesktop.KEY_ICON, Util.KeyFileUtil.get_string); 72 | if (icon == null) { 73 | return ""; 74 | } 75 | 76 | return (string) icon; 77 | } 78 | 79 | set { 80 | Value? icon = null; 81 | if (value != "") { 82 | icon = value; 83 | } 84 | 85 | Util.KeyFileUtil.set_value (keyfile_dirty, KeyFileDesktop.KEY_ICON, icon, Util.KeyFileUtil.set_string); 86 | } 87 | } 88 | 89 | /** 90 | * Value of "GenericName" entry. 91 | */ 92 | public string value_generic_name { 93 | owned get { 94 | Value? generic_name = Util.KeyFileUtil.get_value (keyfile_dirty, KeyFileDesktop.KEY_GENERIC_NAME, Util.KeyFileUtil.get_locale_string); 95 | if (generic_name == null) { 96 | return ""; 97 | } 98 | 99 | return (string) generic_name; 100 | } 101 | 102 | set { 103 | Value? generic_name = null; 104 | if (value != "") { 105 | generic_name = value; 106 | } 107 | 108 | Util.KeyFileUtil.set_value (keyfile_dirty, KeyFileDesktop.KEY_GENERIC_NAME, generic_name, Util.KeyFileUtil.set_string); 109 | } 110 | } 111 | 112 | /** 113 | * Value of "Comment" entry. 114 | */ 115 | public string value_comment { 116 | owned get { 117 | Value? comment = Util.KeyFileUtil.get_value (keyfile_dirty, KeyFileDesktop.KEY_COMMENT, Util.KeyFileUtil.get_locale_string); 118 | if (comment == null) { 119 | return ""; 120 | } 121 | 122 | return (string) comment; 123 | } 124 | 125 | set { 126 | Value? comment = null; 127 | if (value != "") { 128 | comment = value; 129 | } 130 | 131 | Util.KeyFileUtil.set_value (keyfile_dirty, KeyFileDesktop.KEY_COMMENT, comment, Util.KeyFileUtil.set_string); 132 | } 133 | } 134 | 135 | /** 136 | * Value of "Categories" entry. 137 | */ 138 | public string[] value_categories { 139 | owned get { 140 | Value? categories = Util.KeyFileUtil.get_value (keyfile_dirty, KeyFileDesktop.KEY_CATEGORIES, Util.KeyFileUtil.get_strv); 141 | if (categories == null) { 142 | return {}; 143 | } 144 | 145 | return (string[]) categories; 146 | } 147 | 148 | set { 149 | Value? categories = null; 150 | if (value.length > 0) { 151 | categories = value; 152 | } 153 | 154 | Util.KeyFileUtil.set_value (keyfile_dirty, KeyFileDesktop.KEY_CATEGORIES, categories, Util.KeyFileUtil.set_strv); 155 | } 156 | } 157 | 158 | /** 159 | * Value of "Keywords" entry. 160 | */ 161 | public string[] value_keywords { 162 | owned get { 163 | Value? keywords = Util.KeyFileUtil.get_value (keyfile_dirty, Util.KeyFileUtil.KEY_KEYWORDS, Util.KeyFileUtil.get_strv); 164 | if (keywords == null) { 165 | return {}; 166 | } 167 | 168 | return (string[]) keywords; 169 | } 170 | 171 | set { 172 | Value? keywords = null; 173 | if (value.length > 0) { 174 | keywords = value; 175 | } 176 | 177 | Util.KeyFileUtil.set_value (keyfile_dirty, Util.KeyFileUtil.KEY_KEYWORDS, keywords, Util.KeyFileUtil.set_strv); 178 | } 179 | } 180 | 181 | /** 182 | * Value of "StartupWMClass" entry. 183 | */ 184 | public string value_startup_wm_class { 185 | owned get { 186 | Value? startup_wm_class = Util.KeyFileUtil.get_value (keyfile_dirty, KeyFileDesktop.KEY_STARTUP_WM_CLASS, Util.KeyFileUtil.get_string); 187 | if (startup_wm_class == null) { 188 | return ""; 189 | } 190 | 191 | return (string) startup_wm_class; 192 | } 193 | 194 | set { 195 | Value? startup_wm_class = null; 196 | if (value != "") { 197 | startup_wm_class = value; 198 | } 199 | 200 | Util.KeyFileUtil.set_value (keyfile_dirty, KeyFileDesktop.KEY_STARTUP_WM_CLASS, startup_wm_class, Util.KeyFileUtil.set_string); 201 | } 202 | } 203 | 204 | /** 205 | * Value of "Terminal" entry. 206 | */ 207 | public bool value_terminal { 208 | get { 209 | Value? terminal = Util.KeyFileUtil.get_value (keyfile_dirty, KeyFileDesktop.KEY_TERMINAL, Util.KeyFileUtil.get_boolean); 210 | if (terminal == null) { 211 | return false; 212 | } 213 | 214 | return (bool) terminal; 215 | } 216 | 217 | set { 218 | Value? terminal = null; 219 | if (value) { 220 | terminal = value; 221 | } 222 | 223 | Util.KeyFileUtil.set_value (keyfile_dirty, KeyFileDesktop.KEY_TERMINAL, terminal, Util.KeyFileUtil.set_boolean); 224 | } 225 | } 226 | 227 | /** 228 | * Value of "NoDisplay" entry. 229 | */ 230 | public bool value_nodisplay { 231 | get { 232 | Value? nodisplay = Util.KeyFileUtil.get_value (keyfile_dirty, KeyFileDesktop.KEY_NO_DISPLAY, Util.KeyFileUtil.get_boolean); 233 | if (nodisplay == null) { 234 | return false; 235 | } 236 | 237 | return (bool) nodisplay; 238 | } 239 | 240 | set { 241 | Value? nodisplay = null; 242 | if (value) { 243 | nodisplay = value; 244 | } 245 | 246 | Util.KeyFileUtil.set_value (keyfile_dirty, KeyFileDesktop.KEY_NO_DISPLAY, nodisplay, Util.KeyFileUtil.set_boolean); 247 | } 248 | } 249 | 250 | /** 251 | * Value of "Name" entry without unsaved changes. 252 | */ 253 | public string saved_value_name { 254 | owned get { 255 | Value? name = Util.KeyFileUtil.get_value (keyfile_clean, KeyFileDesktop.KEY_NAME, Util.KeyFileUtil.get_locale_string); 256 | if (name == null) { 257 | return ""; 258 | } 259 | 260 | return (string) name; 261 | } 262 | } 263 | 264 | /** 265 | * Value of "Icon" entry without unsaved changes. 266 | */ 267 | public string saved_value_icon { 268 | owned get { 269 | Value? icon = Util.KeyFileUtil.get_value (keyfile_clean, KeyFileDesktop.KEY_ICON, Util.KeyFileUtil.get_string); 270 | if (icon == null) { 271 | return ""; 272 | } 273 | 274 | return (string) icon; 275 | } 276 | } 277 | 278 | /** 279 | * Value of "Comment" entry without unsaved changes. 280 | */ 281 | public string saved_value_comment { 282 | owned get { 283 | Value? comment = Util.KeyFileUtil.get_value (keyfile_clean, KeyFileDesktop.KEY_COMMENT, Util.KeyFileUtil.get_locale_string); 284 | if (comment == null) { 285 | return ""; 286 | } 287 | 288 | return (string) comment; 289 | } 290 | } 291 | 292 | /** 293 | * Returns if this contains unsaved changes to the disk. 294 | */ 295 | public bool is_clean { 296 | get { 297 | return Util.KeyFileUtil.equals (keyfile_dirty, keyfile_clean); 298 | } 299 | } 300 | 301 | /** 302 | * Data in a single desktop file that loaded from the disk. 303 | */ 304 | private KeyFile keyfile_clean; 305 | /** 306 | * Data in a single desktop file that may contain unsaved changes to the disk. 307 | */ 308 | private KeyFile keyfile_dirty; 309 | 310 | /** 311 | * The constructor. 312 | * 313 | * @param path the absolute path to the desktop file 314 | */ 315 | public DesktopFile (string path) { 316 | Object ( 317 | path: path 318 | ); 319 | } 320 | 321 | construct { 322 | keyfile_clean = new KeyFile (); 323 | keyfile_dirty = new KeyFile (); 324 | } 325 | 326 | /** 327 | * Read content of the desktop file from the disk. 328 | * 329 | * @return true if succeeded, false otherwise 330 | */ 331 | public bool load_file () { 332 | bool ret = Util.KeyFileUtil.load_file (keyfile_clean, path, KeyFileFlags.KEEP_TRANSLATIONS); 333 | if (!ret) { 334 | return false; 335 | } 336 | 337 | return Util.KeyFileUtil.copy (keyfile_dirty, keyfile_clean); 338 | } 339 | 340 | /** 341 | * Write content of the desktop file to the disk. 342 | * 343 | * @return true if succeeded, false otherwise 344 | */ 345 | public bool save_file () { 346 | Util.KeyFileUtil.set_string (keyfile_dirty, KeyFileDesktop.KEY_TYPE, "Application"); 347 | 348 | bool ret = Util.KeyFileUtil.save_file (keyfile_dirty, path); 349 | if (!ret) { 350 | return false; 351 | } 352 | 353 | return Util.KeyFileUtil.copy (keyfile_clean, keyfile_dirty); 354 | } 355 | } 356 | -------------------------------------------------------------------------------- /src/Model/DesktopFileModel.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * SPDX-FileCopyrightText: 2021-2025 Ryo Nakano 4 | * 5 | * Inspired from: 6 | * - https://github.com/elementary/switchboard-plug-keyboard/blob/caef4fd900b41c669d48fc1c91eced6a89709f62/src/Views/InputMethod.vala#L369 7 | * - https://github.com/pantheon-tweaks/pantheon-tweaks/blob/7d366f5e4774175be2d7177d1b8486e0c97d7bfe/src/Settings/ThemeSettings.vala#L62 8 | */ 9 | 10 | /** 11 | * The class to load desktop files and store them in the type of {@link DesktopFile}. 12 | */ 13 | public class Model.DesktopFileModel : Object { 14 | /** 15 | * Notifies loading desktop files succeeded. 16 | */ 17 | public signal void load_success (); 18 | 19 | /** 20 | * Notifies loading desktop files failed. 21 | */ 22 | public signal void load_failure (); 23 | 24 | /** 25 | * List of {@link DesktopFile}. 26 | */ 27 | public Gee.ArrayList files_list { get; private set; } 28 | 29 | /** 30 | * The directory where user desktop files are stored. 31 | */ 32 | private string desktop_files_path; 33 | 34 | public DesktopFileModel () { 35 | } 36 | 37 | construct { 38 | files_list = new Gee.ArrayList (); 39 | 40 | desktop_files_path = Path.build_filename (Environment.get_home_dir (), ".local/share/applications"); 41 | 42 | // Create the desktop files directory if not exists 43 | if (!FileUtils.test (desktop_files_path, FileTest.EXISTS)) { 44 | var desktop_files_dir = File.new_for_path (desktop_files_path); 45 | 46 | try { 47 | desktop_files_dir.make_directory_with_parents (); 48 | } catch (Error err) { 49 | warning ("Failed to make directory. path=%s: %s", desktop_files_path, err.message); 50 | } 51 | } 52 | } 53 | 54 | /** 55 | * Search for desktop files and store in the {@link DesktopFile} data type. 56 | * 57 | * Search ``~/.local/share/applications`` for files with .desktop suffix. Create a new 58 | * {@link DesktopFile} if a matching file found and is valid. Repeat this for all files in the directory. 59 | * 60 | * Emits {@link load_success} if loaded successfully, {@link load_failure} otherwise. 61 | */ 62 | public async void load () { 63 | bool is_success = false; 64 | 65 | new Thread (null, () => { 66 | files_list.clear (); 67 | 68 | var desktop_files_dir = File.new_for_path (desktop_files_path); 69 | FileEnumerator enumerator; 70 | try { 71 | enumerator = desktop_files_dir.enumerate_children (FileAttribute.STANDARD_NAME, 72 | FileQueryInfoFlags.NONE); 73 | } catch (Error err) { 74 | warning ("Failed to get information of files: %s", err.message); 75 | // Schedule to let the UI thread resume from the yield sentence. 76 | Idle.add (load.callback); 77 | return; 78 | } 79 | 80 | FileInfo file_info; 81 | try { 82 | // Check all files in the directory one by one 83 | while ((file_info = enumerator.next_file ()) != null) { 84 | // Ignore any files without the .desktop suffix 85 | string name = file_info.get_name (); 86 | if (!name.has_suffix (DesktopFile.DESKTOP_SUFFIX)) { 87 | continue; 88 | } 89 | 90 | File relative_path = desktop_files_dir.resolve_relative_path (name); 91 | string path = relative_path.get_path (); 92 | 93 | var file = new DesktopFile (path); 94 | bool ret = file.load_file (); 95 | // Skip adding to the list if we fail to load. 96 | if (!ret) { 97 | continue; 98 | } 99 | 100 | files_list.add (file); 101 | } 102 | } catch (Error err) { 103 | warning ("Failed to load file info: %s", err.message); 104 | // Schedule to let the UI thread resume from the yield sentence. 105 | Idle.add (load.callback); 106 | return; 107 | } 108 | 109 | is_success = true; 110 | // Schedule to let the UI thread resume from the yield sentence. 111 | Idle.add (load.callback); 112 | }); 113 | 114 | // Give up control of the CPU to the calling method. 115 | yield; 116 | 117 | if (is_success) { 118 | load_success (); 119 | } else { 120 | load_failure (); 121 | } 122 | } 123 | 124 | /** 125 | * Create a new {@link DesktopFile} with random filename. 126 | * 127 | * @return Created {@link DesktopFile} 128 | */ 129 | public Model.DesktopFile create_file () { 130 | string filename = Config.APP_ID + "." + Uuid.string_random (); 131 | string path = Path.build_filename ( 132 | desktop_files_path, 133 | filename + Model.DesktopFile.DESKTOP_SUFFIX 134 | ); 135 | 136 | var file = new Model.DesktopFile (path); 137 | 138 | files_list.add (file); 139 | 140 | return file; 141 | } 142 | 143 | /** 144 | * Delete desktop file from list and the disk. 145 | * 146 | * @param file A {@link DesktopFile} to delete 147 | * @return true if succeeded, false otherwise 148 | */ 149 | public bool delete_file (Model.DesktopFile file) { 150 | bool ret = delete_from_disk (file.path); 151 | if (!ret) { 152 | return false; 153 | } 154 | 155 | files_list.remove (file); 156 | 157 | return true; 158 | } 159 | 160 | /** 161 | * Delete file at path from the disk. 162 | * 163 | * @param path A file to delete 164 | * @return true if succeeded, false otherwise 165 | */ 166 | private bool delete_from_disk (string path) { 167 | var file = File.new_for_path (path); 168 | 169 | if (!file.query_exists ()) { 170 | return true; 171 | } 172 | 173 | bool ret = false; 174 | try { 175 | ret = file.delete (); 176 | } catch (Error err) { 177 | warning ("Failed to delete file. path=%s: %s", path, err.message); 178 | } 179 | 180 | return ret; 181 | } 182 | 183 | /** 184 | * Check if there is a desktop file with unsaved changes. 185 | * 186 | * @return true if a desktop file with unsaved changes exists, false otherwise 187 | */ 188 | public bool has_unsaved_changes () { 189 | foreach (Model.DesktopFile file in files_list) { 190 | if (!file.is_clean) { 191 | return true; 192 | } 193 | } 194 | 195 | return false; 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /src/Util.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * SPDX-FileCopyrightText: 2021-2025 Ryo Nakano 4 | */ 5 | 6 | namespace Util { 7 | /** 8 | * Whether the app is running on Pantheon desktop environment. 9 | */ 10 | public static bool is_on_pantheon () { 11 | return Environment.get_variable ("XDG_CURRENT_DESKTOP") == "Pantheon"; 12 | } 13 | 14 | public static Adw.ColorScheme to_adw_scheme (string str_scheme) { 15 | switch (str_scheme) { 16 | case Define.ColorScheme.DEFAULT: 17 | return Adw.ColorScheme.DEFAULT; 18 | case Define.ColorScheme.FORCE_LIGHT: 19 | return Adw.ColorScheme.FORCE_LIGHT; 20 | case Define.ColorScheme.FORCE_DARK: 21 | return Adw.ColorScheme.FORCE_DARK; 22 | default: 23 | warning ("Invalid color scheme string: %s", str_scheme); 24 | return Adw.ColorScheme.DEFAULT; 25 | } 26 | } 27 | 28 | public static string to_str_scheme (Adw.ColorScheme adw_scheme) { 29 | switch (adw_scheme) { 30 | case Adw.ColorScheme.DEFAULT: 31 | return Define.ColorScheme.DEFAULT; 32 | case Adw.ColorScheme.FORCE_LIGHT: 33 | return Define.ColorScheme.FORCE_LIGHT; 34 | case Adw.ColorScheme.FORCE_DARK: 35 | return Define.ColorScheme.FORCE_DARK; 36 | default: 37 | warning ("Invalid color scheme: %d", adw_scheme); 38 | return Define.ColorScheme.DEFAULT; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Util/DesktopFileUtil.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * SPDX-FileCopyrightText: 2021-2025 Ryo Nakano 4 | */ 5 | 6 | /** 7 | * Definitions and methods related to creating desktop files. 8 | */ 9 | namespace Util.DesktopFileUtil { 10 | /** 11 | * The mask bit to get permission info from ``Posix.mode_t``. 12 | */ 13 | private const Posix.mode_t PERMISSION_MASK = Posix.S_IRWXU | Posix.S_IRWXG | Posix.S_IRWXO; 14 | 15 | /** 16 | * Add execute permission to the given path. 17 | * 18 | * If the current user already has execute permission to the given path, 19 | * this method doesn't change its permission and returns true. 20 | * 21 | * @param path the path to add execute permission for the current user 22 | * @return true when succeed, false otherwise 23 | */ 24 | public bool add_exec_permission (string path) { 25 | int ret; 26 | Posix.Stat sbuf; 27 | 28 | // Also we can check if it's really a path 29 | ret = Posix.stat (path, out sbuf); 30 | if (ret != 0) { 31 | warning ("Failed to get the current mode of \"%s\": %s", 32 | path, Posix.strerror (Posix.errno)); 33 | return false; 34 | } 35 | 36 | Posix.mode_t current_permission = sbuf.st_mode & PERMISSION_MASK; 37 | 38 | // Do nothing if the current user already has execute permission 39 | if ((current_permission & Posix.S_IXUSR) == Posix.S_IXUSR) { 40 | return true; 41 | } 42 | 43 | ret = Posix.chmod (path, current_permission | Posix.S_IXUSR); 44 | if (ret != 0) { 45 | warning ("Failed to give exec permission to \"%s\": %s", 46 | path, Posix.strerror (Posix.errno)); 47 | return false; 48 | } 49 | 50 | return true; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Util/KeyFileUtil.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * SPDX-FileCopyrightText: 2021-2025 Ryo Nakano 4 | */ 5 | 6 | /** 7 | * Definitions and wrapper methods related to KeyFile. 8 | */ 9 | namespace Util.KeyFileUtil { 10 | /** 11 | * A key under ``g_key_file_desktop_group``, whose value is a list of strings giving the keywords which may be used in 12 | * addition to other metadata to describe this entry. 13 | * 14 | * Note: Using ``KeyFileDesktop.KEY_KEYWORDS`` will cause the cc failing with ``‘G_KEY_FILE_DESKTOP_KEY_KEYWORDS’ undeclared`` 15 | * error.<
> 16 | * This constant does not seem to be defined in the original glib and defined in the following patch.<
> 17 | * (and maybe valac uses glibc with this patch and thus it does not complain any error.)<
> 18 | * <
> 19 | * [[https://sources.debian.org/patches/glib2.0/2.78.3-2/01_gettext-desktopfiles.patch/]]<
> 20 | * <
> 21 | * We just keep to borrow the definition of KEY_KEYWORDS here instead of applying the patch, 22 | * since it might have side effect. 23 | */ 24 | public const string KEY_KEYWORDS = "Keywords"; 25 | 26 | /** 27 | * The language name that the user prefers in the system settings, e.g. "en_US", "ja_JP", etc. 28 | * 29 | * Used to show the ``KEY_NAME`` and ``KEY_COMMENT`` in the user's system language. 30 | */ 31 | private static unowned string? preferred_language = null; 32 | private static unowned string get_preferred_language () { 33 | if (preferred_language == null) { 34 | unowned var languages = Intl.get_language_names (); 35 | preferred_language = languages[0]; 36 | } 37 | 38 | return preferred_language; 39 | } 40 | 41 | /** 42 | * Check if two KeyFiles have the same content. 43 | * 44 | * @param a KeyFile to compare 45 | * @param b KeyFile to compare 46 | * @return true if two KeyFiles have the same content 47 | */ 48 | public static bool equals (KeyFile a, KeyFile b) { 49 | string a_data = a.to_data (); 50 | string b_data = b.to_data (); 51 | 52 | return a_data == b_data; 53 | } 54 | 55 | /** 56 | * Sync content of KeyFile between. 57 | * 58 | * @param src KeyFile to be copied from 59 | * @param dst KeyFile to be copied to 60 | * @return true if successfully copied, false otherwise 61 | */ 62 | public static bool copy (KeyFile dst, KeyFile src) { 63 | string data = src.to_data (); 64 | 65 | try { 66 | dst.load_from_data (data, data.length, KeyFileFlags.KEEP_TRANSLATIONS); 67 | } catch (KeyFileError err) { 68 | warning ("Failed to KeyFile.load_from_data: %s", err.message); 69 | return false; 70 | } 71 | 72 | return true; 73 | } 74 | 75 | //////////////////////////////////////////////////////////////////////////// 76 | // 77 | // Key Opearations 78 | // 79 | //////////////////////////////////////////////////////////////////////////// 80 | 81 | /** 82 | * Return the value associated with ``key``. 83 | * 84 | * @param keyfile a ``KeyFile`` 85 | * @param key a key 86 | * @return the value associated with the key 87 | */ 88 | public delegate Value GetValueFunc (KeyFile keyfile, string key) throws KeyFileError; 89 | /** 90 | * Associates a new value with ``key``. 91 | * 92 | * If ``key`` cannot be found then it is created. 93 | * 94 | * @param keyfile a ``KeyFile`` 95 | * @param key a key 96 | * @param val a value to associate 97 | */ 98 | public delegate void SetValueFunc (KeyFile keyfile, string key, Value val); 99 | 100 | /** 101 | * Return the value associated with ``key``. 102 | * 103 | * @param keyfile a ``KeyFile`` 104 | * @param key a key 105 | * @param get_func a function to actually get value from ``keyfile`` 106 | * @return the value associated with the key, or null if the key was not found or could not be parsed 107 | */ 108 | public static Value? get_value (KeyFile keyfile, string key, GetValueFunc get_func) { 109 | Value? val = null; 110 | 111 | if (!has_key (keyfile, key)) { 112 | return val; 113 | } 114 | 115 | try { 116 | val = get_func (keyfile, key); 117 | } catch (KeyFileError err) { 118 | warning ("Failed to get value from keyfile: key=%s: %s", key, err.message); 119 | } 120 | 121 | return val; 122 | } 123 | 124 | /** 125 | * Associates a new value with ``key``. 126 | * 127 | * If ``key`` cannot be found then it is created. If ``val`` is ``null`` then ``key`` is removed. 128 | * 129 | * @param keyfile a ``KeyFile`` 130 | * @param key a key 131 | * @param val a value to associate or ``null`` to remove ``key`` 132 | * @param set_func a function to actually set value to ``keyfile`` 133 | */ 134 | public static void set_value (KeyFile keyfile, string key, Value? val, SetValueFunc set_func) { 135 | if (val != null) { 136 | // Update the value when the corresponding entry has some value. 137 | set_func (keyfile, key, val); 138 | } else { 139 | // Remove the key when it exists and the corresponding entry has no value. 140 | if (has_key (keyfile, key)) { 141 | try { 142 | keyfile.remove_key (KeyFileDesktop.GROUP, key); 143 | } catch (KeyFileError err) { 144 | warning ("Failed to KeyFile.remove_key: key=%s: %s", key, err.message); 145 | } 146 | } 147 | } 148 | } 149 | 150 | public static Value get_boolean (KeyFile keyfile, string key) throws KeyFileError { 151 | return keyfile.get_boolean (KeyFileDesktop.GROUP, key); 152 | } 153 | 154 | public static void set_boolean (KeyFile keyfile, string key, Value val) { 155 | keyfile.set_boolean (KeyFileDesktop.GROUP, key, (bool) val); 156 | } 157 | 158 | public static Value get_string (KeyFile keyfile, string key) throws KeyFileError { 159 | return keyfile.get_string (KeyFileDesktop.GROUP, key); 160 | } 161 | 162 | public static void set_string (KeyFile keyfile, string key, Value val) { 163 | keyfile.set_string (KeyFileDesktop.GROUP, key, (string) val); 164 | } 165 | 166 | public static Value get_strv (KeyFile keyfile, string key) throws KeyFileError { 167 | return keyfile.get_string_list (KeyFileDesktop.GROUP, key); 168 | } 169 | 170 | public static void set_strv (KeyFile keyfile, string key, Value val) { 171 | keyfile.set_string_list (KeyFileDesktop.GROUP, key, (string[]) val); 172 | } 173 | 174 | public static Value get_locale_string (KeyFile keyfile, string key) throws KeyFileError { 175 | string? locale = keyfile.get_locale_for_key (KeyFileDesktop.GROUP, key, get_preferred_language ()); 176 | 177 | return keyfile.get_locale_string (KeyFileDesktop.GROUP, key, locale); 178 | } 179 | 180 | public static bool has_key (KeyFile keyfile, string key) { 181 | bool ret = false; 182 | 183 | // Maybe keyfile is new and has no key yet 184 | if (!keyfile.has_group (KeyFileDesktop.GROUP)) { 185 | return ret; 186 | } 187 | 188 | try { 189 | ret = keyfile.has_key (KeyFileDesktop.GROUP, key); 190 | } catch (KeyFileError err) { 191 | warning ("Failed to KeyFile.has_key: key=%s: %s", key, err.message); 192 | } 193 | 194 | return ret; 195 | } 196 | 197 | //////////////////////////////////////////////////////////////////////////// 198 | // 199 | // File Opearations 200 | // 201 | //////////////////////////////////////////////////////////////////////////// 202 | 203 | public static bool load_file (KeyFile keyfile, string path, KeyFileFlags flags) { 204 | bool ret = false; 205 | 206 | try { 207 | ret = keyfile.load_from_file (path, flags); 208 | } catch (FileError err) { 209 | warning ("Failed to load from file. path=%s: %s", path, err.message); 210 | } catch (KeyFileError err) { 211 | warning ("Invalid keyfile. path=%s: %s", path, err.message); 212 | } 213 | 214 | return ret; 215 | } 216 | 217 | public static bool save_file (KeyFile keyfile, string path) { 218 | bool ret = false; 219 | 220 | try { 221 | ret = keyfile.save_to_file (path); 222 | } catch (FileError err) { 223 | warning ("Failed to save file. path=%s: %s", path, err.message); 224 | } 225 | 226 | return ret; 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /src/View/FilesView.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * SPDX-FileCopyrightText: 2021-2025 Ryo Nakano 4 | */ 5 | 6 | public class View.FilesView : Adw.NavigationPage { 7 | public signal void delete_activated (Model.DesktopFile file); 8 | public signal void selected (Model.DesktopFile file); 9 | 10 | private ListStore list_store; 11 | 12 | public FilesView () { 13 | } 14 | 15 | construct { 16 | list_store = new ListStore (typeof (Model.DesktopFile)); 17 | 18 | var headerbar = setup_headerbar (); 19 | var content = setup_content (); 20 | 21 | var toolbar_view = new Adw.ToolbarView (); 22 | toolbar_view.add_top_bar (headerbar); 23 | toolbar_view.set_content (content); 24 | 25 | title = Define.APP_NAME; 26 | child = toolbar_view; 27 | width_request = 350; 28 | } 29 | 30 | private Gtk.Widget setup_headerbar () { 31 | var create_button = new Gtk.Button.from_icon_name ("list-add-symbolic") { 32 | tooltip_text = _("Create a new entry"), 33 | action_name = "win.new" 34 | }; 35 | 36 | // Construct the settings menu 37 | var theme_submenu = new GLib.Menu (); 38 | // See https://valadoc.org/gio-2.0/GLib.Action.parse_detailed_name.html for the format 39 | theme_submenu.append (_("S_ystem"), "app.color-scheme('%s')".printf (Define.ColorScheme.DEFAULT)); 40 | theme_submenu.append (_("_Light"), "app.color-scheme('%s')".printf (Define.ColorScheme.FORCE_LIGHT)); 41 | theme_submenu.append (_("_Dark"), "app.color-scheme('%s')".printf (Define.ColorScheme.FORCE_DARK)); 42 | 43 | var menu = new GLib.Menu (); 44 | menu.append_submenu (_("_Style"), theme_submenu); 45 | menu.append (_("_Keyboard Shortcuts"), "win.show-help-overlay"); 46 | // Pantheon prefers AppCenter instead of an about dialog for app details, so prevent it from being shown on Pantheon 47 | if (!Util.is_on_pantheon ()) { 48 | ///TRANSLATORS: %s will be replaced by the app name 49 | menu.append (_("_About %s").printf (Define.APP_NAME), "app.about"); 50 | } 51 | 52 | var menu_button = new Gtk.MenuButton () { 53 | tooltip_text = _("Main Menu"), 54 | icon_name = "open-menu-symbolic", 55 | menu_model = menu, 56 | primary = true 57 | }; 58 | 59 | var headerbar = new Adw.HeaderBar (); 60 | headerbar.pack_start (create_button); 61 | headerbar.pack_end (menu_button); 62 | 63 | return headerbar; 64 | } 65 | 66 | private Gtk.Widget setup_content () { 67 | // NoFilesPage: Shown when no desktop files available. 68 | var no_files_page = new Adw.StatusPage () { 69 | title = _("No Entries Found"), 70 | description = _("Click the + button on the top to create one."), 71 | icon_name = "dialog-information", 72 | vexpand = true, 73 | hexpand = true 74 | }; 75 | 76 | // FilesListPage: The page to list available desktop files. 77 | var files_list = new Gtk.ListBox (); 78 | files_list.set_placeholder (no_files_page); 79 | files_list.bind_model (list_store, create_files_row); 80 | files_list.add_css_class ("navigation-sidebar"); 81 | 82 | // Pack into a scrolled window in case there are many desktop files in the files list 83 | var files_list_page = new Gtk.ScrolledWindow () { 84 | child = files_list, 85 | hscrollbar_policy = Gtk.PolicyType.NEVER, 86 | vexpand = true, 87 | hexpand = true 88 | }; 89 | 90 | return files_list_page; 91 | } 92 | 93 | public void set_list_data (Gee.ArrayList list) { 94 | list_store.remove_all (); 95 | 96 | list.foreach ((item) => { 97 | list_store.append (item); 98 | return true; 99 | }); 100 | } 101 | 102 | private Gtk.Widget create_files_row (Object item) { 103 | var file = item as Model.DesktopFile; 104 | 105 | var app_icon = new Gtk.Image.from_gicon (new ThemedIcon ("application-x-executable")) { 106 | pixel_size = 48, 107 | margin_top = 6, 108 | margin_bottom = 6 109 | }; 110 | try { 111 | app_icon.gicon = Icon.new_for_string (file.saved_value_icon); 112 | } catch (Error err) { 113 | warning ("Failed to update app_icon: %s", err.message); 114 | } 115 | 116 | var delete_button = new Gtk.Button.from_icon_name ("edit-delete-symbolic") { 117 | tooltip_text = _("Delete…"), 118 | valign = Gtk.Align.CENTER 119 | }; 120 | delete_button.add_css_class ("flat"); 121 | delete_button.clicked.connect (() => { 122 | var delete_dialog = setup_delete_dialog (file.saved_value_name); 123 | 124 | delete_dialog.response.connect ((response_id) => { 125 | if (response_id != Define.DialogResponse.OK) { 126 | return; 127 | } 128 | 129 | delete_dialog.destroy (); 130 | 131 | delete_activated (file); 132 | }); 133 | 134 | delete_dialog.present ((Adw.ApplicationWindow) get_root ()); 135 | }); 136 | 137 | var row = new Adw.ActionRow () { 138 | title = file.saved_value_name, 139 | subtitle = file.saved_value_comment, 140 | title_lines = 1, 141 | subtitle_lines = 1, 142 | activatable = true 143 | }; 144 | row.add_prefix (app_icon); 145 | row.add_suffix (delete_button); 146 | row.activated.connect (() => { 147 | selected (file); 148 | }); 149 | 150 | return row; 151 | } 152 | 153 | private Adw.AlertDialog setup_delete_dialog (string app_name) { 154 | string dialog_title = _("Delete Entry?"); 155 | if (app_name != "") { 156 | dialog_title = _("Delete Entry of “%s”?").printf (app_name); 157 | } 158 | 159 | var delete_dialog = new Adw.AlertDialog ( 160 | dialog_title, 161 | _("This removes the app from the launcher.") 162 | ); 163 | 164 | delete_dialog.add_response (Define.DialogResponse.CANCEL, _("_Cancel")); 165 | delete_dialog.add_response (Define.DialogResponse.OK, _("_Delete")); 166 | 167 | delete_dialog.set_response_appearance (Define.DialogResponse.OK, Adw.ResponseAppearance.DESTRUCTIVE); 168 | 169 | delete_dialog.default_response = Define.DialogResponse.CANCEL; 170 | delete_dialog.close_response = Define.DialogResponse.CANCEL; 171 | 172 | return delete_dialog; 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /src/Widget/CategoriesRow.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * SPDX-FileCopyrightText: 2021-2025 Ryo Nakano 4 | */ 5 | 6 | /** 7 | * List Categories of the app. 8 | * 9 | * There are ``Adw.SwitchRow`` for each category and ``Adw.SwitchRow.active`` represents 10 | * whether the corresponding category is listed in the desktop file. 11 | */ 12 | public class Widget.CategoriesRow : Adw.ExpanderRow { 13 | /** 14 | * A signal emitted when categories are changed (specifically, when a ``Adw.SwitchRow`` in ``this`` 15 | * is turned on / off). 16 | */ 17 | public signal void categories_changed (); 18 | 19 | /** 20 | * Preserve the category name and its corresponding switch row. 21 | */ 22 | private class RowItem : Object { 23 | public string category { get; construct; } 24 | public string label { get; construct; } 25 | 26 | public Adw.SwitchRow row { get; construct; } 27 | 28 | public RowItem (string category, string label) { 29 | Object ( 30 | category: category, 31 | label: label 32 | ); 33 | } 34 | 35 | construct { 36 | row = new Adw.SwitchRow () { 37 | title = _(label) 38 | }; 39 | } 40 | } 41 | 42 | /** 43 | * Stores all switch rows in ``this``. 44 | */ 45 | private Gee.ArrayList row_items; 46 | 47 | /** 48 | * Represent one category. 49 | */ 50 | private struct Categories { 51 | /** Name of the category. */ 52 | string name; 53 | /** Translatable name of the category. */ 54 | string translatable_name; 55 | } 56 | 57 | /** 58 | * Array of known categories. 59 | * 60 | * Note: See https://specifications.freedesktop.org/menu-spec/menu-spec-1.0.html#category-registry 61 | */ 62 | private const Categories[] CATEGORIES_TABLE = { 63 | { "AudioVideo", N_("Sound & Video") }, 64 | { "Audio", N_("Audio") }, 65 | { "Video", N_("Video") }, 66 | { "Development", N_("Programming") }, 67 | { "Education", N_("Education") }, 68 | { "Game", N_("Games") }, 69 | { "Graphics", N_("Graphics") }, 70 | { "Network", N_("Internet") }, 71 | { "Office", N_("Office") }, 72 | { "Science", N_("Science") }, 73 | { "Settings", N_("Settings") }, 74 | { "System", N_("System Tools") }, 75 | { "Utility", N_("Accessories") }, 76 | }; 77 | 78 | public CategoriesRow () { 79 | } 80 | 81 | construct { 82 | title = _("Categories"); 83 | subtitle = _("Categories applicable to the app. (You can select more than one.)"); 84 | 85 | row_items = new Gee.ArrayList (); 86 | 87 | // Create and append a switch row for each category 88 | foreach (var category in CATEGORIES_TABLE) { 89 | var item = new RowItem (category.name, category.translatable_name); 90 | item.row.notify["active"].connect (() => { 91 | categories_changed (); 92 | }); 93 | row_items.add (item); 94 | add_row (item.row); 95 | } 96 | } 97 | 98 | /** 99 | * Return categories in a string array. 100 | * 101 | * @return categories represented in a string array 102 | */ 103 | public string[] to_strv () { 104 | string[] _categories = {}; 105 | 106 | /* 107 | * Each category has a switch row. 108 | * If the switch row is activated, that means that category is selected, 109 | * so we add the name of that category in the Categories section 110 | * in the desktop file. 111 | */ 112 | row_items.foreach ((item) => { 113 | if (item.row.active) { 114 | _categories += item.category; 115 | } 116 | 117 | return true; 118 | }); 119 | 120 | return _categories; 121 | } 122 | 123 | /** 124 | * Reflect categories in a string array to the UI. 125 | * 126 | * @param categories categories represented in a string array 127 | */ 128 | public void from_strv (string[] categories) { 129 | row_items.foreach ((item) => { 130 | // Clear the current selection 131 | item.row.active = false; 132 | 133 | foreach (unowned string category in categories) { 134 | // The category is in the desktop file 135 | if (item.category == category) { 136 | item.row.active = true; 137 | // We find the category matching, so no longer need the rest of the loop. 138 | continue; 139 | } 140 | } 141 | 142 | return true; 143 | }); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/Widget/KeywordsRow.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * SPDX-FileCopyrightText: 2021-2025 Ryo Nakano 4 | */ 5 | 6 | /** 7 | * List Keywords of the app. 8 | * 9 | * There are {@link Widget.KeywordsRow.KeywordRow} for each keyword. 10 | */ 11 | public class Widget.KeywordsRow : Adw.ExpanderRow { 12 | /** 13 | * A signal emitted when keywords are changed. 14 | */ 15 | public signal void keywords_changed (); 16 | 17 | /** 18 | * A row that can edit or delete one keyword. 19 | */ 20 | private class KeywordRow : Adw.EntryRow { 21 | /** 22 | * A signal emitted when the delete button is clicked. 23 | */ 24 | public signal void delete_clicked (); 25 | 26 | /** 27 | * Create a new {@link Widget.KeywordsRow.KeywordRow} and set its text to ``keyword``. 28 | * 29 | * @param keyword the keyword to set to the text property 30 | */ 31 | public KeywordRow (string keyword) { 32 | title = _("Keyword"); 33 | text = keyword; 34 | 35 | var delete_button = new Gtk.Button.from_icon_name ("edit-delete-symbolic") { 36 | tooltip_text = _("Delete keyword"), 37 | valign = Gtk.Align.CENTER 38 | }; 39 | delete_button.add_css_class ("flat"); 40 | add_suffix (delete_button); 41 | 42 | delete_button.clicked.connect (() => { 43 | delete_clicked (); 44 | }); 45 | } 46 | } 47 | 48 | /** 49 | * Stores all keyword rows in ``this``. 50 | */ 51 | private Gee.ArrayList rows; 52 | 53 | public KeywordsRow () { 54 | } 55 | 56 | construct { 57 | title = _("Keywords"); 58 | subtitle = _("These words can be used as search terms."); 59 | 60 | rows = new Gee.ArrayList (); 61 | 62 | var add_keyword_button = new Gtk.Button.from_icon_name ("list-add-symbolic") { 63 | tooltip_text = _("Add a new keyword"), 64 | valign = Gtk.Align.CENTER 65 | }; 66 | add_keyword_button.add_css_class ("flat"); 67 | add_suffix (add_keyword_button); 68 | 69 | add_keyword_button.clicked.connect (() => { 70 | expanded = true; 71 | add_keyword (); 72 | }); 73 | } 74 | 75 | /** 76 | * Return keywords in a string array. 77 | * 78 | * @return keywords represented in a string array 79 | */ 80 | public string[] to_strv () { 81 | string[] _keywords = {}; 82 | 83 | rows.foreach ((row) => { 84 | _keywords += row.text; 85 | return true; 86 | }); 87 | 88 | return _keywords; 89 | } 90 | 91 | /** 92 | * Reflect keywords in a string array to the UI. 93 | * 94 | * @param keywords keywords represented in a string array 95 | */ 96 | public void from_strv (string[] keywords) { 97 | // Clear all of the currently added entries 98 | rows.foreach ((row) => { 99 | remove_row (row); 100 | return true; 101 | }); 102 | 103 | foreach (unowned string keyword in keywords) { 104 | add_keyword (keyword); 105 | } 106 | } 107 | 108 | /** 109 | * Add new keyword. 110 | * 111 | * @param keyword the keyword 112 | */ 113 | public void add_keyword (string keyword = "") { 114 | var row = new KeywordRow (keyword); 115 | ((Gtk.Editable) row).changed.connect (() => { 116 | keywords_changed (); 117 | }); 118 | row.delete_clicked.connect (() => { 119 | remove_row (row); 120 | keywords_changed (); 121 | }); 122 | rows.add (row); 123 | add_row (row); 124 | } 125 | 126 | /** 127 | * Remove row. 128 | * 129 | * @param row the {@link Widget.KeywordsRow.KeywordRow} to remove 130 | */ 131 | private void remove_row (KeywordRow row) { 132 | rows.remove (row); 133 | remove (row); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/meson.build: -------------------------------------------------------------------------------- 1 | config_data = configuration_data() 2 | config_data.set_quoted('LOCALEDIR', get_option('prefix') / get_option('localedir')) 3 | config_data.set_quoted('GETTEXT_PACKAGE', meson.project_name()) 4 | config_data.set_quoted('APP_ID', app_id) 5 | config_data.set_quoted('APP_VERSION', app_version) 6 | config_data.set_quoted('RESOURCE_PREFIX', '/' + meson.project_name().replace('.', '/')) 7 | config_file = configure_file( 8 | input: 'Config.vala.in', 9 | output: '@BASENAME@', 10 | configuration: config_data 11 | ) 12 | 13 | granite_dep = dependency('granite-7', version: '>= 7.2.0', required: get_option('granite')) 14 | if granite_dep.found() 15 | add_project_arguments('--define=USE_GRANITE', language: 'vala') 16 | endif 17 | 18 | dependencies = [ 19 | dependency('gee-0.8'), 20 | dependency('gio-unix-2.0'), 21 | dependency('glib-2.0', version: '>= 2.74'), 22 | granite_dep, 23 | dependency('gtk4', version: '>= 4.10'), 24 | dependency('libadwaita-1', version: '>= 1.5.0'), 25 | dependency('pango'), 26 | meson.get_compiler('vala').find_library('posix'), 27 | ] 28 | 29 | sources = files( 30 | 'Model/DesktopFile.vala', 31 | 'Model/DesktopFileModel.vala', 32 | 'Util/KeyFileUtil.vala', 33 | 'Util/DesktopFileUtil.vala', 34 | 'View/EditView.vala', 35 | 'View/FilesView.vala', 36 | 'Widget/CategoriesRow.vala', 37 | 'Widget/KeywordsRow.vala', 38 | 'Application.vala', 39 | 'Define.vala', 40 | 'MainWindow.vala', 41 | 'Util.vala', 42 | ) 43 | 44 | executable( 45 | app_id, 46 | asresources, 47 | config_file, 48 | sources, 49 | dependencies: dependencies, 50 | install: true 51 | ) 52 | 53 | if get_option('doc') 54 | valadoc = find_program('valadoc') 55 | 56 | valadoc_output_dir = 'valadoc' 57 | valadoc_target = custom_target( 58 | 'valadoc', 59 | command: [ 60 | valadoc, 61 | '--pkg=gee-0.8', 62 | '--pkg=gio-2.0', 63 | '--pkg=gio-unix-2.0', 64 | '--pkg=glib-2.0', 65 | '--pkg=gtk4', 66 | '--pkg=libadwaita-1', 67 | '--pkg=pango', 68 | '--pkg=posix', 69 | sources, 70 | config_file, 71 | '--package-name=' + meson.project_name(), 72 | '--package-version=' + meson.project_version(), 73 | '--verbose', 74 | '--force', 75 | '--use-svg-images', 76 | '-o', valadoc_output_dir, 77 | ], 78 | 79 | build_by_default: true, 80 | output: valadoc_output_dir 81 | ) 82 | endif 83 | -------------------------------------------------------------------------------- /subprojects/blueprint-compiler.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | directory = blueprint-compiler 3 | url = https://gitlab.gnome.org/jwestman/blueprint-compiler.git 4 | revision = v0.16.0 5 | depth = 1 6 | 7 | [provide] 8 | program_names = blueprint-compiler 9 | --------------------------------------------------------------------------------