@@ -60,8 +60,12 @@ typedef struct {
6060 GtkWidget * swin_view ;
6161 GtkWidget * swin_preview ;
6262 GtkWidget * icon_view ;
63+ GtkWidget * search_bar ;
64+ GtkWidget * entry ;
65+ GtkWidget * search_button ;
6366
6467 GtkTreeModel * model ;
68+ GtkTreeModel * filter_model ;
6569
6670 GFile * font_file ;
6771} FontViewApplication ;
@@ -497,6 +501,39 @@ info_button_clicked_cb (GtkButton *button,
497501 gtk_widget_show_all (dialog );
498502}
499503
504+ static gboolean
505+ font_visible_func (GtkTreeModel * model ,
506+ GtkTreeIter * iter ,
507+ gpointer data )
508+ {
509+ FontViewApplication * self = data ;
510+ gboolean ret ;
511+ const char * search ;
512+ char * name ;
513+ char * cf_name ;
514+ char * cf_search ;
515+
516+ if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self -> search_button )))
517+ return TRUE;
518+
519+ search = gtk_entry_get_text (GTK_ENTRY (self -> entry ));
520+
521+ gtk_tree_model_get (model , iter ,
522+ COLUMN_NAME , & name ,
523+ -1 );
524+
525+ cf_name = g_utf8_casefold (name , -1 );
526+ cf_search = g_utf8_casefold (search , -1 );
527+
528+ ret = strstr (cf_name , cf_search ) != NULL ;
529+
530+ g_free (name );
531+ g_free (cf_name );
532+ g_free (cf_search );
533+
534+ return ret ;
535+ }
536+
500537static void
501538font_view_ensure_model (FontViewApplication * self )
502539{
@@ -506,6 +543,9 @@ font_view_ensure_model (FontViewApplication *self)
506543 self -> model = font_view_model_new ();
507544 g_signal_connect (self -> model , "config-changed" ,
508545 G_CALLBACK (font_model_config_changed_cb ), self );
546+ self -> filter_model = gtk_tree_model_filter_new (self -> model , NULL );
547+ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (self -> filter_model ),
548+ font_visible_func , self , NULL );
509549}
510550
511551static void
@@ -579,6 +619,7 @@ icon_view_release_cb (GtkWidget *widget,
579619 FontViewApplication * self = user_data ;
580620 GtkTreePath * path ;
581621 GtkTreeIter iter ;
622+ GtkTreeIter filter_iter ;
582623 gchar * font_path ;
583624 gint face_index ;
584625 GFile * file ;
@@ -591,7 +632,10 @@ icon_view_release_cb (GtkWidget *widget,
591632 event -> x , event -> y );
592633
593634 if (path != NULL &&
594- gtk_tree_model_get_iter (self -> model , & iter , path )) {
635+ gtk_tree_model_get_iter (self -> filter_model , & filter_iter , path )) {
636+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (self -> filter_model ),
637+ & iter ,
638+ & filter_iter );
595639 gtk_tree_model_get (self -> model , & iter ,
596640 COLUMN_PATH , & font_path ,
597641 COLUMN_FACE_INDEX , & face_index ,
@@ -637,7 +681,7 @@ font_view_application_do_overview (FontViewApplication *self)
637681 GtkWidget * icon_view ;
638682 GtkCellRenderer * cell ;
639683
640- self -> icon_view = icon_view = gtk_icon_view_new_with_model (self -> model );
684+ self -> icon_view = icon_view = gtk_icon_view_new_with_model (self -> filter_model );
641685 g_object_set (icon_view ,
642686 "column-spacing" , VIEW_COLUMN_SPACING ,
643687 "margin" , VIEW_MARGIN ,
@@ -750,6 +794,13 @@ static GActionEntry action_entries[] = {
750794 { "quit" , action_quit , NULL , NULL , NULL }
751795};
752796
797+ static void
798+ search_text_changed (GtkEntry * entry ,
799+ FontViewApplication * self )
800+ {
801+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (self -> filter_model ));
802+ }
803+
753804static void
754805font_view_application_startup (GApplication * application )
755806{
@@ -786,6 +837,9 @@ font_view_application_startup (GApplication *application)
786837
787838 self -> toolbar = gd_main_toolbar_new ();
788839 gtk_style_context_add_class (gtk_widget_get_style_context (self -> toolbar ), "menubar" );
840+ self -> search_button = gd_main_toolbar_add_toggle (GD_MAIN_TOOLBAR (self -> toolbar ),
841+ NULL , _ ("Search" ),
842+ FALSE);
789843 gtk_container_add (GTK_CONTAINER (self -> main_grid ), self -> toolbar );
790844
791845 self -> notebook = gtk_notebook_new ();
@@ -806,6 +860,19 @@ font_view_application_startup (GApplication *application)
806860 GTK_POLICY_AUTOMATIC , GTK_POLICY_NEVER );
807861 gtk_container_add (GTK_CONTAINER (self -> notebook ), swin );
808862
863+ self -> search_bar = gtk_search_bar_new ();
864+ gtk_container_add (GTK_CONTAINER (self -> main_grid ), self -> search_bar );
865+
866+ self -> entry = gtk_search_entry_new ();
867+ gtk_entry_set_width_chars (GTK_ENTRY (self -> entry ), 40 );
868+ gtk_container_add (GTK_CONTAINER (self -> search_bar ), self -> entry );
869+
870+ g_object_bind_property (self -> search_bar , "search-mode-enabled" ,
871+ self -> search_button , "active" ,
872+ G_BINDING_BIDIRECTIONAL );
873+
874+ g_signal_connect (self -> entry , "search-changed" , G_CALLBACK (search_text_changed ), self );
875+
809876 gtk_widget_show_all (window );
810877}
811878
@@ -832,6 +899,7 @@ font_view_application_dispose (GObject *obj)
832899 FontViewApplication * self = FONT_VIEW_APPLICATION (obj );
833900
834901 g_clear_object (& self -> model );
902+ g_clear_object (& self -> filter_model );
835903
836904 G_OBJECT_CLASS (font_view_application_parent_class )-> dispose (obj );
837905}
0 commit comments