diff options
-rwxr-xr-x | configure | 306 | ||||
-rw-r--r-- | configure.ac | 10 | ||||
-rw-r--r-- | data/Makefile.am | 4 | ||||
-rw-r--r-- | data/Makefile.in | 13 | ||||
-rw-r--r-- | data/org.ayatana.indicator.datetime.gschema.xml | 61 | ||||
-rw-r--r-- | debian/changelog | 19 | ||||
-rw-r--r-- | debian/control | 3 | ||||
-rwxr-xr-x | debian/rules | 1 | ||||
-rw-r--r-- | src/indicator-datetime.c | 642 |
9 files changed, 1004 insertions, 55 deletions
@@ -764,6 +764,10 @@ GETTEXT_PACKAGE DBUSSERVICEDIR INDICATORICONSDIR INDICATORDIR +GSETTINGS_RULES +GLIB_COMPILE_SCHEMAS +gsettingsschemadir +GSETTINGS_DISABLE_SCHEMAS_COMPILE INDICATOR_LIBS INDICATOR_CFLAGS PKG_CONFIG @@ -922,6 +926,7 @@ enable_fast_install with_gnu_ld enable_libtool_lock enable_silent_rules +enable_schemas_compile enable_localinstall ' ac_precious_vars='build_alias @@ -1568,6 +1573,8 @@ Optional Features: --disable-libtool-lock avoid locking (might break parallel builds) --enable-silent-rules less verbose build output (undo: `make V=1') --disable-silent-rules verbose build output (undo: `make V=0') + --disable-schemas-compile + Disable regeneration of gschemas.compiled on install --enable-localinstall install all of the files localy instead of system directories (for distcheck) @@ -6261,13 +6268,13 @@ if test "${lt_cv_nm_interface+set}" = set; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:6264: $ac_compile\"" >&5) + (eval echo "\"\$as_me:6271: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:6267: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:6274: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:6270: output\"" >&5) + (eval echo "\"\$as_me:6277: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -7472,7 +7479,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 7475 "configure"' > conftest.$ac_ext + echo '#line 7482 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -8718,11 +8725,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8721: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8728: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:8725: \$? = $ac_status" >&5 + echo "$as_me:8732: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -9057,11 +9064,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9060: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9067: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:9064: \$? = $ac_status" >&5 + echo "$as_me:9071: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -9162,11 +9169,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9165: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9172: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:9169: \$? = $ac_status" >&5 + echo "$as_me:9176: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9217,11 +9224,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9220: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9227: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:9224: \$? = $ac_status" >&5 + echo "$as_me:9231: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -11601,7 +11608,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11604 "configure" +#line 11611 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11697,7 +11704,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11700 "configure" +#line 11707 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12146,6 +12153,7 @@ fi INDICATOR_REQUIRED_VERSION=0.3.0 DBUSMENUGLIB_REQUIRED_VERSION=0.1.1 DBUSMENUGTK_REQUIRED_VERSION=0.1.1 +GIO_REQUIRED_VERSION=2.25.0 pkg_failed=no @@ -12159,16 +12167,19 @@ if test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"indicator >= \$INDICATOR_REQUIRED_VERSION dbusmenu-glib >= \$DBUSMENUGLIB_REQUIRED_VERSION - dbusmenu-gtk >= \$DBUSMENUGTK_REQUIRED_VERSION\""; } >&5 + dbusmenu-gtk >= \$DBUSMENUGTK_REQUIRED_VERSION + gio-2.0 >= \$GIO_REQUIRED_VERSION\""; } >&5 ($PKG_CONFIG --exists --print-errors "indicator >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION - dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION") 2>&5 + dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION + gio-2.0 >= $GIO_REQUIRED_VERSION") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_INDICATOR_CFLAGS=`$PKG_CONFIG --cflags "indicator >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION - dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION" 2>/dev/null` + dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION + gio-2.0 >= $GIO_REQUIRED_VERSION" 2>/dev/null` else pkg_failed=yes fi @@ -12183,16 +12194,19 @@ if test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"indicator >= \$INDICATOR_REQUIRED_VERSION dbusmenu-glib >= \$DBUSMENUGLIB_REQUIRED_VERSION - dbusmenu-gtk >= \$DBUSMENUGTK_REQUIRED_VERSION\""; } >&5 + dbusmenu-gtk >= \$DBUSMENUGTK_REQUIRED_VERSION + gio-2.0 >= \$GIO_REQUIRED_VERSION\""; } >&5 ($PKG_CONFIG --exists --print-errors "indicator >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION - dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION") 2>&5 + dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION + gio-2.0 >= $GIO_REQUIRED_VERSION") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_INDICATOR_LIBS=`$PKG_CONFIG --libs "indicator >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION - dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION" 2>/dev/null` + dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION + gio-2.0 >= $GIO_REQUIRED_VERSION" 2>/dev/null` else pkg_failed=yes fi @@ -12213,18 +12227,21 @@ fi if test $_pkg_short_errors_supported = yes; then INDICATOR_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "indicator >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION - dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION"` + dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION + gio-2.0 >= $GIO_REQUIRED_VERSION"` else INDICATOR_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "indicator >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION - dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION"` + dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION + gio-2.0 >= $GIO_REQUIRED_VERSION"` fi # Put the nasty error message in config.log where it belongs echo "$INDICATOR_PKG_ERRORS" >&5 as_fn_error "Package requirements (indicator >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION - dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION) were not met: + dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION + gio-2.0 >= $GIO_REQUIRED_VERSION) were not met: $INDICATOR_PKG_ERRORS @@ -12260,6 +12277,249 @@ fi ########################### +# Grab the GSettings Macros +########################### + + + + # Check whether --enable-schemas-compile was given. +if test "${enable_schemas_compile+set}" = set; then : + enableval=$enable_schemas_compile; case ${enableval} in + yes) GSETTINGS_DISABLE_SCHEMAS_COMPILE="" ;; + no) GSETTINGS_DISABLE_SCHEMAS_COMPILE="1" ;; + *) as_fn_error "bad value ${enableval} for --enable-schemas-compile" "$LINENO" 5 ;; + esac +fi + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.16 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi + +fi + gsettingsschemadir=${datadir}/glib-2.0/schemas + + if test x$cross_compiling != xyes; then + GLIB_COMPILE_SCHEMAS=`$PKG_CONFIG --variable glib_compile_schemas gio-2.0` + else + # Extract the first word of "glib-compile-schemas", so it can be a program name with args. +set dummy glib-compile-schemas; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_GLIB_COMPILE_SCHEMAS+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $GLIB_COMPILE_SCHEMAS in + [\\/]* | ?:[\\/]*) + ac_cv_path_GLIB_COMPILE_SCHEMAS="$GLIB_COMPILE_SCHEMAS" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_GLIB_COMPILE_SCHEMAS="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +GLIB_COMPILE_SCHEMAS=$ac_cv_path_GLIB_COMPILE_SCHEMAS +if test -n "$GLIB_COMPILE_SCHEMAS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GLIB_COMPILE_SCHEMAS" >&5 +$as_echo "$GLIB_COMPILE_SCHEMAS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi + + if test "x$GLIB_COMPILE_SCHEMAS" = "x"; then + as_fn_error "glib-compile-schemas not found." "$LINENO" 5 + else + : + fi + + GSETTINGS_RULES=' +.PHONY : uninstall-gsettings-schemas install-gsettings-schemas clean-gsettings-schemas + +mostlyclean-am: clean-gsettings-schemas + +gsettings__enum_file = $(addsuffix .enums.xml,$(gsettings_ENUM_NAMESPACE)) + +%.gschema.valid: %.gschema.xml $(gsettings__enum_file) + $(AM_V_GEN) if test -f "$<"; then d=; else d="$(srcdir)/"; fi; $(GLIB_COMPILE_SCHEMAS) --dry-run $(addprefix --schema-file=,$(gsettings__enum_file)) --schema-file=$${d}$< && touch $@ + +all-am: $(gsettings_SCHEMAS:.xml=.valid) +uninstall-am: uninstall-gsettings-schemas +install-data-am: install-gsettings-schemas + +.SECONDARY: $(gsettings_SCHEMAS) + +gsettings__base_list = \ + sed "$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g" | \ + sed "$$!N;$$!N;$$!N;$$!N;s/\n/ /g" + +install-gsettings-schemas: $(gsettings_SCHEMAS:.xml=.valid) $(gsettings__enum_file) + @$(NORMAL_INSTALL) + test -z "$(gsettingsschemadir)" || $(MKDIR_P) "$(DESTDIR)$(gsettingsschemadir)" + @list='\''$(gsettings__enum_file) $(gsettings_SCHEMAS)'\''; test -n "$(gsettingsschemadir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(gsettings__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '\''$(DESTDIR)$(gsettingsschemadir)'\''"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(gsettingsschemadir)" || exit $$?; \ + done + test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir) + +uninstall-gsettings-schemas: + @$(NORMAL_UNINSTALL) + @list='\''$(gsettings_SCHEMAS) $(gsettings__enum_file)'\''; test -n "$(gsettingsschemadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e '\''s|^.*/||'\''`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '\''$(DESTDIR)$(gsettingsschemadir)'\'' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(gsettingsschemadir)" && rm -f $$files + test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir) + +clean-gsettings-schemas: + rm -f $(gsettings_SCHEMAS:.xml=.valid) $(gsettings__enum_file) + +ifdef gsettings_ENUM_NAMESPACE +$(gsettings__enum_file): $(gsettings_ENUM_FILES) + $(AM_V_GEN) glib-mkenums --comments '\''<!-- @comment@ -->'\'' --fhead "<schemalist>" --vhead " <@type@ id='\''$(gsettings_ENUM_NAMESPACE).@EnumName@'\''>" --vprod " <value nick='\''@valuenick@'\'' value='\''@valuenum@'\''/>" --vtail " </@type@>" --ftail "</schemalist>" $(gsettings_ENUM_FILES) > $@.tmp && mv $@.tmp $@ +endif +' + + + + + + + +########################### # Check to see if we're local ########################### diff --git a/configure.ac b/configure.ac index fdc85c2..f8997bf 100644 --- a/configure.ac +++ b/configure.ac @@ -35,15 +35,23 @@ PKG_PROG_PKG_CONFIG INDICATOR_REQUIRED_VERSION=0.3.0 DBUSMENUGLIB_REQUIRED_VERSION=0.1.1 DBUSMENUGTK_REQUIRED_VERSION=0.1.1 +GIO_REQUIRED_VERSION=2.25.0 PKG_CHECK_MODULES(INDICATOR, indicator >= $INDICATOR_REQUIRED_VERSION dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION - dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION) + dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION + gio-2.0 >= $GIO_REQUIRED_VERSION) AC_SUBST(INDICATOR_CFLAGS) AC_SUBST(INDICATOR_LIBS) ########################### +# Grab the GSettings Macros +########################### + +GLIB_GSETTINGS + +########################### # Check to see if we're local ########################### diff --git a/data/Makefile.am b/data/Makefile.am index b19cee4..2e6900c 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -1,5 +1,9 @@ #SUBDIRS = icons +gsettings_SCHEMAS = \ + org.ayatana.indicator.datetime.gschema.xml +@GSETTINGS_RULES@ + dbus_servicesdir = $(DBUSSERVICEDIR) dbus_services_DATA = indicator-datetime.service diff --git a/data/Makefile.in b/data/Makefile.in index dfd7b2e..8144a86 100644 --- a/data/Makefile.in +++ b/data/Makefile.in @@ -39,7 +39,11 @@ host_triplet = @host@ subdir = data DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/gsettings.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs @@ -108,12 +112,14 @@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_MKENUMS = @GLIB_MKENUMS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GNOMELOCALEDIR = @GNOMELOCALEDIR@ GREP = @GREP@ +GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@ INDICATORDIR = @INDICATORDIR@ INDICATORICONSDIR = @INDICATORICONSDIR@ INDICATOR_CFLAGS = @INDICATOR_CFLAGS@ @@ -194,6 +200,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ +gsettingsschemadir = @gsettingsschemadir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -223,6 +230,9 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ +gsettings_SCHEMAS = \ + org.ayatana.indicator.datetime.gschema.xml + dbus_servicesdir = $(DBUSSERVICEDIR) dbus_services_DATA = indicator-datetime.service EXTRA_DIST = indicator-datetime.service.in @@ -436,6 +446,7 @@ uninstall-am: uninstall-dbus_servicesDATA mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am uninstall uninstall-am uninstall-dbus_servicesDATA +@GSETTINGS_RULES@ %.service: %.service.in sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ diff --git a/data/org.ayatana.indicator.datetime.gschema.xml b/data/org.ayatana.indicator.datetime.gschema.xml new file mode 100644 index 0000000..c794d83 --- /dev/null +++ b/data/org.ayatana.indicator.datetime.gschema.xml @@ -0,0 +1,61 @@ +<schemalist> + <enum id="time-enum"> + <value nick="locale-default" value="0" /> + <value nick="12-hour" value="1" /> + <value nick="24-hour" value="2" /> + <value nick="custom" value="3" /> + </enum> + <schema id="org.ayatana.indicator.datetime" path="/apps/indicators/datetime/" gettext-domain="indicator-datetime"> + <key name="time-format" enum="time-enum"> + <default>'locale-default'</default> + <summary>What the time format should be</summary> + <description> + Controls the time format that is displayed in the indicator. For almost + all users this should be the default for their locale. If you think the + setting is wrong for your locale please join or talk to the translation + team for your langauge. If you just want something different you can + adjust this to be either 12 or 24 time. Or, you can use a custom format + string and set the custom-time-format setting. + </description> + </key> + <key name="show-seconds" type="b"> + <default>false</default> + <summary>Show the number of seconds in the indicator</summary> + <description> + Makes the datetime indicator show the number of seconds in the indicator. + It's important to note that this will cause additional battery drain as + the time will update 60 times as often, so it is not recommended. Also, + this setting will be ignored if the time-format value is set to custom. + </description> + </key> + <key name="show-day" type="b"> + <default>false</default> + <summary>Show the day of the week in the indicator</summary> + <description> + Puts the day of the week on the panel along with the time and/or date + depending on settings. This setting will be ignored if the time-format + value is set to custom. + </description> + </key> + <key name="show-date" type="b"> + <default>false</default> + <summary>Show the month and date in the indicator</summary> + <description> + Puts the month and the date in the panel along with the time and/or day + of the week depending on settings. This setting will be ignored if the + time-format value is set to custom. + </description> + </key> + <key name="custom-time-format" type="s"> + <default>"%l:%M %p"</default> + <summary>The format string passed to strftime</summary> + <description> + The format of the time and/or date that is visible on the panel when using + the indicator. For most users this will be a set of predefined values as + determined by the configuration utility, but advanced users can change it + to anything strftime can accept. Look at the man page on strftime for + more information. + </description> + </key> + </schema> +</schemalist> diff --git a/debian/changelog b/debian/changelog index 153cc61..92c3ced 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,22 @@ +indicator-datetime (0.0.5-0ubuntu2) maverick; urgency=low + + * debian/rules: use gnome.mk so a translation template is built (lp: #612540) + + -- Sebastien Bacher <seb128@ubuntu.com> Tue, 03 Aug 2010 12:41:08 +0200 + +indicator-datetime (0.0.5-0ubuntu1) maverick; urgency=low + + * New version update + + [ Ted Gould ] + * Upstream Merge + * Making time format configurable via translations and + gsettings. + * debian/control: Adding in a glib dependency to get gsettings + * Autogen update + + -- Sebastien Bacher <seb128@ubuntu.com> Thu, 22 Jul 2010 21:41:12 +0200 + indicator-datetime (0.0.4-0ubuntu1) maverick; urgency=low * New upstream release. diff --git a/debian/control b/debian/control index 40c540b..7ef65bc 100644 --- a/debian/control +++ b/debian/control @@ -7,7 +7,8 @@ Build-Depends: cdbs, intltool (>= 0.35.0), libindicator-dev (>= 0.3.0), libdbusmenu-glib-dev (>= 0.1.1), - libdbusmenu-gtk-dev (>= 0.1.1) + libdbusmenu-gtk-dev (>= 0.1.1), + libglib2.0-dev (>= 2.25.0) Standards-Version: 3.8.4 Homepage: https://launchpad.net/indicator-datetime diff --git a/debian/rules b/debian/rules index 87f7f7e..ff2614a 100755 --- a/debian/rules +++ b/debian/rules @@ -3,6 +3,7 @@ include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/rules/simple-patchsys.mk include /usr/share/cdbs/1/class/autotools.mk +include /usr/share/cdbs/1/class/gnome.mk include /usr/share/cdbs/1/rules/utils.mk install/indicator-datetime:: diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c index 6b32f1a..7034fb8 100644 --- a/src/indicator-datetime.c +++ b/src/indicator-datetime.c @@ -27,6 +27,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <glib.h> #include <glib-object.h> #include <glib/gi18n-lib.h> +#include <gio/gio.h> /* Indicator Stuff */ #include <libindicator/indicator.h> @@ -63,13 +64,58 @@ struct _IndicatorDatetimePrivate { GtkLabel * label; guint timer; + gchar * time_string; + + gint time_mode; + gboolean show_seconds; + gboolean show_date; + gboolean show_day; + gchar * custom_string; + guint idle_measure; gint max_width; IndicatorServiceManager * sm; DbusmenuGtkMenu * menu; + + GSettings * settings; +}; + +/* Enum for the properties so that they can be quickly + found and looked up. */ +enum { + PROP_0, + PROP_TIME_FORMAT, + PROP_SHOW_SECONDS, + PROP_SHOW_DAY, + PROP_SHOW_DATE, + PROP_CUSTOM_TIME_FORMAT }; +#define PROP_TIME_FORMAT_S "time-format" +#define PROP_SHOW_SECONDS_S "show-seconds" +#define PROP_SHOW_DAY_S "show-day" +#define PROP_SHOW_DATE_S "show-date" +#define PROP_CUSTOM_TIME_FORMAT_S "custom-time-format" + +#define SETTINGS_INTERFACE "org.ayatana.indicator.datetime" +#define SETTINGS_TIME_FORMAT_S "time-format" +#define SETTINGS_SHOW_SECONDS_S "show-seconds" +#define SETTINGS_SHOW_DAY_S "show-day" +#define SETTINGS_SHOW_DATE_S "show-date" +#define SETTINGS_CUSTOM_TIME_FORMAT_S "custom-time-format" + +enum { + SETTINGS_TIME_LOCALE = 0, + SETTINGS_TIME_12_HOUR = 1, + SETTINGS_TIME_24_HOUR = 2, + SETTINGS_TIME_CUSTOM = 3 +}; + +#define DEFAULT_TIME_12_FORMAT "%l:%M %p" +#define DEFAULT_TIME_24_FORMAT "%H:%M" +#define DEFAULT_TIME_FORMAT DEFAULT_TIME_12_FORMAT + #define INDICATOR_DATETIME_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_DATETIME_TYPE, IndicatorDatetimePrivate)) @@ -77,10 +123,18 @@ GType indicator_datetime_get_type (void); static void indicator_datetime_class_init (IndicatorDatetimeClass *klass); static void indicator_datetime_init (IndicatorDatetime *self); +static void set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); +static void get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static void indicator_datetime_dispose (GObject *object); static void indicator_datetime_finalize (GObject *object); static GtkLabel * get_label (IndicatorObject * io); static GtkMenu * get_menu (IndicatorObject * io); +static GVariant * bind_enum_set (const GValue * value, const GVariantType * type, gpointer user_data); +static gboolean bind_enum_get (GValue * value, GVariant * variant, gpointer user_data); +static gchar * generate_format_string (IndicatorDatetime * self); +static struct tm * update_label (IndicatorDatetime * io); +static void guess_label_size (IndicatorDatetime * self); +static void setup_timer (IndicatorDatetime * self, struct tm * ltime); /* Indicator Module Config */ INDICATOR_SET_VERSION @@ -98,11 +152,52 @@ indicator_datetime_class_init (IndicatorDatetimeClass *klass) object_class->dispose = indicator_datetime_dispose; object_class->finalize = indicator_datetime_finalize; + object_class->set_property = set_property; + object_class->get_property = get_property; + IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass); io_class->get_label = get_label; io_class->get_menu = get_menu; + g_object_class_install_property (object_class, + PROP_TIME_FORMAT, + g_param_spec_int(PROP_TIME_FORMAT_S, + "A choice of which format should be used on the panel", + "Chooses between letting the locale choose the time, 12-hour time, 24-time or using the custom string passed to strftime().", + SETTINGS_TIME_LOCALE, /* min */ + SETTINGS_TIME_CUSTOM, /* max */ + SETTINGS_TIME_LOCALE, /* default */ + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_SHOW_SECONDS, + g_param_spec_boolean(PROP_SHOW_SECONDS_S, + "Whether to show seconds in the indicator.", + "Shows seconds along with the time in the indicator. Also effects refresh interval.", + FALSE, /* default */ + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_SHOW_DAY, + g_param_spec_boolean(PROP_SHOW_DAY_S, + "Whether to show the day of the week in the indicator.", + "Shows the day of the week along with the time in the indicator.", + FALSE, /* default */ + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_SHOW_DATE, + g_param_spec_boolean(PROP_SHOW_DATE_S, + "Whether to show the day and month in the indicator.", + "Shows the day and month along with the time in the indicator.", + FALSE, /* default */ + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_CUSTOM_TIME_FORMAT, + g_param_spec_string(PROP_CUSTOM_TIME_FORMAT_S, + "The format that is used to show the time on the panel.", + "A format string in the form used to pass to strftime to make a string for displaying on the panel.", + DEFAULT_TIME_FORMAT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return; } @@ -117,9 +212,51 @@ indicator_datetime_init (IndicatorDatetime *self) self->priv->idle_measure = 0; self->priv->max_width = 0; + self->priv->time_string = g_strdup(DEFAULT_TIME_FORMAT); + + self->priv->time_mode = SETTINGS_TIME_LOCALE; + self->priv->show_seconds = FALSE; + self->priv->show_date = FALSE; + self->priv->show_day = FALSE; + self->priv->custom_string = g_strdup(DEFAULT_TIME_FORMAT); + self->priv->sm = NULL; self->priv->menu = NULL; + self->priv->settings = g_settings_new(SETTINGS_INTERFACE); + if (self->priv->settings != NULL) { + g_settings_bind_with_mapping(self->priv->settings, + SETTINGS_TIME_FORMAT_S, + self, + PROP_TIME_FORMAT_S, + G_SETTINGS_BIND_DEFAULT, + bind_enum_get, + bind_enum_set, + NULL, NULL); /* Userdata and destroy func */ + g_settings_bind(self->priv->settings, + SETTINGS_SHOW_SECONDS_S, + self, + PROP_SHOW_SECONDS_S, + G_SETTINGS_BIND_DEFAULT); + g_settings_bind(self->priv->settings, + SETTINGS_SHOW_DAY_S, + self, + PROP_SHOW_DAY_S, + G_SETTINGS_BIND_DEFAULT); + g_settings_bind(self->priv->settings, + SETTINGS_SHOW_DATE_S, + self, + PROP_SHOW_DATE_S, + G_SETTINGS_BIND_DEFAULT); + g_settings_bind(self->priv->settings, + SETTINGS_CUSTOM_TIME_FORMAT_S, + self, + PROP_CUSTOM_TIME_FORMAT_S, + G_SETTINGS_BIND_DEFAULT); + } else { + g_warning("Unable to get settings for '" SETTINGS_INTERFACE "'"); + } + self->priv->sm = indicator_service_manager_new_version(SERVICE_NAME, SERVICE_VERSION); return; @@ -155,6 +292,11 @@ indicator_datetime_dispose (GObject *object) self->priv->sm = NULL; } + if (self->priv->settings != NULL) { + g_object_unref(G_OBJECT(self->priv->settings)); + self->priv->settings = NULL; + } + G_OBJECT_CLASS (indicator_datetime_parent_class)->dispose (object); return; } @@ -162,11 +304,181 @@ indicator_datetime_dispose (GObject *object) static void indicator_datetime_finalize (GObject *object) { + IndicatorDatetime * self = INDICATOR_DATETIME(object); + + if (self->priv->time_string != NULL) { + g_free(self->priv->time_string); + self->priv->time_string = NULL; + } + + if (self->priv->custom_string != NULL) { + g_free(self->priv->custom_string); + self->priv->custom_string = NULL; + } G_OBJECT_CLASS (indicator_datetime_parent_class)->finalize (object); return; } +/* Turns the int value into a string GVariant */ +static GVariant * +bind_enum_set (const GValue * value, const GVariantType * type, gpointer user_data) +{ + switch (g_value_get_int(value)) { + case SETTINGS_TIME_LOCALE: + return g_variant_new_string("locale-default"); + case SETTINGS_TIME_12_HOUR: + return g_variant_new_string("12-hour"); + case SETTINGS_TIME_24_HOUR: + return g_variant_new_string("24-hour"); + case SETTINGS_TIME_CUSTOM: + return g_variant_new_string("custom"); + default: + return NULL; + } +} + +/* Turns a string GVariant into an int value */ +static gboolean +bind_enum_get (GValue * value, GVariant * variant, gpointer user_data) +{ + const gchar * str = g_variant_get_string(variant, NULL); + gint output = 0; + + if (g_strcmp0(str, "locale-default") == 0) { + output = SETTINGS_TIME_LOCALE; + } else if (g_strcmp0(str, "12-hour") == 0) { + output = SETTINGS_TIME_12_HOUR; + } else if (g_strcmp0(str, "24-hour") == 0) { + output = SETTINGS_TIME_24_HOUR; + } else if (g_strcmp0(str, "custom") == 0) { + output = SETTINGS_TIME_CUSTOM; + } else { + return FALSE; + } + + g_value_set_int(value, output); + return TRUE; +} + +/* Sets a property on the object */ +static void +set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) +{ + IndicatorDatetime * self = INDICATOR_DATETIME(object); + gboolean update = FALSE; + + switch(prop_id) { + case PROP_TIME_FORMAT: { + gint newval = g_value_get_int(value); + if (newval != self->priv->time_mode) { + update = TRUE; + self->priv->time_mode = newval; + } + break; + } + case PROP_SHOW_SECONDS: + if (g_value_get_boolean(value) != self->priv->show_seconds) { + self->priv->show_seconds = !self->priv->show_seconds; + if (self->priv->time_mode != SETTINGS_TIME_CUSTOM) { + update = TRUE; + setup_timer(self, NULL); + } + } + break; + case PROP_SHOW_DAY: + if (g_value_get_boolean(value) != self->priv->show_day) { + self->priv->show_day = !self->priv->show_day; + if (self->priv->time_mode != SETTINGS_TIME_CUSTOM) { + update = TRUE; + } + } + break; + case PROP_SHOW_DATE: + if (g_value_get_boolean(value) != self->priv->show_date) { + self->priv->show_date = !self->priv->show_date; + if (self->priv->time_mode != SETTINGS_TIME_CUSTOM) { + update = TRUE; + } + } + break; + case PROP_CUSTOM_TIME_FORMAT: { + const gchar * newstr = g_value_get_string(value); + if (g_strcmp0(newstr, self->priv->custom_string) != 0) { + if (self->priv->custom_string != NULL) { + g_free(self->priv->custom_string); + self->priv->custom_string = NULL; + } + self->priv->custom_string = g_strdup(newstr); + if (self->priv->time_mode == SETTINGS_TIME_CUSTOM) { + update = TRUE; + setup_timer(self, NULL); + } + } + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + return; + } + + if (!update) { + return; + } + + /* Get the new format string */ + gchar * newformat = generate_format_string(self); + + /* check to ensure the format really changed */ + if (g_strcmp0(self->priv->time_string, newformat) == 0) { + g_free(newformat); + return; + } + + /* Okay now process the change */ + if (self->priv->time_string != NULL) { + g_free(self->priv->time_string); + self->priv->time_string = NULL; + } + self->priv->time_string = newformat; + + /* And update everything */ + update_label(self); + guess_label_size(self); + + return; +} + +/* Gets a property from the object */ +static void +get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) +{ + IndicatorDatetime * self = INDICATOR_DATETIME(object); + + switch(prop_id) { + case PROP_TIME_FORMAT: + g_value_set_int(value, self->priv->time_mode); + break; + case PROP_SHOW_SECONDS: + g_value_set_boolean(value, self->priv->show_seconds); + break; + case PROP_SHOW_DAY: + g_value_set_boolean(value, self->priv->show_day); + break; + case PROP_SHOW_DATE: + g_value_set_boolean(value, self->priv->show_date); + break; + case PROP_CUSTOM_TIME_FORMAT: + g_value_set_string(value, self->priv->custom_string); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + return; + } + + return; +} + /* Looks at the size of the label, if it grew beyond what we thought was the max, make sure it doesn't shrink again. */ static gboolean @@ -190,12 +502,12 @@ idle_measure (gpointer data) } /* Updates the label to be the current time. */ -static void +static struct tm * update_label (IndicatorDatetime * io) { IndicatorDatetime * self = INDICATOR_DATETIME(io); - if (self->priv->label == NULL) return; + if (self->priv->label == NULL) return NULL; gchar longstr[128]; time_t t; @@ -206,10 +518,10 @@ update_label (IndicatorDatetime * io) if (ltime == NULL) { g_debug("Error getting local time"); gtk_label_set_label(self->priv->label, _("Error getting time")); - return; + return NULL; } - strftime(longstr, 128, "%l:%M %p", ltime); + strftime(longstr, 128, self->priv->time_string, ltime); gchar * utf8 = g_locale_to_utf8(longstr, -1, NULL, NULL, NULL); gtk_label_set_label(self->priv->label, utf8); @@ -219,24 +531,43 @@ update_label (IndicatorDatetime * io) self->priv->idle_measure = g_idle_add(idle_measure, io); } - return; + return ltime; } /* Runs every minute and updates the time */ gboolean -minute_timer_func (gpointer user_data) +timer_func (gpointer user_data) { IndicatorDatetime * self = INDICATOR_DATETIME(user_data); + self->priv->timer = 0; + struct tm * ltime = update_label(self); + setup_timer(self, ltime); + return FALSE; +} - if (self->priv->label != NULL) { - update_label(self); - return TRUE; - } else { +/* Configure the timer to run the next time through */ +static void +setup_timer (IndicatorDatetime * self, struct tm * ltime) +{ + if (self->priv->timer != 0) { + g_source_remove(self->priv->timer); self->priv->timer = 0; - return FALSE; } + + if (self->priv->show_seconds) { + self->priv->timer = g_timeout_add_seconds(1, timer_func, self); + } else { + if (ltime == NULL) { + time_t t; + t = time(NULL); + ltime = localtime(&t); + } - return FALSE; + /* Plus 2 so we're just after the minute, don't want to be early. */ + self->priv->timer = g_timeout_add_seconds(60 - ltime->tm_sec + 2, timer_func, self); + } + + return; } /* Does a quick meausre of how big the string is in @@ -254,33 +585,203 @@ measure_string (GtkStyle * style, PangoContext * context, const gchar * string) return width; } +/* Format for the table of strftime() modifiers to what + we need to check when determining the length */ +typedef struct _strftime_type_t strftime_type_t; +struct _strftime_type_t { + char character; + gint mask; +}; + +enum { + STRFTIME_MASK_NONE = 0, /* Hours or minutes as we always test those */ + STRFTIME_MASK_SECONDS = 1 << 0, /* Seconds count */ + STRFTIME_MASK_AMPM = 1 << 1, /* AM/PM counts */ + STRFTIME_MASK_WEEK = 1 << 2, /* Day of the week maters (Sat, Sun, etc.) */ + STRFTIME_MASK_DAY = 1 << 3, /* Day of the month counts (Feb 1st) */ + STRFTIME_MASK_MONTH = 1 << 4, /* Which month matters */ + STRFTIME_MASK_YEAR = 1 << 5, /* Which year matters */ + /* Last entry, combines all previous */ + STRFTIME_MASK_ALL = (STRFTIME_MASK_SECONDS | STRFTIME_MASK_AMPM | STRFTIME_MASK_WEEK | STRFTIME_MASK_DAY | STRFTIME_MASK_MONTH | STRFTIME_MASK_YEAR) +}; + +/* A table taken from the man page of strftime to what the different + characters can effect. These are worst case in that we need to + test the length based on all these things to ensure that we have + a reasonable string lenght measurement. */ +const static strftime_type_t strftime_type[] = { + {'a', STRFTIME_MASK_WEEK}, + {'A', STRFTIME_MASK_WEEK}, + {'b', STRFTIME_MASK_MONTH}, + {'B', STRFTIME_MASK_MONTH}, + {'c', STRFTIME_MASK_ALL}, /* We don't know, so we have to assume all */ + {'C', STRFTIME_MASK_YEAR}, + {'d', STRFTIME_MASK_MONTH}, + {'D', STRFTIME_MASK_MONTH | STRFTIME_MASK_YEAR | STRFTIME_MASK_DAY}, + {'e', STRFTIME_MASK_DAY}, + {'F', STRFTIME_MASK_MONTH | STRFTIME_MASK_YEAR | STRFTIME_MASK_DAY}, + {'G', STRFTIME_MASK_YEAR}, + {'g', STRFTIME_MASK_YEAR}, + {'h', STRFTIME_MASK_MONTH}, + {'j', STRFTIME_MASK_DAY}, + {'m', STRFTIME_MASK_MONTH}, + {'p', STRFTIME_MASK_AMPM}, + {'P', STRFTIME_MASK_AMPM}, + {'r', STRFTIME_MASK_AMPM}, + {'s', STRFTIME_MASK_SECONDS}, + {'S', STRFTIME_MASK_SECONDS}, + {'T', STRFTIME_MASK_SECONDS}, + {'u', STRFTIME_MASK_WEEK}, + {'U', STRFTIME_MASK_DAY | STRFTIME_MASK_MONTH}, + {'V', STRFTIME_MASK_DAY | STRFTIME_MASK_MONTH}, + {'w', STRFTIME_MASK_DAY}, + {'W', STRFTIME_MASK_DAY | STRFTIME_MASK_MONTH}, + {'x', STRFTIME_MASK_YEAR | STRFTIME_MASK_MONTH | STRFTIME_MASK_DAY | STRFTIME_MASK_WEEK}, + {'X', STRFTIME_MASK_SECONDS}, + {'y', STRFTIME_MASK_YEAR}, + {'Y', STRFTIME_MASK_YEAR}, + /* Last one */ + {0, 0} +}; + #define FAT_NUMBER 8 +/* Looks through the characters in the format string to + ensure that we can figure out which of the things we + need to check in determining the length. */ +static gint +generate_strftime_bitmask (IndicatorDatetime * self) +{ + gint retval = 0; + glong strlength = g_utf8_strlen(self->priv->time_string, -1); + gint i; + g_debug("Evaluating bitmask for '%s'", self->priv->time_string); + + for (i = 0; i < strlength; i++) { + if (self->priv->time_string[i] == '%' && i + 1 < strlength) { + gchar evalchar = self->priv->time_string[i + 1]; + + /* If we're using alternate formats we need to skip those characters */ + if (evalchar == 'E' || evalchar == 'O') { + if (i + 2 < strlength) { + evalchar = self->priv->time_string[i + 2]; + } else { + continue; + } + } + + /* Let's look at that character in the table */ + int j; + for (j = 0; strftime_type[j].character != 0; j++) { + if (strftime_type[j].character == evalchar) { + retval |= strftime_type[j].mask; + break; + } + } + } + } + + return retval; +} + +/* Build an array up of all the time values that we want to check + for length to ensure we're in a good place */ +static void +build_timeval_array (GArray * timevals, gint mask) +{ + struct tm mytm = {0}; + + /* Sun 12/28/8888 00:00 */ + mytm.tm_hour = 0; + mytm.tm_mday = 28; + mytm.tm_mon = 11; + mytm.tm_year = 8888 - 1900; + mytm.tm_wday = 0; + mytm.tm_yday = 363; + g_array_append_val(timevals, mytm); + + if (mask & STRFTIME_MASK_AMPM) { + /* Sun 12/28/8888 12:00 */ + mytm.tm_hour = 12; + g_array_append_val(timevals, mytm); + } + + /* NOTE: Ignoring year 8888 should handle it */ + + if (mask & STRFTIME_MASK_MONTH) { + gint oldlen = timevals->len; + gint i, j; + for (i = 0; i < oldlen; i++) { + for (j = 0; j < 11; j++) { + struct tm localval = g_array_index(timevals, struct tm, i); + localval.tm_mon = j; + /* Not sure if I need to adjust yday & wday, hope not */ + g_array_append_val(timevals, localval); + } + } + } + + /* Doing these together as it seems like just slightly more + coverage on the numerical days, but worth it. */ + if (mask & (STRFTIME_MASK_WEEK | STRFTIME_MASK_DAY)) { + gint oldlen = timevals->len; + gint i, j; + for (i = 0; i < oldlen; i++) { + for (j = 22; j < 28; j++) { + struct tm localval = g_array_index(timevals, struct tm, i); + + gint diff = 28 - j; + + localval.tm_mday = j; + localval.tm_wday = localval.tm_wday - diff; + if (localval.tm_wday < 0) { + localval.tm_wday += 7; + } + localval.tm_yday = localval.tm_yday - diff; + + g_array_append_val(timevals, localval); + } + } + } + + return; +} + /* Try to get a good guess at what a maximum width of the entire string would be. */ static void guess_label_size (IndicatorDatetime * self) { + /* This is during startup. */ + if (self->priv->label == NULL) return; + GtkStyle * style = gtk_widget_get_style(GTK_WIDGET(self->priv->label)); PangoContext * context = gtk_widget_get_pango_context(GTK_WIDGET(self->priv->label)); + gint * max_width = &(self->priv->max_width); + gint posibilitymask = generate_strftime_bitmask(self); + + /* Build the array of possibilities that we want to test */ + GArray * timevals = g_array_new(FALSE, TRUE, sizeof(struct tm)); + build_timeval_array(timevals, posibilitymask); + + g_debug("Checking against %d posible times", timevals->len); + gint check_time; + for (check_time = 0; check_time < timevals->len; check_time++) { + gchar longstr[128]; + strftime(longstr, 128, self->priv->time_string, &(g_array_index(timevals, struct tm, check_time))); + + gchar * utf8 = g_locale_to_utf8(longstr, -1, NULL, NULL, NULL); + gint length = measure_string(style, context, utf8); + g_free(utf8); + + if (length > *max_width) { + *max_width = length; + } + } - /* TRANSLATORS: This string is used for measuring the size of - the font used for showing the time and is not shown to the - user anywhere. */ - gchar * am_str = g_strdup_printf(_("%d%d:%d%d AM"), FAT_NUMBER, FAT_NUMBER, FAT_NUMBER, FAT_NUMBER); - gint am_width = measure_string(style, context, am_str); - g_free(am_str); - - /* TRANSLATORS: This string is used for measuring the size of - the font used for showing the time and is not shown to the - user anywhere. */ - gchar * pm_str = g_strdup_printf(_("%d%d:%d%d PM"), FAT_NUMBER, FAT_NUMBER, FAT_NUMBER, FAT_NUMBER); - gint pm_width = measure_string(style, context, pm_str); - g_free(pm_str); - - self->priv->max_width = MAX(am_width, pm_width); - gtk_widget_set_size_request(GTK_WIDGET(self->priv->label), self->priv->max_width, -1); + g_array_free(timevals, TRUE); + gtk_widget_set_size_request(GTK_WIDGET(self->priv->label), self->priv->max_width, -1); g_debug("Guessing max time width: %d", self->priv->max_width); return; @@ -298,6 +799,89 @@ style_changed (GtkWidget * widget, GtkStyle * oldstyle, gpointer data) return; } +/* Tries to figure out what our format string should be. Lots + of translator comments in here. */ +static gchar * +generate_format_string (IndicatorDatetime * self) +{ + if (self->priv->time_mode == SETTINGS_TIME_CUSTOM) { + return g_strdup(self->priv->custom_string); + } + + gboolean twelvehour = TRUE; + + if (self->priv->time_mode == SETTINGS_TIME_LOCALE) { + /* TRANSLATORS: This string is used to determine the default + clock style for your locale. If it is the string '12' then + the default will be a 12-hour clock using AM/PM string. If + it is '24' then it will be a 24-hour clock. Users may over + ride this setting so it's still important to translate the + other strings no matter how this is set. */ + const gchar * locale_default = _("12"); + + if (g_strcmp0(locale_default, "24") == 0) { + twelvehour = FALSE; + } + } else if (self->priv->time_mode == SETTINGS_TIME_24_HOUR) { + twelvehour = FALSE; + } + + const gchar * time_string = NULL; + if (twelvehour) { + if (self->priv->show_seconds) { + /* TRANSLATORS: A format string for the strftime function for + a clock showing 12-hour time with seconds. */ + time_string = _("%l:%M:%S %p"); + } else { + /* TRANSLATORS: A format string for the strftime function for + a clock showing 12-hour time. */ + time_string = _(DEFAULT_TIME_12_FORMAT); + } + } else { + if (self->priv->show_seconds) { + /* TRANSLATORS: A format string for the strftime function for + a clock showing 24-hour time with seconds. */ + time_string = _("%H:%M:%S"); + } else { + /* TRANSLATORS: A format string for the strftime function for + a clock showing 24-hour time. */ + time_string = _(DEFAULT_TIME_24_FORMAT); + } + } + + /* Checkpoint, let's not fail */ + g_return_val_if_fail(time_string != NULL, g_strdup(DEFAULT_TIME_FORMAT)); + + /* If there's no date or day let's just leave now and + not worry about the rest of this code */ + if (!self->priv->show_date && !self->priv->show_day) { + return g_strdup(time_string); + } + + const gchar * date_string = NULL; + if (self->priv->show_date && self->priv->show_day) { + /* TRANSLATORS: This is a format string passed to strftime to represent + the day of the week, the month and the day of the month. */ + date_string = _("%a %b %e"); + } else if (self->priv->show_date) { + /* TRANSLATORS: This is a format string passed to strftime to represent + the month and the day of the month. */ + date_string = _("%b %e"); + } else if (self->priv->show_day) { + /* TRANSLATORS: This is a format string passed to strftime to represent + the day of the week. */ + date_string = _("%a"); + } + + /* Check point, we should have a date string */ + g_return_val_if_fail(date_string != NULL, g_strdup(time_string)); + + /* TRANSLATORS: This is a format string passed to strftime to combine the + date and the time. The value of "%s, %s" would result in a string like + this in US English 12-hour time: 'Fri Jul 16, 11:50 AM' */ + return g_strdup_printf(_("%s, %s"), date_string, time_string); +} + /* Grabs the label. Creates it if it doesn't exist already */ static GtkLabel * @@ -316,7 +900,7 @@ get_label (IndicatorObject * io) } if (self->priv->timer == 0) { - self->priv->timer = g_timeout_add_seconds(60, minute_timer_func, self); + setup_timer(self, NULL); } return self->priv->label; |