Logo Search packages:      
Sourcecode: galeon version File versions

galeon-encoding-dialog.c

/*
 *  Copyright (C) 2000, 2001, 2002, 2003 Marco Pesenti Gritti
 *  Copyright (C) 2003 Christian Persch
 *  Copyright (C) 2003 Crispin Flowerday
 *
 *  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, 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 "config.h"
#endif

#include "galeon-encoding-dialog.h"
#include "galeon-encodings.h"
#include "galeon-embed.h"
#include "galeon-embed-shell.h"
#include "galeon-shell.h"
#include "gul-state.h"

#include <gtk/gtklabel.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtktreeview.h>
#include <gtk/gtktreeselection.h>
#include <gtk/gtktogglebutton.h>
#include <gtk/gtkdialog.h>
#include <gtk/gtkliststore.h>
#include <gtk/gtkcellrenderertext.h>

#include <gtk/gtktreeview.h>
#include <gtk/gtktreemodel.h>

#include <glib/gi18n.h>
#include <string.h>

enum
{
      COL_NAME,
      COL_ENCODING,
};


enum
{
      PROP_ENCODING_TREEVIEW,
      PROP_AUTOMATIC,
      PROP_MANUAL,
      PROP_WINDOW
};

static const
GaleonDialogProperty properties [] =
{
      { PROP_ENCODING_TREEVIEW, "encoding_treeview",  NULL, PT_NORMAL, NULL },
      { PROP_AUTOMATIC,         "automatic_button",   NULL, PT_NORMAL, NULL },
      { PROP_MANUAL,            "manual_button",      NULL, PT_NORMAL, NULL },
      { PROP_WINDOW,            "encoding_dialog",    NULL, PT_NORMAL, NULL },
      { -1 }
};

#define GALEON_ENCODING_DIALOG_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), \
                               GALEON_TYPE_ENCODING_DIALOG, GaleonEncodingDialogPrivate))


struct GaleonEncodingDialogPrivate
{
      GaleonEncodings *encodings;
      GaleonWindow *window;
      GaleonEmbed *embed;
      GtkWidget *enc_view;
      gboolean update_tag;
      gint ignore_activation;
};

void        galeon_encoding_dialog_response_cb  (GtkWidget *widget,
                                           gint response,
                                           GaleonEncodingDialog *dialog);

G_DEFINE_TYPE (GaleonEncodingDialog, galeon_encoding_dialog, GALEON_TYPE_EMBED_DIALOG);

static void
sync_encoding_against_embed (GaleonEncodingDialog *dialog)
{
      GaleonEmbed *embed;
      GaleonEncodingPageInfo *page_info;
      const GaleonEncodingInfo *info;
        GtkTreeSelection *selection;
        GtkTreeModel *model;
        GList *rows;
      GtkWidget *button;
      GtkTreeIter iter;

      embed = galeon_embed_dialog_get_embed (GALEON_EMBED_DIALOG (dialog));
      g_return_if_fail (GALEON_IS_EMBED (embed));

      page_info = galeon_embed_get_encoding_info (embed);
      if (page_info == NULL) return;

      info = galeon_encodings_get_encoding (dialog->priv->encodings, page_info->encoding);
      if (!info) return;

      /* Stop the selection_changed callback from firing */
      dialog->priv->update_tag = TRUE;

      /* select the current encoding in the list view */
      model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->enc_view));
        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->enc_view));
      gtk_tree_model_get_iter_first (model, &iter);
      do {
            gchar *encoding;
            gtk_tree_model_get (model, &iter, COL_ENCODING, &encoding, -1);
            if (!strcmp (encoding, page_info->encoding))
            {
                  gtk_tree_selection_select_iter (selection, &iter);
                  g_free (encoding);
                  break;
            }
            g_free (encoding);
      } while (gtk_tree_model_iter_next (model, &iter));

      /* scroll the view so the active encoding is visible */
        rows = gtk_tree_selection_get_selected_rows (selection, &model);
        if (rows != NULL)
      {
            gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (dialog->priv->enc_view),
                                    (GtkTreePath *) rows->data,
                                    NULL, /* column */
                                    TRUE,
                                    0.5,
                                    0.0);
            g_list_foreach (rows, (GFunc)gtk_tree_path_free, NULL);
            g_list_free (rows);
      }

      button = galeon_dialog_get_control (GALEON_DIALOG (dialog), 
                                  page_info->forced ? PROP_MANUAL : PROP_AUTOMATIC);
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);

      galeon_encoding_page_info_free (page_info);

      dialog->priv->update_tag = FALSE;
}

/* Re-sync the dialog when the embed stops loading
 */
static void
embed_net_stop_cb (GaleonEmbed *embed, GaleonEncodingDialog *dialog)
{
      if (dialog->priv->ignore_activation)
      {
            dialog->priv->ignore_activation--;
            return;
      }

      sync_encoding_against_embed (dialog);
}


/** Re-sync the dialog when the embed changes 
 */
