Logo Search packages:      
Sourcecode: autoprofile version File versions  Download package

preferences.c

/*--------------------------------------------------------------------------*
 * AUTOPROFILE                                                              *
 *                                                                          *
 * A Gaim away message and profile manager that supports dynamic text       *
 *                                                                          *
 * AutoProfile is the legal property of its developers.  Please refer to    *
 * the COPYRIGHT file distributed with this source distribution.            *
 *                                                                          *
 * 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 *
 *--------------------------------------------------------------------------*/

#include "autoprofile.h"
#include "gtkimhtml.h"
#include "gtkimhtmltoolbar.h"
#include "request.h"
#include "gtkdialogs.h"

static GtkWidget *cur_comp_menu, *cur_comp_container, *comp_view,
  *comp_list_store;
static GtkWidget *account_view;
static GtkListStore *account_list;
static GtkWidget *message_view;
static GtkListStore *message_list;
static GtkWidget *msg_window = NULL;
static GtkWidget *msgtext = NULL;

static gboolean update_string (GtkWidget *, GdkEventFocus *, gpointer);
static gboolean update_delay_update (GtkSpinButton *, gpointer);
static gboolean update_delay_respond (GtkWidget *, GdkEventFocus *, 
  gpointer);

static gboolean update_account_list_profile (GtkWidget *, GdkEventFocus *, 
  gpointer);
static gboolean update_account_list_away (GtkWidget *, GdkEventFocus *, 
  gpointer);
static gboolean change_comp_menu (GtkTreeSelection *, gpointer);

static void show_new_output_dialog (void);
static void remove_output_text (void);
static void toggle_profile (void);
static void toggle_away (void);
static void edit_msg (void);
static void refresh_view (void);
static gboolean display_diff_msg (GtkTreeSelection *, gpointer);

struct edit_message {
      GtkWidget *window;
      GtkWidget *toolbar;
      GtkWidget *entry;
      GtkWidget *text;
  char *orig_title;
  char *orig_text;
};

/* Returns boolean in regards to account having option set for updates
 * and responses. */
gboolean get_account_boolean (GaimAccount *account, char *value) 
{
  GList *accounts_list, *start_list;

  /* Obtain list of values as per preference type */
  if (!strcmp (value, "enable_profile")) {
    accounts_list = gaim_prefs_get_string_list (
      "/plugins/gtk/autoprofile/accounts/enable_profile");
  } else if (!strcmp (value, "enable_away")) {
    accounts_list = gaim_prefs_get_string_list (
      "/plugins/gtk/autoprofile/accounts/enable_away");
  } else {
    auto_debug ("get_account_boolean", "invalid paramater");
    return FALSE;
  }

  start_list = accounts_list;

  /* Search through list of values */
  while (accounts_list) {
    /* Check usernames */
    if (!strcmp ((char *) accounts_list->data, account->username)) {
      /* Error check */
      if (accounts_list->next == NULL) {
        auto_debug ("get_account_boolean", "invalid account string");
        free_string_list (start_list);
        return FALSE;
      }
      /* Compare protocols since usernames correct */
      if (!strcmp ((char *) accounts_list->next->data, account->protocol_id)) {
        free_string_list (start_list);
        return TRUE;
      }
    } 
    /* Error check */
    if (accounts_list->next == NULL)
      auto_debug ("get_account_boolean", "invalid account string");
    /* Increment */
    accounts_list = accounts_list->next->next;
  }

  /* Not found */
  free_string_list (start_list);
  return FALSE;
}

/* Switch pages callback */
static void switch_page (GtkNotebook *notebook, GtkNotebookPage *page,
  guint num, gpointer data) 
{
  gaim_prefs_set_int ("/plugins/gtk/autoprofile/tab_number", num);
}

