[nautilus-actions] nautilus-actions-gconf2desktop.sh migration tool



commit 86b4a15865438fe5c2e247bd526ba661e2d33d74
Author: Pierre Wieser <pwieser trychlos org>
Date:   Thu Jan 6 00:17:16 2011 +0100

    nautilus-actions-gconf2desktop.sh migration tool
    
    The script takes care of migrating users and mandatory items to .desktop files.

 ChangeLog                                      |   12 +
 configure.ac                                   |   15 +-
 src/utils/.gitignore                           |    3 +
 src/utils/Makefile.am                          |   29 ++
 src/utils/nautilus-actions-delete.c            |  255 +++++++++++++++
 src/utils/nautilus-actions-gconf2desktop.sh.in |  412 ++++++++++++++++++++++++
 src/utils/nautilus-actions-print.c             |  244 ++++++++++++++
 7 files changed, 959 insertions(+), 11 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 73edcf2..160f0b1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -101,6 +101,18 @@
 	* src/nact/nautilus-actions-config-tool.ui:
 	Apply patch provided by Christian Kirbach. Fix #638548.
 
+2011-01-05 Pierre Wieser <pwieser trychlos org>
+
+	* src/utils/nautilus-actions-gconf2desktop.sh.in:
+	* src/utils/nautilus-actions-delete.c:
+	* src/utils/nautilus-actions-print.c:
+	New items migration script and programs.
+	They take care of migrating users and mandatory items to .desktop files.
+
+	* configure.ac:
+	* src/utils/Makefile.am:
+	* src/utils/.gitignore: Updated accordingly.
+
 2011-01-04 Pierre Wieser <pwieser trychlos org>
 
 	* src/core/na-tokens.c (na_tokens_new_from_selection):
diff --git a/configure.ac b/configure.ac
index 8799b35..25eea6a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,7 +28,7 @@
 
 AC_PREREQ([2.53])
 
