summaryrefslogtreecommitdiff
path: root/mini-commander/src
diff options
context:
space:
mode:
Diffstat (limited to 'mini-commander/src')
-rw-r--r--mini-commander/src/Makefile.am115
-rw-r--r--mini-commander/src/about.c56
-rw-r--r--mini-commander/src/about.h4
-rw-r--r--mini-commander/src/browser-mini.xpm11
-rw-r--r--mini-commander/src/cmd_completion.c246
-rw-r--r--mini-commander/src/cmd_completion.h34
-rw-r--r--mini-commander/src/command_line.c598
-rw-r--r--mini-commander/src/command_line.h41
-rw-r--r--mini-commander/src/exec.c93
-rw-r--r--mini-commander/src/exec.h35
-rw-r--r--mini-commander/src/help.c42
-rw-r--r--mini-commander/src/help.h4
-rw-r--r--mini-commander/src/history-mini.xpm11
-rw-r--r--mini-commander/src/history.c144
-rw-r--r--mini-commander/src/history.h6
-rw-r--r--mini-commander/src/macro.c155
-rw-r--r--mini-commander/src/macro.h42
-rw-r--r--mini-commander/src/mate-mini-commander.pngbin0 -> 703 bytes
-rw-r--r--mini-commander/src/mc-default-macros.h65
-rw-r--r--mini-commander/src/mc-install-default-macros.c179
-rw-r--r--mini-commander/src/mini-commander-applet-menu.xml4
-rw-r--r--mini-commander/src/mini-commander-global.schemas.in31
-rw-r--r--mini-commander/src/mini-commander.schemas.in193
-rw-r--r--mini-commander/src/mini-commander.ui713
-rw-r--r--mini-commander/src/mini-commander_applet.c430
-rw-r--r--mini-commander/src/mini-commander_applet.h72
-rw-r--r--mini-commander/src/org.mate.applets.MiniCommanderApplet.mate-panel-applet.in.in16
-rw-r--r--mini-commander/src/org.mate.panel.applet.MiniCommanderAppletFactory.service.in3
-rw-r--r--mini-commander/src/preferences.c1128
-rw-r--r--mini-commander/src/preferences.h109
30 files changed, 4580 insertions, 0 deletions
diff --git a/mini-commander/src/Makefile.am b/mini-commander/src/Makefile.am
new file mode 100644
index 00000000..1eace378
--- /dev/null
+++ b/mini-commander/src/Makefile.am
@@ -0,0 +1,115 @@
+## Process this file with automake to produce Makefile.in
+
+INCLUDES = \
+ -I. \
+ -I$(srcdir) \
+ -DMC_MENU_UI_DIR=\""$(uidir)"\" \
+ $(MATE_APPLETS3_CFLAGS) \
+ $(WARN_CFLAGS) \
+ $(MATE_INCLUDEDIR)
+
+libexec_PROGRAMS = mini_commander_applet
+
+tooldir = $(libexecdir)/mate-applets
+tool_PROGRAMS = mc-install-default-macros
+
+mini_commander_applet_SOURCES = \
+ about.c \
+ about.h \
+ cmd_completion.c \
+ cmd_completion.h \
+ command_line.c \
+ command_line.h \
+ exec.c \
+ exec.h \
+ mini-commander_applet.c \
+ mini-commander_applet.h \
+ help.c \
+ help.h \
+ history.c \
+ history.h \
+ macro.c \
+ macro.h \
+ preferences.c \
+ preferences.h \
+ mc-default-macros.h
+
+mini_commander_applet_LDADD = \
+ $(MATE_APPLETS3_LIBS)
+
+mc_install_default_macros_SOURCES = \
+ mc-install-default-macros.c \
+ mc-default-macros.h
+
+mc_install_default_macros_LDADD = \
+ $(MATE_APPLETS_LIBS)
+
+builder_DATA = mini-commander.ui
+
+BITMAPS = \
+ browser-mini.xpm \
+ history-mini.xpm
+
+desktop_iconsdir = $(iconsdir)/hicolor/48x48/apps
+desktop_icons_DATA = mate-mini-commander.png
+
+gtk_update_icon_cache = gtk-update-icon-cache -f -t $(iconsdir)/hicolor
+install-data-hook: update-icon-cache
+uninstall-hook: update-icon-cache
+update-icon-cache:
+ @-if test -z "$(DESTDIR)"; then \
+ echo "Updating Gtk icon cache."; \
+ $(gtk_update_icon_cache); \
+ else \
+ echo "*** Icon cache not updated. After (un)install, run this:"; \
+ echo "*** $(gtk_update_icon_cache)"; \
+ fi
+
+appletdir = $(datadir)/mate-panel/applets
+applet_in_files = org.mate.applets.MiniCommanderApplet.mate-panel-applet.in
+applet_DATA = $(applet_in_files:.mate-panel-applet.in=.mate-panel-applet)
+
+$(applet_in_files): $(applet_in_files).in Makefile
+ $(AM_V_GEN)sed \
+ -e "s|\@LIBEXECDIR\@|$(libexecdir)|" \
+ -e "s|\@VERSION\@|$(PACKAGE_VERSION)|" \
+ $< > $@
+
+%.mate-panel-applet: %.mate-panel-applet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+servicedir = $(datadir)/dbus-1/services
+service_in_files = org.mate.panel.applet.MiniCommanderAppletFactory.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+org.mate.panel.applet.MiniCommanderAppletFactory.service: $(service_in_files)
+ $(AM_V_GEN)sed \
+ -e "s|\@LIBEXECDIR\@|$(libexecdir)|" \
+ $< > $@
+
+CLEANFILES = $(applet_DATA) $(applet_DATA).in $(service_DATA) $(schemas_DATA)
+
+schemasdir = @MATECONF_SCHEMA_FILE_DIR@
+schemas_in_files = mini-commander.schemas.in mini-commander-global.schemas.in
+schemas_DATA = $(schemas_in_files:.schemas.in=.schemas)
+
+@INTLTOOL_SCHEMAS_RULE@
+
+uidir = $(datadir)/mate-2.0/ui
+ui_DATA = mini-commander-applet-menu.xml
+
+if MATECONF_SCHEMAS_INSTALL
+install-data-local:
+ MATECONF_CONFIG_SOURCE=$(MATECONF_SCHEMA_CONFIG_SOURCE) $(MATECONFTOOL) --makefile-install-rule $(schemas_DATA) ;
+ MATECONF_CONFIG_SOURCE=$(MATECONF_SCHEMA_CONFIG_SOURCE) $(top_builddir)/mini-commander/src/mc-install-default-macros
+endif
+
+EXTRA_DIST = \
+ org.mate.applets.MiniCommanderApplet.mate-panel-applet.in.in \
+ $(service_in_files) \
+ $(desktop_icons_DATA) \
+ $(BITMAPS) \
+ $(ui_DATA) \
+ $(builder_DATA) \
+ $(schemas_in_files)
+
+-include $(top_srcdir)/git.mk
diff --git a/mini-commander/src/about.c b/mini-commander/src/about.c
new file mode 100644
index 00000000..d862d4ed
--- /dev/null
+++ b/mini-commander/src/about.c
@@ -0,0 +1,56 @@
+/*
+ * Mini-Commander Applet
+ * Copyright (C) 1998, 1999 Oliver Maruhn <[email protected]>
+ *
+ * Author: Oliver Maruhn <[email protected]>
+ *
+ * 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 <config.h>
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "about.h"
+
+void about_box (GtkAction *action,
+ MCData *mcdata)
+{
+ static const gchar *authors[] = {
+ "Oliver Maruhn <[email protected]>",
+ "Mark McLoughlin <[email protected]>",
+ NULL
+ };
+
+ const gchar *documenters[] = {
+ "Dan Mueth <[email protected]>",
+ "Oliver Maruhn <[email protected]>",
+ "Sun MATE Documentation Team <[email protected]>",
+ NULL
+ };
+
+ gtk_show_about_dialog (NULL,
+ "version", VERSION,
+ "copyright", "\xc2\xa9 1998-2005 Oliver Maruhn and others",
+ "comments", _("This MATE applet adds a command line to "
+ "the panel. It features command completion, "
+ "command history, and changeable macros."),
+ "authors", authors,
+ "documenters", documenters,
+ "translator-credits", _("translator-credits"),
+ "logo-icon-name", "mate-mini-commander",
+ NULL);
+}
diff --git a/mini-commander/src/about.h b/mini-commander/src/about.h
new file mode 100644
index 00000000..875ea62d
--- /dev/null
+++ b/mini-commander/src/about.h
@@ -0,0 +1,4 @@
+#include "mini-commander_applet.h"
+
+void about_box (GtkAction *action,
+ MCData *mcdata);
diff --git a/mini-commander/src/browser-mini.xpm b/mini-commander/src/browser-mini.xpm
new file mode 100644
index 00000000..6fb6b7fb
--- /dev/null
+++ b/mini-commander/src/browser-mini.xpm
@@ -0,0 +1,11 @@
+/* XPM */
+static const char * browser_mini_xpm[] = {
+"7 6 2 1",
+" c NONE",
+". c #000000000000",
+" ... ",
+" ..... ",
+" ..... ",
+" ..... ",
+" ... ",
+" "};
diff --git a/mini-commander/src/cmd_completion.c b/mini-commander/src/cmd_completion.c
new file mode 100644
index 00000000..7b91ff5b
--- /dev/null
+++ b/mini-commander/src/cmd_completion.c
@@ -0,0 +1,246 @@
+/*
+ * Mini-Commander Applet
+ * Copyright (C) 1998, 1999 Oliver Maruhn <[email protected]>
+ *
+ * Author: Oliver Maruhn <[email protected]>
+ *
+ * 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
+ */
+
+/*
+ If you expect tons of C code for command completion then you will
+ probably be astonished...
+
+ These routines have probably to be rewritten in future. But they
+ should work on every system with a bash-alike shell.
+*/
+
+#include <config.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <mate-panel-applet.h>
+
+#include <sys/stat.h>
+#include <dirent.h>
+
+#include "cmd_completion.h"
+#include "preferences.h"
+#include "macro.h"
+
+
+static GList* cmdc( char* );
+static void process_dir( const gchar* );
+static void cleanup( void );
+static gint g_list_str_cmp( gconstpointer, gconstpointer );
+
+/* global declaration so g_atexit() can reference it to free it.
+ * (not strictly necessary).
+ */
+static GList *path_elements = NULL;
+
+void
+mc_cmd_completion (MCData *mc,
+ char *cmd)
+{
+ char buffer[MC_MAX_COMMAND_LENGTH] = "";
+ char largest_possible_completion[MC_MAX_COMMAND_LENGTH] = "";
+ int num_whitespaces, i, pos;
+
+ GList *possible_completions_list = NULL;
+ GList *completion_element;
+
+
+ if(strlen(cmd) == 0)
+ {
+ return;
+ }
+
+ num_whitespaces = mc_macro_prefix_len_wspace (mc, cmd) - mc_macro_prefix_len (mc, cmd);
+ possible_completions_list = cmdc(cmd + mc_macro_prefix_len_wspace (mc, cmd));
+
+ /* get first possible completion */
+ completion_element = g_list_first(possible_completions_list);
+ if(completion_element)
+ strcpy(largest_possible_completion, (char *) completion_element->data);
+ else
+ strcpy(largest_possible_completion, "");
+
+ /* get the rest */
+ while((completion_element = g_list_next(completion_element)))
+ {
+ strcpy(buffer, (char *) completion_element->data);
+ pos = 0;
+ while(largest_possible_completion[pos] != '\000'
+ && buffer[pos] != '\000'
+ && strncmp(largest_possible_completion, buffer, pos + 1) == 0)
+ pos++;
+ strncpy(largest_possible_completion, buffer, pos);
+ /* strncpy does not add \000 to the end */
+ largest_possible_completion[pos] = '\000';
+ }
+
+ if(strlen(largest_possible_completion) > 0)
+ {
+ if(mc_macro_get_prefix(mc, cmd) != NULL)
+ strcpy(cmd, mc_macro_get_prefix(mc, cmd));
+ else
+ strcpy(cmd, "");
+
+ /* fill up the whitespaces */
+ for(i = 0; i < num_whitespaces; i++)
+ strcat(cmd, " ");
+
+ strcat(cmd, largest_possible_completion);
+ }
+}
+
+/*
+ * cmdc() -- command completion function.
+ *
+ * cmdc takes a char* and returns a GList* of possible completions.
+ *
+ * Initial version by Travis Hume <[email protected]>.
+ *
+ */
+static GList *
+cmdc( char *s )
+{
+ GCompletion *completion = NULL;
+ GList *ret_list = NULL;
+ static GHashTable *path_hash = NULL;
+ static char *path = NULL;
+ gchar *path_elem;
+ struct stat buf;
+ static gboolean inited = FALSE;
+ gpointer hash_key = NULL;
+
+
+ /*
+ * Only want to build the GCompletion once. At some point I'd like to add
+ * code to refresh the GCompletion, either at a regular interval, or when
+ * there is a completion failure, ...
+ *
+ */
+ if(!inited)
+ {
+ /* Make a local copy of the path variable. Otherwise the path
+ environment variable would be modified. */
+ path = (char *) malloc(sizeof(char) * (strlen(getenv("PATH")) + 1));
+ strcpy(path, getenv("PATH"));
+
+ path_hash = g_hash_table_new( g_str_hash, g_str_equal );
+
+ for( path_elem = strtok( path, ":" ); path_elem;
+ path_elem = strtok( NULL, ":" ))
+ {
+ if( stat( path_elem, &buf ))
+ continue;
+
+ if( buf.st_mode & S_IFDIR )
+ {
+ /* keep a hash of processed paths, to avoid reprocessing
+ * dupped path entries.
+ */
+ hash_key = g_hash_table_lookup( path_hash, path_elem );
+ if( hash_key )
+ continue; /* duplicate $PATH entry */
+ else
+ {
+ g_hash_table_insert(
+ path_hash, (gpointer)path_elem, (gpointer)path_elem );
+
+ process_dir( path_elem );
+ }
+ }
+ }
+
+ /* atexit() we want to free the completion. */
+ g_atexit( cleanup );
+
+ inited = TRUE;
+ }
+
+ completion = g_completion_new( NULL );
+ g_completion_add_items( completion, path_elements );
+ ret_list = g_list_copy( g_completion_complete( completion, s, NULL ));
+ g_completion_free( completion );
+
+ return g_list_sort( ret_list, (GCompareFunc)g_list_str_cmp );
+}
+
+
+/*
+ * Compare function to return a sorted completion.
+ */
+static gint
+g_list_str_cmp( gconstpointer a, gconstpointer b )
+{
+ return( strcmp( (char *)a, (char *)b ));
+}
+
+
+
+/*
+ * Reads directory entries and adds non-dir, executable files
+ * to the GCompletion.
+ * Initial version by Travis Hume <[email protected]>.
+ */
+static void
+process_dir( const char *d )
+{
+ DIR *dir;
+ struct dirent *de;
+ struct stat buf;
+ gpointer data;
+ gchar *path_str;
+
+
+ if( (dir = opendir( d )) == NULL )
+ return;
+
+ while( (de = readdir( dir )) != NULL )
+ {
+ if( strcmp( de->d_name, "." ) == 0 || strcmp( de->d_name, "..") == 0)
+ continue;
+
+ path_str = (gchar *)g_malloc( strlen( d ) + 1 + strlen( de->d_name ) + 1);
+ strcpy( path_str, d );
+ strcat( path_str, "/" );
+ strcat( path_str, de->d_name );
+ if( stat( path_str, &buf ) != 0)
+ continue;
+ g_free( (gpointer)path_str );
+
+ if( S_ISDIR( buf.st_mode ) )
+ continue;
+
+ data = g_malloc( strlen( (gchar *)de->d_name ) + 1 );
+ strcpy( (gchar *)data, (gchar *)(de->d_name) );
+ if( buf.st_mode & S_IXUSR )
+ path_elements = g_list_append( path_elements, data );
+ }
+ closedir( dir );
+}
+
+
+/*
+ * cleanup() -- free the memory used by the GCompletion.
+ */
+static void
+cleanup( void )
+{
+ g_list_free( path_elements );
+}
diff --git a/mini-commander/src/cmd_completion.h b/mini-commander/src/cmd_completion.h
new file mode 100644
index 00000000..042092fe
--- /dev/null
+++ b/mini-commander/src/cmd_completion.h
@@ -0,0 +1,34 @@
+/*
+ * Mini-Commander Applet
+ * Copyright (C) 1998 Oliver Maruhn <[email protected]>
+ *
+ * Author: Oliver Maruhn <[email protected]>
+ *
+ * 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
+ */
+#ifndef __CMD_COMPLETION_H__
+#define __CMD_COMPLETION_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#include "mini-commander_applet.h"
+
+void mc_cmd_completion (MCData *mc, char *cmd);
+
+G_END_DECLS
+
+#endif /* __CMD_COMPLETION_H__ */
diff --git a/mini-commander/src/command_line.c b/mini-commander/src/command_line.c
new file mode 100644
index 00000000..ef0c8d17
--- /dev/null
+++ b/mini-commander/src/command_line.c
@@ -0,0 +1,598 @@
+/*
+ * Mini-Commander Applet
+ * Copyright (C) 1998, 1999 Oliver Maruhn <[email protected]>
+ *
+ * Author: Oliver Maruhn <[email protected]>
+ *
+ * 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 <config.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include <mate-panel-applet.h>
+
+#include "mini-commander_applet.h"
+#include "command_line.h"
+#include "preferences.h"
+#include "exec.h"
+#include "cmd_completion.h"
+#include "history.h"
+
+static gint file_browser_response_signal(GtkWidget *widget, gint response, gpointer mc_data);
+static gint history_popup_clicked_cb(GtkWidget *widget, gpointer data);
+static gint history_popup_clicked_inside_cb(GtkWidget *widget, gpointer data);
+static gchar* history_auto_complete(GtkWidget *widget, GdkEventKey *event);
+
+
+static int history_position = MC_HISTORY_LIST_LENGTH;
+static gchar *browsed_folder = NULL;
+
+static gboolean
+button_press_cb (GtkEntry *entry,
+ GdkEventButton *event,
+ MCData *mc)
+{
+ const gchar *str;
+
+ mate_panel_applet_request_focus (mc->applet, event->time);
+
+ if (mc->error) {
+ mc->error = FALSE;
+ str = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
+ gtk_entry_set_text (entry, (gchar *) str + 3);
+ }
+ return FALSE;
+}
+
+static gboolean
+command_key_event (GtkEntry *entry,
+ GdkEventKey *event,
+ MCData *mc)
+{
+ guint key = event->keyval;
+ char *command;
+ static char current_command[MC_MAX_COMMAND_LENGTH];
+ char buffer[MC_MAX_COMMAND_LENGTH];
+ gboolean propagate_event = TRUE;
+ const gchar *str;
+
+ if (mc->error) {
+ mc->error = FALSE;
+ str = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
+ gtk_entry_set_text (entry, (gchar *) str + 3);
+ gtk_editable_set_position (GTK_EDITABLE (entry), strlen (str));
+ }
+ if(key == GDK_Tab
+ || key == GDK_KP_Tab
+ || key == GDK_ISO_Left_Tab)
+ {
+ if(event->state == GDK_CONTROL_MASK)
+ {
+ /*
+ * Move focus to the next widget (browser) button.
+ */
+ gtk_widget_child_focus (GTK_WIDGET (mc->applet), GTK_DIR_TAB_FORWARD);
+ propagate_event = FALSE;
+ }
+ else if(event->state != GDK_SHIFT_MASK)
+ {
+ /* tab key pressed */
+ strcpy(buffer, (char *) gtk_entry_get_text(GTK_ENTRY(entry)));
+ mc_cmd_completion (mc, buffer);
+ gtk_entry_set_text(GTK_ENTRY(entry), (gchar *) buffer);
+
+ propagate_event = FALSE;
+ }
+ }
+ else if(key == GDK_Up
+ || key == GDK_KP_Up
+ || key == GDK_ISO_Move_Line_Up
+ || key == GDK_Pointer_Up)
+ {
+ /* up key pressed */
+ if(history_position == MC_HISTORY_LIST_LENGTH)
+ {
+ /* store current command line */
+ strcpy(current_command, (char *) gtk_entry_get_text(entry));
+ }
+ if(history_position > 0 && exists_history_entry(history_position - 1))
+ {
+ gtk_entry_set_text(entry, (gchar *) get_history_entry(--history_position));
+ }
+
+ propagate_event = FALSE;
+ }
+ else if(key == GDK_Down
+ || key == GDK_KP_Down
+ || key == GDK_ISO_Move_Line_Down
+ || key == GDK_Pointer_Down)
+ {
+ /* down key pressed */
+ if(history_position < MC_HISTORY_LIST_LENGTH - 1)
+ {
+ gtk_entry_set_text(entry, (gchar *) get_history_entry(++history_position));
+ }
+ else if(history_position == MC_HISTORY_LIST_LENGTH - 1)
+ {
+ gtk_entry_set_text(entry, (gchar *) current_command);
+ ++history_position;
+ }
+
+ propagate_event = FALSE;
+ }
+ else if(key == GDK_Return
+ || key == GDK_KP_Enter
+ || key == GDK_ISO_Enter
+ || key == GDK_3270_Enter)
+ {
+ /* enter pressed -> exec command */
+ command = (char *) malloc(sizeof(char) * MC_MAX_COMMAND_LENGTH);
+ strcpy(command, (char *) gtk_entry_get_text(entry));
+ mc_exec_command(mc, command);
+
+ history_position = MC_HISTORY_LIST_LENGTH;
+ free(command);
+
+ strcpy(current_command, "");
+ propagate_event = FALSE;
+ }
+ else if (mc->preferences.auto_complete_history && key >= GDK_space && key <= GDK_asciitilde )
+ {
+ char *completed_command;
+ gint current_position = gtk_editable_get_position(GTK_EDITABLE(entry));
+
+ if(current_position != 0)
+ {
+ gtk_editable_delete_text( GTK_EDITABLE(entry), current_position, -1 );
+ completed_command = history_auto_complete(GTK_WIDGET (entry), event);
+
+ if(completed_command != NULL)
+ {
+ gtk_entry_set_text(entry, completed_command);
+ gtk_editable_set_position(GTK_EDITABLE(entry), current_position + 1);
+ propagate_event = FALSE;
+ }
+ }
+ }
+
+ return !propagate_event;
+}
+
+static gint
+history_popup_clicked_cb(GtkWidget *widget, gpointer data)
+{
+ gdk_pointer_ungrab(GDK_CURRENT_TIME);
+ gdk_keyboard_ungrab(GDK_CURRENT_TIME);
+ gtk_grab_remove(GTK_WIDGET(widget));
+ gtk_widget_destroy(GTK_WIDGET(widget));
+ widget = NULL;
+
+ /* go on */
+ return (FALSE);
+}
+
+static gint
+history_popup_clicked_inside_cb(GtkWidget *widget, gpointer data)
+{
+ /* eat signal (prevent that popup will be destroyed) */
+ return(TRUE);
+}
+
+static gboolean
+history_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer data)
+{
+ if (event->keyval == GDK_Escape) {
+ gdk_pointer_ungrab(GDK_CURRENT_TIME);
+ gdk_keyboard_ungrab(GDK_CURRENT_TIME);
+ gtk_grab_remove(GTK_WIDGET(widget));
+ gtk_widget_destroy(GTK_WIDGET(widget));
+ widget = NULL;
+ }
+
+ return FALSE;
+
+}
+
+static gboolean
+history_list_key_press_cb (GtkWidget *widget,
+ GdkEventKey *event,
+ MCData *mc)
+{
+ GtkTreeView *tree = g_object_get_data (G_OBJECT (mc->applet), "tree");
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ gchar *command;
+
+ switch (event->keyval) {
+ case GDK_KP_Enter:
+ case GDK_ISO_Enter:
+ case GDK_3270_Enter:
+ case GDK_Return:
+ case GDK_space:
+ case GDK_KP_Space:
+ if ((event->state & GDK_CONTROL_MASK) &&
+ (event->keyval == GDK_space || event->keyval == GDK_KP_Space))
+ break;
+
+ if (!gtk_tree_selection_get_selected (gtk_tree_view_get_selection (tree),
+ &model,
+ &iter))
+ return FALSE;
+ gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
+ 0, &command, -1);
+ mc_exec_command (mc, command);
+ g_free (command);
+ gtk_widget_destroy(GTK_WIDGET(widget->parent->parent->parent));
+
+ return TRUE;
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+history_list_button_press_cb (GtkWidget *widget,
+ GdkEventButton *event,
+ MCData *mc)
+{
+ GtkTreeView *tree = g_object_get_data (G_OBJECT (mc->applet), "tree");
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ gchar *command;
+
+ if (event->type == GDK_2BUTTON_PRESS) {
+ if (!gtk_tree_selection_get_selected (gtk_tree_view_get_selection (tree),
+ &model,
+ &iter))
+ return FALSE;
+ gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
+ 0, &command, -1);
+ mc_exec_command(mc, command);
+ g_free (command);
+ gtk_widget_destroy(GTK_WIDGET(widget->parent->parent->parent));
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+int
+mc_show_history (GtkWidget *widget,
+ MCData *mc)
+{
+ GtkWidget *window;
+ GtkWidget *frame;
+ GtkWidget *scrolled_window;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ GtkWidget *treeview;
+ GtkCellRenderer *cell_renderer;
+ GtkTreeViewColumn *column;
+ GtkRequisition req;
+ gchar *command_list[1];
+ int i, j;
+ gint x, y, width, height, screen_width, screen_height;
+
+ /* count commands stored in history list */
+ for(i = 0, j = 0; i < MC_HISTORY_LIST_LENGTH; i++)
+ if(exists_history_entry(i))
+ j++;
+
+ window = gtk_window_new(GTK_WINDOW_POPUP);
+ gtk_window_set_screen (GTK_WINDOW (window),
+ gtk_widget_get_screen (GTK_WIDGET (mc->applet)));
+ gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
+ gtk_window_set_type_hint(GTK_WINDOW(window), GDK_WINDOW_TYPE_HINT_COMBO);
+ /* cb */
+ g_signal_connect_after(GTK_OBJECT(window),
+ "button_press_event",
+ G_CALLBACK(history_popup_clicked_cb),
+ NULL);
+ g_signal_connect_after (G_OBJECT (window), "key_press_event",
+ G_CALLBACK (history_key_press_cb), NULL);
+
+ /* size */
+ gtk_widget_set_size_request(GTK_WIDGET(window), 200, 350);
+
+
+ /* frame */
+ frame = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
+ gtk_widget_show(frame);
+ gtk_container_add(GTK_CONTAINER(window), frame);
+
+ /* scrollbars */
+ /* create scrolled window to put the Gtk_list widget inside */
+ scrolled_window=gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ g_signal_connect(GTK_OBJECT(scrolled_window),
+ "button_press_event",
+ G_CALLBACK(history_popup_clicked_inside_cb),
+ NULL);
+ gtk_container_add(GTK_CONTAINER(frame), scrolled_window);
+ gtk_container_set_border_width (GTK_CONTAINER(scrolled_window), 2);
+ gtk_widget_show(scrolled_window);
+
+ store = gtk_list_store_new (1, G_TYPE_STRING);
+
+ /* add history entries to list */
+ if (j == 0) {
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,0, _("No items in history"), -1);
+ }
+ else {
+ for(i = 0; i < MC_HISTORY_LIST_LENGTH; i++)
+ {
+ if(exists_history_entry(i))
+ {
+ command_list[0] = get_history_entry(i);
+ gtk_list_store_prepend (store, &iter);
+ gtk_list_store_set (store, &iter,0,command_list[0],-1);
+ }
+ }
+ }
+ model = GTK_TREE_MODEL(store);
+ treeview = gtk_tree_view_new_with_model (model);
+ g_object_set_data (G_OBJECT (mc->applet), "tree", treeview);
+ cell_renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes (NULL, cell_renderer,
+ "text", 0, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
+ if (j == 0) {
+ gtk_tree_selection_set_mode( (GtkTreeSelection *)gtk_tree_view_get_selection
+ (GTK_TREE_VIEW (treeview)),
+ GTK_SELECTION_NONE);
+ }
+ else {
+ gtk_tree_selection_set_mode( (GtkTreeSelection *)gtk_tree_view_get_selection
+ (GTK_TREE_VIEW (treeview)),
+ GTK_SELECTION_SINGLE);
+ g_signal_connect (G_OBJECT (treeview), "button_press_event",
+ G_CALLBACK (history_list_button_press_cb), mc);
+ g_signal_connect (G_OBJECT (treeview), "key_press_event",
+ G_CALLBACK (history_list_key_press_cb), mc);
+ }
+
+ g_object_unref (G_OBJECT (model));
+ gtk_container_add(GTK_CONTAINER(scrolled_window),treeview);
+ gtk_widget_show (treeview);
+
+ gtk_widget_size_request (window, &req);
+ gdk_window_get_origin (GTK_WIDGET (mc->applet)->window, &x, &y);
+ gdk_window_get_geometry (GTK_WIDGET (mc->applet)->window, NULL, NULL,
+ &width, &height, NULL);
+
+ switch (mate_panel_applet_get_orient (mc->applet)) {
+ case MATE_PANEL_APPLET_ORIENT_DOWN:
+ y += height;
+ break;
+ case MATE_PANEL_APPLET_ORIENT_UP:
+ y -= req.height;
+ break;
+ case MATE_PANEL_APPLET_ORIENT_LEFT:
+ x -= req.width;
+ break;
+ case MATE_PANEL_APPLET_ORIENT_RIGHT:
+ x += width;
+ break;
+ }
+
+ screen_width = gdk_screen_width ();
+ screen_height = gdk_screen_height ();
+ x = CLAMP (x - 2, 0, MAX (0, screen_width - req.width));
+ y = CLAMP (y - 2, 0, MAX (0, screen_height - req.height));
+ gtk_window_move (GTK_WINDOW (window), x, y);
+ gtk_widget_show(window);
+
+ /* grab focus */
+ gdk_pointer_grab (window->window,
+ TRUE,
+ GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_ENTER_NOTIFY_MASK
+ | GDK_LEAVE_NOTIFY_MASK
+ | GDK_POINTER_MOTION_MASK,
+ NULL,
+ NULL,
+ GDK_CURRENT_TIME);
+ gdk_keyboard_grab (window->window, TRUE, GDK_CURRENT_TIME);
+ gtk_grab_add(window);
+ gtk_widget_grab_focus (treeview);
+
+ return FALSE;
+}
+
+static gint
+file_browser_response_signal(GtkWidget *widget, gint response, gpointer mc_data)
+{
+ MCData *mc = mc_data;
+ gchar *filename;
+
+ if (response == GTK_RESPONSE_OK) {
+
+ filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(mc->file_select));
+
+ if (filename != NULL) {
+ if (browsed_folder)
+ g_free (browsed_folder);
+
+ browsed_folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER(mc->file_select));
+
+ mc_exec_command(mc, filename);
+ g_free(filename);
+ }
+ }
+
+ /* destroy file select dialog */
+ gtk_widget_destroy (mc->file_select);
+ mc->file_select = NULL;
+
+ /* go on */
+ return FALSE;
+}
+
+int
+mc_show_file_browser (GtkWidget *widget,
+ MCData *mc)
+{
+ if(mc->file_select && GTK_WIDGET_VISIBLE(mc->file_select)) {
+ gtk_window_present (GTK_WINDOW (mc->file_select));
+ return TRUE;
+ }
+
+ /* build file select dialog */
+ mc->file_select = gtk_file_chooser_dialog_new((gchar *) _("Start program"),
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_EXECUTE, GTK_RESPONSE_OK,
+ NULL);
+
+ g_signal_connect(G_OBJECT(mc->file_select),
+ "response",
+ G_CALLBACK(file_browser_response_signal),
+ mc);
+
+ /* set path to last selected path */
+ if (browsed_folder)
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(mc->file_select),
+ (gchar *) browsed_folder);
+
+ /* Set as modal */
+ gtk_window_set_modal(GTK_WINDOW(mc->file_select),TRUE);
+
+ gtk_window_set_screen (GTK_WINDOW (mc->file_select),
+ gtk_widget_get_screen (GTK_WIDGET (mc->applet)));
+ gtk_window_set_position (GTK_WINDOW (mc->file_select), GTK_WIN_POS_CENTER);
+
+ gtk_widget_show(mc->file_select);
+
+ return FALSE;
+}
+
+void
+mc_create_command_entry (MCData *mc)
+{
+ mc->entry = gtk_entry_new ();
+ gtk_entry_set_max_length (GTK_ENTRY (mc->entry), MC_MAX_COMMAND_LENGTH);
+
+ g_signal_connect (mc->entry, "key_press_event",
+ G_CALLBACK (command_key_event), mc);
+
+ g_signal_connect (mc->entry, "button_press_event",
+ G_CALLBACK (button_press_cb), mc);
+
+ if (!mc->preferences.show_default_theme)
+ {
+ gtk_widget_set_name (mc->entry, "minicommander-applet-entry");
+ mc_command_update_entry_color (mc);
+ }
+ else
+ gtk_widget_set_name (mc->entry,
+ "minicommander-applet-entry-default");
+
+ mc_command_update_entry_size (mc);
+
+ set_atk_name_description (mc->entry,
+ _("Command line"),
+ _("Type a command here and Mate will execute it for you"));
+}
+
+void
+mc_command_update_entry_color (MCData *mc)
+{
+ GdkColor fg;
+ GdkColor bg;
+ char *rc_string;
+
+ fg.red = mc->preferences.cmd_line_color_fg_r;
+ fg.green = mc->preferences.cmd_line_color_fg_g;
+ fg.blue = mc->preferences.cmd_line_color_fg_b;
+
+ /* FIXME: wish we had an API for this, see bug #79585 */
+ rc_string = g_strdup_printf (
+ "\n"
+ " style \"minicommander-applet-entry-style\"\n"
+ " {\n"
+ " GtkWidget::cursor-color=\"#%04x%04x%04x\"\n"
+ " }\n"
+ " widget \"*.minicommander-applet-entry\" "
+ "style \"minicommander-applet-entry-style\"\n"
+ "\n",
+ fg.red, fg.green, fg.blue);
+ gtk_rc_parse_string (rc_string);
+ g_free (rc_string);
+
+ gtk_widget_modify_text (mc->entry, GTK_STATE_NORMAL, &fg);
+ gtk_widget_modify_text (mc->entry, GTK_STATE_PRELIGHT, &fg);
+
+ bg.red = mc->preferences.cmd_line_color_bg_r;
+ bg.green = mc->preferences.cmd_line_color_bg_g;
+ bg.blue = mc->preferences.cmd_line_color_bg_b;
+
+ gtk_widget_modify_base (mc->entry, GTK_STATE_NORMAL, &bg);
+ gtk_widget_modify_base (mc->entry, GTK_STATE_PRELIGHT, &bg);
+}
+
+void
+mc_command_update_entry_size (MCData *mc)
+{
+ int size_x = -1;
+
+ size_x = mc->preferences.normal_size_x - 17;
+ if ((mc->orient == MATE_PANEL_APPLET_ORIENT_LEFT) || (mc->orient == MATE_PANEL_APPLET_ORIENT_RIGHT)) {
+ size_x = MIN(size_x, mc->preferences.panel_size_x - 17);
+ gtk_widget_set_size_request (GTK_WIDGET (mc->entry), size_x, -1);
+ } else {
+ gtk_widget_set_size_request (GTK_WIDGET (mc->entry), size_x, mc->preferences.normal_size_y+2);
+ }
+}
+
+
+/* Thanks to Halfline <[email protected]> for his initial version
+ of history_auto_complete */
+gchar *
+history_auto_complete(GtkWidget *widget, GdkEventKey *event)
+{
+ gchar current_command[MC_MAX_COMMAND_LENGTH];
+ gchar* completed_command;
+ int i;
+
+ g_snprintf(current_command, sizeof(current_command), "%s%s",
+ gtk_entry_get_text(GTK_ENTRY(widget)), event->string);
+ for(i = MC_HISTORY_LIST_LENGTH - 1; i >= 0; i--)
+ {
+ if(!exists_history_entry(i))
+ break;
+ completed_command = get_history_entry(i);
+ if(!strncmp(completed_command, current_command, strlen(current_command)))
+ return completed_command;
+ }
+
+ return NULL;
+}
diff --git a/mini-commander/src/command_line.h b/mini-commander/src/command_line.h
new file mode 100644
index 00000000..195b2425
--- /dev/null
+++ b/mini-commander/src/command_line.h
@@ -0,0 +1,41 @@
+/*
+ * Mini-Commander Applet
+ * Copyright (C) 1998, 1999 Oliver Maruhn <[email protected]>
+ *
+ * Author: Oliver Maruhn <[email protected]>
+ *
+ * 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
+ */
+
+#ifndef __COMMAND_LINE_H__
+#define __COMMAND_LINE_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#include "mini-commander_applet.h"
+
+void mc_create_command_entry (MCData *mc);
+int mc_show_history (GtkWidget *widget,
+ MCData *mc);
+int mc_show_file_browser (GtkWidget *widget,
+ MCData *mc);
+void mc_command_update_entry_color (MCData *mc);
+void mc_command_update_entry_size (MCData *mc);
+
+G_END_DECLS
+
+#endif /* __COMMAND_LINE_H__ */
diff --git a/mini-commander/src/exec.c b/mini-commander/src/exec.c
new file mode 100644
index 00000000..40688bfa
--- /dev/null
+++ b/mini-commander/src/exec.c
@@ -0,0 +1,93 @@
+/*
+ * Mini-Commander Applet
+ * Copyright (C) 1998 Oliver Maruhn <[email protected]>
+ *
+ * Author: Oliver Maruhn <[email protected]>
+ *
+ * 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 <config.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+#include <mateconf/mateconf-client.h>
+
+#include "exec.h"
+#include "macro.h"
+#include "preferences.h"
+#include "history.h"
+
+#define KEY_AUDIBLE_BELL "/apps/marco/general/audible_bell"
+
+static void beep (void);
+
+void
+mc_exec_command (MCData *mc,
+ const char *cmd)
+{
+ GError *error = NULL;
+ char command [1000];
+ char **argv = NULL;
+ gchar *str;
+
+ strncpy (command, cmd, sizeof (command));
+ command [sizeof (command) - 1] = '\0';
+
+ mc_macro_expand_command (mc, command);
+
+ if (!g_shell_parse_argv (command, NULL, &argv, &error)) {
+ if (error != NULL) {
+ g_error_free (error);
+ error = NULL;
+ }
+
+ return;
+ }
+
+ if(!gdk_spawn_on_screen (gtk_widget_get_screen (GTK_WIDGET (mc->applet)),
+ g_get_home_dir (), argv, NULL,
+ G_SPAWN_SEARCH_PATH,
+ NULL, NULL, NULL,
+ &error)) {
+ str = g_strconcat ("(?)", command, NULL);
+ gtk_entry_set_text (GTK_ENTRY (mc->entry), str);
+ //gtk_editable_set_position (GTK_EDITABLE (mc->entry), 0);
+ mc->error = TRUE;
+ beep ();
+ g_free (str);
+ } else {
+ gtk_entry_set_text (GTK_ENTRY (mc->entry), (gchar *) "");
+ append_history_entry (mc, cmd, FALSE);
+ }
+ g_strfreev (argv);
+
+ if (error != NULL)
+ g_error_free (error);
+}
+
+static void beep (void)
+{
+ MateConfClient *default_client;
+ gboolean audible_bell_set;
+
+ default_client = mateconf_client_get_default ();
+ audible_bell_set = mateconf_client_get_bool (default_client, KEY_AUDIBLE_BELL, NULL);
+ if (audible_bell_set) {
+ gdk_beep ();
+ }
+}
diff --git a/mini-commander/src/exec.h b/mini-commander/src/exec.h
new file mode 100644
index 00000000..01d46c10
--- /dev/null
+++ b/mini-commander/src/exec.h
@@ -0,0 +1,35 @@
+/*
+ * Mini-Commander Applet
+ * Copyright (C) 1998 Oliver Maruhn <[email protected]>
+ *
+ * Author: Oliver Maruhn <[email protected]>
+ *
+ * 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
+ */
+#ifndef __EXEC_H__
+#define __EXEC_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#include "mini-commander_applet.h"
+
+void mc_exec_command (MCData *mc,
+ const char *cmd);
+
+G_END_DECLS
+
+#endif /* __EXEC_H__ */
diff --git a/mini-commander/src/help.c b/mini-commander/src/help.c
new file mode 100644
index 00000000..b5c4b66b
--- /dev/null
+++ b/mini-commander/src/help.c
@@ -0,0 +1,42 @@
+/*
+ * Mini-Commander Applet
+ * Copyright (C) 1998 Oliver Maruhn <[email protected]>
+ *
+ * Author: Oliver Maruhn <[email protected]>
+ *
+ * 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 <config.h>
+
+#include "help.h"
+
+void
+show_help (GtkAction *action,
+ MCData *mcdata)
+{
+ GError *error = NULL;
+
+ gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (mcdata->applet)),
+ "command-line",
+ gtk_get_current_event_time (),
+ &error);
+
+ if (error) { /* FIXME: this error needs to be seen by the user */
+ g_warning ("help error: %s\n", error->message);
+ g_error_free (error);
+ error = NULL;
+ }
+}
diff --git a/mini-commander/src/help.h b/mini-commander/src/help.h
new file mode 100644
index 00000000..495984ab
--- /dev/null
+++ b/mini-commander/src/help.h
@@ -0,0 +1,4 @@
+#include "mini-commander_applet.h"
+
+void show_help (GtkAction *action,
+ MCData *mcdata);
diff --git a/mini-commander/src/history-mini.xpm b/mini-commander/src/history-mini.xpm
new file mode 100644
index 00000000..b7ad65eb
--- /dev/null
+++ b/mini-commander/src/history-mini.xpm
@@ -0,0 +1,11 @@
+/* XPM */
+static const char * history_mini_xpm[] = {
+"7 6 2 1",
+" c NONE",
+". c #000000000000",
+" ",
+".......",
+" ..... ",
+" ... ",
+" . ",
+" "};
diff --git a/mini-commander/src/history.c b/mini-commander/src/history.c
new file mode 100644
index 00000000..750796da
--- /dev/null
+++ b/mini-commander/src/history.c
@@ -0,0 +1,144 @@
+/*
+ * Mini-Commander Applet
+ * Copyright (C) 1998 Oliver Maruhn <[email protected]>
+ *
+ * Author: Oliver Maruhn <[email protected]>
+ *
+ * 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
+ */
+
+/* Actually the command history is a simple list. So, I guess this
+ here could also be done with the list routines of glib. */
+
+#include <config.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <mateconf/mateconf.h>
+#include <mate-panel-applet.h>
+#include <mate-panel-applet-mateconf.h>
+
+#include "history.h"
+#include "preferences.h"
+
+static char *history_command[MC_HISTORY_LIST_LENGTH];
+static void delete_history_entry(int element_number);
+
+
+int
+exists_history_entry(int pos)
+{
+ return(history_command[pos] != NULL);
+}
+
+char *
+get_history_entry(int pos)
+{
+ return(history_command[pos]);
+}
+
+void
+set_history_entry(int pos, char * entry)
+{
+ if(history_command[pos] != NULL)
+ free(history_command[pos]);
+ history_command[pos] = (char *)malloc(sizeof(char) * (strlen(entry) + 1));
+ strcpy(history_command[pos], entry);
+}
+
+/* load_history indicates whether the history list is being loaded at startup.
+** If true then don't save the new entries with mateconf (since they are being read
+** using mateconf
+*/
+void
+append_history_entry(MCData *mcdata, const char * entry, gboolean load_history)
+{
+ MatePanelApplet *applet = mcdata->applet;
+ MateConfValue *history;
+ GSList *list = NULL;
+ int pos, i;
+
+ /* remove older dupes */
+ for(pos = 0; pos <= MC_HISTORY_LIST_LENGTH - 1; pos++)
+ {
+ if(exists_history_entry(pos) && strcmp(entry, history_command[pos]) == 0)
+ /* dupe found */
+ delete_history_entry(pos);
+ }
+
+ /* delete oldest entry */
+ if(history_command[0] != NULL)
+ free(history_command[0]);
+
+ /* move entries */
+ for(pos = 0; pos < MC_HISTORY_LIST_LENGTH - 1; pos++)
+ {
+ history_command[pos] = history_command[pos+1];
+ /* printf("%s\n", history_command[pos]); */
+ }
+
+ /* append entry */
+ history_command[MC_HISTORY_LIST_LENGTH - 1] = (char *)malloc(sizeof(char) * (strlen(entry) + 1));
+ strcpy(history_command[MC_HISTORY_LIST_LENGTH - 1], entry);
+
+ if (load_history)
+ return;
+
+ /* If not writable, just keeps the history around for this session */
+ if ( ! mc_key_writable (mcdata, "history"))
+ return;
+
+ /* Save history - this seems like a waste to do it every time it's updated
+ ** but it doesn't seem to work when called on the destroy signal of the applet
+ */
+ for(i = 0; i < MC_HISTORY_LIST_LENGTH; i++)
+ {
+ MateConfValue *value_entry;
+
+ value_entry = mateconf_value_new (MATECONF_VALUE_STRING);
+ if(exists_history_entry(i)) {
+ mateconf_value_set_string (value_entry, (gchar *) get_history_entry(i));
+ list = g_slist_append (list, value_entry);
+ }
+
+ }
+
+ history = mateconf_value_new (MATECONF_VALUE_LIST);
+ if (list) {
+ mateconf_value_set_list_type (history, MATECONF_VALUE_STRING);
+ mateconf_value_set_list (history, list);
+ mate_panel_applet_mateconf_set_value (applet, "history", history, NULL);
+ }
+
+ while (list) {
+ MateConfValue *value = list->data;
+ mateconf_value_free (value);
+ list = g_slist_next (list);
+ }
+
+ mateconf_value_free (history);
+
+}
+
+void
+delete_history_entry(int element_number)
+{
+ int pos;
+
+ for(pos = element_number; pos > 0; --pos)
+ history_command[pos] = history_command[pos - 1];
+
+ history_command[0] = NULL;
+}
diff --git a/mini-commander/src/history.h b/mini-commander/src/history.h
new file mode 100644
index 00000000..1dd5dea2
--- /dev/null
+++ b/mini-commander/src/history.h
@@ -0,0 +1,6 @@
+#include "mini-commander_applet.h"
+
+int exists_history_entry(int pos);
+extern char *get_history_entry(int pos);
+extern void set_history_entry(int pos, char * entry);
+extern void append_history_entry(MCData *mcdata, const char * entry, gboolean load_history);
diff --git a/mini-commander/src/macro.c b/mini-commander/src/macro.c
new file mode 100644
index 00000000..060d4c50
--- /dev/null
+++ b/mini-commander/src/macro.c
@@ -0,0 +1,155 @@
+/*
+ * Mini-Commander Applet
+ * Copyright (C) 1998 Oliver Maruhn <[email protected]>
+ *
+ * Author: Oliver Maruhn <[email protected]>
+ *
+ * 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 <config.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <regex.h>
+
+#include "macro.h"
+#include "preferences.h"
+
+/* search for the longest matching prefix */
+static MCMacro *
+mc_macro_with_prefix (MCData *mc,
+ char *command)
+{
+ MCMacro *retval = NULL;
+ GSList *l;
+ int prefix_len_found = 0;
+
+ for (l = mc->preferences.macros; l; l = l->next) {
+ MCMacro *macro = l->data;
+ int pattern_len;
+
+ pattern_len = strlen (macro->pattern);
+
+ if (pattern_len > prefix_len_found &&
+ !strncmp (command, macro->pattern, pattern_len) &&
+ (strstr (macro->command, "$1") || pattern_len == strlen (command))) {
+ /* found a matching prefix;
+ * if macro does not contain "$1" then the prefix has
+ * to to have the same length as the command
+ */
+ prefix_len_found = pattern_len;
+ retval = macro;
+ }
+ }
+
+ return retval;
+}
+
+int
+mc_macro_prefix_len (MCData *mc,
+ char *command)
+{
+ MCMacro *macro;
+
+ macro = mc_macro_with_prefix (mc, command);
+ if (!macro)
+ return 0;
+
+ return strlen (macro->pattern);
+}
+
+int
+mc_macro_prefix_len_wspace (MCData *mc,
+ char *command)
+{
+ char *c_ptr;
+
+ c_ptr = command + mc_macro_prefix_len (mc, command);
+
+ while (*c_ptr != '\0' && *c_ptr == ' ')
+ c_ptr++;
+
+ return c_ptr - command;
+}
+
+char *
+mc_macro_get_prefix (MCData *mc,
+ char *command)
+{
+ MCMacro *macro;
+
+ macro = mc_macro_with_prefix (mc, command);
+ if (!macro)
+ return NULL;
+
+ return macro->pattern;
+}
+
+void
+mc_macro_expand_command (MCData *mc,
+ char *command)
+{
+ GSList *l;
+ char command_exec [1000];
+
+ command_exec [0] = '\0';
+
+ for (l = mc->preferences.macros; l; l = l->next) {
+ regmatch_t regex_matches [MC_MAX_NUM_MACRO_PARAMETERS];
+ MCMacro *macro = l->data;
+
+ if (regexec (&macro->regex, command, MC_MAX_NUM_MACRO_PARAMETERS, regex_matches, 0) != REG_NOMATCH) {
+ char placeholder [100];
+ char *char_p;
+ int inside_placeholder;
+ int parameter_number;
+
+ inside_placeholder = 0;
+
+ for (char_p = macro->command; *char_p != '\0'; ++char_p) {
+ if (inside_placeholder == 0 &&
+ *char_p == '\\' &&
+ *(char_p + 1) >= '0' &&
+ *(char_p + 1) <= '9') {
+ strcpy (placeholder, "");
+ inside_placeholder = 1;
+ } else if (inside_placeholder &&
+ (*(char_p + 1) < '0' || *(char_p + 1) > '9'))
+ inside_placeholder = 2;
+
+ if (inside_placeholder == 0)
+ strncat (command_exec, char_p, 1);
+ else
+ strncat (placeholder, char_p, 1);
+
+ if (inside_placeholder == 2) {
+ parameter_number = atoi (placeholder + 1);
+
+ if (parameter_number <= MC_MAX_NUM_MACRO_PARAMETERS &&
+ regex_matches [parameter_number].rm_eo > 0)
+ strncat (command_exec,
+ command + regex_matches [parameter_number].rm_so,
+ regex_matches [parameter_number].rm_eo - regex_matches [parameter_number].rm_so);
+
+ inside_placeholder = 0;
+ }
+ }
+ }
+ }
+
+ if (command_exec [0] != '\0')
+ strcpy (command, command_exec);
+}
diff --git a/mini-commander/src/macro.h b/mini-commander/src/macro.h
new file mode 100644
index 00000000..7beb2fb6
--- /dev/null
+++ b/mini-commander/src/macro.h
@@ -0,0 +1,42 @@
+/*
+ * Mini-Commander Applet
+ * Copyright (C) 1998 Oliver Maruhn <[email protected]>
+ *
+ * Author: Oliver Maruhn <[email protected]>
+ *
+ * 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
+ */
+
+#ifndef __MACRO_H__
+#define __MACRO_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#include "mini-commander_applet.h"
+
+void mc_macro_expand_command (MCData *mc,
+ char *command);
+int mc_macro_prefix_len (MCData *mc,
+ char *command);
+int mc_macro_prefix_len_wspace (MCData *mc,
+ char *command);
+char *mc_macro_get_prefix (MCData *mc,
+ char *command);
+
+G_END_DECLS
+
+#endif /* __MACRO_H__ */
diff --git a/mini-commander/src/mate-mini-commander.png b/mini-commander/src/mate-mini-commander.png
new file mode 100644
index 00000000..b2152e3c
--- /dev/null
+++ b/mini-commander/src/mate-mini-commander.png
Binary files differ
diff --git a/mini-commander/src/mc-default-macros.h b/mini-commander/src/mc-default-macros.h
new file mode 100644
index 00000000..9ede9c73
--- /dev/null
+++ b/mini-commander/src/mc-default-macros.h
@@ -0,0 +1,65 @@
+/*
+ * Mini-Commander Applet
+ * Copyright (C) 2002 Sun Microsystems Inc.
+ *
+ * Authors: Mark McLoughlin <[email protected]>
+ *
+ * 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
+ */
+
+#ifndef __MC_DEFAULT_MACROS_H__
+#define __MC_DEFAULT_MACROS_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+ char *pattern;
+ char *command;
+} MCDefaultMacro;
+
+/* These are both the defaults stored in the MateConfSchema
+ * and the fallback defaults that are used if we are
+ * having MateConf problems.
+ *
+ * See mc-install-default-macros.c for how they get
+ * installed into the schemas.
+ */
+static const MCDefaultMacro mc_default_macros [] = {
+ { "^(https?://.*)$", "mate-open \\1" },
+ { "^(ftp://.*)", "mate-open \\1" },
+ { "^(www\\..*)$", "mate-open http://\\1" },
+ { "^(ftp\\..*)$", "mate-open ftp://\\1" },
+
+ /* altavista search */
+ { "^av: *(.*)$", "mate-open http://www.altavista.net/cgi-bin/query?pg=q\\&kl=XX\\&q=$(echo '\\1'|sed -e ': p;s/+/%2B/;t p;: s;s/\\ /+/;t s;: q;s/\\\"/%22/;t q')" },
+
+ /* yahoo search */
+ { "^yahoo: *(.*)$", "mate-open http://ink.yahoo.com/bin/query?p=$(echo '\\1'|sed -e ': p;s/+/%2B/;t p;: s;s/\\ /+/;t s;: q;s/\\\"/%22/;t q')" },
+
+ /* freshmeat search */
+ { "^fm: *(.*)$", "mate-open http://core.freshmeat.net/search.php3?query=$(echo '\\1'|tr \" \" +)" },
+
+ /* dictionary search */
+ { "^dictionary: *(.*)$", "mate-dictionary \"\\1\"" },
+
+ /* google search */
+ { "^google: *(.*)$", "mate-open http://www.google.com/search?q=\\1" },
+};
+
+G_END_DECLS
+
+#endif /* __MC_DEFAULT_MACROS_H__ */
diff --git a/mini-commander/src/mc-install-default-macros.c b/mini-commander/src/mc-install-default-macros.c
new file mode 100644
index 00000000..51750173
--- /dev/null
+++ b/mini-commander/src/mc-install-default-macros.c
@@ -0,0 +1,179 @@
+/*
+ * mc-install-default-macros.c:
+ * Copyright (C) 2002 Sun Microsystems Inc.
+ *
+ * Authors: Mark McLoughlin <[email protected]>
+ *
+ * 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
+ */
+
+/* This reads the macro patterns and commands lists
+ * schemas and sets the default values to be our
+ * default list of macros.
+ *
+ * This is easier than trying to have this stuff
+ * in the .schemas file - you would believe the
+ * kind of escaping and hackery needed to get
+ * it into the .schemas, and even then its impossible
+ * to tell which pattern is for which macro ...
+ */
+
+/* This is to have access to mateconf_engine_get_local() */
+#define MATECONF_ENABLE_INTERNALS 1
+
+#include <config.h>
+#include <stdio.h>
+
+#include <glib/gi18n.h>
+#include <mateconf/mateconf.h>
+#include <mateconf/mateconf-client.h>
+#include <mateconf/mateconf-engine.h>
+
+/* Okay, I'm VERY bold. I deserve to be spanked.
+ *
+ * But this isn't installed, its only used at build time,
+ * so I don't feel too bad. If these disappear from the
+ * ABI or their signature changes, the build will break
+ * and someone will have to figure out how to fix it.
+ * Too bad, whoever you are :/
+ */
+void mateconf_shutdown_daemon (GError **err);
+
+#include "mc-default-macros.h"
+
+#define MC_PATTERNS_SHEMA_KEY "/schemas/apps/mini-commander-global/macro_patterns"
+#define MC_COMMANDS_SHEMA_KEY "/schemas/apps/mini-commander-global/macro_commands"
+
+/*
+ * Keep these old schemas around in order to keep
+ * old configurations from breaking. See bug #91194
+ */
+#define MC_DEPRECATED_PATTERNS_SHEMA_KEY "/schemas/apps/mini-commander/prefs/macro_patterns"
+#define MC_DEPRECATED_COMMANDS_SHEMA_KEY "/schemas/apps/mini-commander/prefs/macro_commands"
+
+static void
+install_default_macros_list (MateConfClient *client,
+ const char *key,
+ int offset)
+{
+ MateConfSchema *schema;
+ MateConfValue *value;
+ GSList *list = NULL;
+ GError *error;
+ int i;
+
+ error = NULL;
+ schema = mateconf_client_get_schema (client, key, &error);
+ if (error) {
+ g_warning (_("Cannot get schema for %s: %s"), key, error->message);
+ g_error_free (error);
+ return;
+ }
+
+ /* mateconf has started to return NULL with no error set. */
+ g_return_if_fail (schema != NULL);
+
+ /* Some sanity checks */
+ g_assert (mateconf_schema_get_type (schema) == MATECONF_VALUE_LIST);
+ g_assert (mateconf_schema_get_list_type (schema) == MATECONF_VALUE_STRING);
+
+ value = mateconf_value_new (MATECONF_VALUE_LIST);
+ mateconf_value_set_list_type (value, MATECONF_VALUE_STRING);
+
+ for (i = 0; i < G_N_ELEMENTS (mc_default_macros); i++)
+ list = g_slist_prepend (list,
+ mateconf_value_new_from_string (MATECONF_VALUE_STRING,
+ G_STRUCT_MEMBER (char *, &mc_default_macros [i], offset),
+ NULL));
+ list = g_slist_reverse (list);
+
+ mateconf_value_set_list_nocopy (value, list);
+ list = NULL;
+
+ mateconf_schema_set_default_value_nocopy (schema, value);
+ value = NULL;
+
+ error = NULL;
+ mateconf_client_set_schema (client, key, schema, &error);
+ if (error) {
+ g_warning (_("Cannot set schema for %s: %s"), key, error->message);
+ g_error_free (error);
+ }
+
+ mateconf_schema_free (schema);
+
+ printf (_("Set default list value for %s\n"), key);
+}
+
+int
+main (int argc, char **argv)
+{
+ MateConfClient *client;
+ MateConfEngine *conf;
+ GError *error = NULL;
+ const char *config_source;
+
+ if (g_getenv ("MATECONF_DISABLE_MAKEFILE_SCHEMA_INSTALL")) {
+ fprintf (stderr, _("MATECONF_DISABLE_MAKEFILE_SCHEMA_INSTALL is set, not installing schemas\n"));
+ return 0;
+ }
+
+ g_type_init ();
+
+ config_source = g_getenv ("MATECONF_CONFIG_SOURCE");
+ if (!config_source) {
+ fprintf (stderr, _("Must set the MATECONF_CONFIG_SOURCE environment variable\n"));
+ return -1;
+ }
+
+ if (*config_source == '\0')
+ config_source = NULL;
+
+ /* shut down daemon, this is a race condition, but will usually work. */
+ mateconf_shutdown_daemon (NULL);
+
+ if (!config_source)
+ conf = mateconf_engine_get_default ();
+ else
+ conf = mateconf_engine_get_local (config_source, &error);
+
+ if (!conf) {
+ g_assert (error != NULL);
+ fprintf (stderr, _("Failed to access configuration source(s): %s\n"), error->message);
+ g_error_free (error);
+ return -1;
+ }
+
+ client = mateconf_client_get_for_engine (conf);
+
+ install_default_macros_list (client, MC_PATTERNS_SHEMA_KEY, G_STRUCT_OFFSET (MCDefaultMacro, pattern));
+ install_default_macros_list (client, MC_COMMANDS_SHEMA_KEY, G_STRUCT_OFFSET (MCDefaultMacro, command));
+
+ install_default_macros_list (client, MC_DEPRECATED_PATTERNS_SHEMA_KEY, G_STRUCT_OFFSET (MCDefaultMacro, pattern));
+ install_default_macros_list (client, MC_DEPRECATED_COMMANDS_SHEMA_KEY, G_STRUCT_OFFSET (MCDefaultMacro, command));
+
+ mateconf_client_suggest_sync (client, &error);
+ if (error) {
+ fprintf (stderr, _("Error syncing config data: %s"),
+ error->message);
+ g_error_free (error);
+ return 1;
+ }
+
+ mateconf_engine_unref (conf);
+ g_object_unref (client);
+
+ return 0;
+}
diff --git a/mini-commander/src/mini-commander-applet-menu.xml b/mini-commander/src/mini-commander-applet-menu.xml
new file mode 100644
index 00000000..5cef44fa
--- /dev/null
+++ b/mini-commander/src/mini-commander-applet-menu.xml
@@ -0,0 +1,4 @@
+<menuitem name="Item 1" action="Props" />
+<menuitem name="Item 2" action="Help" />
+<menuitem name="Item 3" action="About" />
+
diff --git a/mini-commander/src/mini-commander-global.schemas.in b/mini-commander/src/mini-commander-global.schemas.in
new file mode 100644
index 00000000..b9714085
--- /dev/null
+++ b/mini-commander/src/mini-commander-global.schemas.in
@@ -0,0 +1,31 @@
+<mateconfschemafile>
+ <schemalist>
+
+ <schema>
+ <key>/schemas/apps/mini-commander-global/macro_patterns</key>
+ <applyto>/apps/mini-commander/macro_patterns</applyto>
+ <owner>mini-commander-applet</owner>
+ <type>list</type>
+ <list_type>string</list_type>
+ <default>[blah]</default> <!-- The default list is set by mc-install-default-macros -->
+ <locale name="C">
+ <short>Macro pattern list</short>
+ <long>List of MateConfValue entries containing strings for the macro patterns.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/mini-commander-global/macro_commands</key>
+ <applyto>/apps/mini-commander/macro_commands</applyto>
+ <owner>mini-commander-applet</owner>
+ <type>list</type>
+ <list_type>string</list_type>
+ <default>[blah]</default> <!-- The default list is set by mc-install-default-macros -->
+ <locale name="C">
+ <short>Macro command list</short>
+ <long>List of MateConfValue entries containing strings for the macro commands.</long>
+ </locale>
+ </schema>
+
+ </schemalist>
+</mateconfschemafile>
diff --git a/mini-commander/src/mini-commander.schemas.in b/mini-commander/src/mini-commander.schemas.in
new file mode 100644
index 00000000..2d5413de
--- /dev/null
+++ b/mini-commander/src/mini-commander.schemas.in
@@ -0,0 +1,193 @@
+<mateconfschemafile>
+ <schemalist>
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/show_handle</key>
+ <owner>mini-commander-applet</owner>
+ <type>bool</type>
+ <default>false</default>
+ <locale name="C">
+ <short>Show handle</short>
+ <long>Show a handle so the applet can be detached from the panel.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/show_frame</key>
+ <owner>mini-commander-applet</owner>
+ <type>bool</type>
+ <default>false</default>
+ <locale name="C">
+ <short>Show frame</short>
+ <long>Show a frame surrounding the applet.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/autocomplete_history</key>
+ <owner>mini-commander-applet</owner>
+ <type>bool</type>
+ <default>true</default>
+ <locale name="C">
+ <short>Perform history autocompletion</short>
+ <long>Attempt to autocomplete a command from the history of commands entered.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/normal_size_x</key>
+ <owner>mini-commander-applet</owner>
+ <type>int</type>
+ <default>150</default>
+ <locale name="C">
+ <short>Width</short>
+ <long>Width of the applet</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/normal_size_y</key>
+ <owner>mini-commander-applet</owner>
+ <type>int</type>
+ <default>48</default>
+ <locale name="C">
+ <short>Not used anymore</short>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/cmd_line_y</key>
+ <owner>mini-commander-applet</owner>
+ <type>int</type>
+ <default>24</default>
+ <locale name="C">
+ <short>Not used anymore</short>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/show_default_theme</key>
+ <owner>mini-commander-applet</owner>
+ <type>bool</type>
+ <default>true</default>
+ <locale name="C">
+ <short>Use the default theme colors</short>
+ <long>Use theme colors instead of custom ones.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/cmd_line_color_fg_r</key>
+ <owner>mini-commander-applet</owner>
+ <type>int</type>
+ <default>64613</default>
+ <locale name="C">
+ <short>Foreground color, red component</short>
+ <long>The red component of the foreground color.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/cmd_line_color_fg_g</key>
+ <owner>mini-commander-applet</owner>
+ <type>int</type>
+ <default>64613</default>
+ <locale name="C">
+ <short>Foreground color, green component</short>
+ <long>The green component of the foreground color.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/cmd_line_color_fg_b</key>
+ <owner>mini-commander-applet</owner>
+ <type>int</type>
+ <default>64613</default>
+ <locale name="C">
+ <short>Foreground color, blue component</short>
+ <long>The blue component of the foreground color.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/cmd_line_color_bg_r</key>
+ <owner>mini-commander-applet</owner>
+ <type>int</type>
+ <default>0</default>
+ <locale name="C">
+ <short>Background color, red component</short>
+ <long>The red component of the background color.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/cmd_line_color_bg_g</key>
+ <owner>mini-commander-applet</owner>
+ <type>int</type>
+ <default>0</default>
+ <locale name="C">
+ <short>Background color, green component</short>
+ <long>The green component of the background color.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/cmd_line_color_bg_b</key>
+ <owner>mini-commander-applet</owner>
+ <type>int</type>
+ <default>0</default>
+ <locale name="C">
+ <short>Background color, blue component</short>
+ <long>The blue component of the background color.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/history</key>
+ <owner>mini-commander-applet</owner>
+ <type>list</type>
+ <list_type>string</list_type>
+ <default>[]</default>
+ <locale name="C">
+ <short>History list</short>
+ <long>List of MateConfValue entries containing strings for history entries.</long>
+ </locale>
+ </schema>
+
+ <!--
+ Keep these deprecated keys around in order to keep older configurations
+ working correctly. See bug #91194
+ -->
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/macro_patterns</key>
+ <owner>mini-commander-applet</owner>
+ <type>list</type>
+ <list_type>string</list_type>
+ <default>[blah]</default> <!-- The default list is set by mc-install-default-macros -->
+ <locale name="C">
+ <short>Macro pattern list</short>
+ <long>
+ This per-applet key is deprecated in favour of the global key,
+ /schemas/apps/mini-commander-global/macro_patterns.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/mini-commander/prefs/macro_commands</key>
+ <owner>mini-commander-applet</owner>
+ <type>list</type>
+ <list_type>string</list_type>
+ <default>[blah]</default> <!-- The default list is set by mc-install-default-macros -->
+ <locale name="C">
+ <short>Macro command list</short>
+ <long>
+ This per-applet key is deprecated in favour of the global key,
+ /schemas/apps/mini-commander-global/macro_patterns.
+ </long>
+ </locale>
+ </schema>
+
+ </schemalist>
+</mateconfschemafile>
diff --git a/mini-commander/src/mini-commander.ui b/mini-commander/src/mini-commander.ui
new file mode 100644
index 00000000..00ea5a90
--- /dev/null
+++ b/mini-commander/src/mini-commander.ui
@@ -0,0 +1,713 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy toplevel-contextual -->
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="value">1</property>
+ <property name="lower">50</property>
+ <property name="upper">400</property>
+ <property name="step_increment">5</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="mc_preferences_dialog">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Command Line Preferences</property>
+ <property name="type_hint">dialog</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox2">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkNotebook" id="preferences_notebook">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="border_width">5</property>
+ <child>
+ <object class="GtkVBox" id="general_page_vbox">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">18</property>
+ <child>
+ <object class="GtkVBox" id="vbox10">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label24">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Auto Completion</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox6">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="label25">
+ <property name="visible">True</property>
+ <property name="label"> </property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="auto_complete_history_toggle">
+ <property name="label" translatable="yes">E_nable history-based auto completion</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox11">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label26">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Size</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox7">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="label27">
+ <property name="visible">True</property>
+ <property name="label"> </property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="size_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Width:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">size_spinner</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox9">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="size_spinner">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="climb_rate">10</property>
+ <property name="numeric">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="size_post_label"/>
+ <relation type="labelled-by" target="size_label"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="size_post_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">pixels</property>
+ <accessibility>
+ <relation type="label-for" target="size_spinner"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox12">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label28">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Colors</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox8">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="label29">
+ <property name="visible">True</property>
+ <property name="label"> </property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="table2">
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="default_theme_toggle">
+ <property name="label" translatable="yes">_Use default theme colors</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="fg_color_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Command line _foreground:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">fg_color_picker</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="bg_color_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Command line _background:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">bg_color_picker</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkColorButton" id="fg_color_picker">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="title" translatable="yes">Pick a color</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkColorButton" id="bg_color_picker">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="title" translatable="yes">Pick a color</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="general_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">General</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox13">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label30">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Macros:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">macros_tree</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox4">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkScrolledWindow" id="macros_scrolled_tree">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="macros_tree">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox7">
+ <property name="visible">True</property>
+ <property name="border_width">4</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkButton" id="add_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <child>
+ <object class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <object class="GtkHBox" id="hbox3">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="stock">gtk-add</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label20">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Add Macro...</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <object class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-delete</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label19">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Delete Macro</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label21">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Macros</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area2">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="help_button">
+ <property name="label">gtk-help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="done_button">
+ <property name="label">gtk-close</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">help_button</action-widget>
+ <action-widget response="-7">done_button</action-widget>
+ </action-widgets>
+ </object>
+ <object class="GtkDialog" id="mc_macro_add_dialog">
+ <property name="visible">True</property>
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Add New Macro</property>
+ <property name="resizable">False</property>
+ <property name="type_hint">dialog</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox3">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkTable" id="table3">
+ <property name="visible">True</property>
+ <property name="border_width">5</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="pattern_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Pattern:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">pattern_entry</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="command_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Co_mmand:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">command_entry</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="pattern_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="command_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area3">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="helpbutton1">
+ <property name="label">gtk-help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button1">
+ <property name="label">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button2">
+ <property name="label">gtk-add</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">helpbutton1</action-widget>
+ <action-widget response="-6">button1</action-widget>
+ <action-widget response="-5">button2</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/mini-commander/src/mini-commander_applet.c b/mini-commander/src/mini-commander_applet.c
new file mode 100644
index 00000000..20dd4969
--- /dev/null
+++ b/mini-commander/src/mini-commander_applet.c
@@ -0,0 +1,430 @@
+ /*
+ * Mini-Commander Applet
+ * Copyright (C) 1998 Oliver Maruhn <[email protected]>,
+ * 2002 Sun Microsystems
+ *
+ * Authors: Oliver Maruhn <[email protected]>,
+ * Mark McLoughlin <[email protected]>
+ *
+ * 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 <config.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gdk/gdkkeysyms.h>
+
+
+#include <gtk/gtk.h>
+
+#include <mate-panel-applet.h>
+#include <mateconf/mateconf-client.h>
+#include "mini-commander_applet.h"
+#include "preferences.h"
+#include "command_line.h"
+#include "about.h"
+#include "help.h"
+
+#include "browser-mini.xpm"
+#include "history-mini.xpm"
+
+#define COMMANDLINE_BROWSER_STOCK "commandline-browser"
+#define COMMANDLINE_HISTORY_STOCK "commandline-history"
+
+#define COMMANDLINE_DEFAULT_ICON_SIZE 6
+
+static gboolean icons_initialized = FALSE;
+static GtkIconSize button_icon_size = 0;
+
+static const GtkActionEntry mini_commander_menu_actions [] = {
+ { "Props", GTK_STOCK_PROPERTIES, N_("_Preferences"),
+ NULL, NULL,
+ G_CALLBACK (mc_show_preferences) },
+ { "Help", GTK_STOCK_HELP, N_("_Help"),
+ NULL, NULL,
+ G_CALLBACK (show_help) },
+ { "About", GTK_STOCK_ABOUT, N_("_About"),
+ NULL, NULL,
+ G_CALLBACK (about_box) }
+};
+
+typedef struct {
+ char *stock_id;
+ const char **icon_data;
+} CommandLineStockIcon;
+
+static CommandLineStockIcon items[] = {
+ { COMMANDLINE_BROWSER_STOCK, browser_mini_xpm },
+ { COMMANDLINE_HISTORY_STOCK, history_mini_xpm }
+};
+
+static void
+register_command_line_stock_icons (GtkIconFactory *factory)
+{
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (items); ++i) {
+ GtkIconSet *icon_set;
+ GdkPixbuf *pixbuf;
+
+ pixbuf = gdk_pixbuf_new_from_xpm_data ((items[i].icon_data));
+
+ icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
+ gtk_icon_factory_add (factory, items[i].stock_id, icon_set);
+
+ gtk_icon_set_unref (icon_set);
+ g_object_unref (G_OBJECT (pixbuf));
+ }
+
+}
+
+static void
+command_line_init_stock_icons (void)
+{
+
+ GtkIconFactory *factory;
+
+ if (icons_initialized)
+ return;
+
+ factory = gtk_icon_factory_new ();
+ gtk_icon_factory_add_default (factory);
+
+ register_command_line_stock_icons (factory);
+
+ button_icon_size = gtk_icon_size_register ("mini-commander-icon",
+ COMMANDLINE_DEFAULT_ICON_SIZE,
+ COMMANDLINE_DEFAULT_ICON_SIZE);
+
+ icons_initialized = TRUE;
+ g_object_unref (factory);
+
+}
+
+void
+set_atk_name_description (GtkWidget *widget,
+ const char *name,
+ const char *description)
+{
+ AtkObject *aobj;
+
+ aobj = gtk_widget_get_accessible (widget);
+ if (GTK_IS_ACCESSIBLE (aobj) == FALSE)
+ return;
+
+ atk_object_set_name (aobj, name);
+ atk_object_set_description (aobj, description);
+}
+
+/* This is a hack around the fact that gtk+ doesn't
+ * propogate button presses on button2/3.
+ */
+static gboolean
+button_press_hack (GtkWidget *widget,
+ GdkEventButton *event,
+ MCData *mc)
+{
+ if (event->button == 3 || event->button == 2) {
+ gtk_propagate_event (GTK_WIDGET (mc->applet), (GdkEvent *) event);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Send button presses on the applet to the entry. This makes Fitts' law work (ie click on the bottom
+** most pixel and the key press will be sent to the entry */
+static gboolean
+send_button_to_entry_event (GtkWidget *widget, GdkEventButton *event, MCData *mc)
+{
+
+ if (event->button == 1) {
+ gtk_widget_grab_focus (mc->entry);
+ return TRUE;
+ }
+ return FALSE;
+
+}
+
+static gboolean
+key_press_cb (GtkWidget *widget, GdkEventKey *event, MCData *mc)
+{
+ switch (event->keyval) {
+ case GDK_b:
+ if (event->state == GDK_CONTROL_MASK) {
+ mc_show_file_browser (NULL, mc);
+ return TRUE;
+ }
+ break;
+ case GDK_h:
+ if (event->state == GDK_CONTROL_MASK) {
+ mc_show_history (NULL, mc);
+ return TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return FALSE;
+
+}
+
+void
+mc_applet_draw (MCData *mc)
+{
+ GtkWidget *icon;
+ GtkWidget *button;
+ GtkWidget *hbox_buttons;
+ MCPreferences prefs = mc->preferences;
+ int size_frames = 0;
+ gchar *command_text = NULL;
+
+ if (mc->entry != NULL)
+ command_text = g_strdup (gtk_editable_get_chars (GTK_EDITABLE (mc->entry), 0, -1));
+
+ mc->cmd_line_size_y = mc->preferences.normal_size_y - size_frames;
+
+ if (mc->applet_box) {
+ gtk_widget_destroy (mc->applet_box);
+ }
+
+ if ( ((mc->orient == MATE_PANEL_APPLET_ORIENT_LEFT) || (mc->orient == MATE_PANEL_APPLET_ORIENT_RIGHT)) && (prefs.panel_size_x < 36) )
+ mc->applet_box = gtk_vbox_new (FALSE, 0);
+ else
+ mc->applet_box = gtk_hbox_new (FALSE, 0);
+
+ gtk_container_set_border_width (GTK_CONTAINER (mc->applet_box), 0);
+
+ mc_create_command_entry (mc);
+
+ if (command_text != NULL) {
+ gtk_entry_set_text (GTK_ENTRY (mc->entry), command_text);
+ g_free (command_text);
+ }
+
+ /* hbox for message label and buttons */
+ if ((mc->orient == MATE_PANEL_APPLET_ORIENT_LEFT) || (mc->orient == MATE_PANEL_APPLET_ORIENT_RIGHT))
+ if (prefs.panel_size_x < 36)
+ hbox_buttons = gtk_vbox_new (TRUE, 0);
+ else
+ hbox_buttons = gtk_hbox_new (TRUE, 0);
+ else
+ if (prefs.normal_size_y > 36)
+ hbox_buttons = gtk_vbox_new (TRUE, 0);
+ else
+ hbox_buttons = gtk_hbox_new (TRUE, 0);
+
+ /* add file-browser button */
+ button = gtk_button_new ();
+
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (mc_show_file_browser), mc);
+ g_signal_connect (button, "button_press_event",
+ G_CALLBACK (button_press_hack), mc);
+
+ icon = gtk_image_new_from_stock (COMMANDLINE_BROWSER_STOCK, button_icon_size);
+ gtk_container_add (GTK_CONTAINER (button), icon);
+
+ gtk_widget_set_tooltip_text (button, _("Browser"));
+ gtk_box_pack_start (GTK_BOX (hbox_buttons), button, TRUE, TRUE, 0);
+
+ set_atk_name_description (button,
+ _("Browser"),
+ _("Click this button to start the browser"));
+
+ /* add history button */
+ button = gtk_button_new ();
+
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (mc_show_history), mc);
+ g_signal_connect (button, "button_press_event",
+ G_CALLBACK (button_press_hack), mc);
+
+ icon = gtk_image_new_from_stock (COMMANDLINE_HISTORY_STOCK, button_icon_size);
+ gtk_container_add (GTK_CONTAINER (button), icon);
+
+ gtk_widget_set_tooltip_text (button, _("History"));
+ gtk_box_pack_end (GTK_BOX (hbox_buttons), button, TRUE, TRUE, 0);
+
+ set_atk_name_description (button,
+ _("History"),
+ _("Click this button for the list of previous commands"));
+
+ gtk_box_pack_start (GTK_BOX (mc->applet_box), mc->entry, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (mc->applet_box), hbox_buttons, TRUE, TRUE, 0);
+
+ gtk_container_add (GTK_CONTAINER (mc->applet), mc->applet_box);
+
+ gtk_widget_show_all (mc->applet_box);
+}
+
+static void
+mc_destroyed (GtkWidget *widget,
+ MCData *mc)
+{
+ MateConfClient *client;
+ int i;
+
+ client = mateconf_client_get_default ();
+ for (i = 0; i < MC_NUM_LISTENERS; i++) {
+ mateconf_client_notify_remove (client, mc->listeners [i]);
+ mc->listeners [i] = 0;
+ }
+ g_object_unref (client);
+
+ mc_macros_free (mc->preferences.macros);
+
+ if (mc->prefs_dialog.dialog)
+ gtk_widget_destroy (mc->prefs_dialog.dialog);
+
+ if (mc->prefs_dialog.dialog)
+ g_object_unref (mc->prefs_dialog.macros_store);
+
+ if (mc->file_select)
+ gtk_widget_destroy (mc->file_select);
+
+ g_free (mc);
+}
+
+static void
+mc_orient_changed (MatePanelApplet *applet,
+ MatePanelAppletOrient orient,
+ MCData *mc)
+{
+ mc->orient = orient;
+ mc_applet_draw (mc);
+}
+
+static void
+mc_pixel_size_changed (MatePanelApplet *applet,
+ GtkAllocation *allocation,
+ MCData *mc)
+{
+ if ((mc->orient == MATE_PANEL_APPLET_ORIENT_LEFT) || (mc->orient == MATE_PANEL_APPLET_ORIENT_RIGHT)) {
+ if (mc->preferences.panel_size_x == allocation->width)
+ return;
+ mc->preferences.panel_size_x = allocation->width;
+ } else {
+ if (mc->preferences.normal_size_y == allocation->height)
+ return;
+ mc->preferences.normal_size_y = allocation->height;
+ }
+
+ mc_applet_draw (mc);
+}
+
+static gboolean
+mini_commander_applet_fill (MatePanelApplet *applet)
+{
+ MCData *mc;
+ MateConfClient *client;
+ GtkActionGroup *action_group;
+ gchar *ui_path;
+
+ client = mateconf_client_get_default ();
+ if (mateconf_client_get_bool (client, "/desktop/mate/lockdown/inhibit_command_line", NULL)) {
+ GtkWidget *error_dialog;
+
+ error_dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ _("Command line has been disabled by your system administrator"));
+
+ gtk_window_set_resizable (GTK_WINDOW (error_dialog), FALSE);
+ gtk_dialog_set_has_separator (GTK_DIALOG (error_dialog), FALSE);
+ gtk_window_set_screen (GTK_WINDOW (error_dialog),
+ gtk_widget_get_screen (GTK_WIDGET (applet)));
+ gtk_dialog_run (GTK_DIALOG (error_dialog));
+ gtk_widget_destroy (error_dialog);
+
+ /* Note that this is only kosher if this is an out of process thing,
+ which we really are. We really don't need/want this applet when
+ command line is disabled */
+ exit (1);
+ }
+
+ g_set_application_name (_("Command Line"));
+
+ gtk_window_set_default_icon_name ("mate-mini-commander");
+
+ mc = g_new0 (MCData, 1);
+ mc->applet = applet;
+
+ mate_panel_applet_add_preferences (applet, "/schemas/apps/mini-commander/prefs", NULL);
+ mate_panel_applet_set_flags (applet, MATE_PANEL_APPLET_EXPAND_MINOR);
+ mc_load_preferences (mc);
+ command_line_init_stock_icons ();
+
+ g_signal_connect (mc->applet, "change_orient",
+ G_CALLBACK (mc_orient_changed), mc);
+ g_signal_connect (mc->applet, "size_allocate",
+ G_CALLBACK (mc_pixel_size_changed), mc);
+
+ mc->preferences.normal_size_y = mate_panel_applet_get_size (applet);
+ mc->orient = mate_panel_applet_get_orient (applet);
+ mc_applet_draw(mc);
+ gtk_widget_show (GTK_WIDGET (mc->applet));
+
+ g_signal_connect (mc->applet, "destroy", G_CALLBACK (mc_destroyed), mc);
+ g_signal_connect (mc->applet, "button_press_event",
+ G_CALLBACK (send_button_to_entry_event), mc);
+ g_signal_connect (mc->applet, "key_press_event",
+ G_CALLBACK (key_press_cb), mc);
+
+ action_group = gtk_action_group_new ("MiniCommander Applet Actions");
+ gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
+ gtk_action_group_add_actions (action_group,
+ mini_commander_menu_actions,
+ G_N_ELEMENTS (mini_commander_menu_actions),
+ mc);
+ ui_path = g_build_filename (MC_MENU_UI_DIR, "mini-commander-applet-menu.xml", NULL);
+ mate_panel_applet_setup_menu_from_file (mc->applet, ui_path, action_group);
+
+ if (mate_panel_applet_get_locked_down (mc->applet)) {
+ GtkAction *action;
+
+ action = gtk_action_group_get_action (action_group, "Props");
+ gtk_action_set_visible (action, FALSE);
+ }
+ g_object_unref (action_group);
+
+ set_atk_name_description (GTK_WIDGET (applet),
+ _("Mini-Commander applet"),
+ _("This applet adds a command line to the panel"));
+
+ return TRUE;
+}
+
+static gboolean
+mini_commander_applet_factory (MatePanelApplet *applet,
+ const gchar *iid,
+ gpointer data)
+{
+ gboolean retval = FALSE;
+
+ if (!strcmp (iid, "MiniCommanderApplet"))
+ retval = mini_commander_applet_fill(applet);
+
+ return retval;
+}
+
+MATE_PANEL_APPLET_OUT_PROCESS_FACTORY ("MiniCommanderAppletFactory",
+ PANEL_TYPE_APPLET,
+ "command-line",
+ mini_commander_applet_factory,
+ NULL)
diff --git a/mini-commander/src/mini-commander_applet.h b/mini-commander/src/mini-commander_applet.h
new file mode 100644
index 00000000..4b4f6ddf
--- /dev/null
+++ b/mini-commander/src/mini-commander_applet.h
@@ -0,0 +1,72 @@
+/*
+ * Mini-Commander Applet
+ * Copyright (C) 1998 Oliver Maruhn <[email protected]>,
+ * 2002 Sun Microsystems
+ *
+ * Authors: Oliver Maruhn <[email protected]>,
+ * Mark McLoughlin <[email protected]>
+ *
+ * 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
+ */
+
+#ifndef __MC_APPLET_H__
+#define __MC_APPLET_H__
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+G_BEGIN_DECLS
+
+#include <gtk/gtk.h>
+#include <mate-panel-applet.h>
+
+typedef struct _MCData MCData;
+
+#include "preferences.h"
+
+/* Constants */
+#define MC_NUM_LISTENERS 12
+#define MC_HISTORY_LIST_LENGTH 50
+#define MC_MAX_COMMAND_LENGTH 505
+#define MC_MAX_NUM_MACRO_PARAMETERS 100
+
+struct _MCData {
+ MatePanelApplet *applet;
+
+ GtkWidget *applet_box;
+
+ GtkWidget *entry;
+ GtkWidget *file_select;
+
+ int label_timeout;
+ int cmd_line_size_y;
+
+ MCPreferences preferences;
+ MCPrefsDialog prefs_dialog;
+
+ guint listeners [MC_NUM_LISTENERS];
+ gboolean error;
+ MatePanelAppletOrient orient;
+};
+
+void mc_applet_draw (MCData *mc);
+
+void set_atk_name_description (GtkWidget *widget,
+ const char *name,
+ const char *description);
+
+G_END_DECLS
+
+#endif /* __MC_APPLET_H__ */
diff --git a/mini-commander/src/org.mate.applets.MiniCommanderApplet.mate-panel-applet.in.in b/mini-commander/src/org.mate.applets.MiniCommanderApplet.mate-panel-applet.in.in
new file mode 100644
index 00000000..a1a80bef
--- /dev/null
+++ b/mini-commander/src/org.mate.applets.MiniCommanderApplet.mate-panel-applet.in.in
@@ -0,0 +1,16 @@
+[Applet Factory]
+Id=MiniCommanderAppletFactory
+Location=@LIBEXECDIR@/mini_commander_applet
+_Name=MiniCommander Applet Factory
+_Description=MiniCommander Applet Factory
+
+[MiniCommanderApplet]
+_Name=Command Line
+_Description=Mini-Commander
+Icon=mate-mini-commander.png
+MateComponentId=OAFIID:MATE_MiniCommanderApplet
+X-MATE-Bugzilla-Bugzilla=MATE
+X-MATE-Bugzilla-Product=mate-applets
+X-MATE-Bugzilla-Component=mini-commander
+X-MATE-Bugzilla-Version=@VERSION@
+X-MATE-Bugzilla-OtherBinaries=mini_commander_applet
diff --git a/mini-commander/src/org.mate.panel.applet.MiniCommanderAppletFactory.service.in b/mini-commander/src/org.mate.panel.applet.MiniCommanderAppletFactory.service.in
new file mode 100644
index 00000000..e7cf453f
--- /dev/null
+++ b/mini-commander/src/org.mate.panel.applet.MiniCommanderAppletFactory.service.in
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.mate.panel.applet.MiniCommanderAppletFactory
+Exec=/home/carlos/mate-cvs/libexec/mini_commander_applet
diff --git a/mini-commander/src/preferences.c b/mini-commander/src/preferences.c
new file mode 100644
index 00000000..4cc2705a
--- /dev/null
+++ b/mini-commander/src/preferences.c
@@ -0,0 +1,1128 @@
+/*
+ * Mini-Commander Applet
+ * Copyright (C) 1998, 1999 Oliver Maruhn <[email protected]>
+ * 2002 Sun Microsystems Inc.
+ *
+ * Authors: Oliver Maruhn <[email protected]>
+ * Mark McLoughlin <[email protected]>
+ *
+ * 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 <config.h>
+
+#include "preferences.h"
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include <mate-panel-applet.h>
+#include <mate-panel-applet-mateconf.h>
+#include <mateconf/mateconf-client.h>
+
+#include "mini-commander_applet.h"
+#include "command_line.h"
+#include "history.h"
+#include "mc-default-macros.h"
+
+enum {
+ COLUMN_PATTERN,
+ COLUMN_COMMAND
+};
+
+#define NEVER_SENSITIVE "never_sensitive"
+
+static GSList *mc_load_macros (MCData *mc);
+
+/* set sensitive and setup NEVER_SENSITIVE appropriately */
+static void
+hard_set_sensitive (GtkWidget *w, gboolean sensitivity)
+{
+ gtk_widget_set_sensitive (w, sensitivity);
+ g_object_set_data (G_OBJECT (w), NEVER_SENSITIVE,
+ GINT_TO_POINTER ( ! sensitivity));
+}
+
+
+/* set sensitive, but always insensitive if NEVER_SENSITIVE is set */
+static void
+soft_set_sensitive (GtkWidget *w, gboolean sensitivity)
+{
+ if (g_object_get_data (G_OBJECT (w), NEVER_SENSITIVE))
+ gtk_widget_set_sensitive (w, FALSE);
+ else
+ gtk_widget_set_sensitive (w, sensitivity);
+}
+
+gboolean
+mc_key_writable (MCData *mc, const char *key)
+{
+ gboolean writable;
+ char *fullkey;
+ static MateConfClient *client = NULL;
+ if (client == NULL)
+ client = mateconf_client_get_default ();
+
+ fullkey = mate_panel_applet_mateconf_get_full_key (mc->applet, key);
+
+ writable = mateconf_client_key_is_writable (client, fullkey, NULL);
+
+ g_free (fullkey);
+
+ return writable;
+}
+
+
+/* MateConf notification handlers
+ */
+static void
+show_default_theme_changed (MateConfClient *client,
+ guint cnxn_id,
+ MateConfEntry *entry,
+ MCData *mc)
+{
+ if (!entry->value || entry->value->type != MATECONF_VALUE_BOOL)
+ return;
+
+ mc->preferences.show_default_theme = mateconf_value_get_bool (entry->value);
+
+ mc_applet_draw (mc); /* FIXME: we shouldn't have to redraw the whole applet */
+}
+
+static void
+auto_complete_history_changed (MateConfClient *client,
+ guint cnxn_id,
+ MateConfEntry *entry,
+ MCData *mc)
+{
+ if (!entry->value || entry->value->type != MATECONF_VALUE_BOOL)
+ return;
+
+ mc->preferences.auto_complete_history = mateconf_value_get_bool (entry->value);
+}
+
+static void
+normal_size_x_changed (MateConfClient *client,
+ guint cnxn_id,
+ MateConfEntry *entry,
+ MCData *mc)
+{
+ if (!entry->value || entry->value->type != MATECONF_VALUE_INT)
+ return;
+
+ mc->preferences.normal_size_x = mateconf_value_get_int (entry->value);
+
+ mc_command_update_entry_size (mc);
+}
+
+static void
+normal_size_y_changed (MateConfClient *client,
+ guint cnxn_id,
+ MateConfEntry *entry,
+ MCData *mc)
+{
+ if (!entry->value || entry->value->type != MATECONF_VALUE_INT)
+ return;
+
+ mc->preferences.normal_size_y = mateconf_value_get_int (entry->value);
+
+ mc_applet_draw (mc); /* FIXME: we shouldn't have to redraw the whole applet */
+}
+
+static void
+cmd_line_color_fg_r_changed (MateConfClient *client,
+ guint cnxn_id,
+ MateConfEntry *entry,
+ MCData *mc)
+{
+ if (!entry->value || entry->value->type != MATECONF_VALUE_INT)
+ return;
+
+ mc->preferences.cmd_line_color_fg_r = mateconf_value_get_int (entry->value);
+
+ mc_command_update_entry_color (mc);
+}
+
+static void
+cmd_line_color_fg_g_changed (MateConfClient *client,
+ guint cnxn_id,
+ MateConfEntry *entry,
+ MCData *mc)
+{
+ if (!entry->value || entry->value->type != MATECONF_VALUE_INT)
+ return;
+
+ mc->preferences.cmd_line_color_fg_g = mateconf_value_get_int (entry->value);
+
+ mc_command_update_entry_color (mc);
+}
+
+static void
+cmd_line_color_fg_b_changed (MateConfClient *client,
+ guint cnxn_id,
+ MateConfEntry *entry,
+ MCData *mc)
+{
+ if (!entry->value || entry->value->type != MATECONF_VALUE_INT)
+ return;
+
+ mc->preferences.cmd_line_color_fg_b = mateconf_value_get_int (entry->value);
+
+ mc_command_update_entry_color (mc);
+}
+
+static void
+cmd_line_color_bg_r_changed (MateConfClient *client,
+ guint cnxn_id,
+ MateConfEntry *entry,
+ MCData *mc)
+{
+ if (!entry->value || entry->value->type != MATECONF_VALUE_INT)
+ return;
+
+ mc->preferences.cmd_line_color_bg_r = mateconf_value_get_int (entry->value);
+
+ mc_command_update_entry_color (mc);
+}
+
+static void
+cmd_line_color_bg_g_changed (MateConfClient *client,
+ guint cnxn_id,
+ MateConfEntry *entry,
+ MCData *mc)
+{
+ if (!entry->value || entry->value->type != MATECONF_VALUE_INT)
+ return;
+
+ mc->preferences.cmd_line_color_bg_g = mateconf_value_get_int (entry->value);
+
+ mc_command_update_entry_color (mc);
+}
+
+static void
+cmd_line_color_bg_b_changed (MateConfClient *client,
+ guint cnxn_id,
+ MateConfEntry *entry,
+ MCData *mc)
+{
+ if (!entry->value || entry->value->type != MATECONF_VALUE_INT)
+ return;
+
+ mc->preferences.cmd_line_color_bg_b = mateconf_value_get_int (entry->value);
+
+ mc_command_update_entry_color (mc);
+}
+
+static gboolean
+load_macros_in_idle (MCData *mc)
+{
+ mc->preferences.idle_macros_loader_id = 0;
+
+ if (mc->preferences.macros)
+ mc_macros_free (mc->preferences.macros);
+
+ mc->preferences.macros = mc_load_macros (mc);
+
+ return FALSE;
+}
+
+static void
+macros_changed (MateConfClient *client,
+ guint cnxn_id,
+ MateConfEntry *entry,
+ MCData *mc)
+{
+ if (!entry->value || entry->value->type != MATECONF_VALUE_LIST)
+ return;
+
+ if (mc->preferences.idle_macros_loader_id == 0)
+ mc->preferences.idle_macros_loader_id =
+ g_idle_add ((GSourceFunc) load_macros_in_idle, mc);
+}
+
+/* Properties dialog
+ */
+static void
+save_macros_to_mateconf (MCData *mc)
+{
+ MCPrefsDialog *dialog;
+ GtkTreeIter iter;
+ MateConfValue *patterns;
+ MateConfValue *commands;
+ GSList *pattern_list = NULL;
+ GSList *command_list = NULL;
+ MateConfClient *client;
+
+ dialog = &mc->prefs_dialog;
+
+ if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dialog->macros_store), &iter))
+ return;
+
+ patterns = mateconf_value_new (MATECONF_VALUE_LIST);
+ mateconf_value_set_list_type (patterns, MATECONF_VALUE_STRING);
+
+ commands = mateconf_value_new (MATECONF_VALUE_LIST);
+ mateconf_value_set_list_type (commands, MATECONF_VALUE_STRING);
+
+ do {
+ char *pattern = NULL;
+ char *command = NULL;
+
+ gtk_tree_model_get (
+ GTK_TREE_MODEL (dialog->macros_store), &iter,
+ 0, &pattern,
+ 1, &command,
+ -1);
+
+ pattern_list = g_slist_prepend (pattern_list,
+ mateconf_value_new_from_string (MATECONF_VALUE_STRING, pattern, NULL));
+ command_list = g_slist_prepend (command_list,
+ mateconf_value_new_from_string (MATECONF_VALUE_STRING, command, NULL));
+ } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (dialog->macros_store), &iter));
+
+ pattern_list = g_slist_reverse (pattern_list);
+ command_list = g_slist_reverse (command_list);
+
+ mateconf_value_set_list_nocopy (patterns, pattern_list); pattern_list = NULL;
+ mateconf_value_set_list_nocopy (commands, command_list); command_list = NULL;
+
+ client = mateconf_client_get_default ();
+ mateconf_client_set (client, "/apps/mini-commander/macro_patterns",
+ patterns, NULL);
+ mateconf_client_set (client, "/apps/mini-commander/macro_commands",
+ commands, NULL);
+
+ mateconf_value_free (patterns);
+ mateconf_value_free (commands);
+}
+
+static gboolean
+duplicate_pattern (MCData *mc,
+ const char *new_pattern)
+{
+ MCPrefsDialog *dialog;
+ GtkTreeIter iter;
+
+ dialog = &mc->prefs_dialog;
+
+ if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dialog->macros_store), &iter))
+ return FALSE;
+
+ do {
+ char *pattern = NULL;
+
+ gtk_tree_model_get (
+ GTK_TREE_MODEL (dialog->macros_store), &iter,
+ 0, &pattern, -1);
+
+ if (!strcmp (pattern, new_pattern))
+ return TRUE;
+
+ } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (dialog->macros_store), &iter));
+
+
+ return FALSE;
+}
+
+static void
+show_help_section (GtkWindow *dialog, gchar *section)
+{
+ GError *error = NULL;
+ char *uri;
+
+ if (section)
+ uri = g_strdup_printf ("ghelp:command-line?%s", section);
+ else
+ uri = g_strdup ("ghelp:command-line");
+
+ gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (dialog)),
+ uri,
+ gtk_get_current_event_time (),
+ &error);
+
+ g_free (uri);
+
+ if (error) {
+ GtkWidget *error_dialog;
+
+ error_dialog = gtk_message_dialog_new (
+ NULL,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ _("There was an error displaying help: %s"),
+ error->message);
+
+ g_signal_connect (error_dialog, "response",
+ G_CALLBACK (gtk_widget_destroy),
+ NULL);
+
+ gtk_window_set_resizable (GTK_WINDOW (error_dialog), FALSE);
+ gtk_window_set_screen (GTK_WINDOW (error_dialog),
+ gtk_widget_get_screen (GTK_WIDGET (dialog)));
+ gtk_widget_show (error_dialog);
+ g_error_free (error);
+ }
+}
+
+static void
+add_response (GtkWidget *window,
+ int id,
+ MCData *mc)
+{
+ MCPrefsDialog *dialog;
+
+ dialog = &mc->prefs_dialog;
+
+ switch (id) {
+ case GTK_RESPONSE_OK: {
+ const char *pattern;
+ const char *command;
+ GtkTreeIter iter;
+ const char *error_message = NULL;
+
+ pattern = gtk_entry_get_text (GTK_ENTRY (dialog->pattern_entry));
+ command = gtk_entry_get_text (GTK_ENTRY (dialog->command_entry));
+
+ if (!pattern || !pattern [0])
+ error_message = _("You must specify a pattern");
+
+ if (!command || !command [0])
+ error_message = error_message != NULL ?
+ _("You must specify a pattern and a command") :
+ _("You must specify a command");
+
+ if (!error_message && duplicate_pattern (mc, pattern))
+ error_message = _("You may not specify duplicate patterns");
+
+ if (error_message) {
+ GtkWidget *error_dialog;
+
+ error_dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ error_message);
+
+ g_signal_connect (error_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
+ gtk_window_set_resizable (GTK_WINDOW (error_dialog), FALSE);
+ gtk_widget_show_all (error_dialog);
+ return;
+ }
+
+ gtk_widget_hide (window);
+
+ gtk_list_store_append (dialog->macros_store, &iter);
+ gtk_list_store_set (dialog->macros_store, &iter,
+ COLUMN_PATTERN, pattern,
+ COLUMN_COMMAND, command,
+ -1);
+
+ gtk_tree_view_columns_autosize (GTK_TREE_VIEW (dialog->macros_tree));
+
+ gtk_editable_delete_text (GTK_EDITABLE (dialog->pattern_entry), 0, -1);
+ gtk_editable_delete_text (GTK_EDITABLE (dialog->command_entry), 0, -1);
+
+ save_macros_to_mateconf (mc);
+ }
+ break;
+ case GTK_RESPONSE_HELP:
+ show_help_section (GTK_WINDOW (window), "command-line-prefs-2");
+ break;
+ case GTK_RESPONSE_CLOSE:
+ default:
+ gtk_editable_delete_text (GTK_EDITABLE (dialog->pattern_entry), 0, -1);
+ gtk_editable_delete_text (GTK_EDITABLE (dialog->command_entry), 0, -1);
+ gtk_widget_hide (window);
+ break;
+ }
+}
+
+static void
+setup_add_dialog (GtkBuilder *builder,
+ MCData *mc)
+{
+ MCPrefsDialog *dialog;
+
+ dialog = &mc->prefs_dialog;
+
+ g_signal_connect (dialog->macro_add_dialog, "response",
+ G_CALLBACK (add_response), mc);
+
+ dialog->pattern_entry = GTK_WIDGET (gtk_builder_get_object (builder, "pattern_entry"));
+ dialog->command_entry = GTK_WIDGET (gtk_builder_get_object (builder, "command_entry"));
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog->macro_add_dialog), GTK_RESPONSE_OK);
+}
+
+static void
+macro_add (GtkWidget *button,
+ MCData *mc)
+{
+ if (!mc->prefs_dialog.macro_add_dialog) {
+ GtkBuilder *builder;
+
+ builder = gtk_builder_new ();
+ gtk_builder_add_from_file (builder, GTK_BUILDERDIR "/mini-commander.ui", NULL);
+
+ mc->prefs_dialog.macro_add_dialog = GTK_WIDGET (gtk_builder_get_object (builder, "mc_macro_add_dialog"));
+
+ g_object_add_weak_pointer (G_OBJECT (mc->prefs_dialog.macro_add_dialog),
+ (gpointer *) &mc->prefs_dialog.macro_add_dialog);
+
+ setup_add_dialog (builder, mc);
+
+ g_object_unref (builder);
+ }
+
+ gtk_window_set_screen (GTK_WINDOW (mc->prefs_dialog.macro_add_dialog),
+ gtk_widget_get_screen (GTK_WIDGET (mc->applet)));
+ gtk_widget_grab_focus (mc->prefs_dialog.pattern_entry);
+ gtk_window_present (GTK_WINDOW (mc->prefs_dialog.macro_add_dialog));
+}
+
+static void
+macro_delete (GtkWidget *button,
+ MCData *mc)
+{
+ MCPrefsDialog *dialog;
+ GtkTreeModel *model = NULL;
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+
+ dialog = &mc->prefs_dialog;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->macros_tree));
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return;
+
+ gtk_list_store_remove (dialog->macros_store, &iter);
+
+ save_macros_to_mateconf (mc);
+}
+
+static void
+show_macros_list (MCData *mc)
+{
+ MCPrefsDialog *dialog;
+ GtkTreeIter iter;
+ GSList *l;
+
+ dialog = &mc->prefs_dialog;
+
+ gtk_list_store_clear (dialog->macros_store);
+
+ for (l = mc->preferences.macros; l; l = l->next) {
+ MCMacro *macro = l->data;
+
+ gtk_list_store_append (dialog->macros_store, &iter);
+ gtk_list_store_set (dialog->macros_store, &iter,
+ COLUMN_PATTERN, macro->pattern,
+ COLUMN_COMMAND, macro->command,
+ -1);
+ }
+
+ gtk_tree_view_columns_autosize (GTK_TREE_VIEW (dialog->macros_tree));
+}
+
+static void
+macro_edited (GtkCellRendererText *renderer,
+ const char *path,
+ const char *new_text,
+ MCData *mc)
+{
+ MCPrefsDialog *dialog;
+ GtkTreeIter iter;
+ int col;
+
+ dialog = &mc->prefs_dialog;
+
+ col = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (renderer), "column"));
+
+ if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (dialog->macros_store), &iter, path))
+ gtk_list_store_set (dialog->macros_store, &iter, col, new_text, -1);
+
+ save_macros_to_mateconf (mc);
+}
+
+static void
+foreground_color_set (GtkColorButton *color_button,
+ MCData *mc)
+{
+ GdkColor color;
+
+ gtk_color_button_get_color (color_button, &color);
+
+ mate_panel_applet_mateconf_set_int (mc->applet, "cmd_line_color_fg_r", (int) color.red, NULL);
+ mate_panel_applet_mateconf_set_int (mc->applet, "cmd_line_color_fg_g", (int) color.green, NULL);
+ mate_panel_applet_mateconf_set_int (mc->applet, "cmd_line_color_fg_b", (int) color.blue, NULL);
+}
+
+static void
+background_color_set (GtkColorButton *color_button,
+ MCData *mc)
+{
+ GdkColor color;
+
+ gtk_color_button_get_color (color_button, &color);
+
+ mate_panel_applet_mateconf_set_int (mc->applet, "cmd_line_color_bg_r", (int) color.red, NULL);
+ mate_panel_applet_mateconf_set_int (mc->applet, "cmd_line_color_bg_g", (int) color.green, NULL);
+ mate_panel_applet_mateconf_set_int (mc->applet, "cmd_line_color_bg_b", (int) color.blue, NULL);
+}
+
+static void
+auto_complete_history_toggled (GtkToggleButton *toggle,
+ MCData *mc)
+{
+ gboolean auto_complete_history;
+
+ auto_complete_history = gtk_toggle_button_get_active (toggle);
+ if (auto_complete_history == mc->preferences.auto_complete_history)
+ return;
+
+ mate_panel_applet_mateconf_set_bool (mc->applet, "autocomplete_history",
+ auto_complete_history, NULL);
+}
+
+static void
+size_value_changed (GtkSpinButton *spinner,
+ MCData *mc)
+{
+ int size;
+
+ size = gtk_spin_button_get_value (spinner);
+ if (size == mc->preferences.normal_size_x)
+ return;
+
+ mate_panel_applet_mateconf_set_int (mc->applet, "normal_size_x", size, NULL);
+}
+
+static void
+use_default_theme_toggled (GtkToggleButton *toggle,
+ MCData *mc)
+{
+ gboolean use_default_theme;
+
+ use_default_theme = gtk_toggle_button_get_active (toggle);
+ if (use_default_theme == mc->preferences.show_default_theme)
+ return;
+
+ soft_set_sensitive (mc->prefs_dialog.fg_color_picker, !use_default_theme);
+ soft_set_sensitive (mc->prefs_dialog.bg_color_picker, !use_default_theme);
+
+ mate_panel_applet_mateconf_set_bool (mc->applet, "show_default_theme", use_default_theme, NULL);
+}
+
+static void
+preferences_response (MCPrefsDialog *dialog,
+ int id,
+ MCData *mc)
+{
+ switch (id) {
+ case GTK_RESPONSE_HELP:
+ show_help_section (GTK_WINDOW (dialog), "command-line-prefs-0");
+ break;
+ case GTK_RESPONSE_CLOSE:
+ default: {
+ GtkTreeViewColumn *col;
+
+ dialog = &mc->prefs_dialog;
+
+ /* A hack to make sure 'edited' on the renderer if we
+ * close the dialog while editing.
+ */
+ col = gtk_tree_view_get_column (GTK_TREE_VIEW (dialog->macros_tree), 0);
+ if (col->editable_widget && GTK_IS_CELL_EDITABLE (col->editable_widget))
+ gtk_cell_editable_editing_done (col->editable_widget);
+
+ col = gtk_tree_view_get_column (GTK_TREE_VIEW (dialog->macros_tree), 1);
+ if (col->editable_widget && GTK_IS_CELL_EDITABLE (col->editable_widget))
+ gtk_cell_editable_editing_done (col->editable_widget);
+
+ gtk_widget_hide (dialog->dialog);
+ }
+ break;
+ }
+}
+
+static void
+mc_preferences_setup_dialog (GtkBuilder *builder,
+ MCData *mc)
+{
+ MCPrefsDialog *dialog;
+ GtkCellRenderer *renderer;
+ MateConfClient *client;
+ GdkColor color;
+
+ dialog = &mc->prefs_dialog;
+
+ g_signal_connect (dialog->dialog, "response",
+ G_CALLBACK (preferences_response), mc);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog->dialog), GTK_RESPONSE_CLOSE);
+ gtk_window_set_default_size (GTK_WINDOW (dialog->dialog), 400, -1);
+
+ dialog->auto_complete_history_toggle = GTK_WIDGET (gtk_builder_get_object (builder, "auto_complete_history_toggle"));
+ dialog->size_spinner = GTK_WIDGET (gtk_builder_get_object (builder, "size_spinner"));
+ dialog->use_default_theme_toggle = GTK_WIDGET (gtk_builder_get_object (builder, "default_theme_toggle"));
+ dialog->fg_color_picker = GTK_WIDGET (gtk_builder_get_object (builder, "fg_color_picker"));
+ dialog->bg_color_picker = GTK_WIDGET (gtk_builder_get_object (builder, "bg_color_picker"));
+ dialog->macros_tree = GTK_WIDGET (gtk_builder_get_object (builder, "macros_tree"));
+ dialog->delete_button = GTK_WIDGET (gtk_builder_get_object (builder, "delete_button"));
+ dialog->add_button = GTK_WIDGET (gtk_builder_get_object (builder, "add_button"));
+
+ /* History based autocompletion */
+ g_signal_connect (dialog->auto_complete_history_toggle, "toggled",
+ G_CALLBACK (auto_complete_history_toggled), mc);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->auto_complete_history_toggle),
+ mc->preferences.auto_complete_history);
+ if ( ! mc_key_writable (mc, "autocomplete_history"))
+ hard_set_sensitive (dialog->auto_complete_history_toggle, FALSE);
+
+ /* Width */
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->size_spinner), mc->preferences.normal_size_x);
+ g_signal_connect (dialog->size_spinner, "value_changed",
+ G_CALLBACK (size_value_changed), mc);
+ if ( ! mc_key_writable (mc, "normal_size_x")) {
+ hard_set_sensitive (dialog->size_spinner, FALSE);
+ hard_set_sensitive (GTK_WIDGET (gtk_builder_get_object (builder, "size_label")), FALSE);
+ hard_set_sensitive (GTK_WIDGET (gtk_builder_get_object (builder, "size_post_label")), FALSE);
+ }
+
+ /* Use default theme */
+ g_signal_connect (dialog->use_default_theme_toggle, "toggled",
+ G_CALLBACK (use_default_theme_toggled), mc);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->use_default_theme_toggle),
+ mc->preferences.show_default_theme);
+ if ( ! mc_key_writable (mc, "show_default_theme"))
+ hard_set_sensitive (dialog->use_default_theme_toggle, FALSE);
+
+ /* Foreground color */
+ g_signal_connect (dialog->fg_color_picker, "color_set",
+ G_CALLBACK (foreground_color_set), mc);
+ color.red = mc->preferences.cmd_line_color_fg_r;
+ color.green = mc->preferences.cmd_line_color_fg_g;
+ color.blue = mc->preferences.cmd_line_color_fg_b;
+ gtk_color_button_set_color (GTK_COLOR_BUTTON (dialog->fg_color_picker), &color);
+ soft_set_sensitive (dialog->fg_color_picker, !mc->preferences.show_default_theme);
+
+ if ( ! mc_key_writable (mc, "cmd_line_color_fg_r") ||
+ ! mc_key_writable (mc, "cmd_line_color_fg_g") ||
+ ! mc_key_writable (mc, "cmd_line_color_fg_b")) {
+ hard_set_sensitive (dialog->fg_color_picker, FALSE);
+ hard_set_sensitive (GTK_WIDGET (gtk_builder_get_object (builder, "fg_color_label")), FALSE);
+ }
+
+ /* Background color */
+ g_signal_connect (dialog->bg_color_picker, "color_set",
+ G_CALLBACK (background_color_set), mc);
+ color.red = mc->preferences.cmd_line_color_bg_r;
+ color.green = mc->preferences.cmd_line_color_bg_g;
+ color.blue = mc->preferences.cmd_line_color_bg_b;
+ gtk_color_button_set_color (GTK_COLOR_BUTTON (dialog->bg_color_picker), &color);
+ soft_set_sensitive (dialog->bg_color_picker, !mc->preferences.show_default_theme);
+
+ if ( ! mc_key_writable (mc, "cmd_line_color_bg_r") ||
+ ! mc_key_writable (mc, "cmd_line_color_bg_g") ||
+ ! mc_key_writable (mc, "cmd_line_color_bg_b")) {
+ hard_set_sensitive (dialog->bg_color_picker, FALSE);
+ hard_set_sensitive (GTK_WIDGET (gtk_builder_get_object (builder, "bg_color_label")), FALSE);
+ }
+
+
+ /* Macros Delete and Add buttons */
+ g_signal_connect (dialog->delete_button, "clicked", G_CALLBACK (macro_delete), mc);
+ g_signal_connect (dialog->add_button, "clicked", G_CALLBACK (macro_add), mc);
+
+ client = mateconf_client_get_default ();
+ if ( ! mateconf_client_key_is_writable (client,
+ "/apps/mini-commander/macro_patterns", NULL) ||
+ ! mateconf_client_key_is_writable (client,
+ "/apps/mini-commander/macro_commands", NULL)) {
+ hard_set_sensitive (dialog->add_button, FALSE);
+ hard_set_sensitive (dialog->delete_button, FALSE);
+ hard_set_sensitive (dialog->macros_tree, FALSE);
+ }
+
+ /* Macros tree view */
+ dialog->macros_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING, NULL);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->macros_tree),
+ GTK_TREE_MODEL (dialog->macros_store));
+
+ renderer = g_object_new (GTK_TYPE_CELL_RENDERER_TEXT, "editable", TRUE, NULL);
+ g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (COLUMN_PATTERN));
+ g_signal_connect (renderer, "edited", G_CALLBACK (macro_edited), mc);
+
+ gtk_tree_view_insert_column_with_attributes (
+ GTK_TREE_VIEW (dialog->macros_tree), -1,
+ _("Pattern"), renderer,
+ "text", COLUMN_PATTERN,
+ NULL);
+
+ renderer = g_object_new (GTK_TYPE_CELL_RENDERER_TEXT, "editable", TRUE, NULL);
+ g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (COLUMN_COMMAND));
+ g_signal_connect (renderer, "edited", G_CALLBACK (macro_edited), mc);
+
+ gtk_tree_view_insert_column_with_attributes (
+ GTK_TREE_VIEW (dialog->macros_tree), -1,
+ _("Command"), renderer,
+ "text", COLUMN_COMMAND,
+ NULL);
+
+ show_macros_list (mc);
+}
+
+void
+mc_show_preferences (GtkAction *action,
+ MCData *mc)
+{
+ if (!mc->prefs_dialog.dialog) {
+ GtkBuilder *builder;
+
+ builder = gtk_builder_new ();
+ gtk_builder_add_from_file (builder, GTK_BUILDERDIR "/mini-commander.ui", NULL);
+
+ mc->prefs_dialog.dialog = GTK_WIDGET (gtk_builder_get_object (builder,
+ "mc_preferences_dialog"));
+
+ g_object_add_weak_pointer (G_OBJECT (mc->prefs_dialog.dialog),
+ (gpointer *) &mc->prefs_dialog.dialog);
+
+ mc_preferences_setup_dialog (builder, mc);
+
+ g_object_unref (builder);
+ }
+
+ gtk_window_set_screen (GTK_WINDOW (mc->prefs_dialog.dialog),
+ gtk_widget_get_screen (GTK_WIDGET (mc->applet)));
+ gtk_window_present (GTK_WINDOW (mc->prefs_dialog.dialog));
+}
+
+static MCMacro *
+mc_macro_new (const char *pattern,
+ const char *command)
+{
+ MCMacro *macro;
+
+ g_return_val_if_fail (pattern != NULL, NULL);
+ g_return_val_if_fail (command != NULL, NULL);
+
+ macro = g_new0 (MCMacro, 1);
+
+ macro->pattern = g_strdup (pattern);
+ macro->command = g_strdup (command);
+
+ if (macro->pattern [0] != '\0')
+ regcomp (&macro->regex, macro->pattern, REG_EXTENDED);
+
+ return macro;
+}
+
+void
+mc_macros_free (GSList *macros)
+{
+ GSList *l;
+
+ for (l = macros; l; l = l->next) {
+ MCMacro *macro = l->data;
+
+ regfree(&macro->regex);
+ g_free (macro->pattern);
+ g_free (macro->command);
+ g_free (macro);
+ }
+
+ g_slist_free (macros);
+}
+
+static GSList *
+mc_load_macros (MCData *mc)
+{
+ MateConfValue *macro_patterns;
+ MateConfValue *macro_commands;
+ GSList *macros_list = NULL;
+ MateConfClient *client;
+
+ client = mateconf_client_get_default ();
+ macro_patterns = mateconf_client_get (client,
+ "/apps/mini-commander/macro_patterns", NULL);
+ macro_commands = mateconf_client_get (client,
+ "/apps/mini-commander/macro_commands", NULL);
+
+ if (macro_patterns && macro_commands) {
+ GSList *patterns;
+ GSList *commands;
+
+ patterns = mateconf_value_get_list (macro_patterns);
+ commands = mateconf_value_get_list (macro_commands);
+
+ for (; patterns && commands; patterns = patterns->next, commands = commands->next) {
+ MateConfValue *v1 = patterns->data;
+ MateConfValue *v2 = commands->data;
+ MCMacro *macro;
+ const char *pattern, *command;
+
+ pattern = mateconf_value_get_string (v1);
+ command = mateconf_value_get_string (v2);
+
+ if (!(macro = mc_macro_new (pattern, command)))
+ continue;
+
+ macros_list = g_slist_prepend (macros_list, macro);
+ }
+ } else {
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (mc_default_macros); i++)
+ macros_list = g_slist_prepend (macros_list,
+ mc_macro_new (mc_default_macros [i].pattern,
+ mc_default_macros [i].command));
+ }
+
+ macros_list = g_slist_reverse (macros_list);
+
+ if (macro_commands)
+ mateconf_value_free (macro_commands);
+
+ if (macro_patterns)
+ mateconf_value_free (macro_patterns);
+
+ return macros_list;
+}
+
+static void
+mc_setup_listeners (MCData *mc)
+{
+ MateConfClient *client;
+ char *key;
+ int i = 0;
+
+ client = mateconf_client_get_default ();
+ mateconf_client_add_dir (client, "/apps/mini-commander",
+ MATECONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+
+ key = mate_panel_applet_mateconf_get_full_key (MATE_PANEL_APPLET (mc->applet), "show_default_theme");
+ mc->listeners [i++] = mateconf_client_notify_add (
+ client, key,
+ (MateConfClientNotifyFunc) show_default_theme_changed,
+ mc,
+ NULL, NULL);
+ g_free (key);
+
+ key = mate_panel_applet_mateconf_get_full_key (MATE_PANEL_APPLET (mc->applet), "autocomplete_history");
+ mc->listeners [i++] = mateconf_client_notify_add (
+ client, key,
+ (MateConfClientNotifyFunc) auto_complete_history_changed,
+ mc,
+ NULL, NULL);
+ g_free (key);
+
+ key = mate_panel_applet_mateconf_get_full_key (MATE_PANEL_APPLET (mc->applet), "normal_size_x");
+ mc->listeners [i++] = mateconf_client_notify_add (
+ client, key,
+ (MateConfClientNotifyFunc) normal_size_x_changed,
+ mc,
+ NULL, NULL);
+ g_free (key);
+
+ key = mate_panel_applet_mateconf_get_full_key (MATE_PANEL_APPLET (mc->applet), "normal_size_y");
+ mc->listeners [i++] = mateconf_client_notify_add (
+ client, key,
+ (MateConfClientNotifyFunc) normal_size_y_changed,
+ mc,
+ NULL, NULL);
+ g_free (key);
+
+ key = mate_panel_applet_mateconf_get_full_key (MATE_PANEL_APPLET (mc->applet), "cmd_line_color_fg_r");
+ mc->listeners [i++] = mateconf_client_notify_add (
+ client, key,
+ (MateConfClientNotifyFunc) cmd_line_color_fg_r_changed,
+ mc,
+ NULL, NULL);
+ g_free (key);
+
+
+ key = mate_panel_applet_mateconf_get_full_key (MATE_PANEL_APPLET (mc->applet), "cmd_line_color_fg_g");
+ mc->listeners [i++] = mateconf_client_notify_add (
+ client, key,
+ (MateConfClientNotifyFunc) cmd_line_color_fg_g_changed,
+ mc,
+ NULL, NULL);
+ g_free (key);
+
+
+ key = mate_panel_applet_mateconf_get_full_key (MATE_PANEL_APPLET (mc->applet), "cmd_line_color_fg_b");
+ mc->listeners [i++] = mateconf_client_notify_add (
+ client, key,
+ (MateConfClientNotifyFunc) cmd_line_color_fg_b_changed,
+ mc,
+ NULL, NULL);
+ g_free (key);
+
+ key = mate_panel_applet_mateconf_get_full_key (MATE_PANEL_APPLET (mc->applet), "cmd_line_color_bg_r");
+ mc->listeners [i++] = mateconf_client_notify_add (
+ client, key,
+ (MateConfClientNotifyFunc) cmd_line_color_bg_r_changed,
+ mc,
+ NULL, NULL);
+ g_free (key);
+
+ key = mate_panel_applet_mateconf_get_full_key (MATE_PANEL_APPLET (mc->applet), "cmd_line_color_bg_g");
+ mc->listeners [i++] = mateconf_client_notify_add (
+ client, key,
+ (MateConfClientNotifyFunc) cmd_line_color_bg_g_changed,
+ mc,
+ NULL, NULL);
+ g_free (key);
+
+ key = mate_panel_applet_mateconf_get_full_key (MATE_PANEL_APPLET (mc->applet), "cmd_line_color_bg_b");
+ mc->listeners [i++] = mateconf_client_notify_add (
+ client, key,
+ (MateConfClientNotifyFunc) cmd_line_color_bg_b_changed,
+ mc,
+ NULL, NULL);
+ g_free (key);
+
+ mc->listeners [i++] = mateconf_client_notify_add (
+ client, "/apps/mini-commander/macro_patterns",
+ (MateConfClientNotifyFunc) macros_changed,
+ mc,
+ NULL, NULL);
+
+ mc->listeners [i++] = mateconf_client_notify_add (
+ client, "/apps/mini-commander/macro_commands",
+ (MateConfClientNotifyFunc) macros_changed,
+ mc,
+ NULL, NULL);
+
+ g_assert (i == MC_NUM_LISTENERS);
+
+ g_object_unref (client);
+}
+
+void
+mc_load_preferences (MCData *mc)
+{
+ MateConfValue *history;
+ GError *error = NULL;
+
+ g_return_if_fail (mc != NULL);
+ g_return_if_fail (PANEL_IS_APPLET (mc->applet));
+
+ mc->preferences.show_default_theme =
+ mate_panel_applet_mateconf_get_bool (mc->applet, "show_default_theme", &error);
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ mc->preferences.show_default_theme = MC_DEFAULT_SHOW_DEFAULT_THEME;
+ }
+
+ mc->preferences.auto_complete_history =
+ mate_panel_applet_mateconf_get_bool (mc->applet, "autocomplete_history", &error);
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ mc->preferences.auto_complete_history = MC_DEFAULT_AUTO_COMPLETE_HISTORY;
+ }
+
+ mc->preferences.normal_size_x =
+ mate_panel_applet_mateconf_get_int (mc->applet, "normal_size_x", &error);
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ mc->preferences.normal_size_x = MC_DEFAULT_NORMAL_SIZE_X;
+ }
+ mc->preferences.normal_size_x = MAX (mc->preferences.normal_size_x, 50);
+
+ mc->preferences.normal_size_y =
+ mate_panel_applet_mateconf_get_int (mc->applet, "normal_size_y", &error);
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ mc->preferences.normal_size_y = MC_DEFAULT_NORMAL_SIZE_Y;
+ }
+ mc->preferences.normal_size_y = CLAMP (mc->preferences.normal_size_y, 5, 200);
+
+ mc->preferences.cmd_line_color_fg_r =
+ mate_panel_applet_mateconf_get_int (mc->applet, "cmd_line_color_fg_r", &error);
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ mc->preferences.cmd_line_color_fg_r = MC_DEFAULT_CMD_LINE_COLOR_FG_R;
+ }
+
+ mc->preferences.cmd_line_color_fg_g =
+ mate_panel_applet_mateconf_get_int (mc->applet, "cmd_line_color_fg_g", &error);
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ mc->preferences.cmd_line_color_fg_g = MC_DEFAULT_CMD_LINE_COLOR_FG_G;
+ }
+
+ mc->preferences.cmd_line_color_fg_b =
+ mate_panel_applet_mateconf_get_int (mc->applet, "cmd_line_color_fg_b", &error);
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ mc->preferences.cmd_line_color_fg_b = MC_DEFAULT_CMD_LINE_COLOR_FG_B;
+ }
+
+ mc->preferences.cmd_line_color_bg_r =
+ mate_panel_applet_mateconf_get_int (mc->applet, "cmd_line_color_bg_r", &error);
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ mc->preferences.cmd_line_color_bg_r = MC_DEFAULT_CMD_LINE_COLOR_BG_R;
+ }
+
+ mc->preferences.cmd_line_color_bg_g =
+ mate_panel_applet_mateconf_get_int (mc->applet, "cmd_line_color_bg_g", &error);
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ mc->preferences.cmd_line_color_bg_g = MC_DEFAULT_CMD_LINE_COLOR_BG_G;
+ }
+
+ mc->preferences.cmd_line_color_bg_b =
+ mate_panel_applet_mateconf_get_int (mc->applet, "cmd_line_color_bg_b", &error);
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ mc->preferences.cmd_line_color_bg_b = MC_DEFAULT_CMD_LINE_COLOR_BG_B;
+ }
+
+ mc->preferences.macros = mc_load_macros (mc);
+
+ history = mate_panel_applet_mateconf_get_value (mc->applet, "history", NULL);
+ if (history) {
+ GSList *l;
+
+ for (l = mateconf_value_get_list (history); l; l = l->next) {
+ const char *entry = NULL;
+
+ if ((entry = mateconf_value_get_string (l->data)))
+ append_history_entry (mc, entry, TRUE);
+ }
+
+ mateconf_value_free (history);
+ }
+
+ mc_setup_listeners (mc);
+
+ mc->preferences.idle_macros_loader_id = 0;
+}
diff --git a/mini-commander/src/preferences.h b/mini-commander/src/preferences.h
new file mode 100644
index 00000000..875a7fa2
--- /dev/null
+++ b/mini-commander/src/preferences.h
@@ -0,0 +1,109 @@
+/*
+ * Mini-Commander Applet
+ * Copyright (C) 1998, 1999 Oliver Maruhn <[email protected]>
+ * 2002 Sun Microsystems Inc.
+ *
+ * Authors: Oliver Maruhn <[email protected]>
+ * Mark McLoughlin <[email protected]>
+ *
+ * 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
+ */
+
+#ifndef __PREFERENCES_H__
+#define __PREFERENCES_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#include <sys/types.h>
+#include <regex.h>
+
+#include <gtk/gtk.h>
+
+typedef struct {
+ char *pattern;
+ char *command;
+ regex_t regex;
+} MCMacro;
+
+typedef struct {
+ int show_default_theme;
+ int auto_complete_history;
+
+ int normal_size_x;
+ int normal_size_y;
+ int panel_size_x;
+
+ int cmd_line_color_fg_r;
+ int cmd_line_color_fg_g;
+ int cmd_line_color_fg_b;
+ int cmd_line_color_bg_r;
+ int cmd_line_color_bg_g;
+ int cmd_line_color_bg_b;
+
+ GSList *macros;
+
+ guint idle_macros_loader_id;
+
+} MCPreferences;
+
+typedef struct {
+ GtkWidget *dialog;
+ GtkWidget *auto_complete_history_toggle;
+ GtkWidget *size_spinner;
+ GtkWidget *use_default_theme_toggle;
+ GtkWidget *fg_color_picker;
+ GtkWidget *bg_color_picker;
+ GtkWidget *macros_tree;
+ GtkWidget *delete_button;
+ GtkWidget *add_button;
+
+ GtkListStore *macros_store;
+
+ GtkWidget *macro_add_dialog;
+ GtkWidget *pattern_entry;
+ GtkWidget *command_entry;
+} MCPrefsDialog;
+
+/* Defaults */
+#define MC_DEFAULT_SHOW_DEFAULT_THEME TRUE
+#define MC_DEFAULT_SHOW_HANDLE FALSE
+#define MC_DEFAULT_SHOW_FRAME FALSE
+#define MC_DEFAULT_AUTO_COMPLETE_HISTORY TRUE
+
+#define MC_DEFAULT_NORMAL_SIZE_X 150
+#define MC_DEFAULT_NORMAL_SIZE_Y 48
+
+#define MC_DEFAULT_CMD_LINE_COLOR_FG_R 0xfc65
+#define MC_DEFAULT_CMD_LINE_COLOR_FG_G 0xfc65
+#define MC_DEFAULT_CMD_LINE_COLOR_FG_B 0xfc65
+#define MC_DEFAULT_CMD_LINE_COLOR_BG_R 0x0
+#define MC_DEFAULT_CMD_LINE_COLOR_BG_G 0x0
+#define MC_DEFAULT_CMD_LINE_COLOR_BG_B 0x0
+
+#include "mini-commander_applet.h"
+
+void mc_load_preferences (MCData *mc);
+void mc_show_preferences (GtkAction *action,
+ MCData *mc);
+void mc_macros_free (GSList *macros);
+
+gboolean mc_key_writable (MCData *mc,
+ const char *key);
+
+G_END_DECLS
+
+#endif