/* Create the main preference menu */
static GtkWidget *get_config_frame (GaimPlugin *plugin)
{
  GtkWidget *ret_container;
  GtkWidget *page;
  GtkWidget *frame, *vbox, *hbox, *large_vbox;
  GtkWidget *spinner, *button, *label, *entry, *text;
  GtkWidget *checkbox;

  GtkTreeSelection *selection;
  char *str, *labeltext, *title;
  char *awaybool, *profilebool;

  int i;

  /* Widgets for per-account settings */
  GList *gaim_accounts;
  GList *comp_list;
  GaimAccount *account;
  GtkCellRenderer *renderer;
  GtkWidget *accountwin, *compwin, *aboutwin, *messagewin;
  GtkTreeIter list_store_iter, comp_list_iter, message_list_iter;
  GtkTreeViewColumn *col;
  gboolean profile_bool, away_bool;
  char *profile_truth, *away_truth;
  struct component *comp;

  GList *message_titles;
  GList *list_start;

  /* Create tabbed notebook */
  ret_container = gtk_notebook_new ();

  /*---------- Getting started info -----*/
  page = gtk_vbox_new (FALSE, 8);
  gtk_container_set_border_width (GTK_CONTAINER (page), 12);
  gtk_notebook_append_page (GTK_NOTEBOOK (ret_container),
    page, gtk_label_new (_("Getting started")));

  /* AutoProfile title */
  labeltext = g_strdup_printf (
    _("<span weight=\"bold\" size=\"larger\">AutoProfile %s</span>"),
    AUTOPROFILE_VERSION);
  label = gtk_label_new (NULL);
  gtk_label_set_markup (GTK_LABEL(label), labeltext);
  gtk_label_set_line_wrap (GTK_LABEL(label), TRUE);
  gtk_misc_set_alignment (GTK_MISC(label), 0.5, 0);
  gtk_box_pack_start (GTK_BOX(page), label, FALSE, FALSE, 0);
  g_free(labeltext);

  /* Window with info */
  aboutwin = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(aboutwin),
    GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(aboutwin), 
    GTK_SHADOW_IN);
  gtk_box_pack_start (GTK_BOX(page), aboutwin, TRUE, TRUE, 0);

  text = gtk_imhtml_new (NULL, NULL);
  gtk_container_add (GTK_CONTAINER(aboutwin), text);
  gaim_setup_imhtml (text);

  /* Info text */
  gtk_imhtml_append_text (GTK_IMHTML(text),
    _("AutoProfile is designed to be customized in nearly every way imaginable "
    "and as such has a detailed interface.  After choosing what you want from "
    "the tabs described below, <font color=red>be sure to double check that "
    "you've activated at least one of your accounts</font><br><br>"
    "Type \"/away\" in a conversation to set yourself to away<br><br>"),
    GTK_IMHTML_NO_SCROLL);
    
  gtk_imhtml_append_text (GTK_IMHTML(text),
    "<u>TABS</u><br>", GTK_IMHTML_NO_SCROLL);
  gtk_imhtml_append_text (GTK_IMHTML(text),
    "<b>Output text</b>: Write the text of your profile and away messages<br>",
    GTK_IMHTML_NO_SCROLL);
  gtk_imhtml_append_text (GTK_IMHTML(text),
    _("<b>Component settings</b>: Configure each automatically generated "
    "\"component\" included in your text<br>"),
    GTK_IMHTML_NO_SCROLL);
  gtk_imhtml_append_text (GTK_IMHTML(text),
    _("<b>Behavior</b>: Choose when new updates will be made and if buddies "
    "can interact directly with AutoProfile<br>"),
    GTK_IMHTML_NO_SCROLL);
  gtk_imhtml_append_text (GTK_IMHTML(text),
    _("<b>Accounts</b>: Choose which accounts AutoProfile will control<br>"),
    GTK_IMHTML_NO_SCROLL);

  gtk_imhtml_append_text (GTK_IMHTML(text),
    _("<br><u>DOCUMENTATION / HELP</u><br>"), GTK_IMHTML_NO_SCROLL);
  gtk_imhtml_append_text (GTK_IMHTML(text),
    _("Complete documentation can be found at:<br> <a href="
    "\"http://hkn.eecs.berkeley.edu/~casey/autoprofile/documentation.php\">"
    "hkn.eecs.berkeley.edu/~casey/autoprofile/documentation.php</a><br>"),
    GTK_IMHTML_NO_SCROLL);

  gtk_imhtml_append_text (GTK_IMHTML(text),
    _("<br><u>ABOUT</u><br>"), GTK_IMHTML_NO_SCROLL);

      str = g_strconcat(
            "<font size=\"3\"><b>", _("Developers"), ":</b></font><br>"
            "  Casey Ho (Lead Developer)<br>"
            "  Mitchell Harwell<br>", NULL);
      gtk_imhtml_append_text(GTK_IMHTML(text), str, GTK_IMHTML_NO_SCROLL);
      g_free(str);

      str = g_strconcat(
            "<font size=\"3\"><b>", _("Contributors/Patchers"), ":</b></font><br>"
            "  Onime Clement<br>"
            "  Michael Milligan<br>"
    "  Mark Painter<br>", NULL);
      gtk_imhtml_append_text(GTK_IMHTML(text), str, GTK_IMHTML_NO_SCROLL);
      g_free(str);


      str = g_strconcat(
            "<font size=\"3\"><b>", _("Website"), ":</b></font><br>"
    "  <a href=\"http://hkn.eecs.berkeley.edu/~casey/autoprofile\">"
    "hkn.eecs.berkeley.edu/~casey/autoprofile<br>", NULL);
      gtk_imhtml_append_text(GTK_IMHTML(text), str, GTK_IMHTML_NO_SCROLL);
      g_free(str);

  /*---------- Component order ----------*/
  page = gtk_vbox_new (FALSE, 5);
  gtk_container_set_border_width (GTK_CONTAINER (page), 12);
  gtk_notebook_append_page (GTK_NOTEBOOK (ret_container),
    page, gtk_label_new (_("Output text")));

  /* Top button list */
  hbox = gtk_hbox_new (FALSE, 3);
  gtk_box_pack_start (GTK_BOX(page), hbox, FALSE, FALSE, 0);
  button = gtk_button_new_with_label ("Add");
  g_signal_connect (G_OBJECT (button), "clicked",
                    G_CALLBACK (show_new_output_dialog), NULL);
  gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 0);
  button = gtk_button_new_with_label ("Remove");
  g_signal_connect (G_OBJECT (button), "clicked",
                    G_CALLBACK (remove_output_text), NULL);
  gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 0);
  button = gtk_button_new_with_label ("Set as profile");
  gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 0);
  g_signal_connect (G_OBJECT (button), "clicked",
                    G_CALLBACK (toggle_profile), NULL);
  button = gtk_button_new_with_label ("Set as default away message");
  gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 0);
  g_signal_connect (G_OBJECT (button), "clicked",
                    G_CALLBACK (toggle_away), NULL);

  /* List of away messages */
  messagewin = gtk_scrolled_window_new (0, 0);
  gtk_box_pack_start (GTK_BOX(page), messagewin, TRUE, TRUE, 0);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (messagewin),
                                  GTK_POLICY_NEVER,
                                  GTK_POLICY_NEVER);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (messagewin),
    GTK_SHADOW_IN);

  message_list = gtk_list_store_new (3, 
    G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
  message_view = gtk_tree_view_new_with_model (
    GTK_TREE_MODEL (message_list));
  gtk_container_add (GTK_CONTAINER (messagewin), message_view);
  renderer = gtk_cell_renderer_text_new ();
  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(message_view), FALSE);
  selection = gtk_tree_view_get_selection (
    GTK_TREE_VIEW (message_view));
  gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
  g_signal_connect (G_OBJECT (selection), "changed",
                    G_CALLBACK (display_diff_msg), NULL);

  col = gtk_tree_view_column_new_with_attributes (
    _("Message text"), renderer, "text", 0, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (message_view), col);
  col = gtk_tree_view_column_new_with_attributes (
    _("Away"), renderer, "text", 1, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (message_view), col);
  col = gtk_tree_view_column_new_with_attributes (
    _("Profile"), renderer, "text", 2, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (message_view), col);

  i = 0;
  message_titles = gaim_prefs_get_string_list (
    "/plugins/gtk/autoprofile/message_titles");
  list_start = message_titles;
  while (message_titles) {
    title = (char *)message_titles->data;
    awaybool = strdup ("");
    profilebool = strdup ("");
 
    if (i == gaim_prefs_get_int (
        "/plugins/gtk/autoprofile/default_profile")) {
      profilebool = _("(Profile)");
    }
    if (i == gaim_prefs_get_int (
        "/plugins/gtk/autoprofile/default_away")) {
      awaybool = _("(Default away message)");
    }

    gtk_list_store_append (message_list, &message_list_iter);
    gtk_list_store_set (message_list, &message_list_iter,
                        0, title,
                        1, awaybool,
                        2, profilebool, -1);
  
    message_titles = message_titles->next;
    i++;
  }
  free_string_list (list_start);

  /* Display window for current message */
  msg_window = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(msg_window), 
    GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(msg_window), 
    GTK_SHADOW_IN);
  gtk_box_pack_start (GTK_BOX(page), msg_window, TRUE, TRUE, 0);

  msgtext = gtk_imhtml_new (NULL, NULL);
  gtk_container_add (GTK_CONTAINER(msg_window), msgtext);
  gaim_setup_imhtml (msgtext);
  gtk_imhtml_append_text (GTK_IMHTML(msgtext), "<BR>",
    GTK_IMHTML_NO_TITLE | GTK_IMHTML_NO_COMMENTS |
    GTK_IMHTML_NO_SCROLL);

  hbox = gtk_hbox_new (FALSE, 6);
  gtk_box_pack_start (GTK_BOX(page), hbox, FALSE, FALSE, 0);

  button = gtk_button_new_with_label ("Refresh view");
  gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 0);
  g_signal_connect (G_OBJECT(button), "clicked",
                    G_CALLBACK (refresh_view), NULL);

  button = gtk_button_new_with_label ("Edit text");
  gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 0);
  g_signal_connect (G_OBJECT (button), "clicked",
                    G_CALLBACK (edit_msg), NULL);
                    
  /*---------- Individual component settings ----------*/
  page = gtk_vbox_new (FALSE, 15);
  gtk_container_set_border_width (GTK_CONTAINER (page), 12);
  gtk_notebook_append_page (GTK_NOTEBOOK (ret_container),
    page, gtk_label_new (_("Component settings")));
  
  hbox = gtk_hbox_new (FALSE, 10);
  gtk_box_pack_start (GTK_BOX (page), hbox, TRUE, TRUE, 0);

  /* Generate list of all components and place into select box */
  compwin = gtk_scrolled_window_new (0, 0);
  gtk_box_pack_start (GTK_BOX (hbox), compwin, FALSE, FALSE, 0);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (compwin),
                                  GTK_POLICY_NEVER,
                                  GTK_POLICY_NEVER);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (compwin),
    GTK_SHADOW_IN);

  comp_list_store = (GtkWidget *) gtk_list_store_new (1, G_TYPE_STRING);
  comp_view = gtk_tree_view_new_with_model (
    GTK_TREE_MODEL (comp_list_store));
  gtk_container_add (GTK_CONTAINER (compwin), comp_view);
  renderer = gtk_cell_renderer_text_new ();

  col = gtk_tree_view_column_new_with_attributes (
    _("Component"), renderer, "text", 0, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (comp_view), col);

  comp_list = components;
  
  while (comp_list) {
    comp = comp_list->data;
    
    gtk_list_store_append (GTK_LIST_STORE (comp_list_store), &comp_list_iter);
    gtk_list_store_set (GTK_LIST_STORE (comp_list_store), &comp_list_iter,
                        0, comp->id, -1);

    comp_list = comp_list->next;
  }

  selection = gtk_tree_view_get_selection (
    GTK_TREE_VIEW (comp_view));
  gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
  /* Connect the signal to select component */
  g_signal_connect (G_OBJECT (selection), "changed",
                    G_CALLBACK (change_comp_menu), NULL);

  /* Display window for component */
  compwin = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(compwin),
    GTK_POLICY_NEVER, GTK_POLICY_NEVER);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(compwin),
    GTK_SHADOW_IN);
  cur_comp_container = gtk_viewport_new (NULL, NULL);
  gtk_container_set_border_width (GTK_CONTAINER (cur_comp_container), 7);

  gtk_viewport_set_shadow_type (GTK_VIEWPORT(cur_comp_container), 
    GTK_SHADOW_NONE);
  gtk_container_add (GTK_CONTAINER(compwin), cur_comp_container);
  gtk_box_pack_start (GTK_BOX (hbox), compwin, TRUE, TRUE, 0);

  cur_comp_menu = gtk_vbox_new (FALSE, 0);
  label = gtk_label_new (
    _("Select a component for which \nto set preferences"));
  gtk_box_pack_start (GTK_BOX(cur_comp_menu), label, TRUE, TRUE, 0);
  gtk_container_add (GTK_CONTAINER(cur_comp_container), cur_comp_menu);

  /*---------- Update frequency ----------*/
  page = gtk_vbox_new (FALSE, 15);
  gtk_container_set_border_width (GTK_CONTAINER (page), 12);
  gtk_notebook_append_page (GTK_NOTEBOOK (ret_container),
    page, gtk_label_new (_("Behavior")));
  
  frame = gaim_gtk_make_frame (page, _("Update frequency"));
  vbox = gtk_vbox_new (FALSE, 5);
  gtk_container_add (GTK_CONTAINER (frame), vbox);

  /* Update delays */
  hbox = gtk_hbox_new (FALSE, 5);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
  label = gtk_label_new (_("Delay"));
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  spinner = gtk_spin_button_new_with_range (1, G_MAXINT, 1);
  gtk_box_pack_start (GTK_BOX (hbox), spinner, FALSE, FALSE, 0);
  label = gtk_label_new (_("minutes between profile updates"));
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinner), gaim_prefs_get_int (
    "/plugins/gtk/autoprofile/delay_profile"));
  g_signal_connect (G_OBJECT (spinner), "value-changed",
                    G_CALLBACK (update_delay_update), "profile");

  hbox = gtk_hbox_new (FALSE, 5);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
  label = gtk_label_new (_("Delay"));
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  spinner = gtk_spin_button_new_with_range (1, G_MAXINT, 1);
  gtk_box_pack_start (GTK_BOX (hbox), spinner, FALSE, FALSE, 0);
  label = gtk_label_new (_("minutes between away message updates"));
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinner), gaim_prefs_get_int (
    "/plugins/gtk/autoprofile/delay_away"));
  g_signal_connect (G_OBJECT (spinner), "value-changed",
                    G_CALLBACK (update_delay_update), "away");


  /*---------- Update frequency ----------*/
  frame = gaim_gtk_make_frame (page, _("Special auto-responses"));
  vbox = gtk_vbox_new (FALSE, 5);
  gtk_container_add (GTK_CONTAINER (frame), vbox);

  /* Auto-response activated */
  checkbox = gaim_gtk_prefs_checkbox (
    _("Allow users to request more auto-responses"),
    "/plugins/gtk/autoprofile/use_trigger", vbox);
  large_vbox = gtk_vbox_new (FALSE, 5);
  gtk_box_pack_start (GTK_BOX (vbox), large_vbox, FALSE, FALSE, 0);
 
  /* Auto-response delay */
  hbox = gtk_hbox_new (FALSE, 5);
  gtk_box_pack_start (GTK_BOX (large_vbox), hbox, FALSE, FALSE, 0);
  label = gtk_label_new (_("Delay"));
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  spinner = gtk_spin_button_new_with_range (1, G_MAXINT, 1);
  gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 0); 
  label = gtk_label_new (_("seconds between auto-responses"));
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinner), gaim_prefs_get_int (
    "/plugins/gtk/autoprofile/delay_respond"));
  g_signal_connect (G_OBJECT (spinner), "value-changed",
                    G_CALLBACK (update_delay_respond), NULL);

  /* Auto-response trigger string */
  label = gtk_label_new (_(
    "Message sent to new conversation:"));
  gtk_box_pack_start (GTK_BOX (large_vbox), label, FALSE, FALSE, 0);
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
  entry = gtk_entry_new ();
  gtk_box_pack_start (GTK_BOX (large_vbox), entry, FALSE, FALSE, 0);
  gtk_entry_set_max_length (GTK_ENTRY (entry), 100);
  gtk_entry_set_text (GTK_ENTRY (entry), gaim_prefs_get_string (
    "/plugins/gtk/autoprofile/text_respond"));
  g_signal_connect (G_OBJECT (entry), "focus-out-event",
                    G_CALLBACK (update_string), "text_respond");
  
  label = gtk_label_new (_(
    "Trigger message used for request:"));
  gtk_box_pack_start (GTK_BOX (large_vbox), label, FALSE, FALSE, 0);
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
  entry = gtk_entry_new ();
  gtk_box_pack_start (GTK_BOX (large_vbox), entry, FALSE, FALSE, 0);
  gtk_entry_set_max_length (GTK_ENTRY (entry), 50);
  gtk_entry_set_text (GTK_ENTRY (entry), gaim_prefs_get_string (
    "/plugins/gtk/autoprofile/text_trigger"));
  g_signal_connect (G_OBJECT (entry), "focus-out-event",
                    G_CALLBACK (update_string), "text_trigger");

  g_signal_connect(G_OBJECT(checkbox), "clicked",
    G_CALLBACK(gaim_gtk_toggle_sensitive), large_vbox);
  if (!gaim_prefs_get_bool ("/plugins/gtk/autoprofile/use_trigger")) {
    gtk_widget_set_sensitive (large_vbox, FALSE);
  } else {
    gtk_widget_set_sensitive (large_vbox, TRUE);
  }

  /*---------- Individual account settings ---------*/
  page = gtk_vbox_new (FALSE, 7);
  gtk_container_set_border_width (GTK_CONTAINER (page), 12);
  gtk_notebook_append_page (GTK_NOTEBOOK (ret_container),
    page, gtk_label_new (_("Accounts")));
  
  hbox = gtk_hbox_new (TRUE, 3);
  gtk_box_pack_start (GTK_BOX (page), hbox, 0, 0, 0);

  button = gtk_button_new_with_label ("Toggle auto-profile");
  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
  g_signal_connect (G_OBJECT (button), "clicked",
                    G_CALLBACK (update_account_list_profile), NULL);
  button = gtk_button_new_with_label ("Toggle auto-away messages");
  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
  g_signal_connect (G_OBJECT (button), "clicked",
                    G_CALLBACK (update_account_list_away), NULL);


  accountwin = gtk_scrolled_window_new (0, 0);
  gtk_container_add (GTK_CONTAINER (page), accountwin);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (accountwin),
                                  GTK_POLICY_NEVER,
                                  GTK_POLICY_NEVER);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (accountwin),
    GTK_SHADOW_IN);

  account_list = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, 
                                     G_TYPE_STRING, G_TYPE_STRING);
  account_view = gtk_tree_view_new_with_model (
    GTK_TREE_MODEL (account_list));
  gtk_container_add (GTK_CONTAINER (accountwin), account_view);
  renderer = gtk_cell_renderer_text_new ();

  col = gtk_tree_view_column_new_with_attributes (
    _("Account"), renderer, "text", 0, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (account_view), col);
  col = gtk_tree_view_column_new_with_attributes (
    _("Protocol"), renderer, "text", 1, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (account_view), col); 
  col = gtk_tree_view_column_new_with_attributes (
    _("Update profile"), renderer, "text", 2, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (account_view), col);
  col = gtk_tree_view_column_new_with_attributes (
    _("Update away message"), renderer, "text", 3, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (account_view), col);

  /* List out each account and their values */
  gaim_accounts = gaim_accounts_get_all ();
  while (gaim_accounts) {
    account = (GaimAccount *)gaim_accounts->data;
   
    profile_bool = get_account_boolean (account, _("enable_profile"));
    away_bool = get_account_boolean (account, _("enable_away"));

    if (profile_bool)
      profile_truth = N_("yes");
    else
      profile_truth = N_("no");

    if (away_bool)
      away_truth = N_("yes");
    else
      away_truth = N_("no");

  
    gtk_list_store_append (account_list, &list_store_iter);
    gtk_list_store_set (account_list, &list_store_iter,
                        0, account->username,
                        1, account->protocol_id,
                        2, profile_truth,
                        3, away_truth,
                        -1);
    
    gaim_accounts = gaim_accounts->next;
  }

  /* Finish up */
  gtk_notebook_set_current_page (GTK_NOTEBOOK(ret_container),
    gaim_prefs_get_int ("/plugins/gtk/autoprofile/tab_number"));
  gtk_widget_show_all (ret_container);
  g_signal_connect (G_OBJECT(ret_container), "switch-page",
                    G_CALLBACK(switch_page), NULL);

  return ret_container; 
}

