@@ -30,6 +30,22 @@ use crate::query::Query;
3030
3131use serde:: Deserialize ;
3232
33+ const SHORTCUT_DEFINITIONS : [ ( & str , & str ) ; 13 ] = [
34+ ( "<primary>q" , "app.quit" ) ,
35+ ( "<primary>question" , "app.shortcuts" ) ,
36+ ( "F5" , "win.refresh" ) ,
37+ ( "<primary>u" , "win.upgrade-container" ) ,
38+ ( "<primary><shift>u" , "win.upgrade-all" ) ,
39+ ( "<primary>i" , "win.install-package" ) ,
40+ ( "<primary>comma" , "win.preferences" ) ,
41+ ( "<primary>period" , "win.open-terminal" ) ,
42+ ( "<primary>e" , "win.view-exportable-apps" ) ,
43+ ( "<primary>Delete" , "win.delete-container" ) ,
44+ ( "<primary>s" , "win.stop-container" ) ,
45+ ( "<primary>l" , "win.command-log" ) ,
46+ ( "<primary>d" , "win.delete-container" ) ,
47+ ] ;
48+
3349#[ derive( Debug , Clone , Deserialize , Hash , Eq , PartialEq ) ]
3450#[ serde( rename_all = "PascalCase" ) ]
3551pub struct Image {
@@ -69,6 +85,9 @@ mod imp {
6985 #[ property( get) ]
7086 pub settings : gio:: Settings ,
7187
88+ pub shortcuts : gio:: ListStore ,
89+ pub shortcuts_enabled : std:: cell:: Cell < bool > ,
90+
7291 #[ property( get, set, builder( ViewType :: default ( ) ) ) ]
7392 current_view : RefCell < ViewType > ,
7493 #[ property( get, set, builder( DialogType :: default ( ) ) ) ]
@@ -109,6 +128,8 @@ mod imp {
109128 selected_task : Default :: default ( ) ,
110129 bundled_update_available : std:: cell:: Cell :: new ( false ) ,
111130 settings : gio:: Settings :: new ( "com.ranfdev.DistroShelf" ) ,
131+ shortcuts : gio:: ListStore :: new :: < gtk:: Shortcut > ( ) ,
132+ shortcuts_enabled : std:: cell:: Cell :: new ( false ) ,
112133 }
113134 }
114135 }
@@ -312,9 +333,57 @@ impl RootStore {
312333 ) ;
313334 } ) ;
314335
336+ this. enable_shortcuts ( ) ;
337+
315338 this
316339 }
317340
341+ fn build_shortcut ( trigger : & str , action : & str ) -> Option < gtk:: Shortcut > {
342+ let trigger =
343+ gtk:: ShortcutTrigger :: parse_string ( trigger) . expect ( "Invalid shortcut trigger" ) ;
344+ let action = gtk:: NamedAction :: new ( action) ;
345+ Some ( gtk:: Shortcut :: new ( Some ( trigger) , Some ( action) ) )
346+ }
347+
348+ fn rebuild_shortcuts_model ( & self ) {
349+ let shortcuts = & self . imp ( ) . shortcuts ;
350+ shortcuts. remove_all ( ) ;
351+ for ( trigger, action) in SHORTCUT_DEFINITIONS {
352+ if let Some ( shortcut) = Self :: build_shortcut ( trigger, action) {
353+ shortcuts. append ( & shortcut) ;
354+ }
355+ }
356+ }
357+
358+ pub fn shortcuts_model ( & self ) -> gio:: ListStore {
359+ self . imp ( ) . shortcuts . clone ( )
360+ }
361+
362+ pub fn shortcut_action_names ( & self ) -> Vec < & ' static str > {
363+ SHORTCUT_DEFINITIONS
364+ . iter ( )
365+ . map ( |( _, action) | * action)
366+ . collect :: < Vec < _ > > ( )
367+ }
368+
369+ pub fn enable_shortcuts ( & self ) {
370+ if self . imp ( ) . shortcuts_enabled . get ( ) {
371+ return ;
372+ }
373+
374+ self . rebuild_shortcuts_model ( ) ;
375+ self . imp ( ) . shortcuts_enabled . set ( true ) ;
376+ }
377+
378+ pub fn disable_shortcuts ( & self ) {
379+ if !self . imp ( ) . shortcuts_enabled . get ( ) {
380+ return ;
381+ }
382+
383+ self . imp ( ) . shortcuts . remove_all ( ) ;
384+ self . imp ( ) . shortcuts_enabled . set ( false ) ;
385+ }
386+
318387 pub fn start_background_tasks ( & self ) {
319388 self . distrobox_version ( ) . refetch ( ) ;
320389 self . container_runtime ( ) . refetch ( ) ;
@@ -1179,4 +1248,32 @@ mod tests {
11791248 assert_eq ! ( returned_task, existing_task) ;
11801249 assert_eq ! ( store. tasks( ) . iter( ) . count( ) , 1 ) ;
11811250 }
1251+
1252+ #[ gtk:: test]
1253+ fn test_shortcuts_toggle_is_idempotent ( ) {
1254+ let store = RootStore :: new ( NullCommandRunnerBuilder :: new ( ) . build ( ) ) ;
1255+
1256+ assert_eq ! (
1257+ store. shortcuts_model( ) . n_items( ) ,
1258+ SHORTCUT_DEFINITIONS . len( ) as u32
1259+ ) ;
1260+
1261+ store. enable_shortcuts ( ) ;
1262+ assert_eq ! (
1263+ store. shortcuts_model( ) . n_items( ) ,
1264+ SHORTCUT_DEFINITIONS . len( ) as u32
1265+ ) ;
1266+
1267+ store. disable_shortcuts ( ) ;
1268+ assert_eq ! ( store. shortcuts_model( ) . n_items( ) , 0 ) ;
1269+
1270+ store. disable_shortcuts ( ) ;
1271+ assert_eq ! ( store. shortcuts_model( ) . n_items( ) , 0 ) ;
1272+
1273+ store. enable_shortcuts ( ) ;
1274+ assert_eq ! (
1275+ store. shortcuts_model( ) . n_items( ) ,
1276+ SHORTCUT_DEFINITIONS . len( ) as u32
1277+ ) ;
1278+ }
11821279}
0 commit comments