#include #define THUNAR_TYPE_FILENAME_INPUT thunar_filename_input_get_type () G_DECLARE_FINAL_TYPE (ThunarFilenameInput, thunar_filename_input, THUNAR, FILENAME_INPUT, GtkBox) struct _ThunarFilenameInput { GtkBox parent; GtkEntry *entry; GtkLabel *label; gint max_text_length; }; G_DEFINE_TYPE (ThunarFilenameInput, thunar_filename_input, GTK_TYPE_BOX) void thunar_filename_input_changed (GtkEditable *editable, gpointer user_data); const gchar* thunar_filename_input_get_text (ThunarFilenameInput *filename_input); static void thunar_filename_input_class_init (ThunarFilenameInputClass *klass) { GtkWidgetClass *gtkwidget_class; gtkwidget_class = GTK_WIDGET_CLASS (klass); g_signal_new ("text-valid", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0 /* closure */, NULL /* accumulator */, NULL /* accumulator data */, NULL /* C marshaller */, G_TYPE_NONE /* return_type */, 0 /* n_params */); g_signal_new ("text-invalid", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0 /* closure */, NULL /* accumulator */, NULL /* accumulator data */, NULL /* C marshaller */, G_TYPE_NONE /* return_type */, 0 /* n_params */); } static void thunar_filename_input_init (ThunarFilenameInput *filename_input) { gtk_orientable_set_orientation (GTK_ORIENTABLE(filename_input),GTK_ORIENTATION_VERTICAL); gtk_container_set_border_width (GTK_CONTAINER (filename_input), 2); filename_input->max_text_length = 10; filename_input->entry = GTK_ENTRY(gtk_entry_new()); gtk_widget_set_hexpand (GTK_WIDGET(filename_input->entry), TRUE); gtk_widget_set_valign (GTK_WIDGET(filename_input->entry), GTK_ALIGN_CENTER); gtk_box_pack_start (GTK_BOX (filename_input),GTK_WIDGET(filename_input->entry),FALSE,FALSE,0); filename_input->label = GTK_LABEL(gtk_label_new("")); gtk_label_set_xalign (filename_input->label, 0.0f); gtk_widget_set_hexpand (GTK_WIDGET(filename_input->label), TRUE); gtk_box_pack_start (GTK_BOX (filename_input),GTK_WIDGET(filename_input->label),FALSE,FALSE,0); g_signal_connect (filename_input->entry, "changed", G_CALLBACK (thunar_filename_input_changed), filename_input); g_signal_emit_by_name(filename_input->entry,"changed",0); } const gchar* thunar_filename_input_get_text (ThunarFilenameInput *filename_input){ return gtk_entry_get_text(filename_input->entry); } void thunar_filename_input_changed (GtkEditable *editable, gpointer user_data) { ThunarFilenameInput *filename_input = THUNAR_FILENAME_INPUT(user_data); GtkEntry *entry = GTK_ENTRY(editable); GtkLabel *label = filename_input->label; gint text_length; const gchar *text; const gchar *p; const gchar *label_text = ""; const gchar *icon_name = NULL; gchar *stripped_text; text_length = gtk_entry_get_text_length(entry); text = gtk_entry_get_text (entry); stripped_text = g_strdup(text); g_strstrip (stripped_text); if (text_length == 0){ gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, NULL); gtk_label_set_text (label,""); gtk_entry_set_activates_default (entry, FALSE); g_signal_emit_by_name(filename_input,"text-invalid",0); g_free(stripped_text); return; } if (g_strcmp0(text,stripped_text) != 0){ label_text = "Filenames should not start or end with a space"; icon_name = "dialog-warning"; } g_free(stripped_text); for (p = text; *p != '\0'; ++p) if (G_UNLIKELY (G_IS_DIR_SEPARATOR (*p))) break; if (*p != '\0'){ label_text = "Directory separator illegal in file name"; icon_name = "dialog-error"; } else if(text_length > filename_input->max_text_length){ label_text = "Filename is too long"; icon_name = "dialog-error"; } gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, icon_name); gtk_entry_set_activates_default (entry, g_strcmp0(icon_name,"dialog-error") != 0); gtk_label_set_text (label,label_text); if(g_strcmp0(icon_name,"dialog-error") != 0) g_signal_emit_by_name(filename_input,"text-valid",0); else g_signal_emit_by_name(filename_input,"text-invalid",0); } static void text_invalid( GtkWidget *widget, gpointer data ) { gtk_widget_set_sensitive(widget,FALSE); } static void text_valid( GtkWidget *widget, gpointer data ) { gtk_widget_set_sensitive(widget,TRUE); } int main(int argc, char *argv[]) { GtkWidget *dialog; gint response; ThunarFilenameInput *filename_input; const gchar *filename; gtk_init(&argc, &argv); dialog = gtk_dialog_new_with_buttons ("Enter file name", NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, "Cancel", GTK_RESPONSE_CANCEL, "Rename", GTK_RESPONSE_OK, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); gtk_window_set_default_size (GTK_WINDOW(dialog),250,-1); filename_input = g_object_new (THUNAR_TYPE_FILENAME_INPUT,NULL); gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),GTK_WIDGET(filename_input)); gtk_widget_show_all (GTK_WIDGET(filename_input)); g_signal_connect_swapped(filename_input,"text-invalid",G_CALLBACK(text_invalid), gtk_dialog_get_widget_for_response(GTK_DIALOG(dialog),GTK_RESPONSE_OK)); g_signal_connect_swapped(filename_input,"text-valid",G_CALLBACK(text_valid), gtk_dialog_get_widget_for_response(GTK_DIALOG(dialog),GTK_RESPONSE_OK)); response = gtk_dialog_run (GTK_DIALOG (dialog)); filename = thunar_filename_input_get_text(filename_input); if (response == GTK_RESPONSE_OK) g_message("Chosen filename: %s\n",filename); if (response == GTK_RESPONSE_CANCEL) g_message("Operation cancelled\n"); gtk_widget_destroy (dialog); return 0; }