/* When component is selected, bring up specific menu */
static gboolean change_comp_menu (GtkTreeSelection *select, gpointer data)
{
  GtkTreeModel *model;
  GtkTreeIter iter;
  gchar *string;
  struct component *comp;
  GList *comp_list;
  GtkWidget *label, *menu;
 
  auto_debug ("prefs", "new component selected");

  /* Figure out which component is selected */
  if (gtk_tree_selection_get_selected (select, &model, &iter)) {
    gtk_tree_model_get (model, &iter, 0, &string, -1);
  }

  comp_list = components;
  
  while (TRUE) {
    comp = comp_list->data;
    if (!strcmp (string, comp->id))
      break;
    comp_list = comp_list->next;
  }
  
  /* Remove old component */
  gtk_container_remove (GTK_CONTAINER (cur_comp_container),
    cur_comp_menu);

  /* Create new preference menu w/ text, etc */
  cur_comp_menu = gtk_vbox_new (FALSE, 5);
  gtk_container_add (GTK_CONTAINER(cur_comp_container), cur_comp_menu);

  label = gtk_label_new (comp->description);
  gtk_box_pack_start (GTK_BOX (cur_comp_menu), label, 0, 0, 0);
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
  gtk_box_pack_start (GTK_BOX (cur_comp_menu),
    gtk_hseparator_new (), 0, 0, 0);
  
  if (comp->pref_menu == NULL ||
      (menu = (comp->pref_menu) ()) == NULL) {
    label = gtk_label_new (_("No options available for this component"));
    gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
    gtk_box_pack_start (GTK_BOX (cur_comp_menu), label, 0, 0, 0);
  } else {
    gtk_box_pack_start (GTK_BOX (cur_comp_menu), menu, TRUE, TRUE, 0);
  }

  gtk_widget_show_all (cur_comp_container);

  return FALSE;
}