static void
sync_embed_cb (GaleonEncodingDialog *dialog, GParamSpec *pspec, gpointer dummy)
{
      GaleonEmbed *embed;
      embed = galeon_embed_dialog_get_embed (GALEON_EMBED_DIALOG (dialog));

      if (dialog->priv->embed != NULL)
      {
            g_signal_handlers_disconnect_by_func (dialog->priv->embed,
                                          G_CALLBACK (embed_net_stop_cb),
                                          dialog);
      }

      g_signal_connect (G_OBJECT (embed), "ge_net_stop",
                    G_CALLBACK (embed_net_stop_cb), dialog);
      dialog->priv->embed = embed;

      sync_encoding_against_embed (dialog);

}

/* Re-sync the current emebed when it changes, this will cause the
 * sync_embed_cb to be fired, hence syncing the dialog
 */
static void
sync_active_tab (GaleonWindow *window, GaleonEmbed *oldembed, GaleonEmbed *newembed,
             GaleonEncodingDialog *dialog)
{
      g_signal_handlers_disconnect_by_func (oldembed,
                                    G_CALLBACK (embed_net_stop_cb),
                                    dialog);
      g_object_set (G_OBJECT (dialog), "GaleonEmbed", newembed, NULL);
}

static void
sync_parent_window_cb (GaleonEncodingDialog *dialog, GParamSpec *pspec, gpointer dummy)
{
      GaleonWindow *window;
      GaleonEmbed *embed;
      GValue value = { 0, };

      g_return_if_fail (dialog->priv->window == NULL);

      g_value_init (&value, GTK_TYPE_WIDGET);
      g_object_get_property (G_OBJECT (dialog), "ParentWindow", &value);
      window = GALEON_WINDOW (g_value_get_object (&value));
      g_value_unset (&value);

      g_return_if_fail (GALEON_IS_WINDOW (window));

      dialog->priv->window = window;

      embed = galeon_window_get_active_embed (dialog->priv->window);
      g_object_set (G_OBJECT (dialog), "GaleonEmbed", embed, NULL);

      g_signal_connect (G_OBJECT (window), "active_embed_changed",
                    G_CALLBACK (sync_active_tab), dialog);
}

static void
activate_choice (GaleonEncodingDialog *dialog, const gchar *selected)
{
      GaleonEmbed *embed;
      GaleonEncodingPageInfo *info;
      GtkWidget *button;

      embed = galeon_embed_dialog_get_embed (GALEON_EMBED_DIALOG (dialog));
      g_return_if_fail (GALEON_IS_EMBED (embed));

      info = galeon_embed_get_encoding_info (embed);
      if (info == NULL) return;

      if (!selected)
      {
            /* only unset if it was forced before */
            if (info->forced)
            {
                  galeon_embed_set_encoding (embed, "");
            }
      }
      else
      {
            /* only force it if it's different from active */
            if (info->encoding && strcmp (info->encoding, selected) != 0)
            {
                  galeon_embed_set_encoding (embed, selected);

                  galeon_encodings_add_recent (dialog->priv->encodings, selected);
                  button = galeon_dialog_get_control (GALEON_DIALOG (dialog), 
                                              PROP_MANUAL);
                  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
            }
      }

      galeon_encoding_page_info_free (info);
}

static void
automatic_toggled_cb (GtkToggleButton *button, GaleonEncodingDialog *dialog)
{
      if (dialog->priv->update_tag == TRUE) return;

      if (gtk_toggle_button_get_active (button))
      {
            activate_choice (dialog, NULL);
      }
}

static void
tree_view_selection_changed_cb (GtkTreeSelection *selection, 
                        GaleonEncodingDialog *dialog)
{
      GtkTreeModel *model;
      GtkTreeIter iter;

      if (dialog->priv->update_tag == TRUE) return;

      if (gtk_tree_selection_get_selected (selection, &model, &iter))
      {
            gchar *encoding;
            gtk_tree_model_get (model, &iter, COL_ENCODING, &encoding, -1);

            /* No need to update the treeview when the net_stop signal 
             * gets called */
            dialog->priv->ignore_activation++;
            activate_choice (dialog, encoding);

            g_free (encoding);
      }
}


static void
tree_view_row_activated_cb (GtkTreeView *treeview, GtkTreePath *path,
                      GtkTreeViewColumn *arg2,
                      GaleonEncodingDialog *dialog)
{
      GtkTreeModel *model;
      GtkTreeIter iter;
      GtkWidget *button;
      gchar *encoding;

      if (dialog->priv->update_tag == TRUE) return;

      model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));

      gtk_tree_model_get_iter (model, &iter, path);
      gtk_tree_model_get (model, &iter, COL_ENCODING, &encoding, -1);

      button = galeon_dialog_get_control (GALEON_DIALOG (dialog), PROP_MANUAL);
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);

      activate_choice (dialog, encoding);

      g_free (encoding);

      /* Get rid of the dialog */
      g_object_unref (dialog);
}

void
galeon_encoding_dialog_response_cb (GtkWidget *widget,
                            gint response,
                            GaleonEncodingDialog *dialog)
{
      g_object_unref (dialog);
}