-AC_INIT([Nautilus-Actions],[3.0.7],[maintainer nautilus-actions org],,[http://www.nautilus-actions.org])
+AC_INIT([Nautilus-Actions],[3.1.0],[maintainer nautilus-actions org],,[http://www.nautilus-actions.org])
 
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 AC_CANONICAL_TARGET
@@ -66,7 +66,10 @@ AC_CONFIG_FILES([
 	src/test/Makefile
 	src/utils/Makefile
 	tools/Makefile
+	src/utils/nautilus-actions-gconf2desktop.sh
 	po/Makefile.in
+],[
+	chmod a+x src/utils/nautilus-actions-gconf2desktop.sh
 ])
 
 AC_CONFIG_MACRO_DIR([m4])
@@ -152,16 +155,6 @@ NA_CHECK_MODULE([NAUTILUS_EXTENSION],[libnautilus-extension >= 2.8])
 AC_SUBST([NAUTILUS_ACTIONS_CFLAGS])
 AC_SUBST([NAUTILUS_ACTIONS_LIBS])
 
-# GSettings migration
-AC_MSG_CHECKING([for GSettings])
-PKG_CHECK_EXISTS([glib-2.0 >= 2.26],[have_gsettings="yes"],[have_gsettings="no"])
-AC_MSG_RESULT([${have_gsettings}])
-if test "x${have_gsettings}" = "xyes"; then have_gsettings_b=1; else have_gsettings_b=0; fi
-AC_DEFINE_UNQUOTED([HAVE_GSETTINGS],[${have_gsettings_b}],[Whether we compile against a recent enough GIO])
-
-# As of N-A 3.0.6, GConf is always enabled
-AM_CONDITIONAL([HAVE_GSETTINGS_AND_GCONF], [test "x${have_gsettings}" = "xyes"])
-
 # check for gtk-doc
 # Starting with gtk-doc 1.15, multiple source dirs are directly handled
 # by gtk-doc.make
diff --git a/src/utils/.gitignore b/src/utils/.gitignore
index d94650a..b1bb19a 100644
--- a/src/utils/.gitignore
+++ b/src/utils/.gitignore
@@ -1,6 +1,9 @@
 nautilus-actions-check-actions-change
+nautilus-actions-delete
+nautilus-actions-gconf2desktop.sh
 nautilus-actions-new-config
 nautilus-actions-new
+nautilus-actions-print
 nautilus-actions-run
 nautilus-actions-run-bindings.h
 nautilus-actions-schemas
diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am
index b10a3d0..60a6801 100644
--- a/src/utils/Makefile.am
+++ b/src/utils/Makefile.am
@@ -27,7 +27,9 @@
 #   ... and many others (see AUTHORS)
 
 bin_PROGRAMS = \
+	nautilus-actions-delete										\
 	nautilus-actions-new										\
+	nautilus-actions-print										\
 	nautilus-actions-run										\
 	nautilus-actions-schemas									\
 	$(NULL)
@@ -40,6 +42,17 @@ AM_CPPFLAGS += \
 	$(NAUTILUS_ACTIONS_CFLAGS)									\
 	$(NULL)
 
+nautilus_actions_delete_SOURCES = \
+	nautilus-actions-delete.c									\
+	console-utils.c												\
+	console-utils.h												\
+	$(NULL)
+
+nautilus_actions_delete_LDADD = \
+	$(top_builddir)/src/core/libna-core.la						\
+	$(NAUTILUS_ACTIONS_LIBS)									\
+	$(NULL)
+
 nautilus_actions_new_SOURCES = \
 	nautilus-actions-new.c										\
 	console-utils.c												\
@@ -51,6 +64,17 @@ nautilus_actions_new_LDADD = \
 	$(NAUTILUS_ACTIONS_LIBS)									\
 	$(NULL)
 
+nautilus_actions_print_SOURCES = \
+	nautilus-actions-print.c									\
+	console-utils.c												\
+	console-utils.h												\
+	$(NULL)
+
+nautilus_actions_print_LDADD = \
+	$(top_builddir)/src/core/libna-core.la						\
+	$(NAUTILUS_ACTIONS_LIBS)									\
+	$(NULL)
+
 BUILT_SOURCES = \
 	nautilus-actions-run-bindings.h								\
 	$(NULL)
@@ -82,4 +106,9 @@ nautilus_actions_schemas_LDADD = \
 
 CLEANFILES = \
 	$(BUILT_SOURCES)											\
+	$(bin_SCRIPTS)												\
+	$(NULL)
+
+bin_SCRIPTS = \
+	nautilus-actions-gconf2desktop.sh							\
 	$(NULL)
diff --git a/src/utils/nautilus-actions-delete.c b/src/utils/nautilus-actions-delete.c
new file mode 100644
index 0000000..7eddf82
--- /dev/null
+++ b/src/utils/nautilus-actions-delete.c
@@ -0,0 +1,255 @@
+/*
+ * Nautilus-Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010, 2011 Pierre Wieser and others (see AUTHORS)
+ *
+ * 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 Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+/*
+ * This program has been written because I do not have found any reliable
+ * way of removing a mandatory key (an action or a menu) from the GConf
+ * XML backend. It is based on http://xmlsoft.org/examples/xpath2.c
+ */
+
+#include <api/na-core-utils.h>
+
+#include "console-utils.h"
+
+#if defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_SAX1_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+
+static gchar     *xpath            = "";
+static gchar     *xmlfile          = "";
+static gboolean   version          = FALSE;
+
+static GOptionEntry entries[] = {
+
+	{ "path"                 , 'p', 0, G_OPTION_ARG_STRING        , &xpath,
+			N_( "The XPath to the tree to be deleted" ), N_( "<STRING>" ) },
+	{ "xml"                  , 'x', 0, G_OPTION_ARG_STRING        , &xmlfile,
+			N_( "The filename of the XML backend" ), N_( "<STRING>" ) },
+	{ NULL }
+};
+
+static GOptionEntry misc_entries[] = {
+
+	{ "version"              , 'v', 0, G_OPTION_ARG_NONE        , &version,
+			N_( "Output the version number" ), NULL },
+	{ NULL }
+};
+
+static GOptionContext  *init_options( void );
+static void             exit_with_usage( void );
+
+static void             delete_path( const gchar *xmlfile, const xmlChar *xpath );
+
+int
+main( int argc, char** argv )
+{
+	int status = EXIT_SUCCESS;
+	GOptionContext *context;
+	GError *error = NULL;
+	gchar *help;
+	gint errors;
+
+	g_type_init();
+	console_init_log_handler();
+
+	context = init_options();
+
+	if( argc == 1 ){
+		g_set_prgname( argv[0] );
+		help = g_option_context_get_help( context, FALSE, NULL );
+		g_print( "\n%s", help );
+		g_free( help );
+		exit( status );
+	}
+
+	if( !g_option_context_parse( context, &argc, &argv, &error )){
+		g_printerr( _( "Syntax error: %s\n" ), error->message );
+		g_error_free (error);
+		exit_with_usage();
+	}
+
+	g_option_context_free( context );
+
+	if( version ){
+		na_core_utils_print_version();
+		exit( status );
+	}
+
+	errors = 0;
+
+	if( !xpath || !strlen( xpath )){
+		g_printerr( _( "Error: a XPath is mandatory.\n" ));
+		errors += 1;
+	}
+
+	if( !xmlfile || !strlen( xmlfile )){
+		g_printerr( _( "Error: a XML filename is mandatory.\n" ));
+		errors += 1;
+	}
+
+	if( errors ){
+		exit_with_usage();
+	}
+
+	/* Init libxml */
+	xmlInitParser();
+	LIBXML_TEST_VERSION
+
+	/* Do the main job */
+	delete_path( xmlfile, BAD_CAST( xpath ));
+
+	/* Shutdown libxml */
+    xmlCleanupParser();
+
+	exit( status );
+}
+
+/*
+ * init options context
+ */
+static GOptionContext *
+init_options( void )
+{
+	GOptionContext *context;
+	gchar* description;
+	GOptionGroup *misc_group;
+
+	context = g_option_context_new( _( "Delete a XPath from a XML document." ));
+
+#ifdef ENABLE_NLS
+	bindtextdomain( GETTEXT_PACKAGE, GNOMELOCALEDIR );
+# ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+	bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" );
+# endif
+	textdomain( GETTEXT_PACKAGE );
+	g_option_context_add_main_entries( context, entries, GETTEXT_PACKAGE );
+#else
+	g_option_context_add_main_entries( context, entries, NULL );
+#endif
+
+	description = console_cmdline_get_description();
+	g_option_context_set_description( context, description );
+	g_free( description );
+
+	misc_group = g_option_group_new(
+			"misc", _( "Miscellaneous options" ), _( "Miscellaneous options" ), NULL, NULL );
+	g_option_group_add_entries( misc_group, misc_entries );
+	g_option_context_add_group( context, misc_group );
+
+	return( context );
+}
+
+/*
+ * print a help message and exit with failure
+ */
+static void
+exit_with_usage( void )
+{
+	g_printerr( _( "Try %s --help for usage.\n" ), g_get_prgname());
+	exit( EXIT_FAILURE );
+}
+
+static void
+delete_path( const gchar *xmlfile, const xmlChar *xpathExpr )
+{
+	xmlDocPtr doc;
+	xmlXPathContextPtr xpathCtx;
+	xmlXPathObjectPtr xpathObj;
+	xmlNodePtr nodePtr;
+	int size, i;
+
+	/* Load XML document */
+	doc = xmlParseFile( xmlfile );
+	if( doc == NULL ){
+		g_printerr( _( "Error: unable to parse file '%s'\n" ), xmlfile );
+		return;
+	}
+
+	/* Create xpath evaluation context */
+	xpathCtx = xmlXPathNewContext( doc );
+	if( xpathCtx == NULL ){
+		g_printerr( _( "Error: unable to create new XPath context\n" ));
+		xmlFreeDoc( doc );
+		return;
+	}
+
+	/* Evaluate xpath expression */
+	xpathObj = xmlXPathEvalExpression( xpathExpr, xpathCtx );
+	if( xpathObj == NULL ){
+		g_printerr( _( "Error: unable to evaluate xpath expression '%s'\n" ), xpathExpr );
+		xmlXPathFreeContext( xpathCtx );
+		xmlFreeDoc( doc );
+		return;
+	}
+
+	/* update selected nodes */
+	/*update_xpath_nodes(xpathObj->nodesetval, value);*/
+	size = ( xpathObj->nodesetval) ? xpathObj->nodesetval->nodeNr : 0;
+	/*g_print( "size=%d\n", size );*/
+	for( i=0 ; i<size ; ++i ){
+		nodePtr = xpathObj->nodesetval->nodeTab[i];
+		/*xmlElemDump( stdout, doc, nodePtr );*/
+		xmlUnlinkNode( nodePtr );
+	}
+
+	/* Cleanup of XPath data */
+	xmlXPathFreeObject( xpathObj );
+	xmlXPathFreeContext( xpathCtx );
+
+	/* dump the resulting document */
+	xmlDocDump( stdout, doc );
+
+	/* free the document */
+	xmlFreeDoc( doc );
+}
+
+#else
+int
+main( void ){
+    fprintf( stderr, "XPath support not compiled in\n" );
+    exit( 1 );
+}
+#endif
diff --git a/src/utils/nautilus-actions-gconf2desktop.sh.in b/src/utils/nautilus-actions-gconf2desktop.sh.in
new file mode 100644
index 0000000..3cc94d9
--- /dev/null
+++ b/src/utils/nautilus-actions-gconf2desktop.sh.in
@@ -0,0 +1,412 @@
+#!/bin/ksh 
+# Nautilus-Actions
+# A Nautilus extension which offers configurable context menu actions.
+#
+# Copyright (C) 2005 The GNOME Foundation
+# Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+# Copyright (C) 2009, 2010, 2011 Pierre Wieser and others (see AUTHORS)
+#
+# 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 Library; see the file COPYING.  If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place,
+# Suite 330, Boston, MA 02111-1307, USA.
+#
+# Authors:
+#   Frederic Ruaudel <grumz grumz net>
+#   Rodrigo Moya <rodrigo gnome-db org>
+#   Pierre Wieser <pwieser trychlos org>
+#   ... and many others (see AUTHORS)
+
+errs=0										# will be the exit code of the script
+my_cmd="${0}"								# e.g. "./make-ks.sh"
+my_parms="$*"								# e.g. "-host toaster"
+my_cmdline="${my_cmd} ${my_parms}"
+me="$(basename ${my_cmd})"					# e.g. "make-ks.sh"
+											# used in msg and msgerr functions
+my_tmproot="/tmp/$(echo ${me} | sed 's?\..*$??').$$"
+											# e.g. "/tmp/make-ks.1978"
+
+# These three functions must be defined using the name() syntax in order
+# to share traps with the caller process (cf. man (1) ksh).
+#
+trap_exit()
+{
+	clear_tmpfiles
+	[ "${opt_verbose}" = "yes" -o ${errs} -gt 0 ] && msg "exiting with code ${errs}"
+	exit ${errs}
+}
+
+trap_int()
+{
+	msg "quitting on keyboard interrupt"
+	let errs+=1
+	exit
+}
+
+trap_term()
+{
+	[ "${opt_verbose}" = "yes" ] && msg "quitting on TERM signal"
+	exit
+}
+
+# setup the different trap functions
+trap 'trap_term' TERM
+trap 'trap_int'  INT
+trap 'trap_exit' EXIT
+
+function clear_tmpfiles
+{
+	\rm -f ${my_tmproot}.*
+}
+
+function msg
+{
+	typeset _eol="\n"
+	[ $# -ge 2 ] && _eol="${2}"
+	printf "[%s] %s${_eol}" ${me} "${1}"
+	return 0
+}
+
+function msgerr
+{
+	msg "error: ${1}" 1>&2
+	return $?
+}
+
+function msgwarn
+{
+	msg "warning: ${1}" 1>&2
+	return $?
+}
+
+function msg_help
+{
+	msg_version
+	echo "
+ This program is meant to safely migrate menus and actions from GConf to
+ .desktop files.
+ Users menus and actions are automatically migrated when Nautilus-Actions
+ menu plugin is loaded by Nautilus file-manager.
+
+ Usage: ${my_cmd} [options]
+   --[no]help                print this message, and exit [${opt_help_def}]
+   --[no]version             print script version, and exit [${opt_version_def}]
+   --[no]dummy               dummy execution [${opt_dummy_def}]
+   --[no]verbose             runs verbosely [${opt_verbose_def}]
+   --print=/filename         full pathname of the nautilus-actions-print program [${opt_print_def}]
+   --dir=/dirname            directory where the migrated objects must be stored [${opt_dir_def}]
+   --[no]force               force the rewriting of an already existing item [${opt_force_def}]
+   --[no]delete              delete the item after the migration [${opt_delete_def}]"
+}
+
+function msg_version
+{
+	echo "
+ @PACKAGE_NAME@ v @PACKAGE_VERSION@
+ Copyright (C) 2011 Pierre Wieser."
+}
+
+function command
+{
+	typeset _cmd="${1}"
+
+	if [ "${opt_dummy}" = "yes" -o "${opt_verbose}" = "yes" ]; then
+		typeset _prefix=""
+		[ "${opt_dummy}" = "yes" ] && _prefix="[dummy] "
+		echo "${_prefix}${_cmd}"
+	fi
+
+	if [ "${opt_dummy}" = "no" ]; then
+		eval ${_cmd}
+	fi
+}
+
+# initialize common command-line options
+nbopt=$#
+opt_help=
+opt_help_def="no"
+opt_dummy=
+opt_dummy_def="yes"
+opt_version=
+opt_version_def="no"
+opt_verbose=
+opt_verbose_def="no"
+
+# a first loop over command line arguments to detect verbose mode
+while :
+do
+	# break when all arguments have been read
+	case $# in
+		0)
+			break
+			;;
+	esac
+
+	# get and try to interpret the next argument
+	_option=$1
+	shift
+
+	# make all options have two hyphens
+	_orig_option=${_option}
+	case ${_option} in
+		--*)
+			;;
+		-*)
+			_option=-${_option}
+				;;
+		esac
+
+	# now process options and their argument
+	case ${_option} in
+		--noverb | --noverbo | --noverbos | --noverbose)
+			opt_verbose="no"
+			;;
+		--verb | --verbo | --verbos | --verbose)
+			opt_verbose="yes"
+				;;
+	esac
+done
+
+[ "${opt_verbose}" = "yes" ] && msg "setting opt_verbose to 'yes'"
+
+# script_opt_verb has scanned all command-line arguments
+# in order to detect the opt_verbose;
+# reset arguments so that they can be scanned again in main script 
+set -- ${my_parms}
+
+# interpreting command-line arguments
+print_program="nautilus-actions-print"
+opt_print=
+opt_print_def="$(which ${print_program} 2>/dev/null)"
+
+opt_dir=
+[ $(id -u) -eq 0 ] && opt_dir_def="/usr" || opt_dir_def="${HOME}/.local"
+opt_dir_def="${opt_dir_def}/share/file-manager/actions"
+
+# default is to not force rewriting of already existing items
+# instead they are renumbered
+opt_force=
+opt_force_def="no"
+
+# default is to not delete the migrated item
+opt_delete=
+opt_delete_def="no"
+
+# path of the branch which contains the configurations
+na_configurations="/apps/nautilus-actions/configurations"
+
+# loop over command line arguments
+pos=0
+while :
+do
+	# break when all arguments have been read
+	case $# in
+		0)
+			break
+			;;
+	esac
+
+	# get and try to interpret the next argument
+	option=$1
+	shift
+
+	# make all options have two hyphens
+	orig_option=${option}
+	case ${option} in
+		--*)
+			;;
+		-*)
+			option=-${option}
+			;;
+	esac
+
+	# split and extract argument for options that take one
+	case ${option} in
+		--*=*)
+			optarg=$(echo ${option} | sed -e 's/^[^=]*=//')
+			option=$(echo ${option} | sed 's/=.*//')
+			;;
+		# these options take a mandatory argument
+		# since, we didn't find it in 'option', so it should be
+		# next word in the command line
+		--di | --dir | \
+		--p | --pr | --pri | --prin | --print)
+			optarg=$1
+			shift
+			;;
+	esac
+
+	# now process options and their argument
+	case ${option} in
+		--de | --del | --dele | --delet | --delete)
+			[ "${opt_verbose}" = "yes" ] && msg "setting opt_delete to 'yes'"
+			opt_delete="yes"
+			;;
+		--di | --dir)
+			[ "${opt_verbose}" = "yes" ] && msg "setting opt_dir to '${optarg}'"
+			opt_dir="${optarg}"
+			;;
+		--du | --dum | --dumm | --dummy)
+			[ "${opt_verbose}" = "yes" ] && msg "setting opt_dummy to 'yes'"
+			opt_dummy="yes"
+			;;
+		--f | --fo | --for | --forc | --force)
+			[ "${opt_verbose}" = "yes" ] && msg "setting opt_force to 'yes'"
+			opt_force="yes"
+			;;
+		--h | --he | --hel | --help)
+			[ "${opt_verbose}" = "yes" ] && msg "setting opt_help to 'yes'"
+			opt_help="yes"
+			;;
+		--node | --nodel | --nodele | --nodelet | --nodelete)
+			[ "${opt_verbose}" = "yes" ] && msg "setting opt_delete to 'no'"
+			opt_delete="no"
+			;;
+		--nodu | --nodum | --nodumm | --nodummy)
+			[ "${opt_verbose}" = "yes" ] && msg "setting opt_dummy to 'no'"
+			opt_dummy="no"
+			;;
+		--nof | --nofo | --nofor | --noforc | --noforce)
+			[ "${opt_verbose}" = "yes" ] && msg "setting opt_force to 'no'"
+			opt_force="no"
+			;;
+		--noh | --nohe | --nohel | --nohelp)
+			[ "${opt_verbose}" = "yes" ] && msg "setting opt_help to 'no'"
+			opt_help="no"
+			;;
+		--noverb | --noverbo | --noverbos | --noverbose)
+			;;
+		--novers | --noversi | --noversio | --noversion)
+			[ "${opt_verbose}" = "yes" ] && msg "setting opt_version to 'no'"
+			opt_version="no"
+			;;
+		--p | --pr | --pri | --prin | --print)
+			[ "${opt_verbose}" = "yes" ] && msg "setting opt_print to '${optarg}'"
+			opt_print="${optarg}"
+			;;
+		--verb | --verbo | --verbos | --verbose)
+			;;
+		--vers | --versi | --versio | --version)
+			[ "${opt_verbose}" = "yes" ] && msg "setting opt_version to 'yes'"
+			opt_version="yes"
+			;;
+		--*)
+			msgerr "unrecognized option: '${orig_option}'"
+			let errs+=1
+			;;
+		# positional parameters
+		*)
+			let pos+=1
+			#if [ ${pos} -eq 1 ]; then
+			#	[ "${opt_verbose}" = "yes" ] && msg "setting opt_output to '${option}'"
+			#	opt_output=${option}
+			#else
+				msgerr "unexpected positional parameter #${pos}: '${option}'"
+				let errs+=1
+			#fi
+			;;
+	esac
+done
+
+# set option defaults
+set | grep -e '^opt_' | cut -d= -f1 | while read _name; do
+	if [ "$(echo ${_name} | sed 's/.*\(_orig\)/\1/')" != "_orig" ]; then
+		if [ "$(echo ${_name} | sed 's/.*\(_def\)/\1/')" != "_def" ]; then
+			_value="$(eval echo "$"${_name})"
+			eval ${_name}_orig="$(eval echo "$"${_name})"
+			if [ ${nbopt} -eq 0 -a "${_name}" = "opt_help" ]; then
+				opt_help="yes"
+				_value="yes"
+			fi
+			if [ "${_value}" = "" ]; then
+				eval ${_name}="$(eval echo "$"${_name}_def)"
+			fi
+		fi
+	fi
+done
+
+if [ "${opt_help}" = "yes" ]; then
+	msg_help
+	echo ""
+	exit
+fi
+
+if [ "${opt_version}" = "yes" ]; then
+	msg_version
+	echo ""
+	exit
+fi
+
+if [ "${opt_print}" = "" ]; then
+	msgerr "${print_program}: not found"
+	let errs+=1
+elif [ ! -x ${opt_print} ]; then
+	msgerr "${print_program}: not executable"
+	let errs+=1
+fi
+
+if [ ${errs} -gt 0 ]; then
+	msg "${errs} error(s) have been detected"
+	msg "try '${my_cmd} --help' for usage"
+	exit
+fi
+
+# ---------------------------------------------------------------------
+# MAIN CODE
+
+# if we do not have gconftool-2, then exit
+which gconftool-2 1>/dev/null 2>&1 || { msg "gconftool-2: not available"; exit 1; }
+
+# create the destination directory if it does not yet exist
+command "mkdir -p ${opt_dir} || exit 1"
+
+let count=0
+
+# list objects in configurations/ subdir
+for dir in $(gconftool-2 --all-dirs ${na_configurations}); do
+	id=$(basename ${dir})
+	let count+=1
+	[ "${opt_verbose}" = "yes" ] && msg "item=${id}"
+	if [ -e ${opt_dir}/${id}.desktop -a "${opt_force}" = "no" ]; then
+		msgwarn "${opt_dir}/${id}.desktop already exists"
+		i=0
+		while [ -e ${opt_dir}/${id}-${i}.desktop ]; do
+			let i+=1
+		done
+		command "${opt_print} --id ${id} | grep -v ${print_program} > ${opt_dir}/${id}-${i}.desktop"
+	else
+		command "${opt_print} --id ${id} | grep -v ${print_program} > ${opt_dir}/${id}.desktop"
+	fi
+done
+
+# force sync
+killall gconfd-2
+
+# at the end, we delete the branch
+if [ "${opt_delete}" = "yes" -a ${count} -gt 0 ]; then
+	if [ $(id -u) -eq 0 ]; then
+		# rather a bad hack to find where mandatory items are stored by GConf
+		# nautilus-actions-delete directly removes our branch from the XML tree!
+		xml=$(find /etc -name gconf.xml.mandatory)/%gconf-tree.xml
+		path='/gconf/dir[ name="apps"]/dir[ name="nautilus-actions"]/dir[ name="configurations"]'
+		command "$(dirname ${opt_print})/nautilus-actions-delete --path '${path}' --xml ${xml} > ${xml}2"
+		command "mv ${xml}2 ${xml}"
+	else
+		# this does not work for mandatory items
+		command "gconftool-2 --recursive-unset ${na_configurations}"
+	fi
+fi
+
+msg "${count} migrated items"
+
+exit
diff --git a/src/utils/nautilus-actions-print.c b/src/utils/nautilus-actions-print.c
new file mode 100644
index 0000000..17d1681
--- /dev/null
+++ b/src/utils/nautilus-actions-print.c
@@ -0,0 +1,244 @@
+/*
+ * Nautilus-Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010, 2011 Pierre Wieser and others (see AUTHORS)
+ *
+ * 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 Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <api/na-core-utils.h>
+#include <api/na-object-api.h>
+
+#include <core/na-exporter.h>
+#include <core/na-export-format.h>
+
+#include "console-utils.h"
+
+static gchar     *id               = "";
+static gchar     *format           = "";
+static gboolean   version          = FALSE;
+
+static GOptionEntry entries[] = {
+
+	{ "id"                   , 'i', 0, G_OPTION_ARG_STRING        , &id,
+			N_( "The identifiant of the menu or the action to be printed" ), N_( "<STRING>" ) },
+	{ "format"               , 'f', 0, G_OPTION_ARG_STRING,     &format,
+			N_( "An export format [Desktop1]" ), N_( "<STRING>" ) },
+	{ NULL }
+};
+
+static GOptionEntry misc_entries[] = {
+
+	{ "version"              , 'v', 0, G_OPTION_ARG_NONE        , &version,
+			N_( "Output the version number" ), NULL },
+	{ NULL }
+};
+
+static NAPivot *pivot = NULL;
+
+static GOptionContext  *init_options( void );
+static NAObjectItem    *get_item( const gchar *id );
+static void             export_item( const NAObjectItem *item, const gchar *format );
+static void             exit_with_usage( void );
+
+int
+main( int argc, char** argv )
+{
+	int status = EXIT_SUCCESS;
+	GOptionContext *context;
+	GError *error = NULL;
+	gchar *help;
+	gint errors;
+	NAObjectItem *item;
+	GList *formats_list, *it;
+	gboolean format_found;
+
+	g_type_init();
+	console_init_log_handler();
+
+	context = init_options();
+
+	if( argc == 1 ){
+		g_set_prgname( argv[0] );
+		help = g_option_context_get_help( context, FALSE, NULL );
+		g_print( "\n%s", help );
+		g_free( help );
+		exit( status );
+	}
+
+	if( !g_option_context_parse( context, &argc, &argv, &error )){
+		g_printerr( _( "Syntax error: %s\n" ), error->message );
+		g_error_free (error);
+		exit_with_usage();
+	}
+
+	g_option_context_free( context );
+
+	if( version ){
+		na_core_utils_print_version();
+		exit( status );
+	}
+
+	errors = 0;
+
+	if( !id || !strlen( id )){
+		g_printerr( _( "Error: a menu or action id is mandatory.\n" ));
+		errors += 1;
+	}
+
+	item = get_item( id );
+	if( !item ){
+		errors += 1;
+	}
+
+	if( !format || !strlen( format )){
+		format = "Desktop1";
+	}
+
+	formats_list = na_exporter_get_formats( pivot );
+	format_found = FALSE;
+
+	for( it = formats_list ; it && !format_found ; it = it->next ){
+		NAExportFormat *export = NA_EXPORT_FORMAT( it->data );
+		gchar *export_id = na_export_format_get_id( export );
+		format_found = !strcmp( export_id, format );
+		g_free( export_id );
+	}
+
+	na_exporter_free_formats( formats_list );
+
+	if( !format_found ){
+		/* i18n: %s stands for the id of the export format, and is not translatable */
+		g_printerr( _( "Error: %s: unknown export format.\n" ), format );
+		errors += 1;
+	}
+
+	if( errors ){
+		exit_with_usage();
+	}
+
+	export_item( item, format );
+
+	exit( status );
+}
+
+/*
+ * init options context
+ */
+static GOptionContext *
+init_options( void )
+{
+	GOptionContext *context;
+	gchar* description;
+	GOptionGroup *misc_group;
+
+	context = g_option_context_new( _( "Print a menu or an action to stdout." ));
+
+#ifdef ENABLE_NLS
+	bindtextdomain( GETTEXT_PACKAGE, GNOMELOCALEDIR );
+# ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+	bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" );
+# endif
+	textdomain( GETTEXT_PACKAGE );
+	g_option_context_add_main_entries( context, entries, GETTEXT_PACKAGE );
+#else
+	g_option_context_add_main_entries( context, entries, NULL );
+#endif
+
+	description = console_cmdline_get_description();
+	g_option_context_set_description( context, description );
+	g_free( description );
+
+	misc_group = g_option_group_new(
+			"misc", _( "Miscellaneous options" ), _( "Miscellaneous options" ), NULL, NULL );
+	g_option_group_add_entries( misc_group, misc_entries );
+	g_option_context_add_group( context, misc_group );
+
+	return( context );
+}
+
+/*
+ * search for the action in the repository
+ */
+static NAObjectItem *
+get_item( const gchar *id )
+{
+	NAObjectItem *item = NULL;
+
+	pivot = na_pivot_new();
+	na_pivot_set_loadable( pivot, PIVOT_LOAD_ALL );
+	na_pivot_load_items( pivot );
+
+	item = na_pivot_get_item( pivot, id );
+
+	if( !item ){
+		g_printerr( _( "Error: item '%s' doesn't exist.\n" ), id );
+	}
+
+	return( item );
+}
+
+/*
+ * displays the specified item on stdout, in the specified export format
+ */
+static void
+export_item( const NAObjectItem *item, const gchar *format )
+{
+	GSList *messages = NULL;
+	GSList *it;
+	GQuark q_format = g_quark_from_string( format );
+
+	gchar *buffer = na_exporter_to_buffer( pivot, item, q_format, &messages );
+
+	for( it = messages ; it ; it = it->next ){
+		g_printerr( "%s\n", ( const gchar * ) it->data );
+	}
+	na_core_utils_slist_free( messages );
+
+	if( buffer ){
+		g_printf( "%s\n", buffer );
+		g_free( buffer );
+	}
+}
+
+/*
+ * print a help message and exit with failure
+ */
+static void
+exit_with_usage( void )
+{
+	g_printerr( _( "Try %s --help for usage.\n" ), g_get_prgname());
+	exit( EXIT_FAILURE );
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]