/* Does meat of updating work for the list of accounts
 * Grabs data from widget, and inverts value of original boolean */
static GList *update_account_list (GList *original, char *field)
{
  GtkTreeSelection *selection;
  GtkTreeIter row_iterator;

  gchar *username, *protocol_id, *bool_profile, *bool_away;

  GList *node, *tmp;
  GList *ret = NULL;

  /* Grab the needed data from the widget */
  selection = gtk_tree_view_get_selection (
    GTK_TREE_VIEW (account_view));
  
  if (!gtk_tree_selection_get_selected (selection, NULL, &row_iterator)) {
    gaim_debug (GAIM_DEBUG_INFO, "autoprofile",
                "update_account_list: failed to retrieve table row\n");
    return original;
  }

  gtk_tree_model_get (GTK_TREE_MODEL (account_list), &row_iterator,
                      0, &username,
                      1, &protocol_id,
                      2, &bool_profile,
                      3, &bool_away, -1);

  /* Change the list and return */
  if ((!strcmp (field, "enable_profile") && !strcmp (bool_profile, "yes")) ||
      (!strcmp (field, "enable_away") && !strcmp (bool_away, "yes"))) {
    /* Remove from the list */
    gaim_debug (GAIM_DEBUG_INFO, "autoprofile",
                "removing account from update list\n");

    while (original) {
      if (!strcmp (original->data, username) &&
          !strcmp (original->next->data, protocol_id)) {
        node = original;
        tmp = node->next;
        original = original->next->next;
        free (node->data);
        free (tmp->data);
        g_list_free_1 (node);
        g_list_free_1 (tmp);
      } else {
        node = original;
        original = original->next->next;
        node->next->next = ret;
        ret = node;
      }
    }

    if (!strcmp (field, "enable_profile")) 
      gtk_list_store_set (account_list, &row_iterator,
                          2, N_("no"), -1);
    else
      gtk_list_store_set (account_list, &row_iterator,
                          3, N_("no"), -1);

    return ret;
  } else {
    /* Otherwise add on */
    GList *ret_start, *ret_end;
    
    auto_debug ("update_account_list", "adding account to update list");
  
    ret_start = (GList *) malloc (sizeof (GList));
    ret_end = (GList *) malloc (sizeof (GList));
    ret_start->data = username;
    ret_start->next = ret_end;
    ret_end->data = protocol_id;
    ret_end->next = original;

    if (!strcmp (field, "enable_profile")) 
      gtk_list_store_set (account_list, &row_iterator,
                          2, N_("yes"), -1);
    else
      gtk_list_store_set (account_list, &row_iterator,
                          3, N_("yes"), -1);

    return ret_start;
  }
}