static int
compare_encodings (GaleonEncodingInfo *a, GaleonEncodingInfo *b)
{
      return g_utf8_collate (a->title, b->title);
}


static void
galeon_encoding_dialog_init (GaleonEncodingDialog *dialog)
{
      GtkWidget *treeview, *button, *window;
        GtkListStore *liststore;
        GtkCellRenderer *renderer;
        GtkTreeViewColumn *column;
      GtkTreeSelection *selection;
      GaleonEmbedShell *embed_shell;
      GList *list, *l;

      dialog->priv = GALEON_ENCODING_DIALOG_GET_PRIVATE (dialog);

      embed_shell = galeon_shell_get_embed_shell (galeon_shell);
      dialog->priv->encodings = galeon_embed_shell_get_encodings (embed_shell);
      dialog->priv->update_tag = FALSE;

      galeon_dialog_construct (GALEON_DIALOG (dialog),
                         properties,
                         "galeon.glade",
                         "encoding_dialog");

      treeview = galeon_dialog_get_control (GALEON_DIALOG (dialog), PROP_ENCODING_TREEVIEW);

      /* Setup the List View */
        liststore = gtk_list_store_new (2,
                                        G_TYPE_STRING,
                                        G_TYPE_STRING);
        gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL(liststore));
        gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
      gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), TRUE);
      selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
      gtk_tree_selection_set_mode (selection,
                             GTK_SELECTION_SINGLE);

      renderer = gtk_cell_renderer_text_new ();
        gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
                                                     COL_NAME,
                                         _("Encoding"),
                                                     renderer,
                                                     "text", COL_NAME,
                                                     NULL);
        column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), COL_NAME);
        gtk_tree_view_column_set_resizable (column, FALSE);
        gtk_tree_view_column_set_reorderable (column, FALSE);

      button = galeon_dialog_get_control (GALEON_DIALOG (dialog), PROP_AUTOMATIC);
      gtk_label_set_use_markup (GTK_LABEL (GTK_BIN (button)->child), TRUE);
      g_signal_connect (button, "toggled",
                    G_CALLBACK (automatic_toggled_cb), dialog);

      button = galeon_dialog_get_control (GALEON_DIALOG (dialog), PROP_MANUAL);
      gtk_label_set_use_markup (GTK_LABEL (GTK_BIN (button)->child), TRUE);

      /* Populate the List */
      list = galeon_encodings_get_encodings (dialog->priv->encodings, LG_ALL);
      list = g_list_sort (list, (GCompareFunc) compare_encodings);
      for (l = list ; l ; l = l->next)
      {
            GtkTreeIter iter;
            GaleonEncodingInfo *info = (GaleonEncodingInfo*)(l->data);

            gtk_list_store_append (liststore, &iter);
            gtk_list_store_set (liststore, &iter,
                            COL_NAME, _(info->title),
                            COL_ENCODING, info->encoding,
                            -1);
      }
      g_list_free (list);
      
      g_object_unref (liststore);

      dialog->priv->enc_view = treeview;

      window = galeon_dialog_get_control (GALEON_DIALOG (dialog), PROP_WINDOW);
      gul_state_monitor_window (window, "Encoding Dialog", 330, 410);

      g_signal_connect (G_OBJECT (selection), "changed",
                    G_CALLBACK (tree_view_selection_changed_cb),
                    dialog);
      g_signal_connect (G_OBJECT (treeview), "row-activated",
                    G_CALLBACK (tree_view_row_activated_cb),
                    dialog);

      g_signal_connect (G_OBJECT (dialog), "notify::ParentWindow",
                    G_CALLBACK (sync_parent_window_cb), NULL);
      g_signal_connect (G_OBJECT (dialog), "notify::GaleonEmbed",
                    G_CALLBACK (sync_embed_cb), NULL);
}

static void
galeon_encoding_dialog_finalize (GObject *object)
{
      GaleonEncodingDialog *dialog = GALEON_ENCODING_DIALOG (object);

      if (dialog->priv->window != NULL)
      {
            g_signal_handlers_disconnect_by_func (dialog->priv->window,
                                          G_CALLBACK (sync_active_tab),
                                          dialog);
      }

      if (dialog->priv->embed != NULL)
      {
            g_signal_handlers_disconnect_by_func (dialog->priv->embed,
                                          G_CALLBACK (embed_net_stop_cb),
                                          dialog);
      }

      G_OBJECT_CLASS (galeon_encoding_dialog_parent_class)->finalize (object);
}

static void
galeon_encoding_dialog_class_init (GaleonEncodingDialogClass *klass)
{
      GObjectClass *object_class = G_OBJECT_CLASS (klass);

      object_class->finalize = galeon_encoding_dialog_finalize;

      g_type_class_add_private (klass, sizeof (GaleonEncodingDialogPrivate));
}
            
GaleonEncodingDialog *
galeon_encoding_dialog_new (GaleonWindow *parent)
{
      return g_object_new (GALEON_TYPE_ENCODING_DIALOG,
                       "ParentWindow", parent,
                       NULL);
}

Generated by  Doxygen 1.6.0   Back to index