464 lines
14 KiB
C
464 lines
14 KiB
C
/*
|
|
Copyright (C) 2007-2009 Christian Dywan <christian@twotoasts.de>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
See the file COPYING for the full license text.
|
|
*/
|
|
|
|
#include "katze-preferences.h"
|
|
|
|
#if HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_GRANITE
|
|
#if HAVE_OSX
|
|
#error FIXME granite on OSX is not implemented
|
|
#endif
|
|
#include <granite.h>
|
|
#endif
|
|
|
|
#if HAVE_HILDON
|
|
#include "katze-scrolled.h"
|
|
#include <hildon/hildon.h>
|
|
#endif
|
|
|
|
#include <string.h>
|
|
#include <glib/gi18n.h>
|
|
|
|
struct _KatzePreferencesPrivate
|
|
{
|
|
#if HAVE_HILDON
|
|
GtkWidget* scrolled;
|
|
GtkSizeGroup* sizegroup;
|
|
GtkSizeGroup* sizegroup2;
|
|
GtkWidget* box;
|
|
GtkWidget* hbox;
|
|
#else
|
|
GtkWidget* notebook;
|
|
GtkWidget* toolbar;
|
|
GtkWidget* toolbutton;
|
|
GtkSizeGroup* sizegroup;
|
|
GtkSizeGroup* sizegroup2;
|
|
GtkWidget* page;
|
|
GtkWidget* frame;
|
|
GtkWidget* box;
|
|
GtkWidget* hbox;
|
|
#endif
|
|
};
|
|
|
|
G_DEFINE_TYPE (KatzePreferences, katze_preferences, GTK_TYPE_DIALOG);
|
|
|
|
static void
|
|
katze_preferences_finalize (GObject* object);
|
|
|
|
static void
|
|
katze_preferences_class_init (KatzePreferencesClass* class)
|
|
{
|
|
GObjectClass* gobject_class = G_OBJECT_CLASS (class);
|
|
gobject_class->finalize = katze_preferences_finalize;
|
|
|
|
g_type_class_add_private (class, sizeof (KatzePreferencesPrivate));
|
|
}
|
|
|
|
static void
|
|
katze_preferences_response_cb (KatzePreferences* preferences,
|
|
gint response)
|
|
{
|
|
if (response == GTK_RESPONSE_CLOSE || response == GTK_RESPONSE_APPLY)
|
|
gtk_widget_destroy (GTK_WIDGET (preferences));
|
|
}
|
|
|
|
#ifdef HAVE_HILDON_2_2
|
|
static void
|
|
katze_preferences_size_request_cb (KatzePreferences* preferences,
|
|
GtkRequisition* requisition)
|
|
{
|
|
GdkScreen* screen = gtk_widget_get_screen (GTK_WIDGET (preferences));
|
|
if (gdk_screen_get_height (screen) > gdk_screen_get_width (screen))
|
|
gtk_widget_hide (gtk_dialog_get_action_area (GTK_DIALOG (preferences)));
|
|
else
|
|
gtk_widget_show (gtk_dialog_get_action_area (GTK_DIALOG (preferences)));
|
|
}
|
|
#endif
|
|
|
|
static void
|
|
katze_preferences_init (KatzePreferences* preferences)
|
|
{
|
|
KatzePreferencesPrivate* priv;
|
|
gchar* dialog_title;
|
|
|
|
preferences->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE ((preferences),
|
|
KATZE_TYPE_PREFERENCES, KatzePreferencesPrivate);
|
|
|
|
dialog_title = g_strdup_printf (_("Preferences for %s"),
|
|
g_get_application_name ());
|
|
g_object_set (preferences,
|
|
"icon-name", GTK_STOCK_PREFERENCES,
|
|
"title", dialog_title,
|
|
#if !GTK_CHECK_VERSION (3, 0, 0)
|
|
"has-separator", FALSE,
|
|
#endif
|
|
NULL);
|
|
g_free (dialog_title);
|
|
|
|
#if !HAVE_OSX
|
|
gtk_dialog_add_buttons (GTK_DIALOG (preferences),
|
|
GTK_STOCK_HELP, GTK_RESPONSE_HELP,
|
|
NULL);
|
|
#if GTK_CHECK_VERSION (3, 0, 0)
|
|
gtk_style_context_add_class (gtk_widget_get_style_context (
|
|
gtk_dialog_get_widget_for_response (GTK_DIALOG (preferences),
|
|
GTK_RESPONSE_HELP)), "help_button");
|
|
#endif
|
|
|
|
gtk_dialog_add_buttons (GTK_DIALOG (preferences),
|
|
#if HAVE_HILDON
|
|
GTK_STOCK_SAVE, GTK_RESPONSE_APPLY,
|
|
#else
|
|
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
|
|
#endif
|
|
NULL);
|
|
#endif
|
|
|
|
g_object_connect (preferences,
|
|
"signal::response", katze_preferences_response_cb, NULL,
|
|
NULL);
|
|
|
|
#ifdef HAVE_HILDON_2_2
|
|
katze_preferences_size_request_cb (preferences, NULL);
|
|
g_object_connect (preferences,
|
|
"signal::size-request", katze_preferences_size_request_cb, NULL,
|
|
NULL);
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
katze_preferences_finalize (GObject* object)
|
|
{
|
|
G_OBJECT_CLASS (katze_preferences_parent_class)->finalize (object);
|
|
}
|
|
|
|
/**
|
|
* katze_preferences_new:
|
|
* @parent: the parent window, or %NULL
|
|
*
|
|
* Creates a new preferences dialog.
|
|
*
|
|
* Return value: a new #KatzePreferences
|
|
*
|
|
* Since: 0.2.1
|
|
**/
|
|
GtkWidget*
|
|
katze_preferences_new (GtkWindow* parent)
|
|
{
|
|
KatzePreferences* preferences;
|
|
|
|
g_return_val_if_fail (!parent || GTK_IS_WINDOW (parent), NULL);
|
|
|
|
preferences = g_object_new (KATZE_TYPE_PREFERENCES,
|
|
"transient-for", parent,
|
|
NULL);
|
|
|
|
return GTK_WIDGET (preferences);
|
|
}
|
|
|
|
#if HAVE_OSX
|
|
static void
|
|
katze_preferences_help_clicked_cb (GtkWidget* button,
|
|
GtkDialog* dialog)
|
|
{
|
|
gtk_dialog_response (dialog, GTK_RESPONSE_HELP);
|
|
}
|
|
|
|
static void
|
|
katze_preferences_toolbutton_clicked_cb (GtkWidget* toolbutton,
|
|
GtkWidget* page)
|
|
{
|
|
gpointer notebook = g_object_get_data (G_OBJECT (toolbutton), "notebook");
|
|
guint n = gtk_notebook_page_num (notebook, page);
|
|
gtk_notebook_set_current_page (notebook, n);
|
|
}
|
|
#endif
|
|
|
|
static void
|
|
katze_preferences_prepare (KatzePreferences* preferences)
|
|
{
|
|
KatzePreferencesPrivate* priv = preferences->priv;
|
|
|
|
#if HAVE_HILDON
|
|
GtkWidget* viewport;
|
|
|
|
priv->scrolled = katze_scrolled_new (NULL, NULL);
|
|
gtk_box_pack_end (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (preferences))),
|
|
priv->scrolled, TRUE, TRUE, 4);
|
|
viewport = gtk_viewport_new (NULL, NULL);
|
|
gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport), GTK_SHADOW_NONE);
|
|
gtk_container_add (GTK_CONTAINER (priv->scrolled), viewport);
|
|
priv->box = gtk_vbox_new (FALSE, 0);
|
|
gtk_container_add (GTK_CONTAINER (viewport), priv->box);
|
|
|
|
priv->hbox = NULL;
|
|
priv->sizegroup = NULL;
|
|
priv->sizegroup2 = NULL;
|
|
|
|
g_signal_connect (priv->scrolled, "destroy",
|
|
G_CALLBACK (gtk_widget_destroyed), &priv->scrolled);
|
|
#else
|
|
#if HAVE_GRANITE
|
|
priv->notebook = g_object_new (GRANITE_WIDGETS_TYPE_STATIC_NOTEBOOK, NULL);
|
|
#else
|
|
priv->notebook = gtk_notebook_new ();
|
|
#endif
|
|
gtk_container_set_border_width (GTK_CONTAINER (priv->notebook), 6);
|
|
|
|
#if HAVE_OSX
|
|
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
|
|
gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
|
|
priv->toolbar = gtk_toolbar_new ();
|
|
gtk_toolbar_set_style (GTK_TOOLBAR (priv->toolbar), GTK_TOOLBAR_BOTH);
|
|
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (priv->toolbar), FALSE);
|
|
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (preferences))),
|
|
priv->toolbar, FALSE, FALSE, 0);
|
|
#else
|
|
priv->toolbar = NULL;
|
|
#endif
|
|
priv->toolbutton = NULL;
|
|
gtk_box_pack_end (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (preferences))),
|
|
priv->notebook, TRUE, TRUE, 4);
|
|
|
|
priv->sizegroup = NULL;
|
|
priv->sizegroup2 = NULL;
|
|
priv->page = NULL;
|
|
priv->frame = NULL;
|
|
priv->box = NULL;
|
|
priv->hbox = NULL;
|
|
|
|
g_signal_connect (priv->notebook, "destroy",
|
|
G_CALLBACK (gtk_widget_destroyed), &priv->notebook);
|
|
#endif
|
|
|
|
#if HAVE_OSX
|
|
GtkWidget* icon;
|
|
GtkWidget* hbox = gtk_hbox_new (FALSE, 0);
|
|
GtkWidget* button = gtk_button_new ();
|
|
icon = gtk_image_new_from_stock (GTK_STOCK_HELP, GTK_ICON_SIZE_BUTTON);
|
|
gtk_button_set_image (GTK_BUTTON (button), icon);
|
|
g_signal_connect (button, "clicked",
|
|
G_CALLBACK (katze_preferences_help_clicked_cb), preferences);
|
|
gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 4);
|
|
gtk_box_pack_end (GTK_BOX (GTK_DIALOG (preferences)->action_area),
|
|
hbox, FALSE, FALSE, 0);
|
|
#endif
|
|
gtk_widget_show_all (gtk_dialog_get_content_area (GTK_DIALOG (preferences)));
|
|
}
|
|
|
|
/**
|
|
* katze_preferences_add_category:
|
|
* @preferences: a #KatzePreferences instance
|
|
* @label: a category label
|
|
* @icon: an icon name
|
|
*
|
|
* Adds a new category with the specified label to the dialog.
|
|
*
|
|
* Since: 0.2.1
|
|
*
|
|
* Since 0.3.4 a #GtkBox is returned that can be packed into.
|
|
**/
|
|
GtkWidget*
|
|
katze_preferences_add_category (KatzePreferences* preferences,
|
|
const gchar* label,
|
|
const gchar* icon)
|
|
{
|
|
KatzePreferencesPrivate* priv;
|
|
|
|
g_return_val_if_fail (KATZE_IS_PREFERENCES (preferences), NULL);
|
|
g_return_val_if_fail (label != NULL, NULL);
|
|
g_return_val_if_fail (icon != NULL, NULL);
|
|
|
|
priv = preferences->priv;
|
|
|
|
#if HAVE_HILDON
|
|
GtkWidget* widget;
|
|
gchar* markup;
|
|
|
|
if (!priv->scrolled)
|
|
katze_preferences_prepare (preferences);
|
|
|
|
widget = gtk_label_new (NULL);
|
|
gtk_widget_show (widget);
|
|
markup = g_markup_printf_escaped ("<b>%s</b>", label);
|
|
gtk_label_set_markup (GTK_LABEL (widget), markup);
|
|
g_free (markup);
|
|
gtk_box_pack_start (GTK_BOX (priv->box), widget, TRUE, TRUE, 0);
|
|
|
|
priv->sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
|
priv->sizegroup2 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
|
priv->hbox = NULL;
|
|
#else
|
|
if (!priv->notebook)
|
|
katze_preferences_prepare (preferences);
|
|
|
|
priv->page = gtk_vbox_new (FALSE, 0);
|
|
priv->sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
|
gtk_widget_show (priv->page);
|
|
gtk_container_set_border_width (GTK_CONTAINER (priv->page), 4);
|
|
#if HAVE_GRANITE
|
|
granite_widgets_static_notebook_append_page (
|
|
GRANITE_WIDGETS_STATIC_NOTEBOOK (priv->notebook),
|
|
priv->page, GTK_LABEL (gtk_label_new (label)));
|
|
#else
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook),
|
|
priv->page, gtk_label_new (label));
|
|
#endif
|
|
#if HAVE_OSX
|
|
priv->toolbutton = GTK_WIDGET (priv->toolbutton ?
|
|
gtk_radio_tool_button_new_from_widget (
|
|
GTK_RADIO_TOOL_BUTTON (priv->toolbutton))
|
|
: gtk_radio_tool_button_new (NULL));
|
|
gtk_widget_show (priv->toolbutton);
|
|
gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->toolbutton), label);
|
|
gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (priv->toolbutton), icon);
|
|
gtk_toolbar_insert (GTK_TOOLBAR (priv->toolbar),
|
|
GTK_TOOL_ITEM (priv->toolbutton), -1);
|
|
g_signal_connect (priv->toolbutton, "clicked",
|
|
G_CALLBACK (katze_preferences_toolbutton_clicked_cb), priv->page);
|
|
if (priv->toolbutton)
|
|
g_object_set_data (G_OBJECT (priv->toolbutton), "notebook", priv->notebook);
|
|
#endif
|
|
#endif
|
|
|
|
return priv->page;
|
|
}
|
|
|
|
#if !HAVE_HILDON
|
|
static GtkWidget*
|
|
katze_hig_frame_new (const gchar* title)
|
|
{
|
|
/* Create a frame with no actual frame but a bold label and indentation */
|
|
GtkWidget* frame = gtk_frame_new (NULL);
|
|
#ifdef G_OS_WIN32
|
|
gtk_frame_set_label (GTK_FRAME (frame), title);
|
|
#else
|
|
gchar* title_bold = g_strdup_printf ("<b>%s</b>", title);
|
|
GtkWidget* label = gtk_label_new (NULL);
|
|
gtk_label_set_markup (GTK_LABEL (label), title_bold);
|
|
g_free (title_bold);
|
|
gtk_frame_set_label_widget (GTK_FRAME (frame), label);
|
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
|
|
#endif
|
|
return frame;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* katze_preferences_add_group:
|
|
* @preferences: a #KatzePreferences instance
|
|
* @label: a group label, or %NULL
|
|
*
|
|
* Adds a new group with the specified label to the dialog.
|
|
*
|
|
* Since: 0.2.1
|
|
*
|
|
* Since 0.3.4 you can pass %NULL to hide the label.
|
|
**/
|
|
void
|
|
katze_preferences_add_group (KatzePreferences* preferences,
|
|
const gchar* label)
|
|
{
|
|
#if !HAVE_HILDON
|
|
KatzePreferencesPrivate* priv;
|
|
|
|
g_return_if_fail (KATZE_IS_PREFERENCES (preferences));
|
|
|
|
priv = preferences->priv;
|
|
priv->sizegroup2 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
|
priv->frame = label ? katze_hig_frame_new (label) :
|
|
g_object_new (GTK_TYPE_FRAME, "shadow-type", GTK_SHADOW_NONE, NULL);
|
|
gtk_container_set_border_width (GTK_CONTAINER (priv->frame), 4);
|
|
gtk_box_pack_start (GTK_BOX (priv->page), priv->frame, FALSE, FALSE, 0);
|
|
priv->box = gtk_vbox_new (FALSE, 4);
|
|
gtk_container_set_border_width (GTK_CONTAINER (priv->box), 4);
|
|
gtk_container_add (GTK_CONTAINER (priv->frame), priv->box);
|
|
gtk_widget_show_all (priv->frame);
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* katze_preferences_add_widget:
|
|
* @preferences: a #KatzePreferences instance
|
|
* @widget: a widget representing an option
|
|
* @type: "filled", "indented", or "spanned"
|
|
*
|
|
* Adds a widget to the dialog.
|
|
*
|
|
* Since: 0.2.1
|
|
**/
|
|
void
|
|
katze_preferences_add_widget (KatzePreferences* preferences,
|
|
GtkWidget* widget,
|
|
const gchar* type)
|
|
{
|
|
KatzePreferencesPrivate* priv;
|
|
const gchar* _type;
|
|
|
|
g_return_if_fail (KATZE_IS_PREFERENCES (preferences));
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
g_return_if_fail (type != NULL);
|
|
|
|
priv = preferences->priv;
|
|
_type = g_intern_string (type);
|
|
|
|
/* Showing implicitly widget and children is not the best idea,
|
|
but lots of repeated function calls aren't either. */
|
|
gtk_widget_show_all (widget);
|
|
|
|
if (!priv->hbox)
|
|
_type = g_intern_string ("indented");
|
|
#ifdef HAVE_HILDON_2_2
|
|
else if (HILDON_IS_CHECK_BUTTON (widget) || HILDON_IS_PICKER_BUTTON (widget))
|
|
_type = g_intern_string ("indented");
|
|
#endif
|
|
|
|
if (_type != g_intern_static_string ("spanned"))
|
|
{
|
|
priv->hbox = gtk_hbox_new (FALSE, 4);
|
|
gtk_widget_show (priv->hbox);
|
|
gtk_box_pack_start (GTK_BOX (priv->hbox), widget, TRUE, FALSE, 0);
|
|
}
|
|
|
|
if (_type == g_intern_static_string ("filled"))
|
|
gtk_box_pack_start (GTK_BOX (priv->box), priv->hbox, TRUE, FALSE, 0);
|
|
else if (_type == g_intern_static_string ("indented"))
|
|
{
|
|
GtkWidget* align = gtk_alignment_new (0, 0.5, 0, 0);
|
|
gtk_widget_show (align);
|
|
gtk_container_add (GTK_CONTAINER (align), priv->hbox);
|
|
#if HAVE_HILDON
|
|
if (!GTK_IS_SPIN_BUTTON (widget) && !GTK_IS_LABEL (widget))
|
|
#else
|
|
if (!GTK_IS_SPIN_BUTTON (widget))
|
|
#endif
|
|
gtk_size_group_add_widget (priv->sizegroup, widget);
|
|
gtk_box_pack_start (GTK_BOX (priv->box), align, TRUE, FALSE, 0);
|
|
}
|
|
else if (_type == g_intern_static_string ("spanned"))
|
|
{
|
|
GtkWidget* align = gtk_alignment_new (0, 0.5, 0, 0);
|
|
gtk_widget_show (align);
|
|
gtk_container_add (GTK_CONTAINER (align), widget);
|
|
if (!GTK_IS_LABEL (widget) && !GTK_IS_SPIN_BUTTON (widget)
|
|
&& !(GTK_IS_BUTTON (widget) && !GTK_IS_TOGGLE_BUTTON (widget)))
|
|
gtk_size_group_add_widget (priv->sizegroup2, widget);
|
|
gtk_box_pack_start (GTK_BOX (priv->hbox), align, TRUE, FALSE, 0);
|
|
}
|
|
|
|
#if HAVE_HILDON
|
|
if (GTK_IS_BUTTON (widget) && !GTK_WIDGET_IS_SENSITIVE (widget))
|
|
gtk_widget_hide (widget);
|
|
#endif
|
|
}
|