/* Updates away list with away boolean */
static gboolean update_account_list_away (GtkWidget *widget, 
                                          GdkEventFocus *evt, 
                                          gpointer data)
{
  GList *data_list;

  data_list = gaim_prefs_get_string_list (
    "/plugins/gtk/autoprofile/accounts/enable_away");
  data_list = update_account_list (data_list, "enable_away");
  gaim_prefs_set_string_list (
    "/plugins/gtk/autoprofile/accounts/enable_away", data_list);
  free_string_list (data_list);
 
  return FALSE;
}

/* Updates account list with profile boolean */
static gboolean update_account_list_profile (GtkWidget *widget, 
                                             GdkEventFocus *evt, 
                                             gpointer data)
{
  GList *data_list;

  data_list = gaim_prefs_get_string_list (
    "/plugins/gtk/autoprofile/accounts/enable_profile");
  data_list = update_account_list (data_list, "enable_profile");
  gaim_prefs_set_string_list (
    "/plugins/gtk/autoprofile/accounts/enable_profile", data_list);
  free_string_list (data_list);
 
  return FALSE;
}

/* Update string arguments */
static gboolean update_string (GtkWidget *widget, GdkEventFocus *evt, 
                               gpointer data)
{
  auto_debug ("update_string", "string preference modified");

      if (!strcmp (data, "text_trigger")) {
            gaim_prefs_set_string ("/plugins/gtk/autoprofile/text_trigger",
      gtk_entry_get_text (GTK_ENTRY (widget)));
  } else if (!strcmp (data, "text_respond")) {
    gaim_prefs_set_string ("/plugins/gtk/autoprofile/text_respond",
      gtk_entry_get_text (GTK_ENTRY (widget)));
  } else {
    auto_debug ("update_string", "invalid data argument");
  }

  return FALSE;
}

/* Update value returned from spinner for auto-update delays */
static gboolean update_delay_update (GtkSpinButton *spin, gpointer data)
{
  int interval;
  int value = gtk_spin_button_get_value_as_int (spin);

  interval = 60 * 1000 * value;

  if (!strcmp ((char *) data, "away")) {
    gaim_prefs_set_int ("/plugins/gtk/autoprofile/delay_away", value);
    if (is_away)
      status_away ();
  } else {
    gaim_prefs_set_int ("/plugins/gtk/autoprofile/delay_profile", value);
    g_source_remove (GPOINTER_TO_INT (profile_timeout));
    profile_timeout = GINT_TO_POINTER (g_timeout_add (
      interval, profile_update, NULL));
  }

  return FALSE;
}

/* Update value returned from spinner for auto-respond delay */
static gboolean update_delay_respond (GtkWidget *widget, GdkEventFocus *evt, 
                                      gpointer data)
{
  gaim_prefs_set_int ("/plugins/gtk/autoprofile/delay_respond",
    gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget)));
  return FALSE;
}

/*------------- Functions for output text page ----------------*/

