@@ -267,6 +267,7 @@ def on_module_selected(self):
267
267
vbox .set_border_width (6 )
268
268
vbox .set_spacing (6 )
269
269
self .sidePage .stack .add_titled (vbox , "shortcuts" , _ ("Shortcuts" ))
270
+ self .sidePage .stack .connect ("notify::visible-child-name" , self .stack_page_changed )
270
271
271
272
headingbox = Gtk .Box .new (Gtk .Orientation .VERTICAL , 2 )
272
273
mainbox = Gtk .Box .new (Gtk .Orientation .HORIZONTAL , 2 )
@@ -281,10 +282,17 @@ def on_module_selected(self):
281
282
282
283
paned .add1 (left_vbox )
283
284
285
+ right_box = Gtk .Box (orientation = Gtk .Orientation .VERTICAL )
286
+ paned .add2 (right_box )
287
+
288
+ self .kb_search_entry = Gtk .Entry (placeholder_text = _ ("Type to search" ))
289
+ right_box .pack_start (self .kb_search_entry , False , False , 2 )
290
+ self .kb_search_handler_id = self .kb_search_entry .connect ("changed" , self .on_kb_search_changed )
291
+
284
292
right_scroller = Gtk .ScrolledWindow .new (None , None )
285
293
right_scroller .set_policy (Gtk .PolicyType .AUTOMATIC , Gtk .PolicyType .NEVER )
286
294
right_scroller .add (right_vbox )
287
- paned . add2 (right_scroller )
295
+ right_box . pack_start (right_scroller , True , True , 2 )
288
296
289
297
category_scroller = Gtk .ScrolledWindow .new (None , None )
290
298
category_scroller .set_shadow_type (Gtk .ShadowType .IN )
@@ -298,9 +306,9 @@ def on_module_selected(self):
298
306
right_vbox .pack_start (kb_name_scroller , True , True , 2 )
299
307
right_vbox .pack_start (entry_scroller , True , True , 2 )
300
308
kb_name_scroller .set_property ('min-content-height' , 150 )
301
- self .cat_tree = Gtk .TreeView . new ( )
302
- self .kb_tree = Gtk .TreeView . new ( )
303
- self .entry_tree = Gtk .TreeView . new ( )
309
+ self .cat_tree = Gtk .TreeView ( enable_search = False , search_column = - 1 )
310
+ self .kb_tree = Gtk .TreeView ( enable_search = False , search_column = - 1 )
311
+ self .entry_tree = Gtk .TreeView ( enable_search = False , search_column = - 1 )
304
312
305
313
self .kb_tree .connect ('row-activated' , self .onCustomKeyBindingEdited )
306
314
self .kb_tree .connect ('button-press-event' , self .onContextMenuPopup )
@@ -331,9 +339,11 @@ def on_module_selected(self):
331
339
self .cat_store = Gtk .TreeStore (str , # Icon name or None
332
340
str , # The category name
333
341
object ) # The category object
342
+ self .kb_root_store = Gtk .ListStore ( str , # Keybinding name
343
+ object )# The keybinding object
334
344
335
- self .kb_store = Gtk .ListStore ( str , # Keybinding name
336
- object ) # The keybinding object
345
+ self .kb_store = Gtk .TreeModelFilter ( child_model = self . kb_root_store )
346
+ self . kb_store . set_visible_func ( self . kb_store_visible_func )
337
347
338
348
self .entry_store = Gtk .ListStore (str ) # Accel string
339
349
@@ -350,7 +360,6 @@ def on_module_selected(self):
350
360
cat_column .set_property ('min-width' , 200 )
351
361
352
362
self .cat_tree .append_column (cat_column )
353
- self .cat_tree .set_search_column (1 )
354
363
self .cat_tree .connect ("cursor-changed" , self .onCategoryChanged )
355
364
356
365
kb_name_cell = Gtk .CellRendererText ()
@@ -371,7 +380,7 @@ def on_module_selected(self):
371
380
self .entry_tree .append_column (entry_column )
372
381
373
382
self .entry_tree .set_tooltip_text (CellRendererKeybinding .TOOLTIP_TEXT )
374
-
383
+ self . current_category = None
375
384
self .main_store = []
376
385
377
386
for cat in CATEGORIES :
@@ -402,11 +411,12 @@ def on_module_selected(self):
402
411
403
412
paned .set_position (max (w , 200 ))
404
413
405
- self .loadCustoms ()
406
414
self .cat_tree .set_model (self .cat_store )
407
415
self .kb_tree .set_model (self .kb_store )
408
416
self .entry_tree .set_model (self .entry_store )
409
417
418
+ self .populate_kb_tree ()
419
+
410
420
vbox .pack_start (headingbox , True , True , 0 )
411
421
412
422
vbox = Gtk .Box (orientation = Gtk .Orientation .VERTICAL )
@@ -425,27 +435,75 @@ def on_module_selected(self):
425
435
widget .show ()
426
436
vbox .pack_start (cheat_box , True , True , 0 )
427
437
438
+ self .kb_search_entry .grab_focus ()
439
+
440
+ def stack_page_changed (self , stack , pspec , data = None ):
441
+ if stack .get_visible_child_name () == "shortcuts" :
442
+ self .kb_search_entry .grab_focus ()
443
+
428
444
def addNotebookTab (self , tab ):
429
445
self .notebook .append_page (tab .tab , Gtk .Label .new (tab .name ))
430
446
self .tabs .append (tab )
431
447
432
448
def onCategoryChanged (self , tree ):
433
- self .kb_store .clear ()
449
+ self .kb_search_entry .handler_block (self .kb_search_handler_id )
450
+ self .kb_search_entry .set_text ("" )
451
+ self .kb_search_entry .handler_unblock (self .kb_search_handler_id )
452
+
434
453
if tree .get_selection () is not None :
435
454
categories , iter = tree .get_selection ().get_selected ()
436
455
if iter :
437
456
category = categories [iter ][2 ]
438
- if category .int_name != "custom" :
439
- for keybinding in category .keybindings :
440
- self .kb_store .append ((keybinding .label , keybinding ))
441
- else :
442
- self .loadCustoms ()
457
+ self .current_category = category
458
+ self .kb_store .refilter ()
459
+
443
460
self .remove_custom_button .set_property ('sensitive' , False )
444
461
445
- def loadCustoms (self ):
462
+ def on_kb_search_changed (self , entry , data = None ):
463
+ self .cat_tree .get_selection ().unselect_all ()
464
+ self .current_category = None
465
+ self .kb_store .refilter ()
466
+
467
+ def populate_kb_tree (self ):
468
+ self .kb_root_store .clear ()
469
+ self .current_category = None
470
+ self .kb_search_entry .handler_block (self .kb_search_handler_id )
471
+ self .kb_search_entry .set_text ("" )
472
+ self .kb_search_entry .handler_unblock (self .kb_search_handler_id )
473
+
446
474
for category in self .main_store :
447
- if category .int_name == "custom" :
448
- category .clear ()
475
+ for keybinding in category .keybindings :
476
+ self .kb_root_store .append ((keybinding .label , keybinding ))
477
+ self .loadCustoms ()
478
+
479
+ def kb_store_visible_func (self , model , iter , data = None ):
480
+ if self .current_category is None and self .kb_search_entry .get_text == "" :
481
+ print ("empty" )
482
+ return False
483
+
484
+ keybinding = self .kb_root_store .get_value (iter , 1 )
485
+
486
+ search = self .kb_search_entry .get_text ().lower ().strip ()
487
+ if search != "" :
488
+ return search in keybinding .label .lower ().strip ()
489
+
490
+ if self .current_category is not None :
491
+ return keybinding .category == self .current_category .int_name
492
+
493
+ def loadCustoms (self ):
494
+ iter = self .kb_root_store .get_iter_first ()
495
+
496
+ while iter :
497
+ # Removing a row moves the iter to the next row, which may also be
498
+ # custom, so we don't want to call iter_next() until we hit a row
499
+ # that isn't, otherwise we may skip one.
500
+ keybinding = self .kb_root_store .get_value (iter , 1 )
501
+ if keybinding .category == "custom" :
502
+ if not self .kb_root_store .remove (iter ):
503
+ break
504
+ continue
505
+
506
+ iter = self .kb_root_store .iter_next (iter )
449
507
450
508
parent = Gio .Settings .new (CUSTOM_KEYS_PARENT_SCHEMA )
451
509
custom_list = parent .get_strv ("custom-list" )
@@ -460,10 +518,7 @@ def loadCustoms(self):
460
518
schema .get_string ("name" ),
461
519
schema .get_string ("command" ),
462
520
schema .get_strv ("binding" ))
463
- self .kb_store .append ((custom_kb .label , custom_kb ))
464
- for category in self .main_store :
465
- if category .int_name == "custom" :
466
- category .add (custom_kb )
521
+ self .kb_root_store .append ((custom_kb .label , custom_kb ))
467
522
468
523
def onKeyBindingChanged (self , tree ):
469
524
self .entry_store .clear ()
@@ -477,7 +532,6 @@ def onKeyBindingChanged(self, tree):
477
532
self .remove_custom_button .set_property ('sensitive' , isinstance (keybinding , CustomKeyBinding ))
478
533
479
534
def onEntryChanged (self , cell , path , accel_string , accel_label , entry_store ):
480
- iter = entry_store .get_iter (path )
481
535
keybindings , kb_iter = self .kb_tree .get_selection ().get_selected ()
482
536
if kb_iter :
483
537
current_keybinding = keybindings [kb_iter ][1 ]
@@ -513,7 +567,6 @@ def onEntryChanged(self, cell, path, accel_string, accel_label, entry_store):
513
567
self .entry_tree .get_selection ().select_path (path )
514
568
515
569
def onEntryCleared (self , cell , path , entry_store ):
516
- iter = entry_store .get_iter (path )
517
570
keybindings , kb_iter = self .kb_tree .get_selection ().get_selected ()
518
571
if kb_iter :
519
572
current_keybinding = keybindings [kb_iter ][1 ]
@@ -557,6 +610,10 @@ def onAddCustomButtonClicked(self, button):
557
610
new_schema .set_string ("name" , dialog .name_entry .get_text ())
558
611
new_schema .set_string ("command" , dialog .command_entry .get_text ().replace ("%20" , "\ " ))
559
612
new_schema .set_strv ("binding" , ())
613
+
614
+ self .loadCustoms ()
615
+ self .kb_store .refilter ()
616
+
560
617
i = 0
561
618
for cat in self .cat_store :
562
619
if cat [2 ].int_name == "custom" :
@@ -596,13 +653,11 @@ def onRemoveCustomButtonClicked(self, button):
596
653
ensureCustomListIsValid (array )
597
654
parent_settings .set_strv ("custom-list" , array )
598
655
599
- i = 0
600
- for cat in self .cat_store :
601
- if cat [2 ].int_name == "custom" :
602
- self .cat_tree .set_cursor (str (i ), self .cat_tree .get_column (0 ), False )
603
- i += 1
656
+ self .loadCustoms ()
657
+ self .kb_store .refilter ()
604
658
605
659
def onCustomKeyBindingEdited (self , kb_treeview , column , kb_column ):
660
+ print ("what" )
606
661
keybindings , iter = kb_treeview .get_selection ().get_selected ()
607
662
if iter :
608
663
keybinding = keybindings [iter ][1 ]
@@ -622,11 +677,6 @@ def onCustomKeyBindingEdited(self, kb_treeview, column, kb_column):
622
677
keybinding .action = dialog .command_entry .get_text ().replace ("%20" , "\ " )
623
678
keybinding .writeSettings ()
624
679
625
- i = 0
626
- for cat in self .cat_store :
627
- if cat [2 ].int_name == "custom" :
628
- self .cat_tree .set_cursor (str (i ), self .cat_tree .get_column (0 ), False )
629
- i += 1
630
680
i = 0
631
681
for keybinding in self .kb_store :
632
682
if keybinding [0 ] == dialog .name_entry .get_text ():
@@ -685,6 +735,7 @@ def clear(self):
685
735
class KeyBinding ():
686
736
def __init__ (self , label , schema , key , category ):
687
737
self .key = key
738
+ self .category = category
688
739
self .label = label
689
740
self .entries = [ ]
690
741
self .settings = Gio .Settings .new (schema )
@@ -724,6 +775,7 @@ def resetDefaults(self):
724
775
725
776
class CustomKeyBinding ():
726
777
def __init__ (self , path , label , action , binding ):
778
+ self .category = "custom"
727
779
self .path = path
728
780
self .label = label
729
781
self .action = action
0 commit comments