/*
 *  shortcuts.c:	
 *
 *  Written by:		Ullrich Hafner
 *  
 *  Copyright (C) 1998 Ullrich Hafner <hafner@bigfoot.de>
 *
 *  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, USA.
 */


/*
 *  $Date: 2000/09/03 19:22:04 $
 *  $Author: hafner $
 *  $Revision: 1.19 $
 *  $State: Exp $
 */

#include "config.h"

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include "proplist_t.h"

#include "keys.h"
#include "misc.h"
#include "dialog.h"
#include "shortcuts.h"
#include "simple.h"
#include "menu.h"
#include "themebrowser.h"

#include "error.h"

/*******************************************************************************

				global variables
  
*******************************************************************************/

extern proplist_t wmconfig;		/* from window.c */
extern proplist_t windowmaker;		/* from window.c */
extern bool_t	   changed;		/* from window.c */
extern GtkTooltips *tooltips;

/*******************************************************************************

				local variables
  
*******************************************************************************/

static GtkWidget *box_shortcut_widget = NULL;
static GtkWidget *shortcut_widget     = NULL;

/*******************************************************************************

				prototypes
  
*******************************************************************************/

static void
key_changed (const key_widget_t *data);
static void
set_string (GtkWidget *widget, gpointer ptr);
static void
selection_made (GtkCList *clist, gint row, gint column, GdkEvent *event,
		gpointer data);
static void
update_shortcut (proplist_t key, gpointer ptr, proplist_t value,
		 const char *path);

/*******************************************************************************

				public code
  
*******************************************************************************/

void
add_shortcut (GtkWidget *page, proplist_t key)
{
   static GtkWidget *clist = NULL;

   if (!clist)
   {
      GtkWidget *dialog;
      GtkWidget *scrolled;
      GtkWidget *vbox;
      GtkWidget *hhbox;
      
      dialog = hhbox = gtk_hbox_new (FALSE, 5);
      gtk_box_pack_start (GTK_BOX (page), hhbox, TRUE, TRUE, 5);

      /*
       *  Clist for all available keys
       */
      {
	 char *title = _("Actions");

	 clist = gtk_clist_new_with_titles (1, &title);
	 gtk_clist_column_titles_passive (GTK_CLIST (clist));
	 gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_BROWSE);
	 gtk_signal_connect (GTK_OBJECT (clist), "select_row",
			     GTK_SIGNAL_FUNC (selection_made), NULL);
	 gtk_clist_set_column_auto_resize (GTK_CLIST (clist), 0, YES);

	 /*
	  *  Scrolled window for clist
	  */
	 scrolled = gtk_scrolled_window_new (NULL, NULL);
	 gtk_widget_set_usize (scrolled, 250, -1);
	 gtk_container_set_border_width (GTK_CONTAINER (scrolled), 5);
	 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
					 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
	 gtk_container_add (GTK_CONTAINER (scrolled), clist);

	 gtk_box_pack_start (GTK_BOX (hhbox), scrolled, TRUE, TRUE, 0);
      }
      
      vbox = gtk_vbox_new (FALSE, 5);
      gtk_box_pack_start (GTK_BOX (hhbox), vbox, FALSE, FALSE, 5);
 
      /*
       *  Shortcut
       */
      {
	 GtkWidget *frame;
	 GtkWidget *box;
	 
	 box_shortcut_widget = frame = gtk_frame_new (_("Shortcut"));
	 gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5);
	 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 5);

	 box = gtk_hbox_new (FALSE, 5);
	 gtk_container_add (GTK_CONTAINER (frame), box);
	 gtk_container_set_border_width (GTK_CONTAINER (box), 5);
      
	 shortcut_widget = key_dialog ("None", tooltips, NULL, key_changed, key);
	 gtk_box_pack_start (GTK_BOX (box), shortcut_widget, TRUE, TRUE, 5);
      }

      /*
       *  Top of window: Modifier key definition
       */
      {
 	 proplist_t plmod   = WMCreatePLString ("ModifierKey");
	 proplist_t pltitle = WMCreatePLString ("Title");
	 proplist_t keydef  = WMGetFromPLDictionary (wmconfig, plmod);
	 proplist_t title   = WMGetFromPLDictionary (keydef, pltitle);
	 GtkWidget  *frame;
	 
	 frame = gtk_frame_new (D_(WMGetFromPLString (title)));
	 gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5);
	 gtk_box_pack_end (GTK_BOX (vbox), frame, FALSE, FALSE, 5);
	 
	 /*
	  *  Get list of valid modifiers
	  */
	 {
	    const char **available = modifier_list ();
	    GtkWidget  *option_menu;

	    {
	       GtkWidget *ohbox =  gtk_hbox_new (TRUE, 0);
	       option_menu
		  = generate_option_menu (NULL, tooltips, NULL,
					  available,
					  WMGetFromPLString (WMGetFromPLDictionary (windowmaker, plmod)), NULL, set_string, WMShallowCopyPropList (plmod));
	       gtk_box_pack_start (GTK_BOX (ohbox), option_menu, FALSE, FALSE, 0);
	       gtk_container_add (GTK_CONTAINER (frame), ohbox);
	       gtk_container_set_border_width (GTK_CONTAINER (ohbox), 5);
	    }
	    {
	       omenudata_t *data = Calloc (1, sizeof (omenudata_t));
      
	       data->omenu  = GTK_OPTION_MENU (option_menu);
	       data->values = available;
	       connect_update_function (plmod, data, update_optionmenu);
	    }
	 }
	 WMReleasePropList (plmod);
      }
	    
      gtk_widget_show_all (dialog);
   }
   
   {
      proplist_t plinfo   = WMCreatePLString ("Info");
      proplist_t keydef   = WMGetFromPLDictionary (wmconfig, key);
      proplist_t info     = WMGetFromPLDictionary (keydef, plinfo);
      char 	 *keyname = D_(WMGetFromPLString (info));
      
      gtk_clist_insert (GTK_CLIST (clist), GTK_CLIST (clist)->rows, &keyname);
      gtk_clist_set_row_data (GTK_CLIST (clist),
			      GTK_CLIST (clist)->rows - 1, key);
      if (GTK_CLIST (clist)->rows == 1)
	 gtk_clist_select_row (GTK_CLIST (clist), 0, 0);

      gtk_clist_sort(GTK_CLIST (clist));	 
   }
   connect_update_function (key, clist, update_shortcut);
}