/* Adds new message text to lists */
static void new_output_text (gpointer data, GaimRequestFields *fields) {
  const char *title;
  GtkTreeIter iter;
  GList *new_node, *old_list;
  char *cur_title, *describe_away, *describe_profile;
  int current_away;

  title = gaim_request_fields_get_string(fields, "title");
  describe_away = _("");
  describe_profile = _("");

  /* Check integrity constraint - no duplicate titles */
  if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL(message_list), &iter)) {
    while (TRUE) {
      gtk_tree_model_get (GTK_TREE_MODEL (message_list), &iter,
                          0, &cur_title, -1);
      if (!strcmp (title, cur_title)) {
        gaim_notify_error(NULL, NULL,
          _("Cannot have two messages with the same title"),
          _("Please use a different name")
        );
        return;
      }
      if (!gtk_tree_model_iter_next (GTK_TREE_MODEL(message_list), &iter)) {
        break;
      }
    }
    gaim_prefs_set_int ("/plugins/gtk/autoprofile/default_profile", 
      gaim_prefs_get_int ("/plugins/gtk/autoprofile/default_profile") + 1);
    gaim_prefs_set_int ("/plugins/gtk/autoprofile/default_away", 
      gaim_prefs_get_int ("/plugins/gtk/autoprofile/default_away") + 1);

  } else {
    gaim_prefs_set_int ("/plugins/gtk/autoprofile/default_profile", 0);
    gaim_prefs_set_int ("/plugins/gtk/autoprofile/default_away", 0);
    describe_away = _("(Default away message)");
    describe_profile = _("(Profile)");
  }

  current_away = gaim_prefs_get_int ("/plugins/gtk/autoprofile/current_away");

  if (current_away >= 0) {
    gaim_prefs_set_int ("/plugins/gtk/autoprofile/current_away",
      current_away + 1);
  }

  /* Update prefs */
  old_list = gaim_prefs_get_string_list (
    "/plugins/gtk/autoprofile/message_texts");
  new_node = (GList *)malloc (sizeof(GList));
  new_node->next = old_list;
  new_node->data = _("Get Autoprofile for Gaim at <a href=\""
    "http://hkn.eecs.berkeley.edu/~casey/autoprofile/\">"
    "hkn.eecs.berkeley.edu/~casey/autoprofile/</a><br><br>%s<br>");
  gaim_prefs_set_string_list ("/plugins/gtk/autoprofile/message_texts",
    new_node);
  free (new_node);
  free_string_list (old_list);

  old_list = gaim_prefs_get_string_list (
    "/plugins/gtk/autoprofile/message_titles");
  new_node = (GList *)malloc (sizeof(GList));
  new_node->next = old_list;
  new_node->data = strdup (title);
  gaim_prefs_set_string_list ("/plugins/gtk/autoprofile/message_titles",
    new_node);
  free_string_list (new_node);

  /* Update the displayed list */
  gtk_list_store_insert (message_list, &iter, 0);
  gtk_list_store_set (message_list, &iter,
                        0, title, 
                        1, describe_away,
                        2, describe_profile, -1);
}

/* Popup to add new message text */
static void show_new_output_dialog(void) {
  GaimRequestFields *fields;
  GaimRequestFieldGroup *group;
  GaimRequestField *field;

  fields = gaim_request_fields_new();

  group = gaim_request_field_group_new(NULL);
  gaim_request_fields_add_group(fields, group);

  field = gaim_request_field_string_new("title", _("_Text title"),
    NULL, FALSE);
  gaim_request_field_set_required(field, TRUE);
  gaim_request_field_set_type_hint(field, "title");
  gaim_request_field_group_add_field(group, field);

  gaim_request_fields(gaim_get_blist(), _("New output text format"),
    NULL,
    _("Please enter the title of the output text you would like to create"),
    fields,
    _("OK"), G_CALLBACK(new_output_text),
    _("Cancel"), NULL,
    NULL);
}

/* Remove selected output text */
static void remove_output_text (void) {
  GtkTreeSelection *selection;
  GtkTreeIter iter;

  GList *note_title, *note_text, *note_title_start, *note_text_start;
  GList *temp1, *temp2;
  GList *orig_title, *orig_text;
  
  char *title;
  int i;
  int current_away, current_profile, current_default;

  selection = gtk_tree_view_get_selection (
    GTK_TREE_VIEW (message_view));
  
  if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
    return;

  gtk_tree_model_get (GTK_TREE_MODEL (message_list), &iter,
                      0, &title, -1);

  gtk_list_store_remove (message_list, &iter);

  note_title = gaim_prefs_get_string_list (
    "/plugins/gtk/autoprofile/message_titles");
  note_text = gaim_prefs_get_string_list (
    "/plugins/gtk/autoprofile/message_texts");
  orig_title = note_title;
  orig_text = note_text;
  note_title_start = NULL;
  note_text_start = NULL;
 
  i = 0;
 
  while (note_title != NULL) {
    if (!strcmp((char *)note_title->data, title)) {
      note_title = note_title->next;
      note_text = note_text->next;

      /* Maintain integrity constraints */
      current_profile = gaim_prefs_get_int (
        "/plugins/gtk/autoprofile/default_profile");
      if (i == current_profile) {
        gaim_prefs_set_int ("/plugins/gtk/autoprofile/default_profile", -1);
      } else if (i < current_profile) {
        gaim_prefs_set_int ("/plugins/gtk/autoprofile/default_profile",
          current_profile - 1);
      }

      current_default = gaim_prefs_get_int (
        "/plugins/gtk/autoprofile/default_away");

      if (i == current_default) {
        gaim_prefs_set_int ("/plugins/gtk/autoprofile/default_away", -1);
      } else if (i < current_default) {
        gaim_prefs_set_int ("/plugins/gtk/autoprofile/default_away",
          current_default - 1);
      }
      
      current_away = gaim_prefs_get_int (
        "/plugins/gtk/autoprofile/current_away");
      if (i == current_away) {
        status_back ();
      } else if (i < current_away) {
        gaim_prefs_set_int ("/plugins/gtk/autoprofile/current_away",
          current_away - 1);
      }

    } else {
      temp1 = (GList *)malloc(sizeof(GList));
      temp2 = (GList *)malloc(sizeof(GList));
      temp1->next = note_title_start;
      temp2->next = note_text_start;
      temp1->data = strdup ((char *)note_title->data);
      temp2->data = strdup ((char *)note_text->data);
      temp1->prev = NULL;
      temp2->prev = NULL;
      if (note_title_start != NULL) {
        note_title_start->prev = temp1;
        note_text_start->prev = temp2;
      }
      note_title_start = temp1;
      note_text_start = temp2;
      note_title = note_title->next;
      note_text = note_text->next;
      i++;
    }
  }

  gaim_prefs_set_string_list ("/plugins/gtk/autoprofile/message_texts",
    g_list_reverse (note_text_start));
  gaim_prefs_set_string_list ("/plugins/gtk/autoprofile/message_titles",
    g_list_reverse (note_title_start));
    
  free_string_list (note_text_start);
  free_string_list (note_title_start);
  free_string_list (orig_title);
  free_string_list (orig_text);
}

static void toggle_profile ()
{
  GtkTreeSelection *selection;
  GtkTreeIter iter, iter2;

  char *title, *title2;
  int position, i;

  position = gaim_prefs_get_int ("/plugins/gtk/autoprofile/default_profile");
  selection = gtk_tree_view_get_selection (
    GTK_TREE_VIEW (message_view));
  
  if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
    return;

  if (position >= 0) {
    gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(message_list), &iter2,
      NULL, position);
    gtk_list_store_set (message_list, &iter2, 2, _(""), -1);
  }
  gtk_list_store_set (message_list, &iter, 2, _("(Profile)"), -1); 

  i = 0;
  gtk_tree_model_get_iter_first (GTK_TREE_MODEL(message_list), &iter2);
  gtk_tree_model_get (GTK_TREE_MODEL (message_list), &iter,
                      0, &title, -1);

  while (TRUE) {
    gtk_tree_model_get (GTK_TREE_MODEL (message_list), &iter2,
                        0, &title2, -1);
    if (!strcmp (title, title2)) {
      break;
    }
    i++;
    gtk_tree_model_iter_next (GTK_TREE_MODEL(message_list), &iter2);
  }

  gaim_prefs_set_int ("/plugins/gtk/autoprofile/default_profile", i);

}

