├── .editorconfig ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── com.github.devalien.workspaces.json ├── data ├── Application.css ├── com.github.devalien.workspaces.appdata.xml.in ├── com.github.devalien.workspaces.desktop.in ├── com.github.devalien.workspaces.gschema.xml ├── css.gresource.xml ├── icons │ ├── 16 │ │ └── com.github.devalien.workspaces.svg │ ├── 24 │ │ └── com.github.devalien.workspaces.svg │ ├── 32 │ │ └── com.github.devalien.workspaces.svg │ ├── 48 │ │ └── com.github.devalien.workspaces.svg │ ├── 64 │ │ ├── com.github.devalien.workspaces.svg │ │ ├── document-new.svg │ │ └── document-page-setup.svg │ ├── 128 │ │ └── com.github.devalien.workspaces.svg │ └── com.github.devalien.workspaces.svg ├── meson.build └── screenshots │ ├── workspaces-preferences-add-item-dark.png │ ├── workspaces-preferences-editing-light.png │ ├── workspaces-preferences-light.png │ ├── workspaces-quick-launcher-dark.png │ └── workspaces-quick-launcher-light.png ├── debian ├── changelog ├── compat ├── control ├── copyright ├── rules └── source │ └── format ├── meson.build ├── meson └── post_install.py ├── po ├── LINGUAS ├── POTFILES ├── com.github.devalien.workspaces.pot ├── de.po ├── extra │ ├── LINGUAS │ ├── POTFILES │ └── meson.build ├── it.po ├── meson.build └── nl.po └── src ├── Application.vala ├── Controllers └── WorkspacesController.vala ├── Dialogs ├── About.vala ├── AddCategory.vala ├── AddItem.vala ├── AddWorkspace.vala ├── Dialog.vala └── Preferences.vala ├── Main.vala ├── Models ├── AppInfo.vala ├── Item.vala ├── ItemType.vala ├── SearchItem.vala ├── Workspace.vala └── WorkspacesStore.vala ├── Popovers ├── AppChooserPopover.vala └── IconChooserPopover.vala ├── PreferencesWindow.vala ├── QuickLaunchWindow.vala ├── Settings ├── CustomShortcutSettings.vala └── Shortcut.vala ├── Views ├── AlertView.vala ├── ItemEditor.vala ├── WorkspaceEditor.vala └── WorkspaceView.vala ├── Widgets ├── AppListBox.vala ├── Dot.vala ├── Entry.vala ├── ExpandableCategory.vala ├── IconButton.vala ├── IconListBox.vala ├── ItemRow.vala ├── QuickWelcome.vala ├── SearchListBox.vala ├── SearchListBoxItem.vala ├── SettingBox.vala ├── ShortcutEntry.vala ├── TypeComboBox.vala ├── Welcome.vala ├── WorkspaceItem.vala └── WorkspaceRow.vala └── meson.build /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig 2 | root = true 3 | 4 | # elementary defaults 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 = 80 12 | tab_width = 4 13 | 14 | [{*.xml,*.xml.in,*.yml}] 15 | tab_width = 2 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | build/ 3 | builddir 4 | build-aux 5 | *~ 6 | .vscode 7 | .buildconfig 8 | .flatpak-builder -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | language: node_js 4 | 5 | node_js: 6 | - 10.17.0 7 | 8 | sudo: required 9 | 10 | services: 11 | - docker 12 | 13 | addons: 14 | apt: 15 | sources: 16 | - ubuntu-toolchain-r-test 17 | packages: 18 | - libstdc++-5-dev 19 | 20 | install: 21 | - npm i -g @elementaryos/houston 22 | 23 | script: 24 | - houston ci -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | ![icon](data/icons/com.github.devalien.workspaces.svg) 4 | 5 | # Workspaces 6 | 7 | ## Make working on different projects easy again! 8 |
9 | 10 |
11 | 12 | ![Screenshot 01](data/screenshots/workspaces-quick-launcher-dark.png?raw=true) 13 | 14 | ![Screenshot 02](data/screenshots/workspaces-preferences-light.png?raw=true) 15 | 16 |
17 | 18 | ## Introduction 19 | Workspaces lets you configure and quickly launch all you need to work on a project. It can open in a second different instances of code, a specific website and a directory. 20 | 21 | ## Motivation 22 | I normally work on different projects throught the day, and some of them require a lot of apps to have open, they have different urls etc. 23 | 24 | With Workspaces I'm able with a click to open all the stuff I need for a project. I can also check links for github, isues etc for the projects. 25 | 26 | I used to use the [Workspaces](https://www.apptorium.com/workspaces) app for mac and I made it very similar. 27 | 28 | ## Installation 29 | 30 | [![Get it on Flathub](https://flathub.org/assets/badges/flathub-badge-en.png)](https://flathub.org/apps/details/com.github.devalien.workspaces) 31 | 32 | [![Get it on AppCenter](https://appcenter.elementary.io/badge.svg)](https://appcenter.elementary.io/com.github.devalien.workspaces) 33 | 34 | This app is available on the elementary OS AppCenter and Flathub. 35 | 36 | # Install it from source 37 | 38 | You can of course download and install this app from source. 39 | 40 | ## Dependencies 41 | 42 | Ensure you have these dependencies installed 43 | 44 | * granite 45 | * gtk+-3.0 46 | * json-glib-1.0 47 | * libgee-0.8 48 | * meson 49 | * vala 50 | * ninja 51 | 52 | ## Install, build and run 53 | 54 | Elementary OS 55 | 56 | ```bash 57 | # install elementary-sdk, meson and ninja 58 | sudo apt install elementary-sdk meson ninja 59 | # clone repository 60 | git clone git@github.com:DevAlien/workspaces.git workspaces 61 | # cd to dir 62 | cd workspaces 63 | # run meson 64 | meson build --prefix=/usr 65 | # cd to build, build and test 66 | cd build 67 | sudo ninja install && com.github.devalien.workspaces 68 | ``` 69 | 70 | 71 | 72 | Ubuntu based 73 | 74 | ```bash 75 | #Install meson 76 | sudo apt-get install python3 python3-pip python3-setuptools \ 77 | python3-wheel ninja-build 78 | sudo pip3 install meson 79 | #Install libraries 80 | sudo apt-get install libjson-glib-dev libgranite-dev libgee-0.8-dev libgtk-3-dev valac 81 | flatpak install --user flathub io.elementary.BaseApp//juno-19.08 82 | 83 | # clone repository 84 | git clone git@github.com:DevAlien/workspaces.git workspaces 85 | # cd to dir 86 | cd workspaces 87 | # run meson 88 | meson build --prefix=/usr 89 | # cd to build, build and test 90 | cd build 91 | sudo ninja install && com.github.devalien.workspaces 92 | ``` 93 | 94 | 95 | ## Generating pot file 96 | 97 | ```bash 98 | # after setting up meson build 99 | cd build 100 | 101 | # generates pot file 102 | sudo ninja com.github.devalien.workspaces-pot 103 | 104 | # to regenerate and propagate changes to every po file 105 | sudo ninja com.github.devalien.workspaces-update-po 106 | ``` 107 | 108 | ## Thanks/Credits 109 | 110 | - [Workspaces](https://www.apptorium.com/workspaces) Where I got the idea. 111 | - [Tuner](https://github.com/louis77/tuner) The creator of this app inspired me to build one myself. 112 | - [Clipped](https://github.com/davidmhewitt/clipped) I took inspiration for the Quick Launch from this app. 113 | - [AppEditor](https://github.com/donadigo/appeditor) Copied the edit part of the app, I will iterate over it in the next releases. 114 | -------------------------------------------------------------------------------- /com.github.devalien.workspaces.json: -------------------------------------------------------------------------------- 1 | { 2 | "app-id": "com.github.devalien.workspaces", 3 | "runtime": "org.freedesktop.Platform", 4 | "runtime-version": "19.08", 5 | "sdk": "org.freedesktop.Sdk", 6 | "base": "io.elementary.BaseApp", 7 | "base-version": "juno-19.08", 8 | "command": "workspaces-wrapper", 9 | "finish-args": [ 10 | "--share=ipc", 11 | "--socket=fallback-x11", 12 | "--socket=wayland", 13 | "--filesystem=host", 14 | "--talk-name=org.freedesktop.Flatpak" 15 | ], 16 | "cleanup": [ 17 | "/include", 18 | "/lib/pkgconfig", 19 | "/man", 20 | "/share/doc", 21 | "/share/gtk-doc", 22 | "/share/man", 23 | "/share/pkgconfig", 24 | "/share/vala", 25 | "*.la", 26 | "*.a" 27 | ], 28 | "modules": [ 29 | { 30 | "name": "wrapper", 31 | "buildsystem": "simple", 32 | "build-commands": [ 33 | "install -m755 workspaces-wrapper /app/bin" 34 | ], 35 | "sources": [ 36 | { 37 | "type": "script", 38 | "dest-filename": "workspaces-wrapper", 39 | "commands": [ 40 | "export PATH=$PATH:/run/host/usr/bin", 41 | "export XDG_DATA_DIRS=$XDG_DATA_DIRS:/run/host/usr/share", 42 | "com.github.devalien.workspaces" 43 | ] 44 | } 45 | ] 46 | }, 47 | { 48 | "name": "Workspaces", 49 | "buildsystem": "meson", 50 | "sources": [ 51 | { 52 | "type": "git", 53 | "url": "https://github.com/devalien/workspaces.git", 54 | "tag": "1.2.1", 55 | "commit": "919375876e4bc7625ddd4800c41750efac9c6ba3" 56 | } 57 | ], 58 | "post-install": [ 59 | "sed -i s:Exec=com.github.devalien.workspaces:Exec=/app/bin/workspaces-wrapper: /app/share/applications/com.github.devalien.workspaces.desktop" 60 | ] 61 | } 62 | ] 63 | } -------------------------------------------------------------------------------- /data/Application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | @define-color shaded_bg shade(@theme_base_color, 0.92); 23 | @define-color shaded_base shade(@theme_base_color, 0.98); 24 | 25 | .ql-entry { 26 | background-color: @shaded_base; 27 | border: none; 28 | border-bottom-left-radius: 0; 29 | border-bottom-right-radius:0; 30 | padding-top: 8px; 31 | padding-bottom: 6px; 32 | padding-right: 8px; 33 | padding-left:8px; 34 | } 35 | 36 | .ql-button { 37 | color: @theme_text_color; 38 | } 39 | 40 | .dialog-label { 41 | margin: 12px; 42 | } 43 | .source-list .view:selected { 44 | background-color: transparent; 45 | background-image: 46 | linear-gradient( 47 | to bottom, 48 | alpha ( 49 | #000, 50 | 0.11 51 | ), 52 | alpha ( 53 | #000, 54 | 0.07 55 | ) 56 | ); 57 | } 58 | 59 | .search-list-item-item { 60 | padding-left: 20px; 61 | } 62 | 63 | .sidebar, .left-header, .pane, .source-list, .drop_grid { 64 | background-color: @shaded_bg; 65 | } 66 | 67 | .left-header, .right-header, .left-header:backdrop, .right-header:backdrop { 68 | background-image: none; 69 | } 70 | .right-header, .right-stack { 71 | transition: all 250ms ease-in-out; 72 | } 73 | 74 | .right-header, .item-editor, .welcome { 75 | background-color: @shaded_base; 76 | } 77 | 78 | .right-header:dir(ltr) { 79 | border-left: none; 80 | border-top-left-radius: 0; 81 | } 82 | 83 | .right-header:dir(rtl) { 84 | border-top-right-radius: 0; 85 | } 86 | 87 | paned { 88 | background-color: @shaded_bg; 89 | border-bottom-left-radius: 4px; 90 | border-bottom-right-radius: 4px; 91 | border-top-left-radius: 4px; 92 | border-top-right-radius: 4px; 93 | } 94 | 95 | paned.horizontal > separator { 96 | background-image: 97 | linear-gradient( 98 | to right, 99 | @menu_separator 1px, 100 | @menu_separator_shadow 1px, 101 | @menu_separator_shadow 2px, 102 | transparent 2px 103 | ); 104 | margin-right: 0px; 105 | min-width: 1px; 106 | padding-right: 0px; 107 | } 108 | 109 | paned.vertical > separator { 110 | background-image: 111 | linear-gradient( 112 | @menu_separator -2px, 113 | @menu_separator_shadow 1px, 114 | @menu_separator_shadow 2px, 115 | transparent 2px 116 | ); 117 | margin-bottom: 0px; 118 | min-height: 1px; 119 | } 120 | 121 | .titlebar { 122 | border: none; 123 | } 124 | 125 | grid.titlebar { 126 | padding: 0; 127 | } 128 | 129 | .left-header:dir(ltr) { 130 | border-top-right-radius: 0; 131 | } 132 | 133 | .left-header:dir(rtl) { 134 | border-top-left-radius: 0; 135 | } 136 | 137 | .dialog-title { 138 | margin-left: 12px; 139 | } 140 | 141 | .icon-selector-button { 142 | border-width: 1px; 143 | border-color: @borders; 144 | } 145 | 146 | .large-search-entry { 147 | font-size: 175%; 148 | } 149 | 150 | 151 | .left-list-label { 152 | color: @theme_text_color; 153 | } 154 | 155 | .item-row:selected, .workspace-row:selected, .workspace-row:hover,.workspace-row:active { 156 | background-color: transparent; box-shadow : none; 157 | } 158 | 159 | 160 | .toogle-box:drop(active) { 161 | border: none;box-shadow : none; 162 | } 163 | 164 | .menu-danger { 165 | color: #ed5353; 166 | } 167 | 168 | .grid-motion { 169 | background-color: shade ( 170 | @theme_base_color, 171 | 1.4 172 | ); 173 | } 174 | 175 | .workspace-row:focus,.workspace-row:backdrop { 176 | outline-width: 0; 177 | } 178 | 179 | .left-header, .right-header { 180 | min-height: 0px; 181 | padding: 0; 182 | } 183 | 184 | .flat .image-button { 185 | padding: 3px; 186 | } 187 | 188 | .workspace-row:selected .toogle-box, .item-row:selected .item-row2 { 189 | color: shade (@theme_text_color, 0.8); 190 | background-color: transparent; 191 | background-image: 192 | linear-gradient( 193 | to bottom, 194 | alpha ( 195 | #000, 196 | 0.11 197 | ), 198 | alpha ( 199 | #000, 200 | 0.07 201 | ) 202 | ); 203 | border-image: 204 | linear-gradient( 205 | to bottom, 206 | alpha ( 207 | #000, 208 | 0.25 209 | ), 210 | alpha ( 211 | @theme_base_color, 212 | 0.3 213 | ) 214 | ) 1 1 1 1; 215 | border-style: solid; 216 | border-width: 1px 0; 217 | box-shadow: 218 | inset 0 1px 0 0 alpha (#000, 0.03), 219 | inset 0 -1px 0 0 alpha (#000, 0.1); 220 | } 221 | 222 | .item-row2 { 223 | padding-top: 1px; 224 | 225 | padding-left: 20px; 226 | border-style: solid; 227 | border-width: 1px 0; 228 | border-color: transparent; 229 | 230 | } 231 | 232 | .hidden-button { 233 | background-color: transparent; 234 | } 235 | 236 | .hidden-button image { 237 | transition: all 150ms ease-in-out; 238 | } 239 | 240 | .hidden-button image { 241 | color: @theme_text_color; 242 | } 243 | 244 | .hidden-button.opened image { 245 | -gtk-icon-transform: rotate(90deg); 246 | } 247 | 248 | .executor-button { 249 | background-color: transparent; 250 | } 251 | 252 | .image-button { 253 | min-height: 0; 254 | min-width: 0; 255 | } 256 | .bold-label { 257 | font-weight: bold; 258 | } 259 | 260 | .workspace-row, .item-row { 261 | padding: 0; 262 | } -------------------------------------------------------------------------------- /data/com.github.devalien.workspaces.appdata.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | com.github.devalien.workspaces 5 | CC0-1.0 6 | GPL-3.0+ 7 | Workspaces 8 | Always be ready for work 9 | 10 |

Make working on different projects easy again!

11 |

Workspaces lets you configure and quickly launch all you need to work on a project. It can open in a second different instances of code, a specific website and a directory

12 |
13 | 14 | com.github.devalien.workspaces 15 | 16 | Goncalo Margalho 17 | http://github.com/DevAlien/workspaces 18 | http://github.com/DevAlien/workspaces/issues 19 | http://github.com/DevAlien/workspaces/issues 20 | 21 | 22 | 23 | https://github.com/devalien/workspaces/raw/master/data/screenshots/workspaces-quick-launcher-light.png 24 | 25 | 26 | https://github.com/devalien/workspaces/raw/master/data/screenshots/workspaces-quick-launcher-dark.png 27 | 28 | 29 | https://github.com/devalien/workspaces/raw/master/data/screenshots/workspaces-preferences-light.png 30 | 31 | 32 | https://github.com/devalien/workspaces/raw/master/data/screenshots/workspaces-preferences-editing-light.png 33 | 34 | 35 | https://github.com/devalien/workspaces/raw/master/data/screenshots/workspaces-preferences-add-item-dark.png 36 | 37 | 38 | 39 | 40 | none 41 | none 42 | none 43 | none 44 | none 45 | none 46 | none 47 | none 48 | none 49 | none 50 | none 51 | none 52 | none 53 | none 54 | none 55 | none 56 | none 57 | none 58 | none 59 | none 60 | none 61 | none 62 | none 63 | none 64 | none 65 | none 66 | none 67 | 68 | 69 | 70 | 71 | 72 |

Fixes

73 |
    74 |
  • Fix run in terminal
  • 75 |
  • Fix Open quick launcher via the knob menu
  • 76 |
  • Fix crash when clicking on link on about dialog by max246
  • 77 |
  • Close quick launcher when selecting an item, unless you press CTRL by Philip-Scott
  • 78 |
  • Fixes visual issues on Switches, they were squashed
  • 79 |
80 |

Improvements

81 |
    82 |
  • Save or don't save latest position by max246
  • 83 |
  • Make the workspaces in the left list sortables with drag and drop
  • 84 |
  • Make the items in the left list sortables with drag and drop
  • 85 |
  • Items can be moved in another workspace just with drag and drop
  • 86 |
  • Workspaces are editable
  • 87 |
  • Workspaces are deletable (should display a warning message)
  • 88 |
  • Workspaces will display an image in the list, if they have one
  • 89 |
  • Items now have a blue dot indicating that they are part of the auto-run
  • 90 |
91 |

Translations

92 |
    93 |
  • German translation by meisenzahl
  • 94 |
  • Dutch Translation by Vistaus
  • 95 |
96 |
97 |
98 | 99 | 100 | 101 |

Release 3.0 for AppCenter

102 |
103 |
104 | 105 | 106 | 107 |

Fixes

108 |
    109 |
  • Fixed typo
  • 110 |
111 |
112 |
113 | 114 | 115 | 116 |

New Features

117 |
    118 |
  • Run commands in terminal
  • 119 |
120 |

Improvements

121 |
    122 |
  • App selection is now a popover
  • 123 |
  • Icon selection is now a popover
  • 124 |
  • Quick launcher now has a better keyboard handling
  • 125 |
126 |

Fixes

127 |
    128 |
  • Fixed theme for other gtk themes
  • 129 |
  • Fixed icon critical message
  • 130 |
131 |
132 |
133 | 134 | 135 | 136 |

Bug Fixes

137 |
    138 |
  • Fixed shortcut for flatpak
  • 139 |
  • Fixed load apps for flatpak
  • 140 |
141 |
142 |
143 | 144 | 145 | 146 |

Features

147 |
    148 |
  • Added default shortcut to launch the app and a way to modify it
  • 149 |
  • Add missing icons
  • 150 |
  • Add URL type
  • 151 |
  • Add Application type
  • 152 |
  • Add Application + Directory type
  • 153 |
  • Add Directory type
  • 154 |
  • Add Custom type
  • 155 |
156 |

Bug Fixes

157 |
    158 |
  • When closing preferences, if you were in the quick launcher, it will open back that one
  • 159 |
160 |
161 |
162 | 163 | 164 |

Improvementes

165 |
    166 |
  • Improved Icon
  • 167 |
  • Add missing icons
  • 168 |
169 |

Bug Fixes

170 |
    171 |
  • Set text color of the search icon on the header
  • 172 |
173 |

Fixes

174 |
    175 |
  • Fix control file for deb packaging
  • 176 |
177 |
178 |
179 | 180 | 181 |

Initial release

