Compare commits
30 Commits
multihead
...
GNOME_VFS_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b6d4bb140 | ||
|
|
d423110faa | ||
|
|
d97f432f33 | ||
|
|
9e7e24a991 | ||
|
|
9662231641 | ||
|
|
808b6df4de | ||
|
|
ba220ebdc3 | ||
|
|
730e168518 | ||
|
|
d5e862145a | ||
|
|
d8fabf0557 | ||
|
|
6981fe9144 | ||
|
|
b2ee2fa5bd | ||
|
|
388af8aa64 | ||
|
|
82c493b6fb | ||
|
|
e1c8837b0b | ||
|
|
94fe6d69d0 | ||
|
|
6d3177ec51 | ||
|
|
a5b9b55591 | ||
|
|
059b37012d | ||
|
|
b28b2644a1 | ||
|
|
fdd551dbad | ||
|
|
cf03cbeff9 | ||
|
|
36656755c3 | ||
|
|
694815ad59 | ||
|
|
ccfe3a4abf | ||
|
|
cdae99d075 | ||
|
|
8deb8274bf | ||
|
|
62c1eec01b | ||
|
|
c65cc26463 | ||
|
|
85d7761573 |
30
.cvsignore
30
.cvsignore
@@ -1,30 +0,0 @@
|
||||
ABOUT-NLS
|
||||
.new.ltmain.sh
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
config.cache
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
configure.scan
|
||||
intl
|
||||
libtool
|
||||
ltconfig
|
||||
ltmain.sh
|
||||
missing
|
||||
mkinstalldirs
|
||||
COPYING
|
||||
install-sh
|
||||
stamp-h
|
||||
stamp-h.in
|
||||
version.h
|
||||
intl
|
||||
macros
|
||||
INSTALL
|
||||
control-center.spec
|
||||
my_control_center_idl
|
||||
@@ -1,2 +0,0 @@
|
||||
Email: hovinen@ximian.com
|
||||
Email: jacob@ximian.com
|
||||
@@ -1,8 +0,0 @@
|
||||
SUBDIRS = intl po capplets root-manager new-control-center
|
||||
|
||||
EXTRA_DIST = control-center.spec.in
|
||||
|
||||
dist-hook: control-center.spec
|
||||
cp control-center.spec $(distdir)
|
||||
|
||||
|
||||
8
README
8
README
@@ -1,8 +0,0 @@
|
||||
Control-Center
|
||||
--------------
|
||||
|
||||
To install this package, you need to install (at minimum):
|
||||
|
||||
ORBit
|
||||
gnome-libs
|
||||
esd
|
||||
19
TODO.xml
19
TODO.xml
@@ -1,19 +0,0 @@
|
||||
<todo>
|
||||
<title>GNOME Control Center TODO list</title>
|
||||
<section>
|
||||
<title>Capplets</title>
|
||||
|
||||
<entry size="big" status="10%" target="1.4">
|
||||
<title>Screensaver XML descriptions</title>
|
||||
<description>
|
||||
<p>
|
||||
Create XML descriptions to allow dialog configuration of the various
|
||||
screensavers that come with XScreensaver. See
|
||||
capplets/new-screensaver-properties/screensavers/README for
|
||||
documentaiton.
|
||||
</p>
|
||||
</description>
|
||||
<contact>hovinen@helixcode.com</contact>
|
||||
</entry>
|
||||
</section> <!--Capplets-->
|
||||
</todo>
|
||||
25
acconfig.h
25
acconfig.h
@@ -1,25 +0,0 @@
|
||||
#undef ENABLE_NLS
|
||||
#undef HAVE_CATGETS
|
||||
#undef HAVE_DEVGTK
|
||||
#undef HAVE_GETTEXT
|
||||
#undef HAVE_LC_MESSAGES
|
||||
#undef HAVE_STPCPY
|
||||
#undef HAVE_LIBSM
|
||||
#undef HAVE_PROGRAM_INVOCATION_SHORT_NAME
|
||||
#undef HAVE_PROGRAM_INVOCATION_NAME
|
||||
#undef PACKAGE
|
||||
#undef VERSION
|
||||
|
||||
#undef HAVE_ESD
|
||||
#undef HAVE_LIBESD
|
||||
|
||||
/* Define if there is no `u_int64_t' and `int64_t'. */
|
||||
#undef u_int64_t
|
||||
#undef int64_t
|
||||
|
||||
#undef HAVE_DEVGTK
|
||||
|
||||
#undef WITH_SYMBOL_UNDERSCORE
|
||||
|
||||
#undef HAVE_PUTENV
|
||||
#undef HAVE_SETENV
|
||||
164
acinclude.m4
164
acinclude.m4
@@ -1,164 +0,0 @@
|
||||
# Configure paths for ESD
|
||||
# Manish Singh 98-9-30
|
||||
# stolen back from Frank Belew
|
||||
# stolen from Manish Singh
|
||||
# Shamelessly stolen from Owen Taylor
|
||||
|
||||
dnl AM_PATH_ESD([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
|
||||
dnl Test for ESD, and define ESD_CFLAGS and ESD_LIBS
|
||||
dnl
|
||||
AC_DEFUN(AM_PATH_ESD,
|
||||
[dnl
|
||||
dnl Get the cflags and libraries from the esd-config script
|
||||
dnl
|
||||
AC_ARG_WITH(esd-prefix,[ --with-esd-prefix=PFX Prefix where ESD is installed (optional)],
|
||||
esd_prefix="$withval", esd_prefix="")
|
||||
AC_ARG_WITH(esd-exec-prefix,[ --with-esd-exec-prefix=PFX Exec prefix where ESD is installed (optional)],
|
||||
esd_exec_prefix="$withval", esd_exec_prefix="")
|
||||
AC_ARG_ENABLE(esdtest, [ --disable-esdtest Do not try to compile and run a test ESD program],
|
||||
, enable_esdtest=yes)
|
||||
|
||||
if test x$esd_exec_prefix != x ; then
|
||||
esd_args="$esd_args --exec-prefix=$esd_exec_prefix"
|
||||
if test x${ESD_CONFIG+set} != xset ; then
|
||||
ESD_CONFIG=$esd_exec_prefix/bin/esd-config
|
||||
fi
|
||||
fi
|
||||
if test x$esd_prefix != x ; then
|
||||
esd_args="$esd_args --prefix=$esd_prefix"
|
||||
if test x${ESD_CONFIG+set} != xset ; then
|
||||
ESD_CONFIG=$esd_prefix/bin/esd-config
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_PATH_PROG(ESD_CONFIG, esd-config, no)
|
||||
min_esd_version=ifelse([$1], ,0.2.5,$1)
|
||||
AC_MSG_CHECKING(for ESD - version >= $min_esd_version)
|
||||
no_esd=""
|
||||
if test "$ESD_CONFIG" = "no" ; then
|
||||
no_esd=yes
|
||||
else
|
||||
ESD_CFLAGS=`$ESD_CONFIG $esdconf_args --cflags`
|
||||
ESD_LIBS=`$ESD_CONFIG $esdconf_args --libs`
|
||||
|
||||
esd_major_version=`$ESD_CONFIG $esd_args --version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
|
||||
esd_minor_version=`$ESD_CONFIG $esd_args --version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
|
||||
esd_micro_version=`$ESD_CONFIG $esd_config_args --version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
|
||||
if test "x$enable_esdtest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $ESD_CFLAGS"
|
||||
LIBS="$LIBS $ESD_LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed ESD is sufficiently new. (Also sanity
|
||||
dnl checks the results of esd-config to some extent
|
||||
dnl
|
||||
rm -f conf.esdtest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <esd.h>
|
||||
|
||||
char*
|
||||
my_strdup (char *str)
|
||||
{
|
||||
char *new_str;
|
||||
|
||||
if (str)
|
||||
{
|
||||
new_str = malloc ((strlen (str) + 1) * sizeof(char));
|
||||
strcpy (new_str, str);
|
||||
}
|
||||
else
|
||||
new_str = NULL;
|
||||
|
||||
return new_str;
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
int major, minor, micro;
|
||||
char *tmp_version;
|
||||
|
||||
system ("touch conf.esdtest");
|
||||
|
||||
/* HP/UX 9 (%@#!) writes to sscanf strings */
|
||||
tmp_version = my_strdup("$min_esd_version");
|
||||
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) {
|
||||
printf("%s, bad version string\n", "$min_esd_version");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (($esd_major_version > major) ||
|
||||
(($esd_major_version == major) && ($esd_minor_version > minor)) ||
|
||||
(($esd_major_version == major) && ($esd_minor_version == minor) && ($esd_micro_version >= micro)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\n*** 'esd-config --version' returned %d.%d.%d, but the minimum version\n", $esd_major_version, $esd_minor_version, $esd_micro_version);
|
||||
printf("*** of ESD required is %d.%d.%d. If esd-config is correct, then it is\n", major, minor, micro);
|
||||
printf("*** best to upgrade to the required version.\n");
|
||||
printf("*** If esd-config was wrong, set the environment variable ESD_CONFIG\n");
|
||||
printf("*** to point to the correct copy of esd-config, and remove the file\n");
|
||||
printf("*** config.cache before re-running configure\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
],, no_esd=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
fi
|
||||
if test "x$no_esd" = x ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$2], , :, [$2])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test "$ESD_CONFIG" = "no" ; then
|
||||
echo "*** The esd-config script installed by ESD could not be found"
|
||||
echo "*** If ESD was installed in PREFIX, make sure PREFIX/bin is in"
|
||||
echo "*** your path, or set the ESD_CONFIG environment variable to the"
|
||||
echo "*** full path to esd-config."
|
||||
else
|
||||
if test -f conf.esdtest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run ESD test program, checking why..."
|
||||
CFLAGS="$CFLAGS $ESD_CFLAGS"
|
||||
LIBS="$LIBS $ESD_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include <esd.h>
|
||||
], [ return 0; ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding ESD or finding the wrong"
|
||||
echo "*** version of ESD. If it is not finding ESD, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means ESD was incorrectly installed"
|
||||
echo "*** or that you have moved ESD since it was installed. In the latter case, you"
|
||||
echo "*** may want to edit the esd-config script: $ESD_CONFIG" ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
fi
|
||||
ESD_CFLAGS=""
|
||||
ESD_LIBS=""
|
||||
ifelse([$3], , :, [$3])
|
||||
fi
|
||||
AC_SUBST(ESD_CFLAGS)
|
||||
AC_SUBST(ESD_LIBS)
|
||||
rm -f conf.esdtest
|
||||
])
|
||||
@@ -1,10 +0,0 @@
|
||||
.deps
|
||||
.libs
|
||||
*.lo
|
||||
*.la
|
||||
Makefile
|
||||
ximia-archiver
|
||||
Makefile.in
|
||||
ximian-config-manager
|
||||
ximian_archiverConf.sh
|
||||
ximian-archiver
|
||||
@@ -1,210 +0,0 @@
|
||||
2001-01-25 Bradford Hovinen <hovinen@ximian.com>
|
||||
|
||||
* config-log.c (get_current_date): Use local time rather than
|
||||
Greenwich Mean Time
|
||||
|
||||
* location.c (location_store_xml): Implement; copy from
|
||||
location_store
|
||||
(location_store): Free filename after use
|
||||
|
||||
* archive.c (archive_load): Free prefix only if not global
|
||||
|
||||
* location.c (location_rollback_all_to): Increment array
|
||||
|
||||
* util.c (parse_date): Normalize values
|
||||
|
||||
2001-01-24 Bradford Hovinen <hovinen@ximian.com>
|
||||
|
||||
* config-log.c (do_load): Disabled locking for now
|
||||
|
||||
* archiver-spec: Added fine-grained location management description
|
||||
|
||||
2001-01-15 Bradford Hovinen <hovinen@ximian.com>
|
||||
|
||||
* Makefile.am: Added rule for ximian_archiverConf.sh; add
|
||||
installation target for Conf.sh
|
||||
|
||||
2001-01-13 Bradford Hovinen <hovinen@ximian.com>
|
||||
|
||||
* Makefile.am: Replaced occurrences of helix with ximian
|
||||
Removed references to ximian_config_manager
|
||||
|
||||
2000-12-22 Bradford Hovinen <hovinen@helixcode.com>
|
||||
|
||||
* archive.c (foreach_cb):
|
||||
(archive_foreach_child_location): Use auxillary structure to pass
|
||||
data to traversal callback
|
||||
(archive_get_location):
|
||||
(archive_register_location): strdup() location ids
|
||||
(free_location_cb): free() key
|
||||
|
||||
2000-12-20 Bradford Hovinen <hovinen@helixcode.com>
|
||||
|
||||
* location.c (location_get_parent): Implement
|
||||
|
||||
* archive.c (load_all_locations): Implement
|
||||
(foreach_cb):
|
||||
(archive_foreach_child_location): Implement
|
||||
|
||||
2000-12-19 Bradford Hovinen <hovinen@helixcode.com>
|
||||
|
||||
* Makefile.am (bin_PROGRAMS): Changed name of archiver to
|
||||
helix-archiver
|
||||
(lib_LIBRARIES): Added libhelix_archiver.a
|
||||
(helix_archiver_SOURCES): Moved archiver core to
|
||||
libhelix_archiver_a_SOURCES
|
||||
(helix_archiver_LDADD): Added libhelix_archiver.a
|
||||
(INCLUDES): Changed XML_CFLAGS to GNOME_XML_CFLAGS
|
||||
(include_HEADERS): Create and include headers for
|
||||
libhelix_archiver.a
|
||||
(includedir): Set includedire to include/helix-archiver
|
||||
|
||||
2000-12-18 Bradford Hovinen <hovinen@helixcode.com>
|
||||
|
||||
* main.c (do_rollback): Support rolling back by steps
|
||||
|
||||
* location.c (location_rollback_backend_by): Implement
|
||||
(location_dump_rollback_data): Support passing steps as well as
|
||||
date
|
||||
|
||||
* config-log.c (config_log_get_rollback_id_by_steps): Implement
|
||||
|
||||
* location.c (write_metadata_file): Don't support writing out the
|
||||
master list any more
|
||||
(save_metadata): Ditto
|
||||
(load_metadata_file): Get backends list from BackendList object
|
||||
(rather than finding it out oneself) if location is toplevel
|
||||
(do_create): Ditto
|
||||
(get_backends_cb): Implement
|
||||
(location_add_backend): Add return values for error conditions
|
||||
|
||||
2000-10-15 Bradford Hovinen <hovinen@helixcode.com>
|
||||
|
||||
* location.c (location_rollback_backends_to): Free id_array when done
|
||||
|
||||
* config-log.c (config_log_reset_filenames): Implement
|
||||
|
||||
* archive.c (archive_set_current_location_id): Move gnome_config_
|
||||
code from set_current_location
|
||||
|
||||
* location.c (location_set_id): Implement
|
||||
|
||||
* main.c (do_rename_location): Implement
|
||||
|
||||
* archive.c (free_location_cb): Don't free locid
|
||||
(archive_get_location):
|
||||
(archive_register_location): Don't strdup the location id
|
||||
(archive_set_current_location_id): Implement
|
||||
|
||||
* main.c: Add options for renaming locations and specifying that
|
||||
backends should be added to or removed from the master list
|
||||
|
||||
* location.c (run_backend_proc): Close all descriptors other than
|
||||
0, 1, 2
|
||||
(location_set_id): Implement
|
||||
(location_set_arg): Free previous locid if exists
|
||||
|
||||
* archive.c (add_location_cb): Implement
|
||||
(archive_set_current_location): Add location change algorithm
|
||||
|
||||
* location.c (location_find_path_from_common_parent): Implement
|
||||
(location_foreach_backend): Implement
|
||||
|
||||
* archive.c (archive_set_current_location): Set
|
||||
archive->current_location_id
|
||||
|
||||
* main.c (do_add_location): Check parent_str for NULL before
|
||||
loading location
|
||||
(do_change_location): Implement
|
||||
(main): Support changing location
|
||||
|
||||
* archive.c (archive_register_location): Implement
|
||||
|
||||
* location.c (do_create):
|
||||
(do_load): Use archive_get_prefix
|
||||
(do_create): Load global location metadata if this location does
|
||||
not inherit from anything
|
||||
(location_get_id): Implement
|
||||
|
||||
* archive.c (archive_get_prefix): Implement
|
||||
|
||||
* location.c (location_get_path): Implement
|
||||
(load_metadata_file): Use archive_is_global
|
||||
(location_set_arg): Set label when setting locid
|
||||
|
||||
* location.[ch]: Make all data members private
|
||||
|
||||
* main.c (main): Get current location name properly, create
|
||||
location iff location id is "default"; bail out with error otherwise
|
||||
(do_remove_location):
|
||||
(do_add_location): Implement
|
||||
|
||||
* config-log.c: Include ctype.h to fix implicit declarations
|
||||
|
||||
* location.c (location_rollback_backends_to): Property initialize i
|
||||
(location_contains): Fix precondition checks
|
||||
(do_create): Remove unused variables
|
||||
|
||||
* archive.c (archive_get_location): Make a copy of locid before
|
||||
working with it
|
||||
(do_load): Fix precondition checks
|
||||
|
||||
* location.c (location_open):
|
||||
(location_new): Make locid const
|
||||
|
||||
* archive.c (archive_get_location): Make locid const
|
||||
|
||||
* location.c (data_delete_cb):
|
||||
(location_delete): Implement
|
||||
|
||||
* config-log.c (config_log_iterate): Implement
|
||||
(config_log_destroy): Make private, pass GtkObject
|
||||
(config_log_delete): Implement
|
||||
|
||||
2000-10-14 Bradford Hovinen <hovinen@helixcode.com>
|
||||
|
||||
* location.c (location_close): Add precondition checks
|
||||
|
||||
* archive.c (archive_destroy): Make private; pass GtkObject
|
||||
|
||||
* location.c (location_add_backend):
|
||||
(location_remove_backend): Add precondition checks
|
||||
(location_destroy): Make private
|
||||
(location_destroy): Pass GtkObject pointer rather than Location
|
||||
pointer; this cleans up assignment in _class_init
|
||||
|
||||
* archive.c (archive_get_current_location_id): Implement
|
||||
(archive_get_current_location): Implement
|
||||
|
||||
2000-09-03 Bradford Hovinen <hovinen@helixcode.com>
|
||||
|
||||
* location.c (location_new): Set is_new
|
||||
(save_metadata): Don't write file unless necessary
|
||||
(save_metadata):
|
||||
(write_metadata_file): Split out file writing into
|
||||
write_metadata_file; write default data file as necessary
|
||||
(location_add_backend):
|
||||
(location_remove_backend): Implement
|
||||
|
||||
* main.c: Add command line arguments for adding/removing locations
|
||||
and backends; move backend id argument into global options
|
||||
|
||||
* location.c (do_load):
|
||||
(load_metadata_file): Split out file parsing logic into
|
||||
load_metadata_file; call load_metadata_file on default file to get
|
||||
contains list if current location doesn't inherit anything
|
||||
(load_metadata_file): g_strdup backend string
|
||||
(load_metadata_file): Warn if top-level location has contains clauses
|
||||
(location_store): Check if the location contains the given backend
|
||||
and try the location it inherits if it doesn't
|
||||
|
||||
* archive.c (archive_load): Set is_global in archive object
|
||||
|
||||
* Makefile.am (Locationmeta{dir|_DATA}): Added commands to install
|
||||
data files
|
||||
(INCLUDES): Added define for LOCATION_DIR
|
||||
|
||||
2000-09-03 Bradford Hovinen <hovinen@helixcode.com>
|
||||
|
||||
* location.c (save_metadata): Write attributes when saving
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
confexecdir = $(libdir)
|
||||
confexec_DATA = ximian_archiverConf.sh
|
||||
|
||||
Locationmetadir = $(datadir)/hcm/default
|
||||
Locationmeta_DATA = default-user.xml default-global.xml
|
||||
|
||||
gladedir = $(prefix)/share/hcm/glade
|
||||
glade_DATA = rollback-location-management.glade
|
||||
|
||||
includedir = $(prefix)/include/ximian-archiver
|
||||
|
||||
INCLUDES = \
|
||||
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
|
||||
-I$(includedir) $(GNOME_INCLUDEDIR) \
|
||||
-DVERSION=\""$(VERSION)"\" \
|
||||
-DCONFIGDIR=\""/etc"\" \
|
||||
-DLOCATION_DIR=\""$(datadir)/hcm/default"\" \
|
||||
-DGLADE_DIR=\""$(datadir)/hcm/glade"\" \
|
||||
$(GNOME_XML_CFLAGS) \
|
||||
$(LIBGLADE_CFLAGS)
|
||||
|
||||
bin_PROGRAMS = ximian-archiver
|
||||
lib_LTLIBRARIES = libximian_archiver.la
|
||||
|
||||
libximian_archiver_la_SOURCES = \
|
||||
archive.c archive.h \
|
||||
location.c location.h \
|
||||
config-log.c config-log.h \
|
||||
backend-list.c backend-list.h \
|
||||
util.c util.h
|
||||
|
||||
include_HEADERS = \
|
||||
archive.h location.h config-log.h backend-list.h util.h
|
||||
|
||||
ximian_archiver_SOURCES = \
|
||||
main.c
|
||||
|
||||
ximian_archiver_LDADD = \
|
||||
$(GNOME_LIBDIR) \
|
||||
$(GNOMEUI_LIBS) \
|
||||
$(INTLLIBS) \
|
||||
$(GNOME_XML_LIB) \
|
||||
libximian_archiver.la
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(Locationmeta_DATA) \
|
||||
$(glade_DATA) \
|
||||
ximian_archiverConf.sh.in
|
||||
|
||||
#
|
||||
# Create the ximian_archiverConf.sh file from the sh.in file
|
||||
#
|
||||
ximian_archiverConf.sh: ximian_archiverConf.sh.in Makefile
|
||||
sed -e 's?\@GNOME_LIBDIR\@?$(GNOME_LIBDIR) -L$(prefix)/lib?' \
|
||||
-e 's?\@GNOMEUI_LIBS\@?$(GNOMEUI_LIBS)?g' \
|
||||
-e 's?\@GNOME_INCLUDEDIR\@?$(GNOME_INCLUDEDIR) -I$(prefix)/include?g' \
|
||||
-e 's?\@ORB_LIBS\@?$(ORB_LIBS)?g' \
|
||||
< $(srcdir)/ximian_archiverConf.sh.in > ximian_archiverConf.tmp \
|
||||
&& mv ximian_archiverConf.tmp ximian_archiverConf.sh
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
* Add per-user master list
|
||||
* Archiving changes in location metadata
|
||||
* Fix race in lock handling and add timeout support (look in gnome-mime)
|
||||
* Support multiple backends from CLI
|
||||
* Add translateable backend description support
|
||||
* Some way to store the rollback time for each backend, for GUI purposes
|
||||
* Have defaults stored somewhere, to be restored when the user goes
|
||||
back before the first configuration edit
|
||||
|
||||
Long-term
|
||||
* Add clustering support:
|
||||
- Add Cluster class inheriting Archive class and overriding path
|
||||
semantics
|
||||
- Change location rollback functionality to send data through to
|
||||
clients if the archive is a cluster
|
||||
* Allow backend specs to identify an order in which they should be applied
|
||||
- Specify this in the master list; have each location look up that
|
||||
information before invoking multiple backends
|
||||
|
||||
Questions
|
||||
|
||||
Done
|
||||
* Global list of configs for a given archive
|
||||
* Location should store backend data in the location where it is valid
|
||||
* Add support for dumping XML to stdout rather than running the backend
|
||||
* Fix bug where EOF not sent through pipe
|
||||
* Changing the name of a location
|
||||
* Adding per-user/global backends
|
||||
- Don't try to write out contains list on toplevel locations
|
||||
- Give error if the user tries to add a backend to a toplevel location
|
||||
* Consistency check on adding and removing backends
|
||||
- Make sure the backend is included in the global metadata list before
|
||||
adding
|
||||
- When removing global and per-user backends, mark the backend
|
||||
"invalid" and exclude from location_foreach_backend,
|
||||
location_rollback_all_to, and location_contains.
|
||||
* Refactor master list into an attribute of Archive
|
||||
* Roll back x number of steps rather than by date
|
||||
* Try to factor out populate_locations_list to be common between the
|
||||
different dialogs
|
||||
@@ -1,635 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* archive.c
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen (hovinen@ximian.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "archive.h"
|
||||
|
||||
typedef struct _GRealTree GRealTree;
|
||||
typedef struct _GTreeNode GTreeNode;
|
||||
|
||||
typedef struct _foreach_t foreach_t;
|
||||
|
||||
struct _foreach_t
|
||||
{
|
||||
Archive *archive;
|
||||
LocationCB callback;
|
||||
Location *parent;
|
||||
gpointer user_data;
|
||||
};
|
||||
|
||||
static GtkObjectClass *parent_class;
|
||||
|
||||
static Archive *user_archive;
|
||||
static Archive *global_archive;
|
||||
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_PREFIX
|
||||
};
|
||||
|
||||
static void archive_init (Archive *archive);
|
||||
static void archive_class_init (ArchiveClass *klass);
|
||||
|
||||
static void archive_destroy (GtkObject *object);
|
||||
|
||||
static void archive_set_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
|
||||
static void archive_get_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
|
||||
static gboolean do_load (Archive *archive);
|
||||
static void load_all_locations (Archive *archive);
|
||||
|
||||
guint
|
||||
archive_get_type (void)
|
||||
{
|
||||
static guint archive_type;
|
||||
|
||||
if (!archive_type) {
|
||||
GtkTypeInfo archive_info = {
|
||||
"Archive",
|
||||
sizeof (Archive),
|
||||
sizeof (ArchiveClass),
|
||||
(GtkClassInitFunc) archive_class_init,
|
||||
(GtkObjectInitFunc) archive_init,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL
|
||||
};
|
||||
|
||||
archive_type =
|
||||
gtk_type_unique (gtk_object_get_type (),
|
||||
&archive_info);
|
||||
}
|
||||
|
||||
return archive_type;
|
||||
}
|
||||
|
||||
static void
|
||||
archive_init (Archive *archive)
|
||||
{
|
||||
archive->prefix = NULL;
|
||||
archive->locations = g_tree_new ((GCompareFunc) strcmp);
|
||||
archive->current_location_id = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
archive_class_init (ArchiveClass *klass)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
|
||||
object_class = GTK_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->destroy = archive_destroy;
|
||||
object_class->set_arg = archive_set_arg;
|
||||
object_class->get_arg = archive_get_arg;
|
||||
|
||||
gtk_object_add_arg_type ("Archive::prefix",
|
||||
GTK_TYPE_POINTER,
|
||||
GTK_ARG_READWRITE,
|
||||
ARG_PREFIX);
|
||||
|
||||
parent_class = gtk_type_class (gtk_object_get_type ());
|
||||
}
|
||||
|
||||
static void
|
||||
archive_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
Archive *archive;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_ARCHIVE (object));
|
||||
g_return_if_fail (arg != NULL);
|
||||
|
||||
archive = ARCHIVE (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_PREFIX:
|
||||
if (GTK_VALUE_POINTER (*arg) != NULL)
|
||||
archive->prefix = g_strdup (GTK_VALUE_POINTER (*arg));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
archive_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
Archive *archive;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_ARCHIVE (object));
|
||||
g_return_if_fail (arg != NULL);
|
||||
|
||||
archive = ARCHIVE (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_PREFIX:
|
||||
GTK_VALUE_POINTER (*arg) = archive->prefix;
|
||||
break;
|
||||
default:
|
||||
arg->type = GTK_TYPE_INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* archive_load:
|
||||
* @is_global: TRUE iff we should load the global archive
|
||||
*
|
||||
* Load either the global or per-user configuration archive
|
||||
*
|
||||
* Return value: Reference to archive
|
||||
**/
|
||||
|
||||
GtkObject *
|
||||
archive_load (gboolean is_global)
|
||||
{
|
||||
GtkObject *object;
|
||||
gchar *prefix;
|
||||
|
||||
if (is_global && global_archive != NULL)
|
||||
return GTK_OBJECT (global_archive);
|
||||
else if (user_archive != NULL)
|
||||
return GTK_OBJECT (user_archive);
|
||||
|
||||
if (is_global)
|
||||
prefix = CONFIGDIR "/ximian-config";
|
||||
else
|
||||
prefix = g_concat_dir_and_file (g_get_home_dir (),
|
||||
".gnome/ximian-config");
|
||||
|
||||
object = gtk_object_new (archive_get_type (),
|
||||
"prefix", prefix,
|
||||
NULL);
|
||||
|
||||
if (!is_global)
|
||||
g_free (prefix);
|
||||
|
||||
if (do_load (ARCHIVE (object)) == FALSE) {
|
||||
gtk_object_destroy (object);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ARCHIVE (object)->is_global = is_global;
|
||||
ARCHIVE (object)->backend_list =
|
||||
BACKEND_LIST (backend_list_new (is_global));
|
||||
|
||||
if (is_global)
|
||||
global_archive = ARCHIVE (object);
|
||||
else
|
||||
user_archive = ARCHIVE (object);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
static gint
|
||||
free_location_cb (gchar *locid, Location *location)
|
||||
{
|
||||
location_close (location);
|
||||
g_free (locid);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
archive_destroy (GtkObject *object)
|
||||
{
|
||||
Archive *archive;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_ARCHIVE (object));
|
||||
|
||||
archive = ARCHIVE (object);
|
||||
|
||||
g_tree_traverse (archive->locations,
|
||||
(GTraverseFunc) free_location_cb,
|
||||
G_IN_ORDER,
|
||||
NULL);
|
||||
|
||||
g_tree_destroy (archive->locations);
|
||||
|
||||
if (archive->current_location_id != NULL)
|
||||
g_free (archive->current_location_id);
|
||||
|
||||
GTK_OBJECT_CLASS (parent_class)->destroy (GTK_OBJECT (archive));
|
||||
}
|
||||
|
||||
/**
|
||||
* archive_close:
|
||||
* @archive:
|
||||
*
|
||||
* Closes the given archive handle. Also closes all locations under this
|
||||
* archive.
|
||||
**/
|
||||
|
||||
void
|
||||
archive_close (Archive *archive)
|
||||
{
|
||||
g_return_if_fail (archive != NULL);
|
||||
g_return_if_fail (IS_ARCHIVE (archive));
|
||||
|
||||
gtk_object_destroy (GTK_OBJECT (archive));
|
||||
}
|
||||
|
||||
/**
|
||||
* archive_get_location:
|
||||
* @archive:
|
||||
* @locid:
|
||||
*
|
||||
* Get a reference to the location with the given name.
|
||||
*
|
||||
* Return value: Reference to location, NULL if no such location exists
|
||||
**/
|
||||
|
||||
Location *
|
||||
archive_get_location (Archive *archive, const gchar *locid)
|
||||
{
|
||||
GtkObject *loc_obj;
|
||||
|
||||
g_return_val_if_fail (archive != NULL, NULL);
|
||||
g_return_val_if_fail (IS_ARCHIVE (archive), NULL);
|
||||
g_return_val_if_fail (locid != NULL, NULL);
|
||||
|
||||
loc_obj = g_tree_lookup (archive->locations, locid);
|
||||
|
||||
if (!loc_obj) {
|
||||
loc_obj = location_open (archive, locid);
|
||||
|
||||
if (!loc_obj) return NULL;
|
||||
|
||||
if (loc_obj)
|
||||
g_tree_insert (archive->locations,
|
||||
g_strdup (locid), loc_obj);
|
||||
}
|
||||
|
||||
if (loc_obj) {
|
||||
gtk_object_ref (loc_obj);
|
||||
return LOCATION (loc_obj);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* archive_register_location:
|
||||
* @archive:
|
||||
* @location:
|
||||
*
|
||||
* Register a location with the archive; invoked by location_new
|
||||
**/
|
||||
|
||||
void
|
||||
archive_register_location (Archive *archive, Location *location)
|
||||
{
|
||||
g_return_if_fail (archive != NULL);
|
||||
g_return_if_fail (IS_ARCHIVE (archive));
|
||||
g_return_if_fail (location != NULL);
|
||||
g_return_if_fail (IS_LOCATION (location));
|
||||
|
||||
g_tree_insert (archive->locations,
|
||||
g_strdup (location_get_id (location)),
|
||||
location);
|
||||
}
|
||||
|
||||
/**
|
||||
* archive_unregister_location:
|
||||
* @archive:
|
||||
* @location:
|
||||
*
|
||||
* Unregisters a location from the archive
|
||||
**/
|
||||
|
||||
void
|
||||
archive_unregister_location (Archive *archive, Location *location)
|
||||
{
|
||||
g_return_if_fail (archive != NULL);
|
||||
g_return_if_fail (IS_ARCHIVE (archive));
|
||||
g_return_if_fail (location != NULL);
|
||||
g_return_if_fail (IS_LOCATION (location));
|
||||
|
||||
/* FIXME: We might be screwing things up here if we're traversing... */
|
||||
g_tree_remove (archive->locations, location);
|
||||
}
|
||||
|
||||
/**
|
||||
* archive_get_current_location:
|
||||
* @archive: object
|
||||
*
|
||||
* Convenience function to get a pointer to the current location
|
||||
*
|
||||
* Return value: Pointer to current location
|
||||
**/
|
||||
|
||||
Location *
|
||||
archive_get_current_location (Archive *archive)
|
||||
{
|
||||
g_return_val_if_fail (archive != NULL, NULL);
|
||||
g_return_val_if_fail (IS_ARCHIVE (archive), NULL);
|
||||
|
||||
return archive_get_location (archive,
|
||||
archive_get_current_location_id
|
||||
(archive));
|
||||
}
|
||||
|
||||
static int
|
||||
add_location_cb (Location *location, gchar *backend_id, GList *backends)
|
||||
{
|
||||
g_list_insert (backends, backend_id, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* archive_set_current_location:
|
||||
* @archive: object
|
||||
* @location: Location to which to set archive
|
||||
*
|
||||
* Set the current location in an archive to the location given; apply
|
||||
* configuration for the new location to all backends necessary
|
||||
**/
|
||||
|
||||
void
|
||||
archive_set_current_location (Archive *archive, Location *location)
|
||||
{
|
||||
GList *location_path, *backends;
|
||||
Location *old_location = archive_get_current_location (archive);
|
||||
|
||||
g_return_if_fail (archive != NULL);
|
||||
g_return_if_fail (IS_ARCHIVE (archive));
|
||||
g_return_if_fail (location != NULL);
|
||||
g_return_if_fail (IS_LOCATION (location));
|
||||
|
||||
archive_set_current_location_id (archive, location_get_id (location));
|
||||
|
||||
location_path = location_find_path_from_common_parent
|
||||
(location, old_location);
|
||||
|
||||
backends = g_list_append (NULL, NULL);
|
||||
|
||||
while (location_path != NULL) {
|
||||
if (location_path->data != NULL) {
|
||||
location_foreach_backend
|
||||
(LOCATION (location_path->data),
|
||||
(LocationBackendCB) add_location_cb,
|
||||
backends);
|
||||
}
|
||||
|
||||
location_path = location_path->next;
|
||||
}
|
||||
|
||||
location_rollback_backends_to (location, NULL, backends->next, TRUE);
|
||||
|
||||
g_list_free (backends);
|
||||
}
|
||||
|
||||
/**
|
||||
* archive_set_current_location_id:
|
||||
* @archive:
|
||||
* @name:
|
||||
*
|
||||
* Sets the current location's name, but does not invoke any rollback
|
||||
**/
|
||||
|
||||
void
|
||||
archive_set_current_location_id (Archive *archive, const gchar *locid)
|
||||
{
|
||||
g_return_if_fail (archive != NULL);
|
||||
g_return_if_fail (IS_ARCHIVE (archive));
|
||||
g_return_if_fail (locid != NULL);
|
||||
|
||||
if (archive->current_location_id != NULL)
|
||||
g_free (archive->current_location_id);
|
||||
|
||||
archive->current_location_id = g_strdup (locid);
|
||||
|
||||
if (archive->is_global)
|
||||
gnome_config_push_prefix ("=" LOCATION_DIR "=");
|
||||
else
|
||||
gnome_config_push_prefix ("ximian-config/");
|
||||
|
||||
gnome_config_set_string ("config/current/location",
|
||||
archive->current_location_id);
|
||||
|
||||
gnome_config_pop_prefix ();
|
||||
gnome_config_sync ();
|
||||
}
|
||||
|
||||
/**
|
||||
* archive_get_current_location_id:
|
||||
* @archive: object
|
||||
*
|
||||
* Get the name of the current location
|
||||
*
|
||||
* Return value: String containing current location, should not be freed
|
||||
**/
|
||||
|
||||
const gchar *
|
||||
archive_get_current_location_id (Archive *archive)
|
||||
{
|
||||
g_return_val_if_fail (archive != NULL, NULL);
|
||||
g_return_val_if_fail (IS_ARCHIVE (archive), NULL);
|
||||
|
||||
if (archive->current_location_id == NULL) {
|
||||
if (archive->is_global)
|
||||
gnome_config_push_prefix ("=" LOCATION_DIR "=");
|
||||
else
|
||||
gnome_config_push_prefix ("ximian-config/");
|
||||
|
||||
archive->current_location_id =
|
||||
gnome_config_get_string
|
||||
("config/current/location=default");
|
||||
|
||||
gnome_config_pop_prefix ();
|
||||
}
|
||||
|
||||
return archive->current_location_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* archive_get_prefix:
|
||||
* @archive:
|
||||
*
|
||||
* Get the prefix for locations in this archive
|
||||
*
|
||||
* Return value: String containing prefix; should not be freed
|
||||
**/
|
||||
|
||||
const gchar *
|
||||
archive_get_prefix (Archive *archive)
|
||||
{
|
||||
g_return_val_if_fail (archive != NULL, FALSE);
|
||||
g_return_val_if_fail (IS_ARCHIVE (archive), FALSE);
|
||||
|
||||
return archive->prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* archive_is_global:
|
||||
* @archive:
|
||||
*
|
||||
* Tell whether the archive is global or per-user
|
||||
*
|
||||
* Return value: TRUE if global, FALSE if per-user
|
||||
**/
|
||||
|
||||
gboolean
|
||||
archive_is_global (Archive *archive)
|
||||
{
|
||||
g_return_val_if_fail (archive != NULL, FALSE);
|
||||
g_return_val_if_fail (IS_ARCHIVE (archive), FALSE);
|
||||
|
||||
return archive->is_global;
|
||||
}
|
||||
|
||||
/**
|
||||
* archive_get_backend_list:
|
||||
* @archive:
|
||||
*
|
||||
* Get the master backend list for this archive
|
||||
*
|
||||
* Return value: Reference to the master backend list
|
||||
**/
|
||||
|
||||
BackendList *
|
||||
archive_get_backend_list (Archive *archive)
|
||||
{
|
||||
g_return_val_if_fail (archive != NULL, FALSE);
|
||||
g_return_val_if_fail (IS_ARCHIVE (archive), FALSE);
|
||||
|
||||
return archive->backend_list;
|
||||
}
|
||||
|
||||
static gint
|
||||
foreach_cb (gchar *key, Location *value, foreach_t *data)
|
||||
{
|
||||
if (location_get_parent (value) == data->parent)
|
||||
return data->callback (data->archive, value,
|
||||
data->user_data);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* archive_foreach_child_location:
|
||||
* @archive:
|
||||
* @callback: Callback to invoke
|
||||
* @parent: Iterate through the children of this location; iterate through
|
||||
* toplevel locations if this is NULL
|
||||
* @data: Arbitrary data to pass to the callback
|
||||
*
|
||||
* Invoke the given callback for each location that inherits the given
|
||||
* location, or for each toplevel location if the parent given is
|
||||
* NULL. Terminate the iteration if any child returns a nonzero value
|
||||
**/
|
||||
|
||||
void
|
||||
archive_foreach_child_location (Archive *archive, LocationCB callback,
|
||||
Location *parent, gpointer data)
|
||||
{
|
||||
foreach_t f_data;
|
||||
|
||||
g_return_if_fail (archive != NULL);
|
||||
g_return_if_fail (IS_ARCHIVE (archive));
|
||||
|
||||
load_all_locations (archive);
|
||||
|
||||
f_data.archive = archive;
|
||||
f_data.callback = callback;
|
||||
f_data.parent = parent;
|
||||
f_data.user_data = data;
|
||||
|
||||
g_tree_traverse (archive->locations,
|
||||
(GTraverseFunc) foreach_cb,
|
||||
G_IN_ORDER,
|
||||
&f_data);
|
||||
}
|
||||
|
||||
/* Load the archive information from disk; return TRUE on success and FALSE on
|
||||
* failure
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
do_load (Archive *archive)
|
||||
{
|
||||
gint ret = 0;
|
||||
|
||||
g_return_val_if_fail (archive != NULL, FALSE);
|
||||
g_return_val_if_fail (IS_ARCHIVE (archive), FALSE);
|
||||
g_return_val_if_fail (archive->prefix != NULL, FALSE);
|
||||
|
||||
if (g_file_test (archive->prefix, G_FILE_TEST_ISDIR) == FALSE)
|
||||
ret = mkdir (archive->prefix, S_IREAD | S_IWRITE | S_IEXEC);
|
||||
|
||||
if (ret == -1) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Load and register all the locations for this archive */
|
||||
|
||||
static void
|
||||
load_all_locations (Archive *archive)
|
||||
{
|
||||
DIR *archive_dir;
|
||||
struct dirent entry, *entryp;
|
||||
gchar *filename;
|
||||
|
||||
archive_dir = opendir (archive->prefix);
|
||||
|
||||
if (archive_dir == NULL) {
|
||||
g_warning ("load_all_locations: %s", g_strerror (errno));
|
||||
return;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (readdir_r (archive_dir, &entry, &entryp)) {
|
||||
g_warning ("load_all_locations: %s",
|
||||
g_strerror (errno));
|
||||
break;
|
||||
}
|
||||
|
||||
if (entryp == NULL) break;
|
||||
|
||||
if (strcmp (entry.d_name, ".") &&
|
||||
strcmp (entry.d_name, ".."))
|
||||
{
|
||||
filename = g_concat_dir_and_file (archive->prefix,
|
||||
entry.d_name);
|
||||
if (g_file_test (filename, G_FILE_TEST_ISDIR))
|
||||
archive_get_location (archive, entry.d_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* archive.h
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen (hovinen@ximian.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ARCHIVE_H
|
||||
#define __ARCHIVE_H
|
||||
|
||||
#include <gnome.h>
|
||||
|
||||
#include "location.h"
|
||||
#include "backend-list.h"
|
||||
|
||||
#define ARCHIVE(obj) GTK_CHECK_CAST (obj, archive_get_type (), Archive)
|
||||
#define ARCHIVE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, archive_get_type (), ArchiveClass)
|
||||
#define IS_ARCHIVE(obj) GTK_CHECK_TYPE (obj, archive_get_type ())
|
||||
|
||||
typedef struct _ArchiveClass ArchiveClass;
|
||||
typedef gint (*LocationCB) (Archive *, Location *, gpointer);
|
||||
|
||||
struct _Archive
|
||||
{
|
||||
GtkObject object;
|
||||
|
||||
gchar *prefix;
|
||||
GTree *locations;
|
||||
gboolean is_global;
|
||||
|
||||
gchar *current_location_id;
|
||||
|
||||
BackendList *backend_list;
|
||||
};
|
||||
|
||||
struct _ArchiveClass
|
||||
{
|
||||
GtkObjectClass parent;
|
||||
};
|
||||
|
||||
guint archive_get_type (void);
|
||||
|
||||
GtkObject *archive_load (gboolean is_global);
|
||||
|
||||
void archive_close (Archive *archive);
|
||||
|
||||
Location *archive_get_location (Archive *archive,
|
||||
const gchar *location);
|
||||
void archive_register_location (Archive *archive,
|
||||
Location *location);
|
||||
void archive_unregister_location (Archive *archive,
|
||||
Location *location);
|
||||
|
||||
Location *archive_get_current_location (Archive *archive);
|
||||
void archive_set_current_location (Archive *archive,
|
||||
Location *location);
|
||||
|
||||
const gchar *archive_get_current_location_id (Archive *archive);
|
||||
void archive_set_current_location_id (Archive *archive,
|
||||
const gchar *locid);
|
||||
|
||||
const gchar *archive_get_prefix (Archive *archive);
|
||||
gboolean archive_is_global (Archive *archive);
|
||||
|
||||
BackendList *archive_get_backend_list (Archive *archive);
|
||||
|
||||
void archive_foreach_child_location (Archive *archive,
|
||||
LocationCB callback,
|
||||
Location *parent,
|
||||
gpointer data);
|
||||
|
||||
#endif /* __ARCHIVE */
|
||||
@@ -1,122 +0,0 @@
|
||||
Rollback archiving internals
|
||||
Copyright (C) 2001 Ximian Code, Inc.
|
||||
Written by Bradford Hovinen <hovinen@ximian.com>
|
||||
|
||||
1. Directory format
|
||||
|
||||
Diagram:
|
||||
|
||||
+ toplevel
|
||||
|-+ Location 1
|
||||
| |- <id>.xml
|
||||
| | .
|
||||
| | .
|
||||
| | .
|
||||
| |- metadata.log:
|
||||
| | [<id> <date> <time> <backend> ] ^
|
||||
| | [ . ] | Time
|
||||
| | [ . ] |
|
||||
| | [ . ] |
|
||||
| \- metadata.xml:
|
||||
| [... ]
|
||||
| [<inherits>location</inherits> ]
|
||||
| [<contains backend-id="backend" type="full|partial"/> ]
|
||||
| [... ]
|
||||
|-+ Location 2
|
||||
| ...
|
||||
|
||||
There is one toplevel directory for each archive. This directory
|
||||
contains one or more location directories. Each location directory
|
||||
must contain two files: an XML file describing the location and a log
|
||||
of changes made in that location. Each change corresponds to an XML
|
||||
file containing a snapshot of the configuration as modified. There is
|
||||
one XML file per backend. Each change has an id number that is
|
||||
incremented atomicall by the archiving script when it stores
|
||||
configuration changes. The id number, as well as the date and time of
|
||||
storage, form a filename that uniquely identifies each configuration
|
||||
change. The archiving script must also store in the log file a line
|
||||
with the id number, date and time of storage, and backend used
|
||||
whenever it stores XML data. New entries are stored at the head of the
|
||||
file, so that during rollback, the file may be foreward scanned to
|
||||
find the appropriate identifier for the configuration file. The
|
||||
per-location XML configuration file contains information on what the
|
||||
location's parent is and what configurations that location defines.
|
||||
|
||||
For now, the backend shall be referred to by its executable name. When
|
||||
the backends gain CORBA interfaces, I suggest that the OAF id be used
|
||||
instead. This reduces the problem of setting a backend's configuration
|
||||
to a simple object activation and method invocation. The OAF id may
|
||||
also be used to resolve the backend's human-readable name.
|
||||
|
||||
2. Meta-configuration details
|
||||
|
||||
In order that this system be complete, there must be a way to
|
||||
ascertain the current location and to roll back changes in location. I
|
||||
propose that there be a special archive in the configuration hierarchy
|
||||
that contains location history in the same format as other
|
||||
locations. The archiver can then be a single script that accepts
|
||||
command-line arguments describing the request action: `archive this
|
||||
data', `roll back this backend's configuration', and `switch to this
|
||||
location'. It then handles all the details of interfacing with the
|
||||
archive and applying the changes in the correct order. Conceptually,
|
||||
the archiver becomes a backend in and of itself, where the frontend is
|
||||
located in the GUI of HCM. It would therefore be adviseable to use the
|
||||
same standards for the archiver as for other backends and hence make
|
||||
it a CORBA service, where the tool-specific interface is as described
|
||||
above.
|
||||
|
||||
3. Fine-grained location management
|
||||
|
||||
A slight modification of the basic location management system allows
|
||||
individual settings to be covered by a location as well as entire
|
||||
backends. The contains tag in a location's metadata file contains the
|
||||
attribute type, which may either by "full" or "partial". In the former
|
||||
case, rollback proceeds as described above. If it is the latter, the
|
||||
archiver, upon rolling back or setting configuration for the relevant
|
||||
backend in that location, first retrieves the required configuration
|
||||
from both the location and its parent using the same algorithm. It
|
||||
then uses an XML merging algorithm to combine the two XML files into
|
||||
one, allowing the child location's data to override its parent's
|
||||
data. This can be accomplished using the same technique as Bonobo uses
|
||||
to allow components to override toolbars and menus in the container.
|
||||
|
||||
When a child location partially defines the data for a particular
|
||||
backend, it must store only those configuration settings that the user
|
||||
explicitly changed when updating that backend's configuration under
|
||||
that location. If the frontend simply dumped its entire XML snapshot
|
||||
to the log, all of the configuration settings would be reflected in
|
||||
that snapshot, and under the method indicated above, partial
|
||||
containment would be equivalent to full containment. Therefore, when a
|
||||
frontend stores its configuration under partial containment, the
|
||||
archiver must run a node-for-node comparison between the XML data of
|
||||
the parent location (retrieved using the method indicated above) and
|
||||
that of the child location. Only those nodes that are different are
|
||||
actually stored in the configuration log.
|
||||
|
||||
When comparing XML nodes, there must be a way to identify distinct
|
||||
nodes for comparison. For example, in a network configuration backend,
|
||||
there might be one node for each interface. If, under the parent
|
||||
location, the nodes are ordered with interface "eth0" before interface
|
||||
"eth1", while under the child location, they are in reverse order, but
|
||||
the configuration is otherwise identical, it is not the intention of
|
||||
the user that child location should override any configuration data of
|
||||
the parent location. Therefore, the best method for comparing XML data
|
||||
is to compare each child of a given node in one source to all the
|
||||
children of the relevant node in the other source. If any child in the
|
||||
other source matches, then the XML node is a duplicate and may be
|
||||
thrown out. If there is another node such that the name and attributes
|
||||
are the same, but the children are different, then the algorithm
|
||||
should be invoked recursively to determine the differences among the
|
||||
children. If there is no such node, then the node should be included.
|
||||
|
||||
4. Future directions
|
||||
|
||||
The metafile log structure may run into scalability problems for
|
||||
installations have have been in place for a long time. An alternative
|
||||
structure that uses binary indexing might be in order. A command line
|
||||
utility (with GUI interface) could be written to recover the file in
|
||||
the case of corruption; such a utility could simply introspect each of
|
||||
the XML files in a directory. Provided that each XML file contains
|
||||
enough information to create a file entry, which is trivial, recovery
|
||||
is assured.
|
||||
|
||||
@@ -1,305 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* backend-list.c
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@ximian.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <parser.h>
|
||||
#include <tree.h>
|
||||
|
||||
#include "backend-list.h"
|
||||
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_IS_GLOBAL
|
||||
};
|
||||
|
||||
struct _BackendListPrivate
|
||||
{
|
||||
gboolean is_global;
|
||||
gchar *filename;
|
||||
GList *backend_ids;
|
||||
};
|
||||
|
||||
static GtkObjectClass *parent_class;
|
||||
|
||||
static void backend_list_init (BackendList *backend_list);
|
||||
static void backend_list_class_init (BackendListClass *class);
|
||||
|
||||
static void backend_list_set_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
static void backend_list_get_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
|
||||
static void backend_list_finalize (GtkObject *object);
|
||||
|
||||
static void do_load (BackendList *backend_list);
|
||||
static void do_save (BackendList *backend_list);
|
||||
|
||||
guint
|
||||
backend_list_get_type (void)
|
||||
{
|
||||
static guint backend_list_type = 0;
|
||||
|
||||
if (!backend_list_type) {
|
||||
GtkTypeInfo backend_list_info = {
|
||||
"BackendList",
|
||||
sizeof (BackendList),
|
||||
sizeof (BackendListClass),
|
||||
(GtkClassInitFunc) backend_list_class_init,
|
||||
(GtkObjectInitFunc) backend_list_init,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL
|
||||
};
|
||||
|
||||
backend_list_type =
|
||||
gtk_type_unique (gtk_object_get_type (),
|
||||
&backend_list_info);
|
||||
}
|
||||
|
||||
return backend_list_type;
|
||||
}
|
||||
|
||||
static void
|
||||
backend_list_init (BackendList *backend_list)
|
||||
{
|
||||
backend_list->p = g_new0 (BackendListPrivate, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
backend_list_class_init (BackendListClass *class)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
|
||||
gtk_object_add_arg_type ("BackendList::is-global",
|
||||
GTK_TYPE_INT,
|
||||
GTK_ARG_CONSTRUCT_ONLY | GTK_ARG_READWRITE,
|
||||
ARG_IS_GLOBAL);
|
||||
|
||||
object_class = GTK_OBJECT_CLASS (class);
|
||||
object_class->finalize = backend_list_finalize;
|
||||
object_class->set_arg = backend_list_set_arg;
|
||||
object_class->get_arg = backend_list_get_arg;
|
||||
|
||||
parent_class = GTK_OBJECT_CLASS
|
||||
(gtk_type_class (gtk_object_get_type ()));
|
||||
}
|
||||
|
||||
static void
|
||||
backend_list_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
BackendList *backend_list;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_BACKEND_LIST (object));
|
||||
|
||||
backend_list = BACKEND_LIST (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_IS_GLOBAL:
|
||||
backend_list->p->is_global = GTK_VALUE_INT (*arg);
|
||||
|
||||
backend_list->p->filename = backend_list->p->is_global ?
|
||||
LOCATION_DIR "/default-global.xml" :
|
||||
LOCATION_DIR "/default-user.xml";
|
||||
do_load (backend_list);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Bad argument set");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
backend_list_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
BackendList *backend_list;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_BACKEND_LIST (object));
|
||||
|
||||
backend_list = BACKEND_LIST (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_IS_GLOBAL:
|
||||
GTK_VALUE_INT (*arg) = backend_list->p->is_global;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Bad argument get");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
backend_list_finalize (GtkObject *object)
|
||||
{
|
||||
BackendList *backend_list;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_BACKEND_LIST (object));
|
||||
|
||||
backend_list = BACKEND_LIST (object);
|
||||
|
||||
g_list_foreach (backend_list->p->backend_ids, (GFunc) g_free, NULL);
|
||||
g_list_free (backend_list->p->backend_ids);
|
||||
g_free (backend_list->p);
|
||||
|
||||
GTK_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
GtkObject *
|
||||
backend_list_new (gboolean is_global)
|
||||
{
|
||||
return gtk_object_new (backend_list_get_type (),
|
||||
"is-global", is_global,
|
||||
NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
backend_list_contains (BackendList *backend_list, gchar *backend_id)
|
||||
{
|
||||
g_return_val_if_fail (backend_list != NULL, FALSE);
|
||||
g_return_val_if_fail (IS_BACKEND_LIST (backend_list), FALSE);
|
||||
|
||||
return (g_list_find (backend_list->p->backend_ids, backend_id) !=
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* backend_list_foreach:
|
||||
* @backend_list:
|
||||
* @callback:
|
||||
* @data:
|
||||
*
|
||||
* Iterates through all the backends, invoking the callback given and aborting
|
||||
* if any callback returns a nonzero value
|
||||
*
|
||||
* Return value: TRUE iff no callback issued a nonzero value, FALSE otherwise
|
||||
**/
|
||||
|
||||
gboolean
|
||||
backend_list_foreach (BackendList *backend_list, BackendCB callback,
|
||||
gpointer data)
|
||||
{
|
||||
GList *node;
|
||||
|
||||
g_return_val_if_fail (backend_list != NULL, FALSE);
|
||||
g_return_val_if_fail (IS_BACKEND_LIST (backend_list), FALSE);
|
||||
g_return_val_if_fail (callback != NULL, FALSE);
|
||||
|
||||
for (node = backend_list->p->backend_ids; node; node = node->next)
|
||||
if (callback (backend_list, node->data, data)) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
backend_list_add (BackendList *backend_list, gchar *backend_id)
|
||||
{
|
||||
g_return_if_fail (backend_list != NULL);
|
||||
g_return_if_fail (IS_BACKEND_LIST (backend_list));
|
||||
g_return_if_fail (backend_id != NULL);
|
||||
|
||||
backend_list->p->backend_ids =
|
||||
g_list_prepend (backend_list->p->backend_ids, backend_id);
|
||||
}
|
||||
|
||||
void
|
||||
backend_list_remove (BackendList *backend_list, gchar *backend_id)
|
||||
{
|
||||
g_return_if_fail (backend_list != NULL);
|
||||
g_return_if_fail (IS_BACKEND_LIST (backend_list));
|
||||
g_return_if_fail (backend_id != NULL);
|
||||
|
||||
backend_list->p->backend_ids =
|
||||
g_list_remove (backend_list->p->backend_ids, backend_id);
|
||||
}
|
||||
|
||||
void
|
||||
backend_list_save (BackendList *backend_list)
|
||||
{
|
||||
g_return_if_fail (backend_list != NULL);
|
||||
g_return_if_fail (IS_BACKEND_LIST (backend_list));
|
||||
|
||||
do_save (backend_list);
|
||||
}
|
||||
|
||||
static void
|
||||
do_load (BackendList *backend_list)
|
||||
{
|
||||
xmlNodePtr root_node, node;
|
||||
xmlDocPtr doc;
|
||||
GList *list_tail = NULL;
|
||||
gchar *contains_str;
|
||||
|
||||
doc = xmlParseFile (backend_list->p->filename);
|
||||
if (doc == NULL) return;
|
||||
root_node = xmlDocGetRootElement (doc);
|
||||
|
||||
for (node = root_node->childs; node; node = node->next) {
|
||||
if (!strcmp (node->name, "contains")) {
|
||||
contains_str = xmlGetProp (node, "backend");
|
||||
|
||||
if (contains_str != NULL) {
|
||||
contains_str = g_strdup (contains_str);
|
||||
list_tail = g_list_append (list_tail,
|
||||
contains_str);
|
||||
if (backend_list->p->backend_ids == NULL)
|
||||
backend_list->p->backend_ids =
|
||||
list_tail;
|
||||
else
|
||||
list_tail = list_tail->next;
|
||||
} else {
|
||||
g_warning ("Bad backends list: " \
|
||||
"contains element with no " \
|
||||
"backend attribute");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_save (BackendList *backend_list)
|
||||
{
|
||||
xmlNodePtr root_node, child_node;
|
||||
xmlDocPtr doc;
|
||||
GList *node;
|
||||
|
||||
doc = xmlNewDoc ("1.0");
|
||||
root_node = xmlNewDocNode (doc, NULL, "location", NULL);
|
||||
|
||||
for (node = backend_list->p->backend_ids; node; node = node->next) {
|
||||
child_node = xmlNewChild (root_node, NULL, "contains", NULL);
|
||||
xmlNewProp (child_node, "backend", node->data);
|
||||
}
|
||||
|
||||
xmlDocSetRootElement (doc, root_node);
|
||||
xmlSaveFile (backend_list->p->filename, doc);
|
||||
xmlFreeDoc (doc);
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* backend-list.h
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@ximian.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __BACKEND_LIST_H
|
||||
#define __BACKEND_LIST_H
|
||||
|
||||
#include <gnome.h>
|
||||
|
||||
BEGIN_GNOME_DECLS
|
||||
|
||||
#define BACKEND_LIST(obj) GTK_CHECK_CAST (obj, backend_list_get_type (), BackendList)
|
||||
#define BACKEND_LIST_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, backend_list_get_type (), BackendListClass)
|
||||
#define IS_BACKEND_LIST(obj) GTK_CHECK_TYPE (obj, backend_list_get_type ())
|
||||
|
||||
typedef struct _BackendList BackendList;
|
||||
typedef struct _BackendListClass BackendListClass;
|
||||
typedef struct _BackendListPrivate BackendListPrivate;
|
||||
|
||||
typedef gint (*BackendCB) (BackendList *, gchar *, gpointer);
|
||||
|
||||
struct _BackendList
|
||||
{
|
||||
GtkObject parent;
|
||||
|
||||
BackendListPrivate *p;
|
||||
};
|
||||
|
||||
struct _BackendListClass
|
||||
{
|
||||
GtkObjectClass gtk_object_class;
|
||||
};
|
||||
|
||||
guint backend_list_get_type (void);
|
||||
|
||||
GtkObject *backend_list_new (gboolean is_global);
|
||||
|
||||
gboolean backend_list_contains (BackendList *backend_list,
|
||||
gchar *backend_id);
|
||||
|
||||
gboolean backend_list_foreach (BackendList *backend_list,
|
||||
BackendCB callback,
|
||||
gpointer data);
|
||||
|
||||
void backend_list_add (BackendList *backend_list,
|
||||
gchar *backend_id);
|
||||
void backend_list_remove (BackendList *backend_list,
|
||||
gchar *backend_id);
|
||||
|
||||
void backend_list_save (BackendList *backend_list);
|
||||
|
||||
END_GNOME_DECLS
|
||||
|
||||
#endif /* __BACKEND_LIST_H */
|
||||
@@ -1,935 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* config-log.c
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen (hovinen@ximian.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "config-log.h"
|
||||
#include "location.h"
|
||||
#include "util.h"
|
||||
|
||||
static GtkObjectClass *parent_class;
|
||||
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_LOCATION
|
||||
};
|
||||
|
||||
typedef struct _ConfigLogEntry ConfigLogEntry;
|
||||
|
||||
struct _ConfigLogEntry
|
||||
{
|
||||
gint id;
|
||||
struct tm *date;
|
||||
gchar *backend_id;
|
||||
};
|
||||
|
||||
static void config_log_init (ConfigLog *config_log);
|
||||
static void config_log_class_init (ConfigLogClass *klass);
|
||||
|
||||
static void config_log_set_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
|
||||
static void config_log_get_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
|
||||
static void config_log_destroy (GtkObject *object);
|
||||
|
||||
static GList *find_config_log_entry_id (ConfigLog *config_log,
|
||||
GList *start,
|
||||
gint id);
|
||||
static GList *find_config_log_entry_date (ConfigLog *config_log,
|
||||
GList *start,
|
||||
struct tm *date);
|
||||
static GList *find_config_log_entry_backend (ConfigLog *config_log,
|
||||
GList *start,
|
||||
gchar *backend_id);
|
||||
|
||||
static GList *load_next_log_entry (ConfigLog *config_log,
|
||||
GList *last);
|
||||
|
||||
static gchar *get_line (FILE *file);
|
||||
static gboolean parse_line (char *buffer,
|
||||
int *id,
|
||||
struct tm *time,
|
||||
char **backend_id);
|
||||
static gboolean time_geq (struct tm *time1,
|
||||
struct tm *time2);
|
||||
|
||||
static gboolean do_load (ConfigLog *config_log);
|
||||
static void do_unload (ConfigLog *config_log);
|
||||
|
||||
static gint get_next_id (ConfigLog *config_log);
|
||||
static struct tm *get_current_date (void);
|
||||
static void write_log (FILE *output,
|
||||
ConfigLogEntry *entry);
|
||||
static void dump_log (ConfigLog *config_log);
|
||||
|
||||
static void config_log_entry_destroy (ConfigLogEntry *entry);
|
||||
|
||||
guint
|
||||
config_log_get_type (void)
|
||||
{
|
||||
static guint config_log_type;
|
||||
|
||||
if (!config_log_type) {
|
||||
GtkTypeInfo config_log_info = {
|
||||
"ConfigLog",
|
||||
sizeof (ConfigLog),
|
||||
sizeof (ConfigLogClass),
|
||||
(GtkClassInitFunc) config_log_class_init,
|
||||
(GtkObjectInitFunc) config_log_init,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL
|
||||
};
|
||||
|
||||
config_log_type =
|
||||
gtk_type_unique (gtk_object_get_type (),
|
||||
&config_log_info);
|
||||
}
|
||||
|
||||
return config_log_type;
|
||||
}
|
||||
|
||||
static void
|
||||
config_log_init (ConfigLog *config_log)
|
||||
{
|
||||
config_log->location = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
config_log_class_init (ConfigLogClass *klass)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
|
||||
object_class = GTK_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->destroy = config_log_destroy;
|
||||
object_class->set_arg = config_log_set_arg;
|
||||
object_class->get_arg = config_log_get_arg;
|
||||
|
||||
gtk_object_add_arg_type ("ConfigLog::location",
|
||||
GTK_TYPE_POINTER,
|
||||
GTK_ARG_READWRITE,
|
||||
ARG_LOCATION);
|
||||
|
||||
parent_class = gtk_type_class (gtk_object_get_type ());
|
||||
}
|
||||
|
||||
static void
|
||||
config_log_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
ConfigLog *config_log;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_CONFIG_LOG (object));
|
||||
g_return_if_fail (arg != NULL);
|
||||
|
||||
config_log = CONFIG_LOG (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_LOCATION:
|
||||
g_return_if_fail (GTK_VALUE_POINTER (*arg) != NULL);
|
||||
g_return_if_fail (IS_LOCATION (GTK_VALUE_POINTER (*arg)));
|
||||
|
||||
config_log->location = GTK_VALUE_POINTER (*arg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
config_log_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
ConfigLog *config_log;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_CONFIG_LOG (object));
|
||||
g_return_if_fail (arg != NULL);
|
||||
|
||||
config_log = CONFIG_LOG (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_LOCATION:
|
||||
GTK_VALUE_POINTER (*arg) = config_log->location;
|
||||
break;
|
||||
default:
|
||||
arg->type = GTK_TYPE_INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loads a configuration log. Creates it if it has not been created
|
||||
* already
|
||||
*/
|
||||
|
||||
GtkObject *
|
||||
config_log_open (Location *location)
|
||||
{
|
||||
GtkObject *object;
|
||||
|
||||
object = gtk_object_new (config_log_get_type (),
|
||||
"location", location,
|
||||
NULL);
|
||||
|
||||
do_load (CONFIG_LOG (object));
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
/* Destroys a configuration log data structure and frees all memory
|
||||
* associated with it, dumping the existing log out to disk
|
||||
*/
|
||||
|
||||
static void
|
||||
config_log_destroy (GtkObject *object)
|
||||
{
|
||||
ConfigLog *config_log;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_CONFIG_LOG (object));
|
||||
|
||||
config_log = CONFIG_LOG (object);
|
||||
|
||||
do_unload (config_log);
|
||||
|
||||
GTK_OBJECT_CLASS (parent_class)->destroy (GTK_OBJECT (config_log));
|
||||
}
|
||||
|
||||
/**
|
||||
* config_log_delete:
|
||||
* @config_log:
|
||||
*
|
||||
* Permanently destroy a config log, including its log file. Also destory the
|
||||
* object
|
||||
**/
|
||||
|
||||
void
|
||||
config_log_delete (ConfigLog *config_log)
|
||||
{
|
||||
g_return_if_fail (config_log != NULL);
|
||||
g_return_if_fail (IS_CONFIG_LOG (config_log));
|
||||
|
||||
if (config_log->file != NULL) {
|
||||
fclose (config_log->file);
|
||||
config_log->file = NULL;
|
||||
}
|
||||
|
||||
if (config_log->filename != NULL)
|
||||
unlink (config_log->filename);
|
||||
|
||||
gtk_object_destroy (GTK_OBJECT (config_log));
|
||||
}
|
||||
|
||||
/* Return the id number of the most recent data written by the given
|
||||
* backend prior to the given date. If date is NULL, it is assumed to
|
||||
* be today.
|
||||
*/
|
||||
|
||||
gint
|
||||
config_log_get_rollback_id_for_date (ConfigLog *config_log,
|
||||
struct tm *date,
|
||||
gchar *backend_id)
|
||||
{
|
||||
GList *node;
|
||||
|
||||
g_return_val_if_fail (config_log != NULL, -1);
|
||||
g_return_val_if_fail (IS_CONFIG_LOG (config_log), -1);
|
||||
g_return_val_if_fail (backend_id != NULL, -1);
|
||||
|
||||
if (config_log->log_data == NULL)
|
||||
config_log->log_data =
|
||||
load_next_log_entry (config_log, NULL);
|
||||
|
||||
if (date == NULL)
|
||||
node = config_log->log_data;
|
||||
else
|
||||
node = find_config_log_entry_date (config_log,
|
||||
config_log->log_data,
|
||||
date);
|
||||
|
||||
node = find_config_log_entry_backend (config_log, node, backend_id);
|
||||
|
||||
if (!node)
|
||||
return -1;
|
||||
else
|
||||
return ((ConfigLogEntry *) node->data)->id;
|
||||
}
|
||||
|
||||
/* Given a linked list of backend ids and a date, return an array of
|
||||
* ids corresponding to the most recent data written by each of the
|
||||
* backends prior to the given date. The array is in the same order as
|
||||
* the backends and should be freed when done. If date is NULL, it is
|
||||
* assumed to be today.
|
||||
*
|
||||
* FIXME: This should really sort the ids by date.
|
||||
*/
|
||||
|
||||
gint *
|
||||
config_log_get_rollback_ids_for_date (ConfigLog *config_log,
|
||||
struct tm *date,
|
||||
GList *backend_ids)
|
||||
{
|
||||
GList *start_node, *node;
|
||||
gint *id_array, i = 0;
|
||||
|
||||
g_return_val_if_fail (config_log != NULL, NULL);
|
||||
g_return_val_if_fail (IS_CONFIG_LOG (config_log), NULL);
|
||||
g_return_val_if_fail (backend_ids != NULL, NULL);
|
||||
|
||||
if (config_log->log_data == NULL)
|
||||
config_log->log_data =
|
||||
load_next_log_entry (config_log, NULL);
|
||||
|
||||
if (date == NULL)
|
||||
start_node = config_log->log_data;
|
||||
else
|
||||
start_node = find_config_log_entry_date (config_log,
|
||||
config_log->log_data,
|
||||
date);
|
||||
|
||||
id_array = g_new (gint, g_list_length (backend_ids));
|
||||
|
||||
for (; backend_ids; backend_ids = backend_ids->next) {
|
||||
node = find_config_log_entry_backend (config_log,
|
||||
start_node,
|
||||
backend_ids->data);
|
||||
if (!node)
|
||||
id_array[i] = -1;
|
||||
else
|
||||
id_array[i] = ((ConfigLogEntry *) node->data)->id;
|
||||
i++;
|
||||
}
|
||||
|
||||
return id_array;
|
||||
}
|
||||
|
||||
/* Return the rollback id that is the given number of steps back from the
|
||||
* current revision, or -1 if there is no such id
|
||||
*/
|
||||
|
||||
gint
|
||||
config_log_get_rollback_id_by_steps (ConfigLog *config_log,
|
||||
guint steps, gchar *backend_id)
|
||||
{
|
||||
GList *node;
|
||||
|
||||
g_return_val_if_fail (config_log != NULL, -1);
|
||||
g_return_val_if_fail (IS_CONFIG_LOG (config_log), -1);
|
||||
g_return_val_if_fail (backend_id != NULL, -1);
|
||||
|
||||
node = config_log->log_data;
|
||||
|
||||
if (node == NULL)
|
||||
node = load_next_log_entry (config_log, node);
|
||||
|
||||
while (node != NULL && steps-- > 0) {
|
||||
node = find_config_log_entry_backend
|
||||
(config_log, node, backend_id);
|
||||
|
||||
if (steps > 0) {
|
||||
if (node->next == NULL)
|
||||
node = load_next_log_entry (config_log, node);
|
||||
else
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (node != NULL)
|
||||
return ((ConfigLogEntry *) node->data)->id;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the backend that generated the data with the given id */
|
||||
|
||||
gchar *
|
||||
config_log_get_backend_id_for_id (ConfigLog *config_log, gint id)
|
||||
{
|
||||
GList *node;
|
||||
|
||||
g_return_val_if_fail (config_log != NULL, NULL);
|
||||
g_return_val_if_fail (IS_CONFIG_LOG (config_log), NULL);
|
||||
g_return_val_if_fail (id >= 0, NULL);
|
||||
|
||||
if (config_log->log_data == NULL)
|
||||
config_log->log_data =
|
||||
load_next_log_entry (config_log, NULL);
|
||||
|
||||
node = find_config_log_entry_id (config_log,
|
||||
config_log->log_data, id);
|
||||
|
||||
if (!node)
|
||||
return NULL;
|
||||
else
|
||||
return ((ConfigLogEntry *) node->data)->backend_id;
|
||||
}
|
||||
|
||||
/* Return the date the data with the given id was written */
|
||||
|
||||
struct tm *
|
||||
config_log_get_date_for_id (ConfigLog *config_log, gint id)
|
||||
{
|
||||
GList *node;
|
||||
|
||||
g_return_val_if_fail (config_log != NULL, NULL);
|
||||
g_return_val_if_fail (IS_CONFIG_LOG (config_log), NULL);
|
||||
g_return_val_if_fail (id >= 0, NULL);
|
||||
|
||||
if (config_log->log_data == NULL)
|
||||
config_log->log_data =
|
||||
load_next_log_entry (config_log, NULL);
|
||||
|
||||
node = find_config_log_entry_id (config_log,
|
||||
config_log->log_data, id);
|
||||
|
||||
if (!node)
|
||||
return NULL;
|
||||
else
|
||||
return ((ConfigLogEntry *) node->data)->date;
|
||||
}
|
||||
|
||||
gint
|
||||
config_log_write_entry (ConfigLog *config_log, gchar *backend_id)
|
||||
{
|
||||
ConfigLogEntry *entry;
|
||||
|
||||
g_return_val_if_fail (config_log != NULL, -1);
|
||||
g_return_val_if_fail (IS_CONFIG_LOG (config_log), -1);
|
||||
g_return_val_if_fail (backend_id != NULL, -1);
|
||||
|
||||
entry = g_new0 (ConfigLogEntry, 1);
|
||||
entry->id = get_next_id (config_log);
|
||||
entry->date = get_current_date ();
|
||||
entry->backend_id = g_strdup (backend_id);
|
||||
|
||||
config_log->log_data = g_list_prepend (config_log->log_data, entry);
|
||||
|
||||
return entry->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* config_log_iterate:
|
||||
* @config_log:
|
||||
* @callback:
|
||||
* @data:
|
||||
*
|
||||
* Iterate through all log entries an invoke the given callback on each one,
|
||||
* passing the id, date created, and backend id to it
|
||||
**/
|
||||
|
||||
void
|
||||
config_log_iterate (ConfigLog *config_log, ConfigLogIteratorCB callback,
|
||||
gpointer data)
|
||||
{
|
||||
GList *node;
|
||||
ConfigLogEntry *entry;
|
||||
|
||||
g_return_if_fail (config_log != NULL);
|
||||
g_return_if_fail (IS_CONFIG_LOG (config_log));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
node = config_log->log_data;
|
||||
while (node != NULL) {
|
||||
entry = (ConfigLogEntry *) node->data;
|
||||
if (callback (config_log, entry->id, entry->backend_id,
|
||||
entry->date, node->data)) break;
|
||||
|
||||
if (node->next == NULL)
|
||||
node = load_next_log_entry (config_log, node);
|
||||
else
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* config_log_reset_filenames:
|
||||
* @config_log:
|
||||
*
|
||||
* Rereads the log's location data to determine filenames
|
||||
**/
|
||||
|
||||
void
|
||||
config_log_reset_filenames (ConfigLog *config_log)
|
||||
{
|
||||
g_return_if_fail (config_log != NULL);
|
||||
g_return_if_fail (IS_CONFIG_LOG (config_log));
|
||||
|
||||
if (config_log->filename != NULL)
|
||||
g_free (config_log->filename);
|
||||
|
||||
config_log->filename =
|
||||
g_concat_dir_and_file (location_get_path
|
||||
(config_log->location),
|
||||
"config.log");
|
||||
if (config_log->lock_filename != NULL)
|
||||
g_free (config_log->lock_filename);
|
||||
|
||||
config_log->lock_filename =
|
||||
g_concat_dir_and_file (location_get_path
|
||||
(config_log->location),
|
||||
"config.log.lock");
|
||||
}
|
||||
|
||||
/* Find the config log entry with the id given, starting at the given
|
||||
* node. Return a pointer to the node.
|
||||
*/
|
||||
|
||||
static GList *
|
||||
find_config_log_entry_id (ConfigLog *config_log, GList *start, gint id)
|
||||
{
|
||||
GList *last;
|
||||
ConfigLogEntry *entry;
|
||||
|
||||
g_return_val_if_fail (config_log != NULL, NULL);
|
||||
g_return_val_if_fail (IS_CONFIG_LOG (config_log), NULL);
|
||||
g_return_val_if_fail (id >= 0, NULL);
|
||||
|
||||
if (!start) return NULL;
|
||||
|
||||
while (start != NULL) {
|
||||
last = start;
|
||||
entry = (ConfigLogEntry *) start->data;
|
||||
if (entry->id == id)
|
||||
return start;
|
||||
else if (entry->id < id)
|
||||
return NULL;
|
||||
start = start->next;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
start = load_next_log_entry (config_log, last);
|
||||
if (start == NULL) return NULL;
|
||||
entry = (ConfigLogEntry *) start->data;
|
||||
if (entry->id == id)
|
||||
return start;
|
||||
else if (entry->id < id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the first config log entry made prior to the given date,
|
||||
* starting at the given node. Return a pointer to the node.
|
||||
*/
|
||||
|
||||
static GList *
|
||||
find_config_log_entry_date (ConfigLog *config_log, GList *start,
|
||||
struct tm *date)
|
||||
{
|
||||
GList *last;
|
||||
ConfigLogEntry *entry;
|
||||
|
||||
g_return_val_if_fail (config_log != NULL, NULL);
|
||||
g_return_val_if_fail (IS_CONFIG_LOG (config_log), NULL);
|
||||
g_return_val_if_fail (date != NULL, NULL);
|
||||
|
||||
if (!start) return NULL;
|
||||
|
||||
while (start != NULL) {
|
||||
last = start;
|
||||
entry = (ConfigLogEntry *) start->data;
|
||||
if (time_geq (date, entry->date))
|
||||
return start;
|
||||
start = start->next;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
start = load_next_log_entry (config_log, last);
|
||||
if (start == NULL) return NULL;
|
||||
entry = (ConfigLogEntry *) start->data;
|
||||
if (time_geq (date, entry->date))
|
||||
return start;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the first config log entry made by the given backend,
|
||||
* starting at the given node. Return a pointer to the node.
|
||||
*/
|
||||
|
||||
static GList *
|
||||
find_config_log_entry_backend (ConfigLog *config_log, GList *start,
|
||||
gchar *backend_id)
|
||||
{
|
||||
GList *last;
|
||||
ConfigLogEntry *entry;
|
||||
|
||||
g_return_val_if_fail (config_log != NULL, NULL);
|
||||
g_return_val_if_fail (IS_CONFIG_LOG (config_log), NULL);
|
||||
g_return_val_if_fail (backend_id != NULL, NULL);
|
||||
|
||||
if (!start) return NULL;
|
||||
|
||||
while (start != NULL) {
|
||||
last = start;
|
||||
entry = (ConfigLogEntry *) start->data;
|
||||
if (!strcmp (entry->backend_id, backend_id))
|
||||
return start;
|
||||
start = start->next;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
start = load_next_log_entry (config_log, last);
|
||||
if (start == NULL) return NULL;
|
||||
entry = (ConfigLogEntry *) start->data;
|
||||
if (!strcmp (entry->backend_id, backend_id))
|
||||
return start;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GList *
|
||||
load_next_log_entry (ConfigLog *config_log, GList *last)
|
||||
{
|
||||
gchar *buffer, *backend_id;
|
||||
ConfigLogEntry *entry;
|
||||
gboolean success;
|
||||
|
||||
g_return_val_if_fail (config_log != NULL, NULL);
|
||||
g_return_val_if_fail (IS_CONFIG_LOG (config_log), NULL);
|
||||
|
||||
if (!config_log->file || feof (config_log->file)) return NULL;
|
||||
|
||||
buffer = get_line (config_log->file);
|
||||
|
||||
entry = g_new0 (ConfigLogEntry, 1);
|
||||
entry->date = g_new0 (struct tm, 1);
|
||||
success = parse_line (buffer, &entry->id,
|
||||
entry->date, &backend_id);
|
||||
|
||||
if (success) {
|
||||
entry->backend_id = g_strdup (backend_id);
|
||||
last = g_list_append (last, entry);
|
||||
|
||||
if (!config_log->log_data) {
|
||||
config_log->log_data = last;
|
||||
config_log->first_old = last;
|
||||
}
|
||||
|
||||
return g_list_find (last, entry);
|
||||
} else {
|
||||
g_free (entry);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read an entire line from the given file, returning a pointer to an
|
||||
* allocated string. Strip the trailing newline from the line.
|
||||
*/
|
||||
|
||||
static gchar *
|
||||
get_line (FILE *file)
|
||||
{
|
||||
int buf_size = 0;
|
||||
char *buf = NULL, *tmp = NULL;
|
||||
size_t distance = 0, amt_read = 0;
|
||||
|
||||
g_return_val_if_fail (file != NULL, NULL);
|
||||
|
||||
while (amt_read == buf_size - distance) {
|
||||
distance = tmp - buf;
|
||||
|
||||
if (distance >= buf_size) {
|
||||
if (buf == NULL) {
|
||||
buf_size = 1024;
|
||||
buf = g_new (char, buf_size);
|
||||
} else {
|
||||
buf_size *= 2;
|
||||
buf = g_renew (char, buf, buf_size);
|
||||
}
|
||||
|
||||
tmp = buf + distance;
|
||||
}
|
||||
|
||||
fgets (tmp, buf_size - distance, file);
|
||||
amt_read = strlen (tmp);
|
||||
tmp += amt_read;
|
||||
}
|
||||
|
||||
if (tmp) *(tmp - 1) = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Parse a line from the log file. All pointers must be valid.
|
||||
*
|
||||
* Note: backend just points to somewhere in buffer, so it becomes
|
||||
* invalid the next time the buffer is overwritten. If there's a
|
||||
* trailing newline, it is not chopped off.
|
||||
*
|
||||
* Returns TRUE on success and FALSE on parse error; if FALSE is
|
||||
* returned, the values placed in the variables given are undefined.
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
parse_line (char *buffer, int *id, struct tm *date, char **backend_id)
|
||||
{
|
||||
sscanf (buffer, "%x", id);
|
||||
|
||||
while (isxdigit (*buffer)) buffer++;
|
||||
|
||||
if (!isspace (*buffer) || !isdigit (*(buffer + 1))) return FALSE;
|
||||
buffer++;
|
||||
|
||||
if (extract_number (&buffer, &date->tm_year, 4) == FALSE)
|
||||
return FALSE;
|
||||
if (extract_number (&buffer, &date->tm_mon, 2) == FALSE)
|
||||
return FALSE;
|
||||
if (extract_number (&buffer, &date->tm_mday, 2) == FALSE)
|
||||
return FALSE;
|
||||
|
||||
date->tm_year -= 1900;
|
||||
date->tm_mon--;
|
||||
|
||||
if (!isspace (*buffer) || !isdigit (*(buffer + 1))) return FALSE;
|
||||
buffer++;
|
||||
|
||||
if (extract_number (&buffer, &date->tm_hour, 2) == FALSE)
|
||||
return FALSE;
|
||||
if (*buffer != ':') return FALSE; buffer++;
|
||||
if (extract_number (&buffer, &date->tm_min, 2) == FALSE)
|
||||
return FALSE;
|
||||
if (*buffer != ':') return FALSE; buffer++;
|
||||
if (extract_number (&buffer, &date->tm_sec, 2) == FALSE)
|
||||
return FALSE;
|
||||
|
||||
if (!isspace (*buffer) || *(buffer + 1) == '\0') return FALSE;
|
||||
buffer++;
|
||||
|
||||
*backend_id = buffer;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Return TRUE if the first given struct tm is greater than or equal
|
||||
* to the second given struct tm; FALSE otherwise
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
time_geq (struct tm *time1, struct tm *time2)
|
||||
{
|
||||
if (time1->tm_year > time2->tm_year) return TRUE;
|
||||
if (time1->tm_year < time2->tm_year) return FALSE;
|
||||
if (time1->tm_mon > time2->tm_mon) return TRUE;
|
||||
if (time1->tm_mon < time2->tm_mon) return FALSE;
|
||||
if (time1->tm_mday > time2->tm_mday) return TRUE;
|
||||
if (time1->tm_mday < time2->tm_mday) return FALSE;
|
||||
if (time1->tm_hour > time2->tm_hour) return TRUE;
|
||||
if (time1->tm_hour < time2->tm_hour) return FALSE;
|
||||
if (time1->tm_min > time2->tm_min) return TRUE;
|
||||
if (time1->tm_min < time2->tm_min) return FALSE;
|
||||
if (time1->tm_sec >= time2->tm_sec) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Opens up a configuration log. Assumes all the structures are
|
||||
* already initialized. Creates the log if not already done.
|
||||
*
|
||||
* Returns TRUE on success and FALSE on failure (unable to open output
|
||||
* file or log is locked)
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
do_load (ConfigLog *config_log)
|
||||
{
|
||||
FILE *lock_file;
|
||||
|
||||
g_return_val_if_fail (config_log != NULL, FALSE);
|
||||
g_return_val_if_fail (IS_CONFIG_LOG (config_log), FALSE);
|
||||
g_return_val_if_fail (config_log->location != NULL, FALSE);
|
||||
g_return_val_if_fail (IS_LOCATION (config_log->location), FALSE);
|
||||
|
||||
do_unload (config_log);
|
||||
config_log_reset_filenames (config_log);
|
||||
|
||||
#if 0 /* Locking disabled for now */
|
||||
/* FIXME: Race condition here, plus lock handling should be
|
||||
* better */
|
||||
|
||||
if (g_file_test (config_log->lock_filename, G_FILE_TEST_ISFILE))
|
||||
return FALSE;
|
||||
|
||||
lock_file = fopen (config_log->lock_filename, "w");
|
||||
fclose (lock_file);
|
||||
#endif
|
||||
|
||||
config_log->file = fopen (config_log->filename, "r");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Closes the input file for a given log and dumps and clears the
|
||||
* cache
|
||||
*/
|
||||
|
||||
static void
|
||||
do_unload (ConfigLog *config_log)
|
||||
{
|
||||
GList *tmp;
|
||||
|
||||
g_return_if_fail (config_log != NULL);
|
||||
g_return_if_fail (IS_CONFIG_LOG (config_log));
|
||||
|
||||
dump_log (config_log);
|
||||
|
||||
if (config_log->file) {
|
||||
fclose (config_log->file);
|
||||
config_log->file = NULL;
|
||||
}
|
||||
|
||||
if (config_log->filename) {
|
||||
g_free (config_log->filename);
|
||||
config_log->filename = NULL;
|
||||
}
|
||||
|
||||
if (config_log->lock_filename) {
|
||||
unlink (config_log->lock_filename);
|
||||
g_free (config_log->lock_filename);
|
||||
config_log->lock_filename = NULL;
|
||||
}
|
||||
|
||||
while (config_log->log_data) {
|
||||
tmp = config_log->log_data->next;
|
||||
config_log_entry_destroy
|
||||
((ConfigLogEntry *) config_log->log_data->data);
|
||||
g_list_free_1 (config_log->log_data);
|
||||
config_log->log_data = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns the next id number in the sequence */
|
||||
|
||||
static gint
|
||||
get_next_id (ConfigLog *config_log)
|
||||
{
|
||||
if (config_log->log_data == NULL) {
|
||||
if (load_next_log_entry (config_log, NULL) == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ((ConfigLogEntry *) config_log->log_data->data)->id + 1;
|
||||
}
|
||||
|
||||
/* Return a newly allocated struct tm with the current time */
|
||||
|
||||
static struct tm *
|
||||
get_current_date (void)
|
||||
{
|
||||
time_t current_time;
|
||||
struct tm *time_1, *ret;
|
||||
|
||||
current_time = time (NULL);
|
||||
time_1 = localtime (¤t_time);
|
||||
ret = g_new (struct tm, 1);
|
||||
memcpy (ret, time_1, sizeof (struct tm));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Write out a log entry */
|
||||
|
||||
static void
|
||||
write_log (FILE *output, ConfigLogEntry *entry)
|
||||
{
|
||||
g_return_if_fail (output != NULL);
|
||||
g_return_if_fail (entry != NULL);
|
||||
g_return_if_fail (entry->id >= 0);
|
||||
g_return_if_fail (entry->date != NULL);
|
||||
g_return_if_fail (entry->backend_id != NULL);
|
||||
|
||||
fprintf (output, "%08x %04d%02d%02d %02d:%02d:%02d %s\n",
|
||||
entry->id, entry->date->tm_year + 1900,
|
||||
entry->date->tm_mon + 1, entry->date->tm_mday,
|
||||
entry->date->tm_hour, entry->date->tm_min,
|
||||
entry->date->tm_sec, entry->backend_id);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_log (ConfigLog *config_log)
|
||||
{
|
||||
char *filename_out;
|
||||
FILE *output;
|
||||
GList *first;
|
||||
char buffer[16384];
|
||||
size_t size;
|
||||
|
||||
g_return_if_fail (config_log != NULL);
|
||||
g_return_if_fail (IS_CONFIG_LOG (config_log));
|
||||
g_return_if_fail (config_log->location != NULL);
|
||||
g_return_if_fail (IS_LOCATION (config_log->location));
|
||||
g_return_if_fail (location_get_path (config_log->location) != NULL);
|
||||
|
||||
filename_out = g_concat_dir_and_file (location_get_path
|
||||
(config_log->location),
|
||||
"config.log.out");
|
||||
|
||||
output = fopen (filename_out, "w");
|
||||
|
||||
if (!output) {
|
||||
g_warning ("Could not open output file: %s",
|
||||
g_strerror (errno));
|
||||
return;
|
||||
}
|
||||
|
||||
for (first = config_log->log_data; first != config_log->first_old;
|
||||
first = first->next)
|
||||
write_log (output, first->data);
|
||||
|
||||
if (config_log->file) {
|
||||
rewind (config_log->file);
|
||||
|
||||
while (!feof (config_log->file)) {
|
||||
size = fread (buffer, sizeof (char),
|
||||
16384, config_log->file);
|
||||
fwrite (buffer, sizeof (char), size, output);
|
||||
}
|
||||
}
|
||||
|
||||
fclose (output);
|
||||
|
||||
if (config_log->filename)
|
||||
rename (filename_out, config_log->filename);
|
||||
}
|
||||
|
||||
static void
|
||||
config_log_entry_destroy (ConfigLogEntry *entry)
|
||||
{
|
||||
g_return_if_fail (entry != NULL);
|
||||
g_return_if_fail (entry->date != NULL);
|
||||
g_return_if_fail (entry->backend_id != NULL);
|
||||
|
||||
g_free (entry->date);
|
||||
g_free (entry->backend_id);
|
||||
g_free (entry);
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* config-log.h
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen (hovinen@ximian.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_LOG_H
|
||||
#define __CONFIG_LOG_H
|
||||
|
||||
#include <gnome.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#define CONFIG_LOG(obj) GTK_CHECK_CAST (obj, config_log_get_type (), ConfigLog)
|
||||
#define CONFIG_LOG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, config_log_get_type (), ConfigLogClass)
|
||||
#define IS_CONFIG_LOG(obj) GTK_CHECK_TYPE (obj, config_log_get_type ())
|
||||
|
||||
typedef struct _ConfigLog ConfigLog;
|
||||
typedef struct _ConfigLogClass ConfigLogClass;
|
||||
|
||||
typedef struct _Location Location;
|
||||
|
||||
typedef gint (*ConfigLogIteratorCB) (ConfigLog *, gint, gchar *,
|
||||
struct tm *, gpointer);
|
||||
|
||||
struct _ConfigLog
|
||||
{
|
||||
GtkObject object;
|
||||
|
||||
Location *location;
|
||||
|
||||
FILE *file;
|
||||
char *filename;
|
||||
char *lock_filename;
|
||||
|
||||
GList *log_data;
|
||||
GList *first_old;
|
||||
};
|
||||
|
||||
struct _ConfigLogClass
|
||||
{
|
||||
GtkObjectClass parent;
|
||||
};
|
||||
|
||||
guint config_log_get_type (void);
|
||||
|
||||
GtkObject *config_log_open (Location *location);
|
||||
void config_log_delete (ConfigLog *config_log);
|
||||
|
||||
gint config_log_get_rollback_id_for_date (ConfigLog *config_log,
|
||||
struct tm *date,
|
||||
gchar *backend_id);
|
||||
gint *config_log_get_rollback_ids_for_date (ConfigLog *config_log,
|
||||
struct tm *date,
|
||||
GList *backend_ids);
|
||||
|
||||
gint config_log_get_rollback_id_by_steps (ConfigLog *config_log,
|
||||
guint steps,
|
||||
gchar *backend_id);
|
||||
|
||||
gchar *config_log_get_backend_id_for_id (ConfigLog *config_log,
|
||||
gint id);
|
||||
struct tm *config_log_get_date_for_id (ConfigLog *config_log,
|
||||
gint id);
|
||||
|
||||
gint config_log_write_entry (ConfigLog *config_log,
|
||||
gchar *backend_id);
|
||||
|
||||
void config_log_iterate (ConfigLog *config_log,
|
||||
ConfigLogIteratorCB callback,
|
||||
gpointer data);
|
||||
|
||||
void config_log_reset_filenames (ConfigLog *config_log);
|
||||
|
||||
#endif /* __CONFIG_LOG */
|
||||
@@ -1,625 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* config-manager-dialog.c
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@ximian.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <glade/glade.h>
|
||||
|
||||
#include "config-manager-dialog.h"
|
||||
#include "create-location-dialog.h"
|
||||
#include "archive.h"
|
||||
#include "location.h"
|
||||
#include "backend-list.h"
|
||||
#include "location-list.h"
|
||||
|
||||
#define WID(str) (glade_xml_get_widget (dialog->p->config_dialog_data, str))
|
||||
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_TYPE
|
||||
};
|
||||
|
||||
struct _ConfigManagerDialogPrivate
|
||||
{
|
||||
GladeXML *config_dialog_data;
|
||||
|
||||
CMDialogType type;
|
||||
|
||||
struct tm *date;
|
||||
gboolean rollback_all;
|
||||
gchar *backend_id;
|
||||
gchar *selected_location_id;
|
||||
|
||||
Archive *global_archive;
|
||||
Archive *user_archive;
|
||||
|
||||
BackendList *global_list;
|
||||
BackendList *user_list;
|
||||
|
||||
Location *current_global;
|
||||
Location *current_user;
|
||||
|
||||
LocationList *location_list;
|
||||
};
|
||||
|
||||
static GnomeDialogClass *parent_class;
|
||||
|
||||
static void config_manager_dialog_init (ConfigManagerDialog *dialog);
|
||||
static void config_manager_dialog_class_init (ConfigManagerDialogClass *class);
|
||||
|
||||
static void config_manager_dialog_set_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
static void config_manager_dialog_get_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
|
||||
static void config_manager_dialog_finalize (GtkObject *object);
|
||||
|
||||
static void ok_cb (GtkWidget *widget,
|
||||
ConfigManagerDialog *dialog);
|
||||
static void apply_cb (GtkWidget *widget,
|
||||
ConfigManagerDialog *dialog);
|
||||
static void cancel_cb (GtkWidget *widget,
|
||||
ConfigManagerDialog *dialog);
|
||||
static void time_count_changed_cb (GtkSpinButton *button,
|
||||
ConfigManagerDialog *dialog);
|
||||
static void rollback_all_toggled_cb (GtkToggleButton *button,
|
||||
ConfigManagerDialog *dialog);
|
||||
static void rollback_one_toggled_cb (GtkToggleButton *button,
|
||||
ConfigManagerDialog *dialog);
|
||||
static void backend_select_cb (GtkMenuItem *menu_item,
|
||||
ConfigManagerDialog *dialog);
|
||||
|
||||
static void create_cb (GtkWidget *button,
|
||||
ConfigManagerDialog *dialog);
|
||||
static void rename_cb (GtkWidget *button,
|
||||
ConfigManagerDialog *dialog);
|
||||
static void destroy_cb (GtkWidget *button,
|
||||
ConfigManagerDialog *dialog);
|
||||
static void change_location_cb (GtkWidget *button,
|
||||
ConfigManagerDialog *dialog);
|
||||
static void edit_location_cb (GtkWidget *button,
|
||||
ConfigManagerDialog *dialog);
|
||||
static void real_create_cb (CreateLocationDialog
|
||||
*create_dialog,
|
||||
gchar *name,
|
||||
Location *parent,
|
||||
ConfigManagerDialog *dialog);
|
||||
|
||||
static void do_rollback (ConfigManagerDialog *dialog);
|
||||
static void reset_time (ConfigManagerDialog *dialog,
|
||||
guint sub_days);
|
||||
static gint populate_backends_cb (BackendList *list,
|
||||
gchar *backend_id,
|
||||
ConfigManagerDialog *dialog);
|
||||
static void populate_backends_list (ConfigManagerDialog *dialog,
|
||||
BackendList *list);
|
||||
|
||||
static void set_backend_controls_sensitive (ConfigManagerDialog *dialog,
|
||||
gboolean s);
|
||||
|
||||
guint
|
||||
config_manager_dialog_get_type (void)
|
||||
{
|
||||
static guint config_manager_dialog_type = 0;
|
||||
|
||||
if (!config_manager_dialog_type) {
|
||||
GtkTypeInfo config_manager_dialog_info = {
|
||||
"ConfigManagerDialog",
|
||||
sizeof (ConfigManagerDialog),
|
||||
sizeof (ConfigManagerDialogClass),
|
||||
(GtkClassInitFunc) config_manager_dialog_class_init,
|
||||
(GtkObjectInitFunc) config_manager_dialog_init,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL
|
||||
};
|
||||
|
||||
config_manager_dialog_type =
|
||||
gtk_type_unique (gnome_dialog_get_type (),
|
||||
&config_manager_dialog_info);
|
||||
}
|
||||
|
||||
return config_manager_dialog_type;
|
||||
}
|
||||
|
||||
static void
|
||||
config_manager_dialog_init (ConfigManagerDialog *dialog)
|
||||
{
|
||||
static char *buttons[] = {
|
||||
GNOME_STOCK_BUTTON_OK,
|
||||
GNOME_STOCK_BUTTON_APPLY,
|
||||
GNOME_STOCK_BUTTON_CANCEL,
|
||||
NULL
|
||||
};
|
||||
|
||||
gnome_dialog_constructv (GNOME_DIALOG (dialog),
|
||||
_("Rollback and Location Management"),
|
||||
buttons);
|
||||
|
||||
dialog->p = g_new0 (ConfigManagerDialogPrivate, 1);
|
||||
dialog->p->config_dialog_data =
|
||||
glade_xml_new (GLADE_DIR "/rollback-location-management.glade",
|
||||
"config_dialog_data");
|
||||
|
||||
gtk_box_pack_start (GTK_BOX
|
||||
(GNOME_DIALOG (dialog)->vbox),
|
||||
WID ("config_dialog_data"), 0, TRUE, TRUE);
|
||||
|
||||
gtk_window_set_policy (GTK_WINDOW (dialog),
|
||||
TRUE, FALSE, TRUE);
|
||||
|
||||
gnome_dialog_button_connect (GNOME_DIALOG (dialog),
|
||||
0, GTK_SIGNAL_FUNC (ok_cb),
|
||||
dialog);
|
||||
gnome_dialog_button_connect (GNOME_DIALOG (dialog),
|
||||
1, GTK_SIGNAL_FUNC (apply_cb),
|
||||
dialog);
|
||||
gnome_dialog_button_connect (GNOME_DIALOG (dialog),
|
||||
2, GTK_SIGNAL_FUNC (cancel_cb),
|
||||
dialog);
|
||||
|
||||
glade_xml_signal_connect_data (dialog->p->config_dialog_data,
|
||||
"time_count_changed_cb",
|
||||
time_count_changed_cb,
|
||||
dialog);
|
||||
glade_xml_signal_connect_data (dialog->p->config_dialog_data,
|
||||
"rollback_all_toggled_cb",
|
||||
rollback_all_toggled_cb,
|
||||
dialog);
|
||||
glade_xml_signal_connect_data (dialog->p->config_dialog_data,
|
||||
"rollback_one_toggled_cb",
|
||||
rollback_one_toggled_cb,
|
||||
dialog);
|
||||
glade_xml_signal_connect_data (dialog->p->config_dialog_data,
|
||||
"create_cb",
|
||||
create_cb,
|
||||
dialog);
|
||||
glade_xml_signal_connect_data (dialog->p->config_dialog_data,
|
||||
"rename_cb",
|
||||
rename_cb,
|
||||
dialog);
|
||||
glade_xml_signal_connect_data (dialog->p->config_dialog_data,
|
||||
"destroy_cb",
|
||||
destroy_cb,
|
||||
dialog);
|
||||
glade_xml_signal_connect_data (dialog->p->config_dialog_data,
|
||||
"change_location_cb",
|
||||
change_location_cb,
|
||||
dialog);
|
||||
glade_xml_signal_connect_data (dialog->p->config_dialog_data,
|
||||
"edit_location_cb",
|
||||
edit_location_cb,
|
||||
dialog);
|
||||
|
||||
dialog->p->rollback_all = TRUE;
|
||||
dialog->p->date = g_new (struct tm, 1);
|
||||
dialog->p->location_list =
|
||||
LOCATION_LIST (location_list_new (FALSE, NULL, NULL));
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (dialog->p->location_list));
|
||||
gtk_container_add (GTK_CONTAINER (WID ("location_tree_location")),
|
||||
GTK_WIDGET (dialog->p->location_list));
|
||||
|
||||
set_backend_controls_sensitive (dialog, FALSE);
|
||||
reset_time (dialog, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
config_manager_dialog_class_init (ConfigManagerDialogClass *class)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
|
||||
gtk_object_add_arg_type ("ConfigManagerDialog::type",
|
||||
GTK_TYPE_INT,
|
||||
GTK_ARG_CONSTRUCT_ONLY | GTK_ARG_READWRITE,
|
||||
ARG_TYPE);
|
||||
|
||||
object_class = GTK_OBJECT_CLASS (class);
|
||||
object_class->finalize = config_manager_dialog_finalize;
|
||||
object_class->set_arg = config_manager_dialog_set_arg;
|
||||
object_class->get_arg = config_manager_dialog_get_arg;
|
||||
|
||||
parent_class = GNOME_DIALOG_CLASS
|
||||
(gtk_type_class (gnome_dialog_get_type ()));
|
||||
}
|
||||
|
||||
static void
|
||||
config_manager_dialog_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
ConfigManagerDialog *dialog;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (object));
|
||||
|
||||
dialog = CONFIG_MANAGER_DIALOG (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_TYPE:
|
||||
dialog->p->type = GTK_VALUE_INT (*arg);
|
||||
|
||||
switch (dialog->p->type) {
|
||||
case CM_DIALOG_USER_ONLY:
|
||||
dialog->p->user_archive =
|
||||
ARCHIVE (archive_load (FALSE));
|
||||
dialog->p->global_archive = NULL;
|
||||
break;
|
||||
|
||||
case CM_DIALOG_GLOBAL_ONLY:
|
||||
dialog->p->global_archive =
|
||||
ARCHIVE (archive_load (TRUE));
|
||||
dialog->p->user_archive = NULL;
|
||||
break;
|
||||
|
||||
case CM_DIALOG_BOTH:
|
||||
dialog->p->user_archive =
|
||||
ARCHIVE (archive_load (FALSE));
|
||||
dialog->p->global_archive =
|
||||
ARCHIVE (archive_load (TRUE));
|
||||
break;
|
||||
}
|
||||
|
||||
if (dialog->p->user_archive != NULL) {
|
||||
dialog->p->user_list =
|
||||
archive_get_backend_list
|
||||
(dialog->p->user_archive);
|
||||
dialog->p->current_user =
|
||||
archive_get_current_location
|
||||
(dialog->p->user_archive);
|
||||
populate_backends_list
|
||||
(dialog, dialog->p->user_list);
|
||||
}
|
||||
|
||||
if (dialog->p->global_archive != NULL) {
|
||||
dialog->p->global_list =
|
||||
archive_get_backend_list
|
||||
(dialog->p->global_archive);
|
||||
dialog->p->current_global =
|
||||
archive_get_current_location
|
||||
(dialog->p->global_archive);
|
||||
populate_backends_list
|
||||
(dialog, dialog->p->global_list);
|
||||
}
|
||||
|
||||
gtk_object_set (GTK_OBJECT (dialog->p->location_list),
|
||||
"user-archive", dialog->p->user_archive,
|
||||
"global-archive", dialog->p->global_archive,
|
||||
NULL);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Bad argument set");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
config_manager_dialog_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
ConfigManagerDialog *dialog;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (object));
|
||||
|
||||
dialog = CONFIG_MANAGER_DIALOG (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_TYPE:
|
||||
GTK_VALUE_INT (*arg) = dialog->p->type;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Bad argument get");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
config_manager_dialog_finalize (GtkObject *object)
|
||||
{
|
||||
ConfigManagerDialog *dialog;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (object));
|
||||
|
||||
dialog = CONFIG_MANAGER_DIALOG (object);
|
||||
|
||||
if (dialog->p->date != NULL)
|
||||
g_free (dialog->p->date);
|
||||
|
||||
if (dialog->p->type == CM_DIALOG_USER_ONLY ||
|
||||
dialog->p->type == CM_DIALOG_BOTH)
|
||||
{
|
||||
gtk_object_unref (GTK_OBJECT (dialog->p->current_user));
|
||||
gtk_object_unref (GTK_OBJECT (dialog->p->user_list));
|
||||
gtk_object_unref (GTK_OBJECT (dialog->p->user_archive));
|
||||
}
|
||||
|
||||
if (dialog->p->type == CM_DIALOG_GLOBAL_ONLY ||
|
||||
dialog->p->type == CM_DIALOG_BOTH)
|
||||
{
|
||||
gtk_object_unref (GTK_OBJECT (dialog->p->current_global));
|
||||
gtk_object_unref (GTK_OBJECT (dialog->p->global_list));
|
||||
gtk_object_unref (GTK_OBJECT (dialog->p->global_archive));
|
||||
}
|
||||
|
||||
g_free (dialog->p);
|
||||
|
||||
GTK_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
config_manager_dialog_new (CMDialogType type)
|
||||
{
|
||||
return gtk_widget_new (config_manager_dialog_get_type (),
|
||||
"type", type,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
ok_cb (GtkWidget *widget, ConfigManagerDialog *dialog)
|
||||
{
|
||||
g_return_if_fail (dialog != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog));
|
||||
|
||||
do_rollback (dialog);
|
||||
|
||||
gnome_dialog_close (GNOME_DIALOG (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
apply_cb (GtkWidget *widget, ConfigManagerDialog *dialog)
|
||||
{
|
||||
g_return_if_fail (dialog != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog));
|
||||
|
||||
do_rollback (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
cancel_cb (GtkWidget *widget, ConfigManagerDialog *dialog)
|
||||
{
|
||||
g_return_if_fail (dialog != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog));
|
||||
|
||||
/* This little hack will trick the location manager into rolling back
|
||||
* to the last known configuration
|
||||
*/
|
||||
g_free (dialog->p->date);
|
||||
dialog->p->date = NULL;
|
||||
do_rollback (dialog);
|
||||
|
||||
gnome_dialog_close (GNOME_DIALOG (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
time_count_changed_cb (GtkSpinButton *button, ConfigManagerDialog *dialog)
|
||||
{
|
||||
g_return_if_fail (dialog != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog));
|
||||
|
||||
reset_time (dialog, gtk_spin_button_get_value_as_int (button));
|
||||
}
|
||||
|
||||
static void
|
||||
rollback_all_toggled_cb (GtkToggleButton *button, ConfigManagerDialog *dialog)
|
||||
{
|
||||
g_return_if_fail (dialog != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog));
|
||||
|
||||
if (gtk_toggle_button_get_active (button)) {
|
||||
dialog->p->rollback_all = TRUE;
|
||||
set_backend_controls_sensitive (dialog, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rollback_one_toggled_cb (GtkToggleButton *button, ConfigManagerDialog *dialog)
|
||||
{
|
||||
g_return_if_fail (dialog != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog));
|
||||
|
||||
if (gtk_toggle_button_get_active (button)) {
|
||||
dialog->p->rollback_all = FALSE;
|
||||
set_backend_controls_sensitive (dialog, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
backend_select_cb (GtkMenuItem *menu_item, ConfigManagerDialog *dialog)
|
||||
{
|
||||
g_return_if_fail (dialog != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog));
|
||||
|
||||
dialog->p->backend_id = gtk_object_get_data (GTK_OBJECT (menu_item),
|
||||
"backend-id");
|
||||
}
|
||||
|
||||
static void
|
||||
create_cb (GtkWidget *button, ConfigManagerDialog *dialog)
|
||||
{
|
||||
CreateLocationDialog *create_dialog;
|
||||
|
||||
g_return_if_fail (dialog != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog));
|
||||
|
||||
create_dialog = CREATE_LOCATION_DIALOG
|
||||
(create_location_dialog_new (dialog->p->type));
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (create_dialog),
|
||||
"create-location",
|
||||
GTK_SIGNAL_FUNC (real_create_cb),
|
||||
dialog);
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (create_dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
rename_cb (GtkWidget *button, ConfigManagerDialog *dialog)
|
||||
{
|
||||
g_return_if_fail (dialog != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_cb (GtkWidget *button, ConfigManagerDialog *dialog)
|
||||
{
|
||||
g_return_if_fail (dialog != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
change_location_cb (GtkWidget *button, ConfigManagerDialog *dialog)
|
||||
{
|
||||
g_return_if_fail (dialog != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog));
|
||||
|
||||
/* FIXME */
|
||||
archive_set_current_location (dialog->p->user_archive,
|
||||
location_list_get_selected_location
|
||||
(dialog->p->location_list));
|
||||
}
|
||||
|
||||
static void
|
||||
edit_location_cb (GtkWidget *button, ConfigManagerDialog *dialog)
|
||||
{
|
||||
g_return_if_fail (dialog != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
real_create_cb (CreateLocationDialog *create_dialog, gchar *name,
|
||||
Location *parent, ConfigManagerDialog *dialog)
|
||||
{
|
||||
g_return_if_fail (dialog != NULL);
|
||||
g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog));
|
||||
|
||||
/* FIXME */
|
||||
location_new (dialog->p->user_archive, name, parent);
|
||||
location_list_reread (dialog->p->location_list);
|
||||
}
|
||||
|
||||
static void
|
||||
do_rollback (ConfigManagerDialog *dialog)
|
||||
{
|
||||
switch (dialog->p->type) {
|
||||
case CM_DIALOG_USER_ONLY:
|
||||
if (dialog->p->rollback_all)
|
||||
location_rollback_all_to
|
||||
(dialog->p->current_user,
|
||||
dialog->p->date, TRUE);
|
||||
else
|
||||
location_rollback_backend_to
|
||||
(dialog->p->current_user,
|
||||
dialog->p->date,
|
||||
dialog->p->backend_id, TRUE);
|
||||
break;
|
||||
|
||||
case CM_DIALOG_GLOBAL_ONLY:
|
||||
if (dialog->p->rollback_all)
|
||||
location_rollback_all_to
|
||||
(dialog->p->current_global,
|
||||
dialog->p->date, TRUE);
|
||||
else
|
||||
location_rollback_backend_to
|
||||
(dialog->p->current_global,
|
||||
dialog->p->date,
|
||||
dialog->p->backend_id, TRUE);
|
||||
break;
|
||||
|
||||
case CM_DIALOG_BOTH:
|
||||
if (dialog->p->rollback_all) {
|
||||
location_rollback_all_to
|
||||
(dialog->p->current_global,
|
||||
dialog->p->date, TRUE);
|
||||
location_rollback_all_to
|
||||
(dialog->p->current_user,
|
||||
dialog->p->date, TRUE);
|
||||
}
|
||||
else if (backend_list_contains
|
||||
(dialog->p->global_list, dialog->p->backend_id))
|
||||
{
|
||||
location_rollback_backend_to
|
||||
(dialog->p->current_global,
|
||||
dialog->p->date,
|
||||
dialog->p->backend_id, TRUE);
|
||||
} else {
|
||||
location_rollback_backend_to
|
||||
(dialog->p->current_user,
|
||||
dialog->p->date,
|
||||
dialog->p->backend_id, TRUE);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reset_time (ConfigManagerDialog *dialog, guint sub_days)
|
||||
{
|
||||
time_t current_time;
|
||||
|
||||
time (¤t_time);
|
||||
current_time -= sub_days * 24 * 60 * 60;
|
||||
localtime_r (¤t_time, dialog->p->date);
|
||||
}
|
||||
|
||||
static gint
|
||||
populate_backends_cb (BackendList *list, gchar *backend_id,
|
||||
ConfigManagerDialog *dialog)
|
||||
{
|
||||
GtkWidget *menu_item;
|
||||
GtkWidget *menu;
|
||||
|
||||
menu_item = gtk_menu_item_new_with_label (backend_id);
|
||||
gtk_widget_show (menu_item);
|
||||
gtk_object_set_data (GTK_OBJECT (menu_item),
|
||||
"backend-id", backend_id);
|
||||
gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
|
||||
GTK_SIGNAL_FUNC (backend_select_cb), dialog);
|
||||
|
||||
menu = gtk_option_menu_get_menu
|
||||
(GTK_OPTION_MENU (WID ("backend_select")));
|
||||
gtk_menu_append (GTK_MENU (menu), menu_item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
populate_backends_list (ConfigManagerDialog *dialog, BackendList *list)
|
||||
{
|
||||
backend_list_foreach (list, (BackendCB) populate_backends_cb, dialog);
|
||||
|
||||
gtk_option_menu_set_history
|
||||
(GTK_OPTION_MENU (WID ("backend_select")), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
set_backend_controls_sensitive (ConfigManagerDialog *dialog, gboolean s)
|
||||
{
|
||||
gtk_widget_set_sensitive (WID ("backend_select"), s);
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* config-manager-dialog.h
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@ximian.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_MANAGER_DIALOG_H
|
||||
#define __CONFIG_MANAGER_DIALOG_H
|
||||
|
||||
#include <gnome.h>
|
||||
|
||||
BEGIN_GNOME_DECLS
|
||||
|
||||
#define CONFIG_MANAGER_DIALOG(obj) GTK_CHECK_CAST (obj, config_manager_dialog_get_type (), ConfigManagerDialog)
|
||||
#define CONFIG_MANAGER_DIALOG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, config_manager_dialog_get_type (), ConfigManagerDialogClass)
|
||||
#define IS_CONFIG_MANAGER_DIALOG(obj) GTK_CHECK_TYPE (obj, config_manager_dialog_get_type ())
|
||||
|
||||
typedef struct _ConfigManagerDialog ConfigManagerDialog;
|
||||
typedef struct _ConfigManagerDialogClass ConfigManagerDialogClass;
|
||||
typedef struct _ConfigManagerDialogPrivate ConfigManagerDialogPrivate;
|
||||
|
||||
typedef enum _CMDialogType CMDialogType;
|
||||
|
||||
struct _ConfigManagerDialog
|
||||
{
|
||||
GnomeDialog parent;
|
||||
|
||||
ConfigManagerDialogPrivate *p;
|
||||
};
|
||||
|
||||
struct _ConfigManagerDialogClass
|
||||
{
|
||||
GnomeDialogClass gnome_dialog_class;
|
||||
};
|
||||
|
||||
enum _CMDialogType {
|
||||
CM_DIALOG_USER_ONLY, CM_DIALOG_GLOBAL_ONLY, CM_DIALOG_BOTH
|
||||
};
|
||||
|
||||
guint config_manager_dialog_get_type (void);
|
||||
|
||||
GtkWidget *config_manager_dialog_new (CMDialogType type);
|
||||
|
||||
END_GNOME_DECLS
|
||||
|
||||
#endif /* __CONFIG_MANAGER_DIALOG_H */
|
||||
@@ -1,53 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* config-manager.c
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@ximian.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <gnome.h>
|
||||
#include <glade/glade.h>
|
||||
|
||||
#include "config-manager-dialog.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
bindtextdomain (PACKAGE, GNOMELOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
gnome_init ("config-manager", VERSION, argc, argv);
|
||||
glade_gnome_init ();
|
||||
|
||||
dialog = config_manager_dialog_new (CM_DIALOG_USER_ONLY);
|
||||
gtk_widget_show (dialog);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
|
||||
gtk_main_quit, NULL);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,291 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* create-location-dialog.c
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@ximian.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <glade/glade.h>
|
||||
|
||||
#include "create-location-dialog.h"
|
||||
#include "location-list.h"
|
||||
|
||||
#define WID(str) (glade_xml_get_widget (dialog->p->create_dialog_data, str))
|
||||
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_TYPE
|
||||
};
|
||||
|
||||
enum {
|
||||
CREATE_LOCATION_SIGNAL,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
struct _CreateLocationDialogPrivate
|
||||
{
|
||||
GladeXML *create_dialog_data;
|
||||
|
||||
CMDialogType type;
|
||||
|
||||
gchar *selected_location_id;
|
||||
|
||||
Archive *global_archive;
|
||||
Archive *user_archive;
|
||||
|
||||
LocationList *location_list;
|
||||
};
|
||||
|
||||
static GnomeDialogClass *parent_class;
|
||||
|
||||
static guint create_location_dialog_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void create_location_dialog_init (CreateLocationDialog *dialog);
|
||||
static void create_location_dialog_class_init (CreateLocationDialogClass *class);
|
||||
|
||||
static void create_location_dialog_set_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
static void create_location_dialog_get_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
|
||||
static void ok_cb (GtkWidget *widget,
|
||||
CreateLocationDialog *dialog);
|
||||
static void cancel_cb (GtkWidget *widget,
|
||||
CreateLocationDialog *dialog);
|
||||
|
||||
static void create_location_dialog_finalize (GtkObject *object);
|
||||
|
||||
guint
|
||||
create_location_dialog_get_type (void)
|
||||
{
|
||||
static guint create_location_dialog_type = 0;
|
||||
|
||||
if (!create_location_dialog_type) {
|
||||
GtkTypeInfo create_location_dialog_info = {
|
||||
"CreateLocationDialog",
|
||||
sizeof (CreateLocationDialog),
|
||||
sizeof (CreateLocationDialogClass),
|
||||
(GtkClassInitFunc) create_location_dialog_class_init,
|
||||
(GtkObjectInitFunc) create_location_dialog_init,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL
|
||||
};
|
||||
|
||||
create_location_dialog_type =
|
||||
gtk_type_unique (gnome_dialog_get_type (),
|
||||
&create_location_dialog_info);
|
||||
}
|
||||
|
||||
return create_location_dialog_type;
|
||||
}
|
||||
|
||||
static void
|
||||
create_location_dialog_init (CreateLocationDialog *dialog)
|
||||
{
|
||||
static char *buttons[] = {
|
||||
GNOME_STOCK_BUTTON_OK,
|
||||
GNOME_STOCK_BUTTON_CANCEL,
|
||||
NULL
|
||||
};
|
||||
|
||||
gnome_dialog_constructv (GNOME_DIALOG (dialog),
|
||||
_("Rollback and Location Management"),
|
||||
buttons);
|
||||
|
||||
dialog->p = g_new0 (CreateLocationDialogPrivate, 1);
|
||||
dialog->p->create_dialog_data =
|
||||
glade_xml_new (GLADE_DIR "/rollback-location-management.glade",
|
||||
"create_dialog_data");
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox),
|
||||
WID ("create_dialog_data"), 0, TRUE, TRUE);
|
||||
|
||||
gtk_window_set_policy (GTK_WINDOW (dialog), TRUE, FALSE, TRUE);
|
||||
|
||||
gnome_dialog_button_connect (GNOME_DIALOG (dialog),
|
||||
0, GTK_SIGNAL_FUNC (ok_cb),
|
||||
dialog);
|
||||
gnome_dialog_button_connect (GNOME_DIALOG (dialog),
|
||||
1, GTK_SIGNAL_FUNC (cancel_cb),
|
||||
dialog);
|
||||
|
||||
dialog->p->location_list =
|
||||
LOCATION_LIST (location_list_new (FALSE, NULL, NULL));
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (dialog->p->location_list));
|
||||
gtk_container_add (GTK_CONTAINER (WID ("location_list_location")),
|
||||
GTK_WIDGET (dialog->p->location_list));
|
||||
}
|
||||
|
||||
static void
|
||||
create_location_dialog_class_init (CreateLocationDialogClass *class)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
|
||||
gtk_object_add_arg_type ("CreateLocationDialog::type",
|
||||
GTK_TYPE_INT,
|
||||
GTK_ARG_CONSTRUCT_ONLY | GTK_ARG_READWRITE,
|
||||
ARG_TYPE);
|
||||
|
||||
object_class = GTK_OBJECT_CLASS (class);
|
||||
object_class->finalize = create_location_dialog_finalize;
|
||||
object_class->set_arg = create_location_dialog_set_arg;
|
||||
object_class->get_arg = create_location_dialog_get_arg;
|
||||
|
||||
create_location_dialog_signals[CREATE_LOCATION_SIGNAL] =
|
||||
gtk_signal_new ("create-location", GTK_RUN_FIRST,
|
||||
object_class->type,
|
||||
GTK_SIGNAL_OFFSET (CreateLocationDialogClass,
|
||||
create_location),
|
||||
gtk_marshal_NONE__POINTER_POINTER,
|
||||
GTK_TYPE_NONE, 2, GTK_TYPE_POINTER,
|
||||
GTK_TYPE_POINTER);
|
||||
|
||||
gtk_object_class_add_signals (object_class,
|
||||
create_location_dialog_signals,
|
||||
LAST_SIGNAL);
|
||||
|
||||
parent_class = GNOME_DIALOG_CLASS
|
||||
(gtk_type_class (gnome_dialog_get_type ()));
|
||||
}
|
||||
|
||||
static void
|
||||
create_location_dialog_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
CreateLocationDialog *dialog;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_CREATE_LOCATION_DIALOG (object));
|
||||
|
||||
dialog = CREATE_LOCATION_DIALOG (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_TYPE:
|
||||
dialog->p->type = GTK_VALUE_INT (*arg);
|
||||
|
||||
switch (dialog->p->type) {
|
||||
case CM_DIALOG_USER_ONLY:
|
||||
dialog->p->user_archive =
|
||||
ARCHIVE (archive_load (FALSE));
|
||||
dialog->p->global_archive = NULL;
|
||||
break;
|
||||
|
||||
case CM_DIALOG_GLOBAL_ONLY:
|
||||
dialog->p->global_archive =
|
||||
ARCHIVE (archive_load (TRUE));
|
||||
dialog->p->user_archive = NULL;
|
||||
break;
|
||||
|
||||
case CM_DIALOG_BOTH:
|
||||
dialog->p->user_archive =
|
||||
ARCHIVE (archive_load (FALSE));
|
||||
dialog->p->global_archive =
|
||||
ARCHIVE (archive_load (TRUE));
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_object_set (GTK_OBJECT (dialog->p->location_list),
|
||||
"user-archive", dialog->p->user_archive,
|
||||
"global-archive", dialog->p->global_archive,
|
||||
NULL);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Bad argument set");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
create_location_dialog_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
CreateLocationDialog *dialog;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_CREATE_LOCATION_DIALOG (object));
|
||||
|
||||
dialog = CREATE_LOCATION_DIALOG (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_TYPE:
|
||||
GTK_VALUE_INT (*arg) = dialog->p->type;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Bad argument get");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
create_location_dialog_finalize (GtkObject *object)
|
||||
{
|
||||
CreateLocationDialog *dialog;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_CREATE_LOCATION_DIALOG (object));
|
||||
|
||||
dialog = CREATE_LOCATION_DIALOG (object);
|
||||
|
||||
g_free (dialog->p);
|
||||
|
||||
GTK_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
GtkObject *
|
||||
create_location_dialog_new (CMDialogType type)
|
||||
{
|
||||
return gtk_object_new (create_location_dialog_get_type (),
|
||||
"type", type,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
ok_cb (GtkWidget *widget, CreateLocationDialog *dialog)
|
||||
{
|
||||
g_return_if_fail (dialog != NULL);
|
||||
g_return_if_fail (IS_CREATE_LOCATION_DIALOG (dialog));
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT (dialog),
|
||||
create_location_dialog_signals
|
||||
[CREATE_LOCATION_SIGNAL],
|
||||
gtk_entry_get_text
|
||||
(GTK_ENTRY (WID ("location_name_entry"))),
|
||||
location_list_get_selected_location
|
||||
(dialog->p->location_list));
|
||||
|
||||
gnome_dialog_close (GNOME_DIALOG (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
cancel_cb (GtkWidget *widget, CreateLocationDialog *dialog)
|
||||
{
|
||||
g_return_if_fail (dialog != NULL);
|
||||
g_return_if_fail (IS_CREATE_LOCATION_DIALOG (dialog));
|
||||
|
||||
gnome_dialog_close (GNOME_DIALOG (dialog));
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* create-location-dialog.h
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@ximian.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __CREATE_LOCATION_DIALOG_H
|
||||
#define __CREATE_LOCATION_DIALOG_H
|
||||
|
||||
#include <gnome.h>
|
||||
|
||||
#include "config-manager-dialog.h"
|
||||
#include "location.h"
|
||||
|
||||
BEGIN_GNOME_DECLS
|
||||
|
||||
#define CREATE_LOCATION_DIALOG(obj) GTK_CHECK_CAST (obj, create_location_dialog_get_type (), CreateLocationDialog)
|
||||
#define CREATE_LOCATION_DIALOG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, create_location_dialog_get_type (), CreateLocationDialogClass)
|
||||
#define IS_CREATE_LOCATION_DIALOG(obj) GTK_CHECK_TYPE (obj, create_location_dialog_get_type ())
|
||||
|
||||
typedef struct _CreateLocationDialog CreateLocationDialog;
|
||||
typedef struct _CreateLocationDialogClass CreateLocationDialogClass;
|
||||
typedef struct _CreateLocationDialogPrivate CreateLocationDialogPrivate;
|
||||
|
||||
struct _CreateLocationDialog
|
||||
{
|
||||
GnomeDialog parent;
|
||||
|
||||
CreateLocationDialogPrivate *p;
|
||||
};
|
||||
|
||||
struct _CreateLocationDialogClass
|
||||
{
|
||||
GnomeDialogClass gnome_dialog_class;
|
||||
|
||||
void (*create_location) (CreateLocationDialog *, gchar *, Location *);
|
||||
};
|
||||
|
||||
guint create_location_dialog_get_type (void);
|
||||
|
||||
GtkObject *create_location_dialog_new (CMDialogType type);
|
||||
|
||||
END_GNOME_DECLS
|
||||
|
||||
#endif /* __CREATE_LOCATION_DIALOG_H */
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<location>
|
||||
<contains>time-conf</contains>
|
||||
<contains>shares-conf</contains>
|
||||
</location>
|
||||
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<location>
|
||||
<contains backend="background-properties-capplet"/>
|
||||
<contains backend="bell-properties-capplet"/>
|
||||
<contains backend="gnome-edit-properties-capplet"/>
|
||||
<contains backend="keyboard-properties-capplet"/>
|
||||
<contains backend="mouse-properties-capplet"/>
|
||||
<contains backend="screensaver-properties-capplet"/>
|
||||
<contains backend="session-properties-capplet"/>
|
||||
<contains backend="wm-properties"/>
|
||||
</location>
|
||||
@@ -1,95 +0,0 @@
|
||||
Changes to the Helix Configuration Manager
|
||||
Copyright (C) 2000 Ximian, Inc.
|
||||
Written by Bradford Hovinen <hovinen@ximian.com>
|
||||
|
||||
As it stands, capplets and Ximian Setup Tools are both run as separate
|
||||
processes through the exec() facility. It is planned that the capplets
|
||||
shall become Bonobo controls in the future, once the OAF/gnorba
|
||||
compatibility problems are worked out. This changes the design of the
|
||||
configuration system considerably, and several things should be done
|
||||
to take full advantage of these changes.
|
||||
|
||||
1. Capplets become Bonobo controls
|
||||
|
||||
It stands to reason that the front ends for Ximian Setup Tools should
|
||||
become Bonobo controls at the same time as capplets. They can each
|
||||
implement the same interface (say, Bonobo::Capplet) with methods
|
||||
getXML(), setXML(), ok(), cancel(), and init() and hence look the same
|
||||
to the shell. This means that the front ends for the Ximian Setup Tools
|
||||
run as the same user as XCM and respond in the same way as capplets do
|
||||
to requests to embed them in the XCM shell window. This is essential
|
||||
for a consistent user interface that will not result in end-user
|
||||
confusion [1]. XCM itself may then export an interface that includes
|
||||
the method runBackend(), to which the frontend supplies a stream of
|
||||
XML that XCM passes through the root manager to the backend via a
|
||||
standard pipe [2]. The backend is then responsible for running the
|
||||
program that archives the XML -- there is no other way to place that
|
||||
XML in a central, system-wide repository. I suggest, therefore, that
|
||||
we modify the design of the current system to make that change, so
|
||||
that we do not have to undo existing work later.
|
||||
|
||||
2. Backends get CORBA interfaces through Perl/ORBit
|
||||
|
||||
At this point, there must be a way for the root manager to forward
|
||||
CORBA sockets to the user securely. This could be done by modifying
|
||||
ORBit so as to give the running program very precise control over the
|
||||
nature of the socket. Access could be granted specifically to the user
|
||||
running the root manager by placing the socket in a directory owned by
|
||||
that user with permissions no more lax than 0700. When the CORBA
|
||||
interfaces are created, applications will be able to make use of it to
|
||||
make system-wide changes as necessary (say, to add a new user during
|
||||
the installation of a piece of software). This means that the
|
||||
traditional rollback facilities must be extended to allow users to
|
||||
roll back changes made by applications. In addition, the application
|
||||
must treat the backend as a black box -- it should never be expected
|
||||
to do anything unusual to support rollback, since buggy or
|
||||
poorly-written applications would otherwise cause trouble for
|
||||
unsuspecting users.
|
||||
|
||||
At this point I suggest that each backend export two interfaces: one
|
||||
that is universal to all backends and one that is specific to that
|
||||
particular tool. The former may include the methods getXML(),
|
||||
setXML(), and commit(). When changes are made through the
|
||||
tool-specific interface, the tool decides whether or not to apply
|
||||
those changes immediately or to queue them up until a commit() is
|
||||
invoked. If changes are made through the backend's CORBA interface and
|
||||
it is deactivated before a commit(), the backend must roll back those
|
||||
changes under the assumption that they are not intended to be
|
||||
permanent.
|
||||
|
||||
Of course, this makes implementation of the cancel() interface on the
|
||||
frontends very easy -- simply deactivate the backend without
|
||||
commit()ing. ok() can be implemented by flushing any remaining
|
||||
changes, calling commit(), and then deactivating the backend. The
|
||||
frontend can and should use the CORBA interface to invoke changes
|
||||
whenever they are made, as long as it makes sense. It is then the
|
||||
backend that sets the policy of whether or not the updates are live,
|
||||
as described above. The frontend must still be able to read XML,
|
||||
though, since it is through that that it will get an initial
|
||||
description of the setup with which to fill in the dialog. In
|
||||
addition, since the frontend may be invoked to make changes to an
|
||||
inactive location, it should be able to write out an XML description
|
||||
of the dialog's contents so that those changes may be archived rather
|
||||
than applied immediately.
|
||||
|
||||
Notes
|
||||
|
||||
[1] A visual cue that signals to the user that he is running a
|
||||
system-wide configuration tool rather than a personal one would be
|
||||
advantageous. Such could take the form of an icon on the dialog, a
|
||||
layout or formatting convention for the dialog proper, or some sort of
|
||||
coloring convention of some of the controls. However, simply having
|
||||
the tool run with root's Gtk+ theme and ignoring the embedding
|
||||
preference, as would be the case if we do not Bonobize the HST
|
||||
frontends, is inconsistent as many users will leave their themes as
|
||||
the default and elect not to embed capplets -- eliminating all visual
|
||||
cues. In addition, it is not particularly lucid and many users will
|
||||
merely be confused by the inconsistent interface. One may imagine many
|
||||
users filing bug reports in the belief that the behavior is
|
||||
erroneous. Hence, that solution is insufficient.
|
||||
|
||||
[2] There must then be a method of multiplexing I/O throught the root
|
||||
manager, as there may be multiple backends running concurrently. A
|
||||
simple protocol could be implemented to do this, or a named pipe could
|
||||
be created if done very carefully as to ensure a high degree of
|
||||
security.
|
||||
@@ -1,364 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* location-list.c
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@ximian.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "location-list.h"
|
||||
|
||||
typedef struct _pair_t pair_t;
|
||||
|
||||
struct _pair_t
|
||||
{
|
||||
gpointer a, b;
|
||||
};
|
||||
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_USER_ARCHIVE,
|
||||
ARG_GLOBAL_ARCHIVE,
|
||||
ARG_SEPARATE_LOCATIONS
|
||||
};
|
||||
|
||||
struct _LocationListPrivate
|
||||
{
|
||||
gchar *selected_location_id;
|
||||
Location *selected_location;
|
||||
|
||||
gboolean separate_locations;
|
||||
Archive *user_archive;
|
||||
Archive *global_archive;
|
||||
};
|
||||
|
||||
static GtkCTreeClass *parent_class;
|
||||
|
||||
static void location_list_init (LocationList *location_list);
|
||||
static void location_list_class_init (LocationListClass *class);
|
||||
|
||||
static void location_list_set_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
static void location_list_get_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
|
||||
static void select_row_cb (LocationList *list,
|
||||
GList *node, gint column);
|
||||
|
||||
static void location_list_finalize (GtkObject *object);
|
||||
|
||||
static gint populate_locations_cb (Archive *archive,
|
||||
Location *location,
|
||||
pair_t *data);
|
||||
static void populate_locations_list (LocationList *list,
|
||||
gboolean do_global);
|
||||
|
||||
guint
|
||||
location_list_get_type (void)
|
||||
{
|
||||
static guint location_list_type = 0;
|
||||
|
||||
if (!location_list_type) {
|
||||
GtkTypeInfo location_list_info = {
|
||||
"LocationList",
|
||||
sizeof (LocationList),
|
||||
sizeof (LocationListClass),
|
||||
(GtkClassInitFunc) location_list_class_init,
|
||||
(GtkObjectInitFunc) location_list_init,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL
|
||||
};
|
||||
|
||||
location_list_type =
|
||||
gtk_type_unique (gtk_ctree_get_type (),
|
||||
&location_list_info);
|
||||
}
|
||||
|
||||
return location_list_type;
|
||||
}
|
||||
|
||||
static void
|
||||
location_list_init (LocationList *location_list)
|
||||
{
|
||||
static char *titles = { "Location" };
|
||||
|
||||
gtk_ctree_construct (GTK_CTREE (location_list),
|
||||
1, 0, &titles);
|
||||
|
||||
gtk_clist_column_titles_hide (GTK_CLIST (location_list));
|
||||
|
||||
location_list->p = g_new0 (LocationListPrivate, 1);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (location_list),
|
||||
"tree-select-row", GTK_SIGNAL_FUNC (select_row_cb),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
location_list_class_init (LocationListClass *class)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
|
||||
gtk_object_add_arg_type ("LocationList::user-archive",
|
||||
GTK_TYPE_POINTER,
|
||||
GTK_ARG_READWRITE,
|
||||
ARG_USER_ARCHIVE);
|
||||
|
||||
gtk_object_add_arg_type ("LocationList::global-archive",
|
||||
GTK_TYPE_POINTER,
|
||||
GTK_ARG_READWRITE,
|
||||
ARG_GLOBAL_ARCHIVE);
|
||||
|
||||
gtk_object_add_arg_type ("LocationList::separate-locations",
|
||||
GTK_TYPE_POINTER,
|
||||
GTK_ARG_READWRITE,
|
||||
ARG_SEPARATE_LOCATIONS);
|
||||
|
||||
object_class = GTK_OBJECT_CLASS (class);
|
||||
object_class->finalize = location_list_finalize;
|
||||
object_class->set_arg = location_list_set_arg;
|
||||
object_class->get_arg = location_list_get_arg;
|
||||
|
||||
parent_class = GTK_CTREE_CLASS
|
||||
(gtk_type_class (gtk_ctree_get_type ()));
|
||||
}
|
||||
|
||||
static void
|
||||
location_list_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
LocationList *location_list;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_LOCATION_LIST (object));
|
||||
|
||||
location_list = LOCATION_LIST (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_USER_ARCHIVE:
|
||||
g_return_if_fail (GTK_VALUE_POINTER (*arg) == NULL ||
|
||||
IS_ARCHIVE (GTK_VALUE_POINTER (*arg)));
|
||||
|
||||
if (GTK_VALUE_POINTER (*arg) == NULL) return;
|
||||
|
||||
location_list->p->user_archive =
|
||||
ARCHIVE (GTK_VALUE_POINTER (*arg));
|
||||
|
||||
gtk_object_ref (GTK_OBJECT (location_list->p->user_archive));
|
||||
populate_locations_list (location_list, FALSE);
|
||||
|
||||
break;
|
||||
|
||||
case ARG_GLOBAL_ARCHIVE:
|
||||
g_return_if_fail (GTK_VALUE_POINTER (*arg) == NULL ||
|
||||
IS_ARCHIVE (GTK_VALUE_POINTER (*arg)));
|
||||
|
||||
if (GTK_VALUE_POINTER (*arg) == NULL) return;
|
||||
|
||||
location_list->p->global_archive =
|
||||
ARCHIVE (GTK_VALUE_POINTER (*arg));
|
||||
|
||||
gtk_object_ref (GTK_OBJECT (location_list->p->global_archive));
|
||||
populate_locations_list (location_list, TRUE);
|
||||
|
||||
break;
|
||||
|
||||
case ARG_SEPARATE_LOCATIONS:
|
||||
location_list->p->separate_locations =
|
||||
GTK_VALUE_INT (*arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Bad argument set");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
location_list_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
LocationList *location_list;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_LOCATION_LIST (object));
|
||||
|
||||
location_list = LOCATION_LIST (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_USER_ARCHIVE:
|
||||
GTK_VALUE_POINTER (*arg) = location_list->p->user_archive;
|
||||
break;
|
||||
|
||||
case ARG_GLOBAL_ARCHIVE:
|
||||
GTK_VALUE_POINTER (*arg) = location_list->p->global_archive;
|
||||
break;
|
||||
|
||||
case ARG_SEPARATE_LOCATIONS:
|
||||
GTK_VALUE_INT (*arg) = location_list->p->separate_locations;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Bad argument get");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
location_list_finalize (GtkObject *object)
|
||||
{
|
||||
LocationList *location_list;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_LOCATION_LIST (object));
|
||||
|
||||
location_list = LOCATION_LIST (object);
|
||||
|
||||
if (location_list->p->user_archive != NULL)
|
||||
gtk_object_unref
|
||||
(GTK_OBJECT (location_list->p->user_archive));
|
||||
|
||||
if (location_list->p->global_archive != NULL)
|
||||
gtk_object_unref
|
||||
(GTK_OBJECT (location_list->p->global_archive));
|
||||
|
||||
g_free (location_list->p);
|
||||
|
||||
GTK_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
location_list_new (gboolean sep_locations, Archive *user_archive,
|
||||
Archive *global_archive)
|
||||
{
|
||||
return gtk_widget_new (location_list_get_type (),
|
||||
"separate-locations", sep_locations,
|
||||
"user-archive", user_archive,
|
||||
"global-archive", global_archive,
|
||||
NULL);
|
||||
}
|
||||
|
||||
gchar *
|
||||
location_list_get_selected_location_id (LocationList *list)
|
||||
{
|
||||
g_return_val_if_fail (list != NULL, NULL);
|
||||
g_return_val_if_fail (IS_LOCATION_LIST (list), NULL);
|
||||
|
||||
return list->p->selected_location_id;
|
||||
}
|
||||
|
||||
Location *
|
||||
location_list_get_selected_location (LocationList *list)
|
||||
{
|
||||
g_return_val_if_fail (list != NULL, NULL);
|
||||
g_return_val_if_fail (IS_LOCATION_LIST (list), NULL);
|
||||
|
||||
return list->p->selected_location;
|
||||
}
|
||||
|
||||
void
|
||||
location_list_reread (LocationList *list)
|
||||
{
|
||||
g_return_if_fail (list != NULL);
|
||||
g_return_if_fail (IS_LOCATION_LIST (list));
|
||||
|
||||
gtk_clist_freeze (GTK_CLIST (list));
|
||||
gtk_clist_clear (GTK_CLIST (list));
|
||||
|
||||
if (list->p->global_archive)
|
||||
populate_locations_list (list, TRUE);
|
||||
|
||||
if (list->p->user_archive)
|
||||
populate_locations_list (list, FALSE);
|
||||
|
||||
gtk_clist_thaw (GTK_CLIST (list));
|
||||
}
|
||||
|
||||
static void
|
||||
select_row_cb (LocationList *list, GList *node, gint column)
|
||||
{
|
||||
GtkCTreeRow *row;
|
||||
|
||||
g_return_if_fail (list != NULL);
|
||||
g_return_if_fail (IS_LOCATION_LIST (list));
|
||||
|
||||
row = GTK_CTREE_ROW (node);
|
||||
list->p->selected_location = row->row.data;
|
||||
list->p->selected_location_id =
|
||||
GTK_CELL_PIXTEXT (row->row.cell[0])->text;
|
||||
}
|
||||
|
||||
static gint
|
||||
populate_locations_cb (Archive *archive, Location *location, pair_t *data)
|
||||
{
|
||||
pair_t new_pair;
|
||||
char *label;
|
||||
|
||||
label = g_strdup (location_get_label (location));
|
||||
|
||||
new_pair.b = gtk_ctree_insert_node (GTK_CTREE (data->a),
|
||||
(GtkCTreeNode *) data->b, NULL,
|
||||
&label, GNOME_PAD_SMALL, NULL,
|
||||
NULL, NULL, NULL, FALSE, TRUE);
|
||||
gtk_ctree_node_set_row_data (GTK_CTREE (data->a),
|
||||
(GtkCTreeNode *) new_pair.b,
|
||||
location);
|
||||
|
||||
new_pair.a = data->a;
|
||||
|
||||
archive_foreach_child_location (archive,
|
||||
(LocationCB) populate_locations_cb,
|
||||
location, &new_pair);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
populate_locations_list (LocationList *list, gboolean do_global)
|
||||
{
|
||||
pair_t pair;
|
||||
Archive *archive;
|
||||
char *label;
|
||||
|
||||
if (do_global) {
|
||||
archive = list->p->global_archive;
|
||||
label = _("Global locations");
|
||||
} else {
|
||||
archive = list->p->user_archive;
|
||||
label = _("User locations");
|
||||
}
|
||||
|
||||
pair.a = list;
|
||||
|
||||
if (list->p->separate_locations)
|
||||
pair.b = gtk_ctree_insert_node (GTK_CTREE (list),
|
||||
NULL, NULL, &label,
|
||||
GNOME_PAD_SMALL, NULL,
|
||||
NULL, NULL, NULL, FALSE,
|
||||
TRUE);
|
||||
else
|
||||
pair.b = NULL;
|
||||
|
||||
archive_foreach_child_location (archive,
|
||||
(LocationCB) populate_locations_cb,
|
||||
NULL, &pair);
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* location-list.h
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@ximian.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __LOCATION_LIST_H
|
||||
#define __LOCATION_LIST_H
|
||||
|
||||
#include <gnome.h>
|
||||
|
||||
#include "archive.h"
|
||||
#include "location.h"
|
||||
#include "config-manager-dialog.h"
|
||||
|
||||
BEGIN_GNOME_DECLS
|
||||
|
||||
#define LOCATION_LIST(obj) GTK_CHECK_CAST (obj, location_list_get_type (), LocationList)
|
||||
#define LOCATION_LIST_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, location_list_get_type (), LocationListClass)
|
||||
#define IS_LOCATION_LIST(obj) GTK_CHECK_TYPE (obj, location_list_get_type ())
|
||||
|
||||
typedef struct _LocationList LocationList;
|
||||
typedef struct _LocationListClass LocationListClass;
|
||||
typedef struct _LocationListPrivate LocationListPrivate;
|
||||
|
||||
struct _LocationList
|
||||
{
|
||||
GtkCTree parent;
|
||||
|
||||
LocationListPrivate *p;
|
||||
};
|
||||
|
||||
struct _LocationListClass
|
||||
{
|
||||
GtkCTreeClass gtk_ctree_class;
|
||||
};
|
||||
|
||||
guint location_list_get_type (void);
|
||||
|
||||
GtkWidget *location_list_new (gboolean sep_locations,
|
||||
Archive *user_archive,
|
||||
Archive *global_archive);
|
||||
|
||||
gchar *location_list_get_selected_location_id (LocationList *list);
|
||||
Location *location_list_get_selected_location (LocationList *list);
|
||||
|
||||
void location_list_reread (LocationList *list);
|
||||
|
||||
END_GNOME_DECLS
|
||||
|
||||
#endif /* __LOCATION_LIST_H */
|
||||
1291
archiver/location.c
1291
archiver/location.c
File diff suppressed because it is too large
Load Diff
@@ -1,117 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* location.h
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen (hovinen@ximian.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __LOCATION_H
|
||||
#define __LOCATION_H
|
||||
|
||||
#include <gnome.h>
|
||||
#include <tree.h>
|
||||
|
||||
#include "config-log.h"
|
||||
|
||||
#define LOCATION(obj) GTK_CHECK_CAST (obj, location_get_type (), Location)
|
||||
#define LOCATION_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, location_get_type (), LocationClass)
|
||||
#define IS_LOCATION(obj) GTK_CHECK_TYPE (obj, location_get_type ())
|
||||
|
||||
typedef struct _LocationClass LocationClass;
|
||||
typedef struct _LocationPrivate LocationPrivate;
|
||||
typedef struct _Archive Archive;
|
||||
|
||||
typedef int (*LocationBackendCB) (Location *, gchar *, gpointer);
|
||||
|
||||
struct _Location
|
||||
{
|
||||
GtkObject object;
|
||||
|
||||
LocationPrivate *p;
|
||||
};
|
||||
|
||||
struct _LocationClass
|
||||
{
|
||||
GtkObjectClass parent;
|
||||
};
|
||||
|
||||
guint location_get_type (void);
|
||||
|
||||
GtkObject *location_new (Archive *archive,
|
||||
const gchar *locid,
|
||||
Location *inherits);
|
||||
GtkObject *location_open (Archive *archive,
|
||||
const gchar *locid);
|
||||
|
||||
void location_close (Location *location);
|
||||
void location_delete (Location *location);
|
||||
|
||||
void location_store (Location *location,
|
||||
gchar *backend_id,
|
||||
FILE *input);
|
||||
void location_store_xml (Location *location,
|
||||
gchar *backend_id,
|
||||
xmlDocPtr xml_doc);
|
||||
|
||||
void location_rollback_backend_to (Location *location,
|
||||
struct tm *date,
|
||||
gchar *backend_id,
|
||||
gboolean parent_chain);
|
||||
void location_rollback_backends_to (Location *location,
|
||||
struct tm *date,
|
||||
GList *backends,
|
||||
gboolean parent_chain);
|
||||
void location_rollback_all_to (Location *location,
|
||||
struct tm *date,
|
||||
gboolean parent_chain);
|
||||
|
||||
void location_rollback_backend_by (Location *location,
|
||||
guint steps,
|
||||
gchar *backend_id,
|
||||
gboolean parent_chain);
|
||||
|
||||
void location_rollback_id (Location *location,
|
||||
gint id);
|
||||
|
||||
void location_dump_rollback_data (Location *location,
|
||||
struct tm *date,
|
||||
guint steps,
|
||||
gchar *backend_id,
|
||||
gboolean parent_chain,
|
||||
FILE *output);
|
||||
|
||||
gboolean location_contains (Location *location, gchar *backend_id);
|
||||
gint location_add_backend (Location *location, gchar *backend_id);
|
||||
void location_remove_backend (Location *location, gchar *backend_id);
|
||||
|
||||
void location_foreach_backend (Location *location,
|
||||
LocationBackendCB callback,
|
||||
gpointer data);
|
||||
|
||||
GList *location_find_path_from_common_parent (Location *location,
|
||||
Location *location2);
|
||||
|
||||
Location *location_get_parent (Location *location);
|
||||
const gchar *location_get_path (Location *location);
|
||||
const gchar *location_get_label (Location *location);
|
||||
const gchar *location_get_id (Location *location);
|
||||
|
||||
void location_set_id (Location *location, const gchar *locid);
|
||||
|
||||
#endif /* __LOCATION */
|
||||
316
archiver/main.c
316
archiver/main.c
@@ -1,316 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* main.c
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen (hovinen@ximian.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/file.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <gnome.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "archive.h"
|
||||
|
||||
/* Variables resulting from command line parsing */
|
||||
|
||||
static gboolean store;
|
||||
static gboolean rollback;
|
||||
static gboolean change_location;
|
||||
static gboolean rename_location;
|
||||
static gboolean push_config;
|
||||
|
||||
static gboolean add_location;
|
||||
static gboolean remove_location;
|
||||
static gboolean add_backend;
|
||||
static gboolean remove_backend;
|
||||
|
||||
static gboolean global;
|
||||
static const gchar *location_id;
|
||||
|
||||
static gchar *backend_id;
|
||||
|
||||
static gchar *date_str;
|
||||
static gboolean all;
|
||||
static gchar *revision_id;
|
||||
static gboolean last;
|
||||
static guint steps;
|
||||
static gboolean show;
|
||||
|
||||
static gchar *parent_str;
|
||||
static gchar *new_name;
|
||||
|
||||
static gboolean master;
|
||||
|
||||
static struct poptOption archiver_operations[] = {
|
||||
{"store", 's', POPT_ARG_NONE, &store, 0,
|
||||
N_("Store XML data in the archive")},
|
||||
{"rollback", 'r', POPT_ARG_NONE, &rollback, 0,
|
||||
N_("Roll back the configuration to a given point")},
|
||||
{"change-location", 'c', POPT_ARG_NONE, &change_location, 0,
|
||||
N_("Change the location profile to the given one")},
|
||||
{"push-config", 'p', POPT_ARG_NONE, &push_config, 0,
|
||||
N_("Push configuration data out to client machines (UNIMPLEMENTED)")},
|
||||
{"rename-location", '\0', POPT_ARG_NONE, &rename_location, 0,
|
||||
N_("Rename a location to a new name")},
|
||||
{"add-location", '\0', POPT_ARG_NONE, &add_location, 0,
|
||||
N_("Add a new location to the archive")},
|
||||
{"remove-location", '\0', POPT_ARG_NONE, &remove_location, 0,
|
||||
N_("Remove a location from the archive")},
|
||||
{"add-backend", '\0', POPT_ARG_NONE, &add_backend, 0,
|
||||
N_("Add a given backend to the given location")},
|
||||
{"remove-backend", '\0', POPT_ARG_NONE, &remove_backend, 0,
|
||||
N_("Remove the given backend from the given location")},
|
||||
{NULL, '\0', 0, NULL, 0}
|
||||
};
|
||||
|
||||
static struct poptOption global_options[] = {
|
||||
{"global", 'g', POPT_ARG_NONE, &global, 0,
|
||||
N_("Use the global repository")},
|
||||
{"location", 'l', POPT_ARG_STRING, &location_id, 0,
|
||||
N_("Identifier of location profile on which to operate"),
|
||||
N_("LOCATION")},
|
||||
{"backend", 'b', POPT_ARG_STRING, &backend_id, 0,
|
||||
N_("Backend being used for this operation"), N_("BACKEND_ID")},
|
||||
{NULL, '\0', 0, NULL, 0}
|
||||
};
|
||||
|
||||
static struct poptOption rollback_options[] = {
|
||||
{"date", 'd', POPT_ARG_STRING, &date_str, 0,
|
||||
N_("Date to which to roll back"), N_("DATE")},
|
||||
{"all", 'a', POPT_ARG_NONE, &all, 0,
|
||||
N_("Roll back all configuration items")},
|
||||
{"revision-id", 'i', POPT_ARG_INT, &revision_id, 0,
|
||||
N_("Roll back to the revision REVISION_ID"), N_("REVISION_ID")},
|
||||
{"last", 't', POPT_ARG_NONE, &last, 0,
|
||||
N_("Roll back to the last known revision")},
|
||||
{"steps", '\0', POPT_ARG_INT, &steps, 0,
|
||||
N_("Roll back by STEPS revisions"), N_("STEPS")},
|
||||
{"show", 'h', POPT_ARG_NONE, &show, 0,
|
||||
N_("Don't run the backend, just dump the output")},
|
||||
{NULL, '\0', 0, NULL, 0}
|
||||
};
|
||||
|
||||
static struct poptOption add_rename_location_options[] = {
|
||||
{"parent", '\0', POPT_ARG_STRING, &parent_str, 0,
|
||||
N_("Parent location for the new location"), N_("PARENT")},
|
||||
{"new-name", '\0', POPT_ARG_STRING, &new_name, 0,
|
||||
N_("New name to assign to the location"), N_("NEW_NAME")},
|
||||
{NULL, '\0', 0, NULL, 0}
|
||||
};
|
||||
|
||||
static struct poptOption add_remove_backend_options[] = {
|
||||
{"master", '\0', POPT_ARG_NONE, &master, 0,
|
||||
N_("Add/remove this backend to/from the master backend list")},
|
||||
{NULL, '\0', 0, NULL, 0}
|
||||
};
|
||||
|
||||
static void
|
||||
do_store (Location *location)
|
||||
{
|
||||
if (!backend_id) {
|
||||
g_message ("No backend specified");
|
||||
return;
|
||||
}
|
||||
|
||||
location_store (location, backend_id, stdin);
|
||||
}
|
||||
|
||||
static void
|
||||
do_rollback (Location *location)
|
||||
{
|
||||
gint id;
|
||||
struct tm *date = NULL;
|
||||
|
||||
if (date_str)
|
||||
date = parse_date (date_str);
|
||||
else if (last || steps > 0)
|
||||
date = NULL;
|
||||
else if (!revision_id) {
|
||||
g_message ("No date specified");
|
||||
return;
|
||||
}
|
||||
|
||||
if (all) {
|
||||
location_rollback_all_to (location, date, TRUE);
|
||||
}
|
||||
else if (backend_id && (date || last)) {
|
||||
/* FIXME: Need to support specifying multiple backends */
|
||||
if (show)
|
||||
location_dump_rollback_data (location, date, 0,
|
||||
backend_id, TRUE, stdout);
|
||||
else
|
||||
location_rollback_backend_to (location, date,
|
||||
backend_id, TRUE);
|
||||
}
|
||||
else if (backend_id && steps) {
|
||||
if (show)
|
||||
location_dump_rollback_data (location, NULL, steps,
|
||||
backend_id, TRUE, stdout);
|
||||
else
|
||||
location_rollback_backend_by (location, steps,
|
||||
backend_id, TRUE);
|
||||
}
|
||||
else if (revision_id) {
|
||||
sscanf (revision_id, "%x", &id);
|
||||
if (id >= 0)
|
||||
location_rollback_id (location, id);
|
||||
else
|
||||
g_message ("Bad id specified");
|
||||
} else {
|
||||
g_message ("No backend specified");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_change_location (Archive *archive, Location *location)
|
||||
{
|
||||
archive_set_current_location (archive, location);
|
||||
}
|
||||
|
||||
static void
|
||||
do_rename_location (Archive *archive, Location *location)
|
||||
{
|
||||
gboolean is_current;
|
||||
|
||||
if (new_name == NULL) {
|
||||
g_message ("You did not specify a new name. Try --help");
|
||||
} else {
|
||||
if (!strcmp (location_get_id (location),
|
||||
archive_get_current_location_id (archive)))
|
||||
is_current = TRUE;
|
||||
else
|
||||
is_current = FALSE;
|
||||
|
||||
location_set_id (location, new_name);
|
||||
|
||||
if (is_current)
|
||||
archive_set_current_location_id (archive, new_name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_add_location (Archive *archive)
|
||||
{
|
||||
GtkObject *location;
|
||||
Location *parent_location = NULL;
|
||||
|
||||
if (parent_str != NULL)
|
||||
parent_location = archive_get_location (archive, parent_str);
|
||||
location = location_new (archive, location_id, parent_location);
|
||||
}
|
||||
|
||||
static void
|
||||
do_remove_location (Location *location)
|
||||
{
|
||||
location_delete (location);
|
||||
}
|
||||
|
||||
static void
|
||||
do_add_backend (Location *location)
|
||||
{
|
||||
location_add_backend (location, backend_id);
|
||||
}
|
||||
|
||||
static void
|
||||
do_remove_backend (Location *location)
|
||||
{
|
||||
location_remove_backend (location, backend_id);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
Archive *archive;
|
||||
Location *location = NULL;
|
||||
|
||||
bindtextdomain (PACKAGE, GNOMELOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
gnomelib_register_popt_table (global_options,
|
||||
_("Global archiver options"));
|
||||
gnomelib_register_popt_table (archiver_operations,
|
||||
_("Archiver commands"));
|
||||
gnomelib_register_popt_table (rollback_options,
|
||||
_("Options for rolling back"));
|
||||
gnomelib_register_popt_table (add_rename_location_options,
|
||||
_("Options for adding or renaming " \
|
||||
"locations"));
|
||||
gnomelib_register_popt_table (add_remove_backend_options,
|
||||
_("Options for adding and removing " \
|
||||
"backends"));
|
||||
|
||||
gtk_type_init ();
|
||||
gnomelib_init ("archiver", VERSION);
|
||||
gnomelib_parse_args (argc, argv, 0);
|
||||
|
||||
archive = ARCHIVE (archive_load (global));
|
||||
|
||||
if (archive == NULL)
|
||||
g_error ("Could not open archive");
|
||||
|
||||
if (location_id == NULL)
|
||||
location_id = archive_get_current_location_id (archive);
|
||||
|
||||
if (!add_location) {
|
||||
location = archive_get_location (archive, location_id);
|
||||
|
||||
if (location == NULL) {
|
||||
if (strcmp (location_id, "default")) {
|
||||
g_message ("Could not open location");
|
||||
return -1;
|
||||
} else {
|
||||
location = LOCATION
|
||||
(location_new (archive, location_id,
|
||||
NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (store)
|
||||
do_store (location);
|
||||
else if (rollback)
|
||||
do_rollback (location);
|
||||
else if (change_location)
|
||||
do_change_location (archive, location);
|
||||
else if (rename_location)
|
||||
do_rename_location (archive, location);
|
||||
else if (add_location)
|
||||
do_add_location (archive);
|
||||
else if (remove_location)
|
||||
do_remove_location (location);
|
||||
else if (add_backend)
|
||||
do_add_backend (location);
|
||||
else if (remove_backend)
|
||||
do_remove_backend (location);
|
||||
|
||||
archive_close (archive);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,647 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<GTK-Interface>
|
||||
|
||||
<project>
|
||||
<name>Rollback-location-management</name>
|
||||
<program_name>rollback-location-management</program_name>
|
||||
<directory></directory>
|
||||
<source_directory>src</source_directory>
|
||||
<pixmaps_directory>pixmaps</pixmaps_directory>
|
||||
<language>C</language>
|
||||
<gnome_support>True</gnome_support>
|
||||
<gettext_support>True</gettext_support>
|
||||
</project>
|
||||
|
||||
<widget>
|
||||
<class>GnomeDialog</class>
|
||||
<name>rollback_location_dialog</name>
|
||||
<type>GTK_WINDOW_TOPLEVEL</type>
|
||||
<position>GTK_WIN_POS_NONE</position>
|
||||
<modal>False</modal>
|
||||
<allow_shrink>False</allow_shrink>
|
||||
<allow_grow>True</allow_grow>
|
||||
<auto_shrink>False</auto_shrink>
|
||||
<auto_close>False</auto_close>
|
||||
<hide_on_close>False</hide_on_close>
|
||||
|
||||
<widget>
|
||||
<class>GtkVBox</class>
|
||||
<child_name>GnomeDialog:vbox</child_name>
|
||||
<name>dialog-vbox1</name>
|
||||
<homogeneous>False</homogeneous>
|
||||
<spacing>8</spacing>
|
||||
<child>
|
||||
<padding>4</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkHButtonBox</class>
|
||||
<child_name>GnomeDialog:action_area</child_name>
|
||||
<name>dialog-action_area1</name>
|
||||
<layout_style>GTK_BUTTONBOX_END</layout_style>
|
||||
<spacing>8</spacing>
|
||||
<child_min_width>85</child_min_width>
|
||||
<child_min_height>27</child_min_height>
|
||||
<child_ipad_x>7</child_ipad_x>
|
||||
<child_ipad_y>0</child_ipad_y>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>True</fill>
|
||||
<pack>GTK_PACK_END</pack>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkButton</class>
|
||||
<name>button1</name>
|
||||
<can_default>True</can_default>
|
||||
<can_focus>True</can_focus>
|
||||
<stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkButton</class>
|
||||
<name>button2</name>
|
||||
<can_default>True</can_default>
|
||||
<can_focus>True</can_focus>
|
||||
<stock_button>GNOME_STOCK_BUTTON_APPLY</stock_button>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkButton</class>
|
||||
<name>button3</name>
|
||||
<can_default>True</can_default>
|
||||
<can_focus>True</can_focus>
|
||||
<stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkNotebook</class>
|
||||
<name>config_dialog_data</name>
|
||||
<can_focus>True</can_focus>
|
||||
<show_tabs>True</show_tabs>
|
||||
<show_border>True</show_border>
|
||||
<tab_pos>GTK_POS_TOP</tab_pos>
|
||||
<scrollable>False</scrollable>
|
||||
<tab_hborder>2</tab_hborder>
|
||||
<tab_vborder>2</tab_vborder>
|
||||
<popup_enable>False</popup_enable>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkTable</class>
|
||||
<name>table1</name>
|
||||
<border_width>5</border_width>
|
||||
<rows>4</rows>
|
||||
<columns>2</columns>
|
||||
<homogeneous>False</homogeneous>
|
||||
<row_spacing>5</row_spacing>
|
||||
<column_spacing>5</column_spacing>
|
||||
|
||||
<widget>
|
||||
<class>GtkRadioButton</class>
|
||||
<name>rollback_all_toggle</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>toggled</name>
|
||||
<handler>rollback_all_toggled_cb</handler>
|
||||
<last_modification_time>Tue, 19 Dec 2000 20:58:48 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Restore all tools</label>
|
||||
<active>False</active>
|
||||
<draw_indicator>True</draw_indicator>
|
||||
<group>restore_type</group>
|
||||
<child>
|
||||
<left_attach>0</left_attach>
|
||||
<right_attach>2</right_attach>
|
||||
<top_attach>1</top_attach>
|
||||
<bottom_attach>2</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>False</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>True</xfill>
|
||||
<yfill>False</yfill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkButton</class>
|
||||
<name>button4</name>
|
||||
<can_focus>True</can_focus>
|
||||
<label>View Logs...</label>
|
||||
<relief>GTK_RELIEF_NORMAL</relief>
|
||||
<child>
|
||||
<left_attach>0</left_attach>
|
||||
<right_attach>1</right_attach>
|
||||
<top_attach>3</top_attach>
|
||||
<bottom_attach>4</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>False</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>True</xfill>
|
||||
<yfill>False</yfill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkButton</class>
|
||||
<name>button5</name>
|
||||
<can_focus>True</can_focus>
|
||||
<label>Advanced...</label>
|
||||
<relief>GTK_RELIEF_NORMAL</relief>
|
||||
<child>
|
||||
<left_attach>1</left_attach>
|
||||
<right_attach>2</right_attach>
|
||||
<top_attach>3</top_attach>
|
||||
<bottom_attach>4</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>False</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>True</xfill>
|
||||
<yfill>False</yfill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkHBox</class>
|
||||
<name>hbox2</name>
|
||||
<homogeneous>False</homogeneous>
|
||||
<spacing>0</spacing>
|
||||
<child>
|
||||
<left_attach>0</left_attach>
|
||||
<right_attach>2</right_attach>
|
||||
<top_attach>2</top_attach>
|
||||
<bottom_attach>3</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>False</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>True</xfill>
|
||||
<yfill>True</yfill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkRadioButton</class>
|
||||
<name>rollback_one_toggle</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>toggled</name>
|
||||
<handler>rollback_one_toggled_cb</handler>
|
||||
<last_modification_time>Tue, 19 Dec 2000 20:58:59 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Restore only</label>
|
||||
<active>False</active>
|
||||
<draw_indicator>True</draw_indicator>
|
||||
<group>restore_type</group>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkOptionMenu</class>
|
||||
<name>backend_select</name>
|
||||
<can_focus>True</can_focus>
|
||||
<items></items>
|
||||
<initial_choice>0</initial_choice>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkHBox</class>
|
||||
<name>hbox1</name>
|
||||
<homogeneous>False</homogeneous>
|
||||
<spacing>5</spacing>
|
||||
<child>
|
||||
<left_attach>0</left_attach>
|
||||
<right_attach>2</right_attach>
|
||||
<top_attach>0</top_attach>
|
||||
<bottom_attach>1</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>True</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>True</xfill>
|
||||
<yfill>True</yfill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label3</name>
|
||||
<label>Restore configuration from</label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0.5</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkSpinButton</class>
|
||||
<name>time_count</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>changed</name>
|
||||
<handler>time_count_changed_cb</handler>
|
||||
<last_modification_time>Tue, 19 Dec 2000 20:15:27 GMT</last_modification_time>
|
||||
</signal>
|
||||
<climb_rate>1</climb_rate>
|
||||
<digits>0</digits>
|
||||
<numeric>False</numeric>
|
||||
<update_policy>GTK_UPDATE_ALWAYS</update_policy>
|
||||
<snap>False</snap>
|
||||
<wrap>False</wrap>
|
||||
<value>1</value>
|
||||
<lower>0</lower>
|
||||
<upper>1000</upper>
|
||||
<step>1</step>
|
||||
<page>10</page>
|
||||
<page_size>10</page_size>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label4</name>
|
||||
<label>days ago</label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0.5</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<child_name>Notebook:tab</child_name>
|
||||
<name>label1</name>
|
||||
<label>Configuration Restoration</label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0.5</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkHBox</class>
|
||||
<name>location_tree_box</name>
|
||||
<border_width>5</border_width>
|
||||
<homogeneous>False</homogeneous>
|
||||
<spacing>5</spacing>
|
||||
|
||||
<widget>
|
||||
<class>GtkVBox</class>
|
||||
<name>vbox1</name>
|
||||
<homogeneous>False</homogeneous>
|
||||
<spacing>5</spacing>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>True</fill>
|
||||
<pack>GTK_PACK_END</pack>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkButton</class>
|
||||
<name>create_button</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>clicked</name>
|
||||
<handler>create_cb</handler>
|
||||
<last_modification_time>Wed, 20 Dec 2000 23:51:41 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Create...</label>
|
||||
<relief>GTK_RELIEF_NORMAL</relief>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkButton</class>
|
||||
<name>destroy_button</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>clicked</name>
|
||||
<handler>destroy_cb</handler>
|
||||
<last_modification_time>Wed, 20 Dec 2000 23:51:56 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Destroy...</label>
|
||||
<relief>GTK_RELIEF_NORMAL</relief>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkButton</class>
|
||||
<name>rename_button</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>clicked</name>
|
||||
<handler>rename_cb</handler>
|
||||
<last_modification_time>Wed, 20 Dec 2000 23:52:13 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Rename...</label>
|
||||
<relief>GTK_RELIEF_NORMAL</relief>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkHSeparator</class>
|
||||
<name>hseparator1</name>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkButton</class>
|
||||
<name>change_location_button</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>clicked</name>
|
||||
<handler>change_location_cb</handler>
|
||||
<last_modification_time>Wed, 20 Dec 2000 23:52:33 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Change to this Location</label>
|
||||
<relief>GTK_RELIEF_NORMAL</relief>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkButton</class>
|
||||
<name>edit_button</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>clicked</name>
|
||||
<handler>edit_location_cb</handler>
|
||||
<last_modification_time>Wed, 20 Dec 2000 23:52:51 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Edit this Location</label>
|
||||
<relief>GTK_RELIEF_NORMAL</relief>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkScrolledWindow</class>
|
||||
<name>location_tree_location</name>
|
||||
<hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy>
|
||||
<vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
|
||||
<hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
|
||||
<vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
<pack>GTK_PACK_END</pack>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>Placeholder</class>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<child_name>Notebook:tab</child_name>
|
||||
<name>label2</name>
|
||||
<label>Location Management</label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0.5</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GnomeDialog</class>
|
||||
<name>create_location_dialog</name>
|
||||
<type>GTK_WINDOW_TOPLEVEL</type>
|
||||
<position>GTK_WIN_POS_NONE</position>
|
||||
<modal>False</modal>
|
||||
<allow_shrink>False</allow_shrink>
|
||||
<allow_grow>False</allow_grow>
|
||||
<auto_shrink>False</auto_shrink>
|
||||
<auto_close>False</auto_close>
|
||||
<hide_on_close>False</hide_on_close>
|
||||
|
||||
<widget>
|
||||
<class>GtkVBox</class>
|
||||
<child_name>GnomeDialog:vbox</child_name>
|
||||
<name>dialog-vbox2</name>
|
||||
<homogeneous>False</homogeneous>
|
||||
<spacing>8</spacing>
|
||||
<child>
|
||||
<padding>4</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkHButtonBox</class>
|
||||
<child_name>GnomeDialog:action_area</child_name>
|
||||
<name>dialog-action_area2</name>
|
||||
<layout_style>GTK_BUTTONBOX_END</layout_style>
|
||||
<spacing>8</spacing>
|
||||
<child_min_width>85</child_min_width>
|
||||
<child_min_height>27</child_min_height>
|
||||
<child_ipad_x>7</child_ipad_x>
|
||||
<child_ipad_y>0</child_ipad_y>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>True</fill>
|
||||
<pack>GTK_PACK_END</pack>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkButton</class>
|
||||
<name>button11</name>
|
||||
<can_default>True</can_default>
|
||||
<can_focus>True</can_focus>
|
||||
<stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkButton</class>
|
||||
<name>button12</name>
|
||||
<can_default>True</can_default>
|
||||
<can_focus>True</can_focus>
|
||||
<stock_button>GNOME_STOCK_BUTTON_APPLY</stock_button>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkButton</class>
|
||||
<name>button13</name>
|
||||
<can_default>True</can_default>
|
||||
<can_focus>True</can_focus>
|
||||
<stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkVBox</class>
|
||||
<name>create_dialog_data</name>
|
||||
<homogeneous>False</homogeneous>
|
||||
<spacing>5</spacing>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkHBox</class>
|
||||
<name>hbox4</name>
|
||||
<homogeneous>False</homogeneous>
|
||||
<spacing>5</spacing>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label7</name>
|
||||
<label>Location name:</label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0.5</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkEntry</class>
|
||||
<name>location_name_entry</name>
|
||||
<can_focus>True</can_focus>
|
||||
<editable>True</editable>
|
||||
<text_visible>True</text_visible>
|
||||
<text_max_length>0</text_max_length>
|
||||
<text></text>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label8</name>
|
||||
<label>Parent Location:</label>
|
||||
<justify>GTK_JUSTIFY_LEFT</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkScrolledWindow</class>
|
||||
<name>location_list_location</name>
|
||||
<hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy>
|
||||
<vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
|
||||
<hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
|
||||
<vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>Placeholder</class>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
</GTK-Interface>
|
||||
@@ -1,163 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* rollback-widget.c
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@ximian.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "rollback-widget.h"
|
||||
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_SAMPLE
|
||||
};
|
||||
|
||||
struct _RollbackWidgetPrivate
|
||||
{
|
||||
/* Private data members */
|
||||
};
|
||||
|
||||
static GtkWidgetClass *parent_class;
|
||||
|
||||
static void rollback_widget_init (RollbackWidget *rollback_widget);
|
||||
static void rollback_widget_class_init (RollbackWidgetClass *class);
|
||||
|
||||
static void rollback_widget_set_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
static void rollback_widget_get_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
|
||||
static void rollback_widget_finalize (GtkObject *object);
|
||||
|
||||
guint
|
||||
rollback_widget_get_type (void)
|
||||
{
|
||||
static guint rollback_widget_type = 0;
|
||||
|
||||
if (!rollback_widget_type) {
|
||||
GtkTypeInfo rollback_widget_info = {
|
||||
"RollbackWidget",
|
||||
sizeof (RollbackWidget),
|
||||
sizeof (RollbackWidgetClass),
|
||||
(GtkClassInitFunc) rollback_widget_class_init,
|
||||
(GtkObjectInitFunc) rollback_widget_init,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL
|
||||
};
|
||||
|
||||
rollback_widget_type =
|
||||
gtk_type_unique (gtk_widget_get_type (),
|
||||
&rollback_widget_info);
|
||||
}
|
||||
|
||||
return rollback_widget_type;
|
||||
}
|
||||
|
||||
static void
|
||||
rollback_widget_init (RollbackWidget *rollback_widget)
|
||||
{
|
||||
rollback_widget->p = g_new0 (RollbackWidgetPrivate, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
rollback_widget_class_init (RollbackWidgetClass *class)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
|
||||
gtk_object_add_arg_type ("RollbackWidget::sample",
|
||||
GTK_TYPE_POINTER,
|
||||
GTK_ARG_READWRITE,
|
||||
ARG_SAMPLE);
|
||||
|
||||
object_class = GTK_OBJECT_CLASS (class);
|
||||
object_class->finalize = rollback_widget_finalize;
|
||||
object_class->set_arg = rollback_widget_set_arg;
|
||||
object_class->get_arg = rollback_widget_get_arg;
|
||||
|
||||
parent_class = GTK_WIDGET_CLASS
|
||||
(gtk_type_class (gtk_widget_get_type ()));
|
||||
}
|
||||
|
||||
static void
|
||||
rollback_widget_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
RollbackWidget *rollback_widget;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_ROLLBACK_WIDGET (object));
|
||||
|
||||
rollback_widget = ROLLBACK_WIDGET (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_SAMPLE:
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Bad argument set");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rollback_widget_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
RollbackWidget *rollback_widget;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_ROLLBACK_WIDGET (object));
|
||||
|
||||
rollback_widget = ROLLBACK_WIDGET (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_SAMPLE:
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Bad argument get");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rollback_widget_finalize (GtkObject *object)
|
||||
{
|
||||
RollbackWidget *rollback_widget;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_ROLLBACK_WIDGET (object));
|
||||
|
||||
rollback_widget = ROLLBACK_WIDGET (object);
|
||||
|
||||
g_free (rollback_widget->p);
|
||||
|
||||
GTK_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
GtkObject *
|
||||
rollback_widget_new (void)
|
||||
{
|
||||
return gtk_object_new (rollback_widget_get_type (),
|
||||
NULL);
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* rollback-widget.h
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@ximian.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ROLLBACK_WIDGET_H
|
||||
#define __ROLLBACK_WIDGET_H
|
||||
|
||||
#include <gnome.h>
|
||||
|
||||
BEGIN_GNOME_DECLS
|
||||
|
||||
#define ROLLBACK_WIDGET(obj) GTK_CHECK_CAST (obj, rollback_widget_get_type (), RollbackWidget)
|
||||
#define ROLLBACK_WIDGET_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, rollback_widget_get_type (), RollbackWidgetClass)
|
||||
#define IS_ROLLBACK_WIDGET(obj) GTK_CHECK_TYPE (obj, rollback_widget_get_type ())
|
||||
|
||||
typedef struct _RollbackWidget RollbackWidget;
|
||||
typedef struct _RollbackWidgetClass RollbackWidgetClass;
|
||||
typedef struct _RollbackWidgetPrivate RollbackWidgetPrivate;
|
||||
|
||||
struct _RollbackWidget
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
RollbackWidgetPrivate *p;
|
||||
};
|
||||
|
||||
struct _RollbackWidgetClass
|
||||
{
|
||||
GtkWidgetClass gtk_widget_class;
|
||||
};
|
||||
|
||||
guint rollback_widget_get_type (void);
|
||||
|
||||
GtkObject *rollback_widget_new (void);
|
||||
|
||||
END_GNOME_DECLS
|
||||
|
||||
#endif /* __ROLLBACK_WIDGET_H */
|
||||
@@ -1,97 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* util.c
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen (hovinen@ximian.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
/* Read a fixed-digit number from a string, advancing the string
|
||||
* pointer. Return TRUE if the extraction was successful, FALSE if
|
||||
* there was no number to extract or if the number was too short.
|
||||
*/
|
||||
|
||||
gboolean
|
||||
extract_number (char **str, int *number, int digits)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
if (!isdigit (**str)) return FALSE;
|
||||
if (digits > 63) digits = 63;
|
||||
|
||||
strncpy (buf, *str, digits);
|
||||
buf[digits] = '\0';
|
||||
*number = atoi (buf);
|
||||
if (strlen (buf) < digits) return FALSE;
|
||||
*str += digits;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct tm *
|
||||
parse_date (char *str)
|
||||
{
|
||||
struct tm *date;
|
||||
gboolean ok;
|
||||
gint value;
|
||||
|
||||
ok = extract_number (&str, &value, 4);
|
||||
if (!ok) return NULL;
|
||||
|
||||
date = g_new (struct tm, 1);
|
||||
date->tm_year = value - 1900;
|
||||
date->tm_mon = 11;
|
||||
date->tm_mday = 31;
|
||||
date->tm_hour = 23;
|
||||
date->tm_min = 59;
|
||||
date->tm_sec = 59;
|
||||
|
||||
if (extract_number (&str, &value, 2))
|
||||
date->tm_mon = value - 1;
|
||||
else
|
||||
return date;
|
||||
|
||||
if (extract_number (&str, &value, 2))
|
||||
date->tm_mday = value;
|
||||
else
|
||||
return date;
|
||||
|
||||
if (extract_number (&str, &value, 2))
|
||||
date->tm_hour = value;
|
||||
else
|
||||
return date;
|
||||
|
||||
if (extract_number (&str, &value, 2))
|
||||
date->tm_min = value;
|
||||
else
|
||||
return date;
|
||||
|
||||
if (extract_number (&str, &value, 2))
|
||||
date->tm_sec = value;
|
||||
|
||||
return date;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* util.h
|
||||
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen (hovinen@ximian.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_H
|
||||
#define __UTIL_H
|
||||
|
||||
#include <time.h>
|
||||
#include <glib.h>
|
||||
|
||||
gboolean extract_number (char **str, int *number, int digits);
|
||||
struct tm *parse_date (char *str);
|
||||
|
||||
#endif /* __UTIL_H */
|
||||
@@ -1,193 +0,0 @@
|
||||
Configuration rollback, location management, and cluster support
|
||||
Copyright (C) 2001 Ximian, Inc.
|
||||
Written by Bradford Hovinen <hovinen@ximian.com>
|
||||
|
||||
I. Basic architecture
|
||||
|
||||
A. Components
|
||||
|
||||
1. Ximian Configuration Manager
|
||||
|
||||
The GUI shell, here referred to as the Ximian Configuration Manager
|
||||
(XCM), acts as launching point for the capplets and Ximian Tools,
|
||||
and a control center for managing rollback, location management, and
|
||||
clustering. It launches other components and knows how to find
|
||||
archived configuration data for rollback. When rollback or a change of
|
||||
location is required, it invokes the required backends or capplets
|
||||
with the --set option and feeds the required XML to them.
|
||||
|
||||
2. Capplets
|
||||
|
||||
Capplets handle user configuration; they combine the front and back
|
||||
ends into one process. They will eventually run as Bonobo controls
|
||||
implementing the Bonobo::Capplet interface, but for now they are run
|
||||
as regular processes. They all support the --get and --set command
|
||||
line options (which will be methods in the Bonobo::Capplet
|
||||
interface). --get returns an XML description of the capplet's state
|
||||
for archival purposes and --set takes an XML description of the
|
||||
capplet's state and applies those settings to the desktop.
|
||||
|
||||
3. Ximian Setup Tools (XSTs)
|
||||
|
||||
These programs are for system-wide configuration and must run as root
|
||||
in order to apply changes. They may also run as a regular user in
|
||||
`read-only' mode. They have separate front- and backends, the former
|
||||
typically written in C and the latter normally written in Perl. This
|
||||
facilitates in-place modification of existing configuration files
|
||||
without the need for creating out own separate, incompatible way of
|
||||
configuring the system. The backends support the --get and --set
|
||||
arguments, analogous to the arguments in capplets mentioned above.
|
||||
|
||||
2. Root manager
|
||||
|
||||
The root manager process runs as root and is launched through
|
||||
gnome-su. It accepts on stdin a set of programs to launch, one per
|
||||
line, with command line arguments. XCM uses it to launch Ximian Setup
|
||||
Tools so that they run as root, without needing to ask the user for a
|
||||
password each time a tool is run. The root manager is run exactly once
|
||||
through console-helper the first time a tool that must be run as root
|
||||
is invoked. On subsequent occasions the command to start the tool is
|
||||
passed to the root manager through stdin.
|
||||
|
||||
3. The script do-changes
|
||||
|
||||
do-changes is responsible for archiving changes made to the system's
|
||||
configuration and passing them on to the backend, if appropriate. It
|
||||
accepts a stream of XML on stdin and stores this XML in the
|
||||
configuration archive directory. If a backend is specified on the
|
||||
command line, it also spawns the backend process with the --set option
|
||||
and feeds the XML to it through stdin.
|
||||
|
||||
II. Configuration process
|
||||
|
||||
When a user makes changes to either his own configuration or that of
|
||||
the system, those changes must be archived so that the system may be
|
||||
rolled back in the future. In the case of capplets, the capplet
|
||||
currently dumps an XML snapshot of its current state to the script
|
||||
do-changes when the user clicks `Ok'. do-changes then archives the
|
||||
state in ~/.gnome/config/<location>/<revision> where <location> is the
|
||||
name of the active location (cf. section IV) and <revision> is
|
||||
incremented after each change.
|
||||
|
||||
When the capplets are converted into Bonobo controls, the situation
|
||||
will be slightly different. XCM will be the recipient of the `Ok'
|
||||
signal, so it will invoke the OKClicked() method of the
|
||||
Bonobo::Capplet interface on the appropriate capplet. It will also
|
||||
invoke the GetXML() method of the same interface in order to retrieve
|
||||
an XML snapshot of the state and store that snapshot with
|
||||
do-changes. Hence, much of the action moves from the capplet to XCM.
|
||||
|
||||
In the case of Ximian Setup Tools, the frontend passes the XML through
|
||||
the do-changes script to the backend whenever the `Ok' button is
|
||||
clicked. It passes to do-changes the argument --backend <backend name>
|
||||
so that do-changes will also invoke the indicated backend and pass the
|
||||
XML to it.
|
||||
|
||||
III. Rollback process
|
||||
|
||||
From within the XCM, the user may elect to roll back either his
|
||||
personal configuration or that of the system to a particular
|
||||
date. XCM looks for a revision directory in the current location
|
||||
profile with the most recent modification date that is not more recent
|
||||
than the date specified by the user. XCM also has a list of what
|
||||
capplets (or XSTs) constitute a complete snapshot of the system's
|
||||
configuration. In order to perform a complete rollback, it backtracks
|
||||
through the revision directories, picking up XML snapshots of capplets
|
||||
until it has a complete set and applies them through the --set
|
||||
method. In the case of XSTs, the XCM knows how to invoke the backend
|
||||
and does so as necessary.
|
||||
|
||||
IV. Location management
|
||||
|
||||
The system may have one or more profiles, each giving different system
|
||||
configurations. For example, a user may own a laptop and wish to hook
|
||||
that laptop up to different networks at different times. Each network
|
||||
may be located in a different time zone, have different network
|
||||
configuration parameters (e.g., DHCP vs. static IPs), and use different
|
||||
default printers. When the user hooks his laptop up in a particular
|
||||
network, it would be advantageous to switch to that network's
|
||||
configuration with a minimum of hassle.
|
||||
|
||||
As mentioned above, configuration data is stored in separate
|
||||
directories corresponding to the name of a given location. XCM has the
|
||||
ability to apply a set of configuration files from a given location in
|
||||
a manner similar to the rollback procedure described above. When the
|
||||
user selects an alternative configuration, it simply goes through the
|
||||
revision history for that location, pulls a complete set of
|
||||
configuration files, and applies them. The procedure is similar for
|
||||
both capplets and XSTs.
|
||||
|
||||
In addition, locations may be expressed hierarchically. For example, a
|
||||
user might specify a location called `Boston' that describes language,
|
||||
time zone, currency, and other locale data, and another location called
|
||||
`Boston Office' that includes network parameters. `Boston Office'
|
||||
inherits its locale data from `Boston', overriding the latter's
|
||||
network configuration.
|
||||
|
||||
To implement this, each location directory contains some metadata that
|
||||
describes what configuration data is valid for it and what other
|
||||
configuration it inherits from. There are one or more root
|
||||
configurations that contain a complete set of data. When applying a
|
||||
new location, XCM looks first at that location's directory, pulling a
|
||||
complete set of all the configuration data defined by that location,
|
||||
and then goes to the next level up in the location hierarchy and does
|
||||
the same thing. It also keeps track of the common subtree root between
|
||||
the old and new locations so that only the configuration items that
|
||||
actually change are collected.
|
||||
|
||||
From a user's perspective, the XCM will present a tree showing the
|
||||
existing locations. Users may create a new location derived from an
|
||||
existing one. When the user elects to configure a particular location,
|
||||
the XCM shell includes icons that are grayed out, indicating that
|
||||
those configuration items are not set in this particular location. If
|
||||
the user attempts to change them, they become specific to that
|
||||
particular location and are recolored accordingly.
|
||||
|
||||
V. Clustering
|
||||
|
||||
A single server may archive the configuration for a large number of
|
||||
individual workstations, providing configuration data to each of the
|
||||
clients on demand. An administrator can then push configuration
|
||||
updates out to each machine with the press of a button, rather than
|
||||
having to go to each machine and update it manually.
|
||||
|
||||
To enable this, each client machine will run a daemon that accepts
|
||||
configuration data pushed out by the server. Some sort of public key
|
||||
signing will be implemented to ensure that this is done securely. On
|
||||
the server end, a series of host groups is maintained, each one
|
||||
containing a set of hosts. These form the top two levels of a
|
||||
configuration hierarchy not unlike what is described above. Each host
|
||||
may override certain configuration values for the cluster as a
|
||||
whole. The cluster may also have multiple `locations', e.g. for
|
||||
configuring a computer lab for computer science during one class and
|
||||
for math during another. Locations may be selected down to the
|
||||
granularity of a single host, or for the entire cluster at
|
||||
once. Cluster-wide configurations occur between the cluster and host
|
||||
level in the configuration hierarchy.
|
||||
|
||||
VI. Issues
|
||||
|
||||
1. We need a way to get an XML state without actually applying
|
||||
changes, so that the user can configure a location without switching
|
||||
to it.
|
||||
|
||||
2. Can we make the XST frontends Bonobo controls, and can we have them
|
||||
run as the regular user rather than as root? This would ensure that
|
||||
certain user interface preferences, such as themes, are kept
|
||||
consistent for a given user between capplets and XSTs. The way to
|
||||
implement this is to have a method on the XCM interface called
|
||||
RunBackend() which returns a BonoboObject referring to the backend
|
||||
that implements the Bonobo::XSTBackend interface, which is similar to
|
||||
the Bonobo::Capplet interface mentioned above. The interface defines
|
||||
the GetXML and SetXML methods. The object should also implement
|
||||
another, XST-specific interface to facilitate setting specific
|
||||
configuration variables, so that live update may be implemented. The
|
||||
root manager must then be extended to support some sort of secure
|
||||
forwarding, allowing the user to access that particular CORBA object.
|
||||
|
||||
3. If we make the XSTs into Bonobo controls, can we give them the same
|
||||
Bonobo::Capplet interface that is given to the Capplets? This would
|
||||
make everything a bit simpler from the XCM's perspective, since it
|
||||
then does not need to know the difference between Capplets and
|
||||
XSTs -- it then only needs to implement the RunBackend() method for
|
||||
the benefit of the XSTs.
|
||||
@@ -1,4 +0,0 @@
|
||||
XIMIAN_ARCHIVER_LIBDIR="@GNOME_LIBDIR@"
|
||||
XIMIAN_ARCHIVER_LIBS="-lximian_archiver @GNOMEUI_LIBS@"
|
||||
XIMIAN_ARCHIVER_INCLUDEDIR="@GNOME_INCLUDEDIR@"
|
||||
MODULE_VERSION="ximian-archiver-@VERSION@"
|
||||
141
autogen.sh
141
autogen.sh
@@ -1,141 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
PKG_NAME="GNOME Control Center"
|
||||
|
||||
(test -f $srcdir/configure.in \
|
||||
&& test -d $srcdir/capplets \
|
||||
&& test -d $srcdir/control-center) || {
|
||||
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
|
||||
echo " top-level "\`$PKG_NAME\'" directory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
ORIGDIR=`pwd`
|
||||
cd $srcdir
|
||||
PROJECT=control-center
|
||||
TEST_TYPE=-f
|
||||
|
||||
DIE=0
|
||||
|
||||
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "You must have autoconf installed to compile $PROJECT."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
(automake --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "You must have automake installed to compile $PROJECT."
|
||||
echo "Get ftp://sourceware.cygnus.com/pub/automake/automake-1.4.tar.gz"
|
||||
echo "(or a newer version if it is available)"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
(grep "^AM_PROG_LIBTOOL" configure.in >/dev/null) && {
|
||||
(libtool --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have \`libtool' installed to compile $PROJECT."
|
||||
echo "Get ftp://ftp.gnu.org/pub/gnu/libtool-1.2d.tar.gz"
|
||||
echo "(or a newer version if it is available)"
|
||||
DIE=1
|
||||
}
|
||||
}
|
||||
|
||||
grep "^AM_GNU_GETTEXT" configure.in >/dev/null && {
|
||||
grep "sed.*POTFILES" $srcdir/configure.in >/dev/null || \
|
||||
(gettext --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have \`gettext' installed to compile $PROJECT."
|
||||
echo "Get ftp://alpha.gnu.org/gnu/gettext-0.10.35.tar.gz"
|
||||
echo "(or a newer version if it is available)"
|
||||
DIE=1
|
||||
}
|
||||
}
|
||||
|
||||
if test "$DIE" -eq 1; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if test -z "$*"; then
|
||||
echo "I am going to run ./configure with no arguments - if you wish "
|
||||
echo "to pass any to it, please specify them on the $0 command line."
|
||||
fi
|
||||
|
||||
case $CC in
|
||||
*xlc | *xlc\ * | *lcc | *lcc\ *) am_opt=--include-deps;;
|
||||
esac
|
||||
|
||||
for coin in `find . -name configure.in -print`
|
||||
do
|
||||
dr=`dirname $coin`
|
||||
if test -f $dr/NO-AUTO-GEN; then
|
||||
echo skipping $dr -- flagged as no auto-gen
|
||||
else
|
||||
echo processing $dr
|
||||
macrodirs=`sed -n -e 's,AM_ACLOCAL_INCLUDE(\(.*\)),\1,gp' < $coin`
|
||||
( cd $dr
|
||||
aclocalinclude="$ACLOCAL_FLAGS"
|
||||
for k in $macrodirs; do
|
||||
if test -d $k; then
|
||||
aclocalinclude="$aclocalinclude -I $k"
|
||||
##else
|
||||
## echo "**Warning**: No such directory \`$k'. Ignored."
|
||||
fi
|
||||
done
|
||||
if grep "^AM_GNU_GETTEXT" configure.in >/dev/null; then
|
||||
if grep "sed.*POTFILES" configure.in >/dev/null; then
|
||||
: do nothing -- we still have an old unmodified configure.in
|
||||
else
|
||||
echo "Creating $dr/aclocal.m4 ..."
|
||||
test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
|
||||
echo "Running gettextize... Ignore non-fatal messages."
|
||||
echo "no" | gettextize --force --copy
|
||||
echo "Making $dr/aclocal.m4 writable ..."
|
||||
test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
|
||||
fi
|
||||
fi
|
||||
if grep "^AM_GNOME_GETTEXT" configure.in >/dev/null; then
|
||||
echo "Creating $dr/aclocal.m4 ..."
|
||||
test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
|
||||
echo "Running gettextize... Ignore non-fatal messages."
|
||||
echo "no" | gettextize --force --copy
|
||||
echo "Making $dr/aclocal.m4 writable ..."
|
||||
test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
|
||||
fi
|
||||
if grep "^AM_PROG_LIBTOOL" configure.in >/dev/null; then
|
||||
echo "Running libtoolize..."
|
||||
libtoolize --force --copy
|
||||
fi
|
||||
echo "Running aclocal $aclocalinclude ..."
|
||||
aclocal $aclocalinclude
|
||||
if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then
|
||||
echo "Running autoheader..."
|
||||
autoheader
|
||||
fi
|
||||
echo "Running automake --gnu $am_opt ..."
|
||||
automake --add-missing --gnu $am_opt
|
||||
echo "Running autoconf ..."
|
||||
autoconf
|
||||
)
|
||||
fi
|
||||
done
|
||||
|
||||
conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c
|
||||
|
||||
cd "$ORIGDIR"
|
||||
|
||||
if test x$NOCONFIGURE = x; then
|
||||
echo Running $srcdir/configure $conf_flags "$@" ...
|
||||
$srcdir/configure $conf_flags "$@" \
|
||||
&& echo Now type \`make\' to compile $PROJECT || exit 1
|
||||
else
|
||||
echo Skipping configure process.
|
||||
fi
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
always_built_SUBDIRS = desktop-links new-mouse-properties \
|
||||
new-screensaver-properties new-background-properties \
|
||||
theme-switcher new-sound-properties new-bell-properties \
|
||||
new-ui-properties url-properties gnome-edit-properties \
|
||||
session-properties wm-properties new-keyboard-properties \
|
||||
mime-type
|
||||
|
||||
SUBDIRS = $(always_built_SUBDIRS)
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
.libs
|
||||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
background-properties-capplet
|
||||
@@ -1,37 +0,0 @@
|
||||
Applicationsdir = $(datadir)/control-center/Desktop
|
||||
Applications_DATA = \
|
||||
background-properties.desktop
|
||||
|
||||
pApplicationsdir = $(datadir)/gnome/apps/Settings/Desktop
|
||||
pApplications_DATA = \
|
||||
background-properties.desktop
|
||||
|
||||
Gladedir = $(datadir)/control-center-data
|
||||
Glade_DATA = \
|
||||
background-properties.glade
|
||||
|
||||
glade_msgs = \
|
||||
background-properties.glade.h
|
||||
|
||||
EXTRA_DIST = $(Applications_DATA) $(Glade_DATA) $(glade_msgs)
|
||||
|
||||
INCLUDES = \
|
||||
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
|
||||
-DGNOME_ICONDIR=\""${prefix}/share/pixmaps"\" \
|
||||
-DG_LOG_DOMAIN=\"background-properties\" \
|
||||
-DGLADE_DATADIR=\""$(Gladedir)"\" \
|
||||
$(GNOME_INCLUDEDIR) \
|
||||
$(BG_CAPPLET_CFLAGS) \
|
||||
-I$(top_srcdir)/ \
|
||||
-I$(top_srcdir)/intl
|
||||
|
||||
bin_PROGRAMS = background-properties-capplet
|
||||
|
||||
background_properties_capplet_SOURCES = \
|
||||
prefs-widget.c prefs-widget.h \
|
||||
preferences.c preferences.h \
|
||||
applier.c applier.h \
|
||||
main.c
|
||||
|
||||
background_properties_capplet_LDADD = \
|
||||
$(GNOME_LIBDIR) $(BG_CAPPLET_LIBS)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,64 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* applier.h
|
||||
* Copyright (C) 2000 Helix Code, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@helixcode.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __APPLIER_H
|
||||
#define __APPLIER_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "preferences.h"
|
||||
|
||||
#define APPLIER(obj) GTK_CHECK_CAST (obj, applier_get_type (), Applier)
|
||||
#define APPLIER_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, applier_get_type (), ApplierClass)
|
||||
#define IS_APPLIER(obj) GTK_CHECK_TYPE (obj, applier_get_type ())
|
||||
|
||||
typedef struct _Applier Applier;
|
||||
typedef struct _ApplierClass ApplierClass;
|
||||
|
||||
typedef struct _ApplierPrivate ApplierPrivate;
|
||||
|
||||
struct _Applier
|
||||
{
|
||||
GtkObject object;
|
||||
ApplierPrivate *private;
|
||||
};
|
||||
|
||||
struct _ApplierClass
|
||||
{
|
||||
GtkObjectClass klass;
|
||||
};
|
||||
|
||||
guint applier_get_type (void);
|
||||
|
||||
GtkObject *applier_new (void);
|
||||
void applier_destroy (GtkObject *object);
|
||||
|
||||
void applier_apply_prefs (Applier *applier, Preferences *prefs,
|
||||
gboolean do_root, gboolean do_preview);
|
||||
|
||||
GtkWidget *applier_class_get_preview_widget (void);
|
||||
|
||||
#endif /* __APPLIER_H */
|
||||
@@ -1,54 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Name=Background
|
||||
Name[da]=Baggrund
|
||||
Name[ca]=Propietats del fons
|
||||
Name[cs]=Pozadí
|
||||
Name[de]=Hintergrund
|
||||
Name[es]=Propiedades del tapiz
|
||||
Name[et]=Taust
|
||||
Name[fi]=Tausta
|
||||
Name[fr]=Arrière-plan
|
||||
Name[gl]=Propiedades do tapiz
|
||||
Name[hu]=Háttér
|
||||
Name[it]=Sfondo
|
||||
Name[ja]=¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É
|
||||
Name[ko]=¹è°æ
|
||||
Name[lt]=Fonas
|
||||
Name[no]=Bakgrunn
|
||||
Name[pl]=T³o
|
||||
Name[pt]=Propriedades do Fundo
|
||||
Name[pt_BR]=Fundo
|
||||
Name[ro]=Fundal
|
||||
Name[ru]=æÏÎ
|
||||
Name[sl]=Ozadje
|
||||
Name[sv]=Bakgrund
|
||||
Name[uk]=ôÌÏ
|
||||
Name[wa]=Fond do scribanne
|
||||
Name[zh_TW.Big5]=®à±I´º
|
||||
Name[zh_CN.GB2312]=×ÀÃæ±³¾°
|
||||
Comment=Configuration of the desktop's background
|
||||
Comment[cs]=Nastavení pozadí pracovní plochy
|
||||
Comment[da]=Indstil din skrivebordsbaggrund
|
||||
Comment[de]=Konfiguration des Desktophintergrundes
|
||||
Comment[es]=Configuración del tapiz del escritorio
|
||||
Comment[et]=Töölaua tausta häälestus
|
||||
Comment[fi]=Työpöydän taustan asetukset
|
||||
Comment[fr]=Configuration des propriétés de l'arrière-plan
|
||||
Comment[gl]=Configuración do tapiz do escritorio
|
||||
Comment[it]=Impostazioni dello sfondo del desktop
|
||||
Comment[ja]=¥Ç¥¹¥¯¥È¥Ã¥×ÇØ·Ê¤ÎÀßÄê
|
||||
Comment[lt]=Darbalaukio fono nustatymas
|
||||
Comment[no]=Konfigurasjon av skrivebordsbakgrunn
|
||||
Comment[pl]=Konfiguracja t³a
|
||||
Comment[pt_BR]=Configuração do fundo da área de trabalho
|
||||
Comment[ro]=Configuraþia fundalului de desktop
|
||||
Comment[sl]=Nastavitev ozadja namizja
|
||||
Comment[sv]=Konfiguration av skrivbordsbakgrund
|
||||
Comment[uk]=ëÏÎÆ¦ÇÕÒÕ×ÁÎÎÑ ÔÌÁ
|
||||
Comment[wa]=Apontiaedje do fond do scribanne
|
||||
Comment[zh_TW.Big5]=³]©w®à±I´º¼Ë¦¡
|
||||
Comment[zh_CN.GB2312]=É趨×ÀÃæ±³¾°Ñùʽ
|
||||
Exec=background-properties-capplet
|
||||
Icon=gnome-ccbackground.png
|
||||
Terminal=0
|
||||
Type=Application
|
||||
@@ -1,540 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<GTK-Interface>
|
||||
|
||||
<project>
|
||||
<name>New-background-properties</name>
|
||||
<program_name>new-background-properties</program_name>
|
||||
<directory></directory>
|
||||
<source_directory>src</source_directory>
|
||||
<pixmaps_directory>pixmaps</pixmaps_directory>
|
||||
<language>C</language>
|
||||
<gnome_support>True</gnome_support>
|
||||
<gettext_support>True</gettext_support>
|
||||
<output_translatable_strings>True</output_translatable_strings>
|
||||
<translatable_strings_file>background-properties.glade.h</translatable_strings_file>
|
||||
</project>
|
||||
|
||||
<widget>
|
||||
<class>GtkWindow</class>
|
||||
<name>window1</name>
|
||||
<title>window1</title>
|
||||
<type>GTK_WINDOW_TOPLEVEL</type>
|
||||
<position>GTK_WIN_POS_NONE</position>
|
||||
<modal>False</modal>
|
||||
<allow_shrink>False</allow_shrink>
|
||||
<allow_grow>True</allow_grow>
|
||||
<auto_shrink>False</auto_shrink>
|
||||
|
||||
<widget>
|
||||
<class>GtkVBox</class>
|
||||
<name>prefs_widget</name>
|
||||
<homogeneous>False</homogeneous>
|
||||
<spacing>0</spacing>
|
||||
|
||||
<widget>
|
||||
<class>GtkEventBox</class>
|
||||
<name>monitor_frame</name>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>Placeholder</class>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkCheckButton</class>
|
||||
<name>disable_toggle</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>toggled</name>
|
||||
<handler>disable_toggled_cb</handler>
|
||||
<last_modification_time>Wed, 06 Sep 2000 00:15:45 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Use GNOME for setting background</label>
|
||||
<active>True</active>
|
||||
<draw_indicator>True</draw_indicator>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkHBox</class>
|
||||
<name>hbox2</name>
|
||||
<homogeneous>False</homogeneous>
|
||||
<spacing>4</spacing>
|
||||
<child>
|
||||
<padding>4</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkFrame</class>
|
||||
<name>color_frame</name>
|
||||
<label>Colors</label>
|
||||
<label_xalign>0</label_xalign>
|
||||
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkTable</class>
|
||||
<name>table4</name>
|
||||
<border_width>4</border_width>
|
||||
<rows>3</rows>
|
||||
<columns>2</columns>
|
||||
<homogeneous>False</homogeneous>
|
||||
<row_spacing>4</row_spacing>
|
||||
<column_spacing>4</column_spacing>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label5</name>
|
||||
<label>Effect</label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<left_attach>0</left_attach>
|
||||
<right_attach>1</right_attach>
|
||||
<top_attach>0</top_attach>
|
||||
<bottom_attach>1</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>False</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>True</xfill>
|
||||
<yfill>False</yfill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label6</name>
|
||||
<label>Color 1</label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<left_attach>0</left_attach>
|
||||
<right_attach>1</right_attach>
|
||||
<top_attach>1</top_attach>
|
||||
<bottom_attach>2</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>False</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>True</xfill>
|
||||
<yfill>False</yfill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label7</name>
|
||||
<label>Color 2</label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<left_attach>0</left_attach>
|
||||
<right_attach>1</right_attach>
|
||||
<top_attach>2</top_attach>
|
||||
<bottom_attach>3</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>False</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>True</xfill>
|
||||
<yfill>False</yfill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GnomeColorPicker</class>
|
||||
<name>color1_select</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>color_set</name>
|
||||
<handler>color1_select_color_set_cb</handler>
|
||||
<last_modification_time>Sat, 09 Dec 2000 01:18:26 GMT</last_modification_time>
|
||||
</signal>
|
||||
<dither>True</dither>
|
||||
<use_alpha>False</use_alpha>
|
||||
<title>Pick a color</title>
|
||||
<child>
|
||||
<left_attach>1</left_attach>
|
||||
<right_attach>2</right_attach>
|
||||
<top_attach>1</top_attach>
|
||||
<bottom_attach>2</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>False</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>True</xfill>
|
||||
<yfill>False</yfill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GnomeColorPicker</class>
|
||||
<name>color2_select</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>color_set</name>
|
||||
<handler>color2_select_color_set_cb</handler>
|
||||
<last_modification_time>Sat, 09 Dec 2000 01:18:35 GMT</last_modification_time>
|
||||
</signal>
|
||||
<dither>True</dither>
|
||||
<use_alpha>False</use_alpha>
|
||||
<title>Pick a color</title>
|
||||
<child>
|
||||
<left_attach>1</left_attach>
|
||||
<right_attach>2</right_attach>
|
||||
<top_attach>2</top_attach>
|
||||
<bottom_attach>3</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>False</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>True</xfill>
|
||||
<yfill>False</yfill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkOptionMenu</class>
|
||||
<name>color_option</name>
|
||||
<can_focus>True</can_focus>
|
||||
<items>Solid Color
|
||||
Vertical Gradient
|
||||
Horizontal Gradient
|
||||
</items>
|
||||
<initial_choice>1</initial_choice>
|
||||
<child>
|
||||
<left_attach>1</left_attach>
|
||||
<right_attach>2</right_attach>
|
||||
<top_attach>0</top_attach>
|
||||
<bottom_attach>1</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>True</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>True</xfill>
|
||||
<yfill>False</yfill>
|
||||
</child>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkFrame</class>
|
||||
<name>wallpaper_frame</name>
|
||||
<label>Wallpaper</label>
|
||||
<label_xalign>0</label_xalign>
|
||||
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkTable</class>
|
||||
<name>table3</name>
|
||||
<border_width>4</border_width>
|
||||
<rows>2</rows>
|
||||
<columns>3</columns>
|
||||
<homogeneous>False</homogeneous>
|
||||
<row_spacing>4</row_spacing>
|
||||
<column_spacing>4</column_spacing>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label3</name>
|
||||
<label>File</label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<left_attach>0</left_attach>
|
||||
<right_attach>1</right_attach>
|
||||
<top_attach>0</top_attach>
|
||||
<bottom_attach>1</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>False</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>True</xfill>
|
||||
<yfill>False</yfill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label4</name>
|
||||
<label>Effect</label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<left_attach>0</left_attach>
|
||||
<right_attach>1</right_attach>
|
||||
<top_attach>1</top_attach>
|
||||
<bottom_attach>2</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>False</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>True</xfill>
|
||||
<yfill>False</yfill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkOptionMenu</class>
|
||||
<name>wp_effect_option</name>
|
||||
<can_focus>True</can_focus>
|
||||
<items>Tiled
|
||||
Centered
|
||||
Scaled (keep aspect ratio)
|
||||
Stretched (change aspect ratio)
|
||||
Embossed
|
||||
</items>
|
||||
<initial_choice>0</initial_choice>
|
||||
<child>
|
||||
<left_attach>1</left_attach>
|
||||
<right_attach>3</right_attach>
|
||||
<top_attach>1</top_attach>
|
||||
<bottom_attach>2</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>True</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>True</xfill>
|
||||
<yfill>False</yfill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkButton</class>
|
||||
<name>browse_button</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>clicked</name>
|
||||
<handler>browse_button_cb</handler>
|
||||
<last_modification_time>Fri, 08 Dec 2000 21:55:52 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Browse...</label>
|
||||
<child>
|
||||
<left_attach>2</left_attach>
|
||||
<right_attach>3</right_attach>
|
||||
<top_attach>0</top_attach>
|
||||
<bottom_attach>1</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>False</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>False</xfill>
|
||||
<yfill>False</yfill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkOptionMenu</class>
|
||||
<name>wp_file_option</name>
|
||||
<width>66</width>
|
||||
<can_focus>True</can_focus>
|
||||
<items>(None)
|
||||
</items>
|
||||
<initial_choice>0</initial_choice>
|
||||
<child>
|
||||
<left_attach>1</left_attach>
|
||||
<right_attach>2</right_attach>
|
||||
<top_attach>0</top_attach>
|
||||
<bottom_attach>1</bottom_attach>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<xexpand>True</xexpand>
|
||||
<yexpand>False</yexpand>
|
||||
<xshrink>False</xshrink>
|
||||
<yshrink>False</yshrink>
|
||||
<xfill>True</xfill>
|
||||
<yfill>False</yfill>
|
||||
</child>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkCheckButton</class>
|
||||
<name>adjust_opacity_toggle</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>toggled</name>
|
||||
<handler>adjust_opacity_toggled_cb</handler>
|
||||
<last_modification_time>Thu, 21 Dec 2000 19:54:21 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Adjust wallpaper's opacity</label>
|
||||
<active>False</active>
|
||||
<draw_indicator>True</draw_indicator>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkHBox</class>
|
||||
<name>opacity_box</name>
|
||||
<homogeneous>False</homogeneous>
|
||||
<spacing>4</spacing>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label10</name>
|
||||
<width>16</width>
|
||||
<label></label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0.5</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label8</name>
|
||||
<label>More Transparent</label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0.5</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkHScale</class>
|
||||
<name>opacity_adjust</name>
|
||||
<can_focus>True</can_focus>
|
||||
<draw_value>False</draw_value>
|
||||
<value_pos>GTK_POS_TOP</value_pos>
|
||||
<digits>1</digits>
|
||||
<policy>GTK_UPDATE_CONTINUOUS</policy>
|
||||
<value>0</value>
|
||||
<lower>0</lower>
|
||||
<upper>0</upper>
|
||||
<step>0</step>
|
||||
<page>0</page>
|
||||
<page_size>0</page_size>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label9</name>
|
||||
<label>More Solid</label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0.5</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkCheckButton</class>
|
||||
<name>auto_apply</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>toggled</name>
|
||||
<handler>auto_apply_toggled_cb</handler>
|
||||
<last_modification_time>Thu, 21 Dec 2000 19:52:25 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Apply changes automatically</label>
|
||||
<active>False</active>
|
||||
<draw_indicator>True</draw_indicator>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
</GTK-Interface>
|
||||
@@ -1,33 +0,0 @@
|
||||
/*n * Fil med oversettbare strenger generert av Glade.
|
||||
* Legg till denne filen i ditt prosjekts POTFILES.in.
|
||||
* IKKE kompiler den som en del av applikasjonen din.
|
||||
*/
|
||||
|
||||
gchar *s = N_("window1");
|
||||
gchar *s = N_("Use GNOME for setting background");
|
||||
gchar *s = N_("Colors");
|
||||
gchar *s = N_("Effect");
|
||||
gchar *s = N_("Color 1");
|
||||
gchar *s = N_("Color 2");
|
||||
gchar *s = N_("Pick a color");
|
||||
gchar *s = N_("Pick a color");
|
||||
gchar *s = N_("Solid Color\n"
|
||||
"Vertical Gradient\n"
|
||||
"Horizontal Gradient\n"
|
||||
"");
|
||||
gchar *s = N_("Wallpaper");
|
||||
gchar *s = N_("File");
|
||||
gchar *s = N_("Effect");
|
||||
gchar *s = N_("Tiled\n"
|
||||
"Centered\n"
|
||||
"Scaled (keep aspect ratio)\n"
|
||||
"Stretched (change aspect ratio)\n"
|
||||
"Embossed\n"
|
||||
"");
|
||||
gchar *s = N_("Browse...");
|
||||
gchar *s = N_("(None)\n"
|
||||
"");
|
||||
gchar *s = N_("Adjust wallpaper's opacity");
|
||||
gchar *s = N_("More Transparent");
|
||||
gchar *s = N_("More Solid");
|
||||
gchar *s = N_("Apply changes automatically");
|
||||
@@ -1,230 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* main.c
|
||||
* Copyright (C) 2000 Helix Code, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen (hovinen@helixcode.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gnome.h>
|
||||
#include <libgnomeui/gnome-window-icon.h>
|
||||
#include <tree.h>
|
||||
#include <parser.h>
|
||||
|
||||
#include <glade/glade.h>
|
||||
|
||||
#include <capplet-widget.h>
|
||||
|
||||
#include <ximian-archiver/archive.h>
|
||||
#include <ximian-archiver/location.h>
|
||||
|
||||
#include "preferences.h"
|
||||
#include "prefs-widget.h"
|
||||
|
||||
static Preferences *prefs;
|
||||
static Preferences *old_prefs;
|
||||
static PrefsWidget *prefs_widget;
|
||||
|
||||
static guint ok_handler_id;
|
||||
static guint cancel_handler_id;
|
||||
|
||||
static void
|
||||
store_archive_data (void)
|
||||
{
|
||||
Archive *archive;
|
||||
Location *location;
|
||||
xmlDocPtr xml_doc;
|
||||
|
||||
archive = ARCHIVE (archive_load (FALSE));
|
||||
location = archive_get_current_location (archive);
|
||||
xml_doc = preferences_write_xml (prefs);
|
||||
location_store_xml (location, "background-properties-capplet",
|
||||
xml_doc);
|
||||
xmlFreeDoc (xml_doc);
|
||||
archive_close (archive);
|
||||
}
|
||||
|
||||
static void
|
||||
ok_cb (GtkWidget *widget)
|
||||
{
|
||||
preferences_save (prefs);
|
||||
preferences_apply_now (prefs);
|
||||
gtk_signal_disconnect (GTK_OBJECT (prefs_widget), ok_handler_id);
|
||||
gtk_signal_disconnect (GTK_OBJECT (prefs_widget), cancel_handler_id);
|
||||
gtk_object_destroy (GTK_OBJECT (prefs_widget));
|
||||
store_archive_data ();
|
||||
}
|
||||
|
||||
static void
|
||||
cancel_cb (GtkWidget *widget)
|
||||
{
|
||||
preferences_save (old_prefs);
|
||||
preferences_apply_now (old_prefs);
|
||||
gtk_signal_disconnect (GTK_OBJECT (prefs_widget), ok_handler_id);
|
||||
gtk_signal_disconnect (GTK_OBJECT (prefs_widget), cancel_handler_id);
|
||||
gtk_object_destroy (GTK_OBJECT (prefs_widget));
|
||||
}
|
||||
|
||||
static void
|
||||
setup_capplet_widget (void)
|
||||
{
|
||||
preferences_freeze (prefs);
|
||||
|
||||
prefs_widget = PREFS_WIDGET (prefs_widget_new (prefs));
|
||||
|
||||
ok_handler_id =
|
||||
gtk_signal_connect (GTK_OBJECT (prefs_widget), "ok",
|
||||
GTK_SIGNAL_FUNC (ok_cb), NULL);
|
||||
cancel_handler_id =
|
||||
gtk_signal_connect (GTK_OBJECT (prefs_widget), "cancel",
|
||||
GTK_SIGNAL_FUNC (cancel_cb), NULL);
|
||||
|
||||
gtk_widget_show_all (GTK_WIDGET (prefs_widget));
|
||||
|
||||
preferences_thaw (prefs);
|
||||
}
|
||||
|
||||
static void
|
||||
do_get_xml (void)
|
||||
{
|
||||
Preferences *prefs;
|
||||
xmlDocPtr doc;
|
||||
|
||||
prefs = PREFERENCES (preferences_new ());
|
||||
preferences_load (prefs);
|
||||
doc = preferences_write_xml (prefs);
|
||||
xmlDocDump (stdout, doc);
|
||||
gtk_object_destroy (GTK_OBJECT (prefs));
|
||||
}
|
||||
|
||||
static void
|
||||
do_set_xml (void)
|
||||
{
|
||||
Preferences *prefs;
|
||||
xmlDocPtr doc;
|
||||
char *buffer = NULL;
|
||||
int len = 0;
|
||||
|
||||
while (!feof (stdin)) {
|
||||
if (!len) buffer = g_new (char, 16384);
|
||||
else buffer = g_renew (char, buffer, len + 16384);
|
||||
fread (buffer + len, 1, 16384, stdin);
|
||||
len += 16384;
|
||||
}
|
||||
|
||||
doc = xmlParseMemory (buffer, strlen (buffer));
|
||||
|
||||
prefs = preferences_read_xml (doc);
|
||||
|
||||
if (prefs) {
|
||||
preferences_save (prefs);
|
||||
preferences_apply_now (prefs);
|
||||
} else {
|
||||
g_warning ("Error while reading the screensaver config file");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_restore_from_defaults (void)
|
||||
{
|
||||
prefs = PREFERENCES (preferences_new ());
|
||||
preferences_save (prefs);
|
||||
preferences_apply_now (prefs);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
GnomeClient *client;
|
||||
GnomeClientFlags flags;
|
||||
gint token, res;
|
||||
gchar *restart_args[3];
|
||||
|
||||
bindtextdomain (PACKAGE, GNOMELOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
glade_gnome_init ();
|
||||
res = gnome_capplet_init ("background-properties-capplet",
|
||||
VERSION, argc, argv, NULL,
|
||||
0, NULL);
|
||||
|
||||
if (res < 0) {
|
||||
g_error ("Could not initialize the capplet.");
|
||||
}
|
||||
else if (res == 3) {
|
||||
do_get_xml ();
|
||||
return 0;
|
||||
}
|
||||
else if (res == 4) {
|
||||
do_set_xml ();
|
||||
return 0;
|
||||
}
|
||||
else if (res == 5) {
|
||||
do_restore_from_defaults ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
client = gnome_master_client ();
|
||||
flags = gnome_client_get_flags (client);
|
||||
|
||||
if (flags & GNOME_CLIENT_IS_CONNECTED) {
|
||||
token = gnome_startup_acquire_token
|
||||
("GNOME_BACKGROUND_PROPERTIES",
|
||||
gnome_client_get_id (client));
|
||||
|
||||
if (token) {
|
||||
gnome_client_set_priority (client, 20);
|
||||
gnome_client_set_restart_style (client,
|
||||
GNOME_RESTART_ANYWAY);
|
||||
restart_args[0] = argv[0];
|
||||
restart_args[1] = "--init-session-settings";
|
||||
restart_args[2] = NULL;
|
||||
gnome_client_set_restart_command (client, 2,
|
||||
restart_args);
|
||||
} else {
|
||||
gnome_client_set_restart_style (client,
|
||||
GNOME_RESTART_NEVER);
|
||||
}
|
||||
} else {
|
||||
token = 1;
|
||||
}
|
||||
|
||||
gnome_window_icon_set_default_from_file
|
||||
(GNOME_ICONDIR"/gnome-ccbackground.png");
|
||||
|
||||
prefs = PREFERENCES (preferences_new ());
|
||||
preferences_load (prefs);
|
||||
|
||||
if (token) {
|
||||
preferences_apply_now (prefs);
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
old_prefs = PREFERENCES (preferences_clone (prefs));
|
||||
setup_capplet_widget ();
|
||||
|
||||
capplet_gtk_main ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,542 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* preferences.c
|
||||
* Copyright (C) 2000 Helix Code, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@helixcode.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gnome.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf-xlibrgb.h>
|
||||
|
||||
#include "preferences.h"
|
||||
#include "applier.h"
|
||||
|
||||
static GtkObjectClass *parent_class;
|
||||
static Applier *applier = NULL;
|
||||
|
||||
static void preferences_init (Preferences *prefs);
|
||||
static void preferences_class_init (PreferencesClass *class);
|
||||
|
||||
static gint xml_read_int (xmlNodePtr node,
|
||||
gchar *propname);
|
||||
static xmlNodePtr xml_write_int (gchar *name,
|
||||
gchar *propname,
|
||||
gint number);
|
||||
|
||||
static gint apply_timeout_cb (Preferences *prefs);
|
||||
|
||||
static GdkColor *read_color_from_string (gchar *string);
|
||||
|
||||
guint
|
||||
preferences_get_type (void)
|
||||
{
|
||||
static guint preferences_type = 0;
|
||||
|
||||
if (!preferences_type) {
|
||||
GtkTypeInfo preferences_info = {
|
||||
"Preferences",
|
||||
sizeof (Preferences),
|
||||
sizeof (PreferencesClass),
|
||||
(GtkClassInitFunc) preferences_class_init,
|
||||
(GtkObjectInitFunc) preferences_init,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL
|
||||
};
|
||||
|
||||
preferences_type =
|
||||
gtk_type_unique (gtk_object_get_type (),
|
||||
&preferences_info);
|
||||
}
|
||||
|
||||
return preferences_type;
|
||||
}
|
||||
|
||||
static void
|
||||
preferences_init (Preferences *prefs)
|
||||
{
|
||||
prefs->frozen = FALSE;
|
||||
|
||||
prefs->color1 = NULL;
|
||||
prefs->color2 = NULL;
|
||||
prefs->wallpaper_filename = NULL;
|
||||
prefs->wallpaper_sel_path = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
preferences_class_init (PreferencesClass *class)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
|
||||
object_class = (GtkObjectClass *) class;
|
||||
object_class->destroy = preferences_destroy;
|
||||
|
||||
parent_class =
|
||||
GTK_OBJECT_CLASS (gtk_type_class (gtk_object_get_type ()));
|
||||
|
||||
if (applier == NULL)
|
||||
applier = APPLIER (applier_new ());
|
||||
}
|
||||
|
||||
GtkObject *
|
||||
preferences_new (void)
|
||||
{
|
||||
GtkObject *object;
|
||||
|
||||
object = gtk_type_new (preferences_get_type ());
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
GtkObject *
|
||||
preferences_clone (Preferences *prefs)
|
||||
{
|
||||
GtkObject *object;
|
||||
Preferences *new_prefs;
|
||||
|
||||
g_return_val_if_fail (prefs != NULL, NULL);
|
||||
g_return_val_if_fail (IS_PREFERENCES (prefs), NULL);
|
||||
|
||||
object = preferences_new ();
|
||||
|
||||
new_prefs = PREFERENCES (object);
|
||||
|
||||
new_prefs->enabled = prefs->enabled;
|
||||
new_prefs->gradient_enabled = prefs->gradient_enabled;
|
||||
new_prefs->wallpaper_enabled = prefs->wallpaper_enabled;
|
||||
new_prefs->orientation = prefs->orientation;
|
||||
new_prefs->wallpaper_type = prefs->wallpaper_type;
|
||||
|
||||
if (prefs->color1)
|
||||
new_prefs->color1 = gdk_color_copy (prefs->color1);
|
||||
if (prefs->color2)
|
||||
new_prefs->color2 = gdk_color_copy (prefs->color2);
|
||||
|
||||
new_prefs->wallpaper_filename = g_strdup (prefs->wallpaper_filename);
|
||||
new_prefs->wallpaper_sel_path = g_strdup (prefs->wallpaper_sel_path);;
|
||||
|
||||
new_prefs->auto_apply = prefs->auto_apply;
|
||||
new_prefs->adjust_opacity = prefs->adjust_opacity;
|
||||
new_prefs->opacity = prefs->opacity;
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
void
|
||||
preferences_destroy (GtkObject *object)
|
||||
{
|
||||
Preferences *prefs;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (object));
|
||||
|
||||
prefs = PREFERENCES (object);
|
||||
|
||||
g_free (prefs->wallpaper_filename);
|
||||
g_free (prefs->wallpaper_sel_path);
|
||||
|
||||
parent_class->destroy (object);
|
||||
}
|
||||
|
||||
void
|
||||
preferences_load (Preferences *prefs)
|
||||
{
|
||||
gchar *string, *wp, *wp1;
|
||||
int i, wps;
|
||||
|
||||
g_return_if_fail (prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs));
|
||||
|
||||
if (prefs->color1) g_free (prefs->color1);
|
||||
string = gnome_config_get_string
|
||||
("/Background/Default/color1=#39374b");
|
||||
prefs->color1 = read_color_from_string (string);
|
||||
g_free (string);
|
||||
|
||||
if (prefs->color2) g_free (prefs->color2);
|
||||
string = gnome_config_get_string
|
||||
("/Background/Default/color2=#42528f");
|
||||
prefs->color2 = read_color_from_string (string);
|
||||
g_free (string);
|
||||
|
||||
string = gnome_config_get_string ("/Background/Default/Enabled=True");
|
||||
prefs->enabled = !(g_strcasecmp (string, "True"));
|
||||
g_free (string);
|
||||
|
||||
string = gnome_config_get_string ("/Background/Default/type=simple");
|
||||
if (!g_strcasecmp (string, "wallpaper"))
|
||||
prefs->wallpaper_enabled = TRUE;
|
||||
else if (g_strcasecmp (string, "simple"))
|
||||
prefs->wallpaper_enabled = FALSE;
|
||||
g_free (string);
|
||||
|
||||
string = gnome_config_get_string ("/Background/Default/simple=gradent");
|
||||
if (!g_strcasecmp (string, "gradient"))
|
||||
prefs->gradient_enabled = TRUE;
|
||||
else if (g_strcasecmp (string, "solid"))
|
||||
prefs->gradient_enabled = FALSE;
|
||||
g_free (string);
|
||||
|
||||
string = gnome_config_get_string
|
||||
("/Background/Default/gradient=vertical");
|
||||
if (!g_strcasecmp (string, "vertical"))
|
||||
prefs->orientation = ORIENTATION_VERT;
|
||||
else if (!g_strcasecmp (string, "horizontal"))
|
||||
prefs->orientation = ORIENTATION_HORIZ;
|
||||
g_free (string);
|
||||
|
||||
prefs->wallpaper_type =
|
||||
gnome_config_get_int ("/Background/Default/wallpaperAlign=0");
|
||||
|
||||
prefs->wallpaper_filename =
|
||||
gnome_config_get_string ("/Background/Default/wallpaper=(None)");
|
||||
prefs->wallpaper_sel_path =
|
||||
gnome_config_get_string
|
||||
("/Background/Default/wallpapers_dir=./");
|
||||
|
||||
prefs->auto_apply = gnome_config_get_bool ("/Background/Default/autoApply=true");
|
||||
|
||||
if (!g_strcasecmp (prefs->wallpaper_filename, "(None)")) {
|
||||
g_free(prefs->wallpaper_filename);
|
||||
prefs->wallpaper_filename = NULL;
|
||||
prefs->wallpaper_enabled = FALSE;
|
||||
} else {
|
||||
prefs->wallpaper_enabled = TRUE;
|
||||
}
|
||||
|
||||
wps = gnome_config_get_int ("/Background/Default/wallpapers=0");
|
||||
|
||||
for (i = 0; i < wps; i++) {
|
||||
wp = g_strdup_printf ("/Background/Default/wallpaper%d", i+1);
|
||||
wp1 = gnome_config_get_string (wp);
|
||||
g_free (wp);
|
||||
|
||||
if (!wp1) continue;
|
||||
|
||||
prefs->wallpapers = g_slist_prepend (prefs->wallpapers, wp1);
|
||||
}
|
||||
prefs->wallpapers = g_slist_reverse (prefs->wallpapers);
|
||||
|
||||
prefs->adjust_opacity = gnome_config_get_bool ("/Background/Default/adjustOpacity=true");
|
||||
|
||||
prefs->opacity = gnome_config_get_int ("/Background/Default/opacity=255");
|
||||
}
|
||||
|
||||
void
|
||||
preferences_save (Preferences *prefs)
|
||||
{
|
||||
char buffer[16];
|
||||
char *wp;
|
||||
GSList *item;
|
||||
int i;
|
||||
|
||||
g_return_if_fail (prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs));
|
||||
|
||||
snprintf (buffer, sizeof(buffer), "#%02x%02x%02x",
|
||||
prefs->color1->red >> 8,
|
||||
prefs->color1->green >> 8,
|
||||
prefs->color1->blue >> 8);
|
||||
gnome_config_set_string ("/Background/Default/color1", buffer);
|
||||
snprintf (buffer, sizeof(buffer), "#%02x%02x%02x",
|
||||
prefs->color2->red >> 8,
|
||||
prefs->color2->green >> 8,
|
||||
prefs->color2->blue >> 8);
|
||||
gnome_config_set_string ("/Background/Default/color2", buffer);
|
||||
|
||||
gnome_config_set_string ("/Background/Default/Enabled",
|
||||
(prefs->enabled) ? "True" : "False");
|
||||
|
||||
gnome_config_set_string ("/Background/Default/simple",
|
||||
(prefs->gradient_enabled) ?
|
||||
"gradient" : "solid");
|
||||
gnome_config_set_string ("/Background/Default/gradient",
|
||||
(prefs->orientation == ORIENTATION_VERT) ?
|
||||
"vertical" : "horizontal");
|
||||
|
||||
gnome_config_set_string ("/Background/Default/wallpaper",
|
||||
(prefs->wallpaper_enabled) ?
|
||||
prefs->wallpaper_filename : "none");
|
||||
gnome_config_set_int ("/Background/Default/wallpaperAlign",
|
||||
prefs->wallpaper_type);
|
||||
|
||||
gnome_config_set_int ("/Background/Default/wallpapers",
|
||||
g_slist_length (prefs->wallpapers));
|
||||
|
||||
for (i = 1, item = prefs->wallpapers; item; i++, item = item->next) {
|
||||
wp = g_strdup_printf ("/Background/Default/wallpaper%d", i);
|
||||
gnome_config_set_string (wp, (char *)item->data);
|
||||
g_free (wp);
|
||||
}
|
||||
|
||||
gnome_config_set_bool ("/Background/Default/autoApply", prefs->auto_apply);
|
||||
gnome_config_set_bool ("/Background/Default/adjustOpacity", prefs->adjust_opacity);
|
||||
gnome_config_set_int ("/Background/Default/opacity",
|
||||
prefs->opacity);
|
||||
|
||||
gnome_config_sync ();
|
||||
}
|
||||
|
||||
void
|
||||
preferences_changed (Preferences *prefs)
|
||||
{
|
||||
if (prefs->frozen) return;
|
||||
|
||||
if (prefs->timeout_id)
|
||||
gtk_timeout_remove (prefs->timeout_id);
|
||||
|
||||
if (prefs->auto_apply)
|
||||
prefs->timeout_id =
|
||||
gtk_timeout_add (2000, (GtkFunction) apply_timeout_cb,
|
||||
prefs);
|
||||
|
||||
applier_apply_prefs (applier, prefs, FALSE, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
preferences_apply_now (Preferences *prefs)
|
||||
{
|
||||
g_return_if_fail (prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs));
|
||||
|
||||
if (prefs->timeout_id)
|
||||
gtk_timeout_remove (prefs->timeout_id);
|
||||
|
||||
prefs->timeout_id = 0;
|
||||
|
||||
applier_apply_prefs (applier, prefs, TRUE, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
preferences_apply_preview (Preferences *prefs)
|
||||
{
|
||||
g_return_if_fail (prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs));
|
||||
|
||||
applier_apply_prefs (applier, prefs, FALSE, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
preferences_freeze (Preferences *prefs)
|
||||
{
|
||||
prefs->frozen = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
preferences_thaw (Preferences *prefs)
|
||||
{
|
||||
prefs->frozen = FALSE;
|
||||
}
|
||||
|
||||
Preferences *
|
||||
preferences_read_xml (xmlDocPtr xml_doc)
|
||||
{
|
||||
Preferences *prefs;
|
||||
xmlNodePtr root_node, node;
|
||||
char *str;
|
||||
|
||||
prefs = PREFERENCES (preferences_new ());
|
||||
|
||||
root_node = xmlDocGetRootElement (xml_doc);
|
||||
|
||||
if (strcmp (root_node->name, "background-properties"))
|
||||
return NULL;
|
||||
|
||||
prefs->wallpaper_enabled = FALSE;
|
||||
prefs->gradient_enabled = FALSE;
|
||||
prefs->orientation = ORIENTATION_VERT;
|
||||
|
||||
if (prefs->color1) {
|
||||
gdk_color_free (prefs->color1);
|
||||
prefs->color1 = NULL;
|
||||
}
|
||||
|
||||
if (prefs->color2) {
|
||||
gdk_color_free (prefs->color2);
|
||||
prefs->color2 = NULL;
|
||||
}
|
||||
|
||||
for (node = root_node->childs; node; node = node->next) {
|
||||
if (!strcmp (node->name, "bg-color1"))
|
||||
prefs->color1 = read_color_from_string
|
||||
(xmlNodeGetContent (node));
|
||||
else if (!strcmp (node->name, "bg-color2"))
|
||||
prefs->color2 = read_color_from_string
|
||||
(xmlNodeGetContent (node));
|
||||
else if (!strcmp (node->name, "enabled"))
|
||||
prefs->enabled = TRUE;
|
||||
else if (!strcmp (node->name, "wallpaper"))
|
||||
prefs->wallpaper_enabled = TRUE;
|
||||
else if (!strcmp (node->name, "gradient"))
|
||||
prefs->gradient_enabled = TRUE;
|
||||
else if (!strcmp (node->name, "orientation")) {
|
||||
str = xmlNodeGetContent (node);
|
||||
|
||||
if (!g_strcasecmp (str, "horizontal"))
|
||||
prefs->orientation = ORIENTATION_HORIZ;
|
||||
else if (!g_strcasecmp (str, "vertical"))
|
||||
prefs->orientation = ORIENTATION_VERT;
|
||||
}
|
||||
else if (!strcmp (node->name, "wallpaper-type"))
|
||||
prefs->wallpaper_type = xml_read_int (node, NULL);
|
||||
else if (!strcmp (node->name, "wallpaper-filename"))
|
||||
prefs->wallpaper_filename =
|
||||
g_strdup (xmlNodeGetContent (node));
|
||||
else if (!strcmp (node->name, "wallpaper-sel-path"))
|
||||
prefs->wallpaper_sel_path =
|
||||
g_strdup (xmlNodeGetContent (node));
|
||||
else if (!strcmp (node->name, "auto-apply"))
|
||||
prefs->auto_apply = TRUE;
|
||||
else if (!strcmp (node->name, "adjust-opacity"))
|
||||
prefs->adjust_opacity = TRUE;
|
||||
else if (!strcmp (node->name, "opacity"))
|
||||
prefs->opacity = xml_read_int (node, NULL);
|
||||
}
|
||||
|
||||
return prefs;
|
||||
}
|
||||
|
||||
xmlDocPtr
|
||||
preferences_write_xml (Preferences *prefs)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr node;
|
||||
char tmp[16];
|
||||
|
||||
doc = xmlNewDoc ("1.0");
|
||||
|
||||
node = xmlNewDocNode (doc, NULL, "background-properties", NULL);
|
||||
|
||||
snprintf (tmp, sizeof (tmp), "#%02x%02x%02x",
|
||||
prefs->color1->red >> 8,
|
||||
prefs->color1->green >> 8,
|
||||
prefs->color1->blue >> 8);
|
||||
xmlNewChild (node, NULL, "bg-color1", tmp);
|
||||
|
||||
snprintf (tmp, sizeof (tmp), "#%02x%02x%02x",
|
||||
prefs->color2->red >> 8,
|
||||
prefs->color2->green >> 8,
|
||||
prefs->color2->blue >> 8);
|
||||
xmlNewChild (node, NULL, "bg-color2", tmp);
|
||||
|
||||
if (prefs->enabled)
|
||||
xmlNewChild (node, NULL, "enabled", NULL);
|
||||
|
||||
if (prefs->wallpaper_enabled)
|
||||
xmlNewChild (node, NULL, "wallpaper", NULL);
|
||||
|
||||
if (prefs->gradient_enabled)
|
||||
xmlNewChild (node, NULL, "gradient", NULL);
|
||||
|
||||
xmlNewChild (node, NULL, "orientation",
|
||||
(prefs->orientation == ORIENTATION_VERT) ?
|
||||
"vertical" : "horizontal");
|
||||
|
||||
xmlAddChild (node, xml_write_int ("wallpaper-type", NULL,
|
||||
prefs->wallpaper_type));
|
||||
|
||||
xmlNewChild (node, NULL, "wallpaper-filename",
|
||||
prefs->wallpaper_filename);
|
||||
xmlNewChild (node, NULL, "wallpaper-sel-path",
|
||||
prefs->wallpaper_sel_path);
|
||||
|
||||
if (prefs->auto_apply)
|
||||
xmlNewChild (node, NULL, "auto-apply", NULL);
|
||||
|
||||
if (prefs->adjust_opacity)
|
||||
xmlNewChild (node, NULL, "adjust-opacity", NULL);
|
||||
xmlAddChild (node, xml_write_int ("opacity", NULL,
|
||||
prefs->opacity));
|
||||
|
||||
xmlDocSetRootElement (doc, node);
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
/* Read a numeric value from a node */
|
||||
|
||||
static gint
|
||||
xml_read_int (xmlNodePtr node, char *propname)
|
||||
{
|
||||
char *text;
|
||||
|
||||
if (propname == NULL)
|
||||
text = xmlNodeGetContent (node);
|
||||
else
|
||||
text = xmlGetProp (node, propname);
|
||||
|
||||
if (text == NULL)
|
||||
return 0;
|
||||
else
|
||||
return atoi (text);
|
||||
}
|
||||
|
||||
/* Write out a numeric value in a node */
|
||||
|
||||
static xmlNodePtr
|
||||
xml_write_int (gchar *name, gchar *propname, gint number)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
gchar *str;
|
||||
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
str = g_strdup_printf ("%d", number);
|
||||
|
||||
node = xmlNewNode (NULL, name);
|
||||
|
||||
if (propname == NULL)
|
||||
xmlNodeSetContent (node, str);
|
||||
else
|
||||
xmlSetProp (node, propname, str);
|
||||
|
||||
g_free (str);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static gint
|
||||
apply_timeout_cb (Preferences *prefs)
|
||||
{
|
||||
preferences_apply_now (prefs);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GdkColor *
|
||||
read_color_from_string (gchar *string)
|
||||
{
|
||||
GdkColor *color;
|
||||
gint32 rgb;
|
||||
|
||||
color = g_new0 (GdkColor, 1);
|
||||
|
||||
gdk_color_parse (string, color);
|
||||
rgb = ((color->red >> 8) << 16) ||
|
||||
((color->green >> 8) << 8) ||
|
||||
(color->blue >> 8);
|
||||
color->pixel = xlib_rgb_xpixel_from_rgb (rgb);
|
||||
|
||||
return color;
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* preferences.h
|
||||
* Copyright (C) 2000 Helix Code, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@helixcode.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __PREFERENCES_H
|
||||
#define __PREFERENCES_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <tree.h>
|
||||
|
||||
#define PREFERENCES(obj) GTK_CHECK_CAST (obj, preferences_get_type (), Preferences)
|
||||
#define PREFERENCES_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, preferences_get_type (), PreferencesClass)
|
||||
#define IS_PREFERENCES(obj) GTK_CHECK_TYPE (obj, preferences_get_type ())
|
||||
|
||||
typedef struct _Preferences Preferences;
|
||||
typedef struct _PreferencesClass PreferencesClass;
|
||||
|
||||
typedef enum _orientation_t {
|
||||
ORIENTATION_HORIZ, ORIENTATION_VERT
|
||||
} orientation_t;
|
||||
|
||||
typedef enum _wallpaper_type_t {
|
||||
WPTYPE_TILED, WPTYPE_CENTERED, WPTYPE_SCALED_ASPECT,
|
||||
WPTYPE_SCALED, WPTYPE_EMBOSSED
|
||||
} wallpaper_type_t;
|
||||
|
||||
struct _Preferences
|
||||
{
|
||||
GtkObject object;
|
||||
|
||||
gboolean frozen;
|
||||
gboolean auto_apply;
|
||||
guint timeout_id;
|
||||
|
||||
gboolean enabled;
|
||||
gboolean gradient_enabled;
|
||||
gboolean wallpaper_enabled;
|
||||
orientation_t orientation;
|
||||
wallpaper_type_t wallpaper_type;
|
||||
|
||||
GdkColor *color1;
|
||||
GdkColor *color2;
|
||||
|
||||
gchar *wallpaper_filename;
|
||||
gchar *wallpaper_sel_path;
|
||||
|
||||
GSList *wallpapers;
|
||||
|
||||
gboolean adjust_opacity;
|
||||
gint opacity;
|
||||
};
|
||||
|
||||
struct _PreferencesClass
|
||||
{
|
||||
GtkObjectClass klass;
|
||||
};
|
||||
|
||||
guint preferences_get_type (void);
|
||||
|
||||
GtkObject *preferences_new (void);
|
||||
GtkObject *preferences_clone (Preferences *prefs);
|
||||
void preferences_destroy (GtkObject *object);
|
||||
|
||||
void preferences_load (Preferences *prefs);
|
||||
void preferences_save (Preferences *prefs);
|
||||
void preferences_changed (Preferences *prefs);
|
||||
void preferences_apply_now (Preferences *prefs);
|
||||
void preferences_apply_preview (Preferences *prefs);
|
||||
|
||||
void preferences_freeze (Preferences *prefs);
|
||||
void preferences_thaw (Preferences *prefs);
|
||||
|
||||
Preferences *preferences_read_xml (xmlDocPtr xml_doc);
|
||||
xmlDocPtr preferences_write_xml (Preferences *prefs);
|
||||
|
||||
#endif /* __PREFERENCES_H */
|
||||
@@ -1,761 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* prefs-widget.c
|
||||
* Copyright (C) 2000 Helix Code, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@helixcode.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "prefs-widget.h"
|
||||
#include "applier.h"
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf-xlibrgb.h>
|
||||
|
||||
#define WID(str) (glade_xml_get_widget (prefs_widget->dialog_data, str))
|
||||
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_PREFERENCES
|
||||
};
|
||||
|
||||
static CappletWidgetClass *parent_class;
|
||||
|
||||
static void
|
||||
set_background_controls_sensitive (PrefsWidget *prefs_widget, gboolean s)
|
||||
{
|
||||
gtk_widget_set_sensitive (WID ("color_frame"), s);
|
||||
gtk_widget_set_sensitive (WID ("wallpaper_frame"), s);
|
||||
gtk_widget_set_sensitive (WID ("adjust_opacity_toggle"), s);
|
||||
gtk_widget_set_sensitive (WID ("opacity_box"), s && prefs_widget->prefs->adjust_opacity);
|
||||
gtk_widget_set_sensitive (WID ("auto_apply"), s);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
prefs_widget_new (Preferences *prefs)
|
||||
{
|
||||
g_return_val_if_fail (prefs == NULL || IS_PREFERENCES (prefs), NULL);
|
||||
|
||||
return gtk_widget_new (prefs_widget_get_type (),
|
||||
"preferences", prefs,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
prefs_widget_set_preferences (PrefsWidget *prefs_widget, Preferences *prefs)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs));
|
||||
|
||||
gtk_object_set (GTK_OBJECT (prefs_widget), "preferences", prefs, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
wallpaper_entry_changed_cb (GtkWidget *e, PrefsWidget *prefs_widget)
|
||||
{
|
||||
char *filename;
|
||||
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
|
||||
g_free (prefs_widget->prefs->wallpaper_filename);
|
||||
|
||||
prefs_widget->prefs->wallpaper_filename =
|
||||
g_strdup (gtk_object_get_data (GTK_OBJECT (e), "wallpaper_filename"));
|
||||
|
||||
prefs_widget->prefs->wallpaper_enabled =
|
||||
prefs_widget->prefs->wallpaper_filename &&
|
||||
g_file_exists (prefs_widget->prefs->wallpaper_filename);
|
||||
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
append_wallpaper (GtkMenu *menu, char *label, char *path, PrefsWidget *prefs_widget)
|
||||
{
|
||||
GtkWidget *item;
|
||||
|
||||
item = gtk_menu_item_new_with_label (label);
|
||||
if (path)
|
||||
gtk_object_set_data (GTK_OBJECT (item), "wallpaper_filename", path);
|
||||
gtk_signal_connect (GTK_OBJECT (item), "activate",
|
||||
GTK_SIGNAL_FUNC (wallpaper_entry_changed_cb),
|
||||
prefs_widget);
|
||||
|
||||
gtk_menu_append (menu, item);
|
||||
}
|
||||
|
||||
static void
|
||||
read_preferences (PrefsWidget *prefs_widget, Preferences *prefs)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkAdjustment *adjustment;
|
||||
GtkWidget *menu;
|
||||
gint i;
|
||||
gint thing;
|
||||
GSList *item;
|
||||
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs));
|
||||
|
||||
gnome_color_picker_set_i16
|
||||
(GNOME_COLOR_PICKER (WID ("color1_select")),
|
||||
prefs->color1->red, prefs->color1->green,
|
||||
prefs->color1->blue, 0xffff);
|
||||
gnome_color_picker_set_i16
|
||||
(GNOME_COLOR_PICKER (WID ("color2_select")),
|
||||
prefs->color2->red, prefs->color2->green,
|
||||
prefs->color2->blue, 0xffff);
|
||||
|
||||
gtk_widget_set_sensitive (
|
||||
glade_xml_get_widget (prefs_widget->dialog_data,
|
||||
"color2_select"),
|
||||
prefs_widget->prefs->gradient_enabled);
|
||||
|
||||
thing = prefs->gradient_enabled
|
||||
? (prefs->orientation == ORIENTATION_VERT
|
||||
? 1 : 2) : 0;
|
||||
|
||||
gtk_option_menu_set_history (GTK_OPTION_MENU (WID ("color_option")), thing);
|
||||
|
||||
widget = WID ("wallpaper_entry");
|
||||
|
||||
#if 0
|
||||
if (prefs->wallpaper_sel_path)
|
||||
gnome_file_entry_set_default_path
|
||||
(GNOME_FILE_ENTRY (widget),
|
||||
prefs->wallpaper_sel_path);
|
||||
#endif
|
||||
|
||||
menu = gtk_menu_new ();
|
||||
append_wallpaper (GTK_MENU (menu), _("(None)"), NULL, prefs_widget);
|
||||
|
||||
#warning FIXME: add a small snapshot of the image? that would rule.
|
||||
for (thing = 0, i = 1, item = prefs->wallpapers; item; i++, item = item->next) {
|
||||
append_wallpaper (GTK_MENU (menu), g_basename (item->data),
|
||||
item->data, prefs_widget);
|
||||
if (prefs->wallpaper_filename &&
|
||||
!strcmp (prefs->wallpaper_filename, item->data))
|
||||
thing = i;
|
||||
}
|
||||
|
||||
if (!thing && prefs->wallpaper_filename) {
|
||||
thing = 1;
|
||||
append_wallpaper (GTK_MENU (menu),
|
||||
g_basename (prefs->wallpaper_filename),
|
||||
prefs->wallpaper_filename, prefs_widget);
|
||||
}
|
||||
|
||||
gtk_option_menu_set_history (GTK_OPTION_MENU (WID ("wp_effect_option")),
|
||||
prefs->wallpaper_type);
|
||||
|
||||
gtk_option_menu_set_menu (GTK_OPTION_MENU (WID ("wp_file_option")), menu);
|
||||
gtk_option_menu_set_history (GTK_OPTION_MENU (WID ("wp_file_option")), thing);
|
||||
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("disable_toggle")),
|
||||
prefs->enabled);
|
||||
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
|
||||
(WID ("auto_apply")),
|
||||
prefs->auto_apply);
|
||||
|
||||
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
|
||||
(WID ("adjust_opacity_toggle")),
|
||||
prefs->adjust_opacity);
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (WID ("opacity_box")),
|
||||
prefs->adjust_opacity && prefs->enabled);
|
||||
|
||||
adjustment = gtk_range_get_adjustment
|
||||
(GTK_RANGE (WID ("opacity_adjust")));
|
||||
gtk_adjustment_set_value (adjustment, prefs->opacity);
|
||||
|
||||
preferences_apply_preview (prefs);
|
||||
}
|
||||
|
||||
static void
|
||||
color1_select_color_set_cb (GnomeColorPicker *cp, guint r, guint g,
|
||||
guint b, guint a, PrefsWidget *prefs_widget)
|
||||
{
|
||||
guint32 rgb;
|
||||
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
|
||||
prefs_widget->prefs->color1->red = r;
|
||||
prefs_widget->prefs->color1->green = g;
|
||||
prefs_widget->prefs->color1->blue = b;
|
||||
rgb = ((r >> 8) << 16) || ((g >> 8) << 8) || (b >> 8);
|
||||
prefs_widget->prefs->color1->pixel = xlib_rgb_xpixel_from_rgb (rgb);
|
||||
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
color2_select_color_set_cb (GnomeColorPicker *cp, guint r, guint g,
|
||||
guint b, guint a, PrefsWidget *prefs_widget)
|
||||
{
|
||||
guint32 rgb;
|
||||
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
|
||||
prefs_widget->prefs->color2->red = r;
|
||||
prefs_widget->prefs->color2->green = g;
|
||||
prefs_widget->prefs->color2->blue = b;
|
||||
rgb = ((r >> 8) << 16) || ((g >> 8) << 8) || (b >> 8);
|
||||
prefs_widget->prefs->color2->pixel = xlib_rgb_xpixel_from_rgb (rgb);
|
||||
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
solid_select_toggled_cb (GtkToggleButton *tb, PrefsWidget *prefs_widget)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
|
||||
if (gtk_toggle_button_get_active (tb)) {
|
||||
prefs_widget->prefs->gradient_enabled = FALSE;
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
}
|
||||
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gradient_select_toggled_cb (GtkToggleButton *tb, PrefsWidget *prefs_widget)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
|
||||
if (gtk_toggle_button_get_active (tb)) {
|
||||
prefs_widget->prefs->gradient_enabled = TRUE;
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
}
|
||||
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
vertical_select_toggled_cb (GtkToggleButton *tb, PrefsWidget *prefs_widget)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
|
||||
if (gtk_toggle_button_get_active (tb)) {
|
||||
prefs_widget->prefs->orientation = ORIENTATION_VERT;
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
}
|
||||
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
horizontal_select_toggled_cb (GtkToggleButton *tb, PrefsWidget *prefs_widget)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
|
||||
if (gtk_toggle_button_get_active (tb)) {
|
||||
prefs_widget->prefs->orientation = ORIENTATION_HORIZ;
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
}
|
||||
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
tiled_select_toggled_cb (GtkToggleButton *tb, PrefsWidget *prefs_widget)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
|
||||
if (gtk_toggle_button_get_active (tb)) {
|
||||
prefs_widget->prefs->wallpaper_type = WPTYPE_TILED;
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
}
|
||||
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
centered_select_toggled_cb (GtkToggleButton *tb, PrefsWidget *prefs_widget)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
|
||||
if (gtk_toggle_button_get_active (tb)) {
|
||||
prefs_widget->prefs->wallpaper_type = WPTYPE_CENTERED;
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
}
|
||||
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
scaled_aspect_select_toggled_cb (GtkToggleButton *tb,
|
||||
PrefsWidget *prefs_widget)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
|
||||
if (gtk_toggle_button_get_active (tb)) {
|
||||
prefs_widget->prefs->wallpaper_type = WPTYPE_SCALED_ASPECT;
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
}
|
||||
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
scaled_select_toggled_cb (GtkToggleButton *tb, PrefsWidget *prefs_widget)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
|
||||
if (gtk_toggle_button_get_active (tb)) {
|
||||
prefs_widget->prefs->wallpaper_type = WPTYPE_SCALED;
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
}
|
||||
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
disable_toggled_cb (GtkToggleButton *tb, PrefsWidget *prefs_widget)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
|
||||
prefs_widget->prefs->enabled = gtk_toggle_button_get_active (tb);
|
||||
|
||||
set_background_controls_sensitive (prefs_widget,
|
||||
prefs_widget->prefs->enabled);
|
||||
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
color_effect_cb (GtkWidget *w, PrefsWidget *prefs_widget)
|
||||
{
|
||||
switch (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (w), "index"))) {
|
||||
case 0:
|
||||
prefs_widget->prefs->gradient_enabled = FALSE;
|
||||
break;
|
||||
case 1:
|
||||
prefs_widget->prefs->gradient_enabled = TRUE;
|
||||
prefs_widget->prefs->orientation = ORIENTATION_VERT;
|
||||
break;
|
||||
case 2:
|
||||
prefs_widget->prefs->gradient_enabled = TRUE;
|
||||
prefs_widget->prefs->orientation = ORIENTATION_HORIZ;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive (
|
||||
glade_xml_get_widget (prefs_widget->dialog_data,
|
||||
"color2_select"),
|
||||
prefs_widget->prefs->gradient_enabled);
|
||||
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
wallpaper_effect_cb (GtkWidget *w, PrefsWidget *prefs_widget)
|
||||
{
|
||||
gint i;
|
||||
|
||||
i = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (w), "index"));
|
||||
|
||||
prefs_widget->prefs->wallpaper_type = i;
|
||||
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_preview(GtkWidget *widget, PrefsWidget *prefs)
|
||||
{
|
||||
char *p;
|
||||
GList *l;
|
||||
GtkWidget *pp = NULL;
|
||||
GdkImlibImage *im;
|
||||
int w,h;
|
||||
GtkWidget *frame;
|
||||
GtkFileSelection *fs;
|
||||
|
||||
g_return_if_fail (widget != NULL);
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
frame = gtk_object_get_data(GTK_OBJECT(widget),"frame");
|
||||
fs = gtk_object_get_data(GTK_OBJECT(frame),"fs");
|
||||
|
||||
if((l = gtk_container_children(GTK_CONTAINER(frame))) != NULL) {
|
||||
pp = l->data;
|
||||
g_list_free(l);
|
||||
}
|
||||
|
||||
if(pp)
|
||||
gtk_widget_destroy(pp);
|
||||
|
||||
p = gtk_file_selection_get_filename(fs);
|
||||
if(!p || !g_file_test (p,G_FILE_TEST_ISLINK|G_FILE_TEST_ISFILE) ||
|
||||
!(im = gdk_imlib_load_image (p)))
|
||||
return;
|
||||
|
||||
w = im->rgb_width;
|
||||
h = im->rgb_height;
|
||||
if(w>h) {
|
||||
if(w>100) {
|
||||
h = h*(100.0/w);
|
||||
w = 100;
|
||||
}
|
||||
} else {
|
||||
if(h>100) {
|
||||
w = w*(100.0/h);
|
||||
h = 100;
|
||||
}
|
||||
}
|
||||
pp = gnome_pixmap_new_from_imlib_at_size (im, w, h);
|
||||
gtk_widget_show(pp);
|
||||
gtk_container_add(GTK_CONTAINER(frame),pp);
|
||||
|
||||
gdk_imlib_destroy_image(im);
|
||||
}
|
||||
|
||||
static void
|
||||
browse_button_cb (GtkWidget *w, PrefsWidget *prefs_widget)
|
||||
{
|
||||
GtkWidget *hbox, *widg;
|
||||
GtkFileSelection *filesel;
|
||||
|
||||
if (prefs_widget->filesel) {
|
||||
gdk_window_show (prefs_widget->filesel->window);
|
||||
gdk_window_raise (prefs_widget->filesel->window);
|
||||
return;
|
||||
}
|
||||
|
||||
prefs_widget->filesel = gtk_file_selection_new (_("Wallpaper Selection"));
|
||||
filesel = GTK_FILE_SELECTION (prefs_widget->filesel);
|
||||
hbox = filesel->file_list;
|
||||
|
||||
do {
|
||||
hbox = hbox->parent;
|
||||
if(!hbox) {
|
||||
g_warning(_("Can't find an hbox, using a normal file "
|
||||
"selection"));
|
||||
goto signal_setup;
|
||||
}
|
||||
} while (!GTK_IS_HBOX (hbox));
|
||||
|
||||
widg = gtk_frame_new (_("Preview"));
|
||||
gtk_widget_show (widg);
|
||||
gtk_box_pack_end (GTK_BOX (hbox), widg, FALSE, FALSE, 0);
|
||||
gtk_widget_set_usize (widg, 110, 110);
|
||||
|
||||
gtk_object_set_data (GTK_OBJECT (widg), "fs", filesel);
|
||||
gtk_object_set_data (GTK_OBJECT (filesel->file_list), "frame", widg);
|
||||
gtk_object_set_data (GTK_OBJECT (filesel->selection_entry), "frame", widg);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (filesel->file_list),"select_row",
|
||||
GTK_SIGNAL_FUNC (setup_preview), prefs_widget);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (filesel->selection_entry), "changed",
|
||||
GTK_SIGNAL_FUNC (setup_preview), prefs_widget);
|
||||
|
||||
|
||||
signal_setup:
|
||||
#if 0
|
||||
if (wpFileSelName)
|
||||
gtk_file_selection_set_filename (filesel, wpFileSelName);
|
||||
else if (origState.wpFileName)
|
||||
gtk_file_selection_set_filename (filesel, origState.wpFileName);
|
||||
#endif
|
||||
gtk_signal_connect (GTK_OBJECT (filesel), "destroy",
|
||||
GTK_SIGNAL_FUNC (gtk_widget_destroyed),
|
||||
&prefs_widget->filesel);
|
||||
#if 0
|
||||
gtk_signal_connect (GTK_OBJECT (filesel->ok_button), "clicked",
|
||||
GTK_SIGNAL_FUNC (wp_selection_ok), prefs_widget);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (filesel->cancel_button), "clicked",
|
||||
GTK_SIGNAL_FUNC (wp_selection_cancel), prefs_widget);
|
||||
#endif
|
||||
gtk_widget_show (filesel);
|
||||
}
|
||||
|
||||
static void
|
||||
auto_apply_toggled_cb (GtkToggleButton *tb, PrefsWidget *prefs_widget)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
|
||||
if (gtk_toggle_button_get_active (tb))
|
||||
prefs_widget->prefs->auto_apply = TRUE;
|
||||
else
|
||||
prefs_widget->prefs->auto_apply = FALSE;
|
||||
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
adjust_opacity_toggled_cb (GtkToggleButton *tb, PrefsWidget *prefs_widget)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
|
||||
prefs_widget->prefs->adjust_opacity = gtk_toggle_button_get_active (tb);
|
||||
gtk_widget_set_sensitive (WID ("opacity_box"), prefs_widget->prefs->enabled && prefs_widget->prefs->adjust_opacity);
|
||||
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
opacity_adjust_changed_cb (GtkAdjustment *adjustment,
|
||||
PrefsWidget *prefs_widget)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
prefs_widget_init (PrefsWidget *prefs_widget)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkAdjustment *adjustment;
|
||||
GList *node;
|
||||
int i;
|
||||
|
||||
prefs_widget->dialog_data =
|
||||
glade_xml_new (GLADE_DATADIR "/background-properties.glade",
|
||||
"prefs_widget");
|
||||
|
||||
widget = glade_xml_get_widget (prefs_widget->dialog_data,
|
||||
"prefs_widget");
|
||||
gtk_container_add (GTK_CONTAINER (prefs_widget), widget);
|
||||
|
||||
widget = glade_xml_get_widget (prefs_widget->dialog_data,
|
||||
"monitor_frame");
|
||||
|
||||
prefs_widget->preview = applier_class_get_preview_widget ();
|
||||
gtk_container_add (GTK_CONTAINER (widget), prefs_widget->preview);
|
||||
|
||||
glade_xml_signal_connect_data (prefs_widget->dialog_data,
|
||||
"color1_select_color_set_cb",
|
||||
color1_select_color_set_cb,
|
||||
prefs_widget);
|
||||
glade_xml_signal_connect_data (prefs_widget->dialog_data,
|
||||
"color2_select_color_set_cb",
|
||||
color2_select_color_set_cb,
|
||||
prefs_widget);
|
||||
glade_xml_signal_connect_data (prefs_widget->dialog_data,
|
||||
"disable_toggled_cb",
|
||||
disable_toggled_cb,
|
||||
prefs_widget);
|
||||
glade_xml_signal_connect_data (prefs_widget->dialog_data,
|
||||
"browse_button_cb",
|
||||
browse_button_cb,
|
||||
prefs_widget);
|
||||
glade_xml_signal_connect_data (prefs_widget->dialog_data,
|
||||
"auto_apply_toggled_cb",
|
||||
auto_apply_toggled_cb,
|
||||
prefs_widget);
|
||||
glade_xml_signal_connect_data (prefs_widget->dialog_data,
|
||||
"adjust_opacity_toggled_cb",
|
||||
adjust_opacity_toggled_cb,
|
||||
prefs_widget);
|
||||
|
||||
/*adjustment = gtk_range_get_adjustment (GTK_RANGE (WID ("opacity_adjust")));*/
|
||||
adjustment = gtk_adjustment_new (100.0, 0.0, 100.0, 1.0, 10.0, 10.0);
|
||||
gtk_range_set_adjustment (GTK_RANGE (WID ("opacity_adjust")), adjustment);
|
||||
gtk_signal_connect (GTK_OBJECT (adjustment), "value-changed",
|
||||
GTK_SIGNAL_FUNC (opacity_adjust_changed_cb),
|
||||
prefs_widget);
|
||||
|
||||
|
||||
widget = WID ("color_option");
|
||||
node = GTK_MENU_SHELL (gtk_option_menu_get_menu (GTK_OPTION_MENU (widget)))->children;
|
||||
|
||||
for (i=0; node; i++, node = node->next) {
|
||||
gtk_signal_connect (GTK_OBJECT (node->data), "activate",
|
||||
GTK_SIGNAL_FUNC (color_effect_cb),
|
||||
prefs_widget);
|
||||
|
||||
gtk_object_set_data (GTK_OBJECT (node->data), "index",
|
||||
GINT_TO_POINTER (i));
|
||||
}
|
||||
|
||||
|
||||
widget = WID ("wp_effect_option");
|
||||
node = GTK_MENU_SHELL (gtk_option_menu_get_menu (GTK_OPTION_MENU (widget)))->children;
|
||||
|
||||
for (i=0; node; i++, node = node->next) {
|
||||
gtk_signal_connect (GTK_OBJECT (node->data), "activate",
|
||||
GTK_SIGNAL_FUNC (wallpaper_effect_cb),
|
||||
prefs_widget);
|
||||
|
||||
gtk_object_set_data (GTK_OBJECT (node->data), "index",
|
||||
GINT_TO_POINTER (i));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
prefs_widget_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
PrefsWidget *prefs_widget;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (object));
|
||||
|
||||
prefs_widget = PREFS_WIDGET (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_PREFERENCES:
|
||||
if (prefs_widget->prefs)
|
||||
gtk_object_unref (GTK_OBJECT (prefs_widget->prefs));
|
||||
|
||||
prefs_widget->prefs = GTK_VALUE_POINTER (*arg);
|
||||
|
||||
if (prefs_widget->prefs) {
|
||||
gtk_object_ref (GTK_OBJECT (prefs_widget->prefs));
|
||||
read_preferences (prefs_widget, prefs_widget->prefs);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Bad argument set");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
prefs_widget_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
PrefsWidget *prefs_widget;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (object));
|
||||
|
||||
prefs_widget = PREFS_WIDGET (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_PREFERENCES:
|
||||
GTK_VALUE_POINTER (*arg) = prefs_widget->prefs;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Bad argument get");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
prefs_widget_class_init (PrefsWidgetClass *class)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
|
||||
gtk_object_add_arg_type ("PrefsWidget::preferences",
|
||||
GTK_TYPE_POINTER,
|
||||
GTK_ARG_READWRITE,
|
||||
ARG_PREFERENCES);
|
||||
|
||||
object_class = GTK_OBJECT_CLASS (class);
|
||||
object_class->set_arg = prefs_widget_set_arg;
|
||||
object_class->get_arg = prefs_widget_get_arg;
|
||||
|
||||
parent_class = CAPPLET_WIDGET_CLASS
|
||||
(gtk_type_class (capplet_widget_get_type ()));
|
||||
}
|
||||
|
||||
|
||||
guint
|
||||
prefs_widget_get_type (void)
|
||||
{
|
||||
static guint prefs_widget_type = 0;
|
||||
|
||||
if (!prefs_widget_type) {
|
||||
GtkTypeInfo prefs_widget_info = {
|
||||
"PrefsWidget",
|
||||
sizeof (PrefsWidget),
|
||||
sizeof (PrefsWidgetClass),
|
||||
(GtkClassInitFunc) prefs_widget_class_init,
|
||||
(GtkObjectInitFunc) prefs_widget_init,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL
|
||||
};
|
||||
|
||||
prefs_widget_type =
|
||||
gtk_type_unique (capplet_widget_get_type (),
|
||||
&prefs_widget_info);
|
||||
}
|
||||
|
||||
return prefs_widget_type;
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* prefs-widget.h
|
||||
* Copyright (C) 2000 Helix Code, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@helixcode.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __PREFS_WIDGET_H
|
||||
#define __PREFS_WIDGET_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glade/glade.h>
|
||||
#include <capplet-widget.h>
|
||||
|
||||
#include "preferences.h"
|
||||
|
||||
#define PREFS_WIDGET(obj) GTK_CHECK_CAST (obj, prefs_widget_get_type (), PrefsWidget)
|
||||
#define PREFS_WIDGET_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, prefs_widget_get_type (), PrefsWidgetClass)
|
||||
#define IS_PREFS_WIDGET(obj) GTK_CHECK_TYPE (obj, prefs_widget_get_type ())
|
||||
|
||||
typedef struct _PrefsWidget PrefsWidget;
|
||||
typedef struct _PrefsWidgetClass PrefsWidgetClass;
|
||||
|
||||
struct _PrefsWidget
|
||||
{
|
||||
CappletWidget capplet_widget;
|
||||
|
||||
Preferences *prefs;
|
||||
GladeXML *dialog_data;
|
||||
GtkWidget *preview;
|
||||
|
||||
GtkWidget *menu;
|
||||
GtkWidget *filesel;
|
||||
};
|
||||
|
||||
struct _PrefsWidgetClass
|
||||
{
|
||||
CappletWidgetClass parent_class;
|
||||
};
|
||||
|
||||
guint prefs_widget_get_type (void);
|
||||
|
||||
GtkWidget *prefs_widget_new (Preferences *prefs);
|
||||
|
||||
void prefs_widget_set_preferences (PrefsWidget *prefs_widget,
|
||||
Preferences *prefs);
|
||||
|
||||
#endif /* __PREFS_WIDGET_H */
|
||||
@@ -2,4 +2,5 @@ Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
.libs
|
||||
nautilus-mime-type-capplet
|
||||
file-types-capplet
|
||||
file-types-capplet.desktop
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
INCLUDES = -I. \
|
||||
-I$(top_srcdir) \
|
||||
-I$(srcdir) \
|
||||
NULL =
|
||||
|
||||
SUBDIRS = libuuid
|
||||
|
||||
INCLUDES = -I. \
|
||||
-I$(top_srcdir) \
|
||||
-I$(srcdir) \
|
||||
-I$(top_srcdir)/intl -I$(top_builddir)/intl \
|
||||
-I$(top_srcdir)/libgnomevfs \
|
||||
$(CAPPLET_INCLUDEDIR) \
|
||||
@@ -9,36 +13,49 @@ INCLUDES = -I. \
|
||||
$(GTK_CFLAGS) \
|
||||
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
|
||||
-I$(includedir) \
|
||||
$(VFS_CFLAGS) $(WERROR)
|
||||
$(VFS_CFLAGS) $(WERROR) \
|
||||
$(NULL)
|
||||
|
||||
bin_PROGRAMS = nautilus-mime-type-capplet
|
||||
|
||||
nautilus_mime_type_capplet_SOURCES = \
|
||||
bin_PROGRAMS = file-types-capplet
|
||||
|
||||
file_types_capplet_SOURCES = \
|
||||
nautilus-mime-type-capplet.h \
|
||||
nautilus-mime-type-capplet-dialogs.h \
|
||||
nautilus-mime-type-icon-entry.h \
|
||||
nautilus-mime-type-capplet.c \
|
||||
nautilus-mime-type-capplet-dialogs.c \
|
||||
nautilus-mime-type-icon-entry.c
|
||||
nautilus-mime-type-icon-entry.c \
|
||||
$(NULL)
|
||||
|
||||
nautilus_mime_type_capplet_LDADD = \
|
||||
|
||||
file_types_capplet_LDADD = \
|
||||
$(CAPPLET_LIBDIR) \
|
||||
$(CAPPLET_LIBS) \
|
||||
$(ORBIT_LIBS) \
|
||||
$(OAF_LIBS) \
|
||||
$(INTLLIBS) \
|
||||
$(top_builddir)/libgnomevfs/libgnomevfs.la \
|
||||
-lgdk_pixbuf
|
||||
-lgdk_pixbuf \
|
||||
$/libuuid/libuuid.a \
|
||||
$(NULL)
|
||||
|
||||
|
||||
sysdir = $(datadir)/control-center
|
||||
sys_DATA = nautilus-mime-type.desktop
|
||||
sysdir = $(datadir)/control-center/Documents
|
||||
sys_in_files = file-types-capplet.desktop.in
|
||||
sys_DATA = $(sys_in_files:.desktop.in=.desktop)
|
||||
|
||||
settingsdir = $(datadir)/gnome/apps/Settings
|
||||
settings_DATA = nautilus-mime-type.desktop
|
||||
settings_DATA = $(sys_DATA)
|
||||
|
||||
desktop_in_file = file-types-capplet.desktop.in
|
||||
|
||||
desktop_file = $(desktop_in_file:.desktop.in=.desktop)
|
||||
|
||||
@XML_I18N_MERGE_DESKTOP_RULE@
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(sys_DATA)
|
||||
$(sys_DATA) $(desktop_in_file)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,9 @@
|
||||
#include <libgnomevfs/gnome-vfs-mime-handlers.h>
|
||||
#include <libgnomevfs/gnome-vfs-application-registry.h>
|
||||
#include <libgnomevfs/gnome-vfs-mime-info.h>
|
||||
#include <libgnomevfs/gnome-vfs-utils.h>
|
||||
|
||||
#include "libuuid/uuid.h"
|
||||
#include "nautilus-mime-type-capplet.h"
|
||||
#include "nautilus-mime-type-capplet-dialogs.h"
|
||||
|
||||
@@ -67,7 +69,8 @@ static edit_dialog_details *edit_component_details = NULL;
|
||||
static void show_new_application_window (GtkWidget *button, GtkWidget *list);
|
||||
static void show_edit_application_window (GtkWidget *button, GtkWidget *list);
|
||||
static void delete_selected_application (GtkWidget *button, GtkWidget *list);
|
||||
static void add_item_to_application_list (GtkWidget *list, const char *name, const char *mime_type, int position);
|
||||
static void add_item_to_application_list (GtkWidget *list, const char *id, const char *name, const char *mime_type,
|
||||
gboolean user_owned, int position);
|
||||
static void find_message_label_callback (GtkWidget *widget, gpointer callback_data);
|
||||
static void find_message_label (GtkWidget *widget, const char *message);
|
||||
|
||||
@@ -138,13 +141,74 @@ application_button_toggled_callback (GtkToggleButton *button, gpointer user_data
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
insert_item (GtkList *list_widget, GtkListItem *item, int position)
|
||||
{
|
||||
GList *singleton_list;
|
||||
|
||||
g_assert (GTK_IS_LIST (list_widget));
|
||||
g_assert (GTK_IS_LIST_ITEM (item));
|
||||
|
||||
/* Due to GTK inheritance stupidity, the "Add" signal, which we
|
||||
* rely on for widget sensitivity updates, is not sent if you
|
||||
* use the GtkList API to add items. So when we add new items,
|
||||
* which always go at the end, we must use the GtkContainer API.
|
||||
*/
|
||||
if (position < 0) {
|
||||
gtk_container_add (GTK_CONTAINER (list_widget), GTK_WIDGET (item));
|
||||
} else {
|
||||
singleton_list = g_list_prepend (NULL, item);
|
||||
gtk_list_insert_items (list_widget, singleton_list, position);
|
||||
/* This looks like a leak of a singleton_list, but believe it or not
|
||||
* gtk_list takes ownership of the list of items.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
static GtkListItem *
|
||||
create_application_list_item (const char *id, const char *name, const char *mime_type,
|
||||
gboolean user_owned, GList *short_list)
|
||||
{
|
||||
GtkWidget *list_item;
|
||||
GtkWidget *hbox, *check_button, *label;
|
||||
|
||||
list_item = gtk_list_item_new ();
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_container_add (GTK_CONTAINER (list_item), hbox);
|
||||
|
||||
check_button = gtk_check_button_new ();
|
||||
gtk_box_pack_start (GTK_BOX (hbox), check_button, FALSE, FALSE, 0);
|
||||
|
||||
label = gtk_label_new (name);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
|
||||
gtk_widget_show_all (list_item);
|
||||
|
||||
/* Save ID and mime type*/
|
||||
gtk_object_set_data_full (GTK_OBJECT (check_button), "application_id", g_strdup (id), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (check_button), "mime_type", g_strdup (mime_type), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (list_item), "application_id", g_strdup (id), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (list_item), "mime_type", g_strdup (mime_type), g_free);
|
||||
gtk_object_set_data (GTK_OBJECT (list_item), "user_owned", GINT_TO_POINTER(user_owned));
|
||||
|
||||
/* Check and see if component is in preferred list */
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
|
||||
application_is_in_list (id, short_list));
|
||||
|
||||
/* Connect to toggled signal */
|
||||
gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
|
||||
GTK_SIGNAL_FUNC (application_button_toggled_callback), NULL);
|
||||
|
||||
return GTK_LIST_ITEM (list_item);
|
||||
}
|
||||
|
||||
static void
|
||||
populate_default_applications_list (GtkWidget *list, const char *mime_type)
|
||||
{
|
||||
GList *short_list, *app_list, *list_element;
|
||||
GnomeVFSMimeApplication *application;
|
||||
GtkWidget *button, *list_item;
|
||||
GtkWidget *hbox, *label;
|
||||
GtkListItem *list_item;
|
||||
|
||||
/* Get the application short list */
|
||||
short_list = gnome_vfs_mime_get_short_list_applications (mime_type);
|
||||
@@ -156,43 +220,20 @@ populate_default_applications_list (GtkWidget *list, const char *mime_type)
|
||||
application = list_element->data;
|
||||
|
||||
/* Create list item */
|
||||
list_item = gtk_list_item_new ();
|
||||
|
||||
/* Create check button */
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_container_add (GTK_CONTAINER (list_item), hbox);
|
||||
|
||||
button = gtk_check_button_new ();
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
||||
list_item = create_application_list_item (application->id, application->name,
|
||||
mime_type,
|
||||
gnome_vfs_application_is_user_owned_application (application),
|
||||
short_list);
|
||||
|
||||
label = gtk_label_new (application->name);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
insert_item (GTK_LIST (list), list_item, -1);
|
||||
|
||||
/* Add list item to list */
|
||||
gtk_container_add (GTK_CONTAINER (list), list_item);
|
||||
|
||||
/* Save ID and mime type*/
|
||||
gtk_object_set_data_full (GTK_OBJECT (button), "application_id", g_strdup (application->id), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (button), "mime_type", g_strdup (mime_type), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (list_item), "application_id", g_strdup (application->id), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (list_item), "mime_type", g_strdup (mime_type), g_free);
|
||||
|
||||
/* Check and see if component is in preferred list */
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
|
||||
application_is_in_list (application->id, short_list));
|
||||
|
||||
/* Connect to toggled signal */
|
||||
gtk_signal_connect (GTK_OBJECT (button), "toggled",
|
||||
GTK_SIGNAL_FUNC (application_button_toggled_callback), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
gnome_vfs_mime_application_list_free (app_list);
|
||||
|
||||
}
|
||||
|
||||
if (short_list != NULL) {
|
||||
gnome_vfs_mime_application_list_free (short_list);
|
||||
}
|
||||
gnome_vfs_mime_application_list_free (short_list);
|
||||
}
|
||||
|
||||
|
||||
@@ -314,11 +355,17 @@ check_button_status (GtkList *list, GtkWidget *widget, ButtonHolder *button_hold
|
||||
gtk_widget_set_sensitive (button_holder->delete_button, FALSE);
|
||||
gtk_widget_set_sensitive (button_holder->edit_button, FALSE);
|
||||
} else {
|
||||
gtk_widget_set_sensitive (button_holder->delete_button, TRUE);
|
||||
gtk_widget_set_sensitive (button_holder->edit_button, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_delete_button (GtkList *list, GtkWidget *widget, ButtonHolder *button_holder)
|
||||
{
|
||||
gtk_widget_set_sensitive (button_holder->delete_button,
|
||||
GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), "user_owned")));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* initialize_edit_applications_dialog
|
||||
@@ -342,6 +389,8 @@ initialize_edit_applications_dialog (const char *mime_type)
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* FIXME: dialog should be parented on Control Center window */
|
||||
|
||||
gtk_container_set_border_width (GTK_CONTAINER (edit_application_details->window), GNOME_PAD);
|
||||
gtk_window_set_policy (GTK_WINDOW (edit_application_details->window), FALSE, TRUE, FALSE);
|
||||
gtk_window_set_default_size (GTK_WINDOW (edit_application_details->window),
|
||||
@@ -357,7 +406,7 @@ initialize_edit_applications_dialog (const char *mime_type)
|
||||
main_vbox = GNOME_DIALOG (edit_application_details->window)->vbox;
|
||||
|
||||
/* Add label */
|
||||
label_text = g_strdup_printf (_("Select applications to appear in menu for mime type \"%s\""), mime_type);
|
||||
label_text = g_strdup_printf (_("Select applications to appear in menu for MIME type \"%s\""), mime_type);
|
||||
label = gtk_label_new (label_text);
|
||||
g_free (label_text);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
@@ -403,11 +452,12 @@ initialize_edit_applications_dialog (const char *mime_type)
|
||||
/* Watch container so we can update buttons */
|
||||
gtk_signal_connect (GTK_OBJECT (list), "add", check_button_status, button_holder);
|
||||
gtk_signal_connect_full (GTK_OBJECT (list), "remove", check_button_status, NULL, button_holder,
|
||||
g_free, FALSE, FALSE);
|
||||
g_free, FALSE, FALSE);
|
||||
gtk_signal_connect (GTK_OBJECT (list), "select_child", update_delete_button, button_holder);
|
||||
|
||||
populate_default_applications_list (list, mime_type);
|
||||
|
||||
gtk_widget_show_all (main_vbox);
|
||||
|
||||
populate_default_applications_list (list, mime_type);
|
||||
}
|
||||
|
||||
|
||||
@@ -447,7 +497,7 @@ initialize_edit_components_dialog (const char *mime_type)
|
||||
main_vbox = GNOME_DIALOG (edit_component_details->window)->vbox;
|
||||
|
||||
/* Add label */
|
||||
label_text = g_strdup_printf (_("Select views to appear in menu for mime type \"%s\""), mime_type);
|
||||
label_text = g_strdup_printf (_("Select views to appear in menu for MIME type \"%s\""), mime_type);
|
||||
label = gtk_label_new (label_text);
|
||||
g_free (label_text);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
@@ -482,19 +532,13 @@ show_edit_applications_dialog (const char *mime_type)
|
||||
if (edit_application_details == NULL) {
|
||||
initialize_edit_applications_dialog (mime_type);
|
||||
}
|
||||
|
||||
switch(gnome_dialog_run (GNOME_DIALOG (edit_application_details->window))) {
|
||||
case 0:
|
||||
nautilus_mime_type_capplet_update_application_info (mime_type);
|
||||
/* Delete the dialog so the lists are repopulated on next lauch */
|
||||
gtk_widget_destroy (edit_application_details->window);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* Delete the dialog so the lists are repopulated on next lauch */
|
||||
gtk_widget_destroy (edit_application_details->window);
|
||||
break;
|
||||
}
|
||||
|
||||
/* FIXME: This is a modal dialog with no Cancel button, so the close box
|
||||
* has to do the same thing as the OK button, which is pretty darn confusing.
|
||||
* It would be better to make it modeless someday.
|
||||
*/
|
||||
gnome_dialog_run_and_close (GNOME_DIALOG (edit_application_details->window));
|
||||
nautilus_mime_type_capplet_update_application_info (mime_type);
|
||||
}
|
||||
|
||||
|
||||
@@ -511,18 +555,13 @@ show_edit_components_dialog (const char *mime_type)
|
||||
initialize_edit_components_dialog (mime_type);
|
||||
}
|
||||
|
||||
switch(gnome_dialog_run (GNOME_DIALOG (edit_component_details->window))) {
|
||||
case 0:
|
||||
nautilus_mime_type_capplet_update_viewer_info (mime_type);
|
||||
/* Delete the dialog so the lists are repopulated on next lauch */
|
||||
gtk_widget_destroy (edit_component_details->window);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* Delete the dialog so the lists are repopulated on next lauch */
|
||||
gtk_widget_destroy (edit_component_details->window);
|
||||
break;
|
||||
}
|
||||
/* FIXME: This is a modal dialog with no Cancel button, so the close box
|
||||
* has to do the same thing as the OK button, which is pretty darn confusing.
|
||||
* It would be better to make it modeless someday.
|
||||
*/
|
||||
gnome_dialog_run_and_close (GNOME_DIALOG (edit_component_details->window));
|
||||
|
||||
nautilus_mime_type_capplet_update_viewer_info (mime_type);
|
||||
}
|
||||
|
||||
|
||||
@@ -688,6 +727,30 @@ display_upper_case_dialog (void)
|
||||
gnome_dialog_run_and_close (dialog);
|
||||
}
|
||||
|
||||
/* Do some basic validation of the text entry and enable the OK button if the text is
|
||||
* determined to be a valid string.
|
||||
*/
|
||||
static void
|
||||
validate_text_and_update_button (GtkEntry *entry, gpointer data)
|
||||
{
|
||||
char *text, *token;
|
||||
gboolean sensitize;
|
||||
|
||||
sensitize = TRUE;
|
||||
|
||||
text = gtk_entry_get_text (entry);
|
||||
if (text == NULL) {
|
||||
sensitize = FALSE;
|
||||
} else {
|
||||
token = strtok (text, " ");
|
||||
if (token == NULL || strlen (token) <= 0) {
|
||||
/* Entered text is invalid as best as we can detect. */
|
||||
sensitize = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (data), sensitize);
|
||||
}
|
||||
|
||||
char *
|
||||
nautilus_mime_type_capplet_show_new_mime_window (void)
|
||||
@@ -696,8 +759,6 @@ nautilus_mime_type_capplet_show_new_mime_window (void)
|
||||
GtkWidget *mime_entry;
|
||||
GtkWidget *label;
|
||||
GtkWidget *desc_entry;
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *vbox;
|
||||
const char *description;
|
||||
char *mime_type, *tmp_str, c;
|
||||
gboolean upper_case_alert;
|
||||
@@ -705,70 +766,62 @@ nautilus_mime_type_capplet_show_new_mime_window (void)
|
||||
mime_type = NULL;
|
||||
upper_case_alert = FALSE;
|
||||
|
||||
dialog = gnome_dialog_new (_("Add Mime Type"), GNOME_STOCK_BUTTON_OK,
|
||||
dialog = gnome_dialog_new (_("Add MIME Type"), GNOME_STOCK_BUTTON_OK,
|
||||
GNOME_STOCK_BUTTON_CANCEL, NULL);
|
||||
gnome_dialog_set_default (GNOME_DIALOG (dialog), 1);
|
||||
label = gtk_label_new (_("Add a new Mime Type\n"
|
||||
"For example: image/tiff; text/x-scheme"));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0);
|
||||
label = gtk_label_new (_("Mime Type:"));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
|
||||
label = gtk_label_new (_("New MIME type (e.g. image/x-thumper):"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), label, TRUE, TRUE, 0);
|
||||
|
||||
mime_entry = gtk_entry_new ();
|
||||
gtk_box_pack_start (GTK_BOX (hbox), mime_entry, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), mime_entry, TRUE, TRUE, 0);
|
||||
|
||||
|
||||
vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), vbox, FALSE, FALSE, 0);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (vbox), GNOME_PAD_SMALL);
|
||||
label = gtk_label_new (_("Type in a description for this mime-type."));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("Description:")), FALSE, FALSE, 0);
|
||||
label = gtk_label_new (_("Description (e.g. Thumper image):"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), label, TRUE, TRUE, 0);
|
||||
|
||||
desc_entry = gtk_entry_new ();
|
||||
gtk_box_pack_start (GTK_BOX (hbox), desc_entry, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), desc_entry, TRUE, TRUE, 0);
|
||||
|
||||
/* Set up text entry validation signal */
|
||||
gtk_signal_connect (GTK_OBJECT (mime_entry), "changed",
|
||||
GTK_SIGNAL_FUNC (validate_text_and_update_button), GNOME_DIALOG (dialog)->buttons->data);
|
||||
|
||||
gnome_dialog_set_close (GNOME_DIALOG (dialog), FALSE);
|
||||
/* Set initial OK button state to desensitized */
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (GNOME_DIALOG (dialog)->buttons->data), FALSE);
|
||||
|
||||
/* Set focus to text entry widget */
|
||||
gtk_widget_grab_focus (mime_entry);
|
||||
|
||||
gtk_widget_show_all (GNOME_DIALOG (dialog)->vbox);
|
||||
|
||||
switch (gnome_dialog_run (GNOME_DIALOG (dialog))) {
|
||||
case 0:
|
||||
mime_type = g_strdup (gtk_entry_get_text (GTK_ENTRY (mime_entry)));
|
||||
g_assert (mime_type != NULL);
|
||||
|
||||
/* Handle illegal mime types as best we can */
|
||||
for (tmp_str = mime_type; (c = *tmp_str) != '\0'; tmp_str++) {
|
||||
if (isascii (c) && isupper (c)) {
|
||||
*tmp_str = tolower (c);
|
||||
upper_case_alert = TRUE;
|
||||
}
|
||||
if (gnome_dialog_run (GNOME_DIALOG (dialog)) == GNOME_OK) {
|
||||
mime_type = g_strdup (gtk_entry_get_text (GTK_ENTRY (mime_entry)));
|
||||
g_assert (mime_type != NULL);
|
||||
|
||||
/* Handle illegal mime types as best we can */
|
||||
for (tmp_str = mime_type; (c = *tmp_str) != '\0'; tmp_str++) {
|
||||
if (isascii ((guchar) c) && isupper ((guchar) c)) {
|
||||
*tmp_str = tolower (c);
|
||||
upper_case_alert = TRUE;
|
||||
}
|
||||
|
||||
description = gtk_entry_get_text (GTK_ENTRY (desc_entry));
|
||||
|
||||
/* Add new mime type here */
|
||||
if (strlen (mime_type) > 3) {
|
||||
gnome_vfs_mime_set_value (mime_type,
|
||||
"description",
|
||||
description);
|
||||
}
|
||||
/* Fall through to close dialog */
|
||||
break;
|
||||
|
||||
case 1:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
description = gtk_entry_get_text (GTK_ENTRY (desc_entry));
|
||||
|
||||
/* Add new mime type here */
|
||||
if (strlen (mime_type) > 3) {
|
||||
/* This call creates the key */
|
||||
gnome_vfs_mime_set_registered_type_key (mime_type,
|
||||
"description",
|
||||
description);
|
||||
|
||||
/* Ths call sets the user information */
|
||||
gnome_vfs_mime_set_value (mime_type,
|
||||
"description",
|
||||
description);
|
||||
}
|
||||
}
|
||||
|
||||
gnome_dialog_close (GNOME_DIALOG (dialog));
|
||||
@@ -793,6 +846,13 @@ add_extension_clicked (GtkWidget *widget, gpointer data)
|
||||
extension_list = GTK_LIST (data);
|
||||
|
||||
new_extension = nautilus_mime_type_capplet_show_new_extension_window ();
|
||||
|
||||
/* Filter out bogus extensions */
|
||||
if (new_extension == NULL || strlen (new_extension) <= 0 || new_extension[0] == ' ') {
|
||||
g_free (new_extension);
|
||||
return;
|
||||
}
|
||||
|
||||
new_list_item = gtk_list_item_new_with_label (new_extension);
|
||||
gtk_widget_show (new_list_item);
|
||||
|
||||
@@ -874,14 +934,16 @@ get_extensions_from_gtk_list (GtkList *list)
|
||||
}
|
||||
|
||||
char *
|
||||
nautilus_mime_type_capplet_show_change_extension_window (const char *mime_type)
|
||||
nautilus_mime_type_capplet_show_change_extension_window (const char *mime_type, gboolean *new_list)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *button;
|
||||
GtkWidget *list;
|
||||
char *extensions_list;
|
||||
char *extensions_list_str;
|
||||
|
||||
*new_list = FALSE;
|
||||
|
||||
dialog = gnome_dialog_new (_("File Extensions "),
|
||||
GNOME_STOCK_BUTTON_OK,
|
||||
GNOME_STOCK_BUTTON_CANCEL,
|
||||
@@ -933,7 +995,6 @@ nautilus_mime_type_capplet_show_change_extension_window (const char *mime_type)
|
||||
|
||||
|
||||
extensions_list = gnome_vfs_mime_get_extensions_list (mime_type);
|
||||
|
||||
if (extensions_list != NULL) {
|
||||
widget_list = NULL;
|
||||
for (temp = extensions_list; temp != NULL; temp = temp->next) {
|
||||
@@ -950,22 +1011,21 @@ nautilus_mime_type_capplet_show_change_extension_window (const char *mime_type)
|
||||
|
||||
gtk_widget_show_all (GNOME_DIALOG (dialog)->vbox);
|
||||
|
||||
switch (gnome_dialog_run (GNOME_DIALOG (dialog))) {
|
||||
case 0:
|
||||
extensions_list = get_extensions_from_gtk_list (GTK_LIST (list));
|
||||
if (extensions_list == NULL) {
|
||||
extensions_list = g_strdup ("");
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
extensions_list = g_strdup ("");
|
||||
break;
|
||||
}
|
||||
extensions_list_str = NULL;
|
||||
if (gnome_dialog_run (GNOME_DIALOG (dialog)) == GNOME_OK) {
|
||||
*new_list = TRUE;
|
||||
extensions_list_str = get_extensions_from_gtk_list (GTK_LIST (list));
|
||||
if (extensions_list_str == NULL) {
|
||||
extensions_list_str = g_strdup ("");
|
||||
}
|
||||
}
|
||||
if (extensions_list_str == NULL) {
|
||||
extensions_list_str = g_strdup ("");
|
||||
}
|
||||
gnome_dialog_close (GNOME_DIALOG (dialog));
|
||||
|
||||
|
||||
return extensions_list;
|
||||
return extensions_list_str;
|
||||
}
|
||||
|
||||
|
||||
@@ -982,7 +1042,9 @@ nautilus_mime_type_capplet_show_new_extension_window (void)
|
||||
GNOME_STOCK_BUTTON_CANCEL, NULL);
|
||||
gnome_dialog_set_default (GNOME_DIALOG (dialog), 0);
|
||||
gnome_dialog_set_close (GNOME_DIALOG (dialog), FALSE);
|
||||
label = gtk_label_new (_("Type in the extensions for this mime-type.\nFor example: .html, .htm"));
|
||||
label = gtk_label_new (_("Type in the extensions for this mime-type (without dot).\n"
|
||||
"You can enter several extensions seperated by a space,\n"
|
||||
"for example: html htm"));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
@@ -998,17 +1060,13 @@ nautilus_mime_type_capplet_show_new_extension_window (void)
|
||||
gtk_widget_show_all (GNOME_DIALOG (dialog)->vbox);
|
||||
|
||||
/* Set focus to text entry widget */
|
||||
gtk_window_set_focus (GTK_WINDOW (dialog), mime_entry);
|
||||
gtk_widget_grab_focus (mime_entry);
|
||||
|
||||
new_extension = g_strdup ("");
|
||||
switch (gnome_dialog_run (GNOME_DIALOG (dialog))) {
|
||||
case 0:
|
||||
new_extension = g_strdup (gtk_entry_get_text (GTK_ENTRY (mime_entry)));
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (gnome_dialog_run (GNOME_DIALOG (dialog)) == GNOME_OK) {
|
||||
new_extension = g_strdup (gtk_entry_get_text (GTK_ENTRY (mime_entry)));
|
||||
} else {
|
||||
new_extension = g_strdup ("");
|
||||
}
|
||||
|
||||
gnome_dialog_close (GNOME_DIALOG (dialog));
|
||||
|
||||
@@ -1020,17 +1078,19 @@ nautilus_mime_type_capplet_show_new_extension_window (void)
|
||||
* Create or update a GnomeVFSMimeApplication and register
|
||||
* it with the mime database.
|
||||
*/
|
||||
static void
|
||||
static char *
|
||||
add_or_update_application (GtkWidget *list, const char *name, const char *command,
|
||||
gboolean multiple, gboolean expects_uris,
|
||||
gboolean update)
|
||||
{
|
||||
GnomeVFSMimeApplication app, *original;
|
||||
const char *mime_type;
|
||||
|
||||
uuid_t app_uuid;
|
||||
char app_uuid_string[100];
|
||||
|
||||
/* Check for empty strings. Command can be empty. */
|
||||
if (name[0] == '\0') {
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mime_type = nautilus_mime_type_capplet_get_selected_item_mime_type ();
|
||||
@@ -1039,7 +1099,11 @@ add_or_update_application (GtkWidget *list, const char *name, const char *comman
|
||||
/* It's ok to cast, we don't modify the application
|
||||
* structure and thus the name/command, this should really
|
||||
* use the application registry explicitly */
|
||||
app.id = (char *)name;
|
||||
|
||||
/* Generate unique application id */
|
||||
uuid_generate(app_uuid);
|
||||
uuid_unparse(app_uuid, app_uuid_string);
|
||||
app.id = app_uuid_string;
|
||||
app.name = (char *)name;
|
||||
app.command = (char *)command;
|
||||
app.can_open_multiple_files = multiple;
|
||||
@@ -1049,7 +1113,7 @@ add_or_update_application (GtkWidget *list, const char *name, const char *comman
|
||||
app.requires_terminal = FALSE;
|
||||
|
||||
if (update) {
|
||||
original = gnome_vfs_mime_application_new_from_id (name);
|
||||
original = gnome_vfs_mime_application_new_from_id (app.id);
|
||||
if (original == NULL) {
|
||||
const char *original_id;
|
||||
GList *selection;
|
||||
@@ -1059,20 +1123,20 @@ add_or_update_application (GtkWidget *list, const char *name, const char *comman
|
||||
/* If there isn't a selection we cannot allow an edit */
|
||||
selection = GTK_LIST (list)->selection;
|
||||
if (selection == NULL || g_list_length (selection) <= 0) {
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get application id and info */
|
||||
item = GTK_LIST_ITEM (selection->data);
|
||||
if (item == NULL) {
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
original_id = gtk_object_get_data (GTK_OBJECT (item), "application_id");
|
||||
if (original_id == NULL) {
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Remove original application data */
|
||||
gnome_vfs_application_registry_remove_mime_type (original_id, mime_type);
|
||||
gnome_vfs_application_registry_sync ();
|
||||
@@ -1083,77 +1147,122 @@ add_or_update_application (GtkWidget *list, const char *name, const char *comman
|
||||
gtk_container_remove (GTK_CONTAINER (list), GTK_WIDGET (item));
|
||||
|
||||
/* Add new widget and restore position */
|
||||
add_item_to_application_list (list, name, mime_type, position);
|
||||
add_item_to_application_list (list, original_id, name, mime_type,
|
||||
gnome_vfs_application_is_user_owned_application (original),
|
||||
position);
|
||||
}
|
||||
}
|
||||
|
||||
gnome_vfs_application_registry_save_mime_application (&app);
|
||||
gnome_vfs_application_registry_add_mime_type (name, mime_type);
|
||||
gnome_vfs_application_registry_add_mime_type (app.id, mime_type);
|
||||
gnome_vfs_application_registry_sync ();
|
||||
|
||||
gnome_vfs_mime_add_application_to_short_list (mime_type, app.id);
|
||||
|
||||
return g_strdup (app.id);
|
||||
}
|
||||
|
||||
static void
|
||||
add_item_to_application_list (GtkWidget *list, const char *name, const char *mime_type, int position)
|
||||
add_item_to_application_list (GtkWidget *list, const char *id, const char *name, const char *mime_type,
|
||||
gboolean user_owned, int position)
|
||||
{
|
||||
GtkWidget *check_button, *list_item, *hbox, *label;
|
||||
|
||||
/* Create list item */
|
||||
list_item = gtk_list_item_new ();
|
||||
|
||||
/* Create check button */
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_container_add (GTK_CONTAINER (list_item), hbox);
|
||||
|
||||
check_button = gtk_check_button_new ();
|
||||
gtk_box_pack_start (GTK_BOX (hbox), check_button, FALSE, FALSE, 0);
|
||||
GtkListItem *list_item;
|
||||
GList *short_list;
|
||||
|
||||
label = gtk_label_new (name);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
|
||||
/* Add list item to list */
|
||||
if (position == -1) {
|
||||
gtk_container_add (GTK_CONTAINER (list), list_item);
|
||||
} else {
|
||||
GList *items;
|
||||
items = g_list_alloc ();
|
||||
items->data = list_item;
|
||||
gtk_list_insert_items (GTK_LIST (list), items, position);
|
||||
gtk_list_select_child (GTK_LIST (list), list_item);
|
||||
short_list = gnome_vfs_mime_get_short_list_applications (mime_type);
|
||||
list_item = create_application_list_item (id, name, mime_type, user_owned, short_list);
|
||||
gnome_vfs_mime_application_list_free (short_list);
|
||||
|
||||
insert_item (GTK_LIST (list), list_item, position);
|
||||
gtk_list_select_child (GTK_LIST (list), GTK_WIDGET (list_item));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_invalid_application_input (GtkWindow *parent_window, const char *name, const char *command)
|
||||
{
|
||||
char *message;
|
||||
char *stripped_name;
|
||||
GnomeDialog *error_dialog;
|
||||
gboolean error_in_name;
|
||||
|
||||
message = NULL;
|
||||
error_in_name = FALSE;
|
||||
|
||||
stripped_name = g_strstrip (g_strdup (name));
|
||||
|
||||
if (strlen (stripped_name) == 0) {
|
||||
message = g_strdup (_("You must enter a name."));
|
||||
error_in_name = TRUE;
|
||||
} else if (strlen (command) == 0) {
|
||||
message = g_strdup (_("You must enter a command."));
|
||||
} else if (!gnome_vfs_is_executable_command_string (command)) {
|
||||
if (command[0] == '/') {
|
||||
/* FIXME: Should strip parameters off before using in this message. */
|
||||
/* FIXME: Should use separate messages for doesn't exist/isn't executable. */
|
||||
/* Both of these FIXMEs would need to handle quoting to work correctly,
|
||||
* since otherwise a space might be part of path or separator before parameters.
|
||||
*/
|
||||
/* FIXME: Should use some line-wrapping technology a la nautilus-stock-dialogs.c */
|
||||
message = g_strdup_printf
|
||||
(_("\"%s\" does not exist or is not executable.\n"
|
||||
"Check your spelling and make sure you have\n"
|
||||
"the right permissions to execute this file."), command);
|
||||
} else {
|
||||
/* FIXME: Should strip parameters off before using in this message */
|
||||
message = g_strdup_printf
|
||||
(_("The command \"%s\" cannot be found.\n"
|
||||
"You must use a command that can work from any command line."), command);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_show_all (list);
|
||||
|
||||
/* Save ID and mime type*/
|
||||
gtk_object_set_data_full (GTK_OBJECT (check_button), "application_id", g_strdup (name), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (check_button), "mime_type", g_strdup (mime_type), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (list_item), "application_id", g_strdup (name), g_free);
|
||||
gtk_object_set_data_full (GTK_OBJECT (list_item), "mime_type", g_strdup (mime_type), g_free);
|
||||
|
||||
/* Check and see if component is in preferred list */
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
|
||||
g_free (stripped_name);
|
||||
|
||||
if (message != NULL) {
|
||||
error_dialog = GNOME_DIALOG (gnome_error_dialog_parented (message,
|
||||
parent_window));
|
||||
gtk_window_set_title (GTK_WINDOW (error_dialog),
|
||||
error_in_name
|
||||
? _("Bad Application Name")
|
||||
: _("Bad Application Command"));
|
||||
|
||||
gnome_dialog_run (error_dialog);
|
||||
g_free (message);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Connect to toggled signal */
|
||||
gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
|
||||
GTK_SIGNAL_FUNC (application_button_toggled_callback), NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
show_new_application_window (GtkWidget *button, GtkWidget *list)
|
||||
run_edit_or_new_application_dialog (const char *mime_type, GtkWidget *list, GnomeVFSMimeApplication *application)
|
||||
{
|
||||
GtkWidget *app_entry, *command_entry;
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *app_entry, *command_entry;
|
||||
GtkWidget *label;
|
||||
GtkWidget *behavior_frame, *frame_vbox;
|
||||
GtkWidget *multiple_check_box, *uri_check_box;
|
||||
GtkWidget *table;
|
||||
char *name, *command, *mime_type;
|
||||
gboolean multiple, uri;
|
||||
gboolean initial_toggle_state;
|
||||
const char *name;
|
||||
const char *command;
|
||||
int dialog_result;
|
||||
gboolean entry_validated;
|
||||
char *invalid_entry_message, *app_id;
|
||||
|
||||
dialog = gnome_dialog_new (_("New Application"), GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL);
|
||||
g_assert (mime_type != NULL || application != NULL);
|
||||
g_assert (GTK_IS_WIDGET (list));
|
||||
|
||||
dialog = gnome_dialog_new (
|
||||
application == NULL
|
||||
? _("Add Application")
|
||||
: _("Edit Application"),
|
||||
GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL);
|
||||
|
||||
/* FIXME: Dialog should be parented on Edit Applications dialog */
|
||||
|
||||
/* Create table */
|
||||
table = gtk_table_new (3, 2, FALSE);
|
||||
table = gtk_table_new (4, 2, FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (GNOME_DIALOG (dialog)->vbox), table);
|
||||
gtk_table_set_row_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
|
||||
gtk_table_set_col_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
|
||||
@@ -1161,21 +1270,26 @@ show_new_application_window (GtkWidget *button, GtkWidget *list)
|
||||
/* Application Name label and entry */
|
||||
label = gtk_label_new (_("Application Name:"));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
gtk_table_attach_defaults ( GTK_TABLE (table), label, 0, 1, 0, 1);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
|
||||
|
||||
app_entry = gtk_entry_new ();
|
||||
gtk_table_attach_defaults ( GTK_TABLE (table), app_entry, 1, 2, 0, 1);
|
||||
if (application != NULL) {
|
||||
gtk_entry_set_text (GTK_ENTRY (app_entry), application->name);
|
||||
}
|
||||
|
||||
/* Application Command label and entry */
|
||||
label = gtk_label_new (_("Application Command:"));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
gtk_table_attach_defaults ( GTK_TABLE (table), label, 0, 1, 1, 2);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
|
||||
|
||||
command_entry = gtk_entry_new ();
|
||||
gtk_table_attach_defaults ( GTK_TABLE (table), command_entry, 1, 2, 1, 2);
|
||||
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), command_entry, 1, 2, 1, 2);
|
||||
if (application != NULL) {
|
||||
gtk_entry_set_text (GTK_ENTRY (command_entry), application->command);
|
||||
}
|
||||
|
||||
/* Open Behavior frame */
|
||||
/* FIXME bugzilla.eazel.com 6066: Need to add expected uri schemes */
|
||||
behavior_frame = gtk_frame_new (_("Open Behavior"));
|
||||
gtk_table_attach_defaults ( GTK_TABLE (table), behavior_frame, 0, 2, 2, 3);
|
||||
|
||||
@@ -1184,52 +1298,70 @@ show_new_application_window (GtkWidget *button, GtkWidget *list)
|
||||
|
||||
multiple_check_box = gtk_check_button_new_with_label (_("Can open multiple files"));
|
||||
gtk_box_pack_start (GTK_BOX (frame_vbox), multiple_check_box, FALSE, FALSE, 0);
|
||||
initial_toggle_state = application == NULL
|
||||
? FALSE
|
||||
: application->can_open_multiple_files;
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (multiple_check_box), initial_toggle_state);
|
||||
|
||||
uri_check_box = gtk_check_button_new_with_label (_("Expects URIs as arguments"));
|
||||
/* FIXME bugzilla.eazel.com 6066: This needs to be three options now: "yes", "no", and "use uris for non-file locations" */
|
||||
uri_check_box = gtk_check_button_new_with_label (_("Can open from URI"));
|
||||
gtk_box_pack_start (GTK_BOX (frame_vbox), uri_check_box, FALSE, FALSE, 0);
|
||||
|
||||
|
||||
initial_toggle_state = application == NULL
|
||||
? FALSE
|
||||
: application->expects_uris;
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (uri_check_box), initial_toggle_state);
|
||||
|
||||
|
||||
gtk_widget_show_all (GNOME_DIALOG (dialog)->vbox);
|
||||
|
||||
/* Set focus to text entry widget */
|
||||
gtk_window_set_focus (GTK_WINDOW (dialog), app_entry);
|
||||
gtk_widget_grab_focus (app_entry);
|
||||
|
||||
switch (gnome_dialog_run (GNOME_DIALOG (dialog))) {
|
||||
case 0:
|
||||
do {
|
||||
dialog_result = gnome_dialog_run (GNOME_DIALOG (dialog));
|
||||
entry_validated = FALSE;
|
||||
|
||||
if (dialog_result == GNOME_OK) {
|
||||
name = gtk_entry_get_text (GTK_ENTRY (app_entry));
|
||||
command = gtk_entry_get_text (GTK_ENTRY (command_entry));
|
||||
multiple = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (multiple_check_box));
|
||||
uri = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (uri_check_box));
|
||||
|
||||
if (strlen (name) > 0 && strlen (command) > 0) {
|
||||
mime_type = gtk_object_get_data (GTK_OBJECT (button), "mime_type");
|
||||
add_or_update_application (list,
|
||||
gtk_entry_get_text (GTK_ENTRY (app_entry)),
|
||||
gtk_entry_get_text (GTK_ENTRY (command_entry)),
|
||||
|
||||
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (multiple_check_box)),
|
||||
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (uri_check_box)),
|
||||
FALSE);
|
||||
add_item_to_application_list (list, name, mime_type, -1);
|
||||
invalid_entry_message = NULL;
|
||||
|
||||
if (!handle_invalid_application_input (GTK_WINDOW (dialog), name, command)) {
|
||||
entry_validated = TRUE;
|
||||
app_id = add_or_update_application (list,
|
||||
name,
|
||||
command,
|
||||
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (multiple_check_box)),
|
||||
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (uri_check_box)),
|
||||
application != NULL);
|
||||
if (application == NULL && app_id != NULL) {
|
||||
add_item_to_application_list (list, app_id, name, mime_type, TRUE, -1);
|
||||
}
|
||||
g_free (app_id);
|
||||
}
|
||||
case 1:
|
||||
gtk_widget_destroy (dialog);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (dialog_result == GNOME_OK && !entry_validated);
|
||||
|
||||
/* FIXME: Close box is treated like Cancel, which loses user changes silently.
|
||||
* Would be better to either do nothing at all (force use of OK or Cancel) or
|
||||
* even put up a little dialog telling them they have to use OK or Cancel.
|
||||
* Too bad we can't prevent the close box from appearing. Window Managers suck.
|
||||
*/
|
||||
if (dialog_result >= 0) {
|
||||
gnome_dialog_close (GNOME_DIALOG (dialog));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_new_application_window (GtkWidget *button, GtkWidget *list)
|
||||
{
|
||||
run_edit_or_new_application_dialog (gtk_object_get_data (GTK_OBJECT (button), "mime_type"), list, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
show_edit_application_window (GtkWidget *button, GtkWidget *list)
|
||||
{
|
||||
GtkWidget *app_entry, *command_entry;
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *label;
|
||||
GtkWidget *behavior_frame, *frame_vbox;
|
||||
GtkWidget *multiple_check_box, *uri_check_box;
|
||||
GtkWidget *table;
|
||||
GList *selection;
|
||||
const char *id;
|
||||
GnomeVFSMimeApplication *application;
|
||||
@@ -1257,78 +1389,16 @@ show_edit_application_window (GtkWidget *button, GtkWidget *list)
|
||||
return;
|
||||
}
|
||||
|
||||
dialog = gnome_dialog_new (_("Edit Application"), GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL);
|
||||
|
||||
/* Create table */
|
||||
table = gtk_table_new (4, 2, FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (GNOME_DIALOG (dialog)->vbox), table);
|
||||
gtk_table_set_row_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
|
||||
gtk_table_set_col_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
|
||||
run_edit_or_new_application_dialog (NULL, list, application);
|
||||
|
||||
/* Application Name label and entry */
|
||||
label = gtk_label_new (_("Application Name:"));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
|
||||
|
||||
app_entry = gtk_entry_new ();
|
||||
gtk_table_attach_defaults ( GTK_TABLE (table), app_entry, 1, 2, 0, 1);
|
||||
gtk_entry_set_text (GTK_ENTRY (app_entry), application->name);
|
||||
|
||||
/* Application Command label and entry */
|
||||
label = gtk_label_new (_("Application Command:"));
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
|
||||
|
||||
command_entry = gtk_entry_new ();
|
||||
gtk_entry_set_text (GTK_ENTRY (command_entry), application->command);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), command_entry, 1, 2, 1, 2);
|
||||
|
||||
/* Open Behavior frame */
|
||||
behavior_frame = gtk_frame_new (_("Open Behavior"));
|
||||
gtk_table_attach_defaults ( GTK_TABLE (table), behavior_frame, 0, 2, 2, 3);
|
||||
|
||||
frame_vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_container_add (GTK_CONTAINER (behavior_frame), frame_vbox);
|
||||
|
||||
multiple_check_box = gtk_check_button_new_with_label (_("Can open multiple files"));
|
||||
gtk_box_pack_start (GTK_BOX (frame_vbox), multiple_check_box, FALSE, FALSE, 0);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (multiple_check_box), application->can_open_multiple_files);
|
||||
|
||||
/* FIXME bugzilla.eazel.com 6066: This needs to be three options now: "yes", "no", and "use uris for non-file locations" */
|
||||
uri_check_box = gtk_check_button_new_with_label (_("Can open from URI"));
|
||||
gtk_box_pack_start (GTK_BOX (frame_vbox), uri_check_box, FALSE, FALSE, 0);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (uri_check_box), application->expects_uris);
|
||||
|
||||
|
||||
gtk_widget_show_all (GNOME_DIALOG (dialog)->vbox);
|
||||
|
||||
/* Set focus to text entry widget */
|
||||
gtk_window_set_focus (GTK_WINDOW (dialog), app_entry);
|
||||
|
||||
switch (gnome_dialog_run (GNOME_DIALOG (dialog))) {
|
||||
case 0:
|
||||
add_or_update_application (list,
|
||||
gtk_entry_get_text (GTK_ENTRY (app_entry)),
|
||||
gtk_entry_get_text (GTK_ENTRY (command_entry)),
|
||||
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (multiple_check_box)),
|
||||
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (uri_check_box)),
|
||||
TRUE);
|
||||
|
||||
case 1:
|
||||
gnome_vfs_mime_application_free (application);
|
||||
gtk_widget_destroy (dialog);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
gnome_vfs_mime_application_free (application);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_selected_application (GtkWidget *button, GtkWidget *list)
|
||||
{
|
||||
GtkListItem *item;
|
||||
const char *mime_type, *name;
|
||||
const char *mime_type, *id;
|
||||
GList *selection;
|
||||
|
||||
/* Get selected list item */
|
||||
@@ -1342,14 +1412,16 @@ delete_selected_application (GtkWidget *button, GtkWidget *list)
|
||||
return;
|
||||
}
|
||||
|
||||
name = gtk_object_get_data (GTK_OBJECT (item), "application_id");
|
||||
g_return_if_fail (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (item), "user_owned")));
|
||||
|
||||
id = gtk_object_get_data (GTK_OBJECT (item), "application_id");
|
||||
mime_type = gtk_object_get_data (GTK_OBJECT (item), "mime_type");
|
||||
|
||||
/* Remove mime data */
|
||||
if (name != NULL && mime_type != NULL) {
|
||||
gnome_vfs_application_registry_remove_mime_type (name, mime_type);
|
||||
/* Remove application if it is user owned */
|
||||
if (id != NULL && mime_type != NULL) {
|
||||
gnome_vfs_application_registry_remove_mime_type (id, mime_type);
|
||||
gnome_vfs_application_registry_sync ();
|
||||
gnome_vfs_mime_remove_application_from_short_list (mime_type, name);
|
||||
gnome_vfs_mime_remove_application_from_short_list (mime_type, id);
|
||||
}
|
||||
|
||||
/* Remove widget from list */
|
||||
|
||||
@@ -30,6 +30,7 @@ void show_edit_components_dialog (const char *mime_type);
|
||||
char *name_from_oaf_server_info (OAF_ServerInfo *server);
|
||||
char *nautilus_mime_type_capplet_show_new_mime_window (void);
|
||||
char *nautilus_mime_type_capplet_show_new_extension_window (void);
|
||||
char *nautilus_mime_type_capplet_show_change_extension_window (const char *mime_type);
|
||||
char *nautilus_mime_type_capplet_show_change_extension_window (const char *mime_type,
|
||||
gboolean *new_list);
|
||||
|
||||
#endif /* NAUTILUS_MIME_TYPE_CAPPLET_DIALOGS_H */
|
||||
|
||||
@@ -48,8 +48,11 @@
|
||||
|
||||
#include "nautilus-mime-type-capplet.h"
|
||||
|
||||
#define DEFAULT_REGULAR_ICON "/nautilus/i-regular-24.png"
|
||||
#define DEFAULT_ACTION_ICON "/nautilus/i-executable.png"
|
||||
#define DEFAULT_REGULAR_ICON "nautilus/i-regular-24.png"
|
||||
#define DEFAULT_ACTION_ICON "nautilus/i-executable.png"
|
||||
|
||||
#define MAX_ICON_WIDTH_IN_LIST 18
|
||||
#define MAX_ICON_HEIGHT_IN_LIST 18
|
||||
|
||||
enum {
|
||||
COLUMN_DESCRIPTION = 0,
|
||||
@@ -90,6 +93,8 @@ static void populate_mime_list (GList *type_li
|
||||
static GdkPixbuf *capplet_get_icon_pixbuf (const char *mime_string,
|
||||
gboolean is_executable);
|
||||
|
||||
|
||||
/* FIXME: Using global variables here is yucky */
|
||||
GtkWidget *capplet;
|
||||
GtkWidget *delete_button;
|
||||
GtkWidget *remove_button;
|
||||
@@ -99,6 +104,8 @@ GtkWidget *default_menu;
|
||||
GtkWidget *application_button, *viewer_button;
|
||||
GtkLabel *mime_label;
|
||||
GtkWidget *description_entry;
|
||||
gboolean description_has_changed;
|
||||
gboolean sort_column_clicked [TOTAL_COLUMNS];
|
||||
|
||||
/*
|
||||
* main
|
||||
@@ -261,11 +268,6 @@ nautilus_mime_type_capplet_add_extension (const char *extension)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check for starting space in string */
|
||||
if (extension[0] == ' ') {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy only contiguous part of string. No spaces allowed. */
|
||||
search_string = g_strdup (extension);
|
||||
token = strtok (search_string, " ");
|
||||
@@ -274,7 +276,7 @@ nautilus_mime_type_capplet_add_extension (const char *extension)
|
||||
title[0] = g_strdup (extension);
|
||||
} else if (strlen (token) <= 0) {
|
||||
return;
|
||||
}else {
|
||||
} else {
|
||||
title[0] = g_strdup (token);
|
||||
}
|
||||
g_free (search_string);
|
||||
@@ -377,26 +379,34 @@ get_selected_mime_type (void)
|
||||
static void
|
||||
really_change_icon (gpointer user_data)
|
||||
{
|
||||
|
||||
NautilusMimeIconEntry *icon_entry;
|
||||
char *filename;
|
||||
const char *mime_type;
|
||||
|
||||
g_assert (NAUTILUS_MIME_IS_ICON_ENTRY (user_data));
|
||||
|
||||
mime_type = get_selected_mime_type ();
|
||||
if (mime_type == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
filename = nautilus_mime_type_icon_entry_get_relative_filename (NAUTILUS_MIME_ICON_ENTRY (user_data));
|
||||
|
||||
icon_entry = NAUTILUS_MIME_ICON_ENTRY (user_data);
|
||||
|
||||
filename = nautilus_mime_type_icon_entry_get_relative_filename (icon_entry);
|
||||
if (filename == NULL) {
|
||||
filename = nautilus_mime_type_icon_entry_get_full_filename (icon_entry);
|
||||
}
|
||||
|
||||
gnome_vfs_mime_set_icon (mime_type, filename);
|
||||
|
||||
nautilus_mime_type_capplet_update_mime_list_icon (mime_type);
|
||||
nautilus_mime_type_capplet_update_mime_list_icon_and_description (mime_type);
|
||||
nautilus_mime_type_capplet_update_info (mime_type);
|
||||
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
static void
|
||||
gil_icon_selected_cb (GnomeIconList *gil, gint num, GdkEvent *event, gpointer user_data)
|
||||
icon_chosen_callback (GnomeIconList *gil, gint num, GdkEvent *event, gpointer user_data)
|
||||
{
|
||||
NautilusMimeIconEntry *icon_entry;
|
||||
const gchar * icon;
|
||||
@@ -420,6 +430,7 @@ gil_icon_selected_cb (GnomeIconList *gil, gint num, GdkEvent *event, gpointer us
|
||||
if(event && event->type == GDK_2BUTTON_PRESS && ((GdkEventButton *)event)->button == 1) {
|
||||
gnome_icon_selection_stop_loading(gis);
|
||||
really_change_icon (user_data);
|
||||
gtk_widget_hide(icon_entry->pick_dialog);
|
||||
}
|
||||
|
||||
|
||||
@@ -428,7 +439,7 @@ gil_icon_selected_cb (GnomeIconList *gil, gint num, GdkEvent *event, gpointer us
|
||||
static void
|
||||
change_icon_clicked_cb_real (GnomeDialog *dialog, gint button_number, gpointer user_data)
|
||||
{
|
||||
if (button_number == 0) {
|
||||
if (button_number == GNOME_OK) {
|
||||
really_change_icon (user_data);
|
||||
}
|
||||
}
|
||||
@@ -440,13 +451,14 @@ change_icon_clicked (GtkWidget *entry, gpointer user_data)
|
||||
GnomeIconSelection * gis;
|
||||
|
||||
nautilus_mime_type_show_icon_selection (NAUTILUS_MIME_ICON_ENTRY (user_data));
|
||||
|
||||
dialog = GNOME_DIALOG (NAUTILUS_MIME_ICON_ENTRY (user_data)->pick_dialog);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (dialog), "clicked", change_icon_clicked_cb_real, user_data);
|
||||
|
||||
gis = gtk_object_get_user_data(GTK_OBJECT(user_data));
|
||||
gtk_signal_connect_after (GTK_OBJECT(GNOME_ICON_SELECTION(gis)->gil),
|
||||
"select_icon", gil_icon_selected_cb, user_data);
|
||||
"select_icon", icon_chosen_callback, user_data);
|
||||
|
||||
}
|
||||
|
||||
@@ -474,15 +486,17 @@ change_file_extensions_clicked (GtkWidget *widget, gpointer user_data)
|
||||
{
|
||||
const char *mime_type;
|
||||
char *new_extensions;
|
||||
gboolean use_new_list;
|
||||
|
||||
mime_type = get_selected_mime_type ();
|
||||
if (mime_type == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
new_extensions = nautilus_mime_type_capplet_show_change_extension_window (mime_type);
|
||||
|
||||
gnome_vfs_mime_set_extensions_list (mime_type, new_extensions);
|
||||
new_extensions = nautilus_mime_type_capplet_show_change_extension_window (mime_type, &use_new_list);
|
||||
if (use_new_list) {
|
||||
gnome_vfs_mime_set_extensions_list (mime_type, new_extensions);
|
||||
}
|
||||
|
||||
update_extensions_list (mime_type);
|
||||
}
|
||||
@@ -551,6 +565,97 @@ list_reveal_row (GtkCList *clist, int row_index)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
find_row_for_mime_type (const char *mime_type, GtkCList *mime_list)
|
||||
{
|
||||
gboolean found_one;
|
||||
int index;
|
||||
const char *row_data;
|
||||
|
||||
if (mime_type == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
found_one = FALSE;
|
||||
|
||||
for (index = 0; index < mime_list->rows; index++) {
|
||||
row_data = gtk_clist_get_row_data (mime_list, index);
|
||||
if (row_data != NULL && strcmp (row_data, mime_type) == 0) {
|
||||
found_one = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_one) {
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
update_description_from_input (GtkEntry *entry)
|
||||
{
|
||||
char *new_description;
|
||||
const char *mime_type;
|
||||
|
||||
g_assert (GTK_IS_ENTRY (entry));
|
||||
g_assert ((gpointer)entry == (gpointer)description_entry);
|
||||
|
||||
description_has_changed = FALSE;
|
||||
|
||||
mime_type = get_selected_mime_type ();
|
||||
if (mime_type == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
new_description = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
|
||||
gnome_vfs_mime_set_description (mime_type, new_description);
|
||||
nautilus_mime_type_capplet_update_mime_list_icon_and_description (mime_type);
|
||||
g_free (new_description);
|
||||
}
|
||||
|
||||
static void
|
||||
description_entry_activate (GtkEntry *entry, gpointer user_data)
|
||||
{
|
||||
g_assert (GTK_IS_ENTRY (entry));
|
||||
g_assert ((gpointer)entry == (gpointer)description_entry);
|
||||
g_assert (user_data == NULL);
|
||||
|
||||
if (description_has_changed) {
|
||||
update_description_from_input (entry);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
description_entry_changed (GtkEntry *entry, gpointer user_data)
|
||||
{
|
||||
g_assert (GTK_IS_ENTRY (entry));
|
||||
g_assert ((gpointer)entry == (gpointer)description_entry);
|
||||
g_assert (user_data == NULL);
|
||||
|
||||
description_has_changed = TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
description_entry_lost_focus (GtkEntry *entry,
|
||||
GdkEventFocus *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_assert (GTK_IS_ENTRY (entry));
|
||||
g_assert ((gpointer)entry == (gpointer)description_entry);
|
||||
g_assert (user_data == NULL);
|
||||
|
||||
if (description_has_changed) {
|
||||
update_description_from_input (entry);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
init_mime_capplet (const char *scroll_to_mime_type)
|
||||
{
|
||||
@@ -560,9 +665,7 @@ init_mime_capplet (const char *scroll_to_mime_type)
|
||||
GtkWidget *mime_list_container;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *table;
|
||||
int index, list_width, column_width;
|
||||
gboolean found_one;
|
||||
const char *row_data;
|
||||
int index, list_width, column_width, found_index;
|
||||
|
||||
capplet = capplet_widget_new ();
|
||||
|
||||
@@ -610,13 +713,26 @@ init_mime_capplet (const char *scroll_to_mime_type)
|
||||
(GtkAttachOptions) (GTK_FILL), 0, 0);
|
||||
|
||||
description_entry = gtk_entry_new ();
|
||||
description_has_changed = FALSE;
|
||||
gtk_box_pack_start (GTK_BOX (vbox), description_entry, FALSE, FALSE, 0);
|
||||
gtk_widget_make_bold (GTK_WIDGET (description_entry));
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (description_entry), "activate",
|
||||
GTK_SIGNAL_FUNC (description_entry_activate),
|
||||
NULL);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (description_entry), "changed",
|
||||
GTK_SIGNAL_FUNC (description_entry_changed),
|
||||
NULL);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (description_entry), "focus_out_event",
|
||||
GTK_SIGNAL_FUNC (description_entry_lost_focus),
|
||||
NULL);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (hbox), FALSE, FALSE, 0);
|
||||
|
||||
mime_label = GTK_LABEL (gtk_label_new (_("Mime Type")));
|
||||
mime_label = GTK_LABEL (gtk_label_new (_("MIME Type")));
|
||||
gtk_label_set_justify (GTK_LABEL (mime_label), GTK_JUSTIFY_LEFT);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (mime_label), FALSE, FALSE, 0);
|
||||
|
||||
@@ -665,11 +781,10 @@ init_mime_capplet (const char *scroll_to_mime_type)
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
|
||||
|
||||
default_menu = gtk_option_menu_new();
|
||||
gtk_widget_set_usize (GTK_WIDGET (default_menu), 170, 0);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), default_menu, TRUE, TRUE, 0);
|
||||
|
||||
button = gtk_button_new_with_label (_("Edit List"));
|
||||
gtk_widget_set_usize (GTK_WIDGET (button), 70, 0);
|
||||
gtk_misc_set_padding (GTK_MISC (GTK_BIN(button)->child), 2, 1);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
||||
gtk_signal_connect (GTK_OBJECT (button), "clicked", edit_default_clicked, mime_list);
|
||||
}
|
||||
@@ -693,13 +808,13 @@ init_mime_capplet (const char *scroll_to_mime_type)
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
gtk_widget_set_usize (hbox, 1, 11);
|
||||
|
||||
button = gtk_button_new_with_label (_("Add new Mime type..."));
|
||||
button = gtk_button_new_with_label (_("Add New MIME Type..."));
|
||||
gtk_signal_connect (GTK_OBJECT (button), "clicked", add_mime_clicked, NULL);
|
||||
gtk_table_attach (GTK_TABLE (small_table), button, 0, 1, 1, 2,
|
||||
(GtkAttachOptions) (GTK_FILL),
|
||||
(GtkAttachOptions) (0), 0, 0);
|
||||
|
||||
button = gtk_button_new_with_label (_("Delete this Mime type..."));
|
||||
button = gtk_button_new_with_label (_("Delete This MIME Type"));
|
||||
gtk_signal_connect (GTK_OBJECT (button), "clicked", delete_mime_clicked, NULL);
|
||||
gtk_table_attach (GTK_TABLE (small_table), button, 0, 1, 2, 3,
|
||||
(GtkAttachOptions) (GTK_FILL),
|
||||
@@ -718,12 +833,6 @@ init_mime_capplet (const char *scroll_to_mime_type)
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* FIXME bugzilla.eazel.com 2765: this call generates a
|
||||
Gtk-WARNING **: gtk_signal_disconnect_by_data(): could not find handler containing data (0x80FA6F8)
|
||||
I think it is a bug in the control-center...
|
||||
*/
|
||||
|
||||
/* Yes, show all widgets */
|
||||
gtk_widget_show_all (capplet);
|
||||
|
||||
@@ -744,32 +853,80 @@ init_mime_capplet (const char *scroll_to_mime_type)
|
||||
/* Sort by description. The description is the first column in the list. */
|
||||
gtk_clist_set_sort_column (GTK_CLIST (mime_list), COLUMN_DESCRIPTION);
|
||||
gtk_clist_sort (GTK_CLIST (mime_list));
|
||||
GTK_CLIST (mime_list)->sort_type = GTK_SORT_ASCENDING;
|
||||
|
||||
/* Set up initial column click tracking state. We do this so the initial clicks on
|
||||
* columns will allow us to set the proper sort state for the user.
|
||||
*/
|
||||
sort_column_clicked[0] = TRUE; /* First sort column has been click by us in setup code */
|
||||
for (index = 1; index < TOTAL_COLUMNS; index++) {
|
||||
sort_column_clicked[index] = FALSE;
|
||||
}
|
||||
|
||||
/* Attempt to select specified mime type in list */
|
||||
if (scroll_to_mime_type != NULL) {
|
||||
found_one = FALSE;
|
||||
|
||||
for (index = 0; index < GTK_CLIST (mime_list)->rows; index++) {
|
||||
row_data = gtk_clist_get_row_data (GTK_CLIST (mime_list), index);
|
||||
if (row_data != NULL && strcmp (row_data, scroll_to_mime_type) == 0) {
|
||||
/* Select mime type and bail */
|
||||
found_one = TRUE;
|
||||
gtk_clist_select_row (GTK_CLIST (mime_list), index, 1);
|
||||
list_reveal_row (GTK_CLIST (mime_list), index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_one) {
|
||||
gtk_clist_select_row (GTK_CLIST (mime_list), 0, 0);
|
||||
if (scroll_to_mime_type != NULL) {
|
||||
found_index = find_row_for_mime_type (scroll_to_mime_type, GTK_CLIST (mime_list));
|
||||
if (found_index != -1) {
|
||||
gtk_clist_select_row (GTK_CLIST (mime_list), found_index, 1);
|
||||
list_reveal_row (GTK_CLIST (mime_list), found_index);
|
||||
} else {
|
||||
gtk_clist_select_row (GTK_CLIST (mime_list), 0, 1);
|
||||
list_reveal_row (GTK_CLIST (mime_list), 0);
|
||||
}
|
||||
} else {
|
||||
gtk_clist_select_row (GTK_CLIST (mime_list), 0, 0);
|
||||
list_reveal_row (GTK_CLIST (mime_list), 0);
|
||||
}
|
||||
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (capplet), TRUE);
|
||||
|
||||
/* Inform control center that our changes are immediate */
|
||||
capplet_widget_changes_are_immediate (CAPPLET_WIDGET (capplet));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_full_path (const char *path_or_name)
|
||||
{
|
||||
return path_or_name[0] == '/';
|
||||
}
|
||||
|
||||
static char *
|
||||
capplet_get_icon_path (const char *path_or_name)
|
||||
{
|
||||
char *result;
|
||||
char *alternate_relative_filename;
|
||||
|
||||
if (is_full_path (path_or_name) && g_file_exists (path_or_name)) {
|
||||
return g_strdup (path_or_name);
|
||||
}
|
||||
|
||||
result = gnome_vfs_icon_path_from_filename (path_or_name);
|
||||
if (result != NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* FIXME bugzilla.eazel.com 639:
|
||||
* It is somewhat evil to special-case the nautilus directory here.
|
||||
* We should clean this up if/when we come up with a way to handle
|
||||
* Nautilus themes here.
|
||||
*/
|
||||
alternate_relative_filename = g_strconcat ("nautilus/", path_or_name, NULL);
|
||||
result = gnome_vfs_icon_path_from_filename (alternate_relative_filename);
|
||||
g_free (alternate_relative_filename);
|
||||
if (result != NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* FIXME bugzilla.eazel.com 639:
|
||||
* To work correctly with Nautilus themed icons, if there's no
|
||||
* suffix we will also try looking in the nautilus dir for a ".png" name.
|
||||
* This will return the icon for the default theme; there is no
|
||||
* mechanism for getting a themed icon in the capplet.
|
||||
*/
|
||||
alternate_relative_filename = g_strconcat ("nautilus/", path_or_name, ".png", NULL);
|
||||
result = gnome_vfs_icon_path_from_filename (alternate_relative_filename);
|
||||
g_free (alternate_relative_filename);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* nautilus_mime_type_capplet_update_info
|
||||
@@ -788,14 +945,9 @@ nautilus_mime_type_capplet_update_info (const char *mime_type) {
|
||||
gtk_label_set_text (GTK_LABEL (mime_label), mime_type);
|
||||
|
||||
description = gnome_vfs_mime_get_description (mime_type);
|
||||
if (description != NULL && strlen (description) > 0) {
|
||||
gtk_entry_set_text (GTK_ENTRY (description_entry), description);
|
||||
} else {
|
||||
gtk_entry_set_text (GTK_ENTRY (description_entry), _("No Description"));
|
||||
}
|
||||
gtk_entry_set_text (GTK_ENTRY (description_entry), description != NULL ? description : "");
|
||||
description_has_changed = FALSE;
|
||||
|
||||
gtk_editable_set_editable (GTK_EDITABLE (description_entry), FALSE);
|
||||
|
||||
/* Update menus */
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (application_button))) {
|
||||
populate_application_menu (default_menu, mime_type);
|
||||
@@ -810,23 +962,16 @@ nautilus_mime_type_capplet_update_info (const char *mime_type) {
|
||||
|
||||
/* Set icon for mime type */
|
||||
icon_name = gnome_vfs_mime_get_icon (mime_type);
|
||||
path = NULL;
|
||||
if (icon_name != NULL) {
|
||||
path = gnome_vfs_icon_path_from_filename (icon_name);
|
||||
if (path != NULL) {
|
||||
nautilus_mime_type_icon_entry_set_icon (NAUTILUS_MIME_ICON_ENTRY (icon_entry), path);
|
||||
g_free (path);
|
||||
} else {
|
||||
/* No icon */
|
||||
nautilus_mime_type_icon_entry_set_icon (NAUTILUS_MIME_ICON_ENTRY (icon_entry),
|
||||
NULL);
|
||||
}
|
||||
} else {
|
||||
/* No icon */
|
||||
path = gnome_vfs_icon_path_from_filename (DEFAULT_REGULAR_ICON);
|
||||
nautilus_mime_type_icon_entry_set_icon (NAUTILUS_MIME_ICON_ENTRY (icon_entry),
|
||||
path);
|
||||
g_free (path);
|
||||
path = capplet_get_icon_path (icon_name);
|
||||
}
|
||||
if (path == NULL) {
|
||||
/* No custom icon specified, or custom icon not found, use default */
|
||||
path = capplet_get_icon_path (DEFAULT_REGULAR_ICON);
|
||||
}
|
||||
nautilus_mime_type_icon_entry_set_icon (NAUTILUS_MIME_ICON_ENTRY (icon_entry), path);
|
||||
g_free (path);
|
||||
|
||||
/* Indicate default action */
|
||||
action = gnome_vfs_mime_get_default_action (mime_type);
|
||||
@@ -1147,9 +1292,18 @@ revert_real_cb (gint reply, gpointer data)
|
||||
gnome_vfs_mime_info_reload ();
|
||||
|
||||
mime_types_list = gnome_vfs_get_registered_mime_types ();
|
||||
|
||||
|
||||
gtk_clist_freeze (GTK_CLIST (mime_list));
|
||||
gtk_clist_clear (GTK_CLIST (mime_list));
|
||||
populate_mime_list (mime_types_list, GTK_CLIST (mime_list));
|
||||
|
||||
/* Sort list using current sort type and select the first item. */
|
||||
gtk_clist_sort (GTK_CLIST (mime_list));
|
||||
gtk_clist_select_row (GTK_CLIST (mime_list), 0, 0);
|
||||
list_reveal_row (GTK_CLIST (mime_list), 0);
|
||||
|
||||
gtk_clist_thaw (GTK_CLIST (mime_list));
|
||||
|
||||
} else {
|
||||
/* NO */
|
||||
}
|
||||
@@ -1161,10 +1315,9 @@ revert_mime_clicked (GtkWidget *widget, gpointer data)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gnome_question_dialog_modal (_("Reverting to system settings\n"
|
||||
"will lose all your personal \n"
|
||||
"Mime configuration.\n"
|
||||
"Revert to System Settings ?\n"),
|
||||
dialog = gnome_question_dialog_modal (_("Reverting to system settings will lose any changes\n"
|
||||
"you have ever made to File Types and Programs.\n"
|
||||
"Revert anyway?"),
|
||||
revert_real_cb, NULL);
|
||||
|
||||
}
|
||||
@@ -1204,9 +1357,10 @@ add_mime_clicked (GtkWidget *widget, gpointer data)
|
||||
GnomeVFSMimeAction *action;
|
||||
GnomeVFSMimeApplication *default_app;
|
||||
OAF_ServerInfo *default_component;
|
||||
int found_index;
|
||||
|
||||
mime_string = nautilus_mime_type_capplet_show_new_mime_window ();
|
||||
if (mime_string != NULL) {
|
||||
if (mime_string != NULL && mime_string[0] != '\0') {
|
||||
/* Add new type to mime list */
|
||||
pixbuf = NULL;
|
||||
|
||||
@@ -1240,7 +1394,7 @@ add_mime_clicked (GtkWidget *widget, gpointer data)
|
||||
pixbuf = capplet_get_icon_pixbuf (mime_string, FALSE);
|
||||
|
||||
if (pixbuf != NULL) {
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, 18, 18);
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST);
|
||||
gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100);
|
||||
gtk_clist_set_pixtext (GTK_CLIST (mime_list), row, 0, text[0], 5, pixmap, bitmap);
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
@@ -1257,7 +1411,11 @@ add_mime_clicked (GtkWidget *widget, gpointer data)
|
||||
g_free (text[3]);
|
||||
text[3] = g_strdup (default_app->name);
|
||||
|
||||
pixbuf = capplet_get_icon_pixbuf (mime_string, TRUE);
|
||||
filename = capplet_get_icon_path (DEFAULT_ACTION_ICON);
|
||||
if (filename != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (filename);
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
gnome_vfs_mime_application_free (default_app);
|
||||
break;
|
||||
@@ -1269,9 +1427,11 @@ add_mime_clicked (GtkWidget *widget, gpointer data)
|
||||
tmp_text = name_from_oaf_server_info (default_component);
|
||||
text[3] = g_strdup_printf (_("View as %s"), tmp_text);
|
||||
g_free (tmp_text);
|
||||
filename = gnome_vfs_icon_path_from_filename ("nautilus/gnome-library.png");
|
||||
pixbuf = gdk_pixbuf_new_from_file (filename);
|
||||
g_free (filename);
|
||||
filename = capplet_get_icon_path ("nautilus/gnome-library.png");
|
||||
if (filename != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (filename);
|
||||
g_free (filename);
|
||||
}
|
||||
CORBA_free (default_component);
|
||||
break;
|
||||
|
||||
@@ -1283,12 +1443,20 @@ add_mime_clicked (GtkWidget *widget, gpointer data)
|
||||
|
||||
/* Set column icon */
|
||||
if (pixbuf != NULL) {
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, 18, 18);
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST);
|
||||
gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100);
|
||||
gtk_clist_set_pixtext (GTK_CLIST (mime_list), row, 3, text[3], 5, pixmap, bitmap);
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
}
|
||||
|
||||
/* Sort, select and scroll to new mime type */
|
||||
gtk_clist_sort (GTK_CLIST (mime_list));
|
||||
found_index = find_row_for_mime_type (mime_string, GTK_CLIST (mime_list));
|
||||
if (found_index != -1) {
|
||||
gtk_clist_select_row (GTK_CLIST (mime_list), found_index, 1);
|
||||
list_reveal_row (GTK_CLIST (mime_list), found_index);
|
||||
}
|
||||
|
||||
g_free (text[0]);
|
||||
g_free (text[1]);
|
||||
g_free (text[2]);
|
||||
@@ -1336,7 +1504,7 @@ edit_default_clicked (GtkWidget *widget, gpointer data)
|
||||
|
||||
|
||||
void
|
||||
nautilus_mime_type_capplet_update_mime_list_icon (const char *mime_string)
|
||||
nautilus_mime_type_capplet_update_mime_list_icon_and_description (const char *mime_string)
|
||||
{
|
||||
char *text;
|
||||
const char *description;
|
||||
@@ -1366,7 +1534,7 @@ nautilus_mime_type_capplet_update_mime_list_icon (const char *mime_string)
|
||||
pixbuf = capplet_get_icon_pixbuf (mime_string, FALSE);
|
||||
|
||||
if (pixbuf != NULL) {
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, 18, 18);
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST);
|
||||
gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100);
|
||||
gtk_clist_set_pixtext (clist, row, 0, text, 5, pixmap, bitmap);
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
@@ -1410,9 +1578,7 @@ update_mime_list_action (const char *mime_string)
|
||||
GnomeVFSMimeAction *action;
|
||||
GnomeVFSMimeApplication *default_app;
|
||||
OAF_ServerInfo *default_component;
|
||||
const char *action_icon_name;
|
||||
char *text, *tmp_text;
|
||||
char *action_icon_path;
|
||||
char *text, *tmp_text, *icon_path;
|
||||
int row;
|
||||
|
||||
pixbuf = NULL;
|
||||
@@ -1423,22 +1589,19 @@ update_mime_list_action (const char *mime_string)
|
||||
action = gnome_vfs_mime_get_default_action (mime_string);
|
||||
if (action != NULL) {
|
||||
switch (action->action_type) {
|
||||
/* FIXME: Big hunks of this code are copied/pasted in several
|
||||
* places in this file. Need to use common routines. One way
|
||||
* to find them is to search for "nautilus/gnome-library.png"
|
||||
*/
|
||||
case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION:
|
||||
/* Get the default application */
|
||||
default_app = gnome_vfs_mime_get_default_application (mime_string);
|
||||
g_free (text);
|
||||
text = g_strdup (default_app->name);
|
||||
action_icon_name = gnome_vfs_mime_get_icon (mime_string);
|
||||
if (action_icon_name != NULL) {
|
||||
/* Get custom icon */
|
||||
action_icon_path = gnome_pixmap_file (action_icon_name);
|
||||
if (action_icon_path != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (action_icon_path);
|
||||
g_free (action_icon_path);
|
||||
}
|
||||
} else {
|
||||
/* Use default icon */
|
||||
pixbuf = gdk_pixbuf_new_from_file (DEFAULT_ACTION_ICON);
|
||||
text = g_strdup (default_app->name);
|
||||
icon_path = capplet_get_icon_path (DEFAULT_ACTION_ICON);
|
||||
if (icon_path != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (icon_path);
|
||||
g_free (icon_path);
|
||||
}
|
||||
gnome_vfs_mime_application_free (default_app);
|
||||
break;
|
||||
@@ -1450,7 +1613,11 @@ update_mime_list_action (const char *mime_string)
|
||||
tmp_text = name_from_oaf_server_info (default_component);
|
||||
text = g_strdup_printf (_("View as %s"), tmp_text);
|
||||
g_free (tmp_text);
|
||||
pixbuf = gdk_pixbuf_new_from_file ("/gnome/share/pixmaps/nautilus/gnome-library.png");
|
||||
icon_path = capplet_get_icon_path ("nautilus/gnome-library.png");
|
||||
if (icon_path != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (icon_path);
|
||||
g_free (icon_path);
|
||||
}
|
||||
CORBA_free (default_component);
|
||||
break;
|
||||
|
||||
@@ -1462,7 +1629,7 @@ update_mime_list_action (const char *mime_string)
|
||||
|
||||
/* Set column icon */
|
||||
if (pixbuf != NULL) {
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, 18, 18);
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST);
|
||||
gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100);
|
||||
gtk_clist_set_pixtext (GTK_CLIST (mime_list), row, 3, text, 5, pixmap, bitmap);
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
@@ -1473,30 +1640,30 @@ update_mime_list_action (const char *mime_string)
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
/* FIXME:
|
||||
* This routine is never called with is_executable TRUE anymore. It
|
||||
* could be simplified, possibly out of existence.
|
||||
*/
|
||||
static GdkPixbuf *
|
||||
capplet_get_icon_pixbuf (const char *mime_string, gboolean is_executable)
|
||||
{
|
||||
const char *description_icon_name;
|
||||
char *description_icon_path;
|
||||
const char *icon_name;
|
||||
char *icon_path;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
pixbuf = NULL;
|
||||
|
||||
description_icon_name = gnome_vfs_mime_get_icon (mime_string);
|
||||
if (description_icon_name != NULL) {
|
||||
/* Get custom icon */
|
||||
description_icon_path = gnome_vfs_icon_path_from_filename (description_icon_name);
|
||||
if (description_icon_path != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (description_icon_path);
|
||||
g_free (description_icon_path);
|
||||
}
|
||||
} else {
|
||||
if (!is_executable) {
|
||||
description_icon_path = gnome_vfs_icon_path_from_filename (DEFAULT_REGULAR_ICON);
|
||||
} else {
|
||||
description_icon_path = gnome_vfs_icon_path_from_filename (DEFAULT_ACTION_ICON);
|
||||
}
|
||||
pixbuf = gdk_pixbuf_new_from_file (description_icon_path);
|
||||
icon_name = gnome_vfs_mime_get_icon (mime_string);
|
||||
if (icon_name == NULL) {
|
||||
icon_name = is_executable
|
||||
? DEFAULT_ACTION_ICON
|
||||
: DEFAULT_REGULAR_ICON;
|
||||
}
|
||||
|
||||
icon_path = capplet_get_icon_path (icon_name);
|
||||
if (icon_path != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (icon_path);
|
||||
g_free (icon_path);
|
||||
}
|
||||
|
||||
return pixbuf;
|
||||
@@ -1507,6 +1674,7 @@ populate_mime_list (GList *type_list, GtkCList *clist)
|
||||
{
|
||||
char *text[4], *tmp_text;
|
||||
const char *description;
|
||||
char *icon_path;
|
||||
char *extensions, *mime_string;
|
||||
gint row;
|
||||
GList *element;
|
||||
@@ -1552,7 +1720,11 @@ populate_mime_list (GList *type_list, GtkCList *clist)
|
||||
pixbuf = capplet_get_icon_pixbuf (mime_string, FALSE);
|
||||
|
||||
if (pixbuf != NULL) {
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, 18, 18);
|
||||
/* FIXME: Big hunks of this code are copied/pasted in several
|
||||
* places in this file. Need to use common routines. One way
|
||||
* to find them is to search for MAX_ICON_WIDTH_IN_LIST
|
||||
*/
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST);
|
||||
gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100);
|
||||
gtk_clist_set_pixtext (clist, row, 0, text[0], 5, pixmap, bitmap);
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
@@ -1569,7 +1741,11 @@ populate_mime_list (GList *type_list, GtkCList *clist)
|
||||
g_free (text[3]);
|
||||
text[3] = g_strdup (default_app->name);
|
||||
|
||||
pixbuf = capplet_get_icon_pixbuf (mime_string, TRUE);
|
||||
icon_path = capplet_get_icon_path (DEFAULT_ACTION_ICON);
|
||||
if (icon_path != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (icon_path);
|
||||
g_free (icon_path);
|
||||
}
|
||||
gnome_vfs_mime_application_free (default_app);
|
||||
break;
|
||||
|
||||
@@ -1580,7 +1756,11 @@ populate_mime_list (GList *type_list, GtkCList *clist)
|
||||
tmp_text = name_from_oaf_server_info (default_component);
|
||||
text[3] = g_strdup_printf (_("View as %s"), tmp_text);
|
||||
g_free (tmp_text);
|
||||
pixbuf = gdk_pixbuf_new_from_file ("/gnome/share/pixmaps/nautilus/gnome-library.png");
|
||||
icon_path = capplet_get_icon_path ("nautilus/gnome-library.png");
|
||||
if (icon_path != NULL) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (icon_path);
|
||||
g_free (icon_path);
|
||||
}
|
||||
CORBA_free (default_component);
|
||||
break;
|
||||
|
||||
@@ -1592,7 +1772,7 @@ populate_mime_list (GList *type_list, GtkCList *clist)
|
||||
|
||||
/* Set column icon */
|
||||
if (pixbuf != NULL) {
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, 18, 18);
|
||||
pixbuf = capplet_gdk_pixbuf_scale_to_fit (pixbuf, MAX_ICON_WIDTH_IN_LIST, MAX_ICON_HEIGHT_IN_LIST);
|
||||
gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &bitmap, 100);
|
||||
gtk_clist_set_pixtext (clist, row, 3, text[3], 5, pixmap, bitmap);
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
@@ -1650,16 +1830,22 @@ sort_case_insensitive (GtkCList *clist, gpointer ptr1, gpointer ptr2)
|
||||
return strcasecmp (text1, text2);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
column_clicked (GtkCList *clist, gint column, gpointer user_data)
|
||||
{
|
||||
gtk_clist_set_sort_column (clist, column);
|
||||
|
||||
/* If the user has not clicked the column yet, make sure
|
||||
* that the sort type is descending the first time.
|
||||
*/
|
||||
if (!sort_column_clicked [column]) {
|
||||
clist->sort_type = GTK_SORT_DESCENDING;
|
||||
sort_column_clicked [column] = TRUE;
|
||||
}
|
||||
|
||||
/* Toggle sort type */
|
||||
if (clist->sort_type == GTK_SORT_ASCENDING) {
|
||||
gtk_clist_set_sort_type (clist, GTK_SORT_DESCENDING);
|
||||
|
||||
} else {
|
||||
gtk_clist_set_sort_type (clist, GTK_SORT_ASCENDING);
|
||||
}
|
||||
@@ -1667,6 +1853,17 @@ column_clicked (GtkCList *clist, gint column, gpointer user_data)
|
||||
gtk_clist_sort (clist);
|
||||
}
|
||||
|
||||
static void
|
||||
mime_list_reset_row_height (GtkCList *list)
|
||||
{
|
||||
guint height_for_icon;
|
||||
guint height_for_text;
|
||||
|
||||
height_for_icon = MAX_ICON_HEIGHT_IN_LIST + 1;
|
||||
height_for_text = GTK_WIDGET (list)->style->font->ascent +
|
||||
GTK_WIDGET (list)->style->font->descent + 1;
|
||||
gtk_clist_set_row_height (list, MAX (height_for_icon, height_for_text));
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_mime_list_and_scroller (void)
|
||||
@@ -1677,7 +1874,7 @@ create_mime_list_and_scroller (void)
|
||||
int index;
|
||||
|
||||
titles[0] = _("Description");
|
||||
titles[1] = _("Mime Type");
|
||||
titles[1] = _("MIME Type");
|
||||
titles[2] = _("Extension");
|
||||
titles[3] = _("Default Action");
|
||||
|
||||
@@ -1706,6 +1903,17 @@ create_mime_list_and_scroller (void)
|
||||
for (index = 0; index < TOTAL_COLUMNS; index++) {
|
||||
gtk_clist_set_column_auto_resize (GTK_CLIST (mime_list), index, FALSE);
|
||||
}
|
||||
|
||||
/* Make height tall enough for icons to look good.
|
||||
* This must be done after the list widget is realized, due to
|
||||
* a bug/design flaw in nautilus_clist_set_row_height. Connecting to
|
||||
* the "realize" signal is slightly too early, so we connect to
|
||||
* "map".
|
||||
*/
|
||||
gtk_signal_connect (GTK_OBJECT (mime_list),
|
||||
"map",
|
||||
mime_list_reset_row_height,
|
||||
NULL);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
7
capplets/file-types/file-types-capplet.desktop.in
Normal file
7
capplets/file-types/file-types-capplet.desktop.in
Normal file
@@ -0,0 +1,7 @@
|
||||
[Desktop Entry]
|
||||
_Name=File Types and Programs
|
||||
_Comment=Specify which programs are used to open or view each file type
|
||||
Icon=gnome-ccmime.png
|
||||
Exec=file-types-capplet
|
||||
Terminal=0
|
||||
Type=Application
|
||||
@@ -25,11 +25,11 @@
|
||||
#ifndef NAUTILUS_MIME_TYPE_CAPPLET_H
|
||||
#define NAUTILUS_MIME_TYPE_CAPPLET_H
|
||||
|
||||
void nautilus_mime_type_capplet_update_info (const char *mime_type);
|
||||
void nautilus_mime_type_capplet_update_application_info (const char *mime_type);
|
||||
void nautilus_mime_type_capplet_update_viewer_info (const char *mime_type);
|
||||
void nautilus_mime_type_capplet_add_extension (const char *extension);
|
||||
const char *nautilus_mime_type_capplet_get_selected_item_mime_type (void);
|
||||
void nautilus_mime_type_capplet_update_mime_list_icon (const char *mime_string);
|
||||
void nautilus_mime_type_capplet_update_info (const char *mime_type);
|
||||
void nautilus_mime_type_capplet_update_application_info (const char *mime_type);
|
||||
void nautilus_mime_type_capplet_update_viewer_info (const char *mime_type);
|
||||
void nautilus_mime_type_capplet_add_extension (const char *extension);
|
||||
const char *nautilus_mime_type_capplet_get_selected_item_mime_type (void);
|
||||
void nautilus_mime_type_capplet_update_mime_list_icon_and_description (const char *mime_string);
|
||||
|
||||
#endif /* NAUTILUS_MIME_TYPE_CAPPLET_H */
|
||||
|
||||
@@ -142,6 +142,7 @@ entry_activated(GtkWidget *widget, NautilusMimeIconEntry *ientry)
|
||||
struct stat buf;
|
||||
GnomeIconSelection * gis;
|
||||
gchar *filename;
|
||||
GtkButton *OK_button;
|
||||
|
||||
g_return_if_fail (widget != NULL);
|
||||
g_return_if_fail (GTK_IS_ENTRY (widget));
|
||||
@@ -161,9 +162,11 @@ entry_activated(GtkWidget *widget, NautilusMimeIconEntry *ientry)
|
||||
if (gis->file_list)
|
||||
gnome_icon_selection_show_icons(gis);
|
||||
} else {
|
||||
/* We pretend like ok has been called */
|
||||
entry_changed (NULL, ientry);
|
||||
gtk_widget_hide (ientry->pick_dialog);
|
||||
/* FIXME: This is a hack to act exactly like we've clicked the
|
||||
* OK button. This should be structured more cleanly.
|
||||
*/
|
||||
OK_button = GTK_BUTTON (GNOME_DIALOG (ientry->pick_dialog)->buttons->data);
|
||||
gtk_button_clicked (OK_button);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,41 +277,6 @@ browse_clicked (GnomeFileEntry *fentry, NautilusMimeIconEntry *ientry)
|
||||
GTK_OBJECT(fs));
|
||||
}
|
||||
|
||||
static void
|
||||
icon_selected_cb (GtkButton *button, NautilusMimeIconEntry *icon_entry)
|
||||
{
|
||||
const gchar *icon;
|
||||
GnomeIconSelection *gis;
|
||||
gchar *path, *filename;
|
||||
const char *mime_type;
|
||||
GtkWidget *entry;
|
||||
|
||||
g_return_if_fail (icon_entry != NULL);
|
||||
g_return_if_fail (NAUTILUS_MIME_IS_ICON_ENTRY (icon_entry));
|
||||
|
||||
gis = gtk_object_get_user_data (GTK_OBJECT (icon_entry));
|
||||
gnome_icon_selection_stop_loading (gis);
|
||||
icon = gnome_icon_selection_get_icon (gis, TRUE);
|
||||
|
||||
if (icon != NULL) {
|
||||
entry = nautilus_mime_type_icon_entry_gtk_entry (icon_entry);
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), icon);
|
||||
entry_changed (NULL, icon_entry);
|
||||
|
||||
path = nautilus_mime_type_icon_entry_get_relative_filename (NAUTILUS_MIME_ICON_ENTRY (icon_entry));
|
||||
if (path != NULL) {
|
||||
filename = strrchr (path, '/');
|
||||
if (filename != NULL) {
|
||||
filename++;
|
||||
mime_type = nautilus_mime_type_capplet_get_selected_item_mime_type ();
|
||||
gnome_vfs_mime_set_icon (mime_type, filename);
|
||||
nautilus_mime_type_capplet_update_mime_list_icon (mime_type);
|
||||
}
|
||||
g_free (path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cancel_pressed (GtkButton * button, NautilusMimeIconEntry * icon_entry)
|
||||
{
|
||||
@@ -322,31 +290,6 @@ cancel_pressed (GtkButton * button, NautilusMimeIconEntry * icon_entry)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gil_icon_selected_cb (GnomeIconList *gil, gint num, GdkEvent *event, NautilusMimeIconEntry *icon_entry)
|
||||
{
|
||||
const gchar * icon;
|
||||
GnomeIconSelection * gis;
|
||||
|
||||
g_return_if_fail (icon_entry != NULL);
|
||||
g_return_if_fail (NAUTILUS_MIME_IS_ICON_ENTRY (icon_entry));
|
||||
|
||||
gis = gtk_object_get_user_data(GTK_OBJECT(icon_entry));
|
||||
icon = gnome_icon_selection_get_icon(gis, TRUE);
|
||||
|
||||
if (icon != NULL) {
|
||||
GtkWidget *e = nautilus_mime_type_icon_entry_gtk_entry(icon_entry);
|
||||
gtk_entry_set_text(GTK_ENTRY(e),icon);
|
||||
|
||||
}
|
||||
|
||||
if(event && event->type == GDK_2BUTTON_PRESS && ((GdkEventButton *)event)->button == 1) {
|
||||
gnome_icon_selection_stop_loading(gis);
|
||||
entry_changed (NULL, icon_entry);
|
||||
gtk_widget_hide(icon_entry->pick_dialog);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_mime_type_show_icon_selection (NautilusMimeIconEntry *icon_entry)
|
||||
{
|
||||
@@ -360,7 +303,7 @@ nautilus_mime_type_show_icon_selection (NautilusMimeIconEntry *icon_entry)
|
||||
|
||||
fe = GNOME_FILE_ENTRY (icon_entry->fentry);
|
||||
p = gnome_file_entry_get_full_path (fe, FALSE);
|
||||
curfile = nautilus_mime_type_icon_entry_get_filename (icon_entry);
|
||||
curfile = nautilus_mime_type_icon_entry_get_full_filename (icon_entry);
|
||||
|
||||
/* Are we part of a modal window? If so, we need to be modal too. */
|
||||
tl = gtk_widget_get_toplevel (GTK_WIDGET (icon_entry->frame));
|
||||
@@ -434,12 +377,12 @@ nautilus_mime_type_show_icon_selection (NautilusMimeIconEntry *icon_entry)
|
||||
gtk_object_set_user_data(GTK_OBJECT(icon_entry), iconsel);
|
||||
|
||||
gnome_icon_selection_add_directory (GNOME_ICON_SELECTION(iconsel), icon_entry->pick_dialog_dir);
|
||||
|
||||
/* Hide the file entry until we figure out how to deal with icon paths
|
||||
outside of the standard gnome paths */
|
||||
/*gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (icon_entry->pick_dialog)->vbox),
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (icon_entry->pick_dialog), _("Select an icon"));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (icon_entry->pick_dialog)->vbox),
|
||||
icon_entry->fentry, FALSE, FALSE, 0);
|
||||
*/
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(icon_entry->pick_dialog)->vbox),
|
||||
iconsel, TRUE, TRUE, 0);
|
||||
|
||||
@@ -451,17 +394,15 @@ nautilus_mime_type_show_icon_selection (NautilusMimeIconEntry *icon_entry)
|
||||
gnome_icon_selection_select_icon(GNOME_ICON_SELECTION(iconsel),
|
||||
g_filename_pointer(curfile));
|
||||
|
||||
gnome_dialog_button_connect(GNOME_DIALOG (icon_entry->pick_dialog),
|
||||
0, /* OK button */
|
||||
GTK_SIGNAL_FUNC (icon_selected_cb),
|
||||
icon_entry);
|
||||
/* FIXME:
|
||||
* OK button is handled by caller, Cancel button is handled here.
|
||||
* This could be cleaned up further.
|
||||
*/
|
||||
gnome_dialog_button_connect(GNOME_DIALOG(icon_entry->pick_dialog),
|
||||
1, /* Cancel button */
|
||||
GTK_SIGNAL_FUNC(cancel_pressed),
|
||||
icon_entry);
|
||||
gtk_signal_connect_after(GTK_OBJECT(GNOME_ICON_SELECTION(iconsel)->gil), "select_icon",
|
||||
GTK_SIGNAL_FUNC(gil_icon_selected_cb),
|
||||
icon_entry);
|
||||
|
||||
} else {
|
||||
GnomeIconSelection *gis =
|
||||
gtk_object_get_user_data(GTK_OBJECT(icon_entry));
|
||||
@@ -476,27 +417,24 @@ nautilus_mime_type_show_icon_selection (NautilusMimeIconEntry *icon_entry)
|
||||
gchar *
|
||||
nautilus_mime_type_icon_entry_get_relative_filename (NautilusMimeIconEntry *ientry)
|
||||
{
|
||||
char *filename;
|
||||
char **path_parts;
|
||||
char *filename;
|
||||
char *result;
|
||||
char **path_parts;
|
||||
|
||||
result = NULL;
|
||||
filename = nautilus_mime_type_icon_entry_get_full_filename (NAUTILUS_MIME_ICON_ENTRY (ientry));
|
||||
if (filename != NULL) {
|
||||
path_parts = g_strsplit (filename, "/share/pixmaps/", 0);
|
||||
g_free (filename);
|
||||
|
||||
filename = nautilus_mime_type_icon_entry_get_filename (NAUTILUS_MIME_ICON_ENTRY (ientry));
|
||||
if (path_parts[1] != NULL) {
|
||||
result = g_strdup (path_parts[1]);
|
||||
}
|
||||
|
||||
path_parts = g_strsplit (filename, "/share/pixmaps/", 0);
|
||||
g_free (filename);
|
||||
filename = NULL;
|
||||
|
||||
if (path_parts[1] != NULL) {
|
||||
filename = g_strdup (path_parts[1]);
|
||||
} else {
|
||||
/* FIXME: bugzilla.eazel.com 4797 */
|
||||
g_warning ("user picked up an icon not in $(prefix)/share/pixmaps\n");
|
||||
filename = g_strdup ("");
|
||||
g_strfreev (path_parts);
|
||||
}
|
||||
|
||||
g_strfreev (path_parts);
|
||||
|
||||
return filename;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -690,7 +628,7 @@ nautilus_mime_type_icon_entry_set_icon (NautilusMimeIconEntry *ientry, const gch
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_mime_type_icon_entry_get_filename:
|
||||
* nautilus_mime_type_icon_entry_get_full_filename:
|
||||
* @ientry: the NautilusMimeIconEntry to work with
|
||||
*
|
||||
* Description: Gets the file name of the image if it was possible
|
||||
@@ -701,7 +639,7 @@ nautilus_mime_type_icon_entry_set_icon (NautilusMimeIconEntry *ientry, const gch
|
||||
* couldn't load the file
|
||||
**/
|
||||
gchar *
|
||||
nautilus_mime_type_icon_entry_get_filename (NautilusMimeIconEntry *ientry)
|
||||
nautilus_mime_type_icon_entry_get_full_filename (NautilusMimeIconEntry *ientry)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ GtkWidget *nautilus_mime_type_icon_entry_gnome_entry (NautilusMimeIconEntry *ien
|
||||
GtkWidget *nautilus_mime_type_icon_entry_gtk_entry (NautilusMimeIconEntry *ientry);
|
||||
|
||||
/*only return a file if it was possible to load it with imlib*/
|
||||
gchar *nautilus_mime_type_icon_entry_get_filename (NautilusMimeIconEntry *ientry);
|
||||
gchar *nautilus_mime_type_icon_entry_get_full_filename (NautilusMimeIconEntry *ientry);
|
||||
gchar *nautilus_mime_type_icon_entry_get_relative_filename (NautilusMimeIconEntry *ientry);
|
||||
void nautilus_mime_type_show_icon_selection (NautilusMimeIconEntry * ientry);
|
||||
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
Makefile.in
|
||||
Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
27
capplets/file-types/libuuid/Makefile.am
Normal file
27
capplets/file-types/libuuid/Makefile.am
Normal file
@@ -0,0 +1,27 @@
|
||||
NULL =
|
||||
|
||||
noinst_LIBRARIES = libuuid.a
|
||||
|
||||
|
||||
noinst_HEADERS = \
|
||||
uuid.h \
|
||||
uuidP.h \
|
||||
$(NULL)
|
||||
|
||||
libuuid_a_SOURCES = \
|
||||
clear.c \
|
||||
compare.c \
|
||||
copy.c \
|
||||
gen_uuid.c \
|
||||
isnull.c \
|
||||
pack.c \
|
||||
parse.c \
|
||||
unpack.c \
|
||||
unparse.c \
|
||||
uuid_time.c \
|
||||
$(NULL)
|
||||
|
||||
INCLUDES = \
|
||||
$(GLIB_CFLAGS) \
|
||||
$(WERROR) \
|
||||
$(NULL)
|
||||
20
capplets/file-types/libuuid/clear.c
Normal file
20
capplets/file-types/libuuid/clear.c
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* clear.c -- Clear a UUID
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "string.h"
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
void uuid_clear(uuid_t uu)
|
||||
{
|
||||
memset(uu, 0, 16);
|
||||
}
|
||||
|
||||
32
capplets/file-types/libuuid/compare.c
Normal file
32
capplets/file-types/libuuid/compare.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* compare.c --- compare whether or not two UUID's are the same
|
||||
*
|
||||
* Returns 0 if the two UUID's are different, and 1 if they are the same.
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "uuidP.h"
|
||||
#include <string.h>
|
||||
|
||||
#define UUCMP(u1,u2) if (u1 != u2) return((u1 < u2) ? -1 : 1);
|
||||
|
||||
int uuid_compare(uuid_t uu1, uuid_t uu2)
|
||||
{
|
||||
struct uuid uuid1, uuid2;
|
||||
|
||||
uuid_unpack(uu1, &uuid1);
|
||||
uuid_unpack(uu2, &uuid2);
|
||||
|
||||
UUCMP(uuid1.time_low, uuid2.time_low);
|
||||
UUCMP(uuid1.time_mid, uuid2.time_mid);
|
||||
UUCMP(uuid1.time_hi_and_version, uuid2.time_hi_and_version);
|
||||
UUCMP(uuid1.clock_seq, uuid2.clock_seq);
|
||||
return memcmp(uuid1.node, uuid2.node, 6);
|
||||
}
|
||||
|
||||
21
capplets/file-types/libuuid/copy.c
Normal file
21
capplets/file-types/libuuid/copy.c
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* copy.c --- copy UUIDs
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
void uuid_copy(uuid_t uu1, uuid_t uu2)
|
||||
{
|
||||
unsigned char *cp1, *cp2;
|
||||
int i;
|
||||
|
||||
for (i=0, cp1 = uu1, cp2 = uu2; i < 16; i++)
|
||||
*cp1++ = *cp2++;
|
||||
}
|
||||
257
capplets/file-types/libuuid/gen_uuid.c
Normal file
257
capplets/file-types/libuuid/gen_uuid.c
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* gen_uuid.c --- generate a DCE-compatible uuid
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef HAVE_SYS_SOCKIO_H
|
||||
#include <sys/sockio.h>
|
||||
#endif
|
||||
#ifdef HAVE_NET_IF_H
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
#ifdef HAVE_SRANDOM
|
||||
#define srand(x) srandom(x)
|
||||
#define rand() random()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Generate a series of random bytes. Use /dev/urandom if possible,
|
||||
* and if not, use srandom/random.
|
||||
*/
|
||||
static void get_random_bytes(void *buf, int nbytes)
|
||||
{
|
||||
static int fd = -2;
|
||||
int i;
|
||||
char *cp = (char *) buf;
|
||||
|
||||
if (fd == -2) {
|
||||
fd = open("/dev/urandom", O_RDONLY);
|
||||
srand((getpid() << 16) ^ getuid() ^ time(0));
|
||||
}
|
||||
if (fd >= 0) {
|
||||
while (nbytes > 0) {
|
||||
i = read(fd, cp, nbytes);
|
||||
if (i < 0) {
|
||||
if ((errno == EINTR) || (errno == EAGAIN))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
nbytes -= i;
|
||||
cp += i;
|
||||
}
|
||||
}
|
||||
if (nbytes == 0)
|
||||
return;
|
||||
|
||||
/* XXX put something better here if no /dev/random! */
|
||||
for (i=0; i < nbytes; i++)
|
||||
*cp++ = rand() & 0xFF;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the ethernet hardware address, if we can find it...
|
||||
*/
|
||||
static int get_node_id(unsigned char *node_id)
|
||||
{
|
||||
#ifdef HAVE_NET_IF_H
|
||||
int sd;
|
||||
struct ifreq ifr, *ifrp;
|
||||
struct ifconf ifc;
|
||||
char buf[1024];
|
||||
int n, i;
|
||||
unsigned char *a;
|
||||
|
||||
/*
|
||||
* BSD 4.4 defines the size of an ifreq to be
|
||||
* max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
|
||||
* However, under earlier systems, sa_len isn't present, so the size is
|
||||
* just sizeof(struct ifreq)
|
||||
*/
|
||||
#ifdef HAVE_SA_LEN
|
||||
#ifndef max
|
||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
#define ifreq_size(i) max(sizeof(struct ifreq),\
|
||||
sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
|
||||
#else
|
||||
#define ifreq_size(i) sizeof(struct ifreq)
|
||||
#endif /* HAVE_SA_LEN*/
|
||||
|
||||
sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
if (sd < 0) {
|
||||
return -1;
|
||||
}
|
||||
memset(buf, 0, sizeof(buf));
|
||||
ifc.ifc_len = sizeof(buf);
|
||||
ifc.ifc_buf = buf;
|
||||
if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
n = ifc.ifc_len;
|
||||
for (i = 0; i < n; i+= ifreq_size(*ifr) ) {
|
||||
ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);
|
||||
strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
|
||||
#ifdef SIOCGIFHWADDR
|
||||
if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
|
||||
continue;
|
||||
a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
|
||||
#else
|
||||
#ifdef SIOCGENADDR
|
||||
if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
|
||||
continue;
|
||||
a = (unsigned char *) ifr.ifr_enaddr;
|
||||
#else
|
||||
/*
|
||||
* XXX we don't have a way of getting the hardware
|
||||
* address
|
||||
*/
|
||||
close(sd);
|
||||
return 0;
|
||||
#endif /* SIOCGENADDR */
|
||||
#endif /* SIOCGIFHWADDR */
|
||||
if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
|
||||
continue;
|
||||
if (node_id) {
|
||||
memcpy(node_id, a, 6);
|
||||
close(sd);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
close(sd);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Assume that the gettimeofday() has microsecond granularity */
|
||||
#define MAX_ADJUSTMENT 10
|
||||
|
||||
static int get_clock(guint32 *clock_high, guint32 *clock_low, guint16 *ret_clock_seq)
|
||||
{
|
||||
static int adjustment = 0;
|
||||
static struct timeval last = {0, 0};
|
||||
static guint16 clock_seq;
|
||||
struct timeval tv;
|
||||
unsigned long long clock_reg;
|
||||
|
||||
try_again:
|
||||
gettimeofday(&tv, 0);
|
||||
if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
|
||||
get_random_bytes(&clock_seq, sizeof(clock_seq));
|
||||
clock_seq &= 0x1FFF;
|
||||
last = tv;
|
||||
last.tv_sec--;
|
||||
}
|
||||
if ((tv.tv_sec < last.tv_sec) ||
|
||||
((tv.tv_sec == last.tv_sec) &&
|
||||
(tv.tv_usec < last.tv_usec))) {
|
||||
clock_seq = (clock_seq+1) & 0x1FFF;
|
||||
adjustment = 0;
|
||||
} else if ((tv.tv_sec == last.tv_sec) &&
|
||||
(tv.tv_usec == last.tv_usec)) {
|
||||
if (adjustment >= MAX_ADJUSTMENT)
|
||||
goto try_again;
|
||||
adjustment++;
|
||||
} else
|
||||
adjustment = 0;
|
||||
|
||||
clock_reg = tv.tv_usec*10 + adjustment;
|
||||
clock_reg += ((unsigned long long) tv.tv_sec)*10000000;
|
||||
clock_reg += (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
|
||||
|
||||
*clock_high = clock_reg >> 32;
|
||||
*clock_low = clock_reg;
|
||||
*ret_clock_seq = clock_seq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uuid_generate_time(uuid_t out)
|
||||
{
|
||||
static unsigned char node_id[6];
|
||||
static int has_init = 0;
|
||||
struct uuid uu;
|
||||
guint32 clock_mid;
|
||||
|
||||
if (!has_init) {
|
||||
if (get_node_id(node_id) <= 0) {
|
||||
get_random_bytes(node_id, 6);
|
||||
/*
|
||||
* Set multicast bit, to prevent conflicts
|
||||
* with IEEE 802 addresses obtained from
|
||||
* network cards
|
||||
*/
|
||||
node_id[0] |= 0x80;
|
||||
}
|
||||
has_init = 1;
|
||||
}
|
||||
get_clock(&clock_mid, &uu.time_low, &uu.clock_seq);
|
||||
uu.clock_seq |= 0x8000;
|
||||
uu.time_mid = (guint16) clock_mid;
|
||||
uu.time_hi_and_version = (clock_mid >> 16) | 0x1000;
|
||||
memcpy(uu.node, node_id, 6);
|
||||
uuid_pack(&uu, out);
|
||||
}
|
||||
|
||||
void uuid_generate_random(uuid_t out)
|
||||
{
|
||||
uuid_t buf;
|
||||
struct uuid uu;
|
||||
|
||||
get_random_bytes(buf, sizeof(buf));
|
||||
uuid_unpack(buf, &uu);
|
||||
|
||||
uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
|
||||
uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
|
||||
uuid_pack(&uu, out);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the generic front-end to uuid_generate_random and
|
||||
* uuid_generate_time. It uses uuid_generate_random only if
|
||||
* /dev/urandom is available, since otherwise we won't have
|
||||
* high-quality randomness.
|
||||
*/
|
||||
void uuid_generate(uuid_t out)
|
||||
{
|
||||
static int has_random = -1;
|
||||
|
||||
if (has_random < 0) {
|
||||
if (access("/dev/urandom", R_OK) == 0)
|
||||
has_random = 1;
|
||||
else
|
||||
has_random = 0;
|
||||
}
|
||||
if (has_random)
|
||||
uuid_generate_random(out);
|
||||
else
|
||||
uuid_generate_time(out);
|
||||
}
|
||||
|
||||
92
capplets/file-types/libuuid/gen_uuid_nt.c
Normal file
92
capplets/file-types/libuuid/gen_uuid_nt.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* gen_uuid_nt.c -- Use NT api to generate uuid
|
||||
*
|
||||
* Written by Andrey Shedel (andreys@ns.cr.cyco.com)
|
||||
*/
|
||||
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
#pragma warning(push,4)
|
||||
|
||||
#pragma comment(lib, "ntdll.lib")
|
||||
|
||||
//
|
||||
// Here is a nice example why it's not a good idea
|
||||
// to use native API in ordinary applications.
|
||||
// Number of parameters in function below was changed from 3 to 4
|
||||
// for NT5.
|
||||
//
|
||||
//
|
||||
// NTSYSAPI
|
||||
// NTSTATUS
|
||||
// NTAPI
|
||||
// NtAllocateUuids(
|
||||
// OUT PULONG p1,
|
||||
// OUT PULONG p2,
|
||||
// OUT PULONG p3,
|
||||
// OUT PUCHAR Seed // 6 bytes
|
||||
// );
|
||||
//
|
||||
//
|
||||
|
||||
unsigned long
|
||||
__stdcall
|
||||
NtAllocateUuids(
|
||||
void* p1, // 8 bytes
|
||||
void* p2, // 4 bytes
|
||||
void* p3 // 4 bytes
|
||||
);
|
||||
|
||||
typedef
|
||||
unsigned long
|
||||
(__stdcall*
|
||||
NtAllocateUuids_2000)(
|
||||
void* p1, // 8 bytes
|
||||
void* p2, // 4 bytes
|
||||
void* p3, // 4 bytes
|
||||
void* seed // 6 bytes
|
||||
);
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Nice, but instead of including ntddk.h ot winnt.h
|
||||
// I should define it here because they MISSED __stdcall in those headers.
|
||||
//
|
||||
|
||||
__declspec(dllimport)
|
||||
struct _TEB*
|
||||
__stdcall
|
||||
NtCurrentTeb(void);
|
||||
|
||||
|
||||
//
|
||||
// The only way to get version information from the system is to examine
|
||||
// one stored in PEB. But it's pretty dangerouse because this value could
|
||||
// be altered in image header.
|
||||
//
|
||||
|
||||
static
|
||||
int
|
||||
Nt5(void)
|
||||
{
|
||||
//return NtCuttentTeb()->Peb->OSMajorVersion >= 5;
|
||||
return (int)*(int*)((char*)(int)(*(int*)((char*)NtCurrentTeb() + 0x30)) + 0xA4) >= 5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void uuid_generate(uuid_t out)
|
||||
{
|
||||
if(Nt5())
|
||||
{
|
||||
unsigned char seed[6];
|
||||
((NtAllocateUuids_2000)NtAllocateUuids)(out, ((char*)out)+8, ((char*)out)+12, &seed[0] );
|
||||
}
|
||||
else
|
||||
{
|
||||
NtAllocateUuids(out, ((char*)out)+8, ((char*)out)+12);
|
||||
}
|
||||
}
|
||||
25
capplets/file-types/libuuid/isnull.c
Normal file
25
capplets/file-types/libuuid/isnull.c
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* isnull.c --- Check whether or not the UUID is null
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
/* Returns 1 if the uuid is the NULL uuid */
|
||||
int uuid_is_null(uuid_t uu)
|
||||
{
|
||||
unsigned char *cp;
|
||||
int i;
|
||||
|
||||
for (i=0, cp = uu; i < 16; i++)
|
||||
if (*cp++)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
46
capplets/file-types/libuuid/pack.c
Normal file
46
capplets/file-types/libuuid/pack.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Internal routine for packing UUID's
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "uuidP.h"
|
||||
|
||||
void uuid_pack(struct uuid *uu, uuid_t ptr)
|
||||
{
|
||||
guint32 tmp;
|
||||
unsigned char *out = ptr;
|
||||
|
||||
tmp = uu->time_low;
|
||||
out[3] = (unsigned char) tmp;
|
||||
tmp >>= 8;
|
||||
out[2] = (unsigned char) tmp;
|
||||
tmp >>= 8;
|
||||
out[1] = (unsigned char) tmp;
|
||||
tmp >>= 8;
|
||||
out[0] = (unsigned char) tmp;
|
||||
|
||||
tmp = uu->time_mid;
|
||||
out[5] = (unsigned char) tmp;
|
||||
tmp >>= 8;
|
||||
out[4] = (unsigned char) tmp;
|
||||
|
||||
tmp = uu->time_hi_and_version;
|
||||
out[7] = (unsigned char) tmp;
|
||||
tmp >>= 8;
|
||||
out[6] = (unsigned char) tmp;
|
||||
|
||||
tmp = uu->clock_seq;
|
||||
out[9] = (unsigned char) tmp;
|
||||
tmp >>= 8;
|
||||
out[8] = (unsigned char) tmp;
|
||||
|
||||
memcpy(out+10, uu->node, 6);
|
||||
}
|
||||
|
||||
52
capplets/file-types/libuuid/parse.c
Normal file
52
capplets/file-types/libuuid/parse.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* parse.c --- UUID parsing
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
int uuid_parse(char *in, uuid_t uu)
|
||||
{
|
||||
struct uuid uuid;
|
||||
int i;
|
||||
char *cp, buf[3];
|
||||
|
||||
if (strlen(in) != 36)
|
||||
return -1;
|
||||
for (i=0, cp = in; i <= 36; i++,cp++) {
|
||||
if ((i == 8) || (i == 13) || (i == 18) ||
|
||||
(i == 23))
|
||||
if (*cp == '-')
|
||||
continue;
|
||||
if (i== 36)
|
||||
if (*cp == 0)
|
||||
continue;
|
||||
if (!isxdigit((guchar) *cp))
|
||||
return -1;
|
||||
}
|
||||
uuid.time_low = strtoul(in, NULL, 16);
|
||||
uuid.time_mid = strtoul(in+9, NULL, 16);
|
||||
uuid.time_hi_and_version = strtoul(in+14, NULL, 16);
|
||||
uuid.clock_seq = strtoul(in+19, NULL, 16);
|
||||
cp = in+24;
|
||||
buf[2] = 0;
|
||||
for (i=0; i < 6; i++) {
|
||||
buf[0] = *cp++;
|
||||
buf[1] = *cp++;
|
||||
uuid.node[i] = strtoul(buf, NULL, 16);
|
||||
}
|
||||
|
||||
uuid_pack(&uuid, uu);
|
||||
return 0;
|
||||
}
|
||||
119
capplets/file-types/libuuid/tst_uuid.c
Normal file
119
capplets/file-types/libuuid/tst_uuid.c
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* tst_uuid.c --- test program from the UUID library
|
||||
*
|
||||
* Copyright (C) 1996, 1997, 1998 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <linux/ext2_fs.h>
|
||||
|
||||
#include "uuid.h"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
uuid_t buf, tst;
|
||||
char str[100];
|
||||
struct timeval tv;
|
||||
time_t time_reg;
|
||||
unsigned char *cp;
|
||||
int i;
|
||||
int failed = 0;
|
||||
int type, variant;
|
||||
|
||||
uuid_generate(buf);
|
||||
uuid_unparse(buf, str);
|
||||
printf("UUID generate = %s\n", str);
|
||||
printf("UUID: ");
|
||||
for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
|
||||
printf("%02x", *cp++);
|
||||
}
|
||||
printf("\n");
|
||||
type = uuid_type(buf); variant = uuid_variant(buf);
|
||||
printf("UUID type = %d, UUID variant = %d\n", type, variant);
|
||||
if (variant != UUID_VARIANT_DCE) {
|
||||
printf("Incorrect UUID Variant; was expecting DCE!\n");
|
||||
failed++;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
uuid_generate_random(buf);
|
||||
uuid_unparse(buf, str);
|
||||
printf("UUID random string = %s\n", str);
|
||||
printf("UUID: ");
|
||||
for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
|
||||
printf("%02x", *cp++);
|
||||
}
|
||||
printf("\n");
|
||||
type = uuid_type(buf); variant = uuid_variant(buf);
|
||||
printf("UUID type = %d, UUID variant = %d\n", type, variant);
|
||||
if (variant != UUID_VARIANT_DCE) {
|
||||
printf("Incorrect UUID Variant; was expecting DCE!\n");
|
||||
failed++;
|
||||
}
|
||||
if (type != 4) {
|
||||
printf("Incorrect UUID type; was expecting "
|
||||
"4 (random type)!\n");
|
||||
failed++;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
uuid_generate_time(buf);
|
||||
uuid_unparse(buf, str);
|
||||
printf("UUID string = %s\n", str);
|
||||
printf("UUID time: ");
|
||||
for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
|
||||
printf("%02x", *cp++);
|
||||
}
|
||||
printf("\n");
|
||||
type = uuid_type(buf); variant = uuid_variant(buf);
|
||||
printf("UUID type = %d, UUID variant = %d\n", type, variant);
|
||||
if (variant != UUID_VARIANT_DCE) {
|
||||
printf("Incorrect UUID Variant; was expecting DCE!\n");
|
||||
failed++;
|
||||
}
|
||||
if (type != 1) {
|
||||
printf("Incorrect UUID type; was expecting "
|
||||
"1 (time-based type)!\\n");
|
||||
failed++;
|
||||
}
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
time_reg = uuid_time(buf, &tv);
|
||||
printf("UUID time is: (%d, %d): %s\n", tv.tv_sec, tv.tv_usec,
|
||||
ctime(&time_reg));
|
||||
uuid_parse(str, tst);
|
||||
if (!uuid_compare(buf, tst))
|
||||
printf("UUID parse and compare succeeded.\n");
|
||||
else {
|
||||
printf("UUID parse and compare failed!\n");
|
||||
failed++;
|
||||
}
|
||||
uuid_clear(tst);
|
||||
if (uuid_is_null(tst))
|
||||
printf("UUID clear and is null succeeded.\n");
|
||||
else {
|
||||
printf("UUID clear and is null failed!\n");
|
||||
failed++;
|
||||
}
|
||||
uuid_copy(buf, tst);
|
||||
if (!uuid_compare(buf, tst))
|
||||
printf("UUID copy and compare succeeded.\n");
|
||||
else {
|
||||
printf("UUID copy and compare failed!\n");
|
||||
failed++;
|
||||
}
|
||||
if (failed) {
|
||||
printf("%d failures.\n", failed);
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
40
capplets/file-types/libuuid/unpack.c
Normal file
40
capplets/file-types/libuuid/unpack.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Internal routine for unpacking UUID
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "uuidP.h"
|
||||
|
||||
void uuid_unpack(uuid_t in, struct uuid *uu)
|
||||
{
|
||||
guint8 *ptr = in;
|
||||
guint32 tmp;
|
||||
|
||||
tmp = *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
uu->time_low = tmp;
|
||||
|
||||
tmp = *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
uu->time_mid = tmp;
|
||||
|
||||
tmp = *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
uu->time_hi_and_version = tmp;
|
||||
|
||||
tmp = *ptr++;
|
||||
tmp = (tmp << 8) | *ptr++;
|
||||
uu->clock_seq = tmp;
|
||||
|
||||
memcpy(uu->node, ptr, 6);
|
||||
}
|
||||
|
||||
28
capplets/file-types/libuuid/unparse.c
Normal file
28
capplets/file-types/libuuid/unparse.c
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* unparse.c -- convert a UUID to string
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
void uuid_unparse(uuid_t uu, char *out)
|
||||
{
|
||||
struct uuid uuid;
|
||||
|
||||
uuid_unpack(uu, &uuid);
|
||||
sprintf(out,
|
||||
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
|
||||
uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
|
||||
uuid.node[0], uuid.node[1], uuid.node[2],
|
||||
uuid.node[3], uuid.node[4], uuid.node[5]);
|
||||
}
|
||||
|
||||
50
capplets/file-types/libuuid/uuid.h
Normal file
50
capplets/file-types/libuuid/uuid.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Public include file for the UUID library
|
||||
*
|
||||
* Copyright (C) 1996, 1997, 1998 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
typedef unsigned char uuid_t[16];
|
||||
|
||||
/* UUID Variant definitions */
|
||||
#define UUID_VARIANT_NCS 0
|
||||
#define UUID_VARIANT_DCE 1
|
||||
#define UUID_VARIANT_MICROSOFT 2
|
||||
#define UUID_VARIANT_OTHER 3
|
||||
|
||||
/* clear.c */
|
||||
void uuid_clear(uuid_t uu);
|
||||
|
||||
/* compare.c */
|
||||
int uuid_compare(uuid_t uu1, uuid_t uu2);
|
||||
|
||||
/* copy.c */
|
||||
void uuid_copy(uuid_t uu1, uuid_t uu2);
|
||||
|
||||
/* gen_uuid.c */
|
||||
void uuid_generate(uuid_t out);
|
||||
void uuid_generate_random(uuid_t out);
|
||||
void uuid_generate_time(uuid_t out);
|
||||
|
||||
/* isnull.c */
|
||||
int uuid_is_null(uuid_t uu);
|
||||
|
||||
/* parse.c */
|
||||
int uuid_parse(char *in, uuid_t uu);
|
||||
|
||||
/* unparse.c */
|
||||
void uuid_unparse(uuid_t uu, char *out);
|
||||
|
||||
/* uuid_time.c */
|
||||
time_t uuid_time(uuid_t uu, struct timeval *ret_tv);
|
||||
int uuid_type(uuid_t uu);
|
||||
int uuid_variant(uuid_t uu);
|
||||
40
capplets/file-types/libuuid/uuidP.h
Normal file
40
capplets/file-types/libuuid/uuidP.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* uuid.h -- private header file for uuids
|
||||
*
|
||||
* Copyright (C) 1996, 1997 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "uuid.h"
|
||||
|
||||
/*
|
||||
* Offset between 15-Oct-1582 and 1-Jan-70
|
||||
*/
|
||||
#define TIME_OFFSET_HIGH 0x01B21DD2
|
||||
#define TIME_OFFSET_LOW 0x13814000
|
||||
|
||||
struct uuid {
|
||||
guint32 time_low;
|
||||
guint16 time_mid;
|
||||
guint16 time_hi_and_version;
|
||||
guint16 clock_seq;
|
||||
guint8 node[6];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* prototypes
|
||||
*/
|
||||
void uuid_pack(struct uuid *uu, uuid_t ptr);
|
||||
void uuid_unpack(uuid_t in, struct uuid *uu);
|
||||
|
||||
|
||||
|
||||
|
||||
138
capplets/file-types/libuuid/uuid_time.c
Normal file
138
capplets/file-types/libuuid/uuid_time.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* uuid_time.c --- Interpret the time field from a uuid. This program
|
||||
* violates the UUID abstraction barrier by reaching into the guts
|
||||
* of a UUID and interpreting it.
|
||||
*
|
||||
* Copyright (C) 1998, 1999 Theodore Ts'o.
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "uuidP.h"
|
||||
|
||||
time_t uuid_time(uuid_t uu, struct timeval *ret_tv)
|
||||
{
|
||||
struct uuid uuid;
|
||||
guint32 high;
|
||||
struct timeval tv;
|
||||
unsigned long long clock_reg;
|
||||
|
||||
uuid_unpack(uu, &uuid);
|
||||
|
||||
high = uuid.time_mid | ((uuid.time_hi_and_version & 0xFFF) << 16);
|
||||
clock_reg = uuid.time_low | ((unsigned long long) high << 32);
|
||||
|
||||
clock_reg -= (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
|
||||
tv.tv_sec = clock_reg / 10000000;
|
||||
tv.tv_usec = (clock_reg % 10000000) / 10;
|
||||
|
||||
if (ret_tv)
|
||||
*ret_tv = tv;
|
||||
|
||||
return tv.tv_sec;
|
||||
}
|
||||
|
||||
int uuid_type(uuid_t uu)
|
||||
{
|
||||
struct uuid uuid;
|
||||
|
||||
uuid_unpack(uu, &uuid);
|
||||
return ((uuid.time_hi_and_version >> 12) & 0xF);
|
||||
}
|
||||
|
||||
int uuid_variant(uuid_t uu)
|
||||
{
|
||||
struct uuid uuid;
|
||||
int var;
|
||||
|
||||
uuid_unpack(uu, &uuid);
|
||||
var = uuid.clock_seq;
|
||||
|
||||
if ((var & 0x8000) == 0)
|
||||
return UUID_VARIANT_NCS;
|
||||
if ((var & 0x4000) == 0)
|
||||
return UUID_VARIANT_DCE;
|
||||
if ((var & 0x2000) == 0)
|
||||
return UUID_VARIANT_MICROSOFT;
|
||||
return UUID_VARIANT_OTHER;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char *variant_string(int variant)
|
||||
{
|
||||
switch (variant) {
|
||||
case UUID_VARIANT_NCS:
|
||||
return "NCS";
|
||||
case UUID_VARIANT_DCE:
|
||||
return "DCE";
|
||||
case UUID_VARIANT_MICROSOFT:
|
||||
return "Microsoft";
|
||||
default:
|
||||
return "Other";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
uuid_t buf;
|
||||
time_t time_reg;
|
||||
struct timeval tv;
|
||||
int type, variant;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s uuid\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
if (uuid_parse(argv[1], buf)) {
|
||||
fprintf(stderr, "Invalid UUID: %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
variant = uuid_variant(buf);
|
||||
type = uuid_type(buf);
|
||||
time_reg = uuid_time(buf, &tv);
|
||||
|
||||
printf("UUID variant is %d (%s)\n", variant, variant_string(variant));
|
||||
if (variant != UUID_VARIANT_DCE) {
|
||||
printf("Warning: This program only knows how to interpret "
|
||||
"DCE UUIDs.\n\tThe rest of the output is likely "
|
||||
"to be incorrect!!\n");
|
||||
}
|
||||
printf("UUID type is %d", type);
|
||||
switch (type) {
|
||||
case 1:
|
||||
printf(" (time based)\n");
|
||||
break;
|
||||
case 2:
|
||||
printf(" (DCE)\n");
|
||||
break;
|
||||
case 3:
|
||||
printf(" (name-based)\n");
|
||||
break;
|
||||
case 4:
|
||||
printf(" (random)\n");
|
||||
break;
|
||||
default:
|
||||
printf("\n");
|
||||
}
|
||||
if (type != 1) {
|
||||
printf("Warning: not a time-based UUID, so UUID time "
|
||||
"decoding will likely not work!\n");
|
||||
}
|
||||
printf("UUID time is: (%u, %u): %s\n", (unsigned)tv.tv_sec, (unsigned)tv.tv_usec,
|
||||
ctime(&time_reg));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -1,20 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Name=File Types and Programs
|
||||
Name[pt_BR]=Tipos de Arquivos e Programas
|
||||
Name[da]=Filtyper og programmer
|
||||
Name[fi]=Tiedostotyypit ja ohjelmat
|
||||
Name[fr]=Type de fichiers et programmes
|
||||
Name[no]=Filtyper og programmer
|
||||
Name[sk]=Typy súborov a programy
|
||||
Name[tr]=Dosya türleri ve uygulamarý
|
||||
Comment=We need a good explanation here.
|
||||
Comment[pt_BR]=Precisamos de uma boa explicação aqui.
|
||||
Comment[da]=Vi har brug for en god forklaring her.
|
||||
Comment[fr]=Éditeur d'association de type de fichiers et d'applications
|
||||
Comment[no]=Koblinger mellom filtyper og programmer
|
||||
Comment[sk]=Sem by to chcelo nejaké rozumné vysvetlenie...
|
||||
Comment[tr]=Eh, buraya da iyi bir anlatým gerek ...
|
||||
Icon=gnome-ccmime.png
|
||||
Exec=nautilus-mime-type-capplet
|
||||
Terminal=0
|
||||
Type=Application
|
||||
@@ -1,9 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
.libs
|
||||
*.lo
|
||||
*.la
|
||||
*.o
|
||||
keyboard-properties
|
||||
keyboard-properties-capplet
|
||||
@@ -1,13 +0,0 @@
|
||||
2000-12-26 Jacob "Ulysses" Berkman <jacob@helixcode.com>
|
||||
|
||||
* keyboard-properties.glade: re-did the UI a bit
|
||||
|
||||
2000-10-08 Bradford Hovinen <hovinen@helixcode.com>
|
||||
|
||||
* Makefile.am (EXTRA_DIST): Add translation file
|
||||
|
||||
2000-09-12 Bradford Hovinen <hovinen@helixcode.com>
|
||||
|
||||
* preferences.c (preferences_clone): Added in missing code to copy
|
||||
preferences over
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
Applicationsdir = $(datadir)/control-center/Desktop
|
||||
Applications_DATA = \
|
||||
keyboard-properties.desktop
|
||||
|
||||
pApplicationsdir = $(datadir)/gnome/apps/Settings/Desktop
|
||||
pApplications_DATA = \
|
||||
keyboard-properties.desktop
|
||||
|
||||
Gladedir = $(datadir)/control-center-data
|
||||
Glade_DATA = \
|
||||
keyboard-properties.glade
|
||||
|
||||
glade_msgs = \
|
||||
keyboard-properties.glade.h
|
||||
|
||||
EXTRA_DIST = ChangeLog $(Applications_DATA) $(Glade_DATA) $(glade_msgs)
|
||||
|
||||
INCLUDES = \
|
||||
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
|
||||
-DGNOME_ICONDIR=\""${prefix}/share/pixmaps"\" \
|
||||
-DG_LOG_DOMAIN=\"keyboard-properties\" \
|
||||
-DGLADE_DATADIR=\""$(Gladedir)"\" \
|
||||
$(CAPPLET_CFLAGS) \
|
||||
-I$(top_srcdir)/ \
|
||||
-I$(top_srcdir)/intl
|
||||
|
||||
bin_PROGRAMS = keyboard-properties
|
||||
|
||||
keyboard_properties_SOURCES = \
|
||||
prefs-widget.c prefs-widget.h \
|
||||
preferences.c preferences.h \
|
||||
main.c
|
||||
|
||||
keyboard_properties_LDADD = $(CAPPLET_LIBS) $(XF86MISC_LIBS)
|
||||
@@ -1,61 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Name=Keyboard
|
||||
Name[ca]=Propietats del teclat
|
||||
Name[cs]=Klávesnice
|
||||
Name[da]=Tastatur
|
||||
Name[de]=Tastatur
|
||||
Name[el]=Ñõèìßóåéò ðëçêôñïëïãßïõ
|
||||
Name[es]=Propiedades del Teclado
|
||||
Name[et]=Klaviatuur
|
||||
Name[fi]=Näppäimistö
|
||||
Name[fr]=Clavier
|
||||
Name[gl]=Teclado
|
||||
Name[hu]=Billentyûzet
|
||||
Name[it]=Tastiera
|
||||
Name[ja]=¥¡¼¥Ü¡¼¥É
|
||||
Name[ko]=ÀÚÆÇ
|
||||
Name[lt]=Klaviatûra
|
||||
Name[no]=Tastatur
|
||||
Name[pl]=Klawiatura
|
||||
Name[pt]=Propriedades do Teclado
|
||||
Name[pt_BR]=Propriedades do Teclado
|
||||
Name[ro]=Tastaturã
|
||||
Name[ru]=ëÌÁ×ÉÁÔÕÒÁ
|
||||
Name[sl]=Tipkovnica
|
||||
Name[sv]=Tangentbord
|
||||
Name[uk]=ëÌÁצÁÔÕÒÁ
|
||||
Name[wa]=Prôpietés del taprece
|
||||
Name[zh_TW.Big5]=Áä½L
|
||||
Name[zh_CN.GB2312]=¼üÅÌ
|
||||
Comment=Keyboard Properties
|
||||
Comment[ca]=Configurar el teclat
|
||||
Comment[cs]=Vlastnosti klávesnice
|
||||
Comment[da]=Tastaturegenskaber
|
||||
Comment[de]=Tastatureinstellungen
|
||||
Comment[el]=Ôñïðïðïßçóç ôùí ñõèìßóåùí ôïõ ðëçêôñïëïãßïõ
|
||||
Comment[es]=Modifica las propiedades del teclado
|
||||
Comment[et]=Klaviatuuri häälestus
|
||||
Comment[fi]=Näppäimistön asetukset
|
||||
Comment[fr]=Configuration des propriétés du clavier
|
||||
Comment[gl]=Propiedades do teclado
|
||||
Comment[hu]=Billentyûzet beállításai
|
||||
Comment[it]=Impostazioni della tastiera
|
||||
Comment[ja]=¥¡¼¥Ü¡¼¥É¤ÎÀßÄê
|
||||
Comment[ko]=ÀÚÆÇ ¼Ó¼º
|
||||
Comment[lt]=Klaviatûros savybës
|
||||
Comment[no]=Egenskaper for tastatur
|
||||
Comment[pl]=Ustawienia klawiatury
|
||||
Comment[pt]=Propriedades do Teclado
|
||||
Comment[pt_BR]=Propriedades do Teclado
|
||||
Comment[ro]=Proprietãþi tastaturã
|
||||
Comment[ru]=ó×ÏÊÓÔ×Á ËÌÁ×ÉÁÔÕÒÙ
|
||||
Comment[sl]=Lastnosti Tipkovnice
|
||||
Comment[sv]=Tangentbordsinställningar
|
||||
Comment[uk]=÷ÌÁÓÔÉ×ÏÓÔ¦ ËÌÁצÁÔÕÒÉ
|
||||
Comment[wa]=Candjî les prôpietés del taprece
|
||||
Comment[zh_TW.Big5]=Áä½L³]©w
|
||||
Comment[zh_CN.GB2312]=¼üÅÌÉ趨
|
||||
Exec=keyboard-properties-capplet
|
||||
Icon=gnome-cckeyboard.png
|
||||
Terminal=0
|
||||
Type=Application
|
||||
@@ -1,370 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<GTK-Interface>
|
||||
|
||||
<project>
|
||||
<name>New-keyboard-properties</name>
|
||||
<program_name>new-keyboard-properties</program_name>
|
||||
<directory></directory>
|
||||
<source_directory>src</source_directory>
|
||||
<pixmaps_directory>pixmaps</pixmaps_directory>
|
||||
<language>C</language>
|
||||
<gnome_support>True</gnome_support>
|
||||
<gettext_support>True</gettext_support>
|
||||
<output_translatable_strings>True</output_translatable_strings>
|
||||
<translatable_strings_file>keyboard-properties.glade.h</translatable_strings_file>
|
||||
</project>
|
||||
|
||||
<widget>
|
||||
<class>GtkWindow</class>
|
||||
<name>window1</name>
|
||||
<title>window1</title>
|
||||
<type>GTK_WINDOW_TOPLEVEL</type>
|
||||
<position>GTK_WIN_POS_NONE</position>
|
||||
<modal>False</modal>
|
||||
<allow_shrink>False</allow_shrink>
|
||||
<allow_grow>True</allow_grow>
|
||||
<auto_shrink>False</auto_shrink>
|
||||
|
||||
<widget>
|
||||
<class>GtkVBox</class>
|
||||
<name>prefs_widget</name>
|
||||
<homogeneous>False</homogeneous>
|
||||
<spacing>4</spacing>
|
||||
|
||||
<widget>
|
||||
<class>GtkCheckButton</class>
|
||||
<name>repeat_toggle</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>toggled</name>
|
||||
<handler>repeat_toggled_cb</handler>
|
||||
<last_modification_time>Thu, 30 Nov 2000 23:56:30 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Enable Keyboard Repeat</label>
|
||||
<active>False</active>
|
||||
<draw_indicator>True</draw_indicator>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkFrame</class>
|
||||
<name>delay_frame</name>
|
||||
<label>Delay Until Repeat</label>
|
||||
<label_xalign>0</label_xalign>
|
||||
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkHBox</class>
|
||||
<name>hbox2</name>
|
||||
<border_width>4</border_width>
|
||||
<homogeneous>True</homogeneous>
|
||||
<spacing>4</spacing>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label5</name>
|
||||
<label></label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0.5</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkToggleButton</class>
|
||||
<name>delay0</name>
|
||||
<can_focus>True</can_focus>
|
||||
<label>....a</label>
|
||||
<relief>GTK_RELIEF_NORMAL</relief>
|
||||
<active>False</active>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkToggleButton</class>
|
||||
<name>delay1</name>
|
||||
<can_focus>True</can_focus>
|
||||
<label>...a</label>
|
||||
<relief>GTK_RELIEF_NORMAL</relief>
|
||||
<active>False</active>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkToggleButton</class>
|
||||
<name>delay2</name>
|
||||
<can_focus>True</can_focus>
|
||||
<label>..a</label>
|
||||
<relief>GTK_RELIEF_NORMAL</relief>
|
||||
<active>False</active>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkToggleButton</class>
|
||||
<name>delay3</name>
|
||||
<can_focus>True</can_focus>
|
||||
<label>.a</label>
|
||||
<relief>GTK_RELIEF_NORMAL</relief>
|
||||
<active>False</active>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label6</name>
|
||||
<label></label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0.5</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkFrame</class>
|
||||
<name>repeat_frame</name>
|
||||
<label>Key Repeat Rate</label>
|
||||
<label_xalign>0</label_xalign>
|
||||
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkHBox</class>
|
||||
<name>hbox3</name>
|
||||
<border_width>4</border_width>
|
||||
<homogeneous>True</homogeneous>
|
||||
<spacing>4</spacing>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label7</name>
|
||||
<label></label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0.5</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkToggleButton</class>
|
||||
<name>repeat0</name>
|
||||
<can_focus>True</can_focus>
|
||||
<label>a....a</label>
|
||||
<relief>GTK_RELIEF_NORMAL</relief>
|
||||
<active>False</active>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkToggleButton</class>
|
||||
<name>repeat1</name>
|
||||
<can_focus>True</can_focus>
|
||||
<label>a...a</label>
|
||||
<relief>GTK_RELIEF_NORMAL</relief>
|
||||
<active>False</active>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkToggleButton</class>
|
||||
<name>repeat2</name>
|
||||
<can_focus>True</can_focus>
|
||||
<label>a..a</label>
|
||||
<relief>GTK_RELIEF_NORMAL</relief>
|
||||
<active>False</active>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkToggleButton</class>
|
||||
<name>repeat3</name>
|
||||
<can_focus>True</can_focus>
|
||||
<label>a.a</label>
|
||||
<relief>GTK_RELIEF_NORMAL</relief>
|
||||
<active>False</active>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label8</name>
|
||||
<label></label>
|
||||
<justify>GTK_JUSTIFY_CENTER</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0.5</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkCheckButton</class>
|
||||
<name>click_toggle</name>
|
||||
<can_focus>True</can_focus>
|
||||
<signal>
|
||||
<name>toggled</name>
|
||||
<handler>click_toggled_cb</handler>
|
||||
<last_modification_time>Mon, 11 Sep 2000 02:02:18 GMT</last_modification_time>
|
||||
</signal>
|
||||
<label>Enable Keyboard Click</label>
|
||||
<active>False</active>
|
||||
<draw_indicator>True</draw_indicator>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkFrame</class>
|
||||
<name>click_frame</name>
|
||||
<label>Keyboard click</label>
|
||||
<label_xalign>0</label_xalign>
|
||||
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkHBox</class>
|
||||
<name>hbox4</name>
|
||||
<border_width>4</border_width>
|
||||
<homogeneous>False</homogeneous>
|
||||
<spacing>4</spacing>
|
||||
|
||||
<widget>
|
||||
<class>GtkLabel</class>
|
||||
<name>label3</name>
|
||||
<label>Click volume</label>
|
||||
<justify>GTK_JUSTIFY_RIGHT</justify>
|
||||
<wrap>False</wrap>
|
||||
<xalign>0</xalign>
|
||||
<yalign>0.5</yalign>
|
||||
<xpad>0</xpad>
|
||||
<ypad>0</ypad>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkHScale</class>
|
||||
<name>click_volume_entry</name>
|
||||
<can_focus>True</can_focus>
|
||||
<draw_value>False</draw_value>
|
||||
<value_pos>GTK_POS_TOP</value_pos>
|
||||
<digits>0</digits>
|
||||
<policy>GTK_UPDATE_CONTINUOUS</policy>
|
||||
<value>0</value>
|
||||
<lower>0</lower>
|
||||
<upper>100</upper>
|
||||
<step>0</step>
|
||||
<page>0</page>
|
||||
<page_size>0</page_size>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkEntry</class>
|
||||
<name>test_entry</name>
|
||||
<can_focus>True</can_focus>
|
||||
<editable>True</editable>
|
||||
<text_visible>True</text_visible>
|
||||
<text_max_length>0</text_max_length>
|
||||
<text>Type here to test setting</text>
|
||||
<child>
|
||||
<padding>0</padding>
|
||||
<expand>False</expand>
|
||||
<fill>False</fill>
|
||||
</child>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
</GTK-Interface>
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Translatable strings file generated by Glade.
|
||||
* Add this file to your project's POTFILES.in.
|
||||
* DO NOT compile it as part of your application.
|
||||
*/
|
||||
|
||||
gchar *s = N_("window1");
|
||||
gchar *s = N_("Enable Keyboard Repeat");
|
||||
gchar *s = N_("Delay Until Repeat");
|
||||
gchar *s = N_("....a");
|
||||
gchar *s = N_("...a");
|
||||
gchar *s = N_("..a");
|
||||
gchar *s = N_(".a");
|
||||
gchar *s = N_("Key Repeat Rate");
|
||||
gchar *s = N_("a....a");
|
||||
gchar *s = N_("a...a");
|
||||
gchar *s = N_("a..a");
|
||||
gchar *s = N_("a.a");
|
||||
gchar *s = N_("Enable Keyboard Click");
|
||||
gchar *s = N_("Keyboard click");
|
||||
gchar *s = N_("Click volume");
|
||||
gchar *s = N_("Type here to test setting");
|
||||
@@ -1,185 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* main.c
|
||||
* Copyright (C) 2000 Helix Code, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen (hovinen@helixcode.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gnome.h>
|
||||
#include <libgnomeui/gnome-window-icon.h>
|
||||
#include <tree.h>
|
||||
#include <parser.h>
|
||||
|
||||
#include <glade/glade.h>
|
||||
|
||||
#include <capplet-widget.h>
|
||||
|
||||
#include "preferences.h"
|
||||
#include "prefs-widget.h"
|
||||
|
||||
static Preferences *prefs;
|
||||
static Preferences *old_prefs;
|
||||
static PrefsWidget *prefs_widget;
|
||||
|
||||
static void
|
||||
ok_cb (GtkWidget *widget)
|
||||
{
|
||||
preferences_save (prefs);
|
||||
preferences_apply_now (prefs);
|
||||
}
|
||||
|
||||
static void
|
||||
cancel_cb (GtkWidget *widget)
|
||||
{
|
||||
preferences_save (old_prefs);
|
||||
preferences_apply_now (old_prefs);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_capplet_widget (void)
|
||||
{
|
||||
preferences_freeze (prefs);
|
||||
|
||||
prefs_widget = PREFS_WIDGET (prefs_widget_new (prefs));
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (prefs_widget), "ok",
|
||||
GTK_SIGNAL_FUNC (ok_cb), NULL);
|
||||
gtk_signal_connect (GTK_OBJECT (prefs_widget), "cancel",
|
||||
GTK_SIGNAL_FUNC (cancel_cb), NULL);
|
||||
|
||||
gtk_widget_show_all (GTK_WIDGET (prefs_widget));
|
||||
|
||||
preferences_thaw (prefs);
|
||||
}
|
||||
|
||||
static void
|
||||
do_get_xml (void)
|
||||
{
|
||||
Preferences *prefs;
|
||||
xmlDocPtr doc;
|
||||
|
||||
prefs = PREFERENCES (preferences_new ());
|
||||
preferences_load (prefs);
|
||||
doc = preferences_write_xml (prefs);
|
||||
xmlDocDump (stdout, doc);
|
||||
gtk_object_destroy (GTK_OBJECT (prefs));
|
||||
}
|
||||
|
||||
static void
|
||||
do_set_xml (void)
|
||||
{
|
||||
Preferences *prefs;
|
||||
xmlDocPtr doc;
|
||||
char *buffer;
|
||||
int len = 0;
|
||||
|
||||
while (!feof (stdin)) {
|
||||
if (!len) buffer = g_new (char, 16384);
|
||||
else buffer = g_renew (char, buffer, len + 16384);
|
||||
fread (buffer + len, 1, 16384, stdin);
|
||||
len += 16384;
|
||||
}
|
||||
|
||||
doc = xmlParseMemory (buffer, strlen (buffer));
|
||||
|
||||
prefs = preferences_read_xml (doc);
|
||||
|
||||
if (prefs)
|
||||
preferences_save (prefs);
|
||||
else
|
||||
g_warning ("Error while reading the screensaver config file");
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
GnomeClient *client;
|
||||
GnomeClientFlags flags;
|
||||
gint token, res;
|
||||
gchar *restart_args[3];
|
||||
|
||||
bindtextdomain (PACKAGE, GNOMELOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
glade_gnome_init ();
|
||||
res = gnome_capplet_init ("keyboard-properties-capplet",
|
||||
VERSION, argc, argv, NULL,
|
||||
0, NULL);
|
||||
|
||||
if (res < 0) {
|
||||
g_error ("Could not initialize the capplet.");
|
||||
}
|
||||
else if (res == 3) {
|
||||
do_get_xml ();
|
||||
return 0;
|
||||
}
|
||||
else if (res == 4) {
|
||||
do_set_xml ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
client = gnome_master_client ();
|
||||
flags = gnome_client_get_flags (client);
|
||||
|
||||
if (flags & GNOME_CLIENT_IS_CONNECTED) {
|
||||
token = gnome_startup_acquire_token
|
||||
("GNOME_KEYBOARD_PROPERTIES",
|
||||
gnome_client_get_id (client));
|
||||
|
||||
if (token) {
|
||||
gnome_client_set_priority (client, 20);
|
||||
gnome_client_set_restart_style (client,
|
||||
GNOME_RESTART_ANYWAY);
|
||||
restart_args[0] = argv[0];
|
||||
restart_args[1] = "--init-session-settings";
|
||||
restart_args[2] = NULL;
|
||||
gnome_client_set_restart_command (client, 2,
|
||||
restart_args);
|
||||
} else {
|
||||
gnome_client_set_restart_style (client,
|
||||
GNOME_RESTART_NEVER);
|
||||
}
|
||||
} else {
|
||||
token = 1;
|
||||
}
|
||||
|
||||
gnome_window_icon_set_default_from_file
|
||||
(GNOME_ICONDIR"/gnome-cckeyboard.png");
|
||||
|
||||
prefs = PREFERENCES (preferences_new ());
|
||||
preferences_load (prefs);
|
||||
|
||||
if (token) {
|
||||
preferences_apply_now (prefs);
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
old_prefs = PREFERENCES (preferences_clone (prefs));
|
||||
setup_capplet_widget ();
|
||||
|
||||
capplet_gtk_main ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,378 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* preferences.c
|
||||
* Copyright (C) 2000 Helix Code, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@helixcode.com>,
|
||||
* Jaka Mocnik <jaka.mocnik@kiss.uni-lj.si>
|
||||
*
|
||||
* Based on gnome-core/desktop-properties/property-keyboard.c
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gnome.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <X11/X.h>
|
||||
|
||||
#ifdef HAVE_X11_EXTENSIONS_XF86MISC_H
|
||||
#include <X11/extensions/xf86misc.h>
|
||||
#endif
|
||||
|
||||
#include "preferences.h"
|
||||
|
||||
static GtkObjectClass *parent_class;
|
||||
|
||||
#ifdef HAVE_X11_EXTENSIONS_XF86MISC_H
|
||||
static XF86MiscKbdSettings kbdsettings;
|
||||
#endif
|
||||
|
||||
static void preferences_init (Preferences *prefs);
|
||||
static void preferences_class_init (PreferencesClass *class);
|
||||
|
||||
static gint xml_read_int (xmlNodePtr node,
|
||||
gchar *propname);
|
||||
static xmlNodePtr xml_write_int (gchar *name,
|
||||
gchar *propname,
|
||||
gint number);
|
||||
|
||||
static gint apply_timeout_cb (Preferences *prefs);
|
||||
|
||||
guint
|
||||
preferences_get_type (void)
|
||||
{
|
||||
static guint preferences_type = 0;
|
||||
|
||||
if (!preferences_type) {
|
||||
GtkTypeInfo preferences_info = {
|
||||
"Preferences",
|
||||
sizeof (Preferences),
|
||||
sizeof (PreferencesClass),
|
||||
(GtkClassInitFunc) preferences_class_init,
|
||||
(GtkObjectInitFunc) preferences_init,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL
|
||||
};
|
||||
|
||||
preferences_type =
|
||||
gtk_type_unique (gtk_object_get_type (),
|
||||
&preferences_info);
|
||||
}
|
||||
|
||||
return preferences_type;
|
||||
}
|
||||
|
||||
static void
|
||||
preferences_init (Preferences *prefs)
|
||||
{
|
||||
prefs->frozen = FALSE;
|
||||
|
||||
/* Code to initialize preferences object to defaults */
|
||||
}
|
||||
|
||||
static void
|
||||
preferences_class_init (PreferencesClass *class)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
|
||||
object_class = (GtkObjectClass *) class;
|
||||
object_class->destroy = preferences_destroy;
|
||||
|
||||
parent_class =
|
||||
GTK_OBJECT_CLASS (gtk_type_class (gtk_object_get_type ()));
|
||||
}
|
||||
|
||||
GtkObject *
|
||||
preferences_new (void)
|
||||
{
|
||||
GtkObject *object;
|
||||
|
||||
object = gtk_type_new (preferences_get_type ());
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
GtkObject *
|
||||
preferences_clone (Preferences *prefs)
|
||||
{
|
||||
GtkObject *object;
|
||||
Preferences *new_prefs;
|
||||
|
||||
g_return_val_if_fail (prefs != NULL, NULL);
|
||||
g_return_val_if_fail (IS_PREFERENCES (prefs), NULL);
|
||||
|
||||
object = preferences_new ();
|
||||
|
||||
new_prefs = PREFERENCES (object);
|
||||
new_prefs->rate = prefs->rate;
|
||||
new_prefs->delay = prefs->delay;
|
||||
new_prefs->repeat = prefs->repeat;
|
||||
new_prefs->volume = prefs->volume;
|
||||
new_prefs->click = prefs->click;
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
void
|
||||
preferences_destroy (GtkObject *object)
|
||||
{
|
||||
Preferences *prefs;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (object));
|
||||
|
||||
prefs = PREFERENCES (object);
|
||||
|
||||
parent_class->destroy (object);
|
||||
}
|
||||
|
||||
void
|
||||
preferences_load (Preferences *prefs)
|
||||
{
|
||||
XKeyboardState kbdstate;
|
||||
gboolean repeat_default, click_default;
|
||||
gint event_base_return, error_base_return;
|
||||
|
||||
g_return_if_fail (prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs));
|
||||
|
||||
prefs->rate = gnome_config_get_int ("/Desktop/Keyboard/rate=-");
|
||||
prefs->delay = gnome_config_get_int ("/Desktop/Keyboard/delay=-1");
|
||||
prefs->repeat = gnome_config_get_bool_with_default
|
||||
("/Desktop/Keyboard/repeat=true", &repeat_default);
|
||||
prefs->volume = gnome_config_get_int
|
||||
("/Desktop/Keyboard/clickvolume=-1");
|
||||
prefs->click = gnome_config_get_bool_with_default
|
||||
("/Desktop/Keyboard/click=false", &click_default);
|
||||
|
||||
XGetKeyboardControl (GDK_DISPLAY (), &kbdstate);
|
||||
|
||||
if (repeat_default)
|
||||
prefs->repeat = kbdstate.global_auto_repeat;
|
||||
|
||||
if (prefs->rate == -1 || prefs->delay == -1) {
|
||||
#ifdef HAVE_X11_EXTENSIONS_XF86MISC_H
|
||||
if (XF86MiscQueryExtension (GDK_DISPLAY (),
|
||||
&event_base_return,
|
||||
&error_base_return) == True)
|
||||
{
|
||||
XF86MiscGetKbdSettings (GDK_DISPLAY (), &kbdsettings);
|
||||
prefs->rate = kbdsettings.rate;
|
||||
prefs->delay = kbdsettings.delay;
|
||||
} else {
|
||||
prefs->rate = 5;
|
||||
prefs->delay = 500;
|
||||
}
|
||||
#else
|
||||
/* FIXME: how to get the keyboard speed on non-xf86? */
|
||||
prefs->rate = 5;
|
||||
prefs->delay = 500;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (click_default)
|
||||
prefs->click = (kbdstate.key_click_percent == 0);
|
||||
|
||||
if (prefs->volume == -1)
|
||||
prefs->volume = kbdstate.key_click_percent;
|
||||
}
|
||||
|
||||
void
|
||||
preferences_save (Preferences *prefs)
|
||||
{
|
||||
g_return_if_fail (prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs));
|
||||
|
||||
gnome_config_set_bool ("/Desktop/Keyboard/repeat", prefs->repeat);
|
||||
gnome_config_set_int ("/Desktop/Keyboard/delay", prefs->delay);
|
||||
gnome_config_set_int ("/Desktop/Keyboard/rate", prefs->rate);
|
||||
gnome_config_set_bool ("/Desktop/Keyboard/click", prefs->click);
|
||||
gnome_config_set_int ("/Desktop/Keyboard/clickvolume", prefs->volume);
|
||||
|
||||
gnome_config_sync ();
|
||||
}
|
||||
|
||||
void
|
||||
preferences_changed (Preferences *prefs)
|
||||
{
|
||||
if (prefs->frozen) return;
|
||||
|
||||
if (prefs->timeout_id)
|
||||
gtk_timeout_remove (prefs->timeout_id);
|
||||
|
||||
preferences_apply_now (prefs);
|
||||
}
|
||||
|
||||
void
|
||||
preferences_apply_now (Preferences *prefs)
|
||||
{
|
||||
XKeyboardControl kbdcontrol;
|
||||
int event_base_return, error_base_return;
|
||||
|
||||
g_return_if_fail (prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs));
|
||||
|
||||
if (prefs->timeout_id)
|
||||
gtk_timeout_remove (prefs->timeout_id);
|
||||
|
||||
prefs->timeout_id = 0;
|
||||
|
||||
if (prefs->repeat) {
|
||||
XAutoRepeatOn (GDK_DISPLAY ());
|
||||
#ifdef HAVE_X11_EXTENSIONS_XF86MISC_H
|
||||
if (XF86MiscQueryExtension (GDK_DISPLAY (),
|
||||
&event_base_return,
|
||||
&error_base_return) == True)
|
||||
{
|
||||
kbdsettings.rate = prefs->rate;
|
||||
kbdsettings.delay = prefs->delay;
|
||||
XF86MiscSetKbdSettings (GDK_DISPLAY (), &kbdsettings);
|
||||
} else {
|
||||
XAutoRepeatOff (GDK_DISPLAY ());
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
XAutoRepeatOff (GDK_DISPLAY ());
|
||||
}
|
||||
|
||||
kbdcontrol.key_click_percent =
|
||||
prefs->click ? prefs->volume : 0;
|
||||
XChangeKeyboardControl (GDK_DISPLAY (), KBKeyClickPercent,
|
||||
&kbdcontrol);
|
||||
}
|
||||
|
||||
void preferences_freeze (Preferences *prefs)
|
||||
{
|
||||
prefs->frozen = TRUE;
|
||||
}
|
||||
|
||||
void preferences_thaw (Preferences *prefs)
|
||||
{
|
||||
prefs->frozen = FALSE;
|
||||
}
|
||||
|
||||
Preferences *
|
||||
preferences_read_xml (xmlDocPtr xml_doc)
|
||||
{
|
||||
Preferences *prefs;
|
||||
xmlNodePtr root_node, node;
|
||||
|
||||
prefs = PREFERENCES (preferences_new ());
|
||||
|
||||
root_node = xmlDocGetRootElement (xml_doc);
|
||||
|
||||
if (strcmp (root_node->name, "keyboard-properties"))
|
||||
return NULL;
|
||||
|
||||
for (node = root_node->childs; node; node = node->next) {
|
||||
if (!strcmp (node->name, "rate"))
|
||||
prefs->rate = xml_read_int (node, NULL);
|
||||
else if (!strcmp (node->name, "delay"))
|
||||
prefs->delay = xml_read_int (node, NULL);
|
||||
else if (!strcmp (node->name, "repeat"))
|
||||
prefs->repeat = TRUE;
|
||||
else if (!strcmp (node->name, "volume"))
|
||||
prefs->volume = xml_read_int (node, NULL);
|
||||
else if (!strcmp (node->name, "click"))
|
||||
prefs->click = TRUE;
|
||||
}
|
||||
|
||||
return prefs;
|
||||
}
|
||||
|
||||
xmlDocPtr
|
||||
preferences_write_xml (Preferences *prefs)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr node;
|
||||
char *tmp;
|
||||
|
||||
doc = xmlNewDoc ("1.0");
|
||||
|
||||
node = xmlNewDocNode (doc, NULL, "keyboard-properties", NULL);
|
||||
|
||||
xmlAddChild (node, xml_write_int ("rate", NULL, prefs->rate));
|
||||
xmlAddChild (node, xml_write_int ("delay", NULL, prefs->delay));
|
||||
|
||||
if (prefs->repeat)
|
||||
xmlNewChild (node, NULL, "repeat", NULL);
|
||||
|
||||
xmlAddChild (node, xml_write_int ("volume", NULL,
|
||||
prefs->volume));
|
||||
|
||||
if (prefs->click)
|
||||
xmlNewChild (node, NULL, "click", NULL);
|
||||
|
||||
xmlDocSetRootElement (doc, node);
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
/* Read a numeric value from a node */
|
||||
|
||||
static gint
|
||||
xml_read_int (xmlNodePtr node, char *propname)
|
||||
{
|
||||
char *text;
|
||||
|
||||
if (propname == NULL)
|
||||
text = xmlNodeGetContent (node);
|
||||
else
|
||||
text = xmlGetProp (node, propname);
|
||||
|
||||
if (text == NULL)
|
||||
return 0;
|
||||
else
|
||||
return atoi (text);
|
||||
}
|
||||
|
||||
/* Write out a numeric value in a node */
|
||||
|
||||
static xmlNodePtr
|
||||
xml_write_int (gchar *name, gchar *propname, gint number)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
gchar *str;
|
||||
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
str = g_strdup_printf ("%d", number);
|
||||
|
||||
node = xmlNewNode (NULL, name);
|
||||
|
||||
if (propname == NULL)
|
||||
xmlNodeSetContent (node, str);
|
||||
else
|
||||
xmlSetProp (node, propname, str);
|
||||
|
||||
g_free (str);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static gint
|
||||
apply_timeout_cb (Preferences *prefs)
|
||||
{
|
||||
preferences_apply_now (prefs);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* preferences.h
|
||||
* Copyright (C) 2000 Helix Code, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@helixcode.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __PREFERENCES_H
|
||||
#define __PREFERENCES_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <tree.h>
|
||||
|
||||
#define PREFERENCES(obj) GTK_CHECK_CAST (obj, preferences_get_type (), Preferences)
|
||||
#define PREFERENCES_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, preferences_get_type (), PreferencesClass)
|
||||
#define IS_PREFERENCES(obj) GTK_CHECK_TYPE (obj, preferences_get_type ())
|
||||
|
||||
typedef struct _Preferences Preferences;
|
||||
typedef struct _PreferencesClass PreferencesClass;
|
||||
|
||||
struct _Preferences
|
||||
{
|
||||
GtkObject object;
|
||||
|
||||
gboolean frozen;
|
||||
guint timeout_id;
|
||||
|
||||
gint rate;
|
||||
gint delay;
|
||||
gint volume;
|
||||
|
||||
gboolean repeat;
|
||||
gboolean click;
|
||||
};
|
||||
|
||||
struct _PreferencesClass
|
||||
{
|
||||
GtkObjectClass klass;
|
||||
};
|
||||
|
||||
guint preferences_get_type (void);
|
||||
|
||||
GtkObject *preferences_new (void);
|
||||
GtkObject *preferences_clone (Preferences *prefs);
|
||||
void preferences_destroy (GtkObject *object);
|
||||
|
||||
void preferences_load (Preferences *prefs);
|
||||
void preferences_save (Preferences *prefs);
|
||||
void preferences_changed (Preferences *prefs);
|
||||
void preferences_apply_now (Preferences *prefs);
|
||||
|
||||
void preferences_freeze (Preferences *prefs);
|
||||
void preferences_thaw (Preferences *prefs);
|
||||
|
||||
Preferences *preferences_read_xml (xmlDocPtr xml_doc);
|
||||
xmlDocPtr preferences_write_xml (Preferences *prefs);
|
||||
|
||||
#endif /* __PREFERENCES_H */
|
||||
@@ -1,366 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* prefs-widget.c
|
||||
* Copyright (C) 2000 Helix Code, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@helixcode.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "prefs-widget.h"
|
||||
|
||||
#define WID(str) (glade_xml_get_widget (prefs_widget->dialog_data, str))
|
||||
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_PREFERENCES
|
||||
};
|
||||
|
||||
static CappletWidgetClass *parent_class;
|
||||
|
||||
static void prefs_widget_init (PrefsWidget *prefs_widget);
|
||||
static void prefs_widget_class_init (PrefsWidgetClass *class);
|
||||
|
||||
static void prefs_widget_set_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
static void prefs_widget_get_arg (GtkObject *object,
|
||||
GtkArg *arg,
|
||||
guint arg_id);
|
||||
|
||||
static void read_preferences (PrefsWidget *prefs_widget,
|
||||
Preferences *prefs);
|
||||
|
||||
static void repeat_toggled_cb (GtkToggleButton *button,
|
||||
PrefsWidget *prefs_widget);
|
||||
static void rate_changed_cb (GtkToggleButton *toggle,
|
||||
PrefsWidget *prefs_widget);
|
||||
static void delay_changed_cb (GtkToggleButton *toggle,
|
||||
PrefsWidget *prefs_widget);
|
||||
static void click_toggled_cb (GtkToggleButton *button,
|
||||
PrefsWidget *prefs_widget);
|
||||
static void click_volume_changed_cb (GtkAdjustment *adjustment,
|
||||
PrefsWidget *prefs_widget);
|
||||
|
||||
guint
|
||||
prefs_widget_get_type (void)
|
||||
{
|
||||
static guint prefs_widget_type = 0;
|
||||
|
||||
if (!prefs_widget_type) {
|
||||
GtkTypeInfo prefs_widget_info = {
|
||||
"PrefsWidget",
|
||||
sizeof (PrefsWidget),
|
||||
sizeof (PrefsWidgetClass),
|
||||
(GtkClassInitFunc) prefs_widget_class_init,
|
||||
(GtkObjectInitFunc) prefs_widget_init,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL
|
||||
};
|
||||
|
||||
prefs_widget_type =
|
||||
gtk_type_unique (capplet_widget_get_type (),
|
||||
&prefs_widget_info);
|
||||
}
|
||||
|
||||
return prefs_widget_type;
|
||||
}
|
||||
|
||||
static void
|
||||
prefs_widget_init (PrefsWidget *prefs_widget)
|
||||
{
|
||||
char delays[] = "delay0";
|
||||
char rates[] = "repeat0";
|
||||
int i;
|
||||
|
||||
GtkWidget *widget;
|
||||
GtkAdjustment *adjustment;
|
||||
|
||||
prefs_widget->dialog_data =
|
||||
glade_xml_new (GLADE_DATADIR "/keyboard-properties.glade",
|
||||
"prefs_widget");
|
||||
|
||||
glade_xml_signal_connect_data
|
||||
(prefs_widget->dialog_data, "repeat_toggled_cb",
|
||||
repeat_toggled_cb, prefs_widget);
|
||||
|
||||
widget = glade_xml_get_widget (prefs_widget->dialog_data,
|
||||
"prefs_widget");
|
||||
gtk_container_add (GTK_CONTAINER (prefs_widget), widget);
|
||||
|
||||
glade_xml_signal_connect_data
|
||||
(prefs_widget->dialog_data, "click_toggled_cb",
|
||||
click_toggled_cb, prefs_widget);
|
||||
|
||||
adjustment = gtk_range_get_adjustment
|
||||
(GTK_RANGE (WID ("click_volume_entry")));
|
||||
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
|
||||
click_volume_changed_cb, prefs_widget);
|
||||
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
rates[6] = delays[5] = '0' + i;
|
||||
prefs_widget->delay[i] = WID (delays);
|
||||
prefs_widget->rate[i] = WID (rates);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (prefs_widget->delay[i]), "toggled",
|
||||
GTK_SIGNAL_FUNC (delay_changed_cb), prefs_widget);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (prefs_widget->rate[i]), "toggled",
|
||||
GTK_SIGNAL_FUNC (rate_changed_cb), prefs_widget);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
prefs_widget_class_init (PrefsWidgetClass *class)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
|
||||
gtk_object_add_arg_type ("PrefsWidget::preferences",
|
||||
GTK_TYPE_POINTER,
|
||||
GTK_ARG_READWRITE,
|
||||
ARG_PREFERENCES);
|
||||
|
||||
object_class = GTK_OBJECT_CLASS (class);
|
||||
object_class->set_arg = prefs_widget_set_arg;
|
||||
object_class->get_arg = prefs_widget_get_arg;
|
||||
|
||||
parent_class = CAPPLET_WIDGET_CLASS
|
||||
(gtk_type_class (capplet_widget_get_type ()));
|
||||
}
|
||||
|
||||
static void
|
||||
prefs_widget_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
PrefsWidget *prefs_widget;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (object));
|
||||
|
||||
prefs_widget = PREFS_WIDGET (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_PREFERENCES:
|
||||
if (prefs_widget->prefs)
|
||||
gtk_object_unref (GTK_OBJECT (prefs_widget->prefs));
|
||||
|
||||
prefs_widget->prefs = GTK_VALUE_POINTER (*arg);
|
||||
|
||||
if (prefs_widget->prefs) {
|
||||
gtk_object_ref (GTK_OBJECT (prefs_widget->prefs));
|
||||
read_preferences (prefs_widget, prefs_widget->prefs);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Bad argument set");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
prefs_widget_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
|
||||
{
|
||||
PrefsWidget *prefs_widget;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (object));
|
||||
|
||||
prefs_widget = PREFS_WIDGET (object);
|
||||
|
||||
switch (arg_id) {
|
||||
case ARG_PREFERENCES:
|
||||
GTK_VALUE_POINTER (*arg) = prefs_widget->prefs;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Bad argument get");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
prefs_widget_new (Preferences *prefs)
|
||||
{
|
||||
g_return_val_if_fail (prefs == NULL || IS_PREFERENCES (prefs), NULL);
|
||||
|
||||
return gtk_widget_new (prefs_widget_get_type (),
|
||||
"preferences", prefs,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
prefs_widget_set_preferences (PrefsWidget *prefs_widget, Preferences *prefs)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs));
|
||||
|
||||
gtk_object_set (GTK_OBJECT (prefs_widget), "preferences", prefs, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
read_preferences (PrefsWidget *prefs_widget, Preferences *prefs)
|
||||
{
|
||||
GtkAdjustment *adjustment;
|
||||
int i;
|
||||
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs));
|
||||
|
||||
gtk_toggle_button_set_active
|
||||
(GTK_TOGGLE_BUTTON (WID ("repeat_toggle")), prefs->repeat);
|
||||
|
||||
i = CLAMP (prefs->rate * 3 / 255, 0, 3);
|
||||
gtk_toggle_button_set_active
|
||||
(GTK_TOGGLE_BUTTON (prefs_widget->rate[i]), TRUE);
|
||||
|
||||
i = CLAMP ((10000 - prefs->delay) * 3 / 10000, 0, 3);
|
||||
gtk_toggle_button_set_active
|
||||
(GTK_TOGGLE_BUTTON (prefs_widget->delay[i]), TRUE);
|
||||
|
||||
gtk_toggle_button_set_active
|
||||
(GTK_TOGGLE_BUTTON (WID ("click_toggle")), prefs->click);
|
||||
|
||||
adjustment = gtk_range_get_adjustment
|
||||
(GTK_RANGE (WID ("click_volume_entry")));
|
||||
gtk_adjustment_set_value (adjustment, prefs->volume);
|
||||
|
||||
gtk_widget_set_sensitive (WID ("click_frame"), prefs_widget->prefs->click);
|
||||
gtk_widget_set_sensitive (WID ("delay_frame"), prefs_widget->prefs->repeat);
|
||||
gtk_widget_set_sensitive (WID ("repeat_frame"), prefs_widget->prefs->repeat);
|
||||
}
|
||||
|
||||
static void
|
||||
repeat_toggled_cb (GtkToggleButton *button, PrefsWidget *prefs_widget)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
g_return_if_fail (button != NULL);
|
||||
g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
|
||||
|
||||
prefs_widget->prefs->repeat =
|
||||
gtk_toggle_button_get_active (button);
|
||||
|
||||
gtk_widget_set_sensitive (WID ("delay_frame"), prefs_widget->prefs->repeat);
|
||||
gtk_widget_set_sensitive (WID ("repeat_frame"), prefs_widget->prefs->repeat);
|
||||
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static int
|
||||
set_scale (GtkToggleButton *toggle, GtkWidget **arr)
|
||||
{
|
||||
int i, retval = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (arr[i] == toggle) retval = i;
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (arr[i]), arr[i] == toggle);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
rate_changed_cb (GtkToggleButton *toggle, PrefsWidget *prefs_widget)
|
||||
{
|
||||
int i;
|
||||
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
g_return_if_fail (toggle != NULL);
|
||||
g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle));
|
||||
|
||||
if (!toggle->active)
|
||||
return;
|
||||
|
||||
i = set_scale (toggle, prefs_widget->rate);
|
||||
prefs_widget->prefs->rate = i * 255 / 3;
|
||||
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
delay_changed_cb (GtkToggleButton *toggle, PrefsWidget *prefs_widget)
|
||||
{
|
||||
int i;
|
||||
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
g_return_if_fail (toggle != NULL);
|
||||
g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle));
|
||||
|
||||
if (!toggle->active)
|
||||
return;
|
||||
|
||||
i = set_scale (toggle, prefs_widget->delay);
|
||||
prefs_widget->prefs->delay = (3 - i) * 10000 / 3;
|
||||
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
click_toggled_cb (GtkToggleButton *button, PrefsWidget *prefs_widget)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
g_return_if_fail (button != NULL);
|
||||
g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
|
||||
|
||||
prefs_widget->prefs->click =
|
||||
gtk_toggle_button_get_active (button);
|
||||
|
||||
gtk_widget_set_sensitive (WID ("click_frame"), prefs_widget->prefs->click);
|
||||
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
click_volume_changed_cb (GtkAdjustment *adjustment, PrefsWidget *prefs_widget)
|
||||
{
|
||||
g_return_if_fail (prefs_widget != NULL);
|
||||
g_return_if_fail (IS_PREFS_WIDGET (prefs_widget));
|
||||
g_return_if_fail (prefs_widget->prefs != NULL);
|
||||
g_return_if_fail (IS_PREFERENCES (prefs_widget->prefs));
|
||||
g_return_if_fail (adjustment != NULL);
|
||||
g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
|
||||
|
||||
prefs_widget->prefs->volume = adjustment->value;
|
||||
|
||||
preferences_changed (prefs_widget->prefs);
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (prefs_widget), TRUE);
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* prefs-widget.h
|
||||
* Copyright (C) 2000 Helix Code, Inc.
|
||||
*
|
||||
* Written by Bradford Hovinen <hovinen@helixcode.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __PREFS_WIDGET_H
|
||||
#define __PREFS_WIDGET_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glade/glade.h>
|
||||
#include <capplet-widget.h>
|
||||
|
||||
#include "preferences.h"
|
||||
|
||||
#define PREFS_WIDGET(obj) GTK_CHECK_CAST (obj, prefs_widget_get_type (), PrefsWidget)
|
||||
#define PREFS_WIDGET_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, prefs_widget_get_type (), PrefsWidgetClass)
|
||||
#define IS_PREFS_WIDGET(obj) GTK_CHECK_TYPE (obj, prefs_widget_get_type ())
|
||||
|
||||
typedef struct _PrefsWidget PrefsWidget;
|
||||
typedef struct _PrefsWidgetClass PrefsWidgetClass;
|
||||
|
||||
struct _PrefsWidget
|
||||
{
|
||||
CappletWidget capplet_widget;
|
||||
|
||||
Preferences *prefs;
|
||||
GladeXML *dialog_data;
|
||||
|
||||
GtkWidget *delay[4];
|
||||
GtkWidget *rate[4];
|
||||
};
|
||||
|
||||
struct _PrefsWidgetClass
|
||||
{
|
||||
CappletWidgetClass parent_class;
|
||||
};
|
||||
|
||||
guint prefs_widget_get_type (void);
|
||||
|
||||
GtkWidget *prefs_widget_new (Preferences *prefs);
|
||||
|
||||
void prefs_widget_set_preferences (PrefsWidget *prefs_widget,
|
||||
Preferences *prefs);
|
||||
|
||||
#endif /* __PREFS_WIDGET_H */
|
||||
@@ -1,23 +0,0 @@
|
||||
INCLUDES = -I. -I$(srcdir) \
|
||||
-I$(top_srcdir)/intl -I$(top_builddir)/intl \
|
||||
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
|
||||
$(CAPPLET_CFLAGS)
|
||||
|
||||
bin_PROGRAMS = mime-type-capplet
|
||||
|
||||
mime_type_capplet_SOURCES = mime-type-capplet.c\
|
||||
mime-data.h mime-data.c edit-window.c\
|
||||
edit-window.h mime-info.c mime-info.h \
|
||||
new-mime-window.h new-mime-window.c
|
||||
|
||||
mime_type_capplet_LDADD = $(CAPPLET_LIBS)
|
||||
|
||||
EXTRA_DIST = \
|
||||
mime-type.desktop
|
||||
|
||||
|
||||
sysdir = $(datadir)/control-center
|
||||
sys_DATA = mime-type.desktop
|
||||
|
||||
install-data-local:
|
||||
$(INSTALL_DATA) $(srcdir)/mime-type.desktop $(DESTDIR)$(datadir)/gnome/apps/Settings/mime-type.desktop
|
||||
@@ -1,578 +0,0 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "edit-window.h"
|
||||
#include "mime-data.h"
|
||||
#include "mime-info.h"
|
||||
#include "capplet-widget.h"
|
||||
|
||||
|
||||
extern GtkWidget *capplet;
|
||||
extern GHashTable *user_mime_types;
|
||||
|
||||
typedef struct {
|
||||
GtkWidget *window;
|
||||
GtkWidget *icon_entry;
|
||||
GtkWidget *mime_type;
|
||||
/* GtkWidget *ext_tag_label; */
|
||||
GtkWidget *regexp1_tag_label;
|
||||
GtkWidget *regexp2_tag_label;
|
||||
/* GtkWidget *ext_label; */
|
||||
GtkWidget *regexp1_label;
|
||||
GtkWidget *regexp2_label;
|
||||
GtkWidget *open_entry;
|
||||
GtkWidget *edit_entry;
|
||||
GtkWidget *view_entry;
|
||||
GtkWidget *ext_scroll;
|
||||
GtkWidget *ext_clist;
|
||||
GtkWidget *ext_entry;
|
||||
GtkWidget *ext_add_button;
|
||||
GtkWidget *ext_remove_button;
|
||||
MimeInfo *mi;
|
||||
MimeInfo *user_mi;
|
||||
GList *tmp_ext[2];
|
||||
} edit_window;
|
||||
static edit_window *main_win = NULL;
|
||||
static gboolean changing = TRUE;
|
||||
static void
|
||||
destruction_handler (GtkWidget *widget, gpointer data)
|
||||
{
|
||||
g_free (main_win);
|
||||
main_win = NULL;
|
||||
}
|
||||
static void
|
||||
entry_changed (GtkWidget *widget, gpointer data)
|
||||
{
|
||||
if (changing == FALSE)
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (capplet),
|
||||
TRUE);
|
||||
}
|
||||
static void
|
||||
ext_clist_selected (GtkWidget *clist, gint row, gint column, gpointer data)
|
||||
{
|
||||
gboolean deletable;
|
||||
|
||||
deletable = GPOINTER_TO_INT (gtk_clist_get_row_data (GTK_CLIST (clist), row));
|
||||
if (deletable)
|
||||
gtk_widget_set_sensitive (main_win->ext_remove_button, TRUE);
|
||||
else
|
||||
gtk_widget_set_sensitive (main_win->ext_remove_button, FALSE);
|
||||
}
|
||||
static void
|
||||
ext_clist_deselected (GtkWidget *clist, gint row, gint column, gpointer data)
|
||||
{
|
||||
if (g_list_length (GTK_CLIST (clist)->selection) == 0)
|
||||
gtk_widget_set_sensitive (main_win->ext_remove_button, FALSE);
|
||||
}
|
||||
static void
|
||||
ext_entry_changed (GtkWidget *entry, gpointer data)
|
||||
{
|
||||
gchar *text;
|
||||
text = gtk_entry_get_text (GTK_ENTRY (entry));
|
||||
gtk_widget_set_sensitive (main_win->ext_add_button, (strlen (text) >0));
|
||||
}
|
||||
static void
|
||||
ext_add (GtkWidget *widget, gpointer data)
|
||||
{
|
||||
gchar *row[1];
|
||||
gint rownumber;
|
||||
|
||||
row[0] = g_strdup (gtk_entry_get_text (GTK_ENTRY (main_win->ext_entry)));
|
||||
rownumber = gtk_clist_append (GTK_CLIST (main_win->ext_clist), row);
|
||||
gtk_clist_set_row_data (GTK_CLIST (main_win->ext_clist), rownumber,
|
||||
GINT_TO_POINTER (TRUE));
|
||||
gtk_entry_set_text (GTK_ENTRY (main_win->ext_entry), "");
|
||||
|
||||
main_win->tmp_ext[0] = g_list_prepend (main_win->tmp_ext[0], row[0]);
|
||||
if (changing == FALSE)
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (capplet),
|
||||
TRUE);
|
||||
}
|
||||
static void
|
||||
ext_remove (GtkWidget *widget, gpointer data)
|
||||
{
|
||||
gint row;
|
||||
gchar *text;
|
||||
gchar *store;
|
||||
GList *tmp;
|
||||
|
||||
text = (gchar *)g_malloc (sizeof (gchar) * 1024);
|
||||
gtk_clist_freeze (GTK_CLIST (main_win->ext_clist));
|
||||
row = GPOINTER_TO_INT (GTK_CLIST (main_win->ext_clist)->selection->data);
|
||||
gtk_clist_get_text (GTK_CLIST (main_win->ext_clist), row, 0, &text);
|
||||
store = g_strdup (text);
|
||||
gtk_clist_remove (GTK_CLIST (main_win->ext_clist), row);
|
||||
|
||||
gtk_clist_thaw (GTK_CLIST (main_win->ext_clist));
|
||||
|
||||
for (tmp = main_win->tmp_ext[0]; tmp; tmp = tmp->next) {
|
||||
GList *found;
|
||||
|
||||
if (strcmp (tmp->data, store) == 0) {
|
||||
found = tmp;
|
||||
|
||||
main_win->tmp_ext[0] = g_list_remove_link (main_win->tmp_ext[0], found);
|
||||
g_list_free_1 (found);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (changing == FALSE)
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (capplet),
|
||||
TRUE);
|
||||
}
|
||||
static void
|
||||
apply_entry_change (GtkWidget *entry, gchar *key, MimeInfo *mi)
|
||||
{
|
||||
const gchar *buf;
|
||||
gchar *text;
|
||||
/* buf is the value that existed before when we
|
||||
* started the capplet */
|
||||
buf = local_mime_get_value (mi->mime_type, key);
|
||||
if (buf == NULL)
|
||||
buf = gnome_mime_get_value (mi->mime_type, key);
|
||||
text = gtk_entry_get_text (GTK_ENTRY (entry));
|
||||
if (text && !*text)
|
||||
text = NULL;
|
||||
|
||||
/* First we see if they've added something. */
|
||||
if (buf == NULL && text)
|
||||
set_mime_key_value (mi->mime_type, key, text);
|
||||
else {
|
||||
/* Has the value changed? */
|
||||
if (text && strcmp (text, buf))
|
||||
set_mime_key_value (mi->mime_type, key, text);
|
||||
else
|
||||
/* We _REALLY_ need a way to specify in
|
||||
* user.keys not to use the system defaults.
|
||||
* (ie. override the system default and
|
||||
* query it).
|
||||
* If we could then we'd set it here. */
|
||||
;
|
||||
}
|
||||
}
|
||||
static GList*
|
||||
copy_mi_extensions (GList *orig)
|
||||
{
|
||||
GList *tmp;
|
||||
GList *list = NULL;
|
||||
|
||||
for (tmp = orig; tmp; tmp = tmp->next) {
|
||||
list = g_list_append (list, g_strdup (tmp->data));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
static void
|
||||
make_readable (MimeInfo *mi)
|
||||
{
|
||||
GList *list;
|
||||
GString *extension;
|
||||
|
||||
extension = g_string_new ("");
|
||||
for (list = ((MimeInfo *) mi)->user_ext[0]; list; list = list->next) {
|
||||
g_string_append (extension, (gchar *) list->data);
|
||||
if (list->next != NULL)
|
||||
g_string_append (extension, ", ");
|
||||
}
|
||||
mi->ext_readable[0] = extension->str;
|
||||
g_string_free (extension, FALSE);
|
||||
|
||||
extension = g_string_new ("");
|
||||
for (list = ((MimeInfo *) mi)->user_ext[1]; list; list = list->next) {
|
||||
g_string_append (extension, (gchar *) list->data);
|
||||
if (list->next != NULL)
|
||||
g_string_append (extension, ", ");
|
||||
}
|
||||
mi->ext_readable[1] = extension->str;
|
||||
g_string_free (extension, FALSE);
|
||||
}
|
||||
static void
|
||||
apply_changes (MimeInfo *mi)
|
||||
{
|
||||
GList *tmp;
|
||||
int i;
|
||||
|
||||
apply_entry_change (gnome_icon_entry_gtk_entry (GNOME_ICON_ENTRY (main_win->icon_entry)),
|
||||
"icon-filename", mi);
|
||||
apply_entry_change (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (main_win->open_entry)),
|
||||
"open", mi);
|
||||
apply_entry_change (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (main_win->view_entry)),
|
||||
"view", mi);
|
||||
apply_entry_change (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (main_win->edit_entry)),
|
||||
"edit", mi);
|
||||
|
||||
if (!main_win->user_mi) {
|
||||
add_to_key (mi->mime_type, "ext: tmp", user_mime_types, TRUE);
|
||||
/* the tmp extension will be removed when we copy the tmp_ext
|
||||
* stuff over the top of it.
|
||||
*/
|
||||
main_win->user_mi = g_hash_table_lookup (user_mime_types,
|
||||
mi->mime_type);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (main_win->tmp_ext[i]) {
|
||||
main_win->user_mi->user_ext[i] = copy_mi_extensions (main_win->tmp_ext[i]);
|
||||
mi->user_ext[i] = copy_mi_extensions (main_win->tmp_ext[i]);
|
||||
} else {
|
||||
main_win->user_mi->user_ext[i] = NULL;
|
||||
mi->user_ext[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
make_readable (main_win->user_mi);
|
||||
|
||||
if (! (main_win->user_mi->ext[0] || main_win->user_mi->ext[1] ||
|
||||
main_win->user_mi->user_ext[0] || main_win->user_mi->ext[1]))
|
||||
g_hash_table_remove (user_mime_types, mi->mime_type);
|
||||
|
||||
/* Free the 2 tmp lists */
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (main_win->tmp_ext[i])
|
||||
for (tmp = main_win->tmp_ext[i]; tmp; tmp = tmp->next)
|
||||
g_free (tmp->data);
|
||||
}
|
||||
if (changing == FALSE)
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (capplet),
|
||||
TRUE);
|
||||
}
|
||||
static void
|
||||
browse_callback (GtkWidget *widget, gpointer data)
|
||||
{
|
||||
}
|
||||
static void
|
||||
initialize_main_win ()
|
||||
{
|
||||
GtkWidget *align, *vbox, *hbox, *vbox2, *vbox3;
|
||||
GtkWidget *frame, *table, *label;
|
||||
GtkWidget *button;
|
||||
GString *extension;
|
||||
gchar *title[2] = {"Extensions"};
|
||||
|
||||
main_win = g_new (edit_window, 1);
|
||||
main_win->window = gnome_dialog_new ("",
|
||||
GNOME_STOCK_BUTTON_OK,
|
||||
GNOME_STOCK_BUTTON_CANCEL,
|
||||
NULL);
|
||||
gtk_signal_connect (GTK_OBJECT (main_win->window),
|
||||
"destroy",
|
||||
destruction_handler,
|
||||
NULL);
|
||||
vbox = GNOME_DIALOG (main_win->window)->vbox;
|
||||
|
||||
/* icon box */
|
||||
main_win->icon_entry = gnome_icon_entry_new ("mime_icon_entry", _("Select an icon..."));
|
||||
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
|
||||
gtk_container_add (GTK_CONTAINER (align), main_win->icon_entry);
|
||||
gtk_signal_connect (GTK_OBJECT (gnome_icon_entry_gtk_entry (GNOME_ICON_ENTRY (main_win->icon_entry))),
|
||||
"changed",
|
||||
entry_changed,
|
||||
NULL);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("Mime Type: ")), FALSE, FALSE, 0);
|
||||
main_win->mime_type = gtk_label_new ("");
|
||||
gtk_box_pack_start (GTK_BOX (hbox), main_win->mime_type, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
|
||||
|
||||
/* extension/regexp */
|
||||
vbox2 = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
main_win->ext_clist = gtk_clist_new_with_titles (1, title);
|
||||
gtk_clist_column_titles_passive (GTK_CLIST (main_win->ext_clist));
|
||||
gtk_clist_set_auto_sort (GTK_CLIST (main_win->ext_clist), TRUE);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (main_win->ext_clist),
|
||||
"select-row",
|
||||
GTK_SIGNAL_FUNC (ext_clist_selected),
|
||||
NULL);
|
||||
gtk_signal_connect (GTK_OBJECT (main_win->ext_clist),
|
||||
"unselect-row",
|
||||
GTK_SIGNAL_FUNC (ext_clist_deselected),
|
||||
NULL);
|
||||
main_win->ext_scroll = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (main_win->ext_scroll),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (main_win->ext_scroll),
|
||||
main_win->ext_clist);
|
||||
|
||||
vbox3 = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
main_win->ext_add_button = gtk_button_new_with_label (_("Add"));
|
||||
gtk_signal_connect (GTK_OBJECT (main_win->ext_add_button),
|
||||
"clicked",
|
||||
GTK_SIGNAL_FUNC (ext_add),
|
||||
NULL);
|
||||
gtk_box_pack_start (GTK_BOX (vbox3), main_win->ext_add_button, FALSE, FALSE, 0);
|
||||
gtk_widget_set_sensitive (main_win->ext_add_button, FALSE);
|
||||
|
||||
main_win->ext_remove_button = gtk_button_new_with_label (_("Remove"));
|
||||
gtk_signal_connect (GTK_OBJECT (main_win->ext_remove_button),
|
||||
"clicked",
|
||||
GTK_SIGNAL_FUNC (ext_remove),
|
||||
NULL);
|
||||
gtk_widget_set_sensitive (main_win->ext_remove_button, FALSE);
|
||||
gtk_box_pack_start (GTK_BOX (vbox3), main_win->ext_remove_button,
|
||||
FALSE, FALSE, 0);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox), main_win->ext_scroll, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), vbox3, FALSE, FALSE, 0);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox2), hbox, TRUE, TRUE, 0);
|
||||
|
||||
main_win->ext_entry = gtk_entry_new ();
|
||||
gtk_signal_connect (GTK_OBJECT (main_win->ext_entry),
|
||||
"changed",
|
||||
ext_entry_changed,
|
||||
NULL);
|
||||
gtk_signal_connect (GTK_OBJECT (main_win->ext_entry),
|
||||
"activate",
|
||||
ext_add,
|
||||
NULL);
|
||||
gtk_box_pack_start (GTK_BOX (vbox2), main_win->ext_entry, TRUE, TRUE, 0);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
main_win->regexp1_label = gtk_label_new ("");
|
||||
main_win->regexp1_tag_label = gtk_label_new (_("First Regular Expression: "));
|
||||
gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), main_win->regexp1_tag_label,
|
||||
FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), main_win->regexp1_label, FALSE, FALSE, 0);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
main_win->regexp2_label = gtk_label_new ("");
|
||||
main_win->regexp2_tag_label = gtk_label_new (_("Second Regular Expression: "));
|
||||
gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), main_win->regexp2_tag_label,
|
||||
FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), main_win->regexp2_label, FALSE, FALSE, 0);
|
||||
|
||||
/* Actions box */
|
||||
frame = gtk_frame_new (_("Mime Type Actions"));
|
||||
vbox2 = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
|
||||
table = gtk_table_new (3, 2, FALSE);
|
||||
gtk_table_set_row_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (table), GNOME_PAD_SMALL);
|
||||
gtk_container_add (GTK_CONTAINER (frame), vbox2);
|
||||
label = gtk_label_new (_("Example: emacs %f"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_misc_set_padding (GTK_MISC (label), 2, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox2), table, FALSE, FALSE, 0);
|
||||
label = gtk_label_new (_("Open"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_misc_set_padding (GTK_MISC (label), 2, 0);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table),
|
||||
label,
|
||||
0, 1, 0, 1);
|
||||
main_win->open_entry = gnome_file_entry_new ("MIME_CAPPLET_OPEN", _("Select a file..."));
|
||||
gtk_signal_connect (GTK_OBJECT (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (main_win->open_entry))),
|
||||
"changed",
|
||||
entry_changed,
|
||||
NULL);
|
||||
|
||||
gtk_table_attach_defaults (GTK_TABLE (table),
|
||||
main_win->open_entry,
|
||||
1, 2, 0, 1);
|
||||
label = gtk_label_new (_("View"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_misc_set_padding (GTK_MISC (label), 2, 0);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table),
|
||||
label,
|
||||
0, 1, 1, 2);
|
||||
|
||||
main_win->view_entry = gnome_file_entry_new ("MIME_CAPPLET_VIEW", _("Select a file..."));
|
||||
gtk_signal_connect (GTK_OBJECT (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (main_win->view_entry))),
|
||||
"changed",
|
||||
entry_changed,
|
||||
NULL);
|
||||
|
||||
gtk_table_attach_defaults (GTK_TABLE (table),
|
||||
main_win->view_entry,
|
||||
1, 2, 1, 2);
|
||||
label = gtk_label_new (_("Edit"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_misc_set_padding (GTK_MISC (label), 2, 0);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table),
|
||||
label,
|
||||
0, 1, 2, 3);
|
||||
main_win->edit_entry = gnome_file_entry_new ("MIME_CAPPLET_EDIT", _("Select a file..."));
|
||||
gtk_signal_connect (GTK_OBJECT (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (main_win->edit_entry))),
|
||||
"changed",
|
||||
entry_changed,
|
||||
NULL);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table),
|
||||
main_win->edit_entry,
|
||||
1, 2, 2, 3);
|
||||
}
|
||||
static void
|
||||
setup_entry (gchar *key, GtkWidget *g_entry, MimeInfo *mi)
|
||||
{
|
||||
const gchar *buf;
|
||||
GtkWidget *entry = gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (g_entry));
|
||||
buf = local_mime_get_value (mi->mime_type, key);
|
||||
if (buf == NULL)
|
||||
buf = gnome_mime_get_value (mi->mime_type, key);
|
||||
if (buf)
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), buf);
|
||||
else
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), "");
|
||||
}
|
||||
void
|
||||
initialize_main_win_vals (void)
|
||||
{
|
||||
MimeInfo *mi;
|
||||
gchar *title;
|
||||
gboolean showext = FALSE;
|
||||
if (main_win == NULL)
|
||||
return;
|
||||
mi = main_win->mi;
|
||||
if (mi == NULL)
|
||||
return;
|
||||
/* now we fill in the fields with the mi stuff. */
|
||||
|
||||
changing = TRUE;
|
||||
gtk_label_set_text (GTK_LABEL (main_win->mime_type), mi->mime_type);
|
||||
gnome_icon_entry_set_icon (GNOME_ICON_ENTRY (main_win->icon_entry),
|
||||
gnome_mime_get_value (mi->mime_type,
|
||||
"icon-filename"));
|
||||
|
||||
gtk_widget_show_all (GNOME_DIALOG (main_win->window)->vbox);
|
||||
/* we initialize everything */
|
||||
title = g_strdup_printf (_("Set actions for %s"), mi->mime_type);
|
||||
gtk_window_set_title (GTK_WINDOW (main_win->window), title);
|
||||
g_free (title);
|
||||
|
||||
/* not sure why this is necessary */
|
||||
gtk_clist_clear (GTK_CLIST (main_win->ext_clist));
|
||||
if (mi->ext[0]) {
|
||||
GList *tmp;
|
||||
gchar *extension[1];
|
||||
gint row;
|
||||
for (tmp = mi->ext[0]; tmp; tmp = tmp->next) {
|
||||
extension[0] = g_strdup (tmp->data);
|
||||
row = gtk_clist_append (GTK_CLIST (main_win->ext_clist),
|
||||
extension);
|
||||
gtk_clist_set_row_data (GTK_CLIST (main_win->ext_clist),
|
||||
row, GINT_TO_POINTER (FALSE));
|
||||
}
|
||||
showext = TRUE;
|
||||
}
|
||||
if (mi->ext[1]) {
|
||||
GList *tmp;
|
||||
gchar *extension[1];
|
||||
gint row;
|
||||
for (tmp = mi->ext[1]; tmp; tmp = tmp->next) {
|
||||
extension[0] = g_strdup (tmp->data);
|
||||
row = gtk_clist_append (GTK_CLIST (main_win->ext_clist),
|
||||
extension);
|
||||
gtk_clist_set_row_data (GTK_CLIST (main_win->ext_clist),
|
||||
row, GINT_TO_POINTER (FALSE));
|
||||
}
|
||||
showext = TRUE;
|
||||
}
|
||||
if (main_win->tmp_ext[0]) {
|
||||
GList *tmp;
|
||||
gchar *extension[1];
|
||||
gint row;
|
||||
for (tmp = main_win->tmp_ext[0]; tmp; tmp = tmp->next) {
|
||||
extension[0] = g_strdup (tmp->data);
|
||||
row = gtk_clist_append (GTK_CLIST (main_win->ext_clist),
|
||||
extension);
|
||||
gtk_clist_set_row_data (GTK_CLIST (main_win->ext_clist),
|
||||
row, GINT_TO_POINTER (TRUE));
|
||||
}
|
||||
showext = TRUE;
|
||||
}
|
||||
if (main_win->tmp_ext[1]) {
|
||||
GList *tmp;
|
||||
gchar *extension[1];
|
||||
gint row;
|
||||
for (tmp = main_win->tmp_ext[0]; tmp; tmp = tmp->next) {
|
||||
extension[0] = g_strdup (tmp->data);
|
||||
row = gtk_clist_append (GTK_CLIST (main_win->ext_clist),
|
||||
extension);
|
||||
gtk_clist_set_row_data (GTK_CLIST (main_win->ext_clist),
|
||||
row, GINT_TO_POINTER (TRUE));
|
||||
}
|
||||
showext = TRUE;
|
||||
}
|
||||
if (!showext) {
|
||||
gtk_widget_hide (main_win->ext_clist);
|
||||
gtk_widget_hide (main_win->ext_entry);
|
||||
gtk_widget_hide (main_win->ext_add_button);
|
||||
gtk_widget_hide (main_win->ext_remove_button);
|
||||
gtk_widget_hide (main_win->ext_scroll);
|
||||
}
|
||||
if (mi->regex_readable[0])
|
||||
gtk_label_set_text (GTK_LABEL (main_win->regexp1_label),
|
||||
mi->regex_readable[0]);
|
||||
else {
|
||||
gtk_widget_hide (main_win->regexp1_label);
|
||||
gtk_widget_hide (main_win->regexp1_tag_label);
|
||||
}
|
||||
if (mi->regex_readable[1])
|
||||
gtk_label_set_text (GTK_LABEL (main_win->regexp2_label),
|
||||
mi->regex_readable[1]);
|
||||
else {
|
||||
gtk_widget_hide (main_win->regexp2_label);
|
||||
gtk_widget_hide (main_win->regexp2_tag_label);
|
||||
}
|
||||
/* initialize the entries */
|
||||
setup_entry ("open", main_win->open_entry, mi);
|
||||
setup_entry ("view", main_win->view_entry, mi);
|
||||
setup_entry ("edit", main_win->edit_entry, mi);
|
||||
changing = FALSE;
|
||||
|
||||
}
|
||||
void
|
||||
launch_edit_window (MimeInfo *mi)
|
||||
{
|
||||
gint size;
|
||||
|
||||
if (main_win == NULL)
|
||||
initialize_main_win ();
|
||||
main_win->mi = mi;
|
||||
main_win->user_mi = g_hash_table_lookup (user_mime_types, mi->mime_type);
|
||||
main_win->tmp_ext[0] = NULL;
|
||||
main_win->tmp_ext[1] = NULL;
|
||||
if (main_win->user_mi) {
|
||||
if (main_win->user_mi->user_ext[0])
|
||||
main_win->tmp_ext[0] = copy_mi_extensions (main_win->user_mi->user_ext[0]);
|
||||
if (main_win->user_mi->user_ext[1])
|
||||
main_win->tmp_ext[1] = copy_mi_extensions (main_win->user_mi->user_ext[1]);
|
||||
}
|
||||
initialize_main_win_vals ();
|
||||
|
||||
switch(gnome_dialog_run (GNOME_DIALOG (main_win->window))) {
|
||||
case 0:
|
||||
apply_changes (mi);
|
||||
case 1:
|
||||
main_win->mi = NULL;
|
||||
gtk_widget_hide (main_win->window);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
hide_edit_window (void)
|
||||
{
|
||||
if (main_win && main_win->mi && main_win->window)
|
||||
gtk_widget_hide (main_win->window);
|
||||
}
|
||||
void
|
||||
show_edit_window (void)
|
||||
{
|
||||
if (main_win && main_win->mi && main_win->window)
|
||||
gtk_widget_show (main_win->window);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
|
||||
/* Copyright (C) 1998 Redhat Software Inc.
|
||||
* Authors: Jonathan Blandford <jrb@redhat.com>
|
||||
*/
|
||||
#include "mime-data.h"
|
||||
#ifndef _EDIT_WINDOW_H_
|
||||
#define _EDIT_WINDOW_H_
|
||||
|
||||
|
||||
void launch_edit_window (MimeInfo *mi);
|
||||
void initialize_main_win_vals (void);
|
||||
void hide_edit_window (void);
|
||||
void show_edit_window (void);
|
||||
|
||||
#endif
|
||||
@@ -1,660 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
|
||||
/* Copyright (C) 1998 Redhat Software Inc.
|
||||
* Authors: Jonathan Blandford <jrb@redhat.com>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "capplet-widget.h"
|
||||
#include "gnome.h"
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <regex.h>
|
||||
#include <ctype.h>
|
||||
#include "edit-window.h"
|
||||
#include "mime-data.h"
|
||||
#include "mime-info.h"
|
||||
#include "new-mime-window.h"
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/* Prototypes */
|
||||
static void mime_fill_from_file (const char *filename, gboolean init_user);
|
||||
static void mime_load_from_dir (const char *mime_info_dir, gboolean system_dir);
|
||||
void add_to_key (char *mime_type, char *def, GHashTable *table, gboolean init_user);
|
||||
static char *get_priority (char *def, int *priority);
|
||||
|
||||
|
||||
/* Global variables */
|
||||
static char *current_lang;
|
||||
static GHashTable *mime_types = NULL;
|
||||
static GHashTable *initial_user_mime_types = NULL;
|
||||
GHashTable *user_mime_types = NULL;
|
||||
static GtkWidget *clist = NULL;
|
||||
extern GtkWidget *delete_button;
|
||||
extern GtkWidget *capplet;
|
||||
/* Initialization functions */
|
||||
static void
|
||||
run_error (gchar *message)
|
||||
{
|
||||
GtkWidget *error_box;
|
||||
|
||||
error_box = gnome_message_box_new (
|
||||
message,
|
||||
GNOME_MESSAGE_BOX_ERROR,
|
||||
GNOME_STOCK_BUTTON_OK,
|
||||
NULL);
|
||||
gnome_dialog_run_and_close (GNOME_DIALOG (error_box));
|
||||
}
|
||||
static char *
|
||||
get_priority (char *def, int *priority)
|
||||
{
|
||||
*priority = 0;
|
||||
|
||||
if (*def == ','){
|
||||
def++;
|
||||
if (*def == '1'){
|
||||
*priority = 0;
|
||||
def++;
|
||||
} else if (*def == '2'){
|
||||
*priority = 1;
|
||||
def++;
|
||||
}
|
||||
}
|
||||
|
||||
while (*def && *def == ':')
|
||||
def++;
|
||||
|
||||
return def;
|
||||
}
|
||||
static void
|
||||
free_mime_info (MimeInfo *mi)
|
||||
{
|
||||
|
||||
}
|
||||
void
|
||||
add_to_key (char *mime_type, char *def, GHashTable *table, gboolean init_user)
|
||||
{
|
||||
int priority = 1;
|
||||
char *s, *p, *ext;
|
||||
int used;
|
||||
MimeInfo *info;
|
||||
|
||||
info = g_hash_table_lookup (table, (const void *) mime_type);
|
||||
if (info == NULL) {
|
||||
info = g_malloc (sizeof (MimeInfo));
|
||||
info->mime_type = g_strdup (mime_type);
|
||||
info->regex[0] = NULL;
|
||||
info->regex[1] = NULL;
|
||||
info->ext[0] = NULL;
|
||||
info->ext[1] = NULL;
|
||||
info->user_ext[0] = NULL;
|
||||
info->user_ext[1] = NULL;
|
||||
info->regex_readable[0] = NULL;
|
||||
info->regex_readable[1] = NULL;
|
||||
info->ext_readable[0] = NULL;
|
||||
info->ext_readable[1] = NULL;
|
||||
info->keys = gnome_mime_get_keys (mime_type);
|
||||
g_hash_table_insert (table, info->mime_type, info);
|
||||
}
|
||||
if (strncmp (def, "ext", 3) == 0){
|
||||
char *tokp;
|
||||
|
||||
def += 3;
|
||||
def = get_priority (def, &priority);
|
||||
s = p = g_strdup (def);
|
||||
|
||||
used = 0;
|
||||
|
||||
while ((ext = strtok_r (s, " \t\n\r,", &tokp)) != NULL){
|
||||
/* FIXME: We really need to check for duplicates before entering this. */
|
||||
if (!init_user) {
|
||||
info->ext[priority] = g_list_prepend (info->ext[priority], ext);
|
||||
} else {
|
||||
info->user_ext[priority] = g_list_prepend (info->user_ext[priority], ext);
|
||||
}
|
||||
used = 1;
|
||||
s = NULL;
|
||||
}
|
||||
if (!used)
|
||||
g_free (p);
|
||||
}
|
||||
|
||||
if (strncmp (def, "regex", 5) == 0){
|
||||
regex_t *regex;
|
||||
|
||||
regex = g_new (regex_t, 1);
|
||||
def += 5;
|
||||
def = get_priority (def, &priority);
|
||||
|
||||
while (*def && isspace (*def))
|
||||
def++;
|
||||
|
||||
if (!*def)
|
||||
return;
|
||||
if (regcomp (regex, def, REG_EXTENDED | REG_NOSUB))
|
||||
g_free (regex);
|
||||
else {
|
||||
info->regex[priority] = regex;
|
||||
g_free (info->regex_readable[priority]);
|
||||
info->regex_readable[priority] = g_strdup (def);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void
|
||||
mime_fill_from_file (const char *filename, gboolean init_user)
|
||||
{
|
||||
FILE *f;
|
||||
char buf [1024];
|
||||
char *current_key;
|
||||
gboolean used;
|
||||
|
||||
g_assert (filename != NULL);
|
||||
|
||||
f = fopen (filename, "r");
|
||||
if (!f)
|
||||
return;
|
||||
|
||||
current_key = NULL;
|
||||
used = FALSE;
|
||||
while (fgets (buf, sizeof (buf), f)){
|
||||
char *p;
|
||||
|
||||
if (buf [0] == '#')
|
||||
continue;
|
||||
|
||||
/* Trim trailing spaces */
|
||||
for (p = buf + strlen (buf) - 1; p >= buf; p--){
|
||||
if (isspace (*p) || *p == '\n')
|
||||
*p = 0;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (!buf [0])
|
||||
continue;
|
||||
|
||||
if (buf [0] == '\t' || buf [0] == ' '){
|
||||
if (current_key){
|
||||
char *p = buf;
|
||||
|
||||
while (*p && isspace (*p))
|
||||
p++;
|
||||
|
||||
if (*p == 0)
|
||||
continue;
|
||||
add_to_key (current_key, p, mime_types, init_user);
|
||||
if (init_user) {
|
||||
add_to_key (current_key, p,
|
||||
initial_user_mime_types,
|
||||
TRUE);
|
||||
add_to_key (current_key, p,
|
||||
user_mime_types, TRUE);
|
||||
}
|
||||
used = TRUE;
|
||||
}
|
||||
} else {
|
||||
if (!used && current_key)
|
||||
g_free (current_key);
|
||||
current_key = g_strdup (buf);
|
||||
if (current_key [strlen (current_key)-1] == ':')
|
||||
current_key [strlen (current_key)-1] = 0;
|
||||
|
||||
used = FALSE;
|
||||
}
|
||||
}
|
||||
fclose (f);
|
||||
}
|
||||
|
||||
static void
|
||||
mime_load_from_dir (const char *mime_info_dir, gboolean system_dir)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *dent;
|
||||
const int extlen = sizeof (".mime") - 1;
|
||||
char *filename;
|
||||
|
||||
dir = opendir (mime_info_dir);
|
||||
if (!dir)
|
||||
return;
|
||||
if (system_dir) {
|
||||
filename = g_concat_dir_and_file (mime_info_dir, "gnome.mime");
|
||||
mime_fill_from_file (filename, FALSE);
|
||||
g_free (filename);
|
||||
}
|
||||
while ((dent = readdir (dir)) != NULL){
|
||||
|
||||
int len = strlen (dent->d_name);
|
||||
|
||||
if (len <= extlen)
|
||||
continue;
|
||||
|
||||
if (strcmp (dent->d_name + len - extlen, ".mime"))
|
||||
continue;
|
||||
if (system_dir && !strcmp (dent->d_name, "gnome.mime"))
|
||||
continue;
|
||||
if (!system_dir && !strcmp (dent->d_name, "user.mime"))
|
||||
continue;
|
||||
|
||||
filename = g_concat_dir_and_file (mime_info_dir, dent->d_name);
|
||||
mime_fill_from_file (filename, FALSE);
|
||||
g_free (filename);
|
||||
}
|
||||
if (!system_dir) {
|
||||
filename = g_concat_dir_and_file (mime_info_dir, "user.mime");
|
||||
mime_fill_from_file (filename, TRUE);
|
||||
g_free (filename);
|
||||
}
|
||||
closedir (dir);
|
||||
}
|
||||
static int
|
||||
add_mime_vals_to_clist (gchar *mime_type, gpointer mi, gpointer cl)
|
||||
{
|
||||
/* we also finalize the MimeInfo structure here, now that we're done
|
||||
* loading it */
|
||||
static gchar *text[2];
|
||||
GList *list;
|
||||
GString *extension;
|
||||
gint row;
|
||||
|
||||
extension = g_string_new ("");
|
||||
for (list = ((MimeInfo *) mi)->ext[0];list; list=list->next) {
|
||||
g_string_append (extension, (gchar *) list->data);
|
||||
if (list->next != NULL)
|
||||
g_string_append (extension, ", ");
|
||||
}
|
||||
if (strcmp (extension->str, "") != 0 && ((MimeInfo *)mi)->user_ext[0])
|
||||
g_string_append (extension, ", ");
|
||||
for (list = ((MimeInfo *) mi)->user_ext[0]; list; list=list->next) {
|
||||
g_string_append (extension, (gchar *) list->data);
|
||||
if (list->next != NULL)
|
||||
g_string_append (extension, ", ");
|
||||
}
|
||||
((MimeInfo *) mi)->ext_readable[0] = extension->str;
|
||||
g_string_free (extension, FALSE);
|
||||
|
||||
extension = g_string_new ("");
|
||||
for (list = ((MimeInfo *) mi)->ext[1];list; list=list->next) {
|
||||
g_string_append (extension, (gchar *) list->data);
|
||||
if (list->next)
|
||||
g_string_append (extension, ", ");
|
||||
}
|
||||
if (strcmp (extension->str, "") != 0 && ((MimeInfo *)mi)->user_ext[1])
|
||||
g_string_append (extension, ", ");
|
||||
for (list = ((MimeInfo *) mi)->user_ext[1]; list; list=list->next) {
|
||||
g_string_append (extension, (gchar *) list->data);
|
||||
if (list->next != NULL)
|
||||
g_string_append (extension, ", ");
|
||||
}
|
||||
((MimeInfo *) mi)->ext_readable[1] = extension->str;
|
||||
g_string_free (extension, FALSE);
|
||||
|
||||
if (((MimeInfo *) mi)->ext[0] || ((MimeInfo *) mi)->user_ext[0]) {
|
||||
extension = g_string_new ((((MimeInfo *) mi)->ext_readable[0]));
|
||||
if (((MimeInfo *) mi)->ext[1] || ((MimeInfo *) mi)->user_ext[1]) {
|
||||
g_string_append (extension, ", ");
|
||||
g_string_append (extension, (((MimeInfo *) mi)->ext_readable[1]));
|
||||
}
|
||||
} else if (((MimeInfo *) mi)->ext[1] || ((MimeInfo *) mi)->user_ext[1])
|
||||
extension = g_string_new ((((MimeInfo *) mi)->ext_readable[1]));
|
||||
else
|
||||
extension = g_string_new ("");
|
||||
|
||||
text[0] = ((MimeInfo *) mi)->mime_type;
|
||||
text[1] = extension->str;
|
||||
|
||||
row = gtk_clist_insert (GTK_CLIST (cl), 1, text);
|
||||
gtk_clist_set_row_data (GTK_CLIST (cl), row, mi);
|
||||
g_string_free (extension, TRUE);
|
||||
return row;
|
||||
}
|
||||
static void
|
||||
selected_row_callback (GtkWidget *widget, gint row, gint column, GdkEvent *event, gpointer data)
|
||||
{
|
||||
MimeInfo *mi;
|
||||
if (column < 0)
|
||||
return;
|
||||
|
||||
mi = (MimeInfo *) gtk_clist_get_row_data (GTK_CLIST (widget),row);
|
||||
|
||||
if (event && event->type == GDK_2BUTTON_PRESS)
|
||||
launch_edit_window (mi);
|
||||
|
||||
if (g_hash_table_lookup (user_mime_types, mi->mime_type)) {
|
||||
gtk_widget_set_sensitive (delete_button, TRUE);
|
||||
} else
|
||||
gtk_widget_set_sensitive (delete_button, FALSE);
|
||||
}
|
||||
|
||||
/* public functions */
|
||||
void
|
||||
delete_clicked (GtkWidget *widget, gpointer data)
|
||||
{
|
||||
MimeInfo *mi;
|
||||
gint row = 0;
|
||||
|
||||
if (GTK_CLIST (clist)->selection)
|
||||
row = GPOINTER_TO_INT ((GTK_CLIST (clist)->selection)->data);
|
||||
else
|
||||
return;
|
||||
mi = (MimeInfo *) gtk_clist_get_row_data (GTK_CLIST (clist), row);
|
||||
|
||||
gtk_clist_remove (GTK_CLIST (clist), row);
|
||||
g_hash_table_remove (user_mime_types, mi->mime_type);
|
||||
remove_mime_info (mi->mime_type);
|
||||
free_mime_info (mi);
|
||||
capplet_widget_state_changed (CAPPLET_WIDGET (capplet),
|
||||
TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
edit_clicked (GtkWidget *widget, gpointer data)
|
||||
{
|
||||
MimeInfo *mi;
|
||||
gint row = 0;
|
||||
|
||||
if (GTK_CLIST (clist)->selection)
|
||||
row = GPOINTER_TO_INT ((GTK_CLIST (clist)->selection)->data);
|
||||
else
|
||||
return;
|
||||
mi = (MimeInfo *) gtk_clist_get_row_data (GTK_CLIST (clist), row);
|
||||
if (mi)
|
||||
launch_edit_window (mi);
|
||||
gtk_clist_remove (GTK_CLIST (clist), row);
|
||||
row = add_mime_vals_to_clist (mi->mime_type, mi, clist);
|
||||
gtk_clist_select_row (GTK_CLIST (clist), row, 0);
|
||||
}
|
||||
void
|
||||
add_clicked (GtkWidget *widget, gpointer data)
|
||||
{
|
||||
launch_new_mime_window ();
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
get_mime_clist (void)
|
||||
{
|
||||
GtkWidget *retval;
|
||||
gchar *titles[2];
|
||||
|
||||
titles[0] = _("Mime Type");
|
||||
titles[1] = _("Extension");
|
||||
retval = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (retval),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
clist = gtk_clist_new_with_titles (2, titles);
|
||||
gtk_signal_connect (GTK_OBJECT (clist),
|
||||
"select_row",
|
||||
GTK_SIGNAL_FUNC (selected_row_callback),
|
||||
NULL);
|
||||
gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_BROWSE);
|
||||
gtk_clist_set_auto_sort (GTK_CLIST (clist), TRUE);
|
||||
if (clist)
|
||||
g_hash_table_foreach (mime_types, (GHFunc) add_mime_vals_to_clist, clist);
|
||||
gtk_clist_columns_autosize (GTK_CLIST (clist));
|
||||
gtk_clist_select_row (GTK_CLIST (clist), 0, 0);
|
||||
gtk_container_add (GTK_CONTAINER (retval), clist);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
finalize_mime_type_foreach (gpointer mime_type, gpointer info, gpointer data)
|
||||
{
|
||||
MimeInfo *mi = (MimeInfo *)info;
|
||||
GList *list;
|
||||
GString *extension;
|
||||
|
||||
extension = g_string_new ("");
|
||||
for (list = ((MimeInfo *) mi)->ext[0];list; list=list->next) {
|
||||
g_string_append (extension, (gchar *) list->data);
|
||||
if (list->next != NULL)
|
||||
g_string_append (extension, ", ");
|
||||
}
|
||||
if (strcmp (extension->str, "") != 0 && mi->user_ext[0])
|
||||
g_string_append (extension, ", ");
|
||||
for (list = ((MimeInfo *) mi)->user_ext[0]; list; list=list->next) {
|
||||
g_string_append (extension, (gchar *) list->data);
|
||||
if (list->next != NULL)
|
||||
g_string_append (extension, ", ");
|
||||
}
|
||||
((MimeInfo *) mi)->ext_readable[0] = extension->str;
|
||||
g_string_free (extension, FALSE);
|
||||
|
||||
extension = g_string_new ("");
|
||||
for (list = ((MimeInfo *) mi)->ext[1];list; list=list->next) {
|
||||
g_string_append (extension, (gchar *) list->data);
|
||||
if (list->next)
|
||||
g_string_append (extension, ", ");
|
||||
}
|
||||
if (strcmp (extension->str, "") != 0 && mi->user_ext[1])
|
||||
g_string_append (extension, ", ");
|
||||
for (list = ((MimeInfo *) mi)->user_ext[1]; list; list=list->next) {
|
||||
g_string_append (extension, (gchar *) list->data);
|
||||
if (list->next != NULL)
|
||||
g_string_append (extension, ", ");
|
||||
}
|
||||
((MimeInfo *) mi)->ext_readable[1] = extension->str;
|
||||
g_string_free (extension, FALSE);
|
||||
|
||||
if (((MimeInfo *) mi)->ext[0] || ((MimeInfo *) mi)->user_ext[0]) {
|
||||
extension = g_string_new ((((MimeInfo *) mi)->ext_readable[0]));
|
||||
if (((MimeInfo *) mi)->ext[1] || ((MimeInfo *) mi)->user_ext[1]) {
|
||||
g_string_append (extension, ", ");
|
||||
g_string_append (extension, (((MimeInfo *) mi)->ext_readable[1]));
|
||||
}
|
||||
} else if (((MimeInfo *) mi)->ext[1] || ((MimeInfo *) mi)->user_ext[1])
|
||||
extension = g_string_new ((((MimeInfo *) mi)->ext_readable[1]));
|
||||
else
|
||||
extension = g_string_new ("");
|
||||
g_string_free (extension, TRUE);
|
||||
}
|
||||
static void
|
||||
finalize_user_mime ()
|
||||
{
|
||||
g_hash_table_foreach (user_mime_types, finalize_mime_type_foreach, NULL);
|
||||
g_hash_table_foreach (initial_user_mime_types, finalize_mime_type_foreach, NULL);
|
||||
}
|
||||
void
|
||||
init_mime_type (void)
|
||||
{
|
||||
char *mime_info_dir;
|
||||
|
||||
mime_types = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
initial_user_mime_types = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
user_mime_types = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
mime_info_dir = gnome_unconditional_datadir_file ("mime-info");
|
||||
mime_load_from_dir (mime_info_dir, TRUE);
|
||||
g_free (mime_info_dir);
|
||||
|
||||
mime_info_dir = g_concat_dir_and_file (gnome_util_user_home (), ".gnome/mime-info");
|
||||
mime_load_from_dir (mime_info_dir, FALSE);
|
||||
g_free (mime_info_dir);
|
||||
finalize_user_mime ();
|
||||
init_mime_info ();
|
||||
}
|
||||
void
|
||||
add_new_mime_type (gchar *mime_type, gchar *raw_ext, gchar *regexp1, gchar *regexp2)
|
||||
{
|
||||
gchar *temp;
|
||||
MimeInfo *mi = NULL;
|
||||
gint row;
|
||||
gchar *ext = NULL;
|
||||
gchar *ptr, *ptr2;
|
||||
|
||||
/* first we make sure that the information is good */
|
||||
if (mime_type == NULL || *mime_type == '\000') {
|
||||
run_error (_("You must enter a mime-type"));
|
||||
return;
|
||||
} else if ((raw_ext == NULL || *raw_ext == '\000') &&
|
||||
(regexp1 == NULL || *regexp1 == '\000') &&
|
||||
(regexp2 == NULL || *regexp2 == '\000')){
|
||||
run_error (_("You must add either a regular-expression or\na file-name extension"));
|
||||
return;
|
||||
}
|
||||
if (strchr (mime_type, '/') == NULL) {
|
||||
run_error (_("Please put your mime-type in the format:\nCATEGORY/TYPE\n\nFor Example:\nimage/png"));
|
||||
return;
|
||||
}
|
||||
if (g_hash_table_lookup (user_mime_types, mime_type) ||
|
||||
g_hash_table_lookup (mime_types, mime_type)) {
|
||||
run_error (_("This mime-type already exists"));
|
||||
return;
|
||||
}
|
||||
if (raw_ext || *raw_ext) {
|
||||
ptr2 = ext = g_malloc (sizeof (raw_ext));
|
||||
for (ptr = raw_ext;*ptr; ptr++) {
|
||||
if (*ptr != '.' && *ptr != ',') {
|
||||
*ptr2 = *ptr;
|
||||
ptr2 += 1;
|
||||
}
|
||||
}
|
||||
*ptr2 = '\000';
|
||||
}
|
||||
/* passed check, now we add it. */
|
||||
if (ext) {
|
||||
temp = g_strconcat ("ext: ", ext, NULL);
|
||||
add_to_key (mime_type, temp, user_mime_types, TRUE);
|
||||
mi = (MimeInfo *) g_hash_table_lookup (user_mime_types, mime_type);
|
||||
g_free (temp);
|
||||
}
|
||||
if (regexp1) {
|
||||
temp = g_strconcat ("regex: ", regexp1, NULL);
|
||||
add_to_key (mime_type, temp, user_mime_types, TRUE);
|
||||
g_free (temp);
|
||||
}
|
||||
if (regexp2) {
|
||||
temp = g_strconcat ("regex,2: ", regexp2, NULL);
|
||||
add_to_key (mime_type, temp, user_mime_types, TRUE);
|
||||
g_free (temp);
|
||||
}
|
||||
/* Finally add it to the clist */
|
||||
if (mi) {
|
||||
row = add_mime_vals_to_clist (mime_type, mi, clist);
|
||||
gtk_clist_select_row (GTK_CLIST (clist), row, 0);
|
||||
gtk_clist_moveto (GTK_CLIST (clist), row, 0, 0.5, 0.0);
|
||||
}
|
||||
g_free (ext);
|
||||
}
|
||||
static void
|
||||
write_mime_foreach (gpointer mime_type, gpointer info, gpointer data)
|
||||
{
|
||||
gchar *buf;
|
||||
MimeInfo *mi = (MimeInfo *) info;
|
||||
fwrite ((char *) mi->mime_type, 1, strlen ((char *) mi->mime_type), (FILE *) data);
|
||||
fwrite ("\n", 1, 1, (FILE *) data);
|
||||
if (mi->ext_readable[0]) {
|
||||
fwrite ("\text: ", 1, strlen ("\text: "), (FILE *) data);
|
||||
fwrite (mi->ext_readable[0], 1,
|
||||
strlen (mi->ext_readable[0]),
|
||||
(FILE *) data);
|
||||
fwrite ("\n", 1, 1, (FILE *) data);
|
||||
}
|
||||
if (mi->regex_readable[0]) {
|
||||
fwrite ("\tregex: ", 1, strlen ("\tregex: "), (FILE *) data);
|
||||
fwrite (mi->regex_readable[0], 1,
|
||||
strlen (mi->regex_readable[0]),
|
||||
(FILE *) data);
|
||||
fwrite ("\n", 1, 1, (FILE *) data);
|
||||
}
|
||||
if (mi->regex_readable[1]) {
|
||||
fwrite ("\tregex,2: ", 1, strlen ("\tregex,2: "), (FILE *) data);
|
||||
fwrite (mi->regex_readable[1], 1,
|
||||
strlen (mi->regex_readable[1]),
|
||||
(FILE *) data);
|
||||
fwrite ("\n", 1, 1, (FILE *) data);
|
||||
}
|
||||
fwrite ("\n", 1, 1, (FILE *) data);
|
||||
}
|
||||
|
||||
static void
|
||||
write_mime (GHashTable *hash)
|
||||
{
|
||||
struct stat s;
|
||||
gchar *dirname, *filename;
|
||||
FILE *file;
|
||||
GtkWidget *error_box;
|
||||
|
||||
dirname = g_concat_dir_and_file (gnome_util_user_home (), ".gnome/mime-info");
|
||||
if ((stat (dirname, &s) < 0) || !(S_ISDIR (s.st_mode))){
|
||||
if (errno == ENOENT) {
|
||||
if (mkdir (dirname, S_IRWXU) < 0) {
|
||||
run_error (_("We are unable to create the directory\n"
|
||||
"~/.gnome/mime-info\n\n"
|
||||
"We will not be able to save the state."));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
run_error (_("We are unable to access the directory\n"
|
||||
"~/.gnome/mime-info\n\n"
|
||||
"We will not be able to save the state."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
filename = g_concat_dir_and_file (dirname, "user.mime");
|
||||
|
||||
remove (filename);
|
||||
file = fopen (filename, "w");
|
||||
if (file == NULL) {
|
||||
run_error (_("Cannot create the file\n~/.gnome/mime-info/user.mime\n\n"
|
||||
"We will not be able to save the state"));
|
||||
return;
|
||||
}
|
||||
g_hash_table_foreach (hash, write_mime_foreach, file);
|
||||
fclose (file);
|
||||
}
|
||||
|
||||
void
|
||||
write_user_mime (void)
|
||||
{
|
||||
write_mime (user_mime_types);
|
||||
}
|
||||
|
||||
void
|
||||
write_initial_mime (void)
|
||||
{
|
||||
write_mime (initial_user_mime_types);
|
||||
}
|
||||
|
||||
void
|
||||
reread_list ()
|
||||
{
|
||||
gtk_clist_freeze (GTK_CLIST (clist));
|
||||
gtk_clist_clear (GTK_CLIST (clist));
|
||||
g_hash_table_foreach (mime_types, (GHFunc) add_mime_vals_to_clist, clist);
|
||||
gtk_clist_thaw (GTK_CLIST (clist));
|
||||
}
|
||||
static void
|
||||
clean_mime_type (gpointer mime_type, gpointer mime_info, gpointer data)
|
||||
{
|
||||
/* we should write this )-: */
|
||||
}
|
||||
void
|
||||
discard_mime_info ()
|
||||
{
|
||||
gchar *filename;
|
||||
g_hash_table_foreach (user_mime_types, clean_mime_type, NULL);
|
||||
g_hash_table_destroy (user_mime_types);
|
||||
g_hash_table_foreach (initial_user_mime_types, clean_mime_type, NULL);
|
||||
g_hash_table_destroy (initial_user_mime_types);
|
||||
user_mime_types = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
initial_user_mime_types = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
filename = g_concat_dir_and_file (gnome_util_user_home (), "/.gnome/mime-info/user.keys");
|
||||
mime_fill_from_file (filename, TRUE);
|
||||
finalize_user_mime ();
|
||||
reread_list ();
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
|
||||
/* Copyright (C) 1998 Redhat Software Inc.
|
||||
* Authors: Jonathan Blandford <jrb@redhat.com>
|
||||
*/
|
||||
#ifndef _MIME_DATA_H_
|
||||
#define _MIME_DATA_H_
|
||||
#include "gnome.h"
|
||||
#include <regex.h>
|
||||
/* Typedefs */
|
||||
typedef struct {
|
||||
char *mime_type;
|
||||
regex_t *regex[2];
|
||||
GList *ext[2];
|
||||
GList *user_ext[2];
|
||||
char *ext_readable[2];
|
||||
char *regex_readable[2];
|
||||
char *file_name;
|
||||
GList *keys;
|
||||
} MimeInfo;
|
||||
|
||||
extern GHashTable *user_mime_types;
|
||||
extern void add_to_key (char *mime_type, char *def, GHashTable *table, gboolean init_user);
|
||||
|
||||
GtkWidget *get_mime_clist (void);
|
||||
void init_mime_type (void);
|
||||
void delete_clicked (GtkWidget *widget, gpointer data);
|
||||
void add_clicked (GtkWidget *widget, gpointer data);
|
||||
void edit_clicked (GtkWidget *widget, gpointer data);
|
||||
void add_new_mime_type (gchar *mime_type, gchar *ext, gchar *regexp1, gchar *regexp2);
|
||||
void write_user_mime (void);
|
||||
void write_initial_mime (void);
|
||||
void reread_list (void);
|
||||
void discard_mime_info (void);
|
||||
#endif
|
||||
@@ -1,492 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
|
||||
/* Copyright (C) 1998 Redhat Software Inc.
|
||||
* Authors: Jonathan Blandford <jrb@redhat.com>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "capplet-widget.h"
|
||||
#include "gnome.h"
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <regex.h>
|
||||
#include <ctype.h>
|
||||
#include "mime-info.h"
|
||||
#include "mime-data.h"
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !defined getc_unlocked && !defined HAVE_GETC_UNLOCKED
|
||||
# define getc_unlocked(fp) getc (fp)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char *mime_type;
|
||||
GHashTable *keys;
|
||||
} GnomeMimeContext;
|
||||
|
||||
typedef enum {
|
||||
STATE_NONE,
|
||||
STATE_LANG,
|
||||
STATE_LOOKING_FOR_KEY,
|
||||
STATE_ON_MIME_TYPE,
|
||||
STATE_ON_KEY,
|
||||
STATE_ON_VALUE
|
||||
} ParserState;
|
||||
|
||||
static char *current_lang = NULL;
|
||||
|
||||
/*
|
||||
* A hash table containing all of the Mime records for specific
|
||||
* mime types (full description, like image/png)
|
||||
*/
|
||||
static GHashTable *specific_types;
|
||||
static GHashTable *initial_specific_types;
|
||||
|
||||
/*
|
||||
* A hash table containing all of the Mime records for non-specific
|
||||
* mime types (like image/\*)
|
||||
*/
|
||||
static GHashTable *generic_types;
|
||||
static GHashTable *initial_generic_types;
|
||||
|
||||
#define SWITCH_TO_MIME_TYPE() {
|
||||
static GnomeMimeContext *
|
||||
context_new (GString *str, gboolean is_default_context)
|
||||
{
|
||||
GnomeMimeContext *context;
|
||||
GHashTable *table;
|
||||
char *mime_type, *p;
|
||||
|
||||
mime_type = g_strdup (str->str);
|
||||
|
||||
if (is_default_context) {
|
||||
if ((p = strstr (mime_type, "/*")) == NULL){
|
||||
table = initial_specific_types;
|
||||
} else {
|
||||
*(p+1) = 0;
|
||||
table = initial_generic_types;
|
||||
}
|
||||
} else {
|
||||
if ((p = strstr (mime_type, "/*")) == NULL){
|
||||
table = specific_types;
|
||||
} else {
|
||||
*(p+1) = 0;
|
||||
table = generic_types;
|
||||
}
|
||||
}
|
||||
context = g_hash_table_lookup (table, mime_type);
|
||||
|
||||
if (context)
|
||||
return context;
|
||||
|
||||
context = g_new (GnomeMimeContext, 1);
|
||||
context->mime_type = mime_type;
|
||||
context->keys = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
g_hash_table_insert (table, context->mime_type, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
release_key_and_value (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
g_free (key);
|
||||
g_free (value);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
remove_this_key (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
if (strcmp ((gchar *)key, (gchar *)user_data) == 0){
|
||||
g_free (key);
|
||||
g_free (value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
static void
|
||||
context_add_key (GnomeMimeContext *context, char *key, char *value)
|
||||
{
|
||||
char *v;
|
||||
|
||||
v = g_hash_table_lookup (context->keys, key);
|
||||
if (v)
|
||||
g_hash_table_foreach_remove (context->keys, remove_this_key, key);
|
||||
|
||||
g_hash_table_insert (context->keys, g_strdup (key), g_strdup (value));
|
||||
}
|
||||
static void
|
||||
context_destroy (GnomeMimeContext *context)
|
||||
{
|
||||
/*
|
||||
* Remove the context from our hash tables, we dont know
|
||||
* where it is: so just remove it from both (it can
|
||||
* only be in one).
|
||||
*/
|
||||
if (context->mime_type) {
|
||||
g_hash_table_remove (specific_types, context->mime_type);
|
||||
g_hash_table_remove (generic_types, context->mime_type);
|
||||
}
|
||||
/*
|
||||
* Destroy it
|
||||
*/
|
||||
if (context->keys) {
|
||||
g_hash_table_foreach_remove (context->keys, release_key_and_value, NULL);
|
||||
g_hash_table_destroy (context->keys);
|
||||
}
|
||||
g_free (context->mime_type);
|
||||
g_free (context);
|
||||
}
|
||||
|
||||
static void
|
||||
load_mime_type_info_from (char *filename)
|
||||
{
|
||||
FILE *mime_file;
|
||||
gboolean in_comment, context_used;
|
||||
GString *line;
|
||||
int column, c;
|
||||
ParserState state;
|
||||
GnomeMimeContext *context, *default_context;
|
||||
char *key;
|
||||
|
||||
mime_file = fopen (filename, "r");
|
||||
if (mime_file == NULL)
|
||||
return;
|
||||
|
||||
in_comment = FALSE;
|
||||
context_used = FALSE;
|
||||
column = 0;
|
||||
context = NULL;
|
||||
default_context = NULL;
|
||||
key = NULL;
|
||||
line = g_string_sized_new (120);
|
||||
state = STATE_NONE;
|
||||
|
||||
while ((c = getc_unlocked (mime_file)) != EOF){
|
||||
column++;
|
||||
if (c == '\r')
|
||||
continue;
|
||||
|
||||
if (c == '#' && column == 0){
|
||||
in_comment = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '\n'){
|
||||
in_comment = FALSE;
|
||||
column = 0;
|
||||
if (state == STATE_ON_MIME_TYPE){
|
||||
context = context_new (line, FALSE);
|
||||
default_context = context_new (line, TRUE);
|
||||
context_used = FALSE;
|
||||
g_string_assign (line, "");
|
||||
state = STATE_LOOKING_FOR_KEY;
|
||||
continue;
|
||||
}
|
||||
if (state == STATE_ON_VALUE){
|
||||
context_used = TRUE;
|
||||
context_add_key (context, key, line->str);
|
||||
context_add_key (default_context, key, line->str);
|
||||
g_string_assign (line, "");
|
||||
g_free (key);
|
||||
key = NULL;
|
||||
state = STATE_LOOKING_FOR_KEY;
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_comment)
|
||||
continue;
|
||||
|
||||
switch (state){
|
||||
case STATE_NONE:
|
||||
if (c != ' ' && c != '\t')
|
||||
state = STATE_ON_MIME_TYPE;
|
||||
else
|
||||
break;
|
||||
/* fall down */
|
||||
|
||||
case STATE_ON_MIME_TYPE:
|
||||
if (c == ':'){
|
||||
in_comment = TRUE;
|
||||
break;
|
||||
}
|
||||
g_string_append_c (line, c);
|
||||
break;
|
||||
|
||||
case STATE_LOOKING_FOR_KEY:
|
||||
if (c == '\t' || c == ' ')
|
||||
break;
|
||||
|
||||
if (c == '['){
|
||||
state = STATE_LANG;
|
||||
break;
|
||||
}
|
||||
|
||||
if (column == 1){
|
||||
state = STATE_ON_MIME_TYPE;
|
||||
g_string_append_c (line, c);
|
||||
break;
|
||||
}
|
||||
state = STATE_ON_KEY;
|
||||
/* falldown */
|
||||
|
||||
case STATE_ON_KEY:
|
||||
if (c == '\\'){
|
||||
c = getc (mime_file);
|
||||
if (c == EOF)
|
||||
break;
|
||||
}
|
||||
if (c == '='){
|
||||
key = g_strdup (line->str);
|
||||
g_string_assign (line, "");
|
||||
state = STATE_ON_VALUE;
|
||||
break;
|
||||
}
|
||||
g_string_append_c (line, c);
|
||||
break;
|
||||
|
||||
case STATE_ON_VALUE:
|
||||
g_string_append_c (line, c);
|
||||
break;
|
||||
|
||||
case STATE_LANG:
|
||||
if (c == ']'){
|
||||
state = STATE_ON_KEY;
|
||||
if (current_lang && line->str [0]){
|
||||
if (strcmp (current_lang, line->str) != 0){
|
||||
in_comment = TRUE;
|
||||
state = STATE_LOOKING_FOR_KEY;
|
||||
}
|
||||
} else {
|
||||
in_comment = TRUE;
|
||||
state = STATE_LOOKING_FOR_KEY;
|
||||
}
|
||||
g_string_assign (line, "");
|
||||
break;
|
||||
}
|
||||
g_string_append_c (line, c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (context){
|
||||
if (key && line->str [0]) {
|
||||
context_add_key (context, key, line->str);
|
||||
context_add_key (default_context, key, line->str);
|
||||
} else
|
||||
if (!context_used) {
|
||||
context_destroy (context);
|
||||
context_destroy (default_context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
g_string_free (line, TRUE);
|
||||
if (key)
|
||||
g_free (key);
|
||||
|
||||
fclose (mime_file);
|
||||
}
|
||||
void
|
||||
set_mime_key_value (gchar *mime_type, gchar *key, gchar *value)
|
||||
{
|
||||
GnomeMimeContext *context;
|
||||
|
||||
/* Assume no generic context's for now. */
|
||||
context = g_hash_table_lookup (specific_types, mime_type);
|
||||
if (context == NULL) {
|
||||
GString *str = g_string_new (mime_type);
|
||||
context = context_new (str, FALSE);
|
||||
g_string_free (str, TRUE);
|
||||
}
|
||||
context_add_key (context, key, value);
|
||||
}
|
||||
void
|
||||
init_mime_info (void)
|
||||
{
|
||||
gchar *filename;
|
||||
|
||||
current_lang = getenv ("LANG");
|
||||
specific_types = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
generic_types = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
initial_specific_types = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
initial_generic_types = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
filename = g_concat_dir_and_file (gnome_util_user_home (), "/.gnome/mime-info/user.keys");
|
||||
load_mime_type_info_from (filename);
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
const char *
|
||||
local_mime_get_value (const char *mime_type, char *key)
|
||||
{
|
||||
char *value, *generic_type, *p;
|
||||
GnomeMimeContext *context;
|
||||
|
||||
g_return_val_if_fail (mime_type != NULL, NULL);
|
||||
g_return_val_if_fail (key != NULL, NULL);
|
||||
context = g_hash_table_lookup (specific_types, mime_type);
|
||||
if (context){
|
||||
value = g_hash_table_lookup (context->keys, key);
|
||||
|
||||
if (value)
|
||||
return value;
|
||||
}
|
||||
|
||||
generic_type = g_strdup (mime_type);
|
||||
p = strchr (generic_type, '/');
|
||||
if (p)
|
||||
*(p+1) = 0;
|
||||
|
||||
context = g_hash_table_lookup (generic_types, generic_type);
|
||||
g_free (generic_type);
|
||||
|
||||
if (context){
|
||||
value = g_hash_table_lookup (context->keys, key);
|
||||
if (value)
|
||||
return value;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static void
|
||||
clean_mime_foreach (gpointer mime_type, gpointer gmc, gpointer data)
|
||||
{
|
||||
context_destroy ((GnomeMimeContext *) gmc);
|
||||
}
|
||||
static void
|
||||
write_mime_keys_foreach (gpointer key_name, gpointer value, gpointer data)
|
||||
{
|
||||
gchar *buf;
|
||||
if (current_lang && strcmp (current_lang, "C"))
|
||||
buf = g_strconcat ("\t[",
|
||||
current_lang,
|
||||
"]",
|
||||
(gchar *) key_name,
|
||||
"=",
|
||||
(gchar *) value,
|
||||
"\n", NULL);
|
||||
else
|
||||
buf = g_strconcat ("\t",
|
||||
(gchar *) key_name,
|
||||
"=",
|
||||
(gchar *) value,
|
||||
"\n", NULL);
|
||||
fwrite (buf, 1, strlen (buf), (FILE *) data);
|
||||
g_free (buf);
|
||||
}
|
||||
static void
|
||||
write_mime_foreach (gpointer mime_type, gpointer gmc, gpointer data)
|
||||
{
|
||||
gchar *buf;
|
||||
GnomeMimeContext *context = (GnomeMimeContext *) gmc;
|
||||
|
||||
buf = g_strconcat ((gchar *) mime_type, ":\n", NULL);
|
||||
fwrite (buf, 1, strlen (buf), (FILE *) data);
|
||||
g_free (buf);
|
||||
g_hash_table_foreach (context->keys, write_mime_keys_foreach, data);
|
||||
fwrite ("\n", 1, strlen ("\n"), (FILE *) data);
|
||||
}
|
||||
|
||||
static void
|
||||
run_error (gchar *message)
|
||||
{
|
||||
GtkWidget *error_box;
|
||||
|
||||
error_box = gnome_message_box_new (
|
||||
message,
|
||||
GNOME_MESSAGE_BOX_ERROR,
|
||||
GNOME_STOCK_BUTTON_OK,
|
||||
NULL);
|
||||
gnome_dialog_run_and_close (GNOME_DIALOG (error_box));
|
||||
}
|
||||
static void
|
||||
write_keys (GHashTable *spec_hash, GHashTable *generic_hash)
|
||||
{
|
||||
struct stat s;
|
||||
gchar *dirname, *filename;
|
||||
FILE *file;
|
||||
GtkWidget *error_box;
|
||||
|
||||
dirname = g_concat_dir_and_file (gnome_util_user_home (), ".gnome/mime-info");
|
||||
if ((stat (dirname, &s) < 0) || !(S_ISDIR (s.st_mode))){
|
||||
if (errno == ENOENT) {
|
||||
if (mkdir (dirname, S_IRWXU) < 0) {
|
||||
run_error (_("We are unable to create the directory\n"
|
||||
"~/.gnome/mime-info.\n\n"
|
||||
"We will not be able to save the state."));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
run_error (_("We are unable to access the directory\n"
|
||||
"~/.gnome/mime-info.\n\n"
|
||||
"We will not be able to save the state."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
filename = g_concat_dir_and_file (dirname, "user.keys");
|
||||
|
||||
remove (filename);
|
||||
file = fopen (filename, "w");
|
||||
if (file == NULL) {
|
||||
run_error (_("Cannot create the file\n~/.gnome/mime-info/user.keys.\n\n"
|
||||
"We will not be able to save the state"));
|
||||
return;
|
||||
}
|
||||
g_hash_table_foreach (spec_hash, write_mime_foreach, file);
|
||||
g_hash_table_foreach (generic_hash, write_mime_foreach, file);
|
||||
fclose (file);
|
||||
}
|
||||
void
|
||||
write_initial_keys (void)
|
||||
{
|
||||
write_keys (initial_generic_types, initial_specific_types);
|
||||
}
|
||||
void
|
||||
write_user_keys (void)
|
||||
{
|
||||
write_keys (generic_types, specific_types);
|
||||
}
|
||||
static void
|
||||
print_mime_foreach (gpointer mime_info, gpointer mi, gpointer data)
|
||||
{
|
||||
g_print ("mime_info:%s:\n", (char *)mime_info);
|
||||
g_print ("\t:%s:\n", ((MimeInfo *)mi)->mime_type);
|
||||
}
|
||||
void
|
||||
discard_key_info (void)
|
||||
{
|
||||
gchar *filename;
|
||||
|
||||
current_lang = getenv ("LANG");
|
||||
g_hash_table_foreach (generic_types, clean_mime_foreach, NULL);
|
||||
/* g_hash_table_foreach (specific_types, print_mime_foreach, NULL); */
|
||||
g_hash_table_foreach (specific_types, clean_mime_foreach, NULL);
|
||||
g_hash_table_destroy (generic_types);
|
||||
g_hash_table_destroy (specific_types);
|
||||
specific_types = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
generic_types = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
filename = g_concat_dir_and_file (gnome_util_user_home (), "/.gnome/mime-info/user.keys");
|
||||
load_mime_type_info_from (filename);
|
||||
reread_list ();
|
||||
g_free (filename);
|
||||
}
|
||||
void
|
||||
remove_mime_info (gchar *mime_type)
|
||||
{
|
||||
g_hash_table_remove (generic_types, mime_type);
|
||||
g_hash_table_remove (specific_types, mime_type);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
|
||||
/* Copyright (C) 1998 Redhat Software Inc.
|
||||
* Authors: Jonathan Blandford <jrb@redhat.com>
|
||||
*/
|
||||
#ifndef _MIME_INFO_H_
|
||||
#define _MIME_INFO_H_
|
||||
#include "gnome.h"
|
||||
#include <regex.h>
|
||||
/* Typedefs */
|
||||
void init_mime_info (void);
|
||||
void discard_key_info (void);
|
||||
void set_mime_key_value (gchar *mime_type, gchar *key, gchar *value);
|
||||
const char * local_mime_get_value (const char *mime_type, char *key);
|
||||
void write_user_keys (void);
|
||||
void write_initial_keys (void);
|
||||
void remove_mime_info (gchar *mime_type);
|
||||
#endif
|
||||
@@ -1,142 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
|
||||
/* Copyright (C) 1998 Redhat Software Inc.
|
||||
* Authors: Jonathan Blandford <jrb@redhat.com>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "capplet-widget.h"
|
||||
#include "gnome.h"
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <regex.h>
|
||||
#include <ctype.h>
|
||||
#include "mime-data.h"
|
||||
#include "mime-info.h"
|
||||
#include "edit-window.h"
|
||||
/* Prototypes */
|
||||
static void try_callback ();
|
||||
static void revert_callback ();
|
||||
static void ok_callback ();
|
||||
static void cancel_callback ();
|
||||
static void help_callback ();
|
||||
GtkWidget *capplet = NULL;
|
||||
GtkWidget *delete_button = NULL;
|
||||
|
||||
static GtkWidget *
|
||||
left_aligned_button (gchar *label)
|
||||
{
|
||||
GtkWidget *button = gtk_button_new_with_label (label);
|
||||
gtk_misc_set_alignment (GTK_MISC (GTK_BIN (button)->child),
|
||||
0.0, 0.5);
|
||||
gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child),
|
||||
GNOME_PAD_SMALL, 0);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
static void
|
||||
try_callback ()
|
||||
{
|
||||
write_user_keys ();
|
||||
write_user_mime ();
|
||||
}
|
||||
static void
|
||||
revert_callback ()
|
||||
{
|
||||
write_initial_keys ();
|
||||
write_initial_mime ();
|
||||
discard_key_info ();
|
||||
discard_mime_info ();
|
||||
initialize_main_win_vals ();
|
||||
}
|
||||
static void
|
||||
ok_callback ()
|
||||
{
|
||||
write_user_keys ();
|
||||
write_user_mime ();
|
||||
}
|
||||
static void
|
||||
cancel_callback ()
|
||||
{
|
||||
write_initial_keys ();
|
||||
write_initial_mime ();
|
||||
}
|
||||
|
||||
static void
|
||||
help_callback ()
|
||||
{
|
||||
/* Sigh... empty as always */
|
||||
}
|
||||
|
||||
static void
|
||||
init_mime_capplet ()
|
||||
{
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *button;
|
||||
|
||||
capplet = capplet_widget_new ();
|
||||
delete_button = left_aligned_button (_("Delete"));
|
||||
gtk_signal_connect (GTK_OBJECT (delete_button), "clicked",
|
||||
delete_clicked, NULL);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, GNOME_PAD);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (hbox), GNOME_PAD_SMALL);
|
||||
gtk_container_add (GTK_CONTAINER (capplet), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), get_mime_clist (), TRUE, TRUE, 0);
|
||||
vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
|
||||
button = left_aligned_button (_("Add..."));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||
gtk_signal_connect (GTK_OBJECT (button), "clicked",
|
||||
add_clicked, NULL);
|
||||
button = left_aligned_button (_("Edit..."));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||
gtk_signal_connect (GTK_OBJECT (button), "clicked",
|
||||
edit_clicked, NULL);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), delete_button, FALSE, FALSE, 0);
|
||||
gtk_widget_show_all (capplet);
|
||||
gtk_signal_connect(GTK_OBJECT(capplet), "try",
|
||||
GTK_SIGNAL_FUNC(try_callback), NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(capplet), "revert",
|
||||
GTK_SIGNAL_FUNC(revert_callback), NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(capplet), "ok",
|
||||
GTK_SIGNAL_FUNC(ok_callback), NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(capplet), "cancel",
|
||||
GTK_SIGNAL_FUNC(cancel_callback), NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(capplet), "page_hidden",
|
||||
GTK_SIGNAL_FUNC(hide_edit_window), NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(capplet), "page_shown",
|
||||
GTK_SIGNAL_FUNC(show_edit_window), NULL);
|
||||
#if 0
|
||||
gtk_signal_connect(GTK_OBJECT(capplet), "help",
|
||||
GTK_SIGNAL_FUNC(help_callback), NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int init_results;
|
||||
|
||||
bindtextdomain (PACKAGE, GNOMELOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
init_results = gnome_capplet_init("mime-type-capplet", VERSION,
|
||||
argc, argv, NULL, 0, NULL);
|
||||
|
||||
if (init_results < 0) {
|
||||
exit (0);
|
||||
}
|
||||
|
||||
if (init_results == 0) {
|
||||
init_mime_type ();
|
||||
init_mime_capplet ();
|
||||
capplet_gtk_main ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user