static void toggle_away ()
{
  GtkTreeSelection *selection;
  GtkTreeIter iter, iter2;

  char *title, *title2;
  int position, i;

  position = gaim_prefs_get_int ("/plugins/gtk/autoprofile/default_away");
  selection = gtk_tree_view_get_selection (
    GTK_TREE_VIEW (message_view));
  
  if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
    return;

  if (position >= 0) {
    gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(message_list), &iter2,
      NULL, position);
    gtk_list_store_set (message_list, &iter2, 1, _(""), -1);
  }
  gtk_list_store_set (message_list, &iter, 1, _("(Default away message)"), -1); 

  i = 0;
  gtk_tree_model_get_iter_first (GTK_TREE_MODEL(message_list), &iter2);
  gtk_tree_model_get (GTK_TREE_MODEL (message_list), &iter,
                      0, &title, -1);

  while (TRUE) {
    gtk_tree_model_get (GTK_TREE_MODEL (message_list), &iter2,
                        0, &title2, -1);
    if (!strcmp (title, title2)) {
      break;
    }
    i++;
    gtk_tree_model_iter_next (GTK_TREE_MODEL(message_list), &iter2);
  }

  gaim_prefs_set_int ("/plugins/gtk/autoprofile/default_away", i);
}

static void refresh_view ()
{
  GtkTreeSelection *selection;

  selection = gtk_tree_view_get_selection (
    GTK_TREE_VIEW (message_view));

  display_diff_msg (selection, NULL);
}

static gboolean display_diff_msg (GtkTreeSelection *select, gpointer data)
{
  GtkTreeModel *model;
  GtkTreeIter iter;
  gchar *message, *title;

  GList *cur_title, *cur_message, *title_start, *message_start;

  /* Figure out which component is selected */
  if (gtk_tree_selection_get_selected (select, &model, &iter)) {
    gtk_tree_model_get (model, &iter, 0, &title, -1);

    cur_title = gaim_prefs_get_string_list (
      "/plugins/gtk/autoprofile/message_titles");
    cur_message = gaim_prefs_get_string_list (
      "/plugins/gtk/autoprofile/message_texts");
    title_start = cur_title;
    message_start = cur_message;

    /* Search for the associated message */
    while (TRUE) {
      if (cur_title == NULL) {
        free_string_list (title_start);
        free_string_list (message_start);
        return FALSE;
      }
      if (!strcmp (title, (char *)cur_title->data)) {
        message = (char *)cur_message->data;
        message = autoprofile_generate (message);
        break;
      }

      cur_title = cur_title->next;
      cur_message = cur_message->next;
    }
    free_string_list (title_start);
    free_string_list (message_start);

    /* Change the display window */
    if (msgtext) {
      gtk_widget_destroy (msgtext);
    }
    
    msgtext = gtk_imhtml_new (NULL, NULL);
    gtk_container_add (GTK_CONTAINER(msg_window), msgtext);
    gaim_setup_imhtml (msgtext);
    gtk_widget_show (msgtext);
    gtk_imhtml_append_text (GTK_IMHTML(msgtext), message, 
      GTK_IMHTML_NO_TITLE |
      GTK_IMHTML_NO_COMMENTS | GTK_IMHTML_NO_SCROLL);
    gtk_imhtml_append_text (GTK_IMHTML(msgtext), "<BR>",
      GTK_IMHTML_NO_TITLE | GTK_IMHTML_NO_COMMENTS |
      GTK_IMHTML_NO_SCROLL);
    free (message);
    return TRUE;
  }

  return FALSE;
}

/*--------------- Stuff regarding the popup edit box --------------------*/
static void destroy_dialog (GtkWidget *w, GtkWidget *w2)
{
  GtkWidget *dest;

  if (!GTK_IS_WIDGET(w2))
    dest = w;
  else
    dest = w2;

  gtk_widget_destroy(dest);
}

static void mess_destroy (GtkWidget *widget, struct edit_message *ca)
{
  destroy_dialog(NULL, ca->window);
  g_free (ca->orig_title);
  g_free (ca->orig_text);
  g_free (ca);
}

static void mess_destroy_ca (GtkWidget *widget, 
  GdkEvent *event, struct edit_message *ca)
{
  mess_destroy(NULL, ca);
}

static void save_mess(GtkWidget *widget, struct edit_message *ca)
{
  gchar *new_message, *old_title, *new_title, *node_title;
  GList *cur_title, *cur_message, *titles_start, *messages_start;
  GtkTreeIter iter;
  GtkTreeSelection *selection;
  int i;

  new_message = strdup (gtk_imhtml_get_markup (GTK_IMHTML(ca->text)));
  new_title = strdup (gtk_entry_get_text (GTK_ENTRY(ca->entry)));
  old_title = ca->orig_title;

  cur_title = gaim_prefs_get_string_list (
    "/plugins/gtk/autoprofile/message_titles");
  cur_message = gaim_prefs_get_string_list (
    "/plugins/gtk/autoprofile/message_texts");
  messages_start = cur_message;
  titles_start = cur_title;

  i = 0;

  /* Check integrity constraint - no duplicate titles */
  if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL(message_list), &iter)) {
    while (TRUE) {
      gtk_tree_model_get (GTK_TREE_MODEL (message_list), &iter,
                          0, &node_title, -1);
      if (!strcmp (new_title, node_title) && 
          strcmp (node_title, old_title) != 0) {
        auto_debug ("message-editor", "ERROR: can't have duplicate titles");
        gaim_notify_error(NULL, NULL,
          _("You cannot have two messages with the same title"),
          _("Please choose a different title"));
        free_string_list (messages_start);
        free_string_list (titles_start);
        free (new_message);
        free (new_title);
        return;
      }
      if (!gtk_tree_model_iter_next (GTK_TREE_MODEL(message_list), &iter)) {
        break;
      }
    }
  }

  /* Search for the associated message */
  while (TRUE) {
    if (cur_title == NULL) {
      auto_debug ("message-editor", "ERROR: message not found");
      gaim_notify_error(NULL, NULL,
        _("Could not find the original message"),
        _("It might have been deleted, please recreate it")
      );
      mess_destroy(NULL, ca);
      free_string_list (messages_start);
      free_string_list (titles_start);
      free (new_message);
      free (new_title);
      return;
    } 
    if (!strcmp (old_title, (char *)cur_title->data)) {
      break;
    }

    cur_title = cur_title->next;
    cur_message = cur_message->next;
    i++;
  }

  /* Update the saved copies */
  free (cur_title->data);
  cur_title->data = new_title;
  cur_message->data = new_message;

  gaim_prefs_set_string_list ("/plugins/gtk/autoprofile/message_titles",
    titles_start);
  gaim_prefs_set_string_list ("/plugins/gtk/autoprofile/message_texts",
    messages_start);

  /* Update the displayed view */
  gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(message_list), &iter,
    NULL, i);
  gtk_list_store_set (message_list, &iter, 0, new_title, -1);

  selection = gtk_tree_view_get_selection (
    GTK_TREE_VIEW (message_view));

  free_string_list (messages_start);
  free_string_list (titles_start);

  display_diff_msg (selection, NULL);
  mess_destroy(NULL, ca);
}

