void fm_folder_model_file_deleted(FmFolderModel* model, FmFileInfo* file) { GSequenceIter *seq_it; /* not required for hidden files */ gboolean update_view; #if 0 /* If there is no file info, that means the dir itself was deleted. */ if( G_UNLIKELY(!file) ) { /* Clear the whole list */ GSequenceIter *items_it = g_sequence_get_begin_iter(model->items); path = gtk_tree_path_new_from_indices(0, -1); while( !g_sequence_iter_is_end(items_it) ) { gtk_tree_model_row_deleted(GTK_TREE_MODEL(model), path); file = (VFSFileInfo*)g_sequence_get(items_it); items_it = g_sequence_iter_next(it); vfs_file_info_unref(file); } for( l = model->items; l; l = model->items ) { gtk_tree_model_row_deleted(GTK_TREE_MODEL(model), path); file = (VFSFileInfo*)l->data; model->items = g_list_delete_link(model->items, l); vfs_file_info_unref(file); } g_sequence_remove_range( g_sequence_get_begin_iter(model->items), g_sequence_get_end_iter(model->items) ); gtk_tree_path_free(path); return; } #endif if( !model->show_hidden && fm_file_info_is_hidden(file) ) /* if this is a hidden file */ { update_view = FALSE; seq_it = g_sequence_get_begin_iter(model->hidden); } else { update_view = TRUE; seq_it = g_sequence_get_begin_iter(model->items); } while( !g_sequence_iter_is_end(seq_it) ) { FmFolderItem* item = (FmFolderItem*)g_sequence_get(seq_it); if( item->inf == file ) break; seq_it = g_sequence_iter_next(seq_it); } if( update_view ) { GtkTreePath* path = gtk_tree_path_new_from_indices(g_sequence_iter_get_position(seq_it), -1); gtk_tree_model_row_deleted(GTK_TREE_MODEL(model), path); gtk_tree_path_free(path); } model->iter_age++; g_sequence_remove(seq_it); }
static void _fm_folder_model_add_file(FmFolderModel* model, FmFileInfo* file) { if( !model->show_hidden && fm_file_info_is_hidden(file) ) g_sequence_append( model->hidden, fm_folder_item_new(file) ); else fm_folder_model_file_created(model, file); }
void fm_folder_model_set_show_hidden(FmFolderModel* model, gboolean show_hidden) { FmFolderItem* item; GList *l, *next; GSequenceIter *items_it; g_return_if_fail(model != NULL); if( model->show_hidden == show_hidden ) return; model->show_hidden = show_hidden; if( show_hidden ) /* add previously hidden items back to the list */ { GSequenceIter *hidden_it = g_sequence_get_begin_iter(model->hidden); while( !g_sequence_iter_is_end(hidden_it) ) { GtkTreeIter it; GSequenceIter *next_hidden_it; GSequenceIter *insert_item_it = g_sequence_search(model->items, g_sequence_get(hidden_it), fm_folder_model_compare, model); next_hidden_it = g_sequence_iter_next(hidden_it); item = (FmFolderItem*)g_sequence_get(hidden_it); it.stamp = model->stamp; it.user_data = hidden_it; g_sequence_move(hidden_it, insert_item_it); GtkTreePath *path = gtk_tree_path_new_from_indices(g_sequence_iter_get_position(hidden_it), -1); gtk_tree_model_row_inserted(GTK_TREE_MODEL(model), path, &it); gtk_tree_path_free(path); hidden_it = next_hidden_it; } } else /* move invisible items to hidden list */ { GSequenceIter *items_it = g_sequence_get_begin_iter(model->items); while( !g_sequence_iter_is_end(items_it) ) { GtkTreePath* tp; GSequenceIter *next_item_it = g_sequence_iter_next(items_it); item = (FmFolderItem*)g_sequence_get(items_it); if( fm_file_info_is_hidden(item->inf) ) { gint delete_pos = g_sequence_iter_get_position(items_it); g_sequence_move( items_it, g_sequence_get_begin_iter(model->hidden) ); tp = gtk_tree_path_new_from_indices(delete_pos, -1); /* tell everybody that we removed an item */ gtk_tree_model_row_deleted(GTK_TREE_MODEL(model), tp); gtk_tree_path_free(tp); } items_it = next_item_it; } } }
void fm_folder_model_file_changed(FmFolderModel* model, FmFileInfo* file) { FmFolderItem* item; GSequenceIter* items_it; GtkTreeIter it; GtkTreePath* path; if( !model->show_hidden && fm_file_info_is_hidden(file) ) return; items_it = g_sequence_get_begin_iter(model->items); /* FIXME: write a GCompareDataFunc for this */ while( !g_sequence_iter_is_end(items_it) ) { item = (FmFolderItem*)g_sequence_get(items_it); if( item->inf == file ) break; items_it = g_sequence_iter_next(items_it); } if( items_it == g_sequence_get_end_iter(model->items) ) return; /* update the icon */ if( item->icon ) { g_object_unref(item->icon); item->icon = NULL; } it.stamp = model->stamp; it.user_data = items_it; path = gtk_tree_path_new_from_indices(g_sequence_iter_get_position(items_it), -1); gtk_tree_model_row_changed(GTK_TREE_MODEL(model), path, &it); gtk_tree_path_free(path); }
static gpointer _dentry_ui_init(GtkBuilder *ui, gpointer uidata, FmFileInfoList *files) { GObject *widget; GtkWidget *new_widget; FmFilePropertiesDEntryData *data; GtkTable *table; GtkLabel *label; GError *err = NULL; FmFileInfo *fi; GFile *gf; gchar *txt; gsize length; const gchar * const *langs; gboolean tmp_bool; /* disable permissions tab and open_with in any case */ #define HIDE_WIDGET(x) widget = gtk_builder_get_object(ui, x); \ gtk_widget_hide(GTK_WIDGET(widget)) /* HIDE_WIDGET("permissions_tab"); TODO: made visibility of permissions_tab configurable */ table = GTK_TABLE(gtk_builder_get_object(ui, "general_table")); HIDE_WIDGET("open_with"); HIDE_WIDGET("open_with_label"); gtk_table_set_row_spacing(table, 5, 0); /* we will do the thing only for single file! */ if (fm_file_info_list_get_length(files) != 1) return NULL; fi = fm_file_info_list_peek_head(files); gf = fm_path_to_gfile(fm_file_info_get_path(fi)); if (!g_file_load_contents(gf, NULL, &txt, &length, NULL, NULL)) { g_warning("file properties dialog: cannot access desktop entry file"); g_object_unref(gf); return NULL; } data = g_slice_new(FmFilePropertiesDEntryData); data->changed = FALSE; data->file = gf; data->kf = g_key_file_new(); g_key_file_load_from_data(data->kf, txt, length, G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, NULL); g_free(txt); /* FIXME: handle errors, also do g_key_file_has_group() */ /* get locale name */ data->lang = NULL; langs = g_get_language_names(); if (strcmp(langs[0], "C") != 0) { /* remove encoding from locale name */ char *sep = strchr(langs[0], '.'); if (sep) data->lang = g_strndup(langs[0], sep - langs[0]); else data->lang = g_strdup(langs[0]); } /* enable events for icon */ widget = gtk_builder_get_object(ui, "icon_eventbox"); data->icon = gtk_builder_get_object(ui, "icon"); gtk_widget_set_can_focus(GTK_WIDGET(widget), TRUE); /* disable Name event handler in the widget */ widget = gtk_builder_get_object(ui, "name"); g_signal_handlers_block_matched(widget, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, uidata); g_signal_connect(widget, "changed", G_CALLBACK(_dentry_name_changed), data); data->name = GTK_ENTRY(widget); data->saved_name = g_strdup(gtk_entry_get_text(data->name)); /* FIXME: two lines below is temporary workaround on FIXME in widget */ gtk_widget_set_can_focus(GTK_WIDGET(widget), TRUE); gtk_editable_set_editable(GTK_EDITABLE(widget), TRUE); /* Name is set from "Name" by libfm already so don't touch it */ /* support 'hidden' option */ data->hidden = NULL; widget = gtk_builder_get_object(ui, "hidden"); if (widget && GTK_IS_TOGGLE_BUTTON(widget) && fm_file_info_is_native(fi)) { data->hidden = (GtkToggleButton*)widget; data->was_hidden = fm_file_info_is_hidden(fi); g_signal_connect(widget, "toggled", G_CALLBACK(_dentry_hidden_toggled), data); gtk_widget_set_can_focus(GTK_WIDGET(data->hidden), TRUE); /* set sensitive since it can be toggled for desktop entry */ gtk_widget_set_sensitive(GTK_WIDGET(widget), TRUE); gtk_widget_show(GTK_WIDGET(data->hidden)); } #undef HIDE_WIDGET /* FIXME: migrate to GtkGrid */ table = GTK_TABLE(gtk_table_new(8, 2, FALSE)); gtk_table_set_row_spacings(table, 4); gtk_table_set_col_spacings(table, 12); gtk_container_set_border_width(GTK_CONTAINER(table), 4); /* row 0: "Exec" GtkHBox: GtkEntry+GtkButton */ new_widget = gtk_label_new(NULL); label = GTK_LABEL(new_widget); gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0); gtk_label_set_markup_with_mnemonic(label, _("<b>Co_mmand:</b>")); gtk_table_attach(table, new_widget, 0, 1, 0, 1, GTK_FILL, 0, 0, 0); #if GTK_CHECK_VERSION(3, 2, 0) /* FIXME: migrate to GtkGrid */ widget = G_OBJECT(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6)); #else widget = G_OBJECT(gtk_hbox_new(FALSE, 6)); #endif new_widget = gtk_button_new_with_mnemonic(_("_Browse...")); gtk_box_pack_end(GTK_BOX(widget), new_widget, FALSE, FALSE, 0); g_signal_connect(new_widget, "clicked", G_CALLBACK(_dentry_browse_exec_event), data); new_widget = gtk_entry_new(); data->exec = GTK_ENTRY(new_widget); txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "Exec", NULL, NULL); if (txt) { gtk_entry_set_text(data->exec, txt); g_free(txt); } gtk_widget_set_tooltip_text(new_widget, _("Command to execute when the application icon is activated")); gtk_box_pack_start(GTK_BOX(widget), new_widget, TRUE, TRUE, 0); g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_exec_changed), data); gtk_table_attach(table, GTK_WIDGET(widget), 1, 2, 0, 1, GTK_FILL|GTK_EXPAND, 0, 0, 0); gtk_label_set_mnemonic_widget(label, new_widget); /* row 1: "Terminal" GtkCheckButton */ new_widget = gtk_check_button_new_with_mnemonic(_("_Execute in terminal emulator")); data->terminal = GTK_TOGGLE_BUTTON(new_widget); tmp_bool = g_key_file_get_boolean(data->kf, GRP_NAME, "Terminal", &err); if (err) /* no such key present */ { tmp_bool = FALSE; g_clear_error(&err); } gtk_toggle_button_set_active(data->terminal, tmp_bool); g_signal_connect(new_widget, "toggled", G_CALLBACK(_dentry_terminal_toggled), data); gtk_table_attach(table, new_widget, 0, 2, 1, 2, GTK_FILL, 0, 18, 0); /* row 2: "X-KeepTerminal" GtkCheckButton */ new_widget = gtk_check_button_new_with_mnemonic(_("_Keep terminal window open after command execution")); data->keep_open = GTK_TOGGLE_BUTTON(new_widget); gtk_widget_set_sensitive(new_widget, tmp_bool); /* disable if not in terminal */ tmp_bool = g_key_file_get_boolean(data->kf, GRP_NAME, "X-KeepTerminal", &err); if (err) /* no such key present */ { tmp_bool = FALSE; g_clear_error(&err); } gtk_toggle_button_set_active(data->keep_open, tmp_bool); g_signal_connect(new_widget, "toggled", G_CALLBACK(_dentry_keepterm_toggled), data); gtk_table_attach(table, new_widget, 0, 2, 2, 3, GTK_FILL, 0, 27, 0); /* row 4: "GenericName" GtkEntry */ new_widget = gtk_label_new(NULL); label = GTK_LABEL(new_widget); gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0); gtk_label_set_markup_with_mnemonic(label, _("<b>D_escription:</b>")); gtk_table_attach(table, new_widget, 0, 1, 4, 5, GTK_FILL, 0, 0, 0); new_widget = gtk_entry_new(); data->generic_name = GTK_ENTRY(new_widget); txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "GenericName", NULL, NULL); if (txt) { gtk_entry_set_text(data->generic_name, txt); g_free(txt); } gtk_widget_set_tooltip_text(new_widget, _("Generic name of the application")); g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_genname_changed), data); gtk_table_attach(table, new_widget, 1, 2, 4, 5, GTK_FILL|GTK_EXPAND, 0, 0, 0); gtk_label_set_mnemonic_widget(label, new_widget); /* row 3: "Path" GtkEntry */ new_widget = gtk_label_new(NULL); label = GTK_LABEL(new_widget); gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0); gtk_label_set_markup_with_mnemonic(label, _("<b>_Working directory:</b>")); gtk_table_attach(table, new_widget, 0, 1, 3, 4, GTK_FILL, 0, 0, 0); new_widget = gtk_entry_new(); data->path = GTK_ENTRY(new_widget); txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "Path", NULL, NULL); if (txt) { gtk_entry_set_text(data->path, txt); g_free(txt); } gtk_widget_set_tooltip_text(new_widget, _("The working directory to run the program in")); g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_path_changed), data); gtk_table_attach(table, new_widget, 1, 2, 3, 4, GTK_FILL|GTK_EXPAND, 0, 0, 0); gtk_label_set_mnemonic_widget(label, new_widget); /* row 5: "Comment" GtkEntry */ new_widget = gtk_label_new(NULL); label = GTK_LABEL(new_widget); gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0); gtk_label_set_markup_with_mnemonic(label, _("<b>_Tooltip:</b>")); gtk_table_attach(table, new_widget, 0, 1, 5, 6, GTK_FILL, 0, 0, 0); new_widget = gtk_entry_new(); data->comment = GTK_ENTRY(new_widget); txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "Comment", NULL, NULL); if (txt) { gtk_entry_set_text(data->comment, txt); g_free(txt); } gtk_widget_set_tooltip_text(new_widget, _("Tooltip to show on application")); g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_tooltip_changed), data); gtk_table_attach(table, new_widget, 1, 2, 5, 6, GTK_FILL|GTK_EXPAND, 0, 0, 0); gtk_label_set_mnemonic_widget(label, new_widget); /* TODO: handle "TryExec" field ? */ /* row 7: "StartupNotify" GtkCheckButton */ new_widget = gtk_check_button_new_with_mnemonic(_("_Use startup notification")); data->notification = GTK_TOGGLE_BUTTON(new_widget); tmp_bool = g_key_file_get_boolean(data->kf, GRP_NAME, "StartupNotify", &err); if (err) /* no such key present */ { tmp_bool = FALSE; g_clear_error(&err); } gtk_toggle_button_set_active(data->notification, tmp_bool); g_signal_connect(new_widget, "toggled", G_CALLBACK(_dentry_notification_toggled), data); gtk_table_attach(table, new_widget, 0, 2, 7, 8, GTK_FILL, 0, 0, 0); /* put the table into third tab and enable it */ widget = gtk_builder_get_object(ui, "extra_tab_label"); gtk_label_set_markup_with_mnemonic(GTK_LABEL(widget), _("_Desktop Entry")); widget = gtk_builder_get_object(ui, "extra_tab"); gtk_container_add(GTK_CONTAINER(widget), GTK_WIDGET(table)); gtk_widget_show_all(GTK_WIDGET(widget)); return data; }