@@ -10,6 +10,7 @@ use cosmic::{
10
10
} ,
11
11
Element ,
12
12
} ;
13
+ use i18n_embed:: LanguageLoader ;
13
14
use mime_guess:: Mime ;
14
15
use std:: collections:: HashMap ;
15
16
@@ -86,6 +87,7 @@ pub fn context_menu<'a>(
86
87
let mut selected_dir = 0 ;
87
88
let mut selected = 0 ;
88
89
let mut selected_trash_only = false ;
90
+ let mut selected_desktop_entry = None ;
89
91
let mut selected_types: Vec < Mime > = vec ! [ ] ;
90
92
tab. items_opt ( ) . map ( |items| {
91
93
for item in items. iter ( ) {
@@ -94,8 +96,16 @@ pub fn context_menu<'a>(
94
96
if item. metadata . is_dir ( ) {
95
97
selected_dir += 1 ;
96
98
}
97
- if item. location_opt == Some ( Location :: Trash ) {
98
- selected_trash_only = true ;
99
+ match & item. location_opt {
100
+ Some ( Location :: Trash ) => selected_trash_only = true ,
101
+ Some ( Location :: Path ( path) ) => {
102
+ if selected == 1
103
+ && path. extension ( ) . and_then ( |s| s. to_str ( ) ) == Some ( "desktop" )
104
+ {
105
+ selected_desktop_entry = Some ( & * * path) ;
106
+ }
107
+ }
108
+ _ => ( ) ,
99
109
}
100
110
selected_types. push ( item. mime . clone ( ) ) ;
101
111
}
@@ -104,6 +114,17 @@ pub fn context_menu<'a>(
104
114
selected_types. sort_unstable ( ) ;
105
115
selected_types. dedup ( ) ;
106
116
selected_trash_only = selected_trash_only && selected == 1 ;
117
+ // Parse the desktop entry if it is the only selection
118
+ let selected_desktop_entry = selected_desktop_entry. and_then ( |path| {
119
+ if selected == 1 {
120
+ let lang_id = crate :: localize:: LANGUAGE_LOADER . current_language ( ) ;
121
+ let language = lang_id. language . as_str ( ) ;
122
+ // Cache?
123
+ cosmic:: desktop:: load_desktop_file ( Some ( language) , path)
124
+ } else {
125
+ None
126
+ }
127
+ } ) ;
107
128
108
129
let mut children: Vec < Element < _ > > = Vec :: new ( ) ;
109
130
match ( & tab. mode , & tab. location ) {
@@ -116,6 +137,17 @@ pub fn context_menu<'a>(
116
137
if tab:: trash_entries ( ) > 0 {
117
138
children. push ( menu_item ( fl ! ( "empty-trash" ) , Action :: EmptyTrash ) . into ( ) ) ;
118
139
}
140
+ } else if let Some ( entry) = selected_desktop_entry {
141
+ children. push ( menu_item ( fl ! ( "open" ) , Action :: Open ) . into ( ) ) ;
142
+ for ( i, action) in entry. desktop_actions . into_iter ( ) . enumerate ( ) {
143
+ children. push ( menu_item ( action. name , Action :: ExecEntryAction ( i) ) . into ( ) )
144
+ }
145
+ children. push ( divider:: horizontal:: light ( ) . into ( ) ) ;
146
+ children. push ( menu_item ( fl ! ( "rename" ) , Action :: Rename ) . into ( ) ) ;
147
+ children. push ( menu_item ( fl ! ( "cut" ) , Action :: Cut ) . into ( ) ) ;
148
+ children. push ( menu_item ( fl ! ( "copy" ) , Action :: Copy ) . into ( ) ) ;
149
+ // Should this simply bypass trash and remove the shortcut?
150
+ children. push ( menu_item ( fl ! ( "move-to-trash" ) , Action :: MoveToTrash ) . into ( ) ) ;
119
151
} else if selected > 0 {
120
152
if selected_dir == 1 && selected == 1 || selected_dir == 0 {
121
153
children. push ( menu_item ( fl ! ( "open" ) , Action :: Open ) . into ( ) ) ;
0 commit comments