/* Display the popup edit dialog */
static void gtk_edit_msg (char *title, char *message)
{
  /* Most code jacked from original Gaim dialog */
  GtkWidget *vbox, *hbox, *big_hbox;
  GtkWidget *label;
  GtkWidget *sw;
  GtkWidget *button;

  gchar *buf;
  GList *cur_comp_node;
  struct component *cur_comp;

  struct edit_message *ca = g_new0(struct edit_message, 1);

  /* Set up window */
  GAIM_DIALOG(ca->window);
  gtk_widget_set_size_request(ca->window, -1, 250);
  gtk_container_set_border_width(GTK_CONTAINER(ca->window), 6);
  gtk_window_set_role(GTK_WINDOW(ca->window), "away_mess");
  gtk_window_set_title(GTK_WINDOW(ca->window), _("Edit message"));
  g_signal_connect(G_OBJECT(ca->window), "delete_event",
    G_CALLBACK(mess_destroy_ca), ca);

  big_hbox = gtk_hbox_new (FALSE, 12);
  gtk_container_add (GTK_CONTAINER(ca->window), big_hbox);

  vbox = gtk_vbox_new(FALSE, 6);
  gtk_box_pack_start (GTK_BOX(big_hbox), vbox, FALSE, FALSE, 0);

  /* Title */
  hbox = gtk_hbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);

  label = gtk_label_new(_("Title: "));
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

  ca->entry = gtk_entry_new();
  gtk_box_pack_start(GTK_BOX(hbox), ca->entry, TRUE, TRUE, 0);
  gaim_set_accessible_label (ca->entry, label);
  gtk_widget_grab_focus(ca->entry);

  /* Toolbar */
  ca->toolbar = gtk_imhtmltoolbar_new();
  gtk_box_pack_start(GTK_BOX(vbox), ca->toolbar, FALSE, FALSE, 0);

      /* Text */
  sw = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
    GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN);
  gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);

  ca->text = gtk_imhtml_new(NULL, NULL);
  gtk_imhtml_set_editable(GTK_IMHTML(ca->text), TRUE);
  gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(ca->text), GTK_WRAP_WORD_CHAR);

  gtk_imhtml_smiley_shortcuts(GTK_IMHTML(ca->text),
    gaim_prefs_get_bool("/gaim/gtk/conversations/smiley_shortcuts"));
  gtk_imhtml_html_shortcuts(GTK_IMHTML(ca->text),
    gaim_prefs_get_bool("/gaim/gtk/conversations/html_shortcuts"));
  if (gaim_prefs_get_bool("/gaim/gtk/conversations/spellcheck"))
    gaim_gtk_setup_gtkspell(GTK_TEXT_VIEW(ca->text));
  gtk_imhtmltoolbar_attach(GTK_IMHTMLTOOLBAR(ca->toolbar), ca->text);

  gtk_container_add(GTK_CONTAINER(sw), ca->text);

  /* Set the text values */
  gtk_entry_set_text(GTK_ENTRY(ca->entry), strdup (title));
  gtk_imhtml_append_text_with_images(GTK_IMHTML(ca->text), 
    strdup (message), 0, NULL);
  ca->orig_title = strdup (title);
  ca->orig_text = strdup (message);

  hbox = gtk_hbox_new(FALSE, 6);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);

  button = gaim_pixbuf_button_from_stock(_("Save"), 
    GTK_STOCK_SAVE, GAIM_BUTTON_HORIZONTAL);
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(save_mess), ca);
  gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);

  button = gaim_pixbuf_button_from_stock(_("Cancel"), 
    GTK_STOCK_CANCEL, GAIM_BUTTON_HORIZONTAL);
  g_signal_connect(G_OBJECT(button), "clicked", 
    G_CALLBACK(mess_destroy), ca);
  gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);

  /* Display component options */
  vbox = gtk_vbox_new (FALSE, 5);
  gtk_box_pack_start (GTK_BOX(big_hbox), vbox, FALSE, FALSE, 0);

  label = gtk_label_new (_("\%a Added text (Away messages)"));
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
  gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 0);
  label = gtk_label_new (_("\%\% Percent sign"));
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
  gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 0);
  label = gtk_label_new (_("\%n Buddy's name (AIM only)"));
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
  gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 0);
  label = gtk_label_new (_("\%t Current time (AIM only)"));
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
  gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 0);
  label = gtk_label_new (_("\%d Current date (AIM only)"));
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
  gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 0);

  cur_comp_node = components;
  while (cur_comp_node) {
    cur_comp = (struct component *)cur_comp_node->data;
    buf = (char *)malloc(101);
    g_snprintf (buf, 100, "%%%c %s", 
      cur_comp->format_char, cur_comp->id);
    label = gtk_label_new (buf);
    gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
    gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 0);
    cur_comp_node = cur_comp_node->next;
  }

  gtk_widget_show_all(ca->window);
}

/* Callback for the button */
static void edit_msg ()
{
  GtkTreeSelection *selection;
  GtkTreeModel *model;
  GtkTreeIter iter;
  gchar *message, *title;

  GList *cur_title, *cur_message, *title_start, *message_start;

  /* Figure out which component is selected */
  selection = gtk_tree_view_get_selection (
    GTK_TREE_VIEW (message_view));
  
  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
    gtk_tree_model_get (model, &iter, 0, &title, -1);

    cur_title = gaim_prefs_get_string_list (
      "/plugins/gtk/autoprofile/message_titles");
    cur_message = gaim_prefs_get_string_list (
      "/plugins/gtk/autoprofile/message_texts");
    title_start = cur_title;
    message_start = cur_message;

    /* Search for the associated message */
    while (TRUE) {
      if (cur_title == NULL) {
        free_string_list (title_start);
        free_string_list (message_start);
        return;
      }
      if (!strcmp (title, (char *)cur_title->data)) {
        message = (char *)cur_message->data;
        break;
      }

      cur_title = cur_title->next;
      cur_message = cur_message->next;
    }
    gtk_edit_msg (title, message);
    free_string_list (title_start);
    free_string_list (message_start);
  }
}

/*--------------- Generate the preference widget once ----------------*/
GaimGtkPluginUiInfo ui_info = 
{ 
  get_config_frame
};





Generated by  Doxygen 1.6.0   Back to index