/*******************************************************************************

				private code
  
*******************************************************************************/

static void
key_changed (const key_widget_t *data)
{
   WMPutInPLDictionary (windowmaker, (proplist_t) data->data,
			    WMCreatePLString (data->keytext));
   toggle_save (changed = YES, (proplist_t) data->data);
}

static void
set_string (GtkWidget *widget, gpointer ptr)
/*
 *  Update string value of ModifierKey set with option_menu.
 *
 *  No return value.
 */
{
   proplist_t key   = (proplist_t) ptr;
   char       *text = gtk_object_get_user_data (GTK_OBJECT (widget));
   
   WMPutInPLDictionary (windowmaker, key, WMCreatePLString (text));
   toggle_save (changed = YES, key);
}

static void
selection_made (GtkCList *clist, gint row, gint column, GdkEvent *event,
		gpointer data)
/*
 *  Update keywidget and label if new keyboard action is selected.
 *
 *  No return value.
 */
{
   proplist_t key = gtk_clist_get_row_data (clist, row);

   if (key)
   {
      key_widget_t *data;

      data 	    = gtk_object_get_user_data (GTK_OBJECT (shortcut_widget));
      data->data = key;
	 
      update_keywidget (data,
			WMGetFromPLString (WMGetFromPLDictionary (windowmaker, key)));
   }
}

static void
update_shortcut (proplist_t key, gpointer ptr, proplist_t value,
		 const char *path)
{
   if (WMIsPLString (value))
   {
      GtkCList   *clist  = GTK_CLIST (ptr);
      gint	 row     = GPOINTER_TO_INT (GTK_CLIST (clist)->selection->data);
      proplist_t rowkey  = gtk_clist_get_row_data (clist, row);
      
      WMPutInPLDictionary (windowmaker, key, value);

      if (WMIsPropListEqualTo (rowkey, key))
      {
	 if (row)
	    selection_made (clist, 0, 0, NULL, NULL);
	 else
	    selection_made (clist, 1, 0, NULL, NULL);
	 
	 selection_made (clist, row, 0, NULL, NULL);

	 message (WMGetFromPLString (key));
      }
   }
}

