/* * Xfce4 Messenger Plugin - DBus message notification plugin for Xfce4 Panel * Copyright (C) 2005-2006 Pasi Orovuo * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_STRING_H #include #endif #include #include #include #include #include #include "preferences-dialog.h" #define BORDER 8 #define MESSAGE_LABEL_MAX_DURATION 180 #define POPUP_WINDOW_MAX_DURATION 60 struct _MessengerPreferencesDialog { GtkDialog parent_instance; /* General */ GtkWidget *show_icon_checkbutton; GtkWidget *show_message_checkbutton; GtkWidget *label_width_spinner; GtkWidget *message_duration_spinner; GtkWidget *show_popup_checkbutton; GtkWidget *popup_duration_spinner; GtkWidget *save_history_checkbutton; GtkWidget *view_history_button; /* Icons */ GtkWidget *icon_treeview; GtkListStore *icon_store; GtkWidget *add_icon_button; GtkWidget *remove_icon_button; GtkWidget *icon_dialog; GtkWidget *icon_dialog_id_entry; GtkWidget *icon_dialog_src_entry; MessengerIconSet *icon_set; MessengerPreferences *preferences; }; struct _MessengerPreferencesDialogClass { GtkDialogClass parent_class; void (*view_history)( MessengerPreferencesDialog *dialog ); }; static void messenger_preferences_dialog_class_init( MessengerPreferencesDialogClass *klass ); static void messenger_preferences_dialog_init ( MessengerPreferencesDialog *self ); static void messenger_preferences_dialog_set_property ( GObject *object, guint property_id, const GValue *value, GParamSpec *pspec ); static void messenger_preferences_dialog_get_property ( GObject *object, guint property_id, GValue *value, GParamSpec *pspec ); static void messenger_preferences_dialog_finalize ( GObject *object ); static void messenger_preferences_dialog_set_preferences( MessengerPreferencesDialog *dialog, MessengerPreferences *preferences ); /* Callbacks */ static void show_icon_checkbutton_toggled_cb ( GtkWidget *widget, gpointer user_data ); static void show_message_checkbutton_toggled_cb ( GtkWidget *widget, gpointer user_data ); static void message_label_width_changed_cb ( GtkWidget *widget, gpointer user_data ); static void message_duration_changed_cb ( GtkWidget *widget, gpointer user_data ); static void show_popup_checkbutton_toggled_cb ( GtkWidget *widget, gpointer user_data ); static void popup_duration_changed_cb ( GtkWidget *widget, gpointer user_data ); static void save_history_checkbutton_toggled_cb ( GtkWidget *widget, gpointer user_data ); static void view_history_clicked_cb ( GtkWidget *widget, gpointer user_data ); static void icon_remove_clicked_cb ( GtkWidget *widget, gpointer user_data ); static void icon_add_clicked_cb ( GtkWidget *widget, gpointer user_data ); static void message_widgets_enable ( MessengerPreferencesDialog *dialog, gboolean show_icon, gboolean show_label ); static void popup_widgets_enable ( MessengerPreferencesDialog *dialog, gboolean enabled ); #if 0 static void icon_store_fill ( MessengerPreferencesDialog *dialog ); #endif enum { VIEW_HISTORY_CLICKED, N_SIGNALS }; enum { PROP_0, PROP_ICON_SET, PROP_PREFERENCES }; enum { ICONS_COL_PIXBUF, ICONS_COL_IDENTIFIER, ICONS_NUM_COLS }; static GObjectClass *messenger_preferences_dialog_parent_class = NULL; static guint messenger_preferences_dialog_signals[N_SIGNALS]; GType messenger_preferences_dialog_get_type( void ) { static GType messenger_preferences_dialog_gtype = 0; if ( !messenger_preferences_dialog_gtype ) { GTypeInfo type_info = { sizeof( MessengerPreferencesDialogClass ), NULL, NULL, (GClassInitFunc) messenger_preferences_dialog_class_init, NULL, NULL, sizeof( MessengerPreferencesDialog ), 0, (GInstanceInitFunc) messenger_preferences_dialog_init, NULL }; messenger_preferences_dialog_gtype = g_type_register_static( GTK_TYPE_DIALOG, "MessengerPreferencesDialog", &type_info, 0 ); } return ( messenger_preferences_dialog_gtype ); } static void messenger_preferences_dialog_class_init( MessengerPreferencesDialogClass *klass ) { GObjectClass *gobject_class = G_OBJECT_CLASS( klass ); messenger_preferences_dialog_parent_class = g_type_class_peek_parent( klass ); gobject_class->set_property = messenger_preferences_dialog_set_property; gobject_class->get_property = messenger_preferences_dialog_get_property; gobject_class->finalize = messenger_preferences_dialog_finalize; klass->view_history = NULL; g_object_class_install_property( gobject_class, PROP_ICON_SET, g_param_spec_object( "icon_set", "Icon Set", "Icon Set", MESSENGER_TYPE_ICON_SET, G_PARAM_READWRITE ) ); g_object_class_install_property( gobject_class, PROP_PREFERENCES, g_param_spec_object( "preferences", "Preferences", "Preferences", MESSENGER_TYPE_PREFERENCES, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY ) ); messenger_preferences_dialog_signals[VIEW_HISTORY_CLICKED] = g_signal_new( "view-history-clicked", MESSENGER_TYPE_PREFERENCES_DIALOG, G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET( MessengerPreferencesDialogClass, view_history ), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, NULL ); } static void messenger_preferences_dialog_init( MessengerPreferencesDialog *self ) { GtkWidget *notebook; GtkWidget *label; GtkWidget *dialog_vbox; GtkWidget *vbox, *hbox, *vbox2; GtkWidget *frame; GtkWidget *buttonbox; GtkWidget *alignment; GtkWidget *image; GtkWidget *scrolledwindow; GtkSizeGroup *sg; gtk_window_set_resizable( GTK_WINDOW( self ), FALSE ); dialog_vbox = GTK_DIALOG( self )->vbox; notebook = gtk_notebook_new(); gtk_widget_show( notebook ); gtk_box_pack_start( GTK_BOX( dialog_vbox ), notebook, TRUE, TRUE, 0 ); /* ======================= General tab ============================ */ vbox = gtk_vbox_new( FALSE, BORDER ); gtk_widget_show( vbox ); gtk_container_set_border_width( GTK_CONTAINER( vbox ), BORDER ); frame = gtk_frame_new( _( "Messages" ) ); gtk_widget_show( frame ); gtk_box_pack_start( GTK_BOX( vbox ), frame, TRUE, FALSE, 0 ); gtk_label_set_use_markup( GTK_LABEL( gtk_frame_get_label_widget( GTK_FRAME( frame ) ) ), TRUE ); gtk_frame_set_shadow_type( GTK_FRAME( frame ), GTK_SHADOW_NONE ); alignment = gtk_alignment_new( 0.50f, 0.50f, 1.0f, 1.0f ); gtk_widget_show( alignment ); gtk_alignment_set_padding( GTK_ALIGNMENT( alignment ), 0, 0, 12, 0 ); gtk_container_add( GTK_CONTAINER( frame ), alignment ); vbox2 = gtk_vbox_new( FALSE, 0 ); gtk_widget_show( vbox2 ); gtk_container_add( GTK_CONTAINER( alignment ), vbox2 ); hbox = gtk_hbox_new( FALSE, BORDER ); gtk_widget_show( hbox ); gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, TRUE, 0 ); self->show_icon_checkbutton = gtk_check_button_new_with_label( _( "Show icon in panel" ) ); gtk_widget_show( self->show_icon_checkbutton ); gtk_box_pack_start( GTK_BOX( hbox ), self->show_icon_checkbutton, TRUE, TRUE, 0 ); hbox = gtk_hbox_new( FALSE, BORDER ); gtk_widget_show( hbox ); gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, TRUE, 0 ); self->show_message_checkbutton = gtk_check_button_new_with_label( _( "Show message in panel" ) ); gtk_widget_show( self->show_message_checkbutton ); gtk_box_pack_start( GTK_BOX( hbox ), self->show_message_checkbutton, TRUE, TRUE, 0 ); alignment = gtk_alignment_new( 0.50f, 0.50f, 1.0f, 1.0f ); gtk_widget_show( alignment ); gtk_alignment_set_padding( GTK_ALIGNMENT( alignment ), 0, 0, 12, 0 ); gtk_box_pack_start( GTK_BOX( vbox2 ), alignment, TRUE, TRUE, 0 ); vbox2 = gtk_vbox_new( FALSE, BORDER ); gtk_widget_show( vbox2 ); gtk_container_add( GTK_CONTAINER( alignment ), vbox2 ); gtk_container_set_border_width( GTK_CONTAINER( vbox2 ), BORDER ); hbox = gtk_hbox_new( FALSE, BORDER ); gtk_widget_show( hbox ); gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, TRUE, 0 ); sg = gtk_size_group_new( GTK_SIZE_GROUP_BOTH ); label = gtk_label_new( _( "Label width:" ) ); gtk_widget_show( label ); gtk_box_pack_start( GTK_BOX( hbox ), label, FALSE, FALSE, 0 ); gtk_misc_set_alignment( GTK_MISC( label ), 0.0f, 0.5f ); gtk_size_group_add_widget( sg, label ); self->label_width_spinner = gtk_spin_button_new_with_range( (gdouble) PREF_MIN_LABEL_WIDTH, (gdouble) PREF_MAX_LABEL_WIDTH, 1.0f ); gtk_widget_show( self->label_width_spinner ); gtk_box_pack_start( GTK_BOX( hbox ), self->label_width_spinner, FALSE, FALSE, 0 ); hbox = gtk_hbox_new( FALSE, BORDER ); gtk_widget_show( hbox ); gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, TRUE, 0 ); label = gtk_label_new( _( "Default duration:" ) ); gtk_widget_show( label ); gtk_box_pack_start( GTK_BOX( hbox ), label, FALSE, FALSE, 0 ); gtk_misc_set_alignment( GTK_MISC( label ), 0.0f, 0.5f ); gtk_size_group_add_widget( sg, label ); self->message_duration_spinner = gtk_spin_button_new_with_range( 1.0f, (gdouble) MESSAGE_LABEL_MAX_DURATION, 1.0f ); gtk_widget_show( self->message_duration_spinner ); gtk_box_pack_start( GTK_BOX( hbox ), self->message_duration_spinner, FALSE, FALSE, 0 ); label = gtk_label_new( _( "second(s)" ) ); gtk_widget_show( label ); gtk_box_pack_start( GTK_BOX( hbox ), label, TRUE, TRUE, 0 ); gtk_misc_set_alignment( GTK_MISC( label ), 0.0f, 0.5f ); frame = gtk_frame_new( _( "Popup window" ) ); gtk_widget_show( frame ); gtk_box_pack_start( GTK_BOX( vbox ), frame, TRUE, FALSE, 0 ); gtk_label_set_use_markup( GTK_LABEL( gtk_frame_get_label_widget( GTK_FRAME( frame ) ) ), TRUE ); gtk_frame_set_shadow_type( GTK_FRAME( frame ), GTK_SHADOW_NONE ); alignment = gtk_alignment_new( 0.50f, 0.50f, 1.0f, 1.0f ); gtk_widget_show( alignment ); gtk_alignment_set_padding( GTK_ALIGNMENT( alignment ), 0, 0, 12, 0 ); gtk_container_add( GTK_CONTAINER( frame ), alignment ); vbox2 = gtk_vbox_new( FALSE, 0 ); gtk_widget_show( vbox2 ); gtk_container_add( GTK_CONTAINER( alignment ), vbox2 ); hbox = gtk_hbox_new( FALSE, 0 ); gtk_widget_show( hbox ); gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, TRUE, 0 ); self->show_popup_checkbutton = gtk_check_button_new_with_label( _( "Show message popup" ) ); gtk_widget_show( self->show_popup_checkbutton ); gtk_box_pack_start( GTK_BOX( hbox ), self->show_popup_checkbutton, TRUE, TRUE, 0 ); alignment = gtk_alignment_new( 0.5f, 0.5f, 1.0f, 1.0f ); gtk_widget_show( alignment ); gtk_alignment_set_padding( GTK_ALIGNMENT( alignment ), 0, 0, 12, 0 ); gtk_box_pack_start( GTK_BOX( vbox2 ), alignment, TRUE, TRUE, 0 ); vbox2 = gtk_vbox_new( FALSE, BORDER ); gtk_widget_show( vbox2 ); gtk_container_add( GTK_CONTAINER( alignment ), vbox2 ); gtk_container_set_border_width( GTK_CONTAINER( vbox2 ), BORDER ); hbox = gtk_hbox_new( FALSE, BORDER ); gtk_widget_show( hbox ); gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, TRUE, 0 ); label = gtk_label_new( _( "Duration:" ) ); gtk_widget_show( label ); gtk_box_pack_start( GTK_BOX( hbox ), label, FALSE, FALSE, 0 ); gtk_misc_set_alignment( GTK_MISC( label ), 0.0f, 0.5f ); gtk_size_group_add_widget( sg, label ); self->popup_duration_spinner = gtk_spin_button_new_with_range( 1.0f, (gdouble) POPUP_WINDOW_MAX_DURATION, 1.0f ); gtk_widget_show( self->popup_duration_spinner ); gtk_box_pack_start( GTK_BOX( hbox ), self->popup_duration_spinner, FALSE, FALSE, 0 ); label = gtk_label_new( _( "Second(s)" ) ); gtk_widget_show( label ); gtk_box_pack_start( GTK_BOX( hbox ), label, FALSE, FALSE, 0 ); frame = gtk_frame_new( _( "History" ) ); gtk_widget_show( frame ); gtk_box_pack_start( GTK_BOX( vbox ), frame, TRUE, FALSE, 0 ); gtk_label_set_use_markup( GTK_LABEL( gtk_frame_get_label_widget( GTK_FRAME( frame ) ) ), TRUE ); gtk_frame_set_shadow_type( GTK_FRAME( frame ), GTK_SHADOW_NONE ); alignment = gtk_alignment_new( 0.50f, 0.50f, 1.0f, 1.0f ); gtk_widget_show( alignment ); gtk_alignment_set_padding( GTK_ALIGNMENT( alignment ), 0, 0, 12, 0 ); gtk_container_add( GTK_CONTAINER( frame ), alignment ); vbox2 = gtk_vbox_new( FALSE, 0 ); gtk_widget_show( vbox2 ); gtk_container_add( GTK_CONTAINER( alignment ), vbox2 ); hbox = gtk_hbox_new( FALSE, 0 ); gtk_widget_show( hbox ); gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, TRUE, 0 ); self->save_history_checkbutton = gtk_check_button_new_with_label( _( "Save history on exit" ) ); gtk_widget_show( self->save_history_checkbutton ); gtk_box_pack_start( GTK_BOX( hbox ), self->save_history_checkbutton, TRUE, TRUE, 0 ); hbox = gtk_hbox_new( FALSE, BORDER ); gtk_widget_show( hbox ); gtk_box_pack_start( GTK_BOX( vbox2 ), hbox, TRUE, TRUE, 0 ); image = gtk_image_new_from_stock( GTK_STOCK_FIND, GTK_ICON_SIZE_BUTTON ); gtk_widget_show( image ); self->view_history_button = gtk_button_new_with_label( _( "View history..." ) ); gtk_widget_show( self->view_history_button ); /* Gtk+ 2.6 only */ gtk_button_set_image( GTK_BUTTON( self->view_history_button ), image ); gtk_box_pack_end( GTK_BOX( hbox ), self->view_history_button, FALSE, FALSE, 0 ); label = gtk_label_new( _( "General" ) ); gtk_widget_show( label ); gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), vbox, label ); /* ======================= Icons tab ============================ */ vbox = gtk_vbox_new( FALSE, BORDER ); gtk_widget_show( vbox ); gtk_container_set_border_width( GTK_CONTAINER( vbox ), BORDER ); hbox = gtk_hbox_new( FALSE, BORDER ); gtk_widget_show( hbox ); gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, TRUE, 0 ); gtk_container_set_border_width( GTK_CONTAINER( hbox ), BORDER ); image = gtk_image_new_from_stock( GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_BUTTON ); gtk_widget_show( image ); gtk_box_pack_start( GTK_BOX( hbox ), image, FALSE, FALSE, 0 ); label = gtk_label_new( _( "Icon associated with an identifier will " "appear with each message prefixed with the " "particular identifier" ) ); gtk_widget_show( label ); gtk_box_pack_start( GTK_BOX( hbox ), label, TRUE, TRUE, 0 ); gtk_label_set_line_wrap( GTK_LABEL( label ), TRUE ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); hbox = gtk_hbox_new( FALSE, 0 ); gtk_widget_show( hbox ); gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, TRUE, 0 ); hbox = gtk_hbox_new( FALSE, 0 ); gtk_widget_show( hbox ); gtk_box_pack_start( GTK_BOX( vbox ), hbox, TRUE, TRUE, 0 ); scrolledwindow = gtk_scrolled_window_new( NULL, NULL ); gtk_widget_show( scrolledwindow ); gtk_box_pack_start( GTK_BOX( hbox ), scrolledwindow, TRUE, TRUE, 0 ); gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolledwindow ), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS ); gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scrolledwindow ), GTK_SHADOW_IN ); self->icon_store = gtk_list_store_new( ICONS_NUM_COLS, GDK_TYPE_PIXBUF, G_TYPE_STRING ); self->icon_treeview = gtk_tree_view_new_with_model( GTK_TREE_MODEL( self->icon_store ) ); g_object_unref( self->icon_store ); gtk_widget_show( self->icon_treeview ); gtk_container_add( GTK_CONTAINER( scrolledwindow ), self->icon_treeview ); gtk_tree_view_insert_column_with_attributes( GTK_TREE_VIEW( self->icon_treeview ), -1, _( "Icon" ), gtk_cell_renderer_pixbuf_new(), "pixbuf", ICONS_COL_PIXBUF, NULL ); gtk_tree_view_insert_column_with_attributes( GTK_TREE_VIEW( self->icon_treeview ), -1, _( "Identifier" ), gtk_cell_renderer_text_new(), "text", ICONS_COL_IDENTIFIER, NULL ); gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( self->icon_treeview ), TRUE ); buttonbox = gtk_hbutton_box_new(); gtk_widget_show( buttonbox ); gtk_box_pack_start( GTK_BOX( vbox ), buttonbox, FALSE, TRUE, 0 ); gtk_button_box_set_layout( GTK_BUTTON_BOX( buttonbox ), GTK_BUTTONBOX_END ); gtk_box_set_spacing( GTK_BOX( buttonbox ), BORDER ); self->remove_icon_button = gtk_button_new_from_stock( GTK_STOCK_REMOVE ); gtk_widget_show( self->remove_icon_button ); gtk_container_add( GTK_CONTAINER( buttonbox ), self->remove_icon_button ); self->add_icon_button = gtk_button_new_from_stock( GTK_STOCK_ADD ); gtk_widget_show( self->add_icon_button ); gtk_container_add( GTK_CONTAINER( buttonbox ), self->add_icon_button ); label = gtk_label_new( _( "Icons" ) ); gtk_widget_show( label ); gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), vbox, label ); g_signal_connect( G_OBJECT( self->show_icon_checkbutton ), "toggled", G_CALLBACK( show_icon_checkbutton_toggled_cb ), self ); g_signal_connect( G_OBJECT( self->show_message_checkbutton ), "toggled", G_CALLBACK( show_message_checkbutton_toggled_cb ), self ); g_signal_connect( G_OBJECT( self->label_width_spinner ), "value-changed", G_CALLBACK( message_label_width_changed_cb ), self ); g_signal_connect( G_OBJECT( self->message_duration_spinner ), "value-changed", G_CALLBACK( message_duration_changed_cb ), self ); g_signal_connect( G_OBJECT( self->show_popup_checkbutton ), "toggled", G_CALLBACK( show_popup_checkbutton_toggled_cb ), self ); g_signal_connect( G_OBJECT( self->popup_duration_spinner ), "value-changed", G_CALLBACK( popup_duration_changed_cb ), self ); g_signal_connect( G_OBJECT( self->save_history_checkbutton ), "toggled", G_CALLBACK( save_history_checkbutton_toggled_cb ), self ); g_signal_connect( G_OBJECT( self->view_history_button ), "clicked", G_CALLBACK( view_history_clicked_cb ), self ); g_signal_connect( G_OBJECT( self->remove_icon_button ), "clicked", G_CALLBACK( icon_remove_clicked_cb ), self ); g_signal_connect( G_OBJECT( self->add_icon_button ), "clicked", G_CALLBACK( icon_add_clicked_cb ), self ); } static void messenger_preferences_dialog_set_preferences( MessengerPreferencesDialog *self, MessengerPreferences *preferences ) { gboolean show_icon, show_label, show_popup, save_history; guint label_width, message_duration, popup_duration; g_return_if_fail( MESSENGER_IS_PREFERENCES( preferences ) ); if ( self->preferences ) { g_object_unref( G_OBJECT( self->preferences ) ); } self->preferences = g_object_ref( G_OBJECT( preferences ) ); g_object_get( G_OBJECT( preferences ), "show-icon", &show_icon, "show-label", &show_label, "show-popup", &show_popup, "label-width", &label_width, "message-duration", &message_duration, "popup-duration", &popup_duration, "save-history", &save_history, NULL ); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( self->show_icon_checkbutton ), show_icon ); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( self->show_message_checkbutton ), show_label ); gtk_spin_button_set_value( GTK_SPIN_BUTTON( self->label_width_spinner ), (gdouble) label_width ); gtk_spin_button_set_value( GTK_SPIN_BUTTON( self->message_duration_spinner ), (gdouble) message_duration ); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( self->show_popup_checkbutton ), show_popup ); gtk_spin_button_set_value( GTK_SPIN_BUTTON( self->popup_duration_spinner ), (gdouble) popup_duration ); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( self->save_history_checkbutton ), save_history ); message_widgets_enable( self, show_icon, show_label ); popup_widgets_enable( self, show_popup ); } static void messenger_preferences_dialog_finalize( GObject *object ) { MessengerPreferencesDialog *dialog = MESSENGER_PREFERENCES_DIALOG( object ); if ( dialog->icon_set ) { g_object_unref( G_OBJECT( dialog->icon_set ) ); } g_object_unref( G_OBJECT( dialog->preferences ) ); G_OBJECT_CLASS( messenger_preferences_dialog_parent_class )->finalize( object ); } static void messenger_preferences_dialog_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *pspec ) { MessengerPreferencesDialog *dialog = MESSENGER_PREFERENCES_DIALOG( object ); switch ( property_id ) { case PROP_ICON_SET: messenger_preferences_dialog_set_icon_set( dialog, g_value_get_object( value ) ); break; case PROP_PREFERENCES: messenger_preferences_dialog_set_preferences( dialog, g_value_get_object( value ) ); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID( dialog, property_id, pspec ); break; } } static void messenger_preferences_dialog_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *pspec ) { MessengerPreferencesDialog *dialog = MESSENGER_PREFERENCES_DIALOG( object ); switch ( property_id ) { case PROP_ICON_SET: g_value_set_object( value, dialog->icon_set ); break; case PROP_PREFERENCES: g_value_set_object( value, dialog->preferences ); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID( dialog, property_id, pspec ); break; } } static void icon_list_add_icon( MessengerPreferencesDialog *dialog, const gchar *identifier, GdkPixbuf *pixbuf ) { GtkTreeIter iter; g_return_if_fail( identifier != NULL ); gtk_list_store_append( dialog->icon_store, &iter ); if ( pixbuf ) { gtk_list_store_set( dialog->icon_store, &iter, ICONS_COL_PIXBUF, pixbuf, ICONS_COL_IDENTIFIER, identifier, -1 ); } else { gtk_list_store_set( dialog->icon_store, &iter, ICONS_COL_IDENTIFIER, identifier, -1 ); } } static void message_widgets_enable( MessengerPreferencesDialog *dialog, gboolean show_icon, gboolean show_label ) { gtk_widget_set_sensitive( dialog->label_width_spinner, show_label ); if ( !show_icon && !show_label ) { gtk_widget_set_sensitive( dialog->message_duration_spinner, FALSE ); } else { gtk_widget_set_sensitive( dialog->message_duration_spinner, TRUE ); } } static void show_icon_checkbutton_toggled_cb( GtkWidget *widget, gpointer user_data ) { MessengerPreferencesDialog *dialog; gboolean active; gboolean show_label; dialog = MESSENGER_PREFERENCES_DIALOG( user_data ); active = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ); show_label = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dialog->show_message_checkbutton ) ); message_widgets_enable( dialog, active, show_label ); g_object_set( G_OBJECT( dialog->preferences ), "show-icon", active, NULL ); } static void show_message_checkbutton_toggled_cb( GtkWidget *widget, gpointer user_data ) { MessengerPreferencesDialog *dialog; gboolean show_icon; gboolean active; dialog = MESSENGER_PREFERENCES_DIALOG( user_data ); show_icon = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dialog->show_icon_checkbutton ) ); active = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ); message_widgets_enable( user_data, show_icon, active ); g_object_set( G_OBJECT( dialog->preferences ), "show-label", active, NULL ); } static void message_label_width_changed_cb( GtkWidget *widget, gpointer user_data ) { g_object_set( G_OBJECT( MESSENGER_PREFERENCES_DIALOG( user_data )->preferences ), "label-width", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( widget ) ), NULL ); } static void message_duration_changed_cb( GtkWidget *widget, gpointer user_data ) { g_object_set( G_OBJECT( MESSENGER_PREFERENCES_DIALOG( user_data )->preferences ), "message-duration", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( widget ) ), NULL ); } static void popup_widgets_enable( MessengerPreferencesDialog *dialog, gboolean enabled ) { gtk_widget_set_sensitive( dialog->popup_duration_spinner, enabled ); } static void popup_duration_changed_cb( GtkWidget *widget, gpointer user_data ) { g_object_set( G_OBJECT( MESSENGER_PREFERENCES_DIALOG( user_data )->preferences ), "popup-duration", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( widget ) ), NULL ); } static void show_popup_checkbutton_toggled_cb( GtkWidget *widget, gpointer user_data ) { gboolean active = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ); popup_widgets_enable( user_data, active ); g_object_set( G_OBJECT( MESSENGER_PREFERENCES_DIALOG( user_data )->preferences ), "show-popup", active, NULL ); } static void save_history_checkbutton_toggled_cb( GtkWidget *widget, gpointer user_data ) { MessengerPreferencesDialog *dialog = user_data; gboolean active = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ); g_object_set( G_OBJECT( dialog->preferences ), "save-history", active, NULL ); } static void icon_list_foreach_with_icon_cb( const gchar *identifier, const gchar *source, gpointer user_data ) { MessengerPreferencesDialog *dialog = user_data; GdkPixbuf *pixbuf; pixbuf = gtk_widget_render_icon( dialog->icon_treeview, identifier, GTK_ICON_SIZE_MENU, NULL ); icon_list_add_icon( dialog, identifier, pixbuf ); g_object_unref( G_OBJECT( pixbuf ) ); } #if 0 static void icon_store_fill( MessengerPreferencesDialog *dialog ) { gtk_list_store_clear( dialog->icon_store ); messenger_icon_set_foreach( dialog->icon_set, icon_list_foreach_with_icon_cb, dialog ); } #endif static gboolean icon_list_has_identifier( MessengerPreferencesDialog *dialog, const gchar *id ) { GtkTreeIter iter; gboolean iter_valid; gboolean has_id = FALSE; if ( messenger_icon_set_has_icon( dialog->icon_set, id ) ) { gint response; response = xfce_message_dialog( GTK_WINDOW( gtk_widget_get_toplevel( dialog->icon_treeview ) ), _( "Replace icon?" ), GTK_STOCK_DIALOG_QUESTION, _( "Replace existing identifier?" ), _( "The list already contains an " "icon for given identifier. Do " "you wish to replace it?" ), GTK_STOCK_NO, GTK_RESPONSE_NO, GTK_STOCK_YES, GTK_RESPONSE_YES, NULL ); if ( response == GTK_RESPONSE_YES ) { iter_valid = gtk_tree_model_get_iter_first( GTK_TREE_MODEL( dialog->icon_store ), &iter ); while ( iter_valid ) { gchar *cur_id; gtk_tree_model_get( GTK_TREE_MODEL( dialog->icon_store ), &iter, ICONS_COL_IDENTIFIER, &cur_id, -1 ); if ( !strcmp( cur_id, id ) ) { gtk_list_store_remove( dialog->icon_store, &iter ); g_free( cur_id ); break; } g_free( cur_id ); iter_valid = gtk_tree_model_iter_next( GTK_TREE_MODEL( dialog->icon_store ), &iter ); } } else { has_id = TRUE; } } return ( has_id ); } static gchar * icon_id_dialog_file_chooser_show( GtkWidget *parent_window ) { gchar *fn = NULL; GtkWidget *chooser; static gchar *file_chooser_dir = NULL; gint response; /* FIXME * file_chooser_dir is being leaked */ chooser = gtk_file_chooser_dialog_new( NULL, GTK_WINDOW( parent_window ), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); if ( file_chooser_dir ) { gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( chooser ), file_chooser_dir ); } response = gtk_dialog_run( GTK_DIALOG( chooser ) ); if ( response == GTK_RESPONSE_OK ) { fn = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( chooser ) ); if ( fn ) { if ( !g_utf8_validate( fn, -1, NULL ) ) { gchar *tmp; tmp = g_filename_to_utf8( fn, -1, NULL, NULL, NULL ); g_free( fn ); fn = tmp; } if ( file_chooser_dir ) { g_free( file_chooser_dir ); } file_chooser_dir = gtk_file_chooser_get_current_folder( GTK_FILE_CHOOSER( chooser ) ); } } gtk_widget_destroy( chooser ); return ( fn ); } static void icon_id_dialog_choose_file_clicked_cb( GtkWidget *widget, gpointer user_data ) { MessengerPreferencesDialog *dialog = user_data; gchar *fn; if ( ( fn = icon_id_dialog_file_chooser_show( dialog->icon_dialog ) ) ) { gtk_entry_set_text( GTK_ENTRY( dialog->icon_dialog_src_entry ), fn ); g_free( fn ); } } static gboolean icon_id_dialog_show( MessengerPreferencesDialog *dialog, const gchar *identifier_in, const gchar *source_in, gchar **identifier_out, gchar **source_out, GdkPixbuf **pixbuf_out ) { GtkWidget *vbox, *hbox; GtkWidget *label, *status; GtkWidget *id_entry, *src_entry; GtkWidget *button, *image; GtkSizeGroup *sg; gboolean edit_mode = ( identifier_in != NULL && source_in != NULL ); gboolean retval = FALSE; g_return_val_if_fail( identifier_out != NULL && source_out != NULL && pixbuf_out != NULL, FALSE ); dialog->icon_dialog = gtk_dialog_new_with_buttons( edit_mode ? _( "Edit existing identifier" ) : _( "Add new icon for identifier" ), GTK_WINDOW( dialog ), GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL ); gtk_window_set_resizable( GTK_WINDOW( dialog->icon_dialog ), FALSE ); gtk_dialog_set_default_response( GTK_DIALOG( dialog->icon_dialog ), GTK_RESPONSE_OK ); vbox = gtk_vbox_new( FALSE, BORDER ); gtk_widget_show( vbox ); gtk_container_set_border_width( GTK_CONTAINER( vbox ), BORDER ); gtk_box_pack_start( GTK_BOX( GTK_DIALOG( dialog->icon_dialog )->vbox ), vbox, TRUE, TRUE, 0 ); hbox = gtk_hbox_new( FALSE, BORDER ); gtk_widget_show( hbox ); gtk_box_pack_start( GTK_BOX( vbox ), hbox, TRUE, TRUE, BORDER ); sg = gtk_size_group_new( GTK_SIZE_GROUP_HORIZONTAL ); label = gtk_label_new( _( "Identifier:" ) ); gtk_misc_set_alignment( GTK_MISC( label ), 0.0f, 0.5f ); gtk_widget_show( label ); gtk_box_pack_start( GTK_BOX( hbox ), label, FALSE, FALSE, 0 ); gtk_size_group_add_widget( GTK_SIZE_GROUP( sg ), label ); dialog->icon_dialog_id_entry = id_entry = gtk_entry_new(); gtk_widget_show( id_entry ); gtk_box_pack_start( GTK_BOX( hbox ), id_entry, TRUE, TRUE, 0 ); if ( identifier_in ) { gtk_entry_set_text( GTK_ENTRY( id_entry ), identifier_in ); } if ( edit_mode ) { gtk_widget_set_sensitive( id_entry, FALSE ); } hbox = gtk_hbox_new( FALSE, BORDER ); gtk_widget_show( hbox ); gtk_box_pack_start( GTK_BOX( vbox ), hbox, TRUE, TRUE, BORDER ); label = gtk_label_new( _( "Source:" ) ); gtk_misc_set_alignment( GTK_MISC( label ), 0.0f, 0.5f ); gtk_widget_show( label ); gtk_box_pack_start( GTK_BOX( hbox ), label, FALSE, FALSE, 0 ); gtk_size_group_add_widget( GTK_SIZE_GROUP( sg ), label ); dialog->icon_dialog_src_entry = src_entry = gtk_entry_new(); gtk_widget_show( src_entry ); gtk_box_pack_start( GTK_BOX( hbox ), src_entry, TRUE, TRUE, 0 ); if ( source_in ) { gtk_entry_set_text( GTK_ENTRY( src_entry ), source_in ); } image = gtk_image_new_from_stock( GTK_STOCK_OPEN, GTK_ICON_SIZE_BUTTON ); gtk_widget_show( image ); button = gtk_button_new(); gtk_widget_show( button ); gtk_container_add( GTK_CONTAINER( button ), image ); gtk_box_pack_start( GTK_BOX( hbox ), button, FALSE, FALSE, 0 ); g_signal_connect( button, "clicked", G_CALLBACK( icon_id_dialog_choose_file_clicked_cb ), dialog ); hbox = gtk_hbox_new( FALSE, BORDER ); gtk_widget_show( hbox ); gtk_box_pack_start( GTK_BOX( vbox ), hbox, TRUE, TRUE, BORDER ); status = gtk_label_new( "" ); gtk_label_set_line_wrap( GTK_LABEL( status ), TRUE ); gtk_misc_set_alignment( GTK_MISC( status ), 0.0f, 0.5f ); gtk_widget_show( status ); gtk_box_pack_start( GTK_BOX( hbox ), status, TRUE, TRUE, 0 ); while ( TRUE ) { gint result = gtk_dialog_run( GTK_DIALOG( dialog->icon_dialog ) ); switch ( result ) { case GTK_RESPONSE_OK: { const gchar *identifier, *source; GdkPixbuf *pixbuf; identifier = gtk_entry_get_text( GTK_ENTRY( id_entry ) ); if ( !identifier || !*identifier ) { gtk_label_set_text( GTK_LABEL( status ), _( "Identifier is required" ) ); continue; } else { if ( !messenger_icon_set_identifier_is_valid( identifier ) ) { gtk_label_set_text( GTK_LABEL( status ), _( "An identifier may only contain " "alphanumeric characters" ) ); continue; } if ( icon_list_has_identifier( dialog, identifier ) ) { continue; } } source = gtk_entry_get_text( GTK_ENTRY( src_entry ) ); if ( !source || !*source ) { gtk_label_set_text( GTK_LABEL( status ), _( "Source is required" ) ); continue; } messenger_icon_set_add_icon( dialog->icon_set, identifier, source ); pixbuf = gtk_widget_render_icon( dialog->icon_treeview, identifier, GTK_ICON_SIZE_MENU, NULL ); if ( G_UNLIKELY( pixbuf == NULL ) ) { messenger_icon_set_remove_icon( dialog->icon_set, identifier ); gtk_label_set_text( GTK_LABEL( status ), _( "Failed to load image" ) ); continue; } *identifier_out = g_strdup( identifier ); *source_out = g_strdup( source ); *pixbuf_out = pixbuf; retval = TRUE; goto out; } break; case GTK_RESPONSE_CANCEL: default: goto out; break; } } out: gtk_widget_destroy( dialog->icon_dialog ); dialog->icon_dialog = NULL; return ( retval ); } static void icon_remove_clicked_cb( GtkWidget *widget, gpointer user_data ) { MessengerPreferencesDialog *dialog = user_data; GtkTreeSelection *selection; GtkTreeIter iter; selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( dialog->icon_treeview ) ); if ( gtk_tree_selection_get_selected( selection, NULL, &iter ) ) { gchar *identifier; gtk_tree_model_get( GTK_TREE_MODEL( dialog->icon_store ), &iter, ICONS_COL_IDENTIFIER, &identifier, -1 ); messenger_icon_set_remove_icon( dialog->icon_set, identifier ); gtk_list_store_remove( dialog->icon_store, &iter ); g_free( identifier ); } } static void icon_add_clicked_cb( GtkWidget *widget, gpointer user_data ) { MessengerPreferencesDialog *dialog = user_data; gchar *identifier = NULL, *source = NULL; GdkPixbuf *pb = NULL; if ( icon_id_dialog_show( dialog, NULL, NULL, &identifier, &source, &pb ) ) { icon_list_add_icon( dialog, identifier, pb ); g_free( identifier ); g_free( source ); g_object_unref( G_OBJECT( pb ) ); } } static void view_history_clicked_cb( GtkWidget *widget, gpointer user_data ) { MessengerPreferencesDialog *dialog = user_data; g_signal_emit( dialog, messenger_preferences_dialog_signals[VIEW_HISTORY_CLICKED], 0, NULL ); } /* ==================== EL API PUBLICA =========================== */ void messenger_preferences_dialog_set_icon_set( MessengerPreferencesDialog *dialog, MessengerIconSet *icon_set ) { g_assert( MESSENGER_IS_PREFERENCES_DIALOG( dialog ) ); g_return_if_fail( MESSENGER_IS_ICON_SET( icon_set ) ); if ( dialog->icon_set ) { g_object_unref( icon_set ); gtk_list_store_clear( dialog->icon_store ); } dialog->icon_set = g_object_ref( G_OBJECT( icon_set ) ); messenger_icon_set_foreach( dialog->icon_set, icon_list_foreach_with_icon_cb, dialog ); } MessengerIconSet * messenger_preferences_dialog_get_icon_set( MessengerPreferencesDialog *dialog ) { return ( dialog->icon_set ); } GtkWidget * messenger_preferences_dialog_new( MessengerPreferences *prefs ) { MessengerPreferencesDialog *dialog; g_assert( MESSENGER_IS_PREFERENCES( prefs ) ); dialog = g_object_new( MESSENGER_TYPE_PREFERENCES_DIALOG, "has-separator", FALSE, "preferences", prefs, NULL ); gtk_dialog_add_buttons( GTK_DIALOG( dialog ), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL ); return ( GTK_WIDGET( dialog ) ); }