182 |
183 |
184 |
185 | 186 | 187 | #ffb017 188 | #000 189 | 0 190 | 191 | 192 |
193 | -------------------------------------------------------------------------------- /data/com.github.devalien.workspaces.desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | Name=Workspaces 4 | Comment=Workspaces to be always ready to work 5 | GenericName=Workspaces 6 | Exec=com.github.devalien.workspaces 7 | Icon=com.github.devalien.workspaces 8 | Terminal=false 9 | Categories=Utility;GTK; 10 | Keywords=Develop;Workspace;Launcher; -------------------------------------------------------------------------------- /data/com.github.devalien.workspaces.gschema.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 360 7 | Horizontal position 8 | Saved horizontal position of main window 9 | 10 | 11 | 640 12 | Vertical position 13 | Saved vertical position of main window 14 | 15 | 16 | 1040 17 | Window width 18 | Saved width of main window 19 | 20 | 21 | 400 22 | Window height 23 | Saved height of main window 24 | 25 | 26 | 255 27 | Most recent pane position 28 | Most recent pane position 29 | 30 | 31 | true 32 | Whether this is the first time that Workspaces has opened 33 | Used to determine whether or not to perform initial install steps 34 | 35 | 36 | true 37 | Define to keep the window centre or not 38 | Used when opening preference 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /data/css.gresource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Application.css 5 | 6 | 7 | 8 | icons/64/document-new.svg 9 | icons/64/document-page-setup.svg 10 | 11 | -------------------------------------------------------------------------------- /data/icons/16/com.github.devalien.workspaces.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 39 | 44 | 56 | 57 | 59 | 62 | 66 | 70 | 71 | 73 | 77 | 81 | 82 | 91 | 93 | 97 | 101 | 105 | 109 | 110 | 119 | 121 | 125 | 129 | 130 | 138 | 147 | 148 | 150 | 151 | 153 | image/svg+xml 154 | 156 | 157 | 158 | 159 | 160 | 169 | 174 | 181 | 190 | 199 | 208 | 212 | 221 | 230 | 239 | 244 | 249 | 253 | 254 | -------------------------------------------------------------------------------- /data/meson.build: -------------------------------------------------------------------------------- 1 | # Install icons 2 | icon_sizes = ['16', '24', '32', '48', '64', '128'] 3 | 4 | foreach i : icon_sizes 5 | install_data ( 6 | join_paths ('icons', i, meson.project_name () + '.svg'), 7 | install_dir: join_paths (get_option ('datadir'), 'icons', 'hicolor', i + 'x' + i, 'apps') 8 | ) 9 | install_data ( 10 | join_paths ('icons', i, meson.project_name () + '.svg'), 11 | install_dir: join_paths (get_option ('datadir'), 'icons', 'hicolor', i + 'x' + i + '@2', 'apps') 12 | ) 13 | endforeach 14 | 15 | # Translate and install our .desktop file so the Applications Menu will see it 16 | i18n.merge_file ( 17 | input: meson.project_name () + '.desktop.in', 18 | output: meson.project_name () + '.desktop', 19 | po_dir: join_paths (meson.source_root (), 'po', 'extra'), 20 | type: 'desktop', 21 | install: true, 22 | install_dir: join_paths (get_option ('datadir'), 'applications') 23 | ) 24 | 25 | # Translate and install our .appdata.xml file so AppCenter will see it 26 | i18n.merge_file ( 27 | input: meson.project_name () + '.appdata.xml.in', 28 | output: meson.project_name () + '.appdata.xml', 29 | po_dir: join_paths (meson.source_root (), 'po', 'extra'), 30 | install: true, 31 | install_dir: join_paths (get_option ('datadir'), 'metainfo') 32 | ) 33 | 34 | # Install schema 35 | install_data ( 36 | meson.project_name () + '.gschema.xml', 37 | install_dir: join_paths (get_option ('datadir'), 'glib-2.0', 'schemas') 38 | ) -------------------------------------------------------------------------------- /data/screenshots/workspaces-preferences-add-item-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevAlien/workspaces/fb45ebfbc32ca57121b2db34bfd61536089288c3/data/screenshots/workspaces-preferences-add-item-dark.png -------------------------------------------------------------------------------- /data/screenshots/workspaces-preferences-editing-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevAlien/workspaces/fb45ebfbc32ca57121b2db34bfd61536089288c3/data/screenshots/workspaces-preferences-editing-light.png -------------------------------------------------------------------------------- /data/screenshots/workspaces-preferences-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevAlien/workspaces/fb45ebfbc32ca57121b2db34bfd61536089288c3/data/screenshots/workspaces-preferences-light.png -------------------------------------------------------------------------------- /data/screenshots/workspaces-quick-launcher-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevAlien/workspaces/fb45ebfbc32ca57121b2db34bfd61536089288c3/data/screenshots/workspaces-quick-launcher-dark.png -------------------------------------------------------------------------------- /data/screenshots/workspaces-quick-launcher-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevAlien/workspaces/fb45ebfbc32ca57121b2db34bfd61536089288c3/data/screenshots/workspaces-quick-launcher-light.png -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | com.github.devalien.workspaces (3.1.0) RELEASED; urgency=low 2 | 3 | * Fix run in terminal * 4 | * Fix Open quick launcher via the knob menu * 5 | * Fix crash when clicking on link on about dialog by max246 * 6 | * Close quick launcher when selecting an item, unless you press CTRL by Philip-Scott * 7 | * Fixes visual issues on Switches, they were squashed * 8 | * Save or don't save latest position by max246 * 9 | * Make the workspaces in the left list sortables with drag and drop * 10 | * Make the items in the left list sortables with drag and drop * 11 | * Items can be moved in another workspace just with drag and drop * 12 | * Workspaces are editable * 13 | * Workspaces are deletable (should display a warning message) * 14 | * Workspaces will display an image in the list, if they have one * 15 | * Items now have a blue dot indicating that they are part of the auto-run * 16 | * German translation by meisenzahl * 17 | * Dutch Translation by Vistaus * 18 | 19 | -- Goncalo Margalho Tue, 14 Aug 2020 11:50:00 +0200 20 | 21 | 22 | com.github.devalien.workspaces (3.0.0) RELEASED; urgency=low 23 | 24 | * Release for AppCenter. * 25 | 26 | -- Goncalo Margalho Tue, 01 Aug 2020 10:50:00 +0200 27 | 28 | com.github.devalien.workspaces (1.3.1) RELEASED; urgency=low 29 | 30 | * Fixed typo. * 31 | 32 | -- Goncalo Margalho Mon, 23 Aug 2020 22:50:00 +0200 33 | 34 | com.github.devalien.workspaces (1.3.0) RELEASED; urgency=low 35 | 36 | * Run commands in terminal. * 37 | * App selection is now a popover. * 38 | * Icon selection is now a popover. * 39 | * Quick launcher now has a better keyboard handling. * 40 | * Fixed theme for other gtk themes. * 41 | * Fixed icon critical message. * 42 | 43 | -- Goncalo Margalho Mon, 23 Aug 2020 03:10:00 +0200 44 | 45 | com.github.devalien.workspaces (1.2.1) RELEASED; urgency=low 46 | 47 | * Fixed shortcut for flatpak. * 48 | * Fixed load apps for flatpak. * 49 | 50 | -- Goncalo Margalho Mon, 21 Aug 2020 12:20:20 +0200 51 | 52 | com.github.devalien.workspaces (1.2.0) RELEASED; urgency=low 53 | 54 | * Added default shortcut to launch the app and a way to modify it. * 55 | * Add missing icons. * 56 | * Add URL type. * 57 | * Add Application type. * 58 | * Add Application + Directory type. * 59 | * Add Directory type. * 60 | * Add Custom type. * 61 | * When closing preferences, if you were in the quick launcher, it will open back that one. * 62 | 63 | -- Goncalo Margalho Mon, 21 Aug 2020 00:20:20 +0200 64 | 65 | com.github.devalien.workspaces (1.1.0) RELEASED; urgency=low 66 | 67 | * Fix control file for deb packaging. * 68 | 69 | -- Goncalo Margalho Mon, 17 Aug 2020 13:41:57 +0200 70 | 71 | com.github.devalien.workspaces (1.0.0) UNRELEASED; urgency=low 72 | 73 | * Initial Release. * 74 | 75 | -- Goncalo Margalho Mon, 17 Aug 2020 8:41:57 +0200 76 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: com.github.devalien.workspaces 2 | Section: x11 3 | Priority: optional 4 | Maintainer: Goncalo Margalho 5 | Build-Depends: cmake (>= 2.8), 6 | debhelper (>= 9), 7 | libgtk-3-dev, 8 | meson, 9 | valac (>= 0.40.0), 10 | libgranite-dev, 11 | libjson-glib-dev, 12 | libgee-0.8-dev 13 | Standards-Version: 3.9.3 14 | 15 | Package: com.github.devalien.workspaces 16 | Architecture: any 17 | Depends: ${misc:Depends}, ${shlibs:Depends} 18 | Description: Workspaces to be always ready to work 19 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://dep.debian.net/deps/dep5 2 | Upstream-Name: deb-packaging 3 | Source: https://github.com/devalien/workspaces 4 | 5 | Files: * 6 | Copyright: 20 Goncalo Margalho 7 | License: GPL-3.0+ 8 | 9 | License: GPL-3.0+ 10 | This program is free software: you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | . 15 | This package is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details. 19 | . 20 | You should have received a copy of the GNU General Public License 21 | along with this program. If not, see . 22 | . 23 | On Debian systems, the complete text of the GNU General 24 | Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". 25 | 26 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | 12 | %: 13 | dh $@ 14 | 15 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | # Project name, programming language and version 2 | project ( 3 | 'com.github.devalien.workspaces', 4 | 'vala', 'c', 5 | version: '3.1.0' 6 | ) 7 | 8 | # Translation module 9 | i18n = import ('i18n') 10 | 11 | # Project arguments 12 | add_project_arguments ( 13 | '-DGETTEXT_PACKAGE="@0@"'.format (meson.project_name ()), 14 | language: 'c' 15 | ) 16 | 17 | 18 | gnome = import('gnome') 19 | 20 | asresources = gnome.compile_resources( 21 | 'as-resources', 'data/css.gresource.xml', 22 | source_dir: 'data', 23 | c_name: 'as' 24 | ) 25 | 26 | # Listing dependencies 27 | dependencies = [ 28 | dependency ('glib-2.0'), 29 | dependency ('gtk+-3.0'), 30 | dependency ('gee-0.8'), 31 | dependency ('granite'), 32 | dependency ('json-glib-1.0') 33 | ] 34 | 35 | subdir ('src') 36 | 37 | # Executable 38 | executable ( 39 | meson.project_name (), 40 | sources, 41 | asresources, 42 | dependencies: dependencies, 43 | install: true 44 | ) 45 | 46 | subdir ('data') 47 | subdir ('po') 48 | 49 | meson.add_install_script ('meson/post_install.py') 50 | -------------------------------------------------------------------------------- /meson/post_install.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from os import path, environ 4 | import subprocess 5 | 6 | prefix = environ.get('MESON_INSTALL_PREFIX', '/usr/local') 7 | schemadir = path.join(environ['MESON_INSTALL_PREFIX'], 'share', 'glib-2.0', 'schemas') 8 | datadir = path.join(prefix, 'share') 9 | desktop_database_dir = path.join(datadir, 'applications') 10 | 11 | if not environ.get('DESTDIR'): 12 | print('Compiling gsettings schemas…') 13 | subprocess.call(['glib-compile-schemas', schemadir]) 14 | print('Updating desktop database…') 15 | subprocess.call(['update-desktop-database', '-q', desktop_database_dir]) 16 | print('Updating icon cache…') 17 | subprocess.call(['gtk-update-icon-cache', '-qtf', path.join(datadir, 'icons', 'hicolor')]) 18 | -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | nl 2 | de 3 | it 4 | -------------------------------------------------------------------------------- /po/POTFILES: -------------------------------------------------------------------------------- 1 | src/Application.vala 2 | src/PreferencesWindow.vala 3 | src/QuickLaunchWindow.vala 4 | 5 | src/Dialogs/AddCategory.vala 6 | src/Dialogs/AddItem.vala 7 | src/Dialogs/AddWorkspace.vala 8 | src/Dialogs/Dialog.vala 9 | src/Dialogs/Preferences.vala 10 | 11 | src/Popovers/AppChooserPopover.vala 12 | src/Popovers/IconChooserPopover.vala 13 | 14 | src/Settings/Shortcut.vala 15 | 16 | src/Views/ItemEditor.vala 17 | 18 | src/Widgets/ExpandableCategory.vala 19 | src/Widgets/IconButton.vala 20 | src/Widgets/QuickWelcome.vala 21 | src/Widgets/TypeComboBox.vala 22 | src/Widgets/Welcome.vala 23 | src/Widgets/WorkspaceItem.vala -------------------------------------------------------------------------------- /po/com.github.devalien.workspaces.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.devalien.workspaces package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: com.github.devalien.workspaces\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2020-09-14 11:56+0200\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 | #: src/PreferencesWindow.vala:53 src/QuickLaunchWindow.vala:38 21 | msgid "Workspaces" 22 | msgstr "" 23 | 24 | #: src/PreferencesWindow.vala:128 src/Dialogs/AddWorkspace.vala:27 25 | #: src/Widgets/QuickWelcome.vala:29 src/Widgets/Welcome.vala:29 26 | msgid "Add Workspace" 27 | msgstr "" 28 | 29 | #: src/PreferencesWindow.vala:141 src/Dialogs/AddItem.vala:27 30 | #: src/Widgets/Welcome.vala:30 31 | msgid "Add Item" 32 | msgstr "" 33 | 34 | #: src/PreferencesWindow.vala:234 src/Views/ItemEditor.vala:135 35 | msgid "Settings" 36 | msgstr "" 37 | 38 | #: src/PreferencesWindow.vala:238 39 | msgid "About" 40 | msgstr "" 41 | 42 | #: src/PreferencesWindow.vala:247 43 | msgid "Light mode" 44 | msgstr "" 45 | 46 | #: src/PreferencesWindow.vala:248 47 | msgid "Dark mode" 48 | msgstr "" 49 | 50 | #: src/PreferencesWindow.vala:272 src/PreferencesWindow.vala:276 51 | msgid "Open Quick Launcher" 52 | msgstr "" 53 | 54 | #: src/PreferencesWindow.vala:299 src/QuickLaunchWindow.vala:112 55 | #: src/Dialogs/Preferences.vala:35 56 | msgid "Preferences" 57 | msgstr "" 58 | 59 | #: src/PreferencesWindow.vala:422 60 | msgid "Cannot create an item without a workspace" 61 | msgstr "" 62 | 63 | #: src/PreferencesWindow.vala:424 64 | msgid "Ok" 65 | msgstr "" 66 | 67 | #: src/PreferencesWindow.vala:428 68 | msgid "To add an item you first need to create a workspace." 69 | msgstr "" 70 | 71 | #: src/PreferencesWindow.vala:449 72 | #, c-format 73 | msgid "You are deleting %s" 74 | msgstr "" 75 | 76 | #: src/PreferencesWindow.vala:450 77 | msgid "" 78 | "Deleting a workspace is an irreversible action. Are you sure you want to " 79 | "delete it?" 80 | msgstr "" 81 | 82 | #: src/PreferencesWindow.vala:455 83 | msgid "DELETE" 84 | msgstr "" 85 | 86 | #: src/QuickLaunchWindow.vala:46 87 | msgid "Search Workspaces…" 88 | msgstr "" 89 | 90 | #: src/QuickLaunchWindow.vala:86 91 | msgid "No Workspaces or Items Found" 92 | msgstr "" 93 | 94 | #: src/QuickLaunchWindow.vala:205 95 | msgid "Try changing search terms." 96 | msgstr "" 97 | 98 | #: src/Dialogs/AddCategory.vala:27 99 | msgid "Add Collection" 100 | msgstr "" 101 | 102 | #: src/Dialogs/AddCategory.vala:28 103 | msgid "My Collection" 104 | msgstr "" 105 | 106 | #: src/Dialogs/AddCategory.vala:30 src/Dialogs/AddItem.vala:30 107 | #: src/Dialogs/AddWorkspace.vala:30 108 | msgid "Create" 109 | msgstr "" 110 | 111 | #: src/Dialogs/AddCategory.vala:47 112 | msgid "Request name must not be empty." 113 | msgstr "" 114 | 115 | #: src/Dialogs/AddItem.vala:28 116 | msgid "New Item" 117 | msgstr "" 118 | 119 | #: src/Dialogs/AddItem.vala:37 120 | msgid "Add to workspace" 121 | msgstr "" 122 | 123 | #: src/Dialogs/AddItem.vala:69 124 | msgid "Item name must not be empty." 125 | msgstr "" 126 | 127 | #: src/Dialogs/AddWorkspace.vala:28 128 | msgid "My Workspace" 129 | msgstr "" 130 | 131 | #: src/Dialogs/AddWorkspace.vala:50 132 | msgid "Workspace name must not be empty." 133 | msgstr "" 134 | 135 | #: src/Dialogs/Dialog.vala:38 136 | msgid "Name:" 137 | msgstr "" 138 | 139 | #: src/Dialogs/Dialog.vala:42 src/Dialogs/Preferences.vala:41 140 | msgid "Close" 141 | msgstr "" 142 | 143 | #. Window properties 144 | #: src/Dialogs/Preferences.vala:33 145 | msgid "Welcome" 146 | msgstr "" 147 | 148 | #: src/Dialogs/Preferences.vala:64 149 | msgid "" 150 | "Workspaces can be opened with a quick shortcut so you'll be able to open " 151 | "your projects faster." 152 | msgstr "" 153 | 154 | #: src/Dialogs/Preferences.vala:81 155 | msgid "General Settings" 156 | msgstr "" 157 | 158 | #: src/Dialogs/Preferences.vala:101 159 | msgid "Open Workspaces Shortcut:" 160 | msgstr "" 161 | 162 | #: src/Dialogs/Preferences.vala:123 163 | msgid "Save last position of window" 164 | msgstr "" 165 | 166 | #: src/Popovers/AppChooserPopover.vala:30 167 | #: src/Popovers/IconChooserPopover.vala:31 168 | msgid "Choose" 169 | msgstr "" 170 | 171 | #: src/Popovers/AppChooserPopover.vala:52 172 | msgid "Search apps…" 173 | msgstr "" 174 | 175 | #: src/Popovers/IconChooserPopover.vala:38 176 | msgid "From file" 177 | msgstr "" 178 | 179 | #: src/Popovers/IconChooserPopover.vala:58 180 | msgid "Search icons…" 181 | msgstr "" 182 | 183 | #: src/Popovers/IconChooserPopover.vala:78 184 | msgid "All Files" 185 | msgstr "" 186 | 187 | #: src/Popovers/IconChooserPopover.vala:82 188 | msgid "Images" 189 | msgstr "" 190 | 191 | #: src/Popovers/IconChooserPopover.vala:86 src/Views/ItemEditor.vala:440 192 | #: src/Views/ItemEditor.vala:498 193 | msgid "Select an image" 194 | msgstr "" 195 | 196 | #: src/Settings/Shortcut.vala:30 197 | msgid "Disabled" 198 | msgstr "" 199 | 200 | #: src/Settings/Shortcut.vala:39 201 | msgid "Ctrl" 202 | msgstr "" 203 | 204 | #: src/Views/ItemEditor.vala:97 src/Views/ItemEditor.vala:102 205 | msgid "Display name" 206 | msgstr "" 207 | 208 | #: src/Views/ItemEditor.vala:148 209 | msgid "Auto Launch with workspace" 210 | msgstr "" 211 | 212 | #: src/Views/ItemEditor.vala:159 213 | msgid "Run in terminal" 214 | msgstr "" 215 | 216 | #: src/Views/ItemEditor.vala:174 src/Widgets/ExpandableCategory.vala:79 217 | #: src/Widgets/WorkspaceItem.vala:55 218 | msgid "Delete" 219 | msgstr "" 220 | 221 | #: src/Views/ItemEditor.vala:180 222 | msgid "Duplicate" 223 | msgstr "" 224 | 225 | #: src/Views/ItemEditor.vala:185 226 | msgid "Test" 227 | msgstr "" 228 | 229 | #: src/Views/ItemEditor.vala:261 230 | msgid "Program to execute along with it's arguments" 231 | msgstr "" 232 | 233 | #: src/Views/ItemEditor.vala:267 234 | msgid "Command Line" 235 | msgstr "" 236 | 237 | #. var terminal_box = new Workspaces.Widgets.SettingBox (_ ("Auto Launch with workspace"), auto_start_switch, true); 238 | #: src/Views/ItemEditor.vala:269 239 | msgid "Custom Settings" 240 | msgstr "" 241 | 242 | #. website_url_entry.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT); 243 | #: src/Views/ItemEditor.vala:290 244 | msgid "Url that will be opened when lauched" 245 | msgstr "" 246 | 247 | #: src/Views/ItemEditor.vala:296 248 | msgid "Website URL" 249 | msgstr "" 250 | 251 | #: src/Views/ItemEditor.vala:298 252 | msgid "URL Settings" 253 | msgstr "" 254 | 255 | #: src/Views/ItemEditor.vala:334 src/Views/ItemEditor.vala:394 256 | msgid "Select Application" 257 | msgstr "" 258 | 259 | #: src/Views/ItemEditor.vala:361 src/Views/ItemEditor.vala:422 260 | msgid "Application to launch" 261 | msgstr "" 262 | 263 | #: src/Views/ItemEditor.vala:363 264 | msgid "Application Settings" 265 | msgstr "" 266 | 267 | #: src/Views/ItemEditor.vala:430 src/Views/ItemEditor.vala:488 268 | msgid "Path to the directory" 269 | msgstr "" 270 | 271 | #: src/Views/ItemEditor.vala:437 src/Views/ItemEditor.vala:495 272 | msgid "Choose Directory" 273 | msgstr "" 274 | 275 | #: src/Views/ItemEditor.vala:461 src/Views/ItemEditor.vala:519 276 | msgid "Directory to open" 277 | msgstr "" 278 | 279 | #. url_settings_grid.add_widget (application_box); 280 | #: src/Views/ItemEditor.vala:464 281 | msgid "Application Directory Settings" 282 | msgstr "" 283 | 284 | #. url_settings_grid.add_widget (application_box); 285 | #: src/Views/ItemEditor.vala:522 286 | msgid "Directory Settings" 287 | msgstr "" 288 | 289 | #: src/Widgets/QuickWelcome.vala:28 290 | msgid "There are no workspaces" 291 | msgstr "" 292 | 293 | #: src/Widgets/QuickWelcome.vala:29 src/Widgets/Welcome.vala:29 294 | msgid "Add a new workspace" 295 | msgstr "" 296 | 297 | #: src/Widgets/TypeComboBox.vala:30 298 | msgid "URL" 299 | msgstr "" 300 | 301 | #: src/Widgets/TypeComboBox.vala:31 302 | msgid "Directory" 303 | msgstr "" 304 | 305 | #: src/Widgets/TypeComboBox.vala:32 306 | msgid "Application" 307 | msgstr "" 308 | 309 | #: src/Widgets/TypeComboBox.vala:33 310 | msgid "Application + Directory" 311 | msgstr "" 312 | 313 | #: src/Widgets/TypeComboBox.vala:34 314 | msgid "Custom command" 315 | msgstr "" 316 | 317 | #: src/Widgets/Welcome.vala:28 318 | msgid "No Workspace selected" 319 | msgstr "" 320 | 321 | #: src/Widgets/Welcome.vala:30 322 | msgid "Add a new item" 323 | msgstr "" 324 | -------------------------------------------------------------------------------- /po/de.po: -------------------------------------------------------------------------------- 1 | # German translations for com.github.devalien.workspaces package. 2 | # Copyright (C) 2020 THE com.github.devalien.workspaces'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the com.github.devalien.workspaces package. 4 | # Marius Meisenzahl , 2020. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: com.github.devalien.workspaces\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2020-09-14 11:56+0200\n" 11 | "PO-Revision-Date: 2020-09-11 16:03+0200\n" 12 | "Last-Translator: Marius Meisenzahl \n" 13 | "Language-Team: none\n" 14 | "Language: de\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 | 20 | #: src/PreferencesWindow.vala:53 src/QuickLaunchWindow.vala:38 21 | msgid "Workspaces" 22 | msgstr "Workspaces" 23 | 24 | #: src/PreferencesWindow.vala:128 src/Dialogs/AddWorkspace.vala:27 25 | #: src/Widgets/QuickWelcome.vala:29 src/Widgets/Welcome.vala:29 26 | msgid "Add Workspace" 27 | msgstr "Arbeitsfläche hinzufügen" 28 | 29 | #: src/PreferencesWindow.vala:141 src/Dialogs/AddItem.vala:27 30 | #: src/Widgets/Welcome.vala:30 31 | msgid "Add Item" 32 | msgstr "Element hinzufügen" 33 | 34 | #: src/PreferencesWindow.vala:234 src/Views/ItemEditor.vala:135 35 | msgid "Settings" 36 | msgstr "Einstellungen" 37 | 38 | #: src/PreferencesWindow.vala:238 39 | msgid "About" 40 | msgstr "Über" 41 | 42 | #: src/PreferencesWindow.vala:247 43 | msgid "Light mode" 44 | msgstr "Heller Modus" 45 | 46 | #: src/PreferencesWindow.vala:248 47 | msgid "Dark mode" 48 | msgstr "Dunkler Modus" 49 | 50 | #: src/PreferencesWindow.vala:272 src/PreferencesWindow.vala:276 51 | msgid "Open Quick Launcher" 52 | msgstr "" 53 | 54 | #: src/PreferencesWindow.vala:299 src/QuickLaunchWindow.vala:112 55 | #: src/Dialogs/Preferences.vala:35 56 | msgid "Preferences" 57 | msgstr "Präferenzen" 58 | 59 | #: src/PreferencesWindow.vala:422 60 | msgid "Cannot create an item without a workspace" 61 | msgstr "Es kann kein Element ohne eine Arbeitsfläche erstellt werden" 62 | 63 | #: src/PreferencesWindow.vala:424 64 | msgid "Ok" 65 | msgstr "Okay" 66 | 67 | #: src/PreferencesWindow.vala:428 68 | msgid "To add an item you first need to create a workspace." 69 | msgstr "" 70 | "Um ein Element hinzufügen, muss erst eine Arbeitsfläche erstellt werden." 71 | 72 | #: src/PreferencesWindow.vala:449 73 | #, c-format 74 | msgid "You are deleting %s" 75 | msgstr "" 76 | 77 | #: src/PreferencesWindow.vala:450 78 | msgid "" 79 | "Deleting a workspace is an irreversible action. Are you sure you want to " 80 | "delete it?" 81 | msgstr "" 82 | 83 | #: src/PreferencesWindow.vala:455 84 | msgid "DELETE" 85 | msgstr "" 86 | 87 | #: src/QuickLaunchWindow.vala:46 88 | msgid "Search Workspaces…" 89 | msgstr "Suche Arbeitsflächen…" 90 | 91 | #: src/QuickLaunchWindow.vala:86 92 | msgid "No Workspaces or Items Found" 93 | msgstr "Es wurden keine Arbeitsflächen oder Elemente gefunden" 94 | 95 | #: src/QuickLaunchWindow.vala:205 96 | msgid "Try changing search terms." 97 | msgstr "Probiere andere Suchbegriffe." 98 | 99 | #: src/Dialogs/AddCategory.vala:27 100 | msgid "Add Collection" 101 | msgstr "Sammlung hinzufügen" 102 | 103 | #: src/Dialogs/AddCategory.vala:28 104 | msgid "My Collection" 105 | msgstr "Meine Sammlung" 106 | 107 | #: src/Dialogs/AddCategory.vala:30 src/Dialogs/AddItem.vala:30 108 | #: src/Dialogs/AddWorkspace.vala:30 109 | msgid "Create" 110 | msgstr "Erstellen" 111 | 112 | #: src/Dialogs/AddCategory.vala:47 113 | msgid "Request name must not be empty." 114 | msgstr "Eingegebener Name darf nicht leer sein." 115 | 116 | #: src/Dialogs/AddItem.vala:28 117 | msgid "New Item" 118 | msgstr "Neues Element" 119 | 120 | #: src/Dialogs/AddItem.vala:37 121 | msgid "Add to workspace" 122 | msgstr "Zur Arbeitsfläche hinzufügen" 123 | 124 | #: src/Dialogs/AddItem.vala:69 125 | msgid "Item name must not be empty." 126 | msgstr "Name des Elements darf nicht leer sein." 127 | 128 | #: src/Dialogs/AddWorkspace.vala:28 129 | msgid "My Workspace" 130 | msgstr "Meine Arbeitsfläche" 131 | 132 | #: src/Dialogs/AddWorkspace.vala:50 133 | msgid "Workspace name must not be empty." 134 | msgstr "Name der Arbeitsfläche darf nicht leer sein." 135 | 136 | #: src/Dialogs/Dialog.vala:38 137 | msgid "Name:" 138 | msgstr "Name:" 139 | 140 | #: src/Dialogs/Dialog.vala:42 src/Dialogs/Preferences.vala:41 141 | msgid "Close" 142 | msgstr "Schließen" 143 | 144 | #. Window properties 145 | #: src/Dialogs/Preferences.vala:33 146 | msgid "Welcome" 147 | msgstr "" 148 | 149 | #: src/Dialogs/Preferences.vala:64 150 | msgid "" 151 | "Workspaces can be opened with a quick shortcut so you'll be able to open " 152 | "your projects faster." 153 | msgstr "" 154 | "Arbeitsflächen kann über eine Tastenkombination geöffnet werden, sodass du " 155 | "deine Projekte schneller öffnen kannst." 156 | 157 | #: src/Dialogs/Preferences.vala:81 158 | msgid "General Settings" 159 | msgstr "Allgemeine Einstellungen" 160 | 161 | #: src/Dialogs/Preferences.vala:101 162 | msgid "Open Workspaces Shortcut:" 163 | msgstr "Tastenkombination zum Öffnen von Workspaces:" 164 | 165 | #: src/Dialogs/Preferences.vala:123 166 | msgid "Save last position of window" 167 | msgstr "" 168 | 169 | #: src/Popovers/AppChooserPopover.vala:30 170 | #: src/Popovers/IconChooserPopover.vala:31 171 | msgid "Choose" 172 | msgstr "Auswählen" 173 | 174 | #: src/Popovers/AppChooserPopover.vala:52 175 | msgid "Search apps…" 176 | msgstr "Suche Apps…" 177 | 178 | #: src/Popovers/IconChooserPopover.vala:38 179 | msgid "From file" 180 | msgstr "Aus einer Datei" 181 | 182 | #: src/Popovers/IconChooserPopover.vala:58 183 | msgid "Search icons…" 184 | msgstr "Suche Icons…" 185 | 186 | #: src/Popovers/IconChooserPopover.vala:78 187 | msgid "All Files" 188 | msgstr "Alle Dateien" 189 | 190 | #: src/Popovers/IconChooserPopover.vala:82 191 | msgid "Images" 192 | msgstr "Bilder" 193 | 194 | #: src/Popovers/IconChooserPopover.vala:86 src/Views/ItemEditor.vala:440 195 | #: src/Views/ItemEditor.vala:498 196 | msgid "Select an image" 197 | msgstr "Wähle ein Bild aus" 198 | 199 | #: src/Settings/Shortcut.vala:30 200 | msgid "Disabled" 201 | msgstr "Deaktiviert" 202 | 203 | #: src/Settings/Shortcut.vala:39 204 | msgid "Ctrl" 205 | msgstr "Strg" 206 | 207 | #: src/Views/ItemEditor.vala:97 src/Views/ItemEditor.vala:102 208 | msgid "Display name" 209 | msgstr "Anzeigename" 210 | 211 | #: src/Views/ItemEditor.vala:148 212 | msgid "Auto Launch with workspace" 213 | msgstr "Automatisch mit Arbeitsfläche starten" 214 | 215 | #: src/Views/ItemEditor.vala:159 216 | msgid "Run in terminal" 217 | msgstr "Im Terminal ausführen" 218 | 219 | #: src/Views/ItemEditor.vala:174 src/Widgets/ExpandableCategory.vala:79 220 | #: src/Widgets/WorkspaceItem.vala:55 221 | msgid "Delete" 222 | msgstr "Löschen" 223 | 224 | #: src/Views/ItemEditor.vala:180 225 | msgid "Duplicate" 226 | msgstr "Kopieren" 227 | 228 | #: src/Views/ItemEditor.vala:185 229 | msgid "Test" 230 | msgstr "Test" 231 | 232 | #: src/Views/ItemEditor.vala:261 233 | msgid "Program to execute along with it's arguments" 234 | msgstr "Auszuführendes Programm mit seinen Argumenten" 235 | 236 | #: src/Views/ItemEditor.vala:267 237 | msgid "Command Line" 238 | msgstr "Kommandozeile" 239 | 240 | #. var terminal_box = new Workspaces.Widgets.SettingBox (_ ("Auto Launch with workspace"), auto_start_switch, true); 241 | #: src/Views/ItemEditor.vala:269 242 | msgid "Custom Settings" 243 | msgstr "Benutzerdefinierte Einstellungen" 244 | 245 | #. website_url_entry.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT); 246 | #: src/Views/ItemEditor.vala:290 247 | msgid "Url that will be opened when lauched" 248 | msgstr "URL, die beim Starten geöffnet wird" 249 | 250 | #: src/Views/ItemEditor.vala:296 251 | msgid "Website URL" 252 | msgstr "Webseiten URL" 253 | 254 | #: src/Views/ItemEditor.vala:298 255 | msgid "URL Settings" 256 | msgstr "URL Einstellungen" 257 | 258 | #: src/Views/ItemEditor.vala:334 src/Views/ItemEditor.vala:394 259 | msgid "Select Application" 260 | msgstr "Wähle Anwendung aus" 261 | 262 | #: src/Views/ItemEditor.vala:361 src/Views/ItemEditor.vala:422 263 | msgid "Application to launch" 264 | msgstr "Zu startende Anwendung" 265 | 266 | #: src/Views/ItemEditor.vala:363 267 | msgid "Application Settings" 268 | msgstr "Anwendungseinstellungen" 269 | 270 | #: src/Views/ItemEditor.vala:430 src/Views/ItemEditor.vala:488 271 | msgid "Path to the directory" 272 | msgstr "Pfad zum Verzeichnis" 273 | 274 | #: src/Views/ItemEditor.vala:437 src/Views/ItemEditor.vala:495 275 | msgid "Choose Directory" 276 | msgstr "Wähle Verzeichnis aus" 277 | 278 | #: src/Views/ItemEditor.vala:461 src/Views/ItemEditor.vala:519 279 | msgid "Directory to open" 280 | msgstr "Zu öffnendes Verzeichnis" 281 | 282 | #. url_settings_grid.add_widget (application_box); 283 | #: src/Views/ItemEditor.vala:464 284 | msgid "Application Directory Settings" 285 | msgstr "Anwendungsverzeichniseinstellungen" 286 | 287 | #. url_settings_grid.add_widget (application_box); 288 | #: src/Views/ItemEditor.vala:522 289 | msgid "Directory Settings" 290 | msgstr "Verzeichniseinstellungen" 291 | 292 | #: src/Widgets/QuickWelcome.vala:28 293 | msgid "There are no workspaces" 294 | msgstr "Es existieren keine Arbeitsflächen" 295 | 296 | #: src/Widgets/QuickWelcome.vala:29 src/Widgets/Welcome.vala:29 297 | msgid "Add a new workspace" 298 | msgstr "Neue Arbeitsfläche hinzufügen" 299 | 300 | #: src/Widgets/TypeComboBox.vala:30 301 | msgid "URL" 302 | msgstr "URL" 303 | 304 | #: src/Widgets/TypeComboBox.vala:31 305 | msgid "Directory" 306 | msgstr "Verzeichnis" 307 | 308 | #: src/Widgets/TypeComboBox.vala:32 309 | msgid "Application" 310 | msgstr "Anwendung" 311 | 312 | #: src/Widgets/TypeComboBox.vala:33 313 | msgid "Application + Directory" 314 | msgstr "Anwendung + Verzeichnis" 315 | 316 | #: src/Widgets/TypeComboBox.vala:34 317 | msgid "Custom command" 318 | msgstr "Benutzerdefinierter Befehl" 319 | 320 | #: src/Widgets/Welcome.vala:28 321 | msgid "No Workspace selected" 322 | msgstr "Keine Arbeitsfläche ausgewählt" 323 | 324 | #: src/Widgets/Welcome.vala:30 325 | msgid "Add a new item" 326 | msgstr "Neues Element hinzufügen" 327 | -------------------------------------------------------------------------------- /po/extra/LINGUAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevAlien/workspaces/fb45ebfbc32ca57121b2db34bfd61536089288c3/po/extra/LINGUAS -------------------------------------------------------------------------------- /po/extra/POTFILES: -------------------------------------------------------------------------------- 1 | data/com.github.devalien.workspaces.desktop.in 2 | data/com.github.devalien.workspaces.appdata.xml.in 3 | -------------------------------------------------------------------------------- /po/extra/meson.build: -------------------------------------------------------------------------------- 1 | # Install metadata translations 2 | i18n.gettext ('extra', 3 | args: [ 4 | '--directory=' + meson.source_root (), 5 | '--from-code=UTF-8' 6 | ], 7 | install: false 8 | ) 9 | -------------------------------------------------------------------------------- /po/it.po: -------------------------------------------------------------------------------- 1 | # Italian translations for com.github.devalien.workspaces package. 2 | # Copyright (C) 2020 THE com.github.devalien.workspaces'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the com.github.devalien.workspaces package. 4 | # nect , 2020. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: com.github.devalien.workspaces\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2020-09-14 11:56+0200\n" 11 | "PO-Revision-Date: 2020-09-26 17:04+0200\n" 12 | "Last-Translator: nect \n" 13 | "Language-Team: LANGUAGE \n" 14 | "Language: it\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 | 20 | #: src/PreferencesWindow.vala:53 src/QuickLaunchWindow.vala:38 21 | msgid "Workspaces" 22 | msgstr "Workspaces" 23 | 24 | #: src/PreferencesWindow.vala:128 src/Dialogs/AddWorkspace.vala:27 25 | #: src/Widgets/QuickWelcome.vala:29 src/Widgets/Welcome.vala:29 26 | msgid "Add Workspace" 27 | msgstr "Aggiungi Workspace" 28 | 29 | #: src/PreferencesWindow.vala:141 src/Dialogs/AddItem.vala:27 30 | #: src/Widgets/Welcome.vala:30 31 | msgid "Add Item" 32 | msgstr "Aggiungi elemento" 33 | 34 | #: src/PreferencesWindow.vala:234 src/Views/ItemEditor.vala:135 35 | msgid "Settings" 36 | msgstr "Impostazioni" 37 | 38 | #: src/PreferencesWindow.vala:238 39 | msgid "About" 40 | msgstr "Info" 41 | 42 | #: src/PreferencesWindow.vala:247 43 | msgid "Light mode" 44 | msgstr "Tema chiaro" 45 | 46 | #: src/PreferencesWindow.vala:248 47 | msgid "Dark mode" 48 | msgstr "Tema scuro" 49 | 50 | #: src/PreferencesWindow.vala:272 src/PreferencesWindow.vala:276 51 | msgid "Open Quick Launcher" 52 | msgstr "Apri Quick Launcher" 53 | 54 | #: src/PreferencesWindow.vala:299 src/QuickLaunchWindow.vala:112 55 | #: src/Dialogs/Preferences.vala:35 56 | msgid "Preferences" 57 | msgstr "Preferenze" 58 | 59 | #: src/PreferencesWindow.vala:422 60 | msgid "Cannot create an item without a workspace" 61 | msgstr "Impossibile creare un elemento senza un workspace" 62 | 63 | #: src/PreferencesWindow.vala:424 64 | msgid "Ok" 65 | msgstr "" 66 | 67 | #: src/PreferencesWindow.vala:428 68 | msgid "To add an item you first need to create a workspace." 69 | msgstr "Per aggiungere un elemento devi prima creare un workspace" 70 | 71 | #: src/PreferencesWindow.vala:449 72 | #, c-format 73 | msgid "You are deleting %s" 74 | msgstr "Stai rimuovendo %s" 75 | 76 | #: src/PreferencesWindow.vala:450 77 | msgid "" 78 | "Deleting a workspace is an irreversible action. Are you sure you want to " 79 | "delete it?" 80 | msgstr "Rimuovere un Workspace e' irreversibile. Sei sicuro che vuoi rimuoverlo?" 81 | 82 | #: src/PreferencesWindow.vala:455 83 | msgid "DELETE" 84 | msgstr "RIMUOVI" 85 | 86 | #: src/QuickLaunchWindow.vala:46 87 | msgid "Search Workspaces…" 88 | msgstr "Cerca Workspace…" 89 | 90 | #: src/QuickLaunchWindow.vala:86 91 | msgid "No Workspaces or Items Found" 92 | msgstr "Nessun Workspace o Elemento trovato" 93 | 94 | #: src/QuickLaunchWindow.vala:205 95 | msgid "Try changing search terms." 96 | msgstr "Prova a cambiare i termini di ricerca" 97 | 98 | #: src/Dialogs/AddCategory.vala:27 99 | msgid "Add Collection" 100 | msgstr "Aggiungi collezione" 101 | 102 | #: src/Dialogs/AddCategory.vala:28 103 | msgid "My Collection" 104 | msgstr "" 105 | 106 | #: src/Dialogs/AddCategory.vala:30 src/Dialogs/AddItem.vala:30 107 | #: src/Dialogs/AddWorkspace.vala:30 108 | msgid "Create" 109 | msgstr "Crea" 110 | 111 | #: src/Dialogs/AddCategory.vala:47 112 | msgid "Request name must not be empty." 113 | msgstr "Il nome della richiesta non puo' essere vuoto." 114 | 115 | #: src/Dialogs/AddItem.vala:28 116 | msgid "New Item" 117 | msgstr "Nuovo elemento" 118 | 119 | #: src/Dialogs/AddItem.vala:37 120 | msgid "Add to workspace" 121 | msgstr "Aggiungi al workspace" 122 | 123 | #: src/Dialogs/AddItem.vala:69 124 | msgid "Item name must not be empty." 125 | msgstr "Il nome dell'elemento non deve essere vuoto" 126 | 127 | #: src/Dialogs/AddWorkspace.vala:28 128 | msgid "My Workspace" 129 | msgstr "" 130 | 131 | #: src/Dialogs/AddWorkspace.vala:50 132 | msgid "Workspace name must not be empty." 133 | msgstr "Il nome del workspace non deve essere vuoto" 134 | 135 | #: src/Dialogs/Dialog.vala:38 136 | msgid "Name:" 137 | msgstr "Nome:" 138 | 139 | #: src/Dialogs/Dialog.vala:42 src/Dialogs/Preferences.vala:41 140 | msgid "Close" 141 | msgstr "Chiudi" 142 | 143 | #. Window properties 144 | #: src/Dialogs/Preferences.vala:33 145 | msgid "Welcome" 146 | msgstr "Benvenuto" 147 | 148 | #: src/Dialogs/Preferences.vala:64 149 | msgid "" 150 | "Workspaces can be opened with a quick shortcut so you'll be able to open " 151 | "your projects faster." 152 | msgstr "I Workspace possono essere aperti con una scorciatoia che ti permettera' di " 153 | "aprire i tuoi progetti piu' velocemente." 154 | 155 | #: src/Dialogs/Preferences.vala:81 156 | msgid "General Settings" 157 | msgstr "Impostazioni Generali" 158 | 159 | #: src/Dialogs/Preferences.vala:101 160 | msgid "Open Workspaces Shortcut:" 161 | msgstr "Scorciatoia per aprire Workspace:" 162 | 163 | #: src/Dialogs/Preferences.vala:123 164 | msgid "Save last position of window" 165 | msgstr "Salva l'ultima posizione della finestra" 166 | 167 | #: src/Popovers/AppChooserPopover.vala:30 168 | #: src/Popovers/IconChooserPopover.vala:31 169 | msgid "Choose" 170 | msgstr "Sceglu" 171 | 172 | #: src/Popovers/AppChooserPopover.vala:52 173 | msgid "Search apps…" 174 | msgstr "Cerca app…" 175 | 176 | #: src/Popovers/IconChooserPopover.vala:38 177 | msgid "From file" 178 | msgstr "Da file" 179 | 180 | #: src/Popovers/IconChooserPopover.vala:58 181 | msgid "Search icons…" 182 | msgstr "Cerca icone…" 183 | 184 | #: src/Popovers/IconChooserPopover.vala:78 185 | msgid "All Files" 186 | msgstr "Tutti i File…" 187 | 188 | #: src/Popovers/IconChooserPopover.vala:82 189 | msgid "Images" 190 | msgstr "Immagini" 191 | 192 | #: src/Popovers/IconChooserPopover.vala:86 src/Views/ItemEditor.vala:440 193 | #: src/Views/ItemEditor.vala:498 194 | msgid "Select an image" 195 | msgstr "Seleziona un'immagine" 196 | 197 | #: src/Settings/Shortcut.vala:30 198 | msgid "Disabled" 199 | msgstr "Disabilitato" 200 | 201 | #: src/Settings/Shortcut.vala:39 202 | msgid "Ctrl" 203 | msgstr "" 204 | 205 | #: src/Views/ItemEditor.vala:97 src/Views/ItemEditor.vala:102 206 | msgid "Display name" 207 | msgstr "Nome visualizzato" 208 | 209 | #: src/Views/ItemEditor.vala:148 210 | msgid "Auto Launch with workspace" 211 | msgstr "Lancia automaticamento con il workspace" 212 | 213 | #: src/Views/ItemEditor.vala:159 214 | msgid "Run in terminal" 215 | msgstr "Apri nel terminale" 216 | 217 | #: src/Views/ItemEditor.vala:174 src/Widgets/ExpandableCategory.vala:79 218 | #: src/Widgets/WorkspaceItem.vala:55 219 | msgid "Delete" 220 | msgstr "Rimuovi" 221 | 222 | #: src/Views/ItemEditor.vala:180 223 | msgid "Duplicate" 224 | msgstr "Duplica" 225 | 226 | #: src/Views/ItemEditor.vala:185 227 | msgid "Test" 228 | msgstr "" 229 | 230 | #: src/Views/ItemEditor.vala:261 231 | msgid "Program to execute along with it's arguments" 232 | msgstr "Programma da eseguire con degli argomenti" 233 | 234 | #: src/Views/ItemEditor.vala:267 235 | msgid "Command Line" 236 | msgstr "Linea dei comandi" 237 | 238 | #. var terminal_box = new Workspaces.Widgets.SettingBox (_ ("Auto Launch with workspace"), auto_start_switch, true); 239 | #: src/Views/ItemEditor.vala:269 240 | msgid "Custom Settings" 241 | msgstr "Impostazioni personalizzate" 242 | 243 | #. website_url_entry.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT); 244 | #: src/Views/ItemEditor.vala:290 245 | msgid "Url that will be opened when lauched" 246 | msgstr "Url che verra' aperto al lancio" 247 | 248 | #: src/Views/ItemEditor.vala:296 249 | msgid "Website URL" 250 | msgstr "URL del sito" 251 | 252 | #: src/Views/ItemEditor.vala:298 253 | msgid "URL Settings" 254 | msgstr "Impostazioni URL" 255 | 256 | #: src/Views/ItemEditor.vala:334 src/Views/ItemEditor.vala:394 257 | msgid "Select Application" 258 | msgstr "Seleziona Applicazione" 259 | 260 | #: src/Views/ItemEditor.vala:361 src/Views/ItemEditor.vala:422 261 | msgid "Application to launch" 262 | msgstr "Applicazione da lanciare" 263 | 264 | #: src/Views/ItemEditor.vala:363 265 | msgid "Application Settings" 266 | msgstr "Impostazioni Applicazione" 267 | 268 | #: src/Views/ItemEditor.vala:430 src/Views/ItemEditor.vala:488 269 | msgid "Path to the directory" 270 | msgstr "Percorso della cartella" 271 | 272 | #: src/Views/ItemEditor.vala:437 src/Views/ItemEditor.vala:495 273 | msgid "Choose Directory" 274 | msgstr "Scegli Cartella" 275 | 276 | #: src/Views/ItemEditor.vala:461 src/Views/ItemEditor.vala:519 277 | msgid "Directory to open" 278 | msgstr "Cartella da aprire" 279 | 280 | #. url_settings_grid.add_widget (application_box); 281 | #: src/Views/ItemEditor.vala:464 282 | msgid "Application Directory Settings" 283 | msgstr "Impostazioni Cartella Applicazione" 284 | 285 | #. url_settings_grid.add_widget (application_box); 286 | #: src/Views/ItemEditor.vala:522 287 | msgid "Directory Settings" 288 | msgstr "Impostazioni Cartella" 289 | 290 | #: src/Widgets/QuickWelcome.vala:28 291 | msgid "There are no workspaces" 292 | msgstr "Non ci sono workspace" 293 | 294 | #: src/Widgets/QuickWelcome.vala:29 src/Widgets/Welcome.vala:29 295 | msgid "Add a new workspace" 296 | msgstr "Aggiungi un nuovo workspace" 297 | 298 | #: src/Widgets/TypeComboBox.vala:30 299 | msgid "URL" 300 | msgstr "" 301 | 302 | #: src/Widgets/TypeComboBox.vala:31 303 | msgid "Directory" 304 | msgstr "Cartella" 305 | 306 | #: src/Widgets/TypeComboBox.vala:32 307 | msgid "Application" 308 | msgstr "Applicazione" 309 | 310 | #: src/Widgets/TypeComboBox.vala:33 311 | msgid "Application + Directory" 312 | msgstr "Applicazione + Cartella" 313 | 314 | #: src/Widgets/TypeComboBox.vala:34 315 | msgid "Custom command" 316 | msgstr "Comando personalizzato" 317 | 318 | #: src/Widgets/Welcome.vala:28 319 | msgid "No Workspace selected" 320 | msgstr "Nessun Workspace selezionato" 321 | 322 | #: src/Widgets/Welcome.vala:30 323 | msgid "Add a new item" 324 | msgstr "Aggiungi un nuovo elemento" 325 | -------------------------------------------------------------------------------- /po/meson.build: -------------------------------------------------------------------------------- 1 | # Install main translations 2 | i18n.gettext (meson.project_name (), 3 | args: [ 4 | '--directory=' + meson.source_root (), 5 | '--from-code=UTF-8' 6 | ], 7 | preset: 'glib' 8 | ) 9 | 10 | subdir ('extra') 11 | -------------------------------------------------------------------------------- /po/nl.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.devalien.workspaces package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: com.github.devalien.workspaces\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2020-09-14 11:56+0200\n" 11 | "PO-Revision-Date: 2020-09-01 14:06+0200\n" 12 | "Last-Translator: Heimen Stoffels \n" 13 | "Language-Team: \n" 14 | "Language: nl\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "X-Generator: Poedit 2.4.1\n" 19 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 20 | 21 | #: src/PreferencesWindow.vala:53 src/QuickLaunchWindow.vala:38 22 | msgid "Workspaces" 23 | msgstr "Werkbladen" 24 | 25 | #: src/PreferencesWindow.vala:128 src/Dialogs/AddWorkspace.vala:27 26 | #: src/Widgets/QuickWelcome.vala:29 src/Widgets/Welcome.vala:29 27 | msgid "Add Workspace" 28 | msgstr "Werkblad toevoegen" 29 | 30 | #: src/PreferencesWindow.vala:141 src/Dialogs/AddItem.vala:27 31 | #: src/Widgets/Welcome.vala:30 32 | msgid "Add Item" 33 | msgstr "Item toevoegen" 34 | 35 | #: src/PreferencesWindow.vala:234 src/Views/ItemEditor.vala:135 36 | msgid "Settings" 37 | msgstr "Instellingen" 38 | 39 | #: src/PreferencesWindow.vala:238 40 | msgid "About" 41 | msgstr "Over" 42 | 43 | #: src/PreferencesWindow.vala:247 44 | msgid "Light mode" 45 | msgstr "Licht thema" 46 | 47 | #: src/PreferencesWindow.vala:248 48 | msgid "Dark mode" 49 | msgstr "Donker thema" 50 | 51 | #: src/PreferencesWindow.vala:272 src/PreferencesWindow.vala:276 52 | msgid "Open Quick Launcher" 53 | msgstr "" 54 | 55 | #: src/PreferencesWindow.vala:299 src/QuickLaunchWindow.vala:112 56 | #: src/Dialogs/Preferences.vala:35 57 | msgid "Preferences" 58 | msgstr "Voorkeuren" 59 | 60 | #: src/PreferencesWindow.vala:422 61 | msgid "Cannot create an item without a workspace" 62 | msgstr "Zonder werkblad kun je geen item toevoegen" 63 | 64 | #: src/PreferencesWindow.vala:424 65 | msgid "Ok" 66 | msgstr "Oké" 67 | 68 | #: src/PreferencesWindow.vala:428 69 | msgid "To add an item you first need to create a workspace." 70 | msgstr "Maak een werkblad en voeg een item toe." 71 | 72 | #: src/PreferencesWindow.vala:449 73 | #, c-format 74 | msgid "You are deleting %s" 75 | msgstr "" 76 | 77 | #: src/PreferencesWindow.vala:450 78 | msgid "" 79 | "Deleting a workspace is an irreversible action. Are you sure you want to " 80 | "delete it?" 81 | msgstr "" 82 | 83 | #: src/PreferencesWindow.vala:455 84 | msgid "DELETE" 85 | msgstr "" 86 | 87 | #: src/QuickLaunchWindow.vala:46 88 | msgid "Search Workspaces…" 89 | msgstr "Werkbladen doorzoeken…" 90 | 91 | #: src/QuickLaunchWindow.vala:86 92 | msgid "No Workspaces or Items Found" 93 | msgstr "Geen werkblad of item gevonden" 94 | 95 | #: src/QuickLaunchWindow.vala:205 96 | msgid "Try changing search terms." 97 | msgstr "Probeer een andere zoekopdracht." 98 | 99 | #: src/Dialogs/AddCategory.vala:27 100 | msgid "Add Collection" 101 | msgstr "Verzameling toevoegen" 102 | 103 | #: src/Dialogs/AddCategory.vala:28 104 | msgid "My Collection" 105 | msgstr "Mijn verzameling" 106 | 107 | #: src/Dialogs/AddCategory.vala:30 src/Dialogs/AddItem.vala:30 108 | #: src/Dialogs/AddWorkspace.vala:30 109 | msgid "Create" 110 | msgstr "Maken" 111 | 112 | #: src/Dialogs/AddCategory.vala:47 113 | msgid "Request name must not be empty." 114 | msgstr "Geef een naam op." 115 | 116 | #: src/Dialogs/AddItem.vala:28 117 | msgid "New Item" 118 | msgstr "Nieuw item" 119 | 120 | #: src/Dialogs/AddItem.vala:37 121 | msgid "Add to workspace" 122 | msgstr "Toevoegen aan werkblad" 123 | 124 | #: src/Dialogs/AddItem.vala:69 125 | msgid "Item name must not be empty." 126 | msgstr "Geef een naam op." 127 | 128 | #: src/Dialogs/AddWorkspace.vala:28 129 | msgid "My Workspace" 130 | msgstr "Mijn werkblad" 131 | 132 | #: src/Dialogs/AddWorkspace.vala:50 133 | msgid "Workspace name must not be empty." 134 | msgstr "Geef een naam op." 135 | 136 | #: src/Dialogs/Dialog.vala:38 137 | msgid "Name:" 138 | msgstr "Naam:" 139 | 140 | #: src/Dialogs/Dialog.vala:42 src/Dialogs/Preferences.vala:41 141 | msgid "Close" 142 | msgstr "Sluiten" 143 | 144 | #. Window properties 145 | #: src/Dialogs/Preferences.vala:33 146 | msgid "Welcome" 147 | msgstr "" 148 | 149 | #: src/Dialogs/Preferences.vala:64 150 | msgid "" 151 | "Workspaces can be opened with a quick shortcut so you'll be able to open " 152 | "your projects faster." 153 | msgstr "" 154 | "Als je werkbladen sneller wilt openen, kun je dat doen met een sneltoets." 155 | 156 | #: src/Dialogs/Preferences.vala:81 157 | msgid "General Settings" 158 | msgstr "Algemene instellingen" 159 | 160 | #: src/Dialogs/Preferences.vala:101 161 | msgid "Open Workspaces Shortcut:" 162 | msgstr "Sneltoets om werkbladen te openen:" 163 | 164 | #: src/Dialogs/Preferences.vala:123 165 | msgid "Save last position of window" 166 | msgstr "" 167 | 168 | #: src/Popovers/AppChooserPopover.vala:30 169 | #: src/Popovers/IconChooserPopover.vala:31 170 | msgid "Choose" 171 | msgstr "Kiezen" 172 | 173 | #: src/Popovers/AppChooserPopover.vala:52 174 | msgid "Search apps…" 175 | msgstr "Toepassingen doorzoeken…" 176 | 177 | #: src/Popovers/IconChooserPopover.vala:38 178 | msgid "From file" 179 | msgstr "Uit bestand" 180 | 181 | #: src/Popovers/IconChooserPopover.vala:58 182 | msgid "Search icons…" 183 | msgstr "Pictogrammen doorzoeken…" 184 | 185 | #: src/Popovers/IconChooserPopover.vala:78 186 | msgid "All Files" 187 | msgstr "Alle bestanden" 188 | 189 | #: src/Popovers/IconChooserPopover.vala:82 190 | msgid "Images" 191 | msgstr "Afbeeldingen" 192 | 193 | #: src/Popovers/IconChooserPopover.vala:86 src/Views/ItemEditor.vala:440 194 | #: src/Views/ItemEditor.vala:498 195 | msgid "Select an image" 196 | msgstr "Kies een afbeelding" 197 | 198 | #: src/Settings/Shortcut.vala:30 199 | msgid "Disabled" 200 | msgstr "Uitgeschakeld" 201 | 202 | #: src/Settings/Shortcut.vala:39 203 | msgid "Ctrl" 204 | msgstr "Ctrl" 205 | 206 | #: src/Views/ItemEditor.vala:97 src/Views/ItemEditor.vala:102 207 | msgid "Display name" 208 | msgstr "Getoonde naam" 209 | 210 | #: src/Views/ItemEditor.vala:148 211 | msgid "Auto Launch with workspace" 212 | msgstr "Automatisch opstarten met werkblad" 213 | 214 | #: src/Views/ItemEditor.vala:159 215 | msgid "Run in terminal" 216 | msgstr "Uitvoeren in terminalvenster" 217 | 218 | #: src/Views/ItemEditor.vala:174 src/Widgets/ExpandableCategory.vala:79 219 | #: src/Widgets/WorkspaceItem.vala:55 220 | msgid "Delete" 221 | msgstr "Verwijderen" 222 | 223 | #: src/Views/ItemEditor.vala:180 224 | msgid "Duplicate" 225 | msgstr "Klonen" 226 | 227 | #: src/Views/ItemEditor.vala:185 228 | msgid "Test" 229 | msgstr "Testen" 230 | 231 | #: src/Views/ItemEditor.vala:261 232 | msgid "Program to execute along with it's arguments" 233 | msgstr "De uit te voeren toepassing, inclusief opdrachtregelopties" 234 | 235 | #: src/Views/ItemEditor.vala:267 236 | msgid "Command Line" 237 | msgstr "Opdrachtregel" 238 | 239 | #. var terminal_box = new Workspaces.Widgets.SettingBox (_ ("Auto Launch with workspace"), auto_start_switch, true); 240 | #: src/Views/ItemEditor.vala:269 241 | msgid "Custom Settings" 242 | msgstr "Aangepaste instellingen" 243 | 244 | #. website_url_entry.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT); 245 | #: src/Views/ItemEditor.vala:290 246 | msgid "Url that will be opened when lauched" 247 | msgstr "De bij het opstarten te openen url" 248 | 249 | #: src/Views/ItemEditor.vala:296 250 | msgid "Website URL" 251 | msgstr "Website-url:" 252 | 253 | #: src/Views/ItemEditor.vala:298 254 | msgid "URL Settings" 255 | msgstr "URL-instellingen" 256 | 257 | #: src/Views/ItemEditor.vala:334 src/Views/ItemEditor.vala:394 258 | msgid "Select Application" 259 | msgstr "Kies een toepassing" 260 | 261 | #: src/Views/ItemEditor.vala:361 src/Views/ItemEditor.vala:422 262 | msgid "Application to launch" 263 | msgstr "De te starten toepassing" 264 | 265 | #: src/Views/ItemEditor.vala:363 266 | msgid "Application Settings" 267 | msgstr "Toepassingsinstellingen" 268 | 269 | #: src/Views/ItemEditor.vala:430 src/Views/ItemEditor.vala:488 270 | msgid "Path to the directory" 271 | msgstr "Het mappad" 272 | 273 | #: src/Views/ItemEditor.vala:437 src/Views/ItemEditor.vala:495 274 | msgid "Choose Directory" 275 | msgstr "Kies een map" 276 | 277 | #: src/Views/ItemEditor.vala:461 src/Views/ItemEditor.vala:519 278 | msgid "Directory to open" 279 | msgstr "De te openen map" 280 | 281 | #. url_settings_grid.add_widget (application_box); 282 | #: src/Views/ItemEditor.vala:464 283 | msgid "Application Directory Settings" 284 | msgstr "Werkmapinstellingen" 285 | 286 | #. url_settings_grid.add_widget (application_box); 287 | #: src/Views/ItemEditor.vala:522 288 | msgid "Directory Settings" 289 | msgstr "Mapinstellingen" 290 | 291 | #: src/Widgets/QuickWelcome.vala:28 292 | msgid "There are no workspaces" 293 | msgstr "Je hebt nog geen werkbladen" 294 | 295 | #: src/Widgets/QuickWelcome.vala:29 src/Widgets/Welcome.vala:29 296 | msgid "Add a new workspace" 297 | msgstr "Voeg een werkblad toe" 298 | 299 | #: src/Widgets/TypeComboBox.vala:30 300 | msgid "URL" 301 | msgstr "URL" 302 | 303 | #: src/Widgets/TypeComboBox.vala:31 304 | msgid "Directory" 305 | msgstr "Map" 306 | 307 | #: src/Widgets/TypeComboBox.vala:32 308 | msgid "Application" 309 | msgstr "Toepassing" 310 | 311 | #: src/Widgets/TypeComboBox.vala:33 312 | msgid "Application + Directory" 313 | msgstr "Toepassing + map" 314 | 315 | #: src/Widgets/TypeComboBox.vala:34 316 | msgid "Custom command" 317 | msgstr "Aangepaste opdracht" 318 | 319 | #: src/Widgets/Welcome.vala:28 320 | msgid "No Workspace selected" 321 | msgstr "Geen werkblad geselecteerd" 322 | 323 | #: src/Widgets/Welcome.vala:30 324 | msgid "Add a new item" 325 | msgstr "Voeg een item toe" 326 | -------------------------------------------------------------------------------- /src/Application.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Application : Gtk.Application { 23 | public signal void unselect_all_items (Workspaces.Widgets.WorkspaceRow ? workspace_row); 24 | public GLib.Settings settings; 25 | public PreferencesWindow preferences_window; 26 | public QuickLaunchWindow ql_window; 27 | public string ? data_dir; 28 | 29 | public Workspaces.Controllers.WorkspacesController workspaces_controller; 30 | 31 | public const string APP_VERSION = "3.1.0"; 32 | public const string APP_ID = "com.github.devalien.workspaces"; 33 | public const string SHOW_WORKSPACES_CMD = APP_ID; 34 | public const string FLATPAK_SHOW_WORKSPACES_CMD = "flatpak run " + APP_ID; 35 | private const string SHOW_WORKSPACES_SHORTCUT = "w"; 36 | 37 | private bool show_quick_launch = false; 38 | private bool show_settings = false; 39 | private bool started_settings = false; 40 | 41 | public signal void update_command (string command); 42 | public Application () { 43 | Object ( 44 | application_id: APP_ID, 45 | flags : ApplicationFlags.HANDLES_COMMAND_LINE 46 | ); 47 | 48 | settings = new GLib.Settings (this.application_id); 49 | 50 | data_dir = Path.build_filename (Environment.get_user_data_dir (), application_id); 51 | ensure_dir (data_dir); 52 | } 53 | 54 | public static Application _instance = null; 55 | 56 | public static Application instance { 57 | get { 58 | if (_instance == null) { 59 | _instance = new Application (); 60 | } 61 | return _instance; 62 | } 63 | } 64 | 65 | public override int command_line (ApplicationCommandLine command_line) { 66 | show_settings = false; 67 | show_quick_launch = true; 68 | started_settings = false; 69 | bool version = false; 70 | 71 | OptionEntry[] options = new OptionEntry[3]; 72 | options[0] = { "version", 0, 0, OptionArg.NONE, ref version, "Display version number", null }; 73 | options[1] = { "show-quick-launch", 0, 0, OptionArg.NONE, ref show_quick_launch, "Display Quick Launch Window", null }; 74 | options[2] = { "preferences", 0, 0, OptionArg.NONE, ref show_settings, "Display Settings window", null }; 75 | 76 | // We have to make an extra copy of the array, since .parse assumes 77 | // that it can remove strings from the array without freeing them. 78 | string[] args = command_line.get_arguments (); 79 | string[] _args = new string[args.length]; 80 | for (int i = 0; i < args.length; i++) { 81 | _args[i] = args[i]; 82 | } 83 | 84 | try { 85 | var opt_context = new OptionContext (); 86 | opt_context.set_help_enabled (true); 87 | opt_context.add_main_entries (options, null); 88 | unowned string[] tmp = _args; 89 | opt_context.parse (ref tmp); 90 | } catch (OptionError e) { 91 | command_line.print ("error: %s\n", e.message); 92 | command_line.print ("Run '%s --help' to see a full list of available command line options.\n", args[0]); 93 | return 0; 94 | } 95 | 96 | if (version) { 97 | command_line.print ("%s\n", APP_VERSION); 98 | return 0; 99 | } 100 | 101 | if (show_quick_launch == false) { 102 | show_settings = true; 103 | started_settings = true; 104 | } 105 | 106 | activate (); 107 | return 0; 108 | } 109 | 110 | public void load_quick_launch () { 111 | show_quick_launch = true; 112 | load_windows (); 113 | } 114 | 115 | public void load_preferences () { 116 | show_quick_launch = false; 117 | load_windows (); 118 | } 119 | 120 | private void load_windows () { 121 | var first_run = settings.get_boolean ("first-run"); 122 | 123 | if (first_run) { 124 | set_default_shortcut (); 125 | settings.set_boolean ("first-run", false); 126 | } 127 | 128 | if (ql_window != null) { 129 | remove_window (ql_window); 130 | ql_window.close (); 131 | ql_window = null; 132 | } 133 | if (preferences_window != null) { 134 | remove_window (preferences_window); 135 | preferences_window.close (); 136 | preferences_window = null; 137 | } 138 | if (show_quick_launch) { 139 | if (ql_window == null) { 140 | ql_window = new QuickLaunchWindow (first_run); 141 | add_window (ql_window); 142 | } else { 143 | ql_window.present (); 144 | } 145 | } else { 146 | if (preferences_window == null) { 147 | preferences_window = new PreferencesWindow (); 148 | add_window (preferences_window); 149 | } else { 150 | preferences_window.present (); 151 | } 152 | } 153 | } 154 | public void close_preferences () { 155 | if (ql_window != null) { 156 | remove_window (ql_window); 157 | ql_window.close (); 158 | ql_window = null; 159 | } 160 | if (preferences_window != null) { 161 | remove_window (preferences_window); 162 | preferences_window.close (); 163 | preferences_window = null; 164 | } 165 | 166 | if (started_settings == false) { 167 | load_quick_launch (); 168 | } 169 | } 170 | protected override void activate () { 171 | var data_file = Path.build_filename (data_dir, "data.json"); 172 | 173 | var store = new Workspaces.Models.Store (data_file); 174 | workspaces_controller = new Workspaces.Controllers.WorkspacesController (store); 175 | 176 | load_windows (); 177 | 178 | var provider = new Gtk.CssProvider (); 179 | provider.load_from_resource ("com/github/devalien/workspaces/Application.css"); 180 | Gtk.StyleContext.add_provider_for_screen (Gdk.Screen.get_default (), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); 181 | 182 | var quit_action = new SimpleAction ("quit", null); 183 | 184 | add_action (quit_action); 185 | set_accels_for_action ("app.quit", {"q"}); 186 | 187 | quit_action.activate.connect (() => { 188 | if (preferences_window != null) { 189 | preferences_window.destroy (); 190 | } 191 | if (ql_window != null) { 192 | ql_window.destroy (); 193 | } 194 | }); 195 | } 196 | 197 | private void set_default_shortcut () { 198 | CustomShortcutSettings.init (); 199 | foreach (var shortcut in CustomShortcutSettings.list_custom_shortcuts ()) { 200 | if (is_flatpak ()) { 201 | if (shortcut.command == FLATPAK_SHOW_WORKSPACES_CMD) { 202 | CustomShortcutSettings.edit_shortcut (shortcut.relocatable_schema, SHOW_WORKSPACES_SHORTCUT); 203 | return; 204 | } 205 | } else { 206 | if (shortcut.command == SHOW_WORKSPACES_CMD) { 207 | CustomShortcutSettings.edit_shortcut (shortcut.relocatable_schema, SHOW_WORKSPACES_SHORTCUT); 208 | return; 209 | } 210 | } 211 | } 212 | var shortcut = CustomShortcutSettings.create_shortcut (); 213 | if (shortcut != null) { 214 | CustomShortcutSettings.edit_shortcut (shortcut, SHOW_WORKSPACES_SHORTCUT); 215 | if (is_flatpak ()) { 216 | CustomShortcutSettings.edit_command (shortcut, FLATPAK_SHOW_WORKSPACES_CMD); 217 | } else { 218 | CustomShortcutSettings.edit_command (shortcut, SHOW_WORKSPACES_CMD); 219 | } 220 | } 221 | } 222 | 223 | private void ensure_dir (string path) { 224 | var dir = File.new_for_path (path); 225 | 226 | try { 227 | debug (@"Ensuring dir exists: $path"); 228 | dir.make_directory (); 229 | } catch (Error e) { 230 | if (!(e is IOError.EXISTS)) { 231 | warning (@"dir couldn't be created: %s", e.message); 232 | } 233 | } 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /src/Controllers/WorkspacesController.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | using Gee; 23 | 24 | public class Workspaces.Controllers.WorkspacesController : Object { 25 | public signal void workspace_added (Workspaces.Models.Workspace workspace); 26 | public signal void item_added (Workspaces.Models.Item item); 27 | public signal void item_removed (Workspaces.Models.Item item); 28 | 29 | public Workspaces.Models.Store store { get; set; } 30 | 31 | public WorkspacesController (Workspaces.Models.Store store) { 32 | this.store = store; 33 | } 34 | 35 | // public void add_category (Workspaces.Models.Category category) { 36 | // store.add_category (category); 37 | // category_added (category); 38 | // } 39 | 40 | public void save () { 41 | store.persist (); 42 | } 43 | public void duplicate_item (Workspaces.Models.Item item) { 44 | var new_item = new Workspaces.Models.Item (item.name); 45 | new_item.icon = item.icon; 46 | new_item.item_type = item.item_type; 47 | new_item.command = item.command; 48 | new_item.auto_start = item.auto_start; 49 | var w = store.get_item_workspace (item); 50 | if (w != null) { 51 | add_item (new_item, w); 52 | } 53 | } 54 | 55 | public void move_workspace (Workspaces.Models.Workspace workspace, int index) { 56 | store.move_workspace (workspace, index); 57 | } 58 | 59 | public void add_workspace (Workspaces.Models.Workspace workspace) { 60 | store.add_workspace (workspace); 61 | workspace_added (workspace); 62 | var item = new Workspaces.Models.Item ("New item"); 63 | store.add_item (item, workspace); 64 | item_added (item); 65 | } 66 | 67 | public void add_item (Workspaces.Models.Item item, Workspaces.Models.Workspace workspace) { 68 | store.add_item (item, workspace); 69 | item_added (item); 70 | } 71 | 72 | public void insert_item (Workspaces.Models.Item item, Workspaces.Models.Workspace workspace, int position) { 73 | store.add_item_at (item, workspace, position); 74 | // item_added (item); 75 | } 76 | 77 | public bool remove_item (Workspaces.Models.Item item) { 78 | return store.remove_item (item); 79 | } 80 | 81 | public bool remove_workspace (Workspaces.Models.Workspace workspace) { 82 | return store.remove_workspace (workspace); 83 | } 84 | 85 | // public bool remove_item (Workspaces.Models.Item item) { 86 | // return store.remove_item (item); 87 | // } 88 | 89 | public ArrayList get_all () { 90 | return store.get_all (); 91 | } 92 | } -------------------------------------------------------------------------------- /src/Dialogs/About.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Dialogs.AboutDialog : Gtk.AboutDialog { 23 | public AboutDialog (Gtk.Window window) { 24 | Object (); 25 | set_destroy_with_parent (true); 26 | set_transient_for (window); 27 | set_modal (true); 28 | 29 | authors = {"Goncalo Margalho"}; 30 | documenters = null; 31 | logo_icon_name = Application.APP_ID; 32 | program_name = "Workspaces"; 33 | comments = "Workspaces to be always ready to work"; 34 | copyright = "Copyright © 2020 Goncalo Margalho"; 35 | version = @"v$(Application.APP_VERSION)"; 36 | 37 | license = """Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 38 | This program is free software; you can redistribute it and/or 39 | modify it under the terms of the GNU General Public 40 | License as published by the Free Software Foundation; either 41 | version 2 of the License, or (at your option) any later version. 42 | This program is distributed in the hope that it will be useful, 43 | but WITHOUT ANY WARRANTY; without even the implied warranty of 44 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 45 | General Public License for more details. 46 | You should have received a copy of the GNU General Public 47 | License along with this program; if not, write to the 48 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 49 | Boston, MA 02110-1301 USA 50 | Authored by: Goncalo Margalho """; 51 | wrap_license = true; 52 | 53 | website = "https://github.com/devalien/workspaces"; 54 | website_label = "Visit us on github.com"; 55 | 56 | //Forcng to use xdg-open instead of GTK default browser due to some distro crashing the app 57 | activate_link.connect((url) => { 58 | this.open_link(url); 59 | return true; 60 | } 61 | ); 62 | 63 | response.connect ((response_id) => { 64 | if (response_id == Gtk.ResponseType.CANCEL || response_id == Gtk.ResponseType.DELETE_EVENT) { 65 | hide_on_delete (); 66 | } 67 | }); 68 | } 69 | 70 | void open_link(string url) { 71 | var to_run_command = "xdg-open "+ url; 72 | if (is_flatpak () == true) { 73 | to_run_command = "flatpak-spawn --host " + to_run_command; 74 | } 75 | try { 76 | string[] ? argvp = null; 77 | Shell.parse_argv (to_run_command, out argvp); 78 | info ("Command to launch: %s".printf (to_run_command)); 79 | string[] env = Environ.get (); 80 | 81 | string cdir = GLib.Environment.get_home_dir (); 82 | Process.spawn_async (cdir, 83 | argvp, 84 | env, 85 | SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD | SpawnFlags.STDOUT_TO_DEV_NULL | SpawnFlags.STDERR_TO_DEV_NULL, 86 | null, 87 | null 88 | ); 89 | } catch (SpawnError e) { 90 | warning ("Error: %s\n", e.message); 91 | } catch (ShellError e) { 92 | warning ("Error: %s\n", e.message); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/Dialogs/AddCategory.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | namespace Workspaces.Dialogs { 23 | public class AddCategory : Dialog { 24 | public signal void creation (Workspaces.Models.Category request); 25 | 26 | public AddCategory (Gtk.Window parent, Gee.ArrayList collections) { 27 | base (_ ("Add Collection"), "workspaces-new-item", parent); 28 | request_name_entry.text = _ ("My Collection"); 29 | 30 | add_button (_ ("Create"), Gtk.ResponseType.APPLY); 31 | 32 | response.connect ((source, id) => { 33 | switch (id) { 34 | case Gtk.ResponseType.APPLY : 35 | var name = request_name_entry.text; 36 | create_category (name.strip ()); 37 | break; 38 | case Gtk.ResponseType.CLOSE : 39 | destroy (); 40 | break; 41 | } 42 | }); 43 | } 44 | 45 | private void create_category (string category_name) { 46 | if (category_name.length == 0) { 47 | show_warning (_ ("Request name must not be empty.")); 48 | } else { 49 | debug ("AddCategory.create_category, creating: " + name); 50 | var category = new Workspaces.Models.Category (category_name, category_name); 51 | creation (category); 52 | destroy (); 53 | } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /src/Dialogs/AddItem.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | namespace Workspaces.Dialogs { 23 | public class AddItem : Dialog { 24 | public signal void creation (Workspaces.Models.Item item, Workspaces.Models.Workspace workspaces); 25 | 26 | public AddItem (Gtk.Window parent, Gee.ArrayList workspaces) { 27 | base (_ ("Add Item"), "workspaces-new-item", parent); 28 | request_name_entry.text = _ ("New Item"); 29 | 30 | add_button (_ ("Create"), Gtk.ResponseType.APPLY); 31 | var content = get_content_area () as Gtk.Box; 32 | 33 | var combo_box = new Gtk.ComboBoxText (); 34 | 35 | if (workspaces.size > 0) { 36 | var combo_container = new Gtk.Box (Gtk.Orientation.VERTICAL, 5); 37 | var workspace_label = new Gtk.Label (_ ("Add to workspace")); 38 | workspace_label.halign = Gtk.Align.START; 39 | combo_container.pack_start (workspace_label); 40 | foreach (var workspace in workspaces) { 41 | combo_box.append (workspace.name, workspace.name); 42 | } 43 | 44 | combo_container.pack_start (combo_box); 45 | combo_box.active = 0; 46 | combo_container.margin_bottom = 12; 47 | content.add (combo_container); 48 | } 49 | 50 | 51 | response.connect ((source, id) => { 52 | switch (id) { 53 | case Gtk.ResponseType.APPLY : 54 | var workspace = workspaces.get (combo_box.active); 55 | create_item (workspace); 56 | 57 | break; 58 | case Gtk.ResponseType.CLOSE : 59 | destroy (); 60 | break; 61 | } 62 | }); 63 | } 64 | 65 | private void create_item (Workspaces.Models.Workspace workspace) { 66 | var name = request_name_entry.text.strip (); 67 | 68 | if (name.length == 0) { 69 | show_warning (_ ("Item name must not be empty.")); 70 | } else { 71 | debug ("AddItem.create_item, creating: " + name); 72 | var item = new Workspaces.Models.Item (name); 73 | 74 | creation (item, workspace); 75 | destroy (); 76 | } 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /src/Dialogs/AddWorkspace.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | namespace Workspaces.Dialogs { 23 | public class AddWorkspace : Dialog { 24 | public signal void creation (Workspaces.Models.Workspace workspace); 25 | 26 | public AddWorkspace (Gtk.Window parent) { 27 | base (_ ("Add Workspace"), "workspaces-new-workspace", parent); 28 | request_name_entry.text = _ ("My Workspace"); 29 | 30 | add_button (_ ("Create"), Gtk.ResponseType.APPLY); 31 | 32 | response.connect ((source, id) => { 33 | switch (id) { 34 | case Gtk.ResponseType.APPLY : 35 | 36 | create_workspace (); 37 | 38 | break; 39 | case Gtk.ResponseType.CLOSE : 40 | destroy (); 41 | break; 42 | } 43 | }); 44 | } 45 | 46 | private void create_workspace () { 47 | var name = request_name_entry.text.strip (); 48 | 49 | if (name.length == 0) { 50 | show_warning (_ ("Workspace name must not be empty.")); 51 | } else { 52 | debug ("AddWorkspace.create_workspace, creating: " + name); 53 | var workspace = new Workspaces.Models.Workspace (name); 54 | 55 | creation (workspace); 56 | destroy (); 57 | } 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /src/Dialogs/Dialog.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | namespace Workspaces.Dialogs { 23 | public abstract class Dialog : Gtk.Dialog { 24 | protected Gtk.Entry request_name_entry; 25 | private DialogTitle dialog_title; 26 | private bool warning_active; 27 | 28 | protected Dialog (string titl, string icon, Gtk.Window parent) { 29 | title = titl; 30 | border_width = 5; 31 | set_size_request (425, 100); 32 | deletable = false; 33 | resizable = false; 34 | transient_for = parent; 35 | modal = true; 36 | warning_active = false; 37 | 38 | var request_name_label = new Gtk.Label (_ ("Name:")); 39 | request_name_entry = new Gtk.Entry (); 40 | dialog_title = new DialogTitle (title, icon); 41 | 42 | add_button (_ ("Close"), Gtk.ResponseType.CLOSE); 43 | 44 | Gtk.Box hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 15); 45 | hbox.pack_start (request_name_label, false, true, 0); 46 | hbox.pack_start (request_name_entry, true, true, 0); 47 | hbox.margin_bottom = 20; 48 | 49 | var content = get_content_area () as Gtk.Box; 50 | 51 | content.margin = 15; 52 | content.margin_top = 0; 53 | 54 | content.add (dialog_title); 55 | content.add (hbox); 56 | } 57 | 58 | protected void show_warning (string warning) { 59 | if ( !warning_active ) { 60 | var content = get_content_area () as Gtk.Box; 61 | 62 | var warning_label = new Gtk.Label ("" + warning + ""); 63 | warning_label.use_markup = true; 64 | warning_label.margin = 5; 65 | content.pack_start (warning_label, false, true, 0); 66 | show_all (); 67 | request_name_entry.get_style_context ().add_class ("error"); 68 | warning_active = true; 69 | } 70 | } 71 | 72 | private class DialogTitle : Gtk.Box { 73 | private Gtk.Image icon; 74 | private Gtk.Label label; 75 | 76 | public string title { 77 | get { 78 | return label.label; 79 | } 80 | set { 81 | label.label = value; 82 | } 83 | } 84 | 85 | public DialogTitle (string text, string icon_name) { 86 | icon = new Gtk.Image.from_icon_name (icon_name, Gtk.IconSize.DIALOG); 87 | label = new Gtk.Label ("" + text + ""); 88 | label.use_markup = true; 89 | label.get_style_context ().add_class ("dialog-title"); 90 | label.xalign = 0; 91 | label.get_style_context ().add_class ("h2"); 92 | 93 | pack_start (icon, false, true, 0); 94 | pack_start (label, true, true, 0); 95 | 96 | margin_bottom = 15; 97 | } 98 | } 99 | } 100 | } -------------------------------------------------------------------------------- /src/Dialogs/Preferences.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Dialogs.Preferences : Gtk.Dialog { 23 | private const int MIN_WIDTH = 300; 24 | private const int MIN_HEIGHT = 280; 25 | 26 | private GLib.Settings settings; 27 | 28 | public Preferences (bool first_run, Gtk.Window parent) { 29 | settings = new GLib.Settings (Workspaces.Application.APP_ID); 30 | transient_for = parent; 31 | // Window properties 32 | if (first_run) 33 | title = _ ("Welcome"); 34 | else 35 | title = _ ("Preferences"); 36 | 37 | set_size_request (MIN_WIDTH, MIN_HEIGHT); 38 | resizable = false; 39 | window_position = Gtk.WindowPosition.CENTER; 40 | 41 | add_button (_ ("Close"), Gtk.ResponseType.CLOSE); 42 | 43 | var content_grid = new Gtk.Grid (); 44 | content_grid.attach (create_general_settings_widgets (first_run), 0, 1, 1, 1); 45 | 46 | var content = get_content_area () as Gtk.Box; 47 | 48 | content.margin = 15; 49 | content.margin_top = 0; 50 | 51 | content.add (content_grid); 52 | show_all (); 53 | 54 | response.connect ((source, id) => { 55 | switch (id) { 56 | case Gtk.ResponseType.CLOSE : 57 | destroy (); 58 | break; 59 | } 60 | }); 61 | } 62 | 63 | private Gtk.Grid create_general_settings_widgets (bool first_run) { 64 | string intro = _ ("Workspaces can be opened with a quick shortcut so you'll be able to open your projects faster."); 65 | 66 | var intro_label = new Gtk.Label (intro); 67 | intro_label.halign = Gtk.Align.START; 68 | intro_label.use_markup = true; 69 | intro_label.max_width_chars = 50; 70 | intro_label.wrap = true; 71 | 72 | Gtk.Grid general_grid = new Gtk.Grid (); 73 | general_grid.margin = 12; 74 | general_grid.hexpand = true; 75 | general_grid.column_spacing = 12; 76 | general_grid.row_spacing = 6; 77 | 78 | 79 | 80 | 81 | var general_header = create_heading (_ ("General Settings")); 82 | 83 | var accel = ""; 84 | string ? accel_path = null; 85 | 86 | CustomShortcutSettings.init (); 87 | foreach (var shortcut in CustomShortcutSettings.list_custom_shortcuts ()) { 88 | if (is_flatpak ()) { 89 | if (shortcut.command == Workspaces.Application.FLATPAK_SHOW_WORKSPACES_CMD) { 90 | accel = shortcut.shortcut; 91 | accel_path = shortcut.relocatable_schema; 92 | } 93 | } else { 94 | if (shortcut.command == Workspaces.Application.SHOW_WORKSPACES_CMD) { 95 | accel = shortcut.shortcut; 96 | accel_path = shortcut.relocatable_schema; 97 | } 98 | } 99 | } 100 | 101 | var paste_shortcut_label = create_label (_ ("Open Workspaces Shortcut:")); 102 | var paste_shortcut_entry = new Workspaces.Widgets.ShortcutEntry (accel); 103 | paste_shortcut_entry.shortcut_changed.connect ((new_shortcut) => { 104 | if (accel_path != null && accel_path != "") { 105 | CustomShortcutSettings.edit_shortcut (accel_path, new_shortcut); 106 | } else { 107 | var shortcut = CustomShortcutSettings.create_shortcut (); 108 | if (shortcut != null) { 109 | CustomShortcutSettings.edit_shortcut (shortcut, new_shortcut); 110 | if (is_flatpak ()) { 111 | CustomShortcutSettings.edit_command (shortcut, Workspaces.Application.FLATPAK_SHOW_WORKSPACES_CMD); 112 | } else { 113 | CustomShortcutSettings.edit_command (shortcut, Workspaces.Application.SHOW_WORKSPACES_CMD); 114 | } 115 | } 116 | } 117 | }); 118 | 119 | var do_last_postion = settings.get_boolean ("save-last-window-position"); 120 | 121 | var save_last_postion_switch = new Gtk.Switch (); 122 | save_last_postion_switch.set_halign (Gtk.Align.END); 123 | var save_last_position_label = create_label (_ ("Save last position of window")); 124 | save_last_postion_switch.notify["active"].connect (this.toggled_position); 125 | save_last_postion_switch.set_active (do_last_postion); 126 | 127 | 128 | 129 | if (first_run) { 130 | general_grid.attach (intro_label, 0, 0, 2, 1); 131 | } 132 | 133 | general_grid.attach (general_header, 0, 1, 1, 1); 134 | 135 | general_grid.attach (paste_shortcut_label, 0, 2, 1, 1); 136 | general_grid.attach (paste_shortcut_entry, 1, 2, 1, 1); 137 | general_grid.attach (save_last_postion_switch, 1, 3, 1,1); 138 | general_grid.attach (save_last_position_label, 0, 3, 1,1); 139 | 140 | return general_grid; 141 | } 142 | void toggled_position (Object switcher, ParamSpec pspec) { 143 | if (((Gtk.Switch)switcher).get_active ()) { 144 | settings.set_boolean ("save-last-window-position", true); 145 | } else 146 | settings.set_boolean ("save-last-window-position", false); 147 | } 148 | 149 | private Gtk.Label create_heading (string text) { 150 | var label = new Gtk.Label (text); 151 | label.get_style_context ().add_class ("h4"); 152 | label.halign = Gtk.Align.START; 153 | 154 | return label; 155 | } 156 | 157 | private Gtk.Label create_label (string text) { 158 | var label = new Gtk.Label (text); 159 | label.hexpand = true; 160 | label.halign = Gtk.Align.START; 161 | label.margin_start = 20; 162 | 163 | return label; 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/Main.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public static void set_widget_visible (Gtk.Widget widget, bool visible) { 23 | if (visible) { 24 | widget.no_show_all = false; 25 | widget.show_all (); 26 | } else { 27 | widget.no_show_all = true; 28 | widget.hide (); 29 | } 30 | } 31 | 32 | public static bool is_flatpak () { 33 | var is_flatpak = Environment.get_variable ("FLATPAK_ID"); 34 | if (is_flatpak != null) { 35 | return true; 36 | } 37 | 38 | return false; 39 | } 40 | public static int main (string[] args) { 41 | var app = Workspaces.Application.instance; 42 | return app.run (args); 43 | } -------------------------------------------------------------------------------- /src/Models/AppInfo.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Models.AppInfo : Object { 23 | public string name { get; set; } 24 | public string icon_name { get; set; } 25 | public string executable { get; set; } 26 | 27 | public AppInfo (string name, string icon, string executable) { 28 | Object ( 29 | name: name, 30 | icon_name: icon, 31 | executable: executable 32 | ); 33 | } 34 | } -------------------------------------------------------------------------------- /src/Models/Item.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Models.Item : Object { 23 | public string id { get; set; } 24 | public string name { get; set; } 25 | public string icon { get; set; } 26 | public string item_type { get; set; } 27 | public string command { get; set; } 28 | public string url { get; set; } 29 | public bool auto_start { get; set; } 30 | public bool run_in_terminal { get; set; } 31 | public Workspaces.Models.AppInfo app_info {get; set;} 32 | public string directory {get; set;} 33 | 34 | public Item (string name) { 35 | Object (); 36 | this.id = Uuid.string_random (); 37 | this.name = name; 38 | this.command = ""; 39 | this.item_type = "Custom"; 40 | this.run_in_terminal = false; 41 | this.auto_start = false; 42 | } 43 | 44 | public void execute_command () { 45 | var to_run_command = prepare_command (); 46 | if (is_flatpak () == true) { 47 | to_run_command = "flatpak-spawn --host " + to_run_command; 48 | } 49 | try { 50 | string[] ? argvp = null; 51 | Shell.parse_argv (to_run_command, out argvp); 52 | info ("Command to launch: %s".printf (to_run_command)); 53 | string[] env = Environ.get (); 54 | 55 | string cdir = GLib.Environment.get_home_dir (); 56 | Process.spawn_async (cdir, 57 | argvp, 58 | env, 59 | SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD | SpawnFlags.STDOUT_TO_DEV_NULL | SpawnFlags.STDERR_TO_DEV_NULL, 60 | null, 61 | null 62 | ); 63 | } catch (SpawnError e) { 64 | warning ("Error: %s\n", e.message); 65 | } catch (ShellError e) { 66 | warning ("Error: %s\n", e.message); 67 | } 68 | } 69 | 70 | private string prepare_command () { 71 | var c = ""; 72 | if (command != null) { 73 | c = command; 74 | } 75 | 76 | switch (item_type) { 77 | case "URL" : 78 | if (url != null && url.length > 0) { 79 | c = "xdg-open " + url; 80 | } 81 | break; 82 | case "Directory" : 83 | if (directory != null && directory.length > 0) { 84 | c = "xdg-open '" + directory + "'"; 85 | } 86 | break; 87 | case "Application" : 88 | if (app_info != null && app_info.executable.length > 0) { 89 | c = app_info.executable + " "; 90 | break; 91 | } else { 92 | return ""; 93 | } 94 | case "ApplicationDirectory" : 95 | if (app_info != null && app_info.executable != null && app_info.executable.length > 0) { 96 | var d = ""; 97 | if (directory != null && directory.length > 0) { 98 | d = " '" + directory + "'"; 99 | } 100 | c = app_info.executable + d; 101 | break; 102 | } else { 103 | return ""; 104 | } 105 | default : 106 | c = command; 107 | break; 108 | } 109 | 110 | if (run_in_terminal) { 111 | c = "x-terminal-emulator -e \"%s\"".printf (c.replace ("\"", "\\\"")); 112 | } 113 | return c; 114 | } 115 | 116 | public string to_string () { 117 | return @"[$(this.id)] $(this.name)"; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/Models/ItemType.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public struct Workspaces.Models.ItemType { 23 | string id; 24 | unowned string name; 25 | string icon_name; 26 | 27 | public bool compare (Workspaces.Models.ItemType item) { 28 | return id == item.id; 29 | } 30 | } -------------------------------------------------------------------------------- /src/Models/SearchItem.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Models.SearchItem : GLib.Object { 23 | public Workspaces.Models.Item item { get; set; } 24 | public Workspaces.Models.Workspace workspace { get; set; } 25 | 26 | public SearchItem () { 27 | GLib.Object (); 28 | } 29 | public void launch () { 30 | if (item != null) { 31 | item.execute_command (); 32 | } else if (workspace != null) { 33 | workspace.launch (); 34 | } 35 | } 36 | 37 | public bool contains_text (string search_text) { 38 | if (item != null) { 39 | string name, command; 40 | 41 | 42 | if (item.name != null) { 43 | name = item.name.down (); 44 | } else { 45 | name = ""; 46 | } 47 | 48 | if (item.command != null) { 49 | command = item.command.down (); 50 | } else { 51 | command = ""; 52 | } 53 | 54 | 55 | return (search_text in name || search_text in command); 56 | } else if (workspace != null) { 57 | string name; 58 | 59 | 60 | if (workspace.name != null) { 61 | name = workspace.name.down (); 62 | } else { 63 | name = ""; 64 | } 65 | 66 | 67 | return (search_text in name); 68 | } 69 | 70 | return false; 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /src/Models/Workspace.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | using Json; 23 | using Gee; 24 | 25 | public class Workspaces.Models.Workspace : GLib.Object, Json.Serializable { 26 | public string id { get; set; } 27 | public string name { get; set; } 28 | public string icon { get; set; } 29 | public ArrayList items { get; set; } 30 | public signal void changed (Workspaces.Models.Workspace workspace); 31 | public signal void item_added (Workspaces.Models.Item item); 32 | 33 | public Workspace (string name) { 34 | GLib.Object (); 35 | 36 | this.id = Uuid.string_random (); 37 | this.name = name; 38 | items = new ArrayList (); 39 | } 40 | 41 | public void add_item (Workspaces.Models.Item item) { 42 | stdout.printf ("name: %s\n", item.name); 43 | items.add (item); 44 | item_added (item); 45 | stdout.printf ("SIZE: %d\n", items.size); 46 | } 47 | 48 | public void insert_item (int position, Workspaces.Models.Item item) { 49 | stdout.printf ("name: %s\n", item.name); 50 | items.insert (position, item); 51 | // item_added (item); 52 | stdout.printf ("SIZE: %d\n", items.size); 53 | } 54 | 55 | public void launch () { 56 | foreach (var i in items) { 57 | if (i.auto_start) { 58 | i.execute_command (); 59 | } 60 | } 61 | } 62 | public string to_string () { 63 | return @"[$(this.id)] $(this.name)"; 64 | } 65 | 66 | public virtual Json.Node serialize_property (string property_name, Value @value, ParamSpec pspec) { 67 | if ( @value.type ().is_a (typeof (Gee.ArrayList))) { 68 | unowned Gee.ArrayList list_value = @value as Gee.ArrayList; 69 | if ( list_value != null || property_name == "data" ) { 70 | var array = new Json.Array.sized (list_value.size); 71 | foreach ( var item in list_value ) { 72 | array.add_element (gobject_serialize (item)); 73 | } 74 | 75 | var node = new Json.Node (NodeType.ARRAY); 76 | node.set_array (array); 77 | return node; 78 | } 79 | } 80 | 81 | return default_serialize_property (property_name, @value, pspec); 82 | } 83 | 84 | public virtual bool deserialize_property (string property_name, out Value @value, ParamSpec pspec, Json.Node property_node) { 85 | if ( property_name == "items" ) { 86 | var node_arr = property_node.get_array ().get_elements (); 87 | var ws = new ArrayList (); 88 | foreach ( var n in node_arr ) { 89 | if ( n.get_node_type () == Json.NodeType.OBJECT ) { 90 | var asd = Json.gobject_deserialize (typeof (Workspaces.Models.Item), n) as Workspaces.Models.Item; 91 | ws.add (asd); 92 | } 93 | } 94 | 95 | @value = ws; 96 | return true; 97 | } 98 | 99 | if ( property_node.get_node_type () == Json.NodeType.VALUE ) { 100 | @value = property_node.get_value (); 101 | return true; 102 | } 103 | return default_deserialize_property (property_name, out @value, pspec, property_node); 104 | } 105 | 106 | public virtual unowned ParamSpec ? find_property (string name) { 107 | return get_class ().find_property (name); 108 | } 109 | } 110 | 111 | -------------------------------------------------------------------------------- /src/Models/WorkspacesStore.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | using Gee; 23 | 24 | public class Workspaces.Models.Store : Object { 25 | private ArrayList _store; 26 | private File _data_file; 27 | 28 | public Store (string data_path) { 29 | Object (); 30 | 31 | _store = new ArrayList (); 32 | _data_file = File.new_for_path (data_path); 33 | debug (@"store initialized in path $data_path"); 34 | ensure (); 35 | load (); 36 | } 37 | 38 | public void add_workspace (Workspaces.Models.Workspace workspace) { 39 | _add_workspace (workspace); 40 | persist (); 41 | } 42 | 43 | public void move_workspace (Workspaces.Models.Workspace workspace, int index) { 44 | debug (workspace.items.size.to_string ()); 45 | _store.remove (workspace); 46 | _store.insert (index, workspace); 47 | // _store.add (workspace); 48 | } 49 | private void _add_workspace (Workspaces.Models.Workspace workspace) { 50 | debug (workspace.items.size.to_string ()); 51 | _store.add (workspace); 52 | } 53 | 54 | public Workspaces.Models.Workspace ? get_item_workspace (Workspaces.Models.Item item) { 55 | foreach ( var w in _store ) { 56 | foreach (var i in w.items) { 57 | if (i.id == item.id) { 58 | return w; 59 | } 60 | } 61 | } 62 | 63 | return null; 64 | } 65 | 66 | public void add_item (Workspaces.Models.Item item, Workspaces.Models.Workspace workspace) { 67 | foreach ( var w in _store ) { 68 | if ( w.id == workspace.id ) { 69 | w.add_item (item); 70 | } 71 | } 72 | persist (); 73 | } 74 | 75 | public void add_item_at (Workspaces.Models.Item item, Workspaces.Models.Workspace workspace, int position) { 76 | foreach ( var w in _store ) { 77 | if ( w.id == workspace.id ) { 78 | w.insert_item (position, item); 79 | } 80 | } 81 | persist (); 82 | } 83 | 84 | public bool remove_item (Workspaces.Models.Item item) { 85 | var has_deleted = false; 86 | foreach ( var w in _store ) { 87 | var index = w.items.index_of (item); 88 | if (index != -1) { 89 | w.items.remove_at (index); 90 | has_deleted = true; 91 | break; 92 | } 93 | } 94 | 95 | persist (); 96 | 97 | return has_deleted; 98 | } 99 | 100 | public bool remove_workspace (Workspaces.Models.Workspace workspace) { 101 | var index = _store.index_of (workspace); 102 | if (index != -1) { 103 | _store.remove_at (index); 104 | persist (); 105 | return true; 106 | } 107 | 108 | return false; 109 | } 110 | 111 | public void remove (Workspaces.Models.Workspace workspace) { 112 | _store.remove (workspace); 113 | persist (); 114 | } 115 | 116 | private void load () { 117 | debug ("loading store"); 118 | Json.Parser parser = new Json.Parser (); 119 | 120 | try { 121 | var stream = _data_file.read (); 122 | parser.load_from_stream (stream); 123 | stream.close (); 124 | } catch ( Error e ) { 125 | warning (@"store: unable to load data, does it exist? $(e.message)"); 126 | } 127 | 128 | Json.Node ? node = parser.get_root (); 129 | Json.Array array = node.get_array (); 130 | array.foreach_element ((a, i, elem) => { 131 | Workspaces.Models.Workspace workspace = Json.gobject_deserialize (typeof (Workspaces.Models.Workspace), elem) as Workspaces.Models.Workspace; 132 | _add_workspace (workspace); 133 | }); 134 | 135 | debug (@"loaded store size: $(_store.size)"); 136 | } 137 | 138 | public void persist () { 139 | debug ("persisting store"); 140 | var data = serialize (); 141 | 142 | try { 143 | _data_file.delete (); 144 | var stream = _data_file.create ( 145 | FileCreateFlags.REPLACE_DESTINATION | FileCreateFlags.PRIVATE 146 | ); 147 | var s = new DataOutputStream (stream); 148 | s.put_string (data); 149 | s.flush (); 150 | s.close (); // closes base stream also 151 | } catch ( Error e ) { 152 | warning (@"store: unable to persist store: $(e.message)"); 153 | } 154 | } 155 | 156 | private void ensure () { 157 | try { 158 | var df = _data_file.create (FileCreateFlags.PRIVATE); 159 | df.write ("[]".data); 160 | df.close (); 161 | debug (@"store created"); 162 | } catch ( Error e ) { 163 | // Ignore, file already existed, which is good 164 | } 165 | } 166 | 167 | public string serialize () { 168 | Json.Builder builder = new Json.Builder (); 169 | builder.begin_array (); 170 | foreach ( var category in _store ) { 171 | var node = Json.gobject_serialize (category); 172 | builder.add_value (node); 173 | } 174 | builder.end_array (); 175 | 176 | Json.Generator generator = new Json.Generator (); 177 | generator.set_root (builder.get_root ()); 178 | string data = generator.to_data (null); 179 | return data; 180 | } 181 | 182 | public ArrayList get_all () { 183 | return _store; 184 | } 185 | } 186 | 187 | -------------------------------------------------------------------------------- /src/Popovers/AppChooserPopover.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Popovers.AppChooserPopover : Gtk.Popover { 23 | public signal void selected (Workspaces.Models.AppInfo app_info); 24 | 25 | private Workspaces.Widgets.AppListBox app_list_box; 26 | private Gtk.SearchEntry search_entry; 27 | private Gtk.Button choose_button; 28 | 29 | construct { 30 | choose_button = new Gtk.Button.with_label (_ ("Choose")); 31 | choose_button.clicked.connect (() => { 32 | send_selected (); 33 | }); 34 | choose_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); 35 | choose_button.sensitive = false; 36 | 37 | var button_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); 38 | button_box.margin = 6; 39 | button_box.pack_end (choose_button); 40 | 41 | app_list_box = new Workspaces.Widgets.AppListBox (); 42 | app_list_box.row_selected.connect (on_row_selected); 43 | app_list_box.row_activated.connect (on_row_activated); 44 | 45 | var scrolled = new Gtk.ScrolledWindow (null, null); 46 | scrolled.height_request = 300; 47 | scrolled.expand = true; 48 | scrolled.add (app_list_box); 49 | scrolled.edge_overshot.connect (on_edge_overshot); 50 | 51 | search_entry = new Gtk.SearchEntry (); 52 | search_entry.placeholder_text = _ ("Search apps…"); 53 | search_entry.margin_bottom = search_entry.margin_top = search_entry.margin_start = search_entry.margin_end = 12; 54 | search_entry.hexpand = true; 55 | search_entry.search_changed.connect (on_search_entry_changed); 56 | 57 | var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); 58 | box.add (search_entry); 59 | box.add (new Gtk.Separator (Gtk.Orientation.HORIZONTAL)); 60 | box.pack_start (scrolled, true, true); 61 | box.add (new Gtk.Separator (Gtk.Orientation.HORIZONTAL)); 62 | box.add (button_box); 63 | add (box); 64 | } 65 | 66 | public AppChooserPopover () { 67 | Object (); 68 | } 69 | 70 | private void on_row_selected (Gtk.ListBoxRow ? row) { 71 | choose_button.sensitive = row != null; 72 | } 73 | 74 | private void on_row_activated (Gtk.ListBoxRow row) { 75 | send_selected (); 76 | } 77 | 78 | private void send_selected () { 79 | Workspaces.Widgets.AppRow ? app = app_list_box.get_selected_app (); 80 | if (app != null) { 81 | selected (app.app_info); 82 | } 83 | } 84 | private void on_edge_overshot (Gtk.PositionType position) { 85 | if (position == Gtk.PositionType.BOTTOM) { 86 | app_list_box.load_next_apps (); 87 | } 88 | } 89 | 90 | private void on_search_entry_changed () { 91 | app_list_box.invalidate_filter (); 92 | app_list_box.search (search_entry.text); 93 | } 94 | } -------------------------------------------------------------------------------- /src/Popovers/IconChooserPopover.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Popovers.IconChooserPopover : Gtk.Popover { 23 | public signal void selected (string icon_name); 24 | public signal void selected_file (File file); 25 | 26 | private Workspaces.Widgets.IconListBox icon_list_box; 27 | private Gtk.SearchEntry search_entry; 28 | private Gtk.Button choose_button; 29 | 30 | construct { 31 | choose_button = new Gtk.Button.with_label (_ ("Choose")); 32 | choose_button.clicked.connect (() => { 33 | send_selected (); 34 | }); 35 | choose_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); 36 | choose_button.sensitive = false; 37 | 38 | var from_file_button = new Gtk.Button.with_label (_ ("From file")); 39 | from_file_button.clicked.connect (choose_from_file_clicked); 40 | 41 | var button_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); 42 | button_box.margin = 6; 43 | button_box.pack_start (from_file_button); 44 | button_box.pack_end (choose_button); 45 | 46 | icon_list_box = new Workspaces.Widgets.IconListBox (); 47 | icon_list_box.row_selected.connect (on_row_selected); 48 | icon_list_box.row_activated.connect (on_row_activated); 49 | 50 | var scrolled = new Gtk.ScrolledWindow (null, null); 51 | scrolled.expand = true; 52 | scrolled.height_request = 300; 53 | scrolled.width_request = 220; 54 | scrolled.add (icon_list_box); 55 | scrolled.edge_overshot.connect (on_edge_overshot); 56 | 57 | search_entry = new Gtk.SearchEntry (); 58 | search_entry.placeholder_text = _ ("Search icons…"); 59 | search_entry.margin_bottom = search_entry.margin_top = search_entry.margin_start = search_entry.margin_end = 12; 60 | search_entry.hexpand = true; 61 | search_entry.search_changed.connect (on_search_entry_changed); 62 | 63 | var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); 64 | box.add (search_entry); 65 | box.add (new Gtk.Separator (Gtk.Orientation.HORIZONTAL)); 66 | box.add (scrolled); 67 | box.add (new Gtk.Separator (Gtk.Orientation.HORIZONTAL)); 68 | box.add (button_box); 69 | add (box); 70 | } 71 | 72 | public IconChooserPopover () { 73 | Object (); 74 | } 75 | 76 | private void choose_from_file_clicked () { 77 | var all_filter = new Gtk.FileFilter (); 78 | all_filter.set_filter_name (_ ("All Files")); 79 | all_filter.add_pattern ("*"); 80 | 81 | var image_filter = new Gtk.FileFilter (); 82 | image_filter.set_filter_name (_ ("Images")); 83 | image_filter.add_mime_type ("image/*"); 84 | 85 | var file_chooser = new Gtk.FileChooserDialog ( 86 | _ ("Select an image"), Application.instance.preferences_window, Gtk.FileChooserAction.OPEN, 87 | "_Cancel", 88 | Gtk.ResponseType.CANCEL, 89 | "_Open", 90 | Gtk.ResponseType.ACCEPT 91 | ); 92 | 93 | file_chooser.add_filter (image_filter); 94 | file_chooser.add_filter (all_filter); 95 | 96 | file_chooser.response.connect ((response) => { 97 | if (response == Gtk.ResponseType.ACCEPT) { 98 | string uri = file_chooser.get_uri (); 99 | var file = File.new_for_uri (uri); 100 | 101 | selected_file (file); 102 | } 103 | 104 | file_chooser.destroy (); 105 | }); 106 | 107 | file_chooser.run (); 108 | } 109 | 110 | private void on_row_selected (Gtk.ListBoxRow ? row) { 111 | choose_button.sensitive = row != null; 112 | } 113 | 114 | private void on_row_activated (Gtk.ListBoxRow row) { 115 | send_selected (); 116 | } 117 | 118 | private void send_selected () { 119 | string ? icon_name = icon_list_box.get_selected_icon_name (); 120 | if (icon_name != null) { 121 | selected (icon_name); 122 | } 123 | } 124 | 125 | private void on_edge_overshot (Gtk.PositionType position) { 126 | if (position == Gtk.PositionType.BOTTOM) { 127 | icon_list_box.load_next_icons (); 128 | } 129 | } 130 | 131 | private void on_search_entry_changed () { 132 | icon_list_box.search (search_entry.text); 133 | icon_list_box.invalidate_filter (); 134 | } 135 | } -------------------------------------------------------------------------------- /src/QuickLaunchWindow.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.QuickLaunchWindow : Gtk.Window { 23 | public signal void search_changed (string search_term); 24 | public signal void paste_item (int id); 25 | public signal void delete_item (int id); 26 | 27 | private Workspaces.Widgets.SearchListBox list_box; 28 | private Gtk.Stack stack; 29 | private Workspaces.Views.AlertView empty_alert; 30 | private Gtk.SearchEntry search_headerbar; 31 | public Workspaces.Controllers.WorkspacesController workspaces_controller; 32 | 33 | public QuickLaunchWindow (bool first_run) { 34 | Object (application: Application.instance, 35 | height_request: 700, 36 | icon_name: "com.github.devalien.workspaces", 37 | resizable: true, 38 | title: _ ("Workspaces"), 39 | width_request: 500); 40 | 41 | workspaces_controller = Application.instance.workspaces_controller; 42 | set_keep_above (true); 43 | window_position = Gtk.WindowPosition.CENTER; 44 | 45 | search_headerbar = new Gtk.SearchEntry (); 46 | search_headerbar.placeholder_text = _ ("Search Workspaces\u2026"); 47 | search_headerbar.hexpand = true; 48 | 49 | search_headerbar.key_press_event.connect ((event) => { 50 | switch (event.keyval) { 51 | case Gdk.Key.Escape : 52 | close (); 53 | return true; 54 | default : 55 | return false; 56 | } 57 | }); 58 | 59 | search_headerbar.search_changed.connect (() => { 60 | list_box.set_search_text (search_headerbar.text); 61 | }); 62 | 63 | 64 | var style_context = search_headerbar.get_style_context (); 65 | style_context.add_class ("large-search-entry"); 66 | 67 | 68 | var list_box_scroll = new Gtk.ScrolledWindow (null, null); 69 | list_box_scroll.vexpand = true; 70 | list_box = new Workspaces.Widgets.SearchListBox (); 71 | search_headerbar.search_changed.connect (() => { 72 | list_box.set_search_text (search_headerbar.text); 73 | }); 74 | list_box_scroll.add (list_box); 75 | list_box_scroll.show_all (); 76 | 77 | list_box.row_activated.connect ((row) => { 78 | var search_item = row as Workspaces.Widgets.SearchListBoxItem; 79 | search_item.item.launch (); 80 | 81 | if (!is_control_pressed ()) { 82 | close (); 83 | } 84 | }); 85 | 86 | empty_alert = new Workspaces.Views.AlertView (_ ("No Workspaces or Items Found"), "", "edit-find-symbolic"); 87 | empty_alert.show_all (); 88 | 89 | var welcome = new Workspaces.Widgets.QuickWelcome (); 90 | 91 | stack = new Gtk.Stack (); 92 | stack.add_named (list_box_scroll, "listbox"); 93 | stack.add_named (empty_alert, "empty"); 94 | stack.add_named (welcome, "welcome"); 95 | 96 | foreach (var item in workspaces_controller.get_all ()) { 97 | var entry = new Workspaces.Models.SearchItem (); 98 | entry.workspace = item; 99 | add_entry (entry); 100 | foreach (var it in item.items) { 101 | var item_entry = new Workspaces.Models.SearchItem (); 102 | item_entry.item = it; 103 | add_entry (item_entry); 104 | } 105 | } 106 | 107 | var add_workspace_button = new Gtk.Button.from_icon_name ("emblem-system-symbolic", Gtk.IconSize.MENU); 108 | add_workspace_button.valign = Gtk.Align.CENTER; 109 | add_workspace_button.halign = Gtk.Align.START; 110 | add_workspace_button.always_show_image = true; 111 | add_workspace_button.can_focus = false; 112 | add_workspace_button.label = _ ("Preferences"); 113 | add_workspace_button.get_style_context ().add_class ("flat"); 114 | add_workspace_button.get_style_context ().add_class ("font-bold"); 115 | add_workspace_button.get_style_context ().add_class ("add-button"); 116 | add_workspace_button.clicked.connect (() => { 117 | Application.instance.load_preferences (); 118 | }); 119 | var add_revealer = new Gtk.Revealer (); 120 | add_revealer.transition_type = Gtk.RevealerTransitionType.CROSSFADE; 121 | add_revealer.reveal_child = true; 122 | add_revealer.add (add_workspace_button); 123 | 124 | var action_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); 125 | action_box.get_style_context ().add_class ("bottom-buttons"); 126 | action_box.margin_end = 9; 127 | action_box.margin_top = 6; 128 | action_box.margin_bottom = 6; 129 | action_box.margin_start = 9; 130 | action_box.hexpand = true; 131 | action_box.pack_start (add_revealer, false, false, 0); 132 | var main_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); 133 | main_box.add (stack); 134 | main_box.add (new Gtk.Separator (Gtk.Orientation.HORIZONTAL)); 135 | main_box.add (action_box); 136 | 137 | add (main_box); 138 | 139 | key_press_event.connect ((event) => { 140 | switch (event.keyval) { 141 | case Gdk.Key.Control_L : 142 | case Gdk.Key.Control_R : 143 | return false; 144 | case Gdk.Key.Down : 145 | case Gdk.Key.Up : 146 | bool has_selection = list_box.get_selected_rows ().length () > 0; 147 | if (!has_selection) { 148 | list_box.select_row (list_box.get_row_at_index (0)); 149 | } 150 | var rows = list_box.get_selected_rows (); 151 | if (rows.length () > 0) { 152 | rows.nth_data (0).grab_focus (); 153 | } 154 | if (has_selection) { 155 | list_box.key_press_event (event); 156 | } 157 | return true; 158 | case Gdk.Key.Return : 159 | bool has_selection = list_box.get_selected_rows ().length () > 0; 160 | if (has_selection) { 161 | list_box.activate (); 162 | } 163 | 164 | return false; 165 | case Gdk.Key.Escape : 166 | close (); 167 | return true; 168 | default : 169 | break; 170 | } 171 | 172 | if (event.keyval != Gdk.Key.Escape && !search_headerbar.is_focus) { 173 | search_headerbar.grab_focus (); 174 | search_headerbar.key_press_event (event); 175 | return true; 176 | } 177 | 178 | return false; 179 | }); 180 | 181 | set_titlebar (search_headerbar); 182 | search_headerbar.get_style_context ().remove_class ("titlebar"); 183 | search_headerbar.get_style_context ().add_class ("ql-entry"); 184 | show_all (); 185 | update_stack_visibility (); 186 | search_headerbar.grab_focus (); 187 | if (first_run) { 188 | var dialog = new Workspaces.Dialogs.Preferences (first_run, this); 189 | dialog.present (); 190 | } 191 | } 192 | 193 | public void add_entry (Workspaces.Models.SearchItem entry) { 194 | list_box.add (new Workspaces.Widgets.SearchListBoxItem (entry)); 195 | update_stack_visibility (); 196 | } 197 | 198 | private void update_stack_visibility () { 199 | if (list_box.get_children ().length () > 0) { 200 | stack.visible_child_name = "listbox"; 201 | } else if (search_headerbar.text.length == 0) { 202 | stack.visible_child_name = "welcome"; 203 | } else { 204 | stack.visible_child_name = "empty"; 205 | empty_alert.description = _ ("Try changing search terms."); 206 | } 207 | } 208 | 209 | private bool is_control_pressed () { 210 | Gdk.ModifierType state; 211 | if (Gtk.get_current_event_state (out state)) { 212 | var s = state & get_modifier_mask (Gdk.ModifierIntent.MODIFY_SELECTION); 213 | if (s == Gdk.ModifierType.CONTROL_MASK) { 214 | return true; 215 | } 216 | } 217 | 218 | return false; 219 | } 220 | } -------------------------------------------------------------------------------- /src/Settings/CustomShortcutSettings.vala: -------------------------------------------------------------------------------- 1 | class CustomShortcutSettings : Object { 2 | const string SCHEMA = "org.gnome.settings-daemon.plugins.media-keys"; 3 | const string KEY = "custom-keybinding"; 4 | 5 | const string RELOCATABLE_SCHEMA_PATH_TEMLPATE = 6 | "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom%d/"; 7 | 8 | const int MAX_SHORTCUTS = 100; 9 | 10 | static GLib.Settings settings; 11 | 12 | public static bool available = false; 13 | 14 | public struct CustomShortcut { 15 | string shortcut; 16 | string command; 17 | string relocatable_schema; 18 | } 19 | 20 | public static void init () { 21 | var schema_source = GLib.SettingsSchemaSource.get_default (); 22 | 23 | var schema = schema_source.lookup (SCHEMA, true); 24 | 25 | if (schema == null) { 26 | warning ("Schema \"%s\" is not installed on your system.", SCHEMA); 27 | return; 28 | } 29 | 30 | settings = new GLib.Settings.full (schema, null, null); 31 | available = true; 32 | } 33 | 34 | static string[] get_relocatable_schemas () { 35 | return settings.get_strv (KEY + "s"); 36 | } 37 | 38 | static string get_relocatable_schema_path (int i) { 39 | return RELOCATABLE_SCHEMA_PATH_TEMLPATE.printf (i); 40 | } 41 | 42 | static GLib.Settings ? get_relocatable_schema_settings (string relocatable_schema) { 43 | return new GLib.Settings.with_path (SCHEMA + "." + KEY, relocatable_schema); 44 | } 45 | 46 | public static string ? create_shortcut () requires (available) { 47 | for (int i = 0; i < MAX_SHORTCUTS; i++) { 48 | var new_relocatable_schema = get_relocatable_schema_path (i); 49 | 50 | if (relocatable_schema_is_used (new_relocatable_schema) == false) { 51 | reset_relocatable_schema (new_relocatable_schema); 52 | add_relocatable_schema (new_relocatable_schema); 53 | return new_relocatable_schema; 54 | } 55 | } 56 | 57 | return (string)null; 58 | } 59 | 60 | static bool relocatable_schema_is_used (string new_relocatable_schema) { 61 | var relocatable_schemas = get_relocatable_schemas (); 62 | 63 | foreach (var relocatable_schema in relocatable_schemas) 64 | if (relocatable_schema == new_relocatable_schema) 65 | return true; 66 | 67 | return false; 68 | } 69 | 70 | static void add_relocatable_schema (string new_relocatable_schema) { 71 | var relocatable_schemas = get_relocatable_schemas (); 72 | relocatable_schemas += new_relocatable_schema; 73 | settings.set_strv (KEY + "s", relocatable_schemas); 74 | apply_settings (settings); 75 | } 76 | 77 | static void reset_relocatable_schema (string relocatable_schema) { 78 | var relocatable_settings = get_relocatable_schema_settings (relocatable_schema); 79 | relocatable_settings.reset ("name"); 80 | relocatable_settings.reset ("command"); 81 | relocatable_settings.reset ("binding"); 82 | apply_settings (relocatable_settings); 83 | } 84 | 85 | public static bool edit_shortcut (string relocatable_schema, string shortcut) 86 | requires (available) { 87 | var relocatable_settings = get_relocatable_schema_settings (relocatable_schema); 88 | relocatable_settings.set_string ("binding", shortcut); 89 | Workspaces.Application.instance.update_command (shortcut); 90 | apply_settings (relocatable_settings); 91 | return true; 92 | } 93 | 94 | public static bool edit_command (string relocatable_schema, string command) 95 | requires (available) { 96 | var relocatable_settings = get_relocatable_schema_settings (relocatable_schema); 97 | relocatable_settings.set_string ("command", command); 98 | relocatable_settings.set_string ("name", command); 99 | apply_settings (relocatable_settings); 100 | return true; 101 | } 102 | 103 | public static GLib.List list_custom_shortcuts () 104 | requires (available) { 105 | var list = new GLib.List (); 106 | foreach (var relocatable_schema in get_relocatable_schemas ()) 107 | list.append (create_custom_shortcut_object (relocatable_schema)); 108 | return list; 109 | } 110 | 111 | static CustomShortcut ? create_custom_shortcut_object (string relocatable_schema) { 112 | var relocatable_settings = get_relocatable_schema_settings (relocatable_schema); 113 | 114 | return { 115 | relocatable_settings.get_string ("binding"), 116 | relocatable_settings.get_string ("command"), 117 | relocatable_schema 118 | }; 119 | } 120 | 121 | private static void apply_settings (GLib.Settings asettings) { 122 | asettings.apply (); 123 | GLib.Settings.sync (); 124 | } 125 | } -------------------------------------------------------------------------------- /src/Settings/Shortcut.vala: -------------------------------------------------------------------------------- 1 | class Shortcut : GLib.Object { 2 | public Gdk.ModifierType modifiers; 3 | public uint accel_key; 4 | 5 | string SEPARATOR = " · "; 6 | 7 | public Shortcut (uint key = 0, Gdk.ModifierType mod = (Gdk.ModifierType) 0) { 8 | accel_key = key; 9 | modifiers = mod; 10 | } 11 | 12 | public Shortcut.parse (string ? str) { 13 | if (str == null) { 14 | accel_key = 0; 15 | modifiers = (Gdk.ModifierType) 0; 16 | return; 17 | } 18 | 19 | Gtk.accelerator_parse (str, out accel_key, out modifiers); 20 | } 21 | 22 | public string to_gsettings () { 23 | if (!valid ()) 24 | return ""; 25 | return Gtk.accelerator_name (accel_key, modifiers); 26 | } 27 | 28 | public string to_readable () { 29 | if (!valid ()) 30 | return _ ("Disabled"); 31 | 32 | string tmp = ""; 33 | 34 | if ((modifiers & Gdk.ModifierType.SHIFT_MASK) > 0) 35 | tmp += "⇧" + SEPARATOR; 36 | if ((modifiers & Gdk.ModifierType.SUPER_MASK) > 0) 37 | tmp += "⌘" + SEPARATOR; 38 | if ((modifiers & Gdk.ModifierType.CONTROL_MASK) > 0) 39 | tmp += _ ("Ctrl") + SEPARATOR; 40 | if ((modifiers & Gdk.ModifierType.MOD1_MASK) > 0) 41 | tmp += "⎇" + SEPARATOR; 42 | if ((modifiers & Gdk.ModifierType.MOD2_MASK) > 0) 43 | tmp += "Mod2" + SEPARATOR; 44 | if ((modifiers & Gdk.ModifierType.MOD3_MASK) > 0) 45 | tmp += "Mod3" + SEPARATOR; 46 | if ((modifiers & Gdk.ModifierType.MOD4_MASK) > 0) 47 | tmp += "Mod4" + SEPARATOR; 48 | 49 | switch (accel_key) { 50 | case Gdk.Key.Tab : 51 | tmp += "↹"; 52 | break; 53 | case Gdk.Key.Up : 54 | tmp += "↑"; 55 | break; 56 | case Gdk.Key.Down : 57 | tmp += "↓"; 58 | break; 59 | case Gdk.Key.Left : 60 | tmp += "←"; 61 | break; 62 | case Gdk.Key.Right : 63 | tmp += "→"; 64 | break; 65 | default : 66 | tmp += Gtk.accelerator_get_label (accel_key, 0); 67 | break; 68 | } 69 | 70 | return tmp; 71 | } 72 | 73 | public bool valid () { 74 | if (accel_key == 0 || (modifiers == (Gdk.ModifierType) 0 && accel_key != Gdk.Key.Print)) 75 | return false; 76 | 77 | if (modifiers == Gdk.ModifierType.SHIFT_MASK) { 78 | if ((accel_key >= Gdk.Key.a && accel_key <= Gdk.Key.z) 79 | || (accel_key >= Gdk.Key.A && accel_key <= Gdk.Key.Z) 80 | || (accel_key >= Gdk.Key.@0 && accel_key <= Gdk.Key.@9) 81 | || (accel_key >= Gdk.Key.kana_fullstop && accel_key <= Gdk.Key.semivoicedsound) 82 | || (accel_key >= Gdk.Key.Arabic_comma && accel_key <= Gdk.Key.Arabic_sukun) 83 | || (accel_key >= Gdk.Key.Serbian_dje && accel_key <= Gdk.Key.Cyrillic_HARDSIGN) 84 | || (accel_key >= Gdk.Key.Greek_ALPHAaccent && accel_key <= Gdk.Key.Greek_omega) 85 | || (accel_key >= Gdk.Key.hebrew_doublelowline && accel_key <= Gdk.Key.hebrew_taf) 86 | || (accel_key >= Gdk.Key.Thai_kokai && accel_key <= Gdk.Key.Thai_lekkao) 87 | || (accel_key >= Gdk.Key.Hangul && accel_key <= Gdk.Key.Hangul_Special) 88 | || (accel_key >= Gdk.Key.Hangul_Kiyeog && accel_key <= Gdk.Key.Hangul_J_YeorinHieuh) 89 | || (accel_key == Gdk.Key.Home) 90 | || (accel_key == Gdk.Key.Left) 91 | || (accel_key == Gdk.Key.Up) 92 | || (accel_key == Gdk.Key.Right) 93 | || (accel_key == Gdk.Key.Down) 94 | || (accel_key == Gdk.Key.Page_Up) 95 | || (accel_key == Gdk.Key.Page_Down) 96 | || (accel_key == Gdk.Key.End) 97 | || (accel_key == Gdk.Key.Tab) 98 | || (accel_key == Gdk.Key.KP_Enter) 99 | || (accel_key == Gdk.Key.Return)) { 100 | return false; 101 | } 102 | } 103 | 104 | return true; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/Views/AlertView.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Views.AlertView : Gtk.Grid { 23 | /** 24 | * The first line of text, should be short and not contain markup. 25 | */ 26 | public string title { 27 | get { 28 | return title_label.label; 29 | } 30 | set { 31 | title_label.label = value; 32 | } 33 | } 34 | 35 | /** 36 | * The second line of text, explaining why this alert is shown. 37 | * You may need to escape it with #escape_text or #printf_escaped 38 | */ 39 | public string description { 40 | get { 41 | return description_label.label; 42 | } 43 | set { 44 | description_label.label = value; 45 | } 46 | } 47 | 48 | /** 49 | * The icon name 50 | */ 51 | public string icon_name { 52 | owned get { 53 | return image.icon_name; 54 | } 55 | set { 56 | image.set_from_icon_name (value, Gtk.IconSize.DIALOG); 57 | } 58 | } 59 | 60 | private Gtk.Label title_label; 61 | private Gtk.Label description_label; 62 | private Gtk.Image image; 63 | 64 | /** 65 | * Makes new AlertView 66 | * 67 | * @param title the first line of text 68 | * @param description the second line of text 69 | * @param icon_name the icon to be shown 70 | */ 71 | public AlertView (string title, string description, string icon_name) { 72 | Object (title: title, description: description, icon_name: icon_name); 73 | } 74 | 75 | construct { 76 | get_style_context ().add_class (Gtk.STYLE_CLASS_VIEW); 77 | 78 | title_label = new Gtk.Label (null); 79 | title_label.hexpand = true; 80 | title_label.get_style_context ().add_class ("h2"); 81 | title_label.max_width_chars = 45; 82 | title_label.wrap = true; 83 | title_label.wrap_mode = Pango.WrapMode.WORD_CHAR; 84 | title_label.xalign = 0; 85 | 86 | description_label = new Gtk.Label (null); 87 | description_label.hexpand = true; 88 | description_label.wrap = true; 89 | description_label.use_markup = true; 90 | description_label.xalign = 0; 91 | description_label.valign = Gtk.Align.START; 92 | 93 | image = new Gtk.Image (); 94 | var image_box = new Gtk.EventBox (); 95 | image_box.margin_top = 6; 96 | image_box.valign = Gtk.Align.START; 97 | image_box.add (image); 98 | 99 | column_spacing = 12; 100 | row_spacing = 6; 101 | halign = Gtk.Align.CENTER; 102 | valign = Gtk.Align.CENTER; 103 | vexpand = true; 104 | margin = 24; 105 | 106 | attach (image_box, 1, 1, 1, 2); 107 | attach (title_label, 2, 1, 1, 1); 108 | attach (description_label, 2, 2, 1, 1); 109 | } 110 | } -------------------------------------------------------------------------------- /src/Views/WorkspaceEditor.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Views.WorkspaceEditor : Gtk.Box { 23 | public signal void removed (); 24 | 25 | private Workspaces.Widgets.WorkspaceRow workspace; 26 | // private Workspaces.Widgets.Workspace workspace; 27 | private Workspaces.Widgets.IconButton icon_button; 28 | private Gtk.Button delete_button; 29 | 30 | private Gtk.Entry name_entry; 31 | 32 | construct { 33 | get_style_context ().add_class ("item-editor"); 34 | icon_button = new Workspaces.Widgets.IconButton (); 35 | icon_button.valign = Gtk.Align.START; 36 | icon_button.changed.connect ((icon) => { 37 | workspace.workspace.icon = icon.to_string (); 38 | Workspaces.Application.instance.preferences_window.workspaces_controller.save (); 39 | workspace.set_icon (icon); 40 | }); 41 | 42 | var name_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 6); 43 | name_box.hexpand = true; 44 | 45 | var header_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 2); 46 | var header_label = new Gtk.Label (_ ("Display name")); 47 | header_label.get_style_context ().add_class ("h4"); 48 | header_label.halign = Gtk.Align.START; 49 | 50 | name_entry = new Workspaces.Widgets.Entry (); 51 | name_entry.placeholder_text = _ ("Display name"); 52 | name_entry.get_style_context ().add_class ("h2"); 53 | name_entry.valign = Gtk.Align.START; 54 | name_entry.changed.connect (() => { 55 | workspace.workspace.name = name_entry.get_text (); 56 | workspace.set_label (name_entry.get_text ()); 57 | Workspaces.Application.instance.preferences_window.workspaces_controller.save (); 58 | }); 59 | header_box.add (header_label); 60 | header_box.add (name_entry); 61 | name_box.add (header_box); 62 | 63 | var header_grid = new Gtk.Grid (); 64 | header_grid.column_spacing = 12; 65 | header_grid.row_spacing = 6; 66 | header_grid.margin_start = 24; 67 | header_grid.margin_end = 24; 68 | header_grid.margin_top = 24; 69 | header_grid.attach (icon_button, 0, 0, 1, 1); 70 | header_grid.attach (name_box, 1, 0, 1, 1); 71 | 72 | var scrolled = new Gtk.ScrolledWindow (null, null); 73 | scrolled.expand = true; 74 | 75 | 76 | delete_button = new Gtk.Button.with_label (_ ("Delete")); 77 | delete_button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); 78 | delete_button.clicked.connect (() => { 79 | Application.instance.preferences_window.delete_workspace_dialog (workspace); 80 | }); 81 | 82 | var button_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); 83 | button_box.margin = 6; 84 | 85 | 86 | button_box.pack_end (delete_button, false, false); 87 | 88 | var bottom_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); 89 | bottom_box.hexpand = true; 90 | bottom_box.add (new Gtk.Separator (Gtk.Orientation.HORIZONTAL)); 91 | bottom_box.add (button_box); 92 | 93 | var overlay = new Gtk.Overlay (); 94 | overlay.add (header_grid); 95 | 96 | pack_start (overlay, false, false); 97 | 98 | pack_end (bottom_box, false, false); 99 | } 100 | 101 | public WorkspaceEditor () { 102 | Object ( 103 | orientation: Gtk.Orientation.VERTICAL, 104 | spacing: 12 105 | ); 106 | } 107 | 108 | public void load_workspace (Workspaces.Widgets.WorkspaceRow workspace) { 109 | this.workspace = workspace; 110 | 111 | if (workspace.workspace.icon == null) { 112 | icon_button.icon = Workspaces.Widgets.IconButton.default_icon; 113 | } else { 114 | try { 115 | icon_button.icon = Icon.new_for_string (workspace.workspace.icon); 116 | } catch (Error e) { 117 | debug (e.message); 118 | } 119 | } 120 | 121 | name_entry.set_text (workspace.workspace.name); 122 | } 123 | } -------------------------------------------------------------------------------- /src/Views/WorkspaceView.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Views.WorkspaceView : Gtk.Box { 23 | private Workspaces.Models.Store workspace; 24 | public WorkspacesController (Workspaces.Models.Workspace workspace) { 25 | Object (); 26 | } 27 | } -------------------------------------------------------------------------------- /src/Widgets/AppListBox.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Widgets.AppRow : Gtk.ListBoxRow { 23 | public Workspaces.Models.AppInfo app_info {get; set;} 24 | 25 | public AppRow (Workspaces.Models.AppInfo app_info) { 26 | Object (app_info: app_info); 27 | var image = new Gtk.Image.from_icon_name (app_info.icon_name, Gtk.IconSize.LARGE_TOOLBAR); 28 | image.pixel_size = 24; 29 | 30 | var label = new Gtk.Label (app_info.name); 31 | 32 | var grid = new Gtk.Grid (); 33 | grid.margin = 6; 34 | grid.column_spacing = 12; 35 | grid.attach (image, 0, 0, 1, 1); 36 | grid.attach (label, 1, 0, 1, 1); 37 | 38 | add (grid); 39 | } 40 | 41 | construct { 42 | } 43 | } 44 | 45 | public class Workspaces.Widgets.AppListBox : Gtk.ListBox { 46 | private const int LOAD_BATCH = 200; 47 | 48 | private static Gee.ArrayList apps; 49 | private static int max_index = -1; 50 | 51 | private Gee.ArrayList added; 52 | private int current_index = 0; 53 | private string search_query = ""; 54 | private Cancellable ? search_cancellable = null; 55 | 56 | static construct { 57 | apps = new Gee.ArrayList (); 58 | 59 | var list = AppInfo.get_all (); 60 | list.@foreach ((app) => { 61 | if (app is DesktopAppInfo) { 62 | var icon = app.get_icon (); 63 | var icon_name = "applications-other"; 64 | if (icon != null) { 65 | icon_name = icon.to_string (); 66 | } 67 | if (app.get_executable () == null) { 68 | return; 69 | } 70 | apps.add (new Workspaces.Models.AppInfo (app.get_name (), icon_name, app.get_executable ())); 71 | } 72 | }); 73 | 74 | max_index = apps.size - 1; 75 | apps.sort ((a, b) => strcmp (a.name, b.name)); 76 | } 77 | 78 | construct { 79 | added = new Gee.ArrayList (); 80 | 81 | set_sort_func (sort_func); 82 | set_filter_func (filter_func); 83 | load_next_apps (); 84 | } 85 | 86 | public AppListBox () { 87 | selection_mode = Gtk.SelectionMode.BROWSE; 88 | activate_on_single_click = false; 89 | } 90 | 91 | public Workspaces.Widgets.AppRow ? get_selected_app () { 92 | var row = get_selected_row (); 93 | if (row == null) { 94 | return null; 95 | } 96 | 97 | var app_row = row as Workspaces.Widgets.AppRow; 98 | if (app_row == null) { 99 | return null; 100 | } 101 | 102 | return app_row; 103 | } 104 | 105 | public void add_app (Workspaces.Models.AppInfo app) { 106 | var row = new Workspaces.Widgets.AppRow (app); 107 | add (row); 108 | 109 | added.add (app); 110 | } 111 | 112 | public void load_next_apps () { 113 | int new_index = current_index + LOAD_BATCH; 114 | int bound = new_index.clamp (0, max_index); 115 | 116 | if (current_index >= bound) { 117 | return; 118 | } 119 | var slice = apps.slice (current_index, bound); 120 | foreach (var app in slice) { 121 | add_app (app); 122 | } 123 | 124 | current_index = new_index; 125 | show_all (); 126 | } 127 | 128 | public void search (string query) { 129 | if (search_cancellable != null) { 130 | search_cancellable.cancel (); 131 | } 132 | 133 | search_cancellable = new Cancellable (); 134 | 135 | search_query = query; 136 | search_internal.begin (search_query); 137 | } 138 | 139 | private async void search_internal (string query) { 140 | new Thread ("search-internal", () => { 141 | Workspaces.Models.AppInfo[] matched = search_apps (query); 142 | if (search_cancellable.is_cancelled ()) { 143 | return null; 144 | } 145 | 146 | Idle.add (() => { 147 | foreach (Workspaces.Models.AppInfo app in matched) { 148 | add_app (app); 149 | } 150 | 151 | show_all (); 152 | invalidate_filter (); 153 | return false; 154 | }); 155 | 156 | return null; 157 | }); 158 | } 159 | 160 | private Workspaces.Models.AppInfo[] search_apps (string query) { 161 | Workspaces.Models.AppInfo[] matched = { }; 162 | for (int i = 0; i < apps.size; i++) { 163 | Workspaces.Models.AppInfo app = apps[i]; 164 | if (!added.contains (app) && query_matches_name (query, app.name)) { 165 | matched += app; 166 | } 167 | } 168 | 169 | return matched; 170 | } 171 | 172 | private int sort_func (Gtk.ListBoxRow row1, Gtk.ListBoxRow row2) { 173 | var icon_row1 = row1 as Workspaces.Widgets.AppRow; 174 | if (icon_row1 == null) { 175 | return 0; 176 | } 177 | 178 | var icon_row2 = row2 as Workspaces.Widgets.AppRow; 179 | if (icon_row2 == null) { 180 | return 0; 181 | } 182 | 183 | return strcmp (icon_row1.app_info.name, icon_row2.app_info.name); 184 | } 185 | 186 | private bool filter_func (Gtk.ListBoxRow row) { 187 | if (search_query.strip () == "") { 188 | return true; 189 | } 190 | var icon_row = row as Workspaces.Widgets.AppRow; 191 | 192 | if (icon_row == null) { 193 | return true; 194 | } 195 | return query_matches_name (search_query, icon_row.app_info.name); 196 | } 197 | 198 | private static bool query_matches_name (string query, string name) { 199 | return query.down () in name.down (); 200 | } 201 | } -------------------------------------------------------------------------------- /src/Widgets/Dot.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Widgets.Dot : Gtk.DrawingArea { 23 | public bool is_hidden = false; 24 | public Dot () { 25 | // Set favored widget size 26 | set_size_request (10, 10); 27 | set_vexpand (true); 28 | set_valign (Gtk.Align.CENTER); 29 | } 30 | 31 | public void set_is_hidden (bool hidden) { 32 | is_hidden = hidden; 33 | queue_draw (); 34 | } 35 | /* Widget is asked to draw itself */ 36 | public override bool draw (Cairo.Context cr) { 37 | if (!is_hidden) { 38 | cr.set_source_rgb (0.258, 0.56, 0.96); 39 | cr.translate (5, 5); 40 | cr.arc (0, 0, 5, 0, 2.0 * 3.14); 41 | cr.fill (); 42 | cr.stroke (); 43 | } 44 | 45 | return false; 46 | } 47 | } -------------------------------------------------------------------------------- /src/Widgets/Entry.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Widgets.Entry : Gtk.Entry { 23 | public override bool draw (Cairo.Context ctx) { 24 | base.draw (ctx); 25 | return true; 26 | } 27 | } -------------------------------------------------------------------------------- /src/Widgets/ExpandableCategory.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Widgets.ExpandableCategory : Granite.Widgets.SourceList.ExpandableItem { 23 | public Workspaces.Models.Workspace workspace { get; set; } 24 | 25 | public signal void added_new_item (Workspaces.Widgets.WorkspaceItem item); 26 | public signal void item_deleted (Workspaces.Widgets.WorkspaceItem item); 27 | 28 | public ExpandableCategory (Workspaces.Models.Workspace workspace) { 29 | Object (name: workspace.name); 30 | 31 | this.workspace = workspace; 32 | load (); 33 | } 34 | 35 | void load () { 36 | collapsible = true; 37 | expanded = true; 38 | var default_icon = new ThemedIcon ("dialog-question"); 39 | // icon_image.gicon = default_icon; 40 | 41 | // icon_image.pixel_size = 24; 42 | icon = default_icon; 43 | foreach ( var item in workspace.items ) { 44 | add_item (item, false); 45 | } 46 | 47 | workspace.item_added.connect ((item) => { 48 | add_item (item, true); 49 | }); 50 | } 51 | public void remove_item (Workspaces.Widgets.WorkspaceItem item) { 52 | remove (item); 53 | item_deleted (item); 54 | } 55 | 56 | private void add_item (Workspaces.Models.Item item, bool to_open) { 57 | var it = new Workspaces.Widgets.WorkspaceItem (item); 58 | it.set_data("stack_child", item.name); 59 | it.action_activated.connect ((i) => { 60 | i.selectable = false; 61 | it.item.execute_command (); 62 | GLib.Timeout.add (100, () => { 63 | i.selectable = true; 64 | return false; 65 | }, GLib.Priority.DEFAULT); 66 | }); 67 | it.activated.connect ((i) => { 68 | warning (i.name); 69 | }); 70 | add (it); 71 | 72 | if (to_open == true) { 73 | added_new_item (it); 74 | } 75 | } 76 | 77 | public override Gtk.Menu ? get_context_menu () { 78 | Gtk.Menu menu = new Gtk.Menu (); 79 | Gtk.MenuItem menu_item = new Gtk.MenuItem.with_label (_ ("Delete")); 80 | menu.add (menu_item); 81 | menu.show_all (); 82 | 83 | return menu; 84 | } 85 | } -------------------------------------------------------------------------------- /src/Widgets/IconButton.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Widgets.IconButton : Gtk.Button { 23 | public signal void changed (Icon icon); 24 | 25 | public Icon icon { 26 | set { 27 | icon_image.gicon = value; 28 | } 29 | 30 | owned get { 31 | return icon_image.gicon; 32 | } 33 | } 34 | 35 | private Gtk.Image icon_image; 36 | 37 | public static Icon default_icon; 38 | 39 | static construct { 40 | default_icon = new ThemedIcon ("dialog-question"); 41 | } 42 | 43 | construct { 44 | get_style_context ().add_class ("icon-selector-button"); 45 | 46 | icon_image = new Gtk.Image (); 47 | icon_image.gicon = default_icon; 48 | icon_image.pixel_size = 64; 49 | image = icon_image; 50 | 51 | var icon_chooser_popover = new Workspaces.Popovers.IconChooserPopover (); 52 | icon_chooser_popover.selected.connect ((icon_name) => { 53 | set_gicon (new ThemedIcon (icon_name)); 54 | icon_chooser_popover.popdown (); 55 | }); 56 | 57 | icon_chooser_popover.selected_file.connect ((file) => { 58 | set_gicon (new FileIcon (file)); 59 | icon_chooser_popover.popdown (); 60 | }); 61 | 62 | clicked.connect ( () => { 63 | icon_chooser_popover.set_relative_to (this); 64 | icon_chooser_popover.show_all (); 65 | icon_chooser_popover.popup (); 66 | }); 67 | 68 | show_all (); 69 | } 70 | 71 | private void set_gicon (Icon icon) { 72 | icon_image.gicon = icon; 73 | changed (icon); 74 | } 75 | } -------------------------------------------------------------------------------- /src/Widgets/IconListBox.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Widgets.IconRow : Gtk.ListBoxRow { 23 | public string icon_name { get; construct; } 24 | 25 | construct { 26 | var image = new Gtk.Image.from_icon_name (icon_name, Gtk.IconSize.LARGE_TOOLBAR); 27 | image.pixel_size = 24; 28 | 29 | var label = new Gtk.Label (icon_name); 30 | 31 | var grid = new Gtk.Grid (); 32 | grid.margin = 6; 33 | grid.column_spacing = 12; 34 | grid.attach (image, 0, 0, 1, 1); 35 | grid.attach (label, 1, 0, 1, 1); 36 | 37 | add (grid); 38 | } 39 | 40 | public IconRow (string icon_name) { 41 | Object (icon_name: icon_name); 42 | } 43 | } 44 | 45 | public class Workspaces.Widgets.IconListBox : Gtk.ListBox { 46 | private const int LOAD_BATCH = 100; 47 | 48 | private static Gee.ArrayList icons; 49 | private static int max_index = -1; 50 | 51 | private Gee.ArrayList added; 52 | private int current_index = 0; 53 | private string search_query = ""; 54 | private Cancellable ? search_cancellable = null; 55 | 56 | static construct { 57 | icons = new Gee.ArrayList (); 58 | 59 | var icon_theme = Gtk.IconTheme.get_default (); 60 | var list = icon_theme.list_icons (null); 61 | list.@foreach ((icon_name) => { 62 | icons.add (icon_name); 63 | }); 64 | 65 | max_index = icons.size - 1; 66 | icons.sort ((a, b) => strcmp (a, b)); 67 | } 68 | 69 | construct { 70 | added = new Gee.ArrayList (); 71 | 72 | set_sort_func (sort_func); 73 | set_filter_func (filter_func); 74 | load_next_icons (); 75 | } 76 | 77 | public IconListBox () { 78 | selection_mode = Gtk.SelectionMode.BROWSE; 79 | activate_on_single_click = false; 80 | } 81 | 82 | public string ? get_selected_icon_name () { 83 | var row = get_selected_row (); 84 | if (row == null) { 85 | return null; 86 | } 87 | 88 | var icon_row = row as Workspaces.Widgets.IconRow; 89 | if (icon_row == null) { 90 | return null; 91 | } 92 | 93 | return icon_row.icon_name; 94 | } 95 | 96 | public void add_icon_name (string icon_name) { 97 | var row = new Workspaces.Widgets.IconRow (icon_name); 98 | add (row); 99 | 100 | added.add (icon_name); 101 | } 102 | 103 | public void load_next_icons () { 104 | int new_index = current_index + LOAD_BATCH; 105 | int bound = new_index.clamp (0, max_index); 106 | 107 | var slice = icons.slice (current_index, bound); 108 | 109 | foreach (var icon_name in slice) { 110 | add_icon_name (icon_name); 111 | } 112 | 113 | current_index = new_index; 114 | show_all (); 115 | } 116 | 117 | public void search (string query) { 118 | if (search_cancellable != null) { 119 | search_cancellable.cancel (); 120 | } 121 | 122 | search_cancellable = new Cancellable (); 123 | 124 | search_query = query; 125 | search_internal.begin (search_query); 126 | } 127 | 128 | private async void search_internal (string query) { 129 | new Thread ("search-internal", () => { 130 | string[] matched = search_icons (query); 131 | if (search_cancellable.is_cancelled ()) { 132 | return null; 133 | } 134 | 135 | Idle.add (() => { 136 | foreach (string icon_name in matched) { 137 | add_icon_name (icon_name); 138 | } 139 | 140 | show_all (); 141 | invalidate_filter (); 142 | return false; 143 | }); 144 | 145 | return null; 146 | }); 147 | } 148 | 149 | private string[] search_icons (string query) { 150 | debug (@"searching $query"); 151 | string[] matched = { }; 152 | for (int i = 0; i < icons.size; i++) { 153 | string icon_name = icons[i]; 154 | if (!added.contains (icon_name) && query_matches_name (query, icon_name)) { 155 | matched += icon_name; 156 | } 157 | } 158 | 159 | return matched; 160 | } 161 | 162 | private int sort_func (Gtk.ListBoxRow row1, Gtk.ListBoxRow row2) { 163 | var icon_row1 = row1 as Workspaces.Widgets.IconRow; 164 | if (icon_row1 == null) { 165 | return 0; 166 | } 167 | 168 | var icon_row2 = row2 as Workspaces.Widgets.IconRow; 169 | if (icon_row2 == null) { 170 | return 0; 171 | } 172 | 173 | return strcmp (icon_row1.icon_name, icon_row2.icon_name); 174 | } 175 | 176 | private bool filter_func (Gtk.ListBoxRow row) { 177 | if (search_query.strip () == "") { 178 | return true; 179 | } 180 | 181 | var icon_row = row as Workspaces.Widgets.IconRow; 182 | if (icon_row == null) { 183 | return true; 184 | } 185 | 186 | return query_matches_name (search_query, icon_row.icon_name); 187 | } 188 | 189 | private static bool query_matches_name (string query, string icon_name) { 190 | return query.down () in icon_name.down (); 191 | } 192 | } -------------------------------------------------------------------------------- /src/Widgets/QuickWelcome.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Widgets.QuickWelcome : Gtk.Grid { 23 | public QuickWelcome () { 24 | Object (); 25 | } 26 | 27 | construct { 28 | var welcome = new Granite.Widgets.Welcome ("Workspaces", _ ("There are no workspaces")); 29 | welcome.append ("workspaces-new-workspace", _ ("Add Workspace"), _ ("Add a new workspace")); 30 | 31 | add (welcome); 32 | 33 | welcome.activated.connect ((index) => { 34 | switch (index) { 35 | case 0 : 36 | Application.instance.load_preferences (); 37 | break; 38 | } 39 | }); 40 | } 41 | } -------------------------------------------------------------------------------- /src/Widgets/SearchListBox.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Widgets.SearchListBox : Gtk.ListBox { 23 | private string search_text = ""; 24 | public SearchListBox () { 25 | set_selection_mode (Gtk.SelectionMode.SINGLE); 26 | set_filter_func (do_filter_list); 27 | } 28 | 29 | public void set_search_text (string search_text) { 30 | this.search_text = search_text; 31 | invalidate_filter (); 32 | } 33 | 34 | protected bool do_filter_list (Gtk.ListBoxRow row) { 35 | SearchListBoxItem child = row as SearchListBoxItem; 36 | 37 | if (search_text.length > 0) { 38 | return child.item.contains_text (search_text.down ()); 39 | } 40 | 41 | return true; 42 | } 43 | } -------------------------------------------------------------------------------- /src/Widgets/SearchListBoxItem.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Widgets.SearchListBoxItem : Gtk.ListBoxRow { 23 | public Workspaces.Models.SearchItem item {get; set;} 24 | 25 | public SearchListBoxItem (Workspaces.Models.SearchItem entry) { 26 | Object (); 27 | 28 | item = entry; 29 | 30 | var grid = new Gtk.Grid (); 31 | grid.column_spacing = 12; 32 | grid.row_spacing = 3; 33 | grid.margin = 12; 34 | grid.margin_bottom = grid.margin_top = 6; 35 | 36 | add (grid); 37 | 38 | var name = ""; 39 | if (entry.workspace != null) { 40 | name = entry.workspace.name; 41 | if (entry.workspace.icon != null) { 42 | try { 43 | var gicon = Icon.new_for_string (entry.workspace.icon); 44 | var icon = new Gtk.Image.from_gicon (gicon, Gtk.IconSize.SMALL_TOOLBAR); 45 | icon.set_pixel_size (32); 46 | grid.attach (icon, 0, 0, 1, 1); 47 | } catch (Error e) { 48 | debug (e.message); 49 | } 50 | } 51 | 52 | var sanitised_text = name.replace ("\n", ""); 53 | var text = new Gtk.Label (sanitised_text); 54 | text.get_style_context ().add_class ("h3"); 55 | text.get_style_context ().add_class ("bold-label"); 56 | text.ellipsize = Pango.EllipsizeMode.MIDDLE; 57 | text.lines = 1; 58 | text.single_line_mode = true; 59 | text.max_width_chars = 60; 60 | 61 | grid.attach (text, 1, 0, 1, 1); 62 | grid.attach (new Workspaces.Widgets.Dot (), 2, 0, 1, 1); 63 | } else if (entry.item != null) { 64 | get_style_context ().add_class ("search-list-item-item"); 65 | name = entry.item.name; 66 | if (entry.item.icon != null) { 67 | try { 68 | var gicon = Icon.new_for_string (entry.item.icon); 69 | var icon = new Gtk.Image.from_gicon (gicon, Gtk.IconSize.SMALL_TOOLBAR); 70 | icon.set_pixel_size (32); 71 | grid.attach (icon, 0, 0, 1, 1); 72 | } catch (Error e) { 73 | debug (e.message); 74 | } 75 | } 76 | var sanitised_text = name.replace ("\n", ""); 77 | var text = new Gtk.Label (sanitised_text); 78 | text.get_style_context ().add_class ("h3"); 79 | text.ellipsize = Pango.EllipsizeMode.MIDDLE; 80 | text.lines = 1; 81 | text.single_line_mode = true; 82 | text.max_width_chars = 60; 83 | grid.attach (text, 1, 0, 1, 1); 84 | 85 | if (entry.item.auto_start == true) { 86 | var dot = new Workspaces.Widgets.Dot (); 87 | dot.set_hexpand (true); 88 | grid.attach (dot, 2, 0, 1, 1); 89 | } 90 | } 91 | 92 | 93 | show_all (); 94 | } 95 | } -------------------------------------------------------------------------------- /src/Widgets/SettingBox.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Widgets.SettingBox : Gtk.ListBoxRow { 23 | public Gtk.Widget widget { get; construct; } 24 | public string title { get; construct; } 25 | 26 | private Gtk.Label label; 27 | 28 | construct { 29 | activatable = false; 30 | selectable = false; 31 | 32 | label = new Gtk.Label (title); 33 | label.halign = Gtk.Align.START; 34 | label.margin = 6; 35 | } 36 | 37 | public SettingBox (string title, Gtk.Widget widget, bool add_separator) { 38 | Object (title: title, widget: widget); 39 | 40 | var main_grid = new Gtk.Grid (); 41 | main_grid.hexpand = true; 42 | main_grid.column_spacing = 12; 43 | main_grid.margin_top = 4; 44 | main_grid.margin_bottom = 4; 45 | 46 | if (add_separator) { 47 | main_grid.attach (new Gtk.Separator (Gtk.Orientation.HORIZONTAL), 0, 0, 2, 1); 48 | } 49 | 50 | main_grid.attach (label, 0, 1, 1, 1); 51 | main_grid.attach (widget, 1, 1, 1, 1); 52 | add (main_grid); 53 | 54 | show_all (); 55 | } 56 | } 57 | 58 | public class Workspaces.Widgets.SettingsGrid : Gtk.Grid { 59 | private Gtk.ListBox list_box; 60 | private Gtk.Label title_label; 61 | 62 | construct { 63 | list_box = new Gtk.ListBox (); 64 | 65 | title_label = new Gtk.Label (null); 66 | title_label.get_style_context ().add_class ("h4"); 67 | title_label.halign = Gtk.Align.START; 68 | 69 | var frame = new Gtk.Frame (null); 70 | frame.add (list_box); 71 | 72 | attach (title_label, 0, 0, 1, 1); 73 | attach (frame, 0, 1, 1, 1); 74 | } 75 | 76 | public SettingsGrid (string ? title) { 77 | Object (); 78 | if (title != null) { 79 | title_label.label = title; 80 | } 81 | // else { 82 | // set_widget_visible (title_label, false); 83 | // } 84 | } 85 | 86 | public void add_widget (Gtk.Widget widget) { 87 | list_box.add (widget); 88 | } 89 | } -------------------------------------------------------------------------------- /src/Widgets/ShortcutEntry.vala: -------------------------------------------------------------------------------- 1 | /* Copyright 2015 Marvin Beckers 2 | * 3 | * This program is free software: you can redistribute it 4 | * and/or modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation, either version 3 of the 6 | * License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be 9 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 11 | * Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program. If not, see http://www.gnu.org/licenses/. 15 | */ 16 | 17 | public class Workspaces.Widgets.ShortcutEntry : Gtk.TreeView { 18 | public signal void shortcut_changed (string new_shortcut); 19 | 20 | public ShortcutEntry (string accel) { 21 | var shortcut = new Shortcut.parse (accel); 22 | 23 | var cell_edit = new Gtk.CellRendererAccel (); 24 | cell_edit.editable = true; 25 | this.insert_column_with_attributes (-1, null, cell_edit, "text", 0); 26 | this.headers_visible = false; 27 | this.get_column (0).expand = true; 28 | 29 | cell_edit.accel_edited.connect ((path, key, mods) => { 30 | var new_shortcut = new Shortcut (key, mods); 31 | change_shortcut (path, new_shortcut); 32 | shortcut_changed (new_shortcut.to_gsettings ()); 33 | }); 34 | 35 | Gtk.TreeIter iter; 36 | var store = new Gtk.ListStore (1, typeof (string)); 37 | store.append (out iter); 38 | store.set (iter, 0, shortcut.to_readable ()); 39 | 40 | model = store; 41 | } 42 | 43 | private void change_shortcut (string path, Shortcut ? shortcut) { 44 | Gtk.TreeIter iter; 45 | 46 | model.get_iter (out iter, new Gtk.TreePath.from_string (path)); 47 | var ls = (model as Gtk.ListStore); 48 | if (ls != null) { 49 | ls.set (iter, 0, shortcut.to_readable ()); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/Widgets/TypeComboBox.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Widgets.TypeComboBox : Gtk.ComboBox { 23 | private Gtk.ListStore list_store; 24 | private Gtk.TreeIter ? active_iter; 25 | 26 | private static Gee.ArrayList types; 27 | 28 | static construct { 29 | types = new Gee.ArrayList (); 30 | types.add ({ "URL", _ ("URL"), "applications-internet" }); 31 | types.add ({ "Directory", _ ("Directory"), "document-open" }); 32 | types.add ({ "Application", _ ("Application"), "applications-interfacedesign" }); 33 | types.add ({ "ApplicationDirectory", _ ("Application + Directory"), "applications-development" }); 34 | types.add ({ "Custom", _ ("Custom command"), "applications-other" }); 35 | } 36 | 37 | construct { 38 | list_store = new Gtk.ListStore (3, typeof (string), typeof (unowned string), typeof (string)); 39 | model = list_store; 40 | 41 | Gtk.TreeIter iter; 42 | foreach (var type in types) { 43 | list_store.append (out iter); 44 | list_store.@set (iter, 0, type.id, 1, type.name, 2, type.icon_name); 45 | } 46 | 47 | var pixbuf_cell = new Gtk.CellRendererPixbuf (); 48 | pack_start (pixbuf_cell, false); 49 | add_attribute (pixbuf_cell, "icon-name", 2); 50 | 51 | var text_cell = new Gtk.CellRendererText (); 52 | pack_start (text_cell, true); 53 | add_attribute (text_cell, "text", 1); 54 | } 55 | 56 | public void set_current_selection (string selected_id) { 57 | Gtk.TreeIter iter; 58 | for (bool next = list_store.get_iter_first (out iter); next; next = list_store.iter_next (ref iter)) { 59 | Value id; 60 | list_store.get_value (iter, 0, out id); 61 | 62 | if (((string)id) == selected_id) { 63 | active_iter = iter; 64 | } 65 | } 66 | 67 | set_active_iter (active_iter); 68 | } 69 | 70 | public string ? get_selected_category_id () { 71 | Gtk.TreeIter iter; 72 | if (!get_active_iter (out iter)) { 73 | return null; 74 | } 75 | 76 | Value id; 77 | list_store.get_value (iter, 0, out id); 78 | 79 | return (string)id; 80 | } 81 | } -------------------------------------------------------------------------------- /src/Widgets/Welcome.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Widgets.Welcome : Gtk.Grid { 23 | public Welcome () { 24 | Object (); 25 | } 26 | 27 | construct { 28 | var welcome = new Granite.Widgets.Welcome ("Workspaces", _ ("No Workspace selected")); 29 | welcome.append ("workspaces-new-workspace", _ ("Add Workspace"), _ ("Add a new workspace")); 30 | welcome.append ("workspaces-new-item", _ ("Add Item"), _ ("Add a new item")); 31 | add (welcome); 32 | 33 | welcome.activated.connect ((index) => { 34 | switch (index) { 35 | case 0 : 36 | Workspaces.Application.instance.preferences_window.show_add_workspace_dialog (); 37 | break; 38 | case 1 : 39 | Workspaces.Application.instance.preferences_window.show_add_item_dialog (); 40 | break; 41 | } 42 | }); 43 | } 44 | } -------------------------------------------------------------------------------- /src/Widgets/WorkspaceItem.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 - Today Goncalo Margalho (https://github.com/devalien) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Goncalo Margalho 20 | */ 21 | 22 | public class Workspaces.Widgets.WorkspaceItem : Granite.Widgets.SourceList.Item { 23 | public Workspaces.Models.Item item {get; set;} 24 | 25 | public WorkspaceItem (Workspaces.Models.Item item) { 26 | Object (name: item.name); 27 | 28 | this.item = item; 29 | // var icon_image = new GLib.Icon (); 30 | if (item.icon != null) { 31 | try { 32 | icon = Icon.new_for_string (item.icon); 33 | } catch (Error e) { 34 | debug (e.message); 35 | } 36 | } 37 | 38 | var default_icon = new ThemedIcon ("media-playback-start"); 39 | // icon_image.gicon = default_icon; 40 | 41 | this.activatable = default_icon; 42 | } 43 | 44 | public void remove_itself () { 45 | var has_deleted = Application.instance.workspaces_controller.remove_item (item); 46 | if (has_deleted) { 47 | var workspace_parent = this.parent as Workspaces.Widgets.ExpandableCategory; 48 | if (workspace_parent != null) { 49 | workspace_parent.remove_item (this); 50 | } 51 | } 52 | } 53 | public override Gtk.Menu ? get_context_menu () { 54 | Gtk.Menu menu = new Gtk.Menu (); 55 | Gtk.MenuItem menu_item = new Gtk.MenuItem.with_label (_ ("Delete")); 56 | menu_item.activate.connect (() => { 57 | remove_itself (); 58 | }); 59 | menu.add (menu_item); 60 | menu.show_all (); 61 | 62 | return menu; 63 | } 64 | } -------------------------------------------------------------------------------- /src/meson.build: -------------------------------------------------------------------------------- 1 | # Listing files to compile 2 | sources = files ( 3 | 'Controllers/WorkspacesController.vala', 4 | 5 | 'Dialogs/About.vala', 6 | 'Dialogs/AddItem.vala', 7 | 'Dialogs/AddWorkspace.vala', 8 | 'Dialogs/Dialog.vala', 9 | 'Dialogs/Preferences.vala', 10 | 11 | 'Models/AppInfo.vala', 12 | 'Models/Item.vala', 13 | 'Models/ItemType.vala', 14 | 'Models/SearchItem.vala', 15 | 'Models/Workspace.vala', 16 | 'Models/WorkspacesStore.vala', 17 | 18 | 'Popovers/IconChooserPopover.vala', 19 | 'Popovers/AppChooserPopover.vala', 20 | 21 | 'Settings/CustomShortcutSettings.vala', 22 | 'Settings/Shortcut.vala', 23 | 24 | 'Views/AlertView.vala', 25 | 'Views/ItemEditor.vala', 26 | 'Views/WorkspaceEditor.vala', 27 | 28 | 'Widgets/AppListBox.vala', 29 | 'Widgets/Dot.vala', 30 | 'Widgets/Entry.vala', 31 | 'Widgets/ExpandableCategory.vala', 32 | 'Widgets/IconButton.vala', 33 | 'Widgets/IconListBox.vala', 34 | 'Widgets/ItemRow.vala', 35 | 'Widgets/QuickWelcome.vala', 36 | 'Widgets/SearchListBox.vala', 37 | 'Widgets/SearchListBoxItem.vala', 38 | 'Widgets/SettingBox.vala', 39 | 'Widgets/ShortcutEntry.vala', 40 | 'Widgets/TypeComboBox.vala', 41 | 'Widgets/Welcome.vala', 42 | 'Widgets/WorkspaceItem.vala', 43 | 'Widgets/WorkspaceRow.vala', 44 | 45 | 'Application.vala', 46 | 'PreferencesWindow.vala', 47 | 'Main.vala', 48 | 'QuickLaunchWindow.vala', 49 | ) 50 | --------------------------------